From d1bf0be0bcb74c67c35556138b891fd907b1d59f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 8 Jan 2012 14:52:56 +0000 Subject: [PATCH] Enhance wxRibbonToolBar functionality to wxRibbonButtonBar level. Allow inserting and deleting tools and not only appending them. Add possibility to enable/disable and toggle tools. Send wxUpdateUIEvent for the tools. Add various properties accessors. Closes #13835. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70297 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 5 +- include/wx/ribbon/toolbar.h | 70 +++++- interface/wx/ribbon/toolbar.h | 331 ++++++++++++++++++++++++- samples/ribbon/ribbondemo.cpp | 57 ++++- src/ribbon/art_aui.cpp | 8 +- src/ribbon/art_msw.cpp | 10 +- src/ribbon/toolbar.cpp | 446 +++++++++++++++++++++++++++++++++- 7 files changed, 907 insertions(+), 20 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index c9efccc0d6..d9397e54b0 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -462,8 +462,9 @@ All (GUI): - Support font-family/style, text-decoration in wxHtmlWindow (Blake Oleander). - Show ribbon tools help strings in tooltips (John Roberts). - Improve row/column selection modes in wxGrid (joostn). -- Allow using wxEVT_UPDATE_UI with wxRibbonButtonBar (Emilien Kia). -- Add wxRibbonButtonBar::InsertXXXButton() methods (Emilien Kia). +- Send wxEVT_UPDATE_UI for wxRibbonButtonBar and wxRibbonToolBar (Emilien Kia). +- Add InsertXXXButton() to wxRibbonButtonBar and wxRibbonToolBar (Emilien Kia). +- Allow enabling/disabling and toggling tools in wxRibbonToolBar (Emilien Kia). - Fix multiple item selection in generic wxTreeCtrl (Igor Korot). - Implement best size calculation for report mode wxListCtrl. diff --git a/include/wx/ribbon/toolbar.h b/include/wx/ribbon/toolbar.h index f15995e93d..a31f5aef48 100644 --- a/include/wx/ribbon/toolbar.h +++ b/include/wx/ribbon/toolbar.h @@ -35,7 +35,8 @@ enum wxRibbonToolBarToolState wxRIBBON_TOOLBAR_TOOL_DROPDOWN_ACTIVE = 1 << 6, wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK = wxRIBBON_TOOLBAR_TOOL_NORMAL_ACTIVE | wxRIBBON_TOOLBAR_TOOL_DROPDOWN_ACTIVE, wxRIBBON_TOOLBAR_TOOL_DISABLED = 1 << 7, - wxRIBBON_TOOLBAR_TOOL_STATE_MASK = 0xF8 + wxRIBBON_TOOLBAR_TOOL_TOGGLED = 1 << 8, + wxRIBBON_TOOLBAR_TOOL_STATE_MASK = 0x1F8 }; @@ -74,6 +75,11 @@ public: const wxBitmap& bitmap, const wxString& help_string = wxEmptyString); + virtual wxRibbonToolBarToolBase* AddToggleTool( + int tool_id, + const wxBitmap& bitmap, + const wxString& help_string = wxEmptyString); + virtual wxRibbonToolBarToolBase* AddTool( int tool_id, const wxBitmap& bitmap, @@ -84,11 +90,71 @@ public: virtual wxRibbonToolBarToolBase* AddSeparator(); + virtual wxRibbonToolBarToolBase* InsertTool( + size_t pos, + int tool_id, + const wxBitmap& bitmap, + const wxString& help_string, + wxRibbonButtonKind kind = wxRIBBON_BUTTON_NORMAL); + + virtual wxRibbonToolBarToolBase* InsertDropdownTool( + size_t pos, + int tool_id, + const wxBitmap& bitmap, + const wxString& help_string = wxEmptyString); + + virtual wxRibbonToolBarToolBase* InsertHybridTool( + size_t pos, + int tool_id, + const wxBitmap& bitmap, + const wxString& help_string = wxEmptyString); + + virtual wxRibbonToolBarToolBase* InsertToggleTool( + size_t pos, + int tool_id, + const wxBitmap& bitmap, + const wxString& help_string = wxEmptyString); + + virtual wxRibbonToolBarToolBase* InsertTool( + size_t pos, + int tool_id, + const wxBitmap& bitmap, + const wxBitmap& bitmap_disabled = wxNullBitmap, + const wxString& help_string = wxEmptyString, + wxRibbonButtonKind kind = wxRIBBON_BUTTON_NORMAL, + wxObject* client_data = NULL); + + virtual wxRibbonToolBarToolBase* InsertSeparator(size_t pos); + + virtual void ClearTools(); + virtual bool DeleteTool(int tool_id); + virtual bool DeleteToolByPos(size_t pos); + + virtual wxRibbonToolBarToolBase* FindById(int tool_id)const; + virtual wxRibbonToolBarToolBase* GetToolByPos(size_t pos)const; + virtual size_t GetToolCount() const; + virtual int GetToolId(const wxRibbonToolBarToolBase* tool)const; + + virtual wxObject* GetToolClientData(int tool_id)const; + virtual bool GetToolEnabled(int tool_id)const; + virtual wxString GetToolHelpString(int tool_id)const; + virtual wxRibbonButtonKind GetToolKind(int tool_id)const; + virtual int GetToolPos(int tool_id)const; + virtual bool GetToolState(int tool_id)const; + virtual bool Realize(); virtual void SetRows(int nMin, int nMax = -1); + virtual void SetToolClientData(int tool_id, wxObject* clientData); + virtual void SetToolDisabledBitmap(int tool_id, const wxBitmap &bitmap); + virtual void SetToolHelpString(int tool_id, const wxString& helpString); + virtual void SetToolNormalBitmap(int tool_id, const wxBitmap &bitmap); + virtual bool IsSizingContinuous() const; + virtual void EnableTool(int tool_id, bool enable = true); + virtual void ToggleTool(int tool_id, bool checked); + protected: friend class wxRibbonToolBarEvent; virtual wxSize DoGetBestSize() const; @@ -110,6 +176,8 @@ protected: void CommonInit(long style); void AppendGroup(); + wxRibbonToolBarToolGroup* InsertGroup(size_t pos); + virtual void UpdateWindowUI(long flags); static wxBitmap MakeDisabledBitmap(const wxBitmap& original); diff --git a/interface/wx/ribbon/toolbar.h b/interface/wx/ribbon/toolbar.h index 1a35d7e3d6..3ab156b770 100644 --- a/interface/wx/ribbon/toolbar.h +++ b/interface/wx/ribbon/toolbar.h @@ -102,6 +102,18 @@ public: const wxBitmap& bitmap, const wxString& help_string = wxEmptyString); + /** + Add a toggle tool to the tool bar (simple version). + + @since 2.9.4 + + @see AddTool() + */ + virtual wxRibbonToolBarToolBase* AddToggleTool( + int tool_id, + const wxBitmap& bitmap, + const wxString& help_string); + /** Add a tool to the tool bar. @@ -124,7 +136,7 @@ public: @return An opaque pointer which can be used only with other tool bar methods. - @see AddDropdownTool(), AddHybridTool(), AddSeparator() + @see AddDropdownTool(), AddHybridTool(), AddSeparator(), InsertTool() */ virtual wxRibbonToolBarToolBase* AddTool( int tool_id, @@ -143,6 +155,253 @@ public: */ virtual wxRibbonToolBarToolBase* AddSeparator(); + /** + Insert a tool to the tool bar (simple version) as the specified + position. + + @since 2.9.4 + + @see InsertTool() + */ + virtual wxRibbonToolBarToolBase* InsertTool( + size_t pos, + int tool_id, + const wxBitmap& bitmap, + const wxString& help_string, + wxRibbonButtonKind kind = wxRIBBON_BUTTON_NORMAL); + + + /** + Insert a dropdown tool to the tool bar (simple version) as the specified + position. + + @since 2.9.4 + + @see AddDropdownTool(), InsertTool() + */ + virtual wxRibbonToolBarToolBase* InsertDropdownTool( + size_t pos, + int tool_id, + const wxBitmap& bitmap, + const wxString& help_string = wxEmptyString); + + /** + Insert a hybrid tool to the tool bar (simple version) as the specified + position. + + @since 2.9.4 + + @see AddHybridTool(), InsertTool() + */ + virtual wxRibbonToolBarToolBase* InsertHybridTool( + size_t pos, + int tool_id, + const wxBitmap& bitmap, + const wxString& help_string = wxEmptyString); + + /** + Insert a toggle tool to the tool bar (simple version) as the specified + position. + + @since 2.9.4 + + @see AddToggleTool(), InsertTool() + */ + virtual wxRibbonToolBarToolBase* InsertToggleTool( + size_t pos, + int tool_id, + const wxBitmap& bitmap, + const wxString& help_string = wxEmptyString); + + /** + Insert a tool to the tool bar at the specified position. + + @param pos + Position of the new tool (number of tools and separators from the + begining of the toolbar). + @param tool_id + ID of the new tool (used for event callbacks). + @param bitmap + Bitmap to use as the foreground for the new tool. Does not have + to be the same size as other tool bitmaps, but should be similar + as otherwise it will look visually odd. + @param bitmap_disabled + Bitmap to use when the tool is disabled. If left as wxNullBitmap, + then a bitmap will be automatically generated from @a bitmap. + @param help_string + The UI help string to associate with the new tool. + @param kind + The kind of tool to add. + @param client_data + Client data to associate with the new tool. + + @return An opaque pointer which can be used only with other tool bar + methods. + + @since 2.9.4 + + @see InsertDropdownTool(), InsertHybridTool(), InsertSeparator() + */ + virtual wxRibbonToolBarToolBase* InsertTool( + size_t pos, + int tool_id, + const wxBitmap& bitmap, + const wxBitmap& bitmap_disabled = wxNullBitmap, + const wxString& help_string = wxEmptyString, + wxRibbonButtonKind kind = wxRIBBON_BUTTON_NORMAL, + wxObject* client_data = NULL); + + /** + Insert a separator to the tool bar at the specified position. + + @since 2.9.4 + + @see AddSeparator(), InsertTool() + */ + virtual wxRibbonToolBarToolBase* InsertSeparator(size_t pos); + + /** + Deletes all the tools in the toolbar. + + @since 2.9.4 + */ + virtual void ClearTools(); + + /** + Removes the specified tool from the toolbar and deletes it. + + @param tool_id + ID of the tool to delete. + + @returns @true if the tool was deleted, @false otherwise. + + @since 2.9.4 + + @see DeleteToolByPos() + */ + virtual bool DeleteTool(int tool_id); + + /** + This function behaves like DeleteTool() but it deletes the tool at the + specified position and not the one with the given id. + Usefull to delete separators. + + @since 2.9.4 + */ + virtual bool DeleteToolByPos(size_t pos); + + /** + Returns a pointer to the tool opaque structure by @a id or @NULL if no + corresponding tool is found. + + @since 2.9.4 + */ + virtual wxRibbonToolBarToolBase* FindById(int tool_id)const; + + /** + Return the opaque pointer corresponding to the given tool. + + @return an opaque pointer, NULL if is a separator or not found. + + @since 2.9.4 + */ + wxRibbonToolBarToolBase* GetToolByPos(size_t pos)const + + /** + Returns the number of tools in the toolbar. + + @since 2.9.4 + */ + virtual size_t GetToolCount() const; + + /** + Return the id assciated to the tool opaque structure. + + The structure pointer must not be @NULL. + + @since 2.9.4 + */ + virtual int GetToolId(const wxRibbonToolBarToolBase* tool)const; + + /** + Get any client data associated with the tool. + + @param toolId + ID of the tool in question, as passed to AddTool(). + + @return Client data, or @NULL if there is none. + + @since 2.9.4 + */ + virtual wxObject* GetToolClientData(int tool_id)const; + + /** + Called to determine whether a tool is enabled (responds to user input). + + @param toolId + ID of the tool in question, as passed to AddTool(). + + @return @true if the tool is enabled, @false otherwise. + + @since 2.9.4 + + @see EnableTool() + */ + virtual bool GetToolEnabled(int tool_id)const; + + /** + Returns the help string for the given tool. + + @param toolId + ID of the tool in question, as passed to AddTool(). + + @since 2.9.4 + */ + virtual wxString GetToolHelpString(int tool_id)const; + + /** + Return the kind of the given tool. + + @param toolId + ID of the tool in question, as passed to AddTool(). + + @since 2.9.4 + */ + virtual wxRibbonButtonKind GetToolKind(int tool_id)const; + + /** + Returns the tool position in the toolbar, or @c wxNOT_FOUND if the tool + is not found. + + @param toolId + ID of the tool in question, as passed to AddTool(). + + @since 2.9.4 + */ + virtual int GetToolPos(int tool_id)const; + + /** + Gets the on/off state of a toggle tool. + + @param toolId + ID of the tool in question, as passed to AddTool(). + + @return @true if the tool is toggled on, @false otherwise. + + @see ToggleTool() + + @since 2.9.4 + */ + virtual bool GetToolState(int tool_id)const; + + /** + Calculate tool layouts and positions. + + Must be called after tools are added to the tool bar, as otherwise + the newly added tools will not be displayed. + */ + virtual bool Realize(); + /** Set the number of rows to distribute tool groups over. @@ -157,4 +416,74 @@ public: The maximum number of rows to use (defaults to nMin). */ virtual void SetRows(int nMin, int nMax = -1); + + /** + Sets the client data associated with the tool. + + @param id + ID of the tool in question, as passed to AddTool(). + + @since 2.9.4 + */ + virtual void SetToolClientData(int tool_id, wxObject* clientData); + + /** + Sets the bitmap to be used by the tool with the given ID when the tool + is in a disabled state. + + @param tool_id + ID of the tool in question, as passed to AddTool(). + + @since 2.9.4 + */ + virtual void SetToolDisabledBitmap(int tool_id, const wxBitmap &bitmap); + + /** + Sets the help string shown in tooltip for the given tool. + + @param tool_Id + ID of the tool in question, as passed to AddTool(). + @param helpString + A string for the help. + + @see GetToolHelpString() + + @since 2.9.4 + */ + virtual void SetToolHelpString(int tool_id, const wxString& helpString); + + /** + Sets the bitmap to be used by the tool with the given ID. + + @param tool_id + ID of the tool in question, as passed to AddTool(). + + @since 2.9.4 + */ + virtual void SetToolNormalBitmap(int tool_id, const wxBitmap &bitmap); + + /** + Enable or disable a single tool on the bar. + + @param tool_id + ID of the tool to enable or disable. + @param enable + @true to enable the tool, @false to disable it. + + @since 2.9.4 + */ + virtual void EnableTool(int tool_id, bool enable = true); + + /** + Set a toggle tool to the checked or unchecked state. + + @param tool_id + ID of the toggle tool to manipulate. + @param checked + @true to set the tool to the toggled/pressed/checked state, + @false to set it to the untoggled/unpressed/unchecked state. + + @since 2.9.4 + */ + virtual void ToggleTool(int tool_id, bool checked); }; diff --git a/samples/ribbon/ribbondemo.cpp b/samples/ribbon/ribbondemo.cpp index b158b4df12..546838ebf0 100644 --- a/samples/ribbon/ribbondemo.cpp +++ b/samples/ribbon/ribbondemo.cpp @@ -108,6 +108,8 @@ public: void OnDefaultProvider(wxRibbonButtonBarEvent& evt); void OnAUIProvider(wxRibbonButtonBarEvent& evt); void OnMSWProvider(wxRibbonButtonBarEvent& evt); + void OnJustify(wxRibbonToolBarEvent& evt); + void OnJustifyUpdateUI(wxUpdateUIEvent& evt); void OnNew(wxRibbonToolBarEvent& evt); void OnNewDropdown(wxRibbonToolBarEvent& evt); void OnPrint(wxRibbonToolBarEvent& evt); @@ -195,6 +197,12 @@ EVT_RIBBONGALLERY_HOVER_CHANGED(ID_PRIMARY_COLOUR, MyFrame::OnHoveredColourChang EVT_RIBBONGALLERY_HOVER_CHANGED(ID_SECONDARY_COLOUR, MyFrame::OnHoveredColourChange) EVT_RIBBONGALLERY_SELECTED(ID_PRIMARY_COLOUR, MyFrame::OnPrimaryColourSelect) EVT_RIBBONGALLERY_SELECTED(ID_SECONDARY_COLOUR, MyFrame::OnSecondaryColourSelect) +EVT_RIBBONTOOLBAR_CLICKED(wxID_JUSTIFY_LEFT, MyFrame::OnJustify) +EVT_RIBBONTOOLBAR_CLICKED(wxID_JUSTIFY_CENTER, MyFrame::OnJustify) +EVT_RIBBONTOOLBAR_CLICKED(wxID_JUSTIFY_RIGHT, MyFrame::OnJustify) +EVT_UPDATE_UI(wxID_JUSTIFY_LEFT, MyFrame::OnJustifyUpdateUI) +EVT_UPDATE_UI(wxID_JUSTIFY_CENTER, MyFrame::OnJustifyUpdateUI) +EVT_UPDATE_UI(wxID_JUSTIFY_RIGHT, MyFrame::OnJustifyUpdateUI) EVT_RIBBONTOOLBAR_CLICKED(wxID_NEW, MyFrame::OnNew) EVT_RIBBONTOOLBAR_DROPDOWN_CLICKED(wxID_NEW, MyFrame::OnNewDropdown) EVT_RIBBONTOOLBAR_CLICKED(wxID_PRINT, MyFrame::OnPrint) @@ -250,14 +258,17 @@ MyFrame::MyFrame() wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxRIBBON_PANEL_NO_AUTO_MINIMISE); wxRibbonToolBar *toolbar = new wxRibbonToolBar(toolbar_panel, ID_MAIN_TOOLBAR); - toolbar->AddTool(wxID_ANY, align_left_xpm); - toolbar->AddTool(wxID_ANY, align_center_xpm); - toolbar->AddTool(wxID_ANY, align_right_xpm); + toolbar->AddToggleTool(wxID_JUSTIFY_LEFT, align_left_xpm); + toolbar->AddToggleTool(wxID_JUSTIFY_CENTER , align_center_xpm); + toolbar->AddToggleTool(wxID_JUSTIFY_RIGHT, align_right_xpm); toolbar->AddSeparator(); toolbar->AddHybridTool(wxID_NEW, wxArtProvider::GetBitmap(wxART_NEW, wxART_OTHER, wxSize(16, 15))); - toolbar->AddTool(wxID_ANY, wxArtProvider::GetBitmap(wxART_FILE_OPEN, wxART_OTHER, wxSize(16, 15))); - toolbar->AddTool(wxID_ANY, wxArtProvider::GetBitmap(wxART_FILE_SAVE, wxART_OTHER, wxSize(16, 15))); - toolbar->AddTool(wxID_ANY, wxArtProvider::GetBitmap(wxART_FILE_SAVE_AS, wxART_OTHER, wxSize(16, 15))); + toolbar->AddTool(wxID_OPEN, wxArtProvider::GetBitmap(wxART_FILE_OPEN, wxART_OTHER, wxSize(16, 15)), "Open something"); + toolbar->AddTool(wxID_SAVE, wxArtProvider::GetBitmap(wxART_FILE_SAVE, wxART_OTHER, wxSize(16, 15)), "Save something"); + toolbar->AddTool(wxID_SAVEAS, wxArtProvider::GetBitmap(wxART_FILE_SAVE_AS, wxART_OTHER, wxSize(16, 15)), "Save something as ..."); + toolbar->EnableTool(wxID_OPEN, false); + toolbar->EnableTool(wxID_SAVE, false); + toolbar->EnableTool(wxID_SAVEAS, false); toolbar->AddSeparator(); toolbar->AddDropdownTool(wxID_UNDO, wxArtProvider::GetBitmap(wxART_UNDO, wxART_OTHER, wxSize(16, 15))); toolbar->AddDropdownTool(wxID_REDO, wxArtProvider::GetBitmap(wxART_REDO, wxART_OTHER, wxSize(16, 15))); @@ -660,6 +671,40 @@ void MyFrame::OnPolygonDropdown(wxRibbonButtonBarEvent& evt) evt.PopupMenu(&menu); } +void MyFrame::OnJustify(wxRibbonToolBarEvent& evt) +{ + long style = m_logwindow->GetWindowStyle() & + ~(wxTE_LEFT | wxTE_CENTER | wxTE_RIGHT); + switch(evt.GetId()) + { + case wxID_JUSTIFY_LEFT: + m_logwindow->SetWindowStyle(style | wxTE_LEFT); + break; + case wxID_JUSTIFY_CENTER: + m_logwindow->SetWindowStyle(style | wxTE_CENTER); + break; + case wxID_JUSTIFY_RIGHT: + m_logwindow->SetWindowStyle(style | wxTE_RIGHT); + break; + } +} + +void MyFrame::OnJustifyUpdateUI(wxUpdateUIEvent& evt) +{ + switch(evt.GetId()) + { + case wxID_JUSTIFY_LEFT: + evt.Check(!m_logwindow->HasFlag(wxTE_CENTER | wxTE_RIGHT)); + break; + case wxID_JUSTIFY_CENTER: + evt.Check(m_logwindow->HasFlag(wxTE_CENTER)); + break; + case wxID_JUSTIFY_RIGHT: + evt.Check(m_logwindow->HasFlag(wxTE_RIGHT)); + break; + } +} + void MyFrame::OnNew(wxRibbonToolBarEvent& WXUNUSED(evt)) { AddText(wxT("New button clicked.")); diff --git a/src/ribbon/art_aui.cpp b/src/ribbon/art_aui.cpp index 99ae7001be..37293f9078 100644 --- a/src/ribbon/art_aui.cpp +++ b/src/ribbon/art_aui.cpp @@ -1067,6 +1067,12 @@ void wxRibbonAUIArtProvider::DrawTool( wxRibbonButtonKind kind, long state) { + if(kind == wxRIBBON_BUTTON_TOGGLE) + { + if(state & wxRIBBON_TOOLBAR_TOOL_TOGGLED) + state ^= wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK; + } + wxRect bg_rect(rect); bg_rect.Deflate(1); if((state & wxRIBBON_TOOLBAR_TOOL_LAST) == 0) @@ -1124,7 +1130,7 @@ void wxRibbonAUIArtProvider::DrawTool( // Foreground int avail_width = bg_rect.GetWidth(); - if(kind != wxRIBBON_BUTTON_NORMAL) + if(kind & wxRIBBON_BUTTON_DROPDOWN) { avail_width -= 8; if(is_split_hybrid) diff --git a/src/ribbon/art_msw.cpp b/src/ribbon/art_msw.cpp index f10d562083..312148f1c6 100644 --- a/src/ribbon/art_msw.cpp +++ b/src/ribbon/art_msw.cpp @@ -2262,6 +2262,12 @@ void wxRibbonMSWArtProvider::DrawTool( wxRibbonButtonKind kind, long state) { + if(kind == wxRIBBON_BUTTON_TOGGLE) + { + if(state & wxRIBBON_TOOLBAR_TOOL_TOGGLED) + state ^= wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK; + } + wxRect bg_rect(rect); bg_rect.Deflate(1); if((state & wxRIBBON_TOOLBAR_TOOL_LAST) == 0) @@ -2332,7 +2338,7 @@ void wxRibbonMSWArtProvider::DrawTool( // Foreground int avail_width = bg_rect.GetWidth(); - if(kind != wxRIBBON_BUTTON_NORMAL) + if(kind & wxRIBBON_BUTTON_DROPDOWN) { avail_width -= 8; if(is_split_hybrid) @@ -2782,7 +2788,7 @@ wxSize wxRibbonMSWArtProvider::GetToolSize( size.IncBy(7, 6); if(is_last) size.IncBy(1, 0); - if(kind != wxRIBBON_BUTTON_NORMAL) + if(kind & wxRIBBON_BUTTON_DROPDOWN) { size.IncBy(8, 0); if(dropdown_region) diff --git a/src/ribbon/toolbar.cpp b/src/ribbon/toolbar.cpp index 12826d1eae..4c4b14cdac 100644 --- a/src/ribbon/toolbar.cpp +++ b/src/ribbon/toolbar.cpp @@ -161,6 +161,15 @@ wxRibbonToolBarToolBase* wxRibbonToolBar::AddHybridTool( wxRIBBON_BUTTON_HYBRID, NULL); } +wxRibbonToolBarToolBase* wxRibbonToolBar::AddToggleTool( + int tool_id, + const wxBitmap& bitmap, + const wxString& help_string) +{ + return AddTool(tool_id, bitmap, wxNullBitmap, help_string, + wxRIBBON_BUTTON_TOGGLE, NULL); +} + wxRibbonToolBarToolBase* wxRibbonToolBar::AddTool( int tool_id, const wxBitmap& bitmap, @@ -168,9 +177,74 @@ wxRibbonToolBarToolBase* wxRibbonToolBar::AddTool( const wxString& help_string, wxRibbonButtonKind kind, wxObject* client_data) +{ + return InsertTool(GetToolCount(), tool_id, bitmap, bitmap_disabled, + help_string, kind, client_data); +} + +wxRibbonToolBarToolBase* wxRibbonToolBar::AddSeparator() +{ + if(m_groups.Last()->tools.IsEmpty()) + return NULL; + + AppendGroup(); + return &m_groups.Last()->dummy_tool; +} + + +wxRibbonToolBarToolBase* wxRibbonToolBar::InsertTool( + size_t pos, + int tool_id, + const wxBitmap& bitmap, + const wxString& help_string, + wxRibbonButtonKind kind) +{ + return InsertTool(pos, tool_id, bitmap, wxNullBitmap, help_string, kind, + NULL); +} + +wxRibbonToolBarToolBase* wxRibbonToolBar::InsertDropdownTool( + size_t pos, + int tool_id, + const wxBitmap& bitmap, + const wxString& help_string) +{ + return InsertTool(pos, tool_id, bitmap, wxNullBitmap, help_string, + wxRIBBON_BUTTON_DROPDOWN, NULL); +} + +wxRibbonToolBarToolBase* wxRibbonToolBar::InsertHybridTool( + size_t pos, + int tool_id, + const wxBitmap& bitmap, + const wxString& help_string) +{ + return InsertTool(pos, tool_id, bitmap, wxNullBitmap, help_string, + wxRIBBON_BUTTON_HYBRID, NULL); +} + +wxRibbonToolBarToolBase* wxRibbonToolBar::InsertToggleTool( + size_t pos, + int tool_id, + const wxBitmap& bitmap, + const wxString& help_string) +{ + return InsertTool(pos, tool_id, bitmap, wxNullBitmap, help_string, + wxRIBBON_BUTTON_TOGGLE, NULL); +} + +wxRibbonToolBarToolBase* wxRibbonToolBar::InsertTool( + size_t pos, + int tool_id, + const wxBitmap& bitmap, + const wxBitmap& bitmap_disabled, + const wxString& help_string, + wxRibbonButtonKind kind, + wxObject* client_data) { wxASSERT(bitmap.IsOk()); + // Create the wxRibbonToolBarToolBase with parameters wxRibbonToolBarToolBase* tool = new wxRibbonToolBarToolBase; tool->id = tool_id; tool->bitmap = bitmap; @@ -188,19 +262,257 @@ wxRibbonToolBarToolBase* wxRibbonToolBar::AddTool( tool->size = wxSize(0, 0); tool->state = 0; - m_groups.Last()->tools.Add(tool); - return tool; + // Find the position where insert tool + size_t group_count = m_groups.GetCount(); + size_t g; + for(g = 0; g < group_count; ++g) + { + wxRibbonToolBarToolGroup* group = m_groups.Item(g); + size_t tool_count = group->tools.GetCount(); + if(pos <= tool_count) + { + group->tools.Insert(tool, pos); + return tool; + } + pos -= tool_count + 1; + } + wxFAIL_MSG("Tool position out of toolbar bounds."); + return NULL; } -wxRibbonToolBarToolBase* wxRibbonToolBar::AddSeparator() +wxRibbonToolBarToolBase* wxRibbonToolBar::InsertSeparator(size_t pos) { + size_t group_count = m_groups.GetCount(); + size_t g; + for(g = 0; g < group_count; ++g) + { + if(pos==0) // Prepend group + return &InsertGroup(g)->dummy_tool; + if(pos==group_count) // Append group + return &InsertGroup(g+1)->dummy_tool; + + wxRibbonToolBarToolGroup* group = m_groups.Item(g); + size_t tool_count = group->tools.GetCount(); + if(pos < tool_count) + { + wxRibbonToolBarToolGroup* new_group = InsertGroup(g+1); + + for(size_t t = pos; t < tool_count; t++) + new_group->tools.Add(group->tools[t]); + group->tools.RemoveAt(pos, tool_count-pos); + + return &group->dummy_tool; + } + pos -= tool_count + 1; + } + // Add an empty group at the end of the bar. if(m_groups.Last()->tools.IsEmpty()) return NULL; - AppendGroup(); return &m_groups.Last()->dummy_tool; } +wxRibbonToolBarToolGroup* wxRibbonToolBar::InsertGroup(size_t pos) +{ + wxRibbonToolBarToolGroup* group = new wxRibbonToolBarToolGroup; + group->position = wxPoint(0, 0); + group->size = wxSize(0, 0); + m_groups.Insert(group, pos); + return group; +} + +void wxRibbonToolBar::ClearTools() +{ + size_t count = m_groups.GetCount(); + size_t i, t; + for(i = 0; i < count; ++i) + { + wxRibbonToolBarToolGroup* group = m_groups.Item(i); + size_t tool_count = group->tools.GetCount(); + for(t = 0; t < tool_count; ++t) + { + wxRibbonToolBarToolBase* tool = group->tools.Item(t); + delete tool; + } + delete group; + } + m_groups.Clear(); +} + +bool wxRibbonToolBar::DeleteTool(int tool_id) +{ + size_t group_count = m_groups.GetCount(); + size_t g, t; + for(g = 0; g < group_count; ++g) + { + wxRibbonToolBarToolGroup* group = m_groups.Item(g); + size_t tool_count = group->tools.GetCount(); + for(t = 0; t < tool_count; ++t) + { + wxRibbonToolBarToolBase* tool = group->tools.Item(t); + if(tool->id == tool_id) + { + group->tools.RemoveAt(t); + delete tool; + return true; + } + } + } + return false; +} + +bool wxRibbonToolBar::DeleteToolByPos(size_t pos) +{ + size_t group_count = m_groups.GetCount(); + size_t g, t; + for(g = 0; g < group_count; ++g) + { + wxRibbonToolBarToolGroup* group = m_groups.Item(g); + size_t tool_count = group->tools.GetCount(); + if(postools.Item(pos); + group->tools.RemoveAt(pos); + delete tool; + return true; + } + else if(pos==tool_count) + { + // Remove separator + if(g < group_count - 1) + { + wxRibbonToolBarToolGroup* next_group = m_groups.Item(g+1); + for(t = 0; t < next_group->tools.GetCount(); ++t) + group->tools.Add(next_group->tools[t]); + m_groups.RemoveAt(g+1); + delete next_group; + } + return true; + } + } + return false; +} + +wxRibbonToolBarToolBase* wxRibbonToolBar::FindById(int tool_id)const +{ + size_t group_count = m_groups.GetCount(); + size_t g, t; + for(g = 0; g < group_count; ++g) + { + wxRibbonToolBarToolGroup* group = m_groups.Item(g); + size_t tool_count = group->tools.GetCount(); + for(t = 0; t < tool_count; ++t) + { + wxRibbonToolBarToolBase* tool = group->tools.Item(t); + if(tool->id == tool_id) + { + return tool; + } + } + } + return NULL; +} + +wxRibbonToolBarToolBase* wxRibbonToolBar::GetToolByPos(size_t pos)const +{ + size_t group_count = m_groups.GetCount(); + size_t g; + for(g = 0; g < group_count; ++g) + { + wxRibbonToolBarToolGroup* group = m_groups.Item(g); + size_t tool_count = group->tools.GetCount(); + if(postools[pos]; + } + else if(pos==tool_count) + { + return NULL; + } + } + return NULL; +} + +size_t wxRibbonToolBar::GetToolCount() const +{ + size_t count = 0; + for(size_t g = 0; g < m_groups.GetCount(); ++g) + { + wxRibbonToolBarToolGroup* group = m_groups.Item(g); + count += group->tools.GetCount(); + } + // There is a splitter in front of every group except for the first + // If only one group, no separator. + if(m_groups.GetCount()>1) + count += m_groups.GetCount() - 1; + return count; +} + +int wxRibbonToolBar::GetToolId(const wxRibbonToolBarToolBase* tool)const +{ + wxCHECK_MSG(tool != NULL , wxNOT_FOUND, "The tool pointer must not be NULL"); + return tool->id; +} + +wxObject* wxRibbonToolBar::GetToolClientData(int tool_id)const +{ + wxRibbonToolBarToolBase* tool = FindById(tool_id); + wxCHECK_MSG(tool != NULL , NULL, "Invalid tool id"); + return tool->client_data; +} + +bool wxRibbonToolBar::GetToolEnabled(int tool_id)const +{ + wxRibbonToolBarToolBase* tool = FindById(tool_id); + wxCHECK_MSG(tool != NULL , false, "Invalid tool id"); + return (tool->state & wxRIBBON_TOOLBAR_TOOL_DISABLED) == 0; +} + +wxString wxRibbonToolBar::GetToolHelpString(int tool_id)const +{ + wxRibbonToolBarToolBase* tool = FindById(tool_id); + wxCHECK_MSG(tool != NULL , wxEmptyString, "Invalid tool id"); + return tool->help_string; +} + +wxRibbonButtonKind wxRibbonToolBar::GetToolKind(int tool_id)const +{ + wxRibbonToolBarToolBase* tool = FindById(tool_id); + wxCHECK_MSG(tool != NULL , wxRIBBON_BUTTON_NORMAL, "Invalid tool id"); + return tool->kind; +} + +int wxRibbonToolBar::GetToolPos(int tool_id)const +{ + size_t group_count = m_groups.GetCount(); + size_t g, t; + int pos = 0; + for(g = 0; g < group_count; ++g) + { + wxRibbonToolBarToolGroup* group = m_groups.Item(g); + size_t tool_count = group->tools.GetCount(); + for(t = 0; t < tool_count; ++t) + { + wxRibbonToolBarToolBase* tool = group->tools.Item(t); + if(tool->id == tool_id) + { + return pos; + } + ++pos; + } + ++pos; // Increment pos for group separator. + } + return wxNOT_FOUND; +} + +bool wxRibbonToolBar::GetToolState(int tool_id)const +{ + wxRibbonToolBarToolBase* tool = FindById(tool_id); + wxCHECK_MSG(tool != NULL , false, "Invalid tool id"); + return (tool->state & wxRIBBON_TOOLBAR_TOOL_TOGGLED) != 0; +} + wxBitmap wxRibbonToolBar::MakeDisabledBitmap(const wxBitmap& original) { wxImage img(original.ConvertToImage()); @@ -220,6 +532,78 @@ bool wxRibbonToolBar::IsSizingContinuous() const return false; } +void wxRibbonToolBar::SetToolClientData(int tool_id, wxObject* clientData) +{ + wxRibbonToolBarToolBase* tool = FindById(tool_id); + wxCHECK_RET(tool != NULL , "Invalid tool id"); + tool->client_data = clientData; +} + +void wxRibbonToolBar::SetToolDisabledBitmap(int tool_id, const wxBitmap &bitmap) +{ + wxRibbonToolBarToolBase* tool = FindById(tool_id); + wxCHECK_RET(tool != NULL , "Invalid tool id"); + tool->bitmap_disabled = bitmap; +} + +void wxRibbonToolBar::SetToolHelpString(int tool_id, const wxString& helpString) +{ + wxRibbonToolBarToolBase* tool = FindById(tool_id); + wxCHECK_RET(tool != NULL , "Invalid tool id"); + tool->help_string = helpString; +} + +void wxRibbonToolBar::SetToolNormalBitmap(int tool_id, const wxBitmap &bitmap) +{ + wxRibbonToolBarToolBase* tool = FindById(tool_id); + wxCHECK_RET(tool != NULL , "Invalid tool id"); + tool->bitmap = bitmap; +} + +void wxRibbonToolBar::EnableTool(int tool_id, bool enable) +{ + wxRibbonToolBarToolBase* tool = FindById(tool_id); + wxCHECK_RET(tool != NULL , "Invalid tool id"); + if(enable) + { + if(tool->state & wxRIBBON_TOOLBAR_TOOL_DISABLED) + { + tool->state &= ~wxRIBBON_TOOLBAR_TOOL_DISABLED; + Refresh(); + } + } + else + { + if((tool->state & wxRIBBON_TOOLBAR_TOOL_DISABLED)==0) + { + tool->state |= wxRIBBON_TOOLBAR_TOOL_DISABLED; + Refresh(); + } + } +} + +void wxRibbonToolBar::ToggleTool(int tool_id, bool checked) +{ + wxRibbonToolBarToolBase* tool = FindById(tool_id); + wxCHECK_RET(tool != NULL , "Invalid tool id"); + if(checked) + { + if((tool->state & wxRIBBON_TOOLBAR_TOOL_TOGGLED) == 0) + { + tool->state |= wxRIBBON_TOOLBAR_TOOL_TOGGLED; + Refresh(); + } + } + else + { + if(tool->state & wxRIBBON_TOOLBAR_TOOL_TOGGLED) + { + tool->state &= ~wxRIBBON_TOOLBAR_TOOL_TOGGLED; + Refresh(); + } + } +} + static int GetSizeInOrientation(wxSize size, wxOrientation orientation) { switch(orientation) @@ -363,7 +747,6 @@ bool wxRibbonToolBar::Realize() tool->size = m_art->GetToolSize(temp_dc, this, tool->bitmap.GetSize(), tool->kind, t == 0, t == (tool_count - 1), &tool->dropdown); - tool->state = tool->state & ~wxRIBBON_TOOLBAR_TOOL_DISABLED; if(t == 0) tool->state |= wxRIBBON_TOOLBAR_TOOL_FIRST; if(t == tool_count - 1) @@ -544,8 +927,12 @@ void wxRibbonToolBar::OnPaint(wxPaintEvent& WXUNUSED(evt)) { wxRibbonToolBarToolBase* tool = group->tools.Item(t); wxRect rect(group->position + tool->position, tool->size); - m_art->DrawTool(dc, this, rect, tool->bitmap, tool->kind, - tool->state); + if(tool->state & wxRIBBON_TOOLBAR_TOOL_DISABLED) + m_art->DrawTool(dc, this, rect, tool->bitmap_disabled, + tool->kind, tool->state); + else + m_art->DrawTool(dc, this, rect, tool->bitmap, tool->kind, + tool->state); } } } @@ -592,6 +979,11 @@ void wxRibbonToolBar::OnMouseMove(wxMouseEvent& evt) } #endif + if(new_hover && new_hover->state & wxRIBBON_TOOLBAR_TOOL_DISABLED) + { + new_hover = NULL; // A disabled tool can not be hilighted + } + if(new_hover != m_hover_tool) { if(m_hover_tool) @@ -668,6 +1060,13 @@ void wxRibbonToolBar::OnMouseUp(wxMouseEvent& WXUNUSED(evt)) if(m_active_tool->state & wxRIBBON_TOOLBAR_TOOL_DROPDOWN_ACTIVE) evt_type = wxEVT_COMMAND_RIBBONTOOL_DROPDOWN_CLICKED; wxRibbonToolBarEvent notification(evt_type, m_active_tool->id); + if(m_active_tool->kind == wxRIBBON_BUTTON_TOGGLE) + { + m_active_tool->state ^= + wxRIBBON_BUTTONBAR_BUTTON_TOGGLED; + notification.SetInt(m_active_tool->state & + wxRIBBON_BUTTONBAR_BUTTON_TOGGLED); + } notification.SetEventObject(this); notification.SetBar(this); ProcessEvent(notification); @@ -692,6 +1091,39 @@ void wxRibbonToolBar::OnMouseEnter(wxMouseEvent& evt) } } +void wxRibbonToolBar::UpdateWindowUI(long flags) +{ + wxWindowBase::UpdateWindowUI(flags); + + // don't waste time updating state of tools in a hidden toolbar + if ( !IsShown() ) + return; + + size_t group_count = m_groups.GetCount(); + size_t g, t; + for(g = 0; g < group_count; ++g) + { + wxRibbonToolBarToolGroup* group = m_groups.Item(g); + size_t tool_count = group->tools.GetCount(); + for(t = 0; t < tool_count; ++t) + { + wxRibbonToolBarToolBase* tool = group->tools.Item(t); + int id = tool->id; + + wxUpdateUIEvent event(id); + event.SetEventObject(this); + + if ( ProcessWindowEvent(event) ) + { + if ( event.GetSetEnabled() ) + EnableTool(id, event.GetEnabled()); + if ( event.GetSetChecked() ) + ToggleTool(id, event.GetChecked()); + } + } + } +} + bool wxRibbonToolBarEvent::PopupMenu(wxMenu* menu) { wxPoint pos = wxDefaultPosition; -- 2.45.2