X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/5f73281084be22f97026ff356dfbed0ff1e4956f..4d623b67ee74794fbeba5805a269433d030c67d5:/samples/htlbox/htlbox.cpp diff --git a/samples/htlbox/htlbox.cpp b/samples/htlbox/htlbox.cpp index adae3ed978..94a17e5112 100644 --- a/samples/htlbox/htlbox.cpp +++ b/samples/htlbox/htlbox.cpp @@ -1,11 +1,11 @@ ///////////////////////////////////////////////////////////////////////////// // Name: htmllbox.cpp -// Purpose: HtmlLbox wxWindows sample +// Purpose: HtmlLbox wxWidgets sample // Author: Vadim Zeitlin // Modified by: // Created: 31.05.03 // RCS-ID: $Id$ -// Copyright: (c) 2003 Vadim Zeitlin +// Copyright: (c) 2003 Vadim Zeitlin // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -37,8 +37,12 @@ #include "wx/textctrl.h" #include "wx/dc.h" + #include "wx/icon.h" #endif +#include "wx/colordlg.h" +#include "wx/numdlg.h" + #include "wx/htmllbox.h" // you can also have a file containing HTML strings for testing, enable this if @@ -48,14 +52,7 @@ #include "wx/textfile.h" #endif -// ---------------------------------------------------------------------------- -// resources -// ---------------------------------------------------------------------------- - -// the application icon (under Windows and OS/2 it is in resources) -#if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__) || defined(__WXX11__) - #include "mondrian.xpm" -#endif +#include "../sample.xpm" // ---------------------------------------------------------------------------- // private classes @@ -66,58 +63,43 @@ class MyHtmlListBox : public wxHtmlListBox { public: - MyHtmlListBox(wxWindow *parent, bool multi = false) - : wxHtmlListBox(parent, -1, wxDefaultPosition, wxDefaultSize, - multi ? wxLB_MULTIPLE : 0) - { - SetMargins(5, 5); + MyHtmlListBox() { } + MyHtmlListBox(wxWindow *parent, bool multi = false); -#ifdef USE_HTML_FILE - if ( !m_file.Open("results") ) - { - wxLogError("Failed to open results file"); - } - else - { - SetItemCount(m_file.GetLineCount()); - } -#else - SetItemCount(10); -#endif - - if ( HasMultipleSelection() ) - Select(3); - else - SetSelection(3); - } + void SetChangeSelFg(bool change) { m_change = change; } + void UpdateFirstItem(); protected: - virtual wxString OnGetItem(size_t n) const - { -#ifdef USE_HTML_FILE - wxString s; - if ( m_file.IsOpened() ) - s = m_file[n]; - - return s; -#else - int level = n % 6 + 1; - return wxString::Format(_T("") - _T("Item %lu") - _T(""), - level, - abs(n - 192) % 256, - abs(n - 256) % 256, - abs(n - 128) % 256, - (unsigned long)n, level); -#endif - } + // override this method to return data to be shown in the listbox (this is + // mandatory) + virtual wxString OnGetItem(size_t n) const; + // change the appearance by overriding these functions (this is optional) virtual void OnDrawSeparator(wxDC& dc, wxRect& rect, size_t n) const; + virtual wxColour GetSelectedTextColour(const wxColour& colFg) const; + + // flag telling us whether we should use fg colour even for the selected + // item + bool m_change; + + // flag which we toggle to update the first items text in OnGetItem() + bool m_firstItemUpdated; + +public: + + // flag which we toggle when the user clicks on the link in 2nd item + // to change 2nd item's text + bool m_linkClicked; +#ifdef USE_HTML_FILE wxTextFile m_file; +#endif + + wxDECLARE_NO_COPY_CLASS(MyHtmlListBox); + DECLARE_DYNAMIC_CLASS(MyHtmlListBox) }; + class MyFrame : public wxFrame { public: @@ -125,6 +107,7 @@ public: virtual ~MyFrame(); // event handlers + void OnSimpleOrCustomBox(wxCommandEvent& event); void OnQuit(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); @@ -132,26 +115,45 @@ public: void OnDrawSeparator(wxCommandEvent&) { m_hlbox->RefreshAll(); } void OnToggleMulti(wxCommandEvent& event); void OnSelectAll(wxCommandEvent& event); + void OnUpdateItem(wxCommandEvent& event); + void OnGetItemRect(wxCommandEvent& event); + + void OnSetBgCol(wxCommandEvent& event); + void OnSetSelBgCol(wxCommandEvent& event); + void OnSetSelFgCol(wxCommandEvent& event); + + void OnClear(wxCommandEvent& event); void OnUpdateUISelectAll(wxUpdateUIEvent& event); void OnLboxSelect(wxCommandEvent& event); void OnLboxDClick(wxCommandEvent& event) { - wxLogMessage(_T("Listbox item %ld double clicked."), event.GetInt()); + wxLogMessage(wxT("Listbox item %d double clicked."), event.GetInt()); } + void OnHtmlLinkClicked(wxHtmlLinkEvent& event); + void OnHtmlCellHover(wxHtmlCellEvent &event); + void OnHtmlCellClicked(wxHtmlCellEvent &event); + + wxSimpleHtmlListBox *GetSimpleBox() + { return wxDynamicCast(m_hlbox, wxSimpleHtmlListBox); } + MyHtmlListBox *GetMyBox() + { return wxDynamicCast(m_hlbox, MyHtmlListBox); } + + void CreateBox(); + private: - MyHtmlListBox *m_hlbox; + wxHtmlListBox *m_hlbox; - // any class wishing to process wxWindows events must use this macro + // any class wishing to process wxWidgets events must use this macro DECLARE_EVENT_TABLE() }; class MyApp : public wxApp { public: - virtual bool OnInit() { (new MyFrame())->Show(); return TRUE; } + virtual bool OnInit() { (new MyFrame())->Show(); return true; } }; // ---------------------------------------------------------------------------- @@ -162,12 +164,22 @@ public: enum { // menu items - HtmlLbox_Quit = 1, + HtmlLbox_CustomBox = 1, + HtmlLbox_SimpleBox, + HtmlLbox_Quit, HtmlLbox_SetMargins, HtmlLbox_DrawSeparator, HtmlLbox_ToggleMulti, HtmlLbox_SelectAll, + HtmlLbox_UpdateItem, + HtmlLbox_GetItemRect, + + HtmlLbox_SetBgCol, + HtmlLbox_SetSelBgCol, + HtmlLbox_SetSelFgCol, + + HtmlLbox_Clear, // it is important for the id corresponding to the "About" command to have // this standard value as otherwise it won't be handled properly under Mac @@ -176,25 +188,41 @@ enum }; // ---------------------------------------------------------------------------- -// event tables and other macros for wxWindows +// event tables and other macros for wxWidgets // ---------------------------------------------------------------------------- BEGIN_EVENT_TABLE(MyFrame, wxFrame) + EVT_MENU(HtmlLbox_CustomBox, MyFrame::OnSimpleOrCustomBox) + EVT_MENU(HtmlLbox_SimpleBox, MyFrame::OnSimpleOrCustomBox) EVT_MENU(HtmlLbox_Quit, MyFrame::OnQuit) EVT_MENU(HtmlLbox_SetMargins, MyFrame::OnSetMargins) EVT_MENU(HtmlLbox_DrawSeparator, MyFrame::OnDrawSeparator) EVT_MENU(HtmlLbox_ToggleMulti, MyFrame::OnToggleMulti) EVT_MENU(HtmlLbox_SelectAll, MyFrame::OnSelectAll) + EVT_MENU(HtmlLbox_UpdateItem, MyFrame::OnUpdateItem) + EVT_MENU(HtmlLbox_GetItemRect, MyFrame::OnGetItemRect) EVT_MENU(HtmlLbox_About, MyFrame::OnAbout) + EVT_MENU(HtmlLbox_SetBgCol, MyFrame::OnSetBgCol) + EVT_MENU(HtmlLbox_SetSelBgCol, MyFrame::OnSetSelBgCol) + EVT_MENU(HtmlLbox_SetSelFgCol, MyFrame::OnSetSelFgCol) + + EVT_MENU(HtmlLbox_Clear, MyFrame::OnClear) EVT_UPDATE_UI(HtmlLbox_SelectAll, MyFrame::OnUpdateUISelectAll) EVT_LISTBOX(wxID_ANY, MyFrame::OnLboxSelect) EVT_LISTBOX_DCLICK(wxID_ANY, MyFrame::OnLboxDClick) + + + // the HTML listbox's events + EVT_HTML_LINK_CLICKED(wxID_ANY, MyFrame::OnHtmlLinkClicked) + EVT_HTML_CELL_HOVER(wxID_ANY, MyFrame::OnHtmlCellHover) + EVT_HTML_CELL_CLICKED(wxID_ANY, MyFrame::OnHtmlCellClicked) + END_EVENT_TABLE() IMPLEMENT_APP(MyApp) @@ -209,41 +237,57 @@ IMPLEMENT_APP(MyApp) // frame constructor MyFrame::MyFrame() - : wxFrame(NULL, -1, _T("HtmlLbox wxWindows Sample"), - wxDefaultPosition, wxSize(400, 500)) + : wxFrame(NULL, wxID_ANY, wxT("HtmlLbox wxWidgets Sample"), + wxDefaultPosition, wxSize(500, 500)) { // set the frame icon - SetIcon(wxICON(mondrian)); + SetIcon(wxICON(sample)); #if wxUSE_MENUS // create a menu bar wxMenu *menuFile = new wxMenu; - menuFile->Append(HtmlLbox_Quit, _T("E&xit\tAlt-X"), _T("Quit this program")); + menuFile->AppendRadioItem(HtmlLbox_CustomBox, wxT("Use custom box"), + wxT("Use a wxHtmlListBox virtual class control")); + menuFile->AppendRadioItem(HtmlLbox_SimpleBox, wxT("Use simple box"), + wxT("Use a wxSimpleHtmlListBox control")); + menuFile->AppendSeparator(); + menuFile->Append(HtmlLbox_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program")); // create our specific menu wxMenu *menuHLbox = new wxMenu; menuHLbox->Append(HtmlLbox_SetMargins, - _T("Set &margins...\tCtrl-G"), - _T("Change the margins around the items")); + wxT("Set &margins...\tCtrl-G"), + wxT("Change the margins around the items")); menuHLbox->AppendCheckItem(HtmlLbox_DrawSeparator, - _T("Draw &separators\tCtrl-S"), - _T("Toggle drawing separators between cells")); + wxT("&Draw separators\tCtrl-D"), + wxT("Toggle drawing separators between cells")); menuHLbox->AppendSeparator(); menuHLbox->AppendCheckItem(HtmlLbox_ToggleMulti, - _T("&Multiple selection\tCtrl-M"), - _T("Toggle multiple selection on/off")); + wxT("&Multiple selection\tCtrl-M"), + wxT("Toggle multiple selection on/off")); + menuHLbox->AppendSeparator(); + menuHLbox->Append(HtmlLbox_SelectAll, wxT("Select &all items\tCtrl-A")); + menuHLbox->Append(HtmlLbox_UpdateItem, wxT("Update &first item\tCtrl-U")); + menuHLbox->Append(HtmlLbox_GetItemRect, wxT("Show &rectangle of item #10\tCtrl-R")); menuHLbox->AppendSeparator(); - menuHLbox->Append(HtmlLbox_SelectAll, _T("Select &all items\tCtrl-A")); + menuHLbox->Append(HtmlLbox_SetBgCol, wxT("Set &background...\tCtrl-B")); + menuHLbox->Append(HtmlLbox_SetSelBgCol, + wxT("Set &selection background...\tCtrl-S")); + menuHLbox->AppendCheckItem(HtmlLbox_SetSelFgCol, + wxT("Keep &foreground in selection\tCtrl-F")); + + menuHLbox->AppendSeparator(); + menuHLbox->Append(HtmlLbox_Clear, wxT("&Clear\tCtrl-L")); // the "About" item should be in the help menu wxMenu *helpMenu = new wxMenu; - helpMenu->Append(HtmlLbox_About, _T("&About...\tF1"), _T("Show about dialog")); + helpMenu->Append(HtmlLbox_About, wxT("&About\tF1"), wxT("Show about dialog")); // now append the freshly created menu to the menu bar... wxMenuBar *menuBar = new wxMenuBar(); - menuBar->Append(menuFile, _T("&File")); - menuBar->Append(menuHLbox, _T("&Listbox")); - menuBar->Append(helpMenu, _T("&Help")); + menuBar->Append(menuFile, wxT("&File")); + menuBar->Append(menuHLbox, wxT("&Listbox")); + menuBar->Append(helpMenu, wxT("&Help")); menuBar->Check(HtmlLbox_DrawSeparator, true); @@ -254,20 +298,20 @@ MyFrame::MyFrame() #if wxUSE_STATUSBAR // create a status bar just for fun (by default with 1 pane only) CreateStatusBar(2); - SetStatusText(_T("Welcome to wxWindows!")); + SetStatusText(wxT("Welcome to wxWidgets!")); #endif // wxUSE_STATUSBAR // create the child controls - m_hlbox = new MyHtmlListBox(this); - wxTextCtrl *text = new wxTextCtrl(this, -1, _T(""), + CreateBox(); + wxTextCtrl *text = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); delete wxLog::SetActiveTarget(new wxLogTextCtrl(text)); // and lay them out wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(m_hlbox, 1, wxGROW); - sizer->Add(text, 1, wxGROW); + sizer->Add(m_hlbox, 2, wxGROW); + sizer->Add(text, 3, wxGROW); SetSizer(sizer); } @@ -277,33 +321,84 @@ MyFrame::~MyFrame() delete wxLog::SetActiveTarget(NULL); } +void MyFrame::CreateBox() +{ + bool multi = GetMenuBar()->IsChecked(HtmlLbox_ToggleMulti); + + if ( GetMenuBar()->IsChecked(HtmlLbox_CustomBox) ) + { + m_hlbox = new MyHtmlListBox(this, multi); + } + else // simple listbox + { + m_hlbox = new wxSimpleHtmlListBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, + 0, NULL, multi ? wxLB_MULTIPLE : 0); + + // unlike wxHtmlListBox which is abstract, wxSimpleHtmlListBox is a + // concrete control and doesn't support virtual mode, this we need + // to add all of its items from the beginning + wxArrayString arr; + for (size_t n = 0; n < 1000; n++ ) + { + wxColour clr((unsigned char)(abs((int)n - 192) % 256), + (unsigned char)(abs((int)n - 256) % 256), + (unsigned char)(abs((int)n - 128) % 256)); + int level = n % 6 + 1; + + wxString label = wxString::Format(wxT("") + wxT("Item %lu") + wxT(""), + level, + clr.GetAsString(wxC2S_HTML_SYNTAX).c_str(), + (unsigned long)n, level); + arr.Add(label); + } + + GetSimpleBox()->Append(arr); + } +} + + // ---------------------------------------------------------------------------- // menu event handlers // ---------------------------------------------------------------------------- +void MyFrame::OnSimpleOrCustomBox(wxCommandEvent& WXUNUSED(event)) +{ + wxWindow *old = m_hlbox; + + // we need to recreate the listbox + CreateBox(); + GetSizer()->Replace(old, m_hlbox); + delete old; + + GetSizer()->Layout(); + Refresh(); +} + void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) { - // TRUE is to force the frame to close - Close(TRUE); + // true is to force the frame to close + Close(true); } void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) { - wxMessageBox(_T("This sample shows wxHtmlListBox class.\n") - _T("\n") - _T("© 2003 Vadim Zeitlin"), - _T("About HtmlLbox"), + wxMessageBox(wxT("This sample shows wxHtmlListBox class.\n") + wxT("\n") + wxT("(c) 2003 Vadim Zeitlin"), + wxT("About HtmlLbox"), wxOK | wxICON_INFORMATION, this); } -void MyFrame::OnSetMargins(wxCommandEvent&) +void MyFrame::OnSetMargins(wxCommandEvent& WXUNUSED(event)) { long margin = wxGetNumberFromUser ( - _T("Enter the margins to use for the listbox items."), - _T("Margin: "), - _T("HtmlLbox: Set the margins"), + wxT("Enter the margins to use for the listbox items."), + wxT("Margin: "), + wxT("HtmlLbox: Set the margins"), 0, 0, 20, this ); @@ -315,22 +410,21 @@ void MyFrame::OnSetMargins(wxCommandEvent&) } } -void MyFrame::OnToggleMulti(wxCommandEvent& event) +void MyFrame::OnToggleMulti(wxCommandEvent& WXUNUSED(event)) { - // we need to recreate the listbox - wxSizer *sizer = GetSizer(); - sizer->Detach(m_hlbox); - delete m_hlbox; + wxWindow *old = m_hlbox; - m_hlbox = new MyHtmlListBox(this, event.IsChecked()); - sizer->Prepend(m_hlbox, 1, wxGROW); + // we need to recreate the listbox + CreateBox(); + GetSizer()->Replace(old, m_hlbox); + delete old; - sizer->Layout(); + GetSizer()->Layout(); } -void MyFrame::OnSelectAll(wxCommandEvent& event) +void MyFrame::OnSelectAll(wxCommandEvent& WXUNUSED(event)) { - m_hlbox->SelectRange(0, m_hlbox->GetItemCount() - 1); + m_hlbox->SelectAll(); } void MyFrame::OnUpdateUISelectAll(wxUpdateUIEvent& event) @@ -338,13 +432,95 @@ void MyFrame::OnUpdateUISelectAll(wxUpdateUIEvent& event) event.Enable( m_hlbox && m_hlbox->HasMultipleSelection() ); } +void MyFrame::OnUpdateItem(wxCommandEvent& WXUNUSED(event)) +{ + if (GetMyBox()) + GetMyBox()->UpdateFirstItem(); +} + +void MyFrame::OnGetItemRect(wxCommandEvent& WXUNUSED(event)) +{ + static const int ITEM = 10; + const wxRect r = m_hlbox->GetItemRect(ITEM); + wxLogMessage("Rect of item %d: (%d, %d)-(%d, %d)", + ITEM, r.x, r.y, r.x + r.width, r.y + r.height); +} + +void MyFrame::OnSetBgCol(wxCommandEvent& WXUNUSED(event)) +{ + wxColour col = wxGetColourFromUser(this, m_hlbox->GetBackgroundColour()); + if ( col.IsOk() ) + { + m_hlbox->SetBackgroundColour(col); + m_hlbox->Refresh(); + +#if wxUSE_STATUSBAR + SetStatusText(wxT("Background colour changed.")); +#endif // wxUSE_STATUSBAR + } +} + +void MyFrame::OnSetSelBgCol(wxCommandEvent& WXUNUSED(event)) +{ + wxColour col = wxGetColourFromUser(this, m_hlbox->GetSelectionBackground()); + if ( col.IsOk() ) + { + m_hlbox->SetSelectionBackground(col); + m_hlbox->Refresh(); + +#if wxUSE_STATUSBAR + SetStatusText(wxT("Selection background colour changed.")); +#endif // wxUSE_STATUSBAR + } +} + +void MyFrame::OnSetSelFgCol(wxCommandEvent& event) +{ + if (GetMyBox()) + { + GetMyBox()->SetChangeSelFg(!event.IsChecked()); + GetMyBox()->Refresh(); + } +} + +void MyFrame::OnClear(wxCommandEvent& WXUNUSED(event)) +{ + m_hlbox->Clear(); +} + +void MyFrame::OnHtmlLinkClicked(wxHtmlLinkEvent &event) +{ + wxLogMessage(wxT("The url '%s' has been clicked!"), event.GetLinkInfo().GetHref().c_str()); + + if (GetMyBox()) + { + GetMyBox()->m_linkClicked = true; + GetMyBox()->RefreshRow(1); + } +} + +void MyFrame::OnHtmlCellHover(wxHtmlCellEvent &event) +{ + wxLogMessage(wxT("Mouse moved over cell %p at %d;%d"), + event.GetCell(), event.GetPoint().x, event.GetPoint().y); +} + +void MyFrame::OnHtmlCellClicked(wxHtmlCellEvent &event) +{ + wxLogMessage(wxT("Click over cell %p at %d;%d"), + event.GetCell(), event.GetPoint().x, event.GetPoint().y); + + // if we don't skip the event, OnHtmlLinkClicked won't be called! + event.Skip(); +} + // ---------------------------------------------------------------------------- // listbox event handlers // ---------------------------------------------------------------------------- void MyFrame::OnLboxSelect(wxCommandEvent& event) { - wxLogMessage(_T("Listbox selection is now %ld."), event.GetInt()); + wxLogMessage(wxT("Listbox selection is now %d."), event.GetInt()); if ( m_hlbox->HasMultipleSelection() ) { @@ -359,25 +535,58 @@ void MyFrame::OnLboxSelect(wxCommandEvent& event) if ( first ) first = false; else - s << _T(", "); + s << wxT(", "); s << item; } if ( !s.empty() ) - wxLogMessage(_T("Selected items: %s"), s.c_str()); + { + wxLogMessage(wxT("Selected items: %s"), s.c_str()); + } } +#if wxUSE_STATUSBAR SetStatusText(wxString::Format( - _T("# items selected = %lu"), + wxT("# items selected = %lu"), (unsigned long)m_hlbox->GetSelectedCount() )); +#endif // wxUSE_STATUSBAR } // ============================================================================ // MyHtmlListBox // ============================================================================ +IMPLEMENT_DYNAMIC_CLASS(MyHtmlListBox, wxHtmlListBox) + +MyHtmlListBox::MyHtmlListBox(wxWindow *parent, bool multi) + : wxHtmlListBox(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, + multi ? wxLB_MULTIPLE : 0) +{ + m_change = true; + m_firstItemUpdated = false; + m_linkClicked = false; + + + SetMargins(5, 5); + +#ifdef USE_HTML_FILE + if ( !m_file.Open(wxT("results")) ) + { + wxLogError(wxT("Failed to open results file")); + } + else + { + SetItemCount(m_file.GetLineCount()); + } +#else + SetItemCount(1000); +#endif + + SetSelection(3); +} + void MyHtmlListBox::OnDrawSeparator(wxDC& dc, wxRect& rect, size_t) const { if ( ((MyFrame *)GetParent())-> @@ -389,3 +598,52 @@ void MyHtmlListBox::OnDrawSeparator(wxDC& dc, wxRect& rect, size_t) const } } +wxString MyHtmlListBox::OnGetItem(size_t n) const +{ + if ( !n && m_firstItemUpdated ) + { + return wxT("

Just updated

"); + } + +#ifdef USE_HTML_FILE + wxString s; + if ( m_file.IsOpened() ) + s = m_file[n]; + + return s; +#else + int level = n % 6 + 1; + + wxColour clr((unsigned char)(abs((int)n - 192) % 256), + (unsigned char)(abs((int)n - 256) % 256), + (unsigned char)(abs((int)n - 128) % 256)); + + wxString label = wxString::Format(wxT("") + wxT("Item %lu") + wxT(""), + level, + clr.GetAsString(wxC2S_HTML_SYNTAX).c_str(), + (unsigned long)n, level); + if ( n == 1 ) + { + if ( !m_linkClicked ) + label += wxT("Click here..."); + else + label += wxT("Clicked here..."); + } + + return label; +#endif +} + +wxColour MyHtmlListBox::GetSelectedTextColour(const wxColour& colFg) const +{ + return m_change ? wxHtmlListBox::GetSelectedTextColour(colFg) : colFg; +} + +void MyHtmlListBox::UpdateFirstItem() +{ + m_firstItemUpdated = !m_firstItemUpdated; + + RefreshRow(0); +}