1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxBetterHTMLControl test
4 // Author: Marianne Gagnon
6 // Copyright: (c) 2010 Marianne Gagnon
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
11 #include <wx/artprov.h>
12 #include <wx/notifmsg.h>
13 #include <wx/settings.h>
16 #include <wx/stc/stc.h>
18 #error "wxStyledTextControl is needed by this sample"
21 #include "wx/webview.h"
24 #include "forward.xpm"
26 #include "refresh.xpm"
28 // --------------------------------------------------------------------------------------------------
30 // --------------------------------------------------------------------------------------------------
32 class SourceViewDialog
: public wxDialog
35 SourceViewDialog(wxWindow
* parent
, wxString source
) :
36 wxDialog(parent
, wxID_ANY
, "Source Code",
37 wxDefaultPosition
, wxSize(700,500),
38 wxDEFAULT_DIALOG_STYLE
| wxRESIZE_BORDER
)
40 wxStyledTextCtrl
* text
= new wxStyledTextCtrl(this, wxID_ANY
);
42 text
->SetMarginWidth(1, 30);
43 text
->SetMarginType(1, wxSTC_MARGIN_NUMBER
);
44 text
->SetText(source
);
46 text
->StyleClearAll();
47 text
->SetLexer(wxSTC_LEX_HTML
);
48 text
->StyleSetForeground(wxSTC_H_DOUBLESTRING
, wxColour(255,0,0));
49 text
->StyleSetForeground(wxSTC_H_SINGLESTRING
, wxColour(255,0,0));
50 text
->StyleSetForeground(wxSTC_H_ENTITY
, wxColour(255,0,0));
51 text
->StyleSetForeground(wxSTC_H_TAG
, wxColour(0,150,0));
52 text
->StyleSetForeground(wxSTC_H_TAGUNKNOWN
, wxColour(0,150,0));
53 text
->StyleSetForeground(wxSTC_H_ATTRIBUTE
, wxColour(0,0,150));
54 text
->StyleSetForeground(wxSTC_H_ATTRIBUTEUNKNOWN
, wxColour(0,0,150));
55 text
->StyleSetForeground(wxSTC_H_COMMENT
, wxColour(150,150,150));
58 wxBoxSizer
* sizer
= new wxBoxSizer(wxVERTICAL
);
59 sizer
->Add(text
, 1, wxEXPAND
);
64 // --------------------------------------------------------------------------------------------------
66 // --------------------------------------------------------------------------------------------------
67 class wxMiniApp
: public wxApp
70 wxWebView
* m_browser_ctrl
;
73 wxToolBarToolBase
* back
;
74 wxToolBarToolBase
* forward
;
75 wxToolBarToolBase
* stop
;
76 wxToolBarToolBase
* reload
;
77 wxToolBarToolBase
* tools
;
81 wxMenuItem
* smallSize
;
82 wxMenuItem
* mediumSize
;
83 wxMenuItem
* largeSize
;
84 wxMenuItem
* largestSize
;
86 //wxMenuItem* offlineMode;
87 //wxMenuItem* onlineMode;
93 int m_animation_angle
;
95 wxPanel
* m_notification_panel
;
96 wxStaticText
* m_notification_text
;
99 // function called at the application initialization
100 virtual bool OnInit();
103 * Implement timer to display the loading animation (OK, I admit this is totally irrelevant to
104 * the HTML control being demonstrated here, but it's fun ;)
106 void onAnimationTimer(wxTimerEvent
& evt
)
108 m_animation_angle
+= 15;
109 if (m_animation_angle
> 360) m_animation_angle
-= 360;
111 wxBitmap
image(32, 32);
115 dc
.SelectObject(image
);
116 dc
.SetBackground(wxBrush(wxColour(255,0,255)));
119 if (m_animation_angle
>= 0 && m_animation_angle
<= 180)
121 dc
.SetBrush(*wxYELLOW_BRUSH
);
122 dc
.SetPen(*wxYELLOW_PEN
);
123 dc
.DrawCircle(16 - int(sin(m_animation_angle
*0.01745f
/* convert to radians */)*14.0f
),
124 16 + int(cos(m_animation_angle
*0.01745f
/* convert to radians */)*14.0f
), 3 );
127 dc
.DrawBitmap(wxBitmap(wxlogo_xpm
), 0, 0, true);
129 if (m_animation_angle
> 180)
131 dc
.SetBrush(*wxYELLOW_BRUSH
);
132 dc
.SetPen(*wxYELLOW_PEN
);
133 dc
.DrawCircle(16 - int(sin(m_animation_angle
*0.01745f
/* convert to radians */)*14.0f
),
134 16 + int(cos(m_animation_angle
*0.01745f
/* convert to radians */)*14.0f
), 3 );
138 image
.SetMask(new wxMask(image
, wxColour(255,0,255)));
139 m_toolbar
->SetToolNormalBitmap(tools
->GetId(), image
);
143 * Method that retrieves the current state from the web control and updates the GUI
144 * the reflect this current state.
148 m_toolbar
->EnableTool( back
->GetId(), m_browser_ctrl
->CanGoBack() );
149 m_toolbar
->EnableTool( forward
->GetId(), m_browser_ctrl
->CanGoForward() );
151 if (m_browser_ctrl
->IsBusy())
153 //tools->SetLabel(_("Loading..."));
157 m_timer
= new wxTimer(this);
158 this->Connect(wxEVT_TIMER
, wxTimerEventHandler(wxMiniApp::onAnimationTimer
), NULL
, this);
160 m_timer
->Start(100); // start animation timer
162 m_toolbar
->EnableTool( stop
->GetId(), true );
166 if (m_timer
!= NULL
) m_timer
->Stop(); // stop animation timer
168 //tools->SetLabel(_("Tools"));
169 m_toolbar
->SetToolNormalBitmap(tools
->GetId(), wxBitmap(wxlogo_xpm
));
170 m_toolbar
->EnableTool( stop
->GetId(), false );
173 frame
->SetTitle( m_browser_ctrl
->GetCurrentTitle() );
174 url
->SetValue( m_browser_ctrl
->GetCurrentURL() );
178 * Callback invoked when user entered an URL and pressed enter
180 void onUrl(wxCommandEvent
& evt
)
182 if (m_notification_panel
->IsShown())
184 m_notification_panel
->Hide();
188 m_browser_ctrl
->LoadUrl( url
->GetValue() );
193 * Callback invoked when user pressed the "back" button
195 void onBack(wxCommandEvent
& evt
)
197 // First, hide notification panel if it was shown
198 if (m_notification_panel
->IsShown())
200 m_notification_panel
->Hide();
204 m_browser_ctrl
->GoBack();
209 * Callback invoked when user pressed the "forward" button
211 void onForward(wxCommandEvent
& evt
)
213 // First, hide notification panel if it was shown
214 if (m_notification_panel
->IsShown())
216 m_notification_panel
->Hide();
220 m_browser_ctrl
->GoForward();
225 * Callback invoked when user pressed the "stop" button
227 void onStop(wxCommandEvent
& evt
)
229 m_browser_ctrl
->Stop();
234 * Callback invoked when user pressed the "reload" button
236 void onReload(wxCommandEvent
& evt
)
238 // First, hide notification panel if it was shown
239 if (m_notification_panel
->IsShown())
241 m_notification_panel
->Hide();
245 m_browser_ctrl
->Reload();
250 * Callback invoked when there is a request to load a new page (for instance
251 * when the user clicks a link)
253 void onNavigationRequest(wxWebNavigationEvent
& evt
)
255 // First, hide notification panel if it was shown
256 if (m_notification_panel
->IsShown())
258 m_notification_panel
->Hide();
262 wxLogMessage("%s", "Navigation request to '" + evt
.GetHref() + "' (target='" +
263 evt
.GetTarget() + "')");
265 wxASSERT(m_browser_ctrl
->IsBusy());
267 // Uncomment this to see how to block navigation requests
268 //int answer = wxMessageBox("Proceed with navigation to '" + evt.GetHref() + "'?",
269 // "Proceed with navigation?", wxYES_NO );
270 //if (answer != wxYES)
278 * Callback invoked when a navigation request was accepted
280 void onNavigationComplete(wxWebNavigationEvent
& evt
)
282 wxLogMessage("%s", "Navigation complete; url='" + evt
.GetHref() + "'");
287 * Callback invoked when a page is finished loading
289 void onDocumentLoaded(wxWebNavigationEvent
& evt
)
291 wxLogMessage("%s", "Document loaded; url='" + evt
.GetHref() + "'");
294 m_browser_ctrl
->GetZoom();
298 * On new window, we veto to stop extra windows appearing
300 void onNewWindow(wxWebNavigationEvent
& evt
)
302 wxLogMessage("%s", "New window; url='" + evt
.GetHref() + "'");
309 * Invoked when user selects the "View Source" menu item
311 void onViewSourceRequest(wxCommandEvent
& evt
)
313 SourceViewDialog
dlg(frame
, m_browser_ctrl
->GetPageSource());
319 * Invoked when user selects the "Menu" item
321 void onToolsClicked(wxCommandEvent
& evt
)
323 if(m_browser_ctrl
->GetCurrentURL() == "")
326 tinySize
->Check(false);
327 smallSize
->Check(false);
328 mediumSize
->Check(false);
329 largeSize
->Check(false);
330 largestSize
->Check(false);
332 wxWebViewZoom zoom
= m_browser_ctrl
->GetZoom();
335 case wxWEB_VIEW_ZOOM_TINY
:
338 case wxWEB_VIEW_ZOOM_SMALL
:
341 case wxWEB_VIEW_ZOOM_MEDIUM
:
344 case wxWEB_VIEW_ZOOM_LARGE
:
347 case wxWEB_VIEW_ZOOM_LARGEST
:
348 largestSize
->Check();
352 // bool IsOfflineMode();
353 // void SetOfflineMode(bool offline);
355 //offlineMode->Check(false);
356 //onlineMode->Check(false);
357 //const bool offline = m_browser_ctrl->IsOfflineMode();
358 //if (offline) offlineMode->Check();
359 //else onlineMode->Check();
361 wxPoint position
= frame
->ScreenToClient( wxGetMousePosition() );
362 frame
->PopupMenu(toolsMenu
, position
.x
, position
.y
);
366 * Invoked when user selects the zoom size in the menu
368 void onSetZoom(wxCommandEvent
& evt
)
370 if (evt
.GetId() == tinySize
->GetId())
372 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_TINY
);
374 else if (evt
.GetId() == smallSize
->GetId())
376 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_SMALL
);
378 else if (evt
.GetId() == mediumSize
->GetId())
380 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_MEDIUM
);
382 else if (evt
.GetId() == largeSize
->GetId())
384 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_LARGE
);
386 else if (evt
.GetId() == largestSize
->GetId())
388 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_LARGEST
);
397 void onChangeOnlineMode(wxCommandEvent& evt)
399 if (evt.GetId() == offlineMode->GetId())
401 m_browser_ctrl->SetOfflineMode(true);
402 m_browser_ctrl->SetPage("<html><body><h1>You are now in offline mode.</h1></body></html>");
404 else if (evt.GetId() == onlineMode->GetId())
406 m_browser_ctrl->SetOfflineMode(false);
416 * Callback invoked when a loading error occurs
418 void onError(wxWebNavigationEvent
& evt
)
420 wxString errorCategory
;
421 switch (evt
.GetInt())
423 case wxWEB_NAV_ERR_CONNECTION
:
424 errorCategory
= "wxWEB_NAV_ERR_CONNECTION";
427 case wxWEB_NAV_ERR_CERTIFICATE
:
428 errorCategory
= "wxWEB_NAV_ERR_CERTIFICATE";
431 case wxWEB_NAV_ERR_AUTH
:
432 errorCategory
= "wxWEB_NAV_ERR_AUTH";
435 case wxWEB_NAV_ERR_SECURITY
:
436 errorCategory
= "wxWEB_NAV_ERR_SECURITY";
439 case wxWEB_NAV_ERR_NOT_FOUND
:
440 errorCategory
= "wxWEB_NAV_ERR_NOT_FOUND";
443 case wxWEB_NAV_ERR_REQUEST
:
444 errorCategory
= "wxWEB_NAV_ERR_REQUEST";
447 case wxWEB_NAV_ERR_USER_CANCELLED
:
448 errorCategory
= "wxWEB_NAV_ERR_USER_CANCELLED";
451 case wxWEB_NAV_ERR_OTHER
:
452 errorCategory
= "wxWEB_NAV_ERR_OTHER";
456 wxLogMessage("Error; url='" + evt
.GetHref() + "', error='" + errorCategory
+ "' (" + evt
.GetString() + ")");
458 // show the notification panel
459 m_notification_text
->SetLabel(_("An error occurred loading ") + evt
.GetHref() + "\n" +
460 "'" + errorCategory
+ "' (" + evt
.GetString() + ")");
461 m_notification_panel
->Layout();
462 m_notification_panel
->GetSizer()->SetSizeHints(m_notification_panel
);
463 m_notification_panel
->Show();
470 * Invoked when user clicks "Hide" in the notification panel
472 void onHideNotifBar(wxCommandEvent
& evt
)
474 m_notification_panel
->Hide();
478 void onClose(wxCloseEvent
& evt
)
483 void onQuitMenu(wxCommandEvent
& evt
)
489 * Invoked when user selects "Print" from the menu
491 void onPrint(wxCommandEvent
& evt
)
493 m_browser_ctrl
->Print();
497 IMPLEMENT_APP(wxMiniApp
);
499 bool wxMiniApp::OnInit()
502 m_animation_angle
= 0;
504 frame
= new wxFrame( NULL
, -1, _("wxBetterHTMLControl Browser Example"), wxDefaultPosition
, wxSize(800, 600) );
506 // wx has a default mechanism to expand the only control of a frame; but since this mechanism
507 // does not involve sizers, invoking ->Layout on the frame does not udpate the layout which is
509 wxBoxSizer
* expandSizer
= new wxBoxSizer(wxHORIZONTAL
);
510 wxPanel
* mainpane
= new wxPanel(frame
, wxID_ANY
);
511 expandSizer
->Add(mainpane
, 1, wxEXPAND
);
512 frame
->SetSizer(expandSizer
);
514 wxLog::SetLogLevel(wxLOG_Max
);
515 logging
= new wxLogWindow(frame
, _("Logging"));
516 wxLog::SetLogLevel(wxLOG_Max
);
518 // ---- Create the Tools menu
519 toolsMenu
= new wxMenu();
520 wxMenuItem
* print
= toolsMenu
->Append(wxID_ANY
, _("Print"));
521 wxMenuItem
* viewSource
= toolsMenu
->Append(wxID_ANY
, _("View Source"));
522 toolsMenu
->AppendSeparator();
523 tinySize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Tiny"));
524 smallSize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Small"));
525 mediumSize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Medium"));
526 largeSize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Large"));
527 largestSize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Largest"));
528 //toolsMenu->AppendSeparator();
529 //offlineMode = toolsMenu->AppendCheckItem(wxID_ANY, _("Offline Mode"));
530 //onlineMode = toolsMenu->AppendCheckItem(wxID_ANY, _("Online Mode"));
532 // ---- Create the Toolbar
533 m_toolbar
= frame
->CreateToolBar(/*wxNO_BORDER |*/ wxTB_TEXT
);
534 m_toolbar
->SetToolBitmapSize(wxSize(32, 32));
536 back
= m_toolbar
->AddTool(wxID_ANY
, _("Back"), wxBitmap(back_xpm
));
537 forward
= m_toolbar
->AddTool(wxID_ANY
, _("Forward"), wxBitmap(forward_xpm
));
538 stop
= m_toolbar
->AddTool(wxID_ANY
, _("Stop"), wxBitmap(stop_xpm
));
539 reload
= m_toolbar
->AddTool(wxID_ANY
, _("Reload"), wxBitmap(refresh_xpm
));
541 url
= new wxTextCtrl(m_toolbar
, wxID_ANY
, wxT("http://www.google.com"),
542 wxDefaultPosition
, wxSize(400, -1), wxTE_PROCESS_ENTER
);
543 m_toolbar
->AddControl(url
, _("URL"));
544 tools
= m_toolbar
->AddTool(wxID_ANY
, _("Menu"), wxBitmap(wxlogo_xpm
));
545 //m_toolbar->SetDropdownMenu(tools->GetId(), toolsMenu);
547 m_toolbar
->Realize();
549 m_toolbar
->Connect(back
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
550 wxCommandEventHandler(wxMiniApp::onBack
), NULL
, this );
551 m_toolbar
->Connect(forward
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
552 wxCommandEventHandler(wxMiniApp::onForward
), NULL
, this );
553 m_toolbar
->Connect(stop
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
554 wxCommandEventHandler(wxMiniApp::onStop
), NULL
, this );
555 m_toolbar
->Connect(reload
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
556 wxCommandEventHandler(wxMiniApp::onReload
), NULL
, this );
557 m_toolbar
->Connect(tools
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
558 wxCommandEventHandler(wxMiniApp::onToolsClicked
), NULL
, this );
560 url
->Connect(url
->GetId(), wxEVT_COMMAND_TEXT_ENTER
, wxCommandEventHandler(wxMiniApp::onUrl
), NULL
, this );
563 frame
->Connect(viewSource
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
564 wxCommandEventHandler(wxMiniApp::onViewSourceRequest
), NULL
, this );
565 frame
->Connect(print
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
566 wxCommandEventHandler(wxMiniApp::onPrint
), NULL
, this );
568 frame
->Connect(tinySize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
569 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
570 frame
->Connect(smallSize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
571 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
572 frame
->Connect(mediumSize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
573 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
574 frame
->Connect(largeSize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
575 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
576 frame
->Connect(largestSize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
577 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
579 // ---- Create the web view
580 m_browser_ctrl
= wxWebView::New(mainpane
, wxID_ANY
);
582 // ---- Create the notification panel
584 wxBoxSizer
* notification_sizer
= new wxBoxSizer(wxHORIZONTAL
);
585 m_notification_panel
= new wxPanel(mainpane
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, wxBORDER_SIMPLE
);
586 m_notification_text
= new wxStaticText(m_notification_panel
, wxID_ANY
, "[No message]");
587 notification_sizer
->Add( new wxStaticBitmap(m_notification_panel
, wxID_ANY
,
588 wxArtProvider::GetBitmap(wxART_WARNING
, wxART_OTHER
, wxSize(48, 48))),
589 0, wxALIGN_CENTER_VERTICAL
| wxALL
, 5 );
590 notification_sizer
->Add(m_notification_text
, 1, wxEXPAND
| wxALIGN_CENTER_VERTICAL
| wxALL
, 5);
591 wxButton
* hideNotif
= new wxButton(m_notification_panel
, wxID_ANY
, _("Hide"));
592 notification_sizer
->Add(hideNotif
, 0, wxALIGN_CENTER_VERTICAL
| wxALL
, 5);
593 m_notification_panel
->SetSizer(notification_sizer
);
594 m_notification_panel
->SetBackgroundColour(wxColor(255,225,110));
595 m_notification_panel
->Hide();
596 hideNotif
->Connect(hideNotif
->GetId(), wxEVT_COMMAND_BUTTON_CLICKED
,
597 wxCommandEventHandler(wxMiniApp::onHideNotifBar
), NULL
, this);
600 wxBoxSizer
* sizer
= new wxBoxSizer(wxVERTICAL
);
601 sizer
->Add(m_notification_panel
, 0, wxEXPAND
| wxALL
, 5);
602 sizer
->Add(m_browser_ctrl
, 1, wxEXPAND
| wxALL
, 5);
604 mainpane
->SetSizer(sizer
);
609 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_NAVIGATING
,
610 wxWebNavigationEventHandler(wxMiniApp::onNavigationRequest
), NULL
, this);
612 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_NAVIGATED
,
613 wxWebNavigationEventHandler(wxMiniApp::onNavigationComplete
), NULL
, this);
615 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_LOADED
,
616 wxWebNavigationEventHandler(wxMiniApp::onDocumentLoaded
), NULL
, this);
618 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_ERROR
,
619 wxWebNavigationEventHandler(wxMiniApp::onError
), NULL
, this);
621 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_NEWWINDOW
,
622 wxWebNavigationEventHandler(wxMiniApp::onNewWindow
), NULL
, this);
624 frame
->Connect(wxEVT_CLOSE_WINDOW
, wxCloseEventHandler(wxMiniApp::onClose
), NULL
, this);
625 Connect(wxID_EXIT
, wxEVT_COMMAND_MENU_SELECTED
, wxCommandEventHandler(wxMiniApp::onQuitMenu
), NULL
, this);
627 // You can test different zoom types (if supported by the backend)
628 // if (m_browser_ctrl->CanSetZoomType(wxWEB_VIEW_ZOOM_TYPE_LAYOUT))
629 // m_browser_ctrl->SetZoomType(wxWEB_VIEW_ZOOM_TYPE_LAYOUT);