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("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("Navigation complete; url='" + evt
.GetHref() + "'");
309 * Callback invoked when a page is finished loading
311 void onDocumentLoaded(wxWebNavigationEvent
& evt
)
313 wxLogMessage("Document loaded; url='" + evt
.GetHref() + "'");
316 m_browser_ctrl
->GetZoom();
320 * Invoked when user selects the "View Source" menu item
322 void onViewSourceRequest(wxCommandEvent
& evt
)
324 SourceViewDialog
dlg(frame
, m_browser_ctrl
->GetPageSource());
330 * Invoked when user selects the "Menu" item
332 void onToolsClicked(wxCommandEvent
& evt
)
334 tinySize
->Check(false);
335 smallSize
->Check(false);
336 mediumSize
->Check(false);
337 largeSize
->Check(false);
338 largestSize
->Check(false);
340 wxWebViewZoom zoom
= m_browser_ctrl
->GetZoom();
343 case wxWEB_VIEW_ZOOM_TINY
:
346 case wxWEB_VIEW_ZOOM_SMALL
:
349 case wxWEB_VIEW_ZOOM_MEDIUM
:
352 case wxWEB_VIEW_ZOOM_LARGE
:
355 case wxWEB_VIEW_ZOOM_LARGEST
:
356 largestSize
->Check();
360 // bool IsOfflineMode();
361 // void SetOfflineMode(bool offline);
363 //offlineMode->Check(false);
364 //onlineMode->Check(false);
365 //const bool offline = m_browser_ctrl->IsOfflineMode();
366 //if (offline) offlineMode->Check();
367 //else onlineMode->Check();
369 wxPoint position
= frame
->ScreenToClient( wxGetMousePosition() );
370 frame
->PopupMenu(toolsMenu
, position
.x
, position
.y
);
374 * Invoked when user selects the zoom size in the menu
376 void onSetZoom(wxCommandEvent
& evt
)
378 if (evt
.GetId() == tinySize
->GetId())
380 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_TINY
);
382 else if (evt
.GetId() == smallSize
->GetId())
384 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_SMALL
);
386 else if (evt
.GetId() == mediumSize
->GetId())
388 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_MEDIUM
);
390 else if (evt
.GetId() == largeSize
->GetId())
392 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_LARGE
);
394 else if (evt
.GetId() == largestSize
->GetId())
396 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_LARGEST
);
405 void onChangeOnlineMode(wxCommandEvent& evt)
407 if (evt.GetId() == offlineMode->GetId())
409 m_browser_ctrl->SetOfflineMode(true);
410 m_browser_ctrl->SetPage("<html><body><h1>You are now in offline mode.</h1></body></html>");
412 else if (evt.GetId() == onlineMode->GetId())
414 m_browser_ctrl->SetOfflineMode(false);
424 * Callback invoked when a loading error occurs
426 void onError(wxWebNavigationEvent
& evt
)
428 wxString errorCategory
;
429 switch (evt
.GetInt())
431 case wxWEB_NAV_ERR_CONNECTION
:
432 errorCategory
= "wxWEB_NAV_ERR_CONNECTION";
435 case wxWEB_NAV_ERR_CERTIFICATE
:
436 errorCategory
= "wxWEB_NAV_ERR_CERTIFICATE";
439 case wxWEB_NAV_ERR_AUTH
:
440 errorCategory
= "wxWEB_NAV_ERR_AUTH";
443 case wxWEB_NAV_ERR_SECURITY
:
444 errorCategory
= "wxWEB_NAV_ERR_SECURITY";
447 case wxWEB_NAV_ERR_NOT_FOUND
:
448 errorCategory
= "wxWEB_NAV_ERR_NOT_FOUND";
451 case wxWEB_NAV_ERR_REQUEST
:
452 errorCategory
= "wxWEB_NAV_ERR_REQUEST";
455 case wxWEB_NAV_ERR_USER_CANCELLED
:
456 errorCategory
= "wxWEB_NAV_ERR_USER_CANCELLED";
459 case wxWEB_NAV_ERR_OTHER
:
460 errorCategory
= "wxWEB_NAV_ERR_OTHER";
464 wxLogMessage("Error; url='" + evt
.GetHref() + "', error='" + errorCategory
+ "' (" + evt
.GetString() + ")");
466 // show the notification panel
467 m_notification_text
->SetLabel(_("An error occurred loading ") + evt
.GetHref() + "\n" +
468 "'" + errorCategory
+ "' (" + evt
.GetString() + ")");
469 m_notification_panel
->Layout();
470 m_notification_panel
->GetSizer()->SetSizeHints(m_notification_panel
);
471 m_notification_panel
->Show();
478 * Invoked when user clicks "Hide" in the notification panel
480 void onHideNotifBar(wxCommandEvent
& evt
)
482 m_notification_panel
->Hide();
486 void onClose(wxCloseEvent
& evt
)
491 void onQuitMenu(wxCommandEvent
& evt
)
497 * Invoked when user selects "Print" from the menu
499 void onPrint(wxCommandEvent
& evt
)
501 m_browser_ctrl
->Print();
505 IMPLEMENT_APP(wxMiniApp
);
507 bool wxMiniApp::OnInit()
510 m_animation_angle
= 0;
512 frame
= new wxFrame( NULL
, -1, _("wxBetterHTMLControl Browser Example"), wxDefaultPosition
, wxSize(800, 600) );
514 // wx has a default mechanism to expand the only control of a frame; but since this mechanism
515 // does not involve sizers, invoking ->Layout on the frame does not udpate the layout which is
517 wxBoxSizer
* expandSizer
= new wxBoxSizer(wxHORIZONTAL
);
518 wxPanel
* mainpane
= new wxPanel(frame
, wxID_ANY
);
519 expandSizer
->Add(mainpane
, 1, wxEXPAND
);
520 frame
->SetSizer(expandSizer
);
522 wxLog::SetLogLevel(wxLOG_Max
);
523 logging
= new wxLogWindow(frame
, _("Logging"));
524 wxLog::SetLogLevel(wxLOG_Max
);
526 // ---- Create the Tools menu
527 toolsMenu
= new wxMenu();
528 wxMenuItem
* print
= toolsMenu
->Append(wxID_ANY
, _("Print"));
529 wxMenuItem
* viewSource
= toolsMenu
->Append(wxID_ANY
, _("View Source"));
530 toolsMenu
->AppendSeparator();
531 tinySize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Tiny"));
532 smallSize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Small"));
533 mediumSize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Medium"));
534 largeSize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Large"));
535 largestSize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Largest"));
536 //toolsMenu->AppendSeparator();
537 //offlineMode = toolsMenu->AppendCheckItem(wxID_ANY, _("Offline Mode"));
538 //onlineMode = toolsMenu->AppendCheckItem(wxID_ANY, _("Online Mode"));
540 // ---- Create the Toolbar
541 m_toolbar
= frame
->CreateToolBar(/*wxNO_BORDER |*/ wxTB_TEXT
);
542 m_toolbar
->SetToolBitmapSize(wxSize(32, 32));
544 back
= m_toolbar
->AddTool(wxID_ANY
, _("Back"), wxBitmap(back_xpm
));
545 forward
= m_toolbar
->AddTool(wxID_ANY
, _("Forward"), wxBitmap(forward_xpm
));
546 stop
= m_toolbar
->AddTool(wxID_ANY
, _("Stop"), wxBitmap(stop_xpm
));
547 reload
= m_toolbar
->AddTool(wxID_ANY
, _("Reload"), wxBitmap(refresh_xpm
));
549 url
= new wxTextCtrl(m_toolbar
, wxID_ANY
, wxT("http://www.google.com"),
550 wxDefaultPosition
, wxSize(400, -1), wxTE_PROCESS_ENTER
);
551 m_toolbar
->AddControl(url
, _("URL"));
552 tools
= m_toolbar
->AddTool(wxID_ANY
, _("Menu"), wxBitmap(wxlogo_xpm
));
553 //m_toolbar->SetDropdownMenu(tools->GetId(), toolsMenu);
555 m_toolbar
->Realize();
557 m_toolbar
->Connect(back
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
558 wxCommandEventHandler(wxMiniApp::onBack
), NULL
, this );
559 m_toolbar
->Connect(forward
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
560 wxCommandEventHandler(wxMiniApp::onForward
), NULL
, this );
561 m_toolbar
->Connect(stop
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
562 wxCommandEventHandler(wxMiniApp::onStop
), NULL
, this );
563 m_toolbar
->Connect(reload
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
564 wxCommandEventHandler(wxMiniApp::onReload
), NULL
, this );
565 m_toolbar
->Connect(tools
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
566 wxCommandEventHandler(wxMiniApp::onToolsClicked
), NULL
, this );
568 url
->Connect(url
->GetId(), wxEVT_COMMAND_TEXT_ENTER
, wxCommandEventHandler(wxMiniApp::onUrl
), NULL
, this );
571 frame
->Connect(viewSource
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
572 wxCommandEventHandler(wxMiniApp::onViewSourceRequest
), NULL
, this );
573 frame
->Connect(print
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
574 wxCommandEventHandler(wxMiniApp::onPrint
), NULL
, this );
576 frame
->Connect(tinySize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
577 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
578 frame
->Connect(smallSize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
579 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
580 frame
->Connect(mediumSize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
581 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
582 frame
->Connect(largeSize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
583 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
584 frame
->Connect(largestSize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
585 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
587 // ---- Create the web view
588 m_browser_ctrl
= wxWebView::New(mainpane
, wxID_ANY
);
590 // ---- Create the notification panel
592 wxBoxSizer
* notification_sizer
= new wxBoxSizer(wxHORIZONTAL
);
593 m_notification_panel
= new wxPanel(mainpane
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, wxBORDER_SIMPLE
);
594 m_notification_text
= new wxStaticText(m_notification_panel
, wxID_ANY
, "[No message]");
595 notification_sizer
->Add( new wxStaticBitmap(m_notification_panel
, wxID_ANY
,
596 wxArtProvider::GetBitmap(wxART_WARNING
, wxART_OTHER
, wxSize(48, 48))),
597 0, wxALIGN_CENTER_VERTICAL
| wxALL
, 5 );
598 notification_sizer
->Add(m_notification_text
, 1, wxEXPAND
| wxALIGN_CENTER_VERTICAL
| wxALL
, 5);
599 wxButton
* hideNotif
= new wxButton(m_notification_panel
, wxID_ANY
, _("Hide"));
600 notification_sizer
->Add(hideNotif
, 0, wxALIGN_CENTER_VERTICAL
| wxALL
, 5);
601 m_notification_panel
->SetSizer(notification_sizer
);
602 m_notification_panel
->SetBackgroundColour(wxColor(255,225,110));
603 m_notification_panel
->Hide();
604 hideNotif
->Connect(hideNotif
->GetId(), wxEVT_COMMAND_BUTTON_CLICKED
,
605 wxCommandEventHandler(wxMiniApp::onHideNotifBar
), NULL
, this);
608 wxBoxSizer
* sizer
= new wxBoxSizer(wxVERTICAL
);
609 sizer
->Add(m_notification_panel
, 0, wxEXPAND
| wxALL
, 5);
610 sizer
->Add(m_browser_ctrl
, 1, wxEXPAND
| wxALL
, 5);
612 mainpane
->SetSizer(sizer
);
617 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_NAVIGATING
,
618 wxWebNavigationEventHandler(wxMiniApp::onNavigationRequest
), NULL
, this);
620 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_NAVIGATED
,
621 wxWebNavigationEventHandler(wxMiniApp::onNavigationComplete
), NULL
, this);
623 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_LOADED
,
624 wxWebNavigationEventHandler(wxMiniApp::onDocumentLoaded
), NULL
, this);
626 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_ERROR
,
627 wxWebNavigationEventHandler(wxMiniApp::onError
), NULL
, this);
629 frame
->Connect(wxEVT_CLOSE_WINDOW
, wxCloseEventHandler(wxMiniApp::onClose
), NULL
, this);
630 Connect(wxID_EXIT
, wxEVT_COMMAND_MENU_SELECTED
, wxCommandEventHandler(wxMiniApp::onQuitMenu
), NULL
, this);
632 // You can test different zoom types (if supported by the backend)
633 // if (m_browser_ctrl->CanSetZoomType(wxWEB_VIEW_ZOOM_TYPE_LAYOUT))
634 // m_browser_ctrl->SetZoomType(wxWEB_VIEW_ZOOM_TYPE_LAYOUT);