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 tinySize
->Check(false);
324 smallSize
->Check(false);
325 mediumSize
->Check(false);
326 largeSize
->Check(false);
327 largestSize
->Check(false);
329 wxWebViewZoom zoom
= m_browser_ctrl
->GetZoom();
332 case wxWEB_VIEW_ZOOM_TINY
:
335 case wxWEB_VIEW_ZOOM_SMALL
:
338 case wxWEB_VIEW_ZOOM_MEDIUM
:
341 case wxWEB_VIEW_ZOOM_LARGE
:
344 case wxWEB_VIEW_ZOOM_LARGEST
:
345 largestSize
->Check();
349 // bool IsOfflineMode();
350 // void SetOfflineMode(bool offline);
352 //offlineMode->Check(false);
353 //onlineMode->Check(false);
354 //const bool offline = m_browser_ctrl->IsOfflineMode();
355 //if (offline) offlineMode->Check();
356 //else onlineMode->Check();
358 wxPoint position
= frame
->ScreenToClient( wxGetMousePosition() );
359 frame
->PopupMenu(toolsMenu
, position
.x
, position
.y
);
363 * Invoked when user selects the zoom size in the menu
365 void onSetZoom(wxCommandEvent
& evt
)
367 if (evt
.GetId() == tinySize
->GetId())
369 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_TINY
);
371 else if (evt
.GetId() == smallSize
->GetId())
373 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_SMALL
);
375 else if (evt
.GetId() == mediumSize
->GetId())
377 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_MEDIUM
);
379 else if (evt
.GetId() == largeSize
->GetId())
381 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_LARGE
);
383 else if (evt
.GetId() == largestSize
->GetId())
385 m_browser_ctrl
->SetZoom(wxWEB_VIEW_ZOOM_LARGEST
);
394 void onChangeOnlineMode(wxCommandEvent& evt)
396 if (evt.GetId() == offlineMode->GetId())
398 m_browser_ctrl->SetOfflineMode(true);
399 m_browser_ctrl->SetPage("<html><body><h1>You are now in offline mode.</h1></body></html>");
401 else if (evt.GetId() == onlineMode->GetId())
403 m_browser_ctrl->SetOfflineMode(false);
413 * Callback invoked when a loading error occurs
415 void onError(wxWebNavigationEvent
& evt
)
417 wxString errorCategory
;
418 switch (evt
.GetInt())
420 case wxWEB_NAV_ERR_CONNECTION
:
421 errorCategory
= "wxWEB_NAV_ERR_CONNECTION";
424 case wxWEB_NAV_ERR_CERTIFICATE
:
425 errorCategory
= "wxWEB_NAV_ERR_CERTIFICATE";
428 case wxWEB_NAV_ERR_AUTH
:
429 errorCategory
= "wxWEB_NAV_ERR_AUTH";
432 case wxWEB_NAV_ERR_SECURITY
:
433 errorCategory
= "wxWEB_NAV_ERR_SECURITY";
436 case wxWEB_NAV_ERR_NOT_FOUND
:
437 errorCategory
= "wxWEB_NAV_ERR_NOT_FOUND";
440 case wxWEB_NAV_ERR_REQUEST
:
441 errorCategory
= "wxWEB_NAV_ERR_REQUEST";
444 case wxWEB_NAV_ERR_USER_CANCELLED
:
445 errorCategory
= "wxWEB_NAV_ERR_USER_CANCELLED";
448 case wxWEB_NAV_ERR_OTHER
:
449 errorCategory
= "wxWEB_NAV_ERR_OTHER";
453 wxLogMessage("Error; url='" + evt
.GetHref() + "', error='" + errorCategory
+ "' (" + evt
.GetString() + ")");
455 // show the notification panel
456 m_notification_text
->SetLabel(_("An error occurred loading ") + evt
.GetHref() + "\n" +
457 "'" + errorCategory
+ "' (" + evt
.GetString() + ")");
458 m_notification_panel
->Layout();
459 m_notification_panel
->GetSizer()->SetSizeHints(m_notification_panel
);
460 m_notification_panel
->Show();
467 * Invoked when user clicks "Hide" in the notification panel
469 void onHideNotifBar(wxCommandEvent
& evt
)
471 m_notification_panel
->Hide();
475 void onClose(wxCloseEvent
& evt
)
480 void onQuitMenu(wxCommandEvent
& evt
)
486 * Invoked when user selects "Print" from the menu
488 void onPrint(wxCommandEvent
& evt
)
490 m_browser_ctrl
->Print();
494 IMPLEMENT_APP(wxMiniApp
);
496 bool wxMiniApp::OnInit()
499 m_animation_angle
= 0;
501 frame
= new wxFrame( NULL
, -1, _("wxBetterHTMLControl Browser Example"), wxDefaultPosition
, wxSize(800, 600) );
503 // wx has a default mechanism to expand the only control of a frame; but since this mechanism
504 // does not involve sizers, invoking ->Layout on the frame does not udpate the layout which is
506 wxBoxSizer
* expandSizer
= new wxBoxSizer(wxHORIZONTAL
);
507 wxPanel
* mainpane
= new wxPanel(frame
, wxID_ANY
);
508 expandSizer
->Add(mainpane
, 1, wxEXPAND
);
509 frame
->SetSizer(expandSizer
);
511 wxLog::SetLogLevel(wxLOG_Max
);
512 logging
= new wxLogWindow(frame
, _("Logging"));
513 wxLog::SetLogLevel(wxLOG_Max
);
515 // ---- Create the Tools menu
516 toolsMenu
= new wxMenu();
517 wxMenuItem
* print
= toolsMenu
->Append(wxID_ANY
, _("Print"));
518 wxMenuItem
* viewSource
= toolsMenu
->Append(wxID_ANY
, _("View Source"));
519 toolsMenu
->AppendSeparator();
520 tinySize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Tiny"));
521 smallSize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Small"));
522 mediumSize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Medium"));
523 largeSize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Large"));
524 largestSize
= toolsMenu
->AppendCheckItem(wxID_ANY
, _("Largest"));
525 //toolsMenu->AppendSeparator();
526 //offlineMode = toolsMenu->AppendCheckItem(wxID_ANY, _("Offline Mode"));
527 //onlineMode = toolsMenu->AppendCheckItem(wxID_ANY, _("Online Mode"));
529 // ---- Create the Toolbar
530 m_toolbar
= frame
->CreateToolBar(/*wxNO_BORDER |*/ wxTB_TEXT
);
531 m_toolbar
->SetToolBitmapSize(wxSize(32, 32));
533 back
= m_toolbar
->AddTool(wxID_ANY
, _("Back"), wxBitmap(back_xpm
));
534 forward
= m_toolbar
->AddTool(wxID_ANY
, _("Forward"), wxBitmap(forward_xpm
));
535 stop
= m_toolbar
->AddTool(wxID_ANY
, _("Stop"), wxBitmap(stop_xpm
));
536 reload
= m_toolbar
->AddTool(wxID_ANY
, _("Reload"), wxBitmap(refresh_xpm
));
538 url
= new wxTextCtrl(m_toolbar
, wxID_ANY
, wxT("http://www.google.com"),
539 wxDefaultPosition
, wxSize(400, -1), wxTE_PROCESS_ENTER
);
540 m_toolbar
->AddControl(url
, _("URL"));
541 tools
= m_toolbar
->AddTool(wxID_ANY
, _("Menu"), wxBitmap(wxlogo_xpm
));
542 //m_toolbar->SetDropdownMenu(tools->GetId(), toolsMenu);
544 m_toolbar
->Realize();
546 m_toolbar
->Connect(back
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
547 wxCommandEventHandler(wxMiniApp::onBack
), NULL
, this );
548 m_toolbar
->Connect(forward
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
549 wxCommandEventHandler(wxMiniApp::onForward
), NULL
, this );
550 m_toolbar
->Connect(stop
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
551 wxCommandEventHandler(wxMiniApp::onStop
), NULL
, this );
552 m_toolbar
->Connect(reload
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
553 wxCommandEventHandler(wxMiniApp::onReload
), NULL
, this );
554 m_toolbar
->Connect(tools
->GetId(), wxEVT_COMMAND_TOOL_CLICKED
,
555 wxCommandEventHandler(wxMiniApp::onToolsClicked
), NULL
, this );
557 url
->Connect(url
->GetId(), wxEVT_COMMAND_TEXT_ENTER
, wxCommandEventHandler(wxMiniApp::onUrl
), NULL
, this );
560 frame
->Connect(viewSource
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
561 wxCommandEventHandler(wxMiniApp::onViewSourceRequest
), NULL
, this );
562 frame
->Connect(print
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
563 wxCommandEventHandler(wxMiniApp::onPrint
), NULL
, this );
565 frame
->Connect(tinySize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
566 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
567 frame
->Connect(smallSize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
568 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
569 frame
->Connect(mediumSize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
570 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
571 frame
->Connect(largeSize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
572 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
573 frame
->Connect(largestSize
->GetId(), wxEVT_COMMAND_MENU_SELECTED
,
574 wxCommandEventHandler(wxMiniApp::onSetZoom
), NULL
, this );
576 // ---- Create the web view
577 m_browser_ctrl
= wxWebView::New(mainpane
, wxID_ANY
);
579 // ---- Create the notification panel
581 wxBoxSizer
* notification_sizer
= new wxBoxSizer(wxHORIZONTAL
);
582 m_notification_panel
= new wxPanel(mainpane
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, wxBORDER_SIMPLE
);
583 m_notification_text
= new wxStaticText(m_notification_panel
, wxID_ANY
, "[No message]");
584 notification_sizer
->Add( new wxStaticBitmap(m_notification_panel
, wxID_ANY
,
585 wxArtProvider::GetBitmap(wxART_WARNING
, wxART_OTHER
, wxSize(48, 48))),
586 0, wxALIGN_CENTER_VERTICAL
| wxALL
, 5 );
587 notification_sizer
->Add(m_notification_text
, 1, wxEXPAND
| wxALIGN_CENTER_VERTICAL
| wxALL
, 5);
588 wxButton
* hideNotif
= new wxButton(m_notification_panel
, wxID_ANY
, _("Hide"));
589 notification_sizer
->Add(hideNotif
, 0, wxALIGN_CENTER_VERTICAL
| wxALL
, 5);
590 m_notification_panel
->SetSizer(notification_sizer
);
591 m_notification_panel
->SetBackgroundColour(wxColor(255,225,110));
592 m_notification_panel
->Hide();
593 hideNotif
->Connect(hideNotif
->GetId(), wxEVT_COMMAND_BUTTON_CLICKED
,
594 wxCommandEventHandler(wxMiniApp::onHideNotifBar
), NULL
, this);
597 wxBoxSizer
* sizer
= new wxBoxSizer(wxVERTICAL
);
598 sizer
->Add(m_notification_panel
, 0, wxEXPAND
| wxALL
, 5);
599 sizer
->Add(m_browser_ctrl
, 1, wxEXPAND
| wxALL
, 5);
601 mainpane
->SetSizer(sizer
);
606 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_NAVIGATING
,
607 wxWebNavigationEventHandler(wxMiniApp::onNavigationRequest
), NULL
, this);
609 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_NAVIGATED
,
610 wxWebNavigationEventHandler(wxMiniApp::onNavigationComplete
), NULL
, this);
612 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_LOADED
,
613 wxWebNavigationEventHandler(wxMiniApp::onDocumentLoaded
), NULL
, this);
615 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_ERROR
,
616 wxWebNavigationEventHandler(wxMiniApp::onError
), NULL
, this);
618 m_browser_ctrl
->Connect(m_browser_ctrl
->GetId(), wxEVT_COMMAND_WEB_VIEW_NEWWINDOW
,
619 wxWebNavigationEventHandler(wxMiniApp::onNewWindow
), NULL
, this);
621 frame
->Connect(wxEVT_CLOSE_WINDOW
, wxCloseEventHandler(wxMiniApp::onClose
), NULL
, this);
622 Connect(wxID_EXIT
, wxEVT_COMMAND_MENU_SELECTED
, wxCommandEventHandler(wxMiniApp::onQuitMenu
), NULL
, this);
624 // You can test different zoom types (if supported by the backend)
625 // if (m_browser_ctrl->CanSetZoomType(wxWEB_VIEW_ZOOM_TYPE_LAYOUT))
626 // m_browser_ctrl->SetZoomType(wxWEB_VIEW_ZOOM_TYPE_LAYOUT);