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 // --------------------------------------------------------------------------------------------------
38 class SourceViewDialog
: public wxDialog
42 void onClose(wxCloseEvent
& evt
)
44 EndModal( GetReturnCode() );
47 SourceViewDialog(wxWindow
* parent
, wxString source
) :
48 wxDialog(parent
, wxID_ANY
, "Source Code",
49 wxDefaultPosition
, wxSize(700,500),
50 wxDEFAULT_DIALOG_STYLE
| wxRESIZE_BORDER
)
52 wxStyledTextCtrl
* text
= new wxStyledTextCtrl(this, wxID_ANY
);
54 //text->SetLexer(wxSTC_LEX_HTML);
55 text
->SetMarginWidth (MARGIN_LINE_NUMBERS
, 50);
56 text
->StyleSetForeground (wxSTC_STYLE_LINENUMBER
, wxColour (75, 75, 75) );
57 text
->StyleSetBackground (wxSTC_STYLE_LINENUMBER
, wxColour (220, 220, 220));
58 text
->SetMarginType (MARGIN_LINE_NUMBERS
, wxSTC_MARGIN_NUMBER
);
60 text
->SetWrapMode (wxSTC_WRAP_WORD
);
62 text
->SetText(source
);
64 text
->StyleClearAll();
65 text
->SetLexer(wxSTC_LEX_HTML
);
66 text
->StyleSetForeground (wxSTC_H_DOUBLESTRING
, wxColour(255,0,0));
67 text
->StyleSetForeground (wxSTC_H_SINGLESTRING
, wxColour(255,0,0));
68 text
->StyleSetForeground (wxSTC_H_ENTITY
, wxColour(255,0,0));
69 text
->StyleSetForeground (wxSTC_H_TAG
, wxColour(0,150,0));
70 text
->StyleSetForeground (wxSTC_H_TAGUNKNOWN
, wxColour(0,150,0));
71 text
->StyleSetForeground (wxSTC_H_ATTRIBUTE
, wxColour(0,0,150));
72 text
->StyleSetForeground (wxSTC_H_ATTRIBUTEUNKNOWN
, wxColour(0,0,150));
73 text
->StyleSetForeground (wxSTC_H_COMMENT
, wxColour(150,150,150));
76 wxBoxSizer
* sizer
= new wxBoxSizer(wxVERTICAL
);
77 sizer
->Add(text
, 1, wxEXPAND
);
80 Connect(wxEVT_CLOSE_WINDOW
, wxCloseEventHandler(SourceViewDialog::onClose
), NULL
, this);
86 // --------------------------------------------------------------------------------------------------
88 // --------------------------------------------------------------------------------------------------
89 class wxMiniApp
: public wxApp
92 wxWebView
* m_browser_ctrl
;
95 wxToolBarToolBase
* back
;
96 wxToolBarToolBase
* forward
;
97 wxToolBarToolBase
* stop
;
98 wxToolBarToolBase
* reload
;
99 wxToolBarToolBase
* tools
;
102 wxMenuItem
* tinySize
;
103 wxMenuItem
* smallSize
;
104 wxMenuItem
* mediumSize
;
105 wxMenuItem
* largeSize
;
106 wxMenuItem
* largestSize
;
108 //wxMenuItem* offlineMode;
109 //wxMenuItem* onlineMode;
111 wxLogWindow
* logging
;
112 wxToolBar
* m_toolbar
;
115 int m_animation_angle
;
117 wxPanel
* m_notification_panel
;
118 wxStaticText
* m_notification_text
;
121 // function called at the application initialization
122 virtual bool OnInit();
125 * Implement timer to display the loading animation (OK, I admit this is totally irrelevant to
126 * the HTML control being demonstrated here, but it's fun ;)
128 void onAnimationTimer(wxTimerEvent
& evt
)
130 m_animation_angle
+= 15;
131 if (m_animation_angle
> 360) m_animation_angle
-= 360;
133 wxBitmap
image(32, 32);
137 dc
.SelectObject(image
);
138 dc
.SetBackground(wxBrush(wxColour(255,0,255)));
141 if (m_animation_angle
>= 0 && m_animation_angle
<= 180)
143 dc
.SetBrush(*wxYELLOW_BRUSH
);
144 dc
.SetPen(*wxYELLOW_PEN
);
145 dc
.DrawCircle(16 - int(sin(m_animation_angle
*0.01745f
/* convert to radians */)*14.0f
),
146 16 + int(cos(m_animation_angle
*0.01745f
/* convert to radians */)*14.0f
), 3 );
149 dc
.DrawBitmap(wxBitmap(wxlogo_xpm
), 0, 0, true);
151 if (m_animation_angle
> 180)
153 dc
.SetBrush(*wxYELLOW_BRUSH
);
154 dc
.SetPen(*wxYELLOW_PEN
);
155 dc
.DrawCircle(16 - int(sin(m_animation_angle
*0.01745f
/* convert to radians */)*14.0f
),
156 16 + int(cos(m_animation_angle
*0.01745f
/* convert to radians */)*14.0f
), 3 );
160 image
.SetMask(new wxMask(image
, wxColour(255,0,255)));
161 m_toolbar
->SetToolNormalBitmap(tools
->GetId(), image
);
165 * Method that retrieves the current state from the web control and updates the GUI
166 * the reflect this current state.
170 m_toolbar
->EnableTool( back
->GetId(), m_browser_ctrl
->CanGoBack() );
171 m_toolbar
->EnableTool( forward
->GetId(), m_browser_ctrl
->CanGoForward() );
173 if (m_browser_ctrl
->IsBusy())
175 //tools->SetLabel(_("Loading..."));
179 m_timer
= new wxTimer(this);
180 this->Connect(wxEVT_TIMER
, wxTimerEventHandler(wxMiniApp::onAnimationTimer
), NULL
, this);
182 m_timer
->Start(100); // start animation timer
184 m_toolbar
->EnableTool( stop
->GetId(), true );
188 if (m_timer
!= NULL
) m_timer
->Stop(); // stop animation timer
190 //tools->SetLabel(_("Tools"));
191 m_toolbar
->SetToolNormalBitmap(tools
->GetId(), wxBitmap(wxlogo_xpm
));
192 m_toolbar
->EnableTool( stop
->GetId(), false );
195 frame
->SetTitle( m_browser_ctrl
->GetCurrentTitle() );
196 url
->SetValue( m_browser_ctrl
->GetCurrentURL() );
200 * Callback invoked when user entered an URL and pressed enter
202 void onUrl(wxCommandEvent
& evt
)
204 if (m_notification_panel
->IsShown())
206 m_notification_panel
->Hide();
210 m_browser_ctrl
->LoadUrl( url
->GetValue() );
215 * Callback invoked when user pressed the "back" button
217 void onBack(wxCommandEvent
& evt
)
219 // First, hide notification panel if it was shown
220 if (m_notification_panel
->IsShown())
222 m_notification_panel
->Hide();
226 m_browser_ctrl
->GoBack();
231 * Callback invoked when user pressed the "forward" button
233 void onForward(wxCommandEvent
& evt
)
235 // First, hide notification panel if it was shown
236 if (m_notification_panel
->IsShown())
238 m_notification_panel
->Hide();
242 m_browser_ctrl
->GoForward();
247 * Callback invoked when user pressed the "stop" button
249 void onStop(wxCommandEvent
& evt
)
251 m_browser_ctrl
->Stop();
256 * Callback invoked when user pressed the "reload" button
258 void onReload(wxCommandEvent
& evt
)
260 // First, hide notification panel if it was shown
261 if (m_notification_panel
->IsShown())
263 m_notification_panel
->Hide();
267 m_browser_ctrl
->Reload();
272 * Callback invoked when there is a request to load a new page (for instance
273 * when the user clicks a link)
275 void onNavigationRequest(wxWebNavigationEvent
& evt
)
277 // First, hide notification panel if it was shown
278 if (m_notification_panel
->IsShown())
280 m_notification_panel
->Hide();
284 wxLogMessage("%s", "Navigation request to '" + evt
.GetHref() + "' (target='" +
285 evt
.GetTarget() + "')");
287 wxASSERT(m_browser_ctrl
->IsBusy());
289 // Uncomment this to see how to block navigation requests
290 //int answer = wxMessageBox("Proceed with navigation to '" + evt.GetHref() + "'?",
291 // "Proceed with navigation?", wxYES_NO );
292 //if (answer != wxYES)
300 * Callback invoked when a navigation request was accepted
302 void onNavigationComplete(wxWebNavigationEvent
& evt
)
304 wxLogMessage("%s", "Navigation complete; url='" + evt
.GetHref() + "'");
309 * Callback invoked when a page is finished loading
311 void onDocumentLoaded(wxWebNavigationEvent
& evt
)
313 wxLogMessage("%s", "Document loaded; url='" + evt
.GetHref() + "'");
316 m_browser_ctrl
->GetZoom();
320 * On new window, we veto to stop extra windows appearing
322 void onNewWindow(wxWebNavigationEvent
& evt
)
324 wxLogMessage("%s", "New window; url='" + evt
.GetHref() + "'");
331 * Invoked when user selects the "View Source" menu item
333 void onViewSourceRequest(wxCommandEvent
& evt
)
335 SourceViewDialog
dlg(frame
, m_browser_ctrl
->GetPageSource());
341 * Invoked when user selects the "Menu" item
343 void onToolsClicked(wxCommandEvent
& evt
)
345 tinySize
->Check(false);
346 smallSize
->Check(false);
347 mediumSize
->Check(false);
348 largeSize
->Check(false);
349 largestSize
->Check(false);
351 wxWebViewZoom zoom
= m_browser_ctrl
->GetZoom();
354 case wxWEB_VIEW_ZOOM_TINY
:
357 case wxWEB_VIEW_ZOOM_SMALL
:
360 case wxWEB_VIEW_ZOOM_MEDIUM
:
363 case wxWEB_VIEW_ZOOM_LARGE
:
366 case wxWEB_VIEW_ZOOM_LARGEST
:
367 largestSize
->Check();
371 // bool IsOfflineMode();
372 // void SetOfflineMode(bool offline);
374 //offlineMode->Check(false);
375 //onlineMode->Check(false);
376 //const bool offline = m_browser_ctrl->IsOfflineMode();
377 //if (offline) offlineMode->Check();
378 //else onlineMode->Check();
380 wxPoint position
= frame
->ScreenToClient( wxGetMousePosition() );
381 frame
->PopupMenu(toolsMenu
, position
.x
, position
.y
);
385 * Invoked when user selects the zoom size in the menu
387 void onSetZoom(wxCommandEvent
& evt
)
389 if (evt
.GetId() == tinySize
->GetId())
391 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_TINY
);
393 else if (evt
.GetId() == smallSize
->GetId())
395 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_SMALL
);
397 else if (evt
.GetId() == mediumSize
->GetId())
399 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_MEDIUM
);
401 else if (evt
.GetId() == largeSize
->GetId())
403 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_LARGE
);
405 else if (evt
.GetId() == largestSize
->GetId())
407 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_LARGEST
);
416 void onChangeOnlineMode(wxCommandEvent& evt)
418 if (evt.GetId() == offlineMode->GetId())
420 m_browser_ctrl->SetOfflineMode(true);
421 m_browser_ctrl->SetPage("<html><body><h1>You are now in offline mode.</h1></body></html>");
423 else if (evt.GetId() == onlineMode->GetId())
425 m_browser_ctrl->SetOfflineMode(false);
435 * Callback invoked when a loading error occurs
437 void onError(wxWebNavigationEvent
& evt
)
439 wxString errorCategory
;
440 switch (evt
.GetInt())
442 case wxWEB_NAV_ERR_CONNECTION
:
443 errorCategory
= "wxWEB_NAV_ERR_CONNECTION";
446 case wxWEB_NAV_ERR_CERTIFICATE
:
447 errorCategory
= "wxWEB_NAV_ERR_CERTIFICATE";
450 case wxWEB_NAV_ERR_AUTH
:
451 errorCategory
= "wxWEB_NAV_ERR_AUTH";
454 case wxWEB_NAV_ERR_SECURITY
:
455 errorCategory
= "wxWEB_NAV_ERR_SECURITY";
458 case wxWEB_NAV_ERR_NOT_FOUND
:
459 errorCategory
= "wxWEB_NAV_ERR_NOT_FOUND";
462 case wxWEB_NAV_ERR_REQUEST
:
463 errorCategory
= "wxWEB_NAV_ERR_REQUEST";
466 case wxWEB_NAV_ERR_USER_CANCELLED
:
467 errorCategory
= "wxWEB_NAV_ERR_USER_CANCELLED";
470 case wxWEB_NAV_ERR_OTHER
:
471 errorCategory
= "wxWEB_NAV_ERR_OTHER";
475 wxLogMessage("Error; url='" + evt
.GetHref() + "', error='" + errorCategory
+ "' (" + evt
.GetString() + ")");
477 // show the notification panel
478 m_notification_text
->SetLabel(_("An error occurred loading ") + evt
.GetHref() + "\n" +
479 "'" + errorCategory
+ "' (" + evt
.GetString() + ")");
480 m_notification_panel
->Layout();
481 m_notification_panel
->GetSizer()->SetSizeHints(m_notification_panel
);
482 m_notification_panel
->Show();
489 * Invoked when user clicks "Hide" in the notification panel
491 void onHideNotifBar(wxCommandEvent
& evt
)
493 m_notification_panel
->Hide();
497 void onClose(wxCloseEvent
& evt
)
502 void onQuitMenu(wxCommandEvent
& evt
)
508 * Invoked when user selects "Print" from the menu
510 void onPrint(wxCommandEvent
& evt
)
512 m_browser_ctrl
->Print();
516 IMPLEMENT_APP(wxMiniApp
);
518 bool wxMiniApp::OnInit()
521 m_animation_angle
= 0;
523 frame
= new wxFrame( NULL
, -1, _("wxBetterHTMLControl Browser Example"), wxDefaultPosition
, wxSize(800, 600) );
525 // wx has a default mechanism to expand the only control of a frame; but since this mechanism
526 // does not involve sizers, invoking ->Layout on the frame does not udpate the layout which is
528 wxBoxSizer
* expandSizer
= new wxBoxSizer(wxHORIZONTAL
);
529 wxPanel
* mainpane
= new wxPanel(frame
, wxID_ANY
);
530 expandSizer
->Add(mainpane
, 1, wxEXPAND
);
531 frame
->SetSizer(expandSizer
);
533 wxLog::SetLogLevel(wxLOG_Max
);
534 logging
= new wxLogWindow(frame
, _("Logging"));
535 wxLog::SetLogLevel(wxLOG_Max
);
537 // ---- Create the Tools menu
538 toolsMenu
= new wxMenu();
539 wxMenuItem
* print
= toolsMenu
->Append(wxID_ANY
, _("Print"));
540 wxMenuItem
* viewSource
= toolsMenu
->Append(wxID_ANY
, _("View Source"));
541 toolsMenu
->AppendSeparator();
542 tinySize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Tiny"));
543 smallSize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Small"));
544 mediumSize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Medium"));
545 largeSize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Large"));
546 largestSize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Largest"));
547 //toolsMenu->AppendSeparator();
548 //offlineMode = toolsMenu->AppendCheckItem(wxID_ANY, _("Offline Mode"));
549 //onlineMode = toolsMenu->AppendCheckItem(wxID_ANY, _("Online Mode"));
551 // ---- Create the Toolbar
552 m_toolbar
= frame
->CreateToolBar(/*wxNO_BORDER |*/ wxTB_TEXT
);
553 m_toolbar
->SetToolBitmapSize(wxSize(32, 32));
555 back
= m_toolbar
->AddTool(wxID_ANY
, _("Back"), wxBitmap(back_xpm
));
556 forward
= m_toolbar
->AddTool(wxID_ANY
, _("Forward"), wxBitmap(forward_xpm
));
557 stop
= m_toolbar
->AddTool(wxID_ANY
, _("Stop"), wxBitmap(stop_xpm
));
558 reload
= m_toolbar
->AddTool(wxID_ANY
, _("Reload"), wxBitmap(refresh_xpm
));
560 url
= new wxTextCtrl(m_toolbar
, wxID_ANY
, wxT("http://www.google.com"),
561 wxDefaultPosition
, wxSize(400, -1), wxTE_PROCESS_ENTER
);
562 m_toolbar
->AddControl(url
, _("URL"));
563 tools
= m_toolbar
->AddTool(wxID_ANY
, _("Menu"), wxBitmap(wxlogo_xpm
));
564 //m_toolbar->SetDropdownMenu(tools->GetId(), toolsMenu);
566 m_toolbar
->Realize();
568 m_toolbar
->Connect(back
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
569 wxCommandEventHandler(wxMiniApp::onBack
), NULL
, this );
570 m_toolbar
->Connect(forward
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
571 wxCommandEventHandler(wxMiniApp::onForward
), NULL
, this );
572 m_toolbar
->Connect(stop
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
573 wxCommandEventHandler(wxMiniApp::onStop
), NULL
, this );
574 m_toolbar
->Connect(reload
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
575 wxCommandEventHandler(wxMiniApp::onReload
), NULL
, this );
576 m_toolbar
->Connect(tools
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
577 wxCommandEventHandler(wxMiniApp::onToolsClicked
), NULL
, this );
579 url
->Connect(url
->GetId(), wxEVT_COMMAND_TEXT_ENTER
, wxCommandEventHandler(wxMiniApp::onUrl
), NULL
, this );
582 frame
->Connect(viewSource
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
583 wxCommandEventHandler(wxMiniApp::onViewSourceRequest
), NULL
, this );
584 frame
->Connect(print
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
585 wxCommandEventHandler(wxMiniApp::onPrint
), NULL
, this );
587 frame
->Connect(tinySize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
588 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
589 frame
->Connect(smallSize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
590 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
591 frame
->Connect(mediumSize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
592 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
593 frame
->Connect(largeSize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
594 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
595 frame
->Connect(largestSize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
596 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
598 // ---- Create the web view
599 m_browser_ctrl
= wxWebView::New(mainpane
, wxID_ANY
);
601 // ---- Create the notification panel
603 wxBoxSizer
* notification_sizer
= new wxBoxSizer(wxHORIZONTAL
);
604 m_notification_panel
= new wxPanel(mainpane
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, wxBORDER_SIMPLE
);
605 m_notification_text
= new wxStaticText(m_notification_panel
, wxID_ANY
, "[No message]");
606 notification_sizer
->Add( new wxStaticBitmap(m_notification_panel
, wxID_ANY
,
607 wxArtProvider::GetBitmap(wxART_WARNING
, wxART_OTHER
, wxSize(48, 48))),
608 0, wxALIGN_CENTER_VERTICAL
| wxALL
, 5 );
609 notification_sizer
->Add(m_notification_text
, 1, wxEXPAND
| wxALIGN_CENTER_VERTICAL
| wxALL
, 5);
610 wxButton
* hideNotif
= new wxButton(m_notification_panel
, wxID_ANY
, _("Hide"));
611 notification_sizer
->Add(hideNotif
, 0, wxALIGN_CENTER_VERTICAL
| wxALL
, 5);
612 m_notification_panel
->SetSizer(notification_sizer
);
613 m_notification_panel
->SetBackgroundColour(wxColor(255,225,110));
614 m_notification_panel
->Hide();
615 hideNotif
->Connect(hideNotif
->GetId(), wxEVT_COMMAND_BUTTON_CLICKED
,
616 wxCommandEventHandler(wxMiniApp::onHideNotifBar
), NULL
, this);
619 wxBoxSizer
* sizer
= new wxBoxSizer(wxVERTICAL
);
620 sizer
->Add(m_notification_panel
, 0, wxEXPAND
| wxALL
, 5);
621 sizer
->Add(m_browser_ctrl
, 1, wxEXPAND
| wxALL
, 5);
623 mainpane
->SetSizer(sizer
);
628 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_NAVIGATING
,
629 wxWebNavigationEventHandler(wxMiniApp::onNavigationRequest
), NULL
, this);
631 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_NAVIGATED
,
632 wxWebNavigationEventHandler(wxMiniApp::onNavigationComplete
), NULL
, this);
634 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_LOADED
,
635 wxWebNavigationEventHandler(wxMiniApp::onDocumentLoaded
), NULL
, this);
637 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_ERROR
,
638 wxWebNavigationEventHandler(wxMiniApp::onError
), NULL
, this);
640 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_NEWWINDOW
,
641 wxWebNavigationEventHandler(wxMiniApp::onNewWindow
), NULL
, this);
643 frame
->Connect(wxEVT_CLOSE_WINDOW
, wxCloseEventHandler(wxMiniApp::onClose
), NULL
, this);
644 Connect(wxID_EXIT
, wxEVT_COMMAND_MENU_SELECTED
, wxCommandEventHandler(wxMiniApp::onQuitMenu
), NULL
, this);
646 // You can test different zoom types (if supported by the backend)
647 // if (m_browser_ctrl->CanSetZoomType(wxWEB_VIEW_ZOOM_TYPE_LAYOUT))
648 // m_browser_ctrl->SetZoomType(wxWEB_VIEW_ZOOM_TYPE_LAYOUT);