X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4cf018e14ea61679b99874765f232b2032b3d3f8..43f4e852a1b2ac37c3db6a2b87315192ac549191:/src/ribbon/buttonbar.cpp diff --git a/src/ribbon/buttonbar.cpp b/src/ribbon/buttonbar.cpp index 3262c3b257..7e2b3bc43a 100644 --- a/src/ribbon/buttonbar.cpp +++ b/src/ribbon/buttonbar.cpp @@ -17,6 +17,7 @@ #if wxUSE_RIBBON +#include "wx/ribbon/panel.h" #include "wx/ribbon/buttonbar.h" #include "wx/ribbon/art.h" #include "wx/dcbuffer.h" @@ -116,7 +117,7 @@ public: wxBitmap bitmap_small; wxBitmap bitmap_small_disabled; wxRibbonButtonBarButtonSizeInfo sizes[3]; - wxObject* client_data; + wxClientDataContainer client_data; int id; wxRibbonButtonKind kind; long state; @@ -178,6 +179,7 @@ public: wxRibbonButtonBar::wxRibbonButtonBar() { m_layouts_valid = false; + CommonInit (0); } wxRibbonButtonBar::wxRibbonButtonBar(wxWindow* parent, @@ -248,6 +250,16 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddDropdownButton( wxRIBBON_BUTTON_DROPDOWN); } +wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddToggleButton( + int button_id, + const wxString& label, + const wxBitmap& bitmap, + const wxString& help_string) +{ + return AddButton(button_id, label, bitmap, help_string, + wxRIBBON_BUTTON_TOGGLE); +} + wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddHybridButton( int button_id, const wxString& label, @@ -257,7 +269,7 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddHybridButton( return AddButton(button_id, label, bitmap, help_string, wxRIBBON_BUTTON_HYBRID); } - + wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddButton( int button_id, const wxString& label, @@ -266,8 +278,22 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddButton( const wxBitmap& bitmap_disabled, const wxBitmap& bitmap_small_disabled, wxRibbonButtonKind kind, - const wxString& help_string, - wxObject* client_data) + const wxString& help_string) +{ + return InsertButton(GetButtonCount(), button_id, label, bitmap, + bitmap_small, bitmap_disabled,bitmap_small_disabled, kind, help_string); +} + +wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton( + size_t pos, + int button_id, + const wxString& label, + const wxBitmap& bitmap, + const wxBitmap& bitmap_small, + const wxBitmap& bitmap_disabled, + const wxBitmap& bitmap_small_disabled, + wxRibbonButtonKind kind, + const wxString& help_string) { wxASSERT(bitmap.IsOk() || bitmap_small.IsOk()); if(m_buttons.IsEmpty()) @@ -329,7 +355,6 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddButton( } base->kind = kind; base->help_string = help_string; - base->client_data = client_data; base->state = 0; wxClientDC temp_dc(this); @@ -337,12 +362,92 @@ wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddButton( FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM, temp_dc); FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_LARGE, temp_dc); - // TODO - m_buttons.Add(base); + m_buttons.Insert(base, pos); m_layouts_valid = false; return base; } + +void +wxRibbonButtonBar::SetItemClientObject(wxRibbonButtonBarButtonBase* item, + wxClientData* data) +{ + wxCHECK_RET( item, "Can't associate client object with an invalid item" ); + + item->client_data.SetClientObject(data); +} + +wxClientData* +wxRibbonButtonBar::GetItemClientObject(const wxRibbonButtonBarButtonBase* item) const +{ + wxCHECK_MSG( item, NULL, "Can't get client object for an invalid item" ); + + return item->client_data.GetClientObject(); +} + +void +wxRibbonButtonBar::SetItemClientData(wxRibbonButtonBarButtonBase* item, + void* data) +{ + wxCHECK_RET( item, "Can't associate client data with an invalid item" ); + + item->client_data.SetClientData(data); +} + +void* +wxRibbonButtonBar::GetItemClientData(const wxRibbonButtonBarButtonBase* item) const +{ + wxCHECK_MSG( item, NULL, "Can't get client data for an invalid item" ); + + return item->client_data.GetClientData(); +} + + +wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton( + size_t pos, + int button_id, + const wxString& label, + const wxBitmap& bitmap, + const wxString& help_string, + wxRibbonButtonKind kind) +{ + return InsertButton(pos, button_id, label, bitmap, wxNullBitmap, + wxNullBitmap, wxNullBitmap, kind, help_string); +} + +wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertDropdownButton( + size_t pos, + int button_id, + const wxString& label, + const wxBitmap& bitmap, + const wxString& help_string) +{ + return InsertButton(pos, button_id, label, bitmap, help_string, + wxRIBBON_BUTTON_DROPDOWN); +} + +wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertToggleButton( + size_t pos, + int button_id, + const wxString& label, + const wxBitmap& bitmap, + const wxString& help_string) +{ + return InsertButton(pos, button_id, label, bitmap, help_string, + wxRIBBON_BUTTON_TOGGLE); +} + +wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertHybridButton( + size_t pos, + int button_id, + const wxString& label, + const wxBitmap& bitmap, + const wxString& help_string) +{ + return InsertButton(pos, button_id, label, bitmap, help_string, + wxRIBBON_BUTTON_HYBRID); +} + void wxRibbonButtonBar::FetchButtonSizeInfo(wxRibbonButtonBarButtonBase* button, wxRibbonButtonBarButtonState size, wxDC& dc) { @@ -371,6 +476,11 @@ wxBitmap wxRibbonButtonBar::MakeDisabledBitmap(const wxBitmap& original) return wxBitmap(img.ConvertToGreyscale()); } +size_t wxRibbonButtonBar::GetButtonCount() const +{ + return m_buttons.GetCount(); +} + bool wxRibbonButtonBar::Realize() { if(!m_layouts_valid) @@ -444,6 +554,36 @@ void wxRibbonButtonBar::EnableButton(int button_id, bool enable) } } +void wxRibbonButtonBar::ToggleButton(int button_id, bool checked) +{ + size_t count = m_buttons.GetCount(); + size_t i; + for(i = 0; i < count; ++i) + { + wxRibbonButtonBarButtonBase* button = m_buttons.Item(i); + if(button->id == button_id) + { + if(checked) + { + if((button->state & wxRIBBON_BUTTONBAR_BUTTON_TOGGLED) == 0) + { + button->state |= wxRIBBON_BUTTONBAR_BUTTON_TOGGLED; + Refresh(); + } + } + else + { + if(button->state & wxRIBBON_BUTTONBAR_BUTTON_TOGGLED) + { + button->state &= ~wxRIBBON_BUTTONBAR_BUTTON_TOGGLED; + Refresh(); + } + } + return; + } + } +} + void wxRibbonButtonBar::SetArtProvider(wxRibbonArtProvider* art) { if(art == m_art) @@ -557,6 +697,42 @@ wxSize wxRibbonButtonBar::DoGetNextLargerSize(wxOrientation direction, return result; } +void wxRibbonButtonBar::UpdateWindowUI(long flags) +{ + wxWindowBase::UpdateWindowUI(flags); + + // don't waste time updating state of tools in a hidden toolbar + if ( !IsShown() ) + return; + + size_t btn_count = m_buttons.size(); + bool rerealize = false; + for ( size_t btn_i = 0; btn_i < btn_count; ++btn_i ) + { + wxRibbonButtonBarButtonBase& btn = *m_buttons.Item(btn_i); + int id = btn.id; + + wxUpdateUIEvent event(id); + event.SetEventObject(this); + + if ( ProcessWindowEvent(event) ) + { + if ( event.GetSetEnabled() ) + EnableButton(id, event.GetEnabled()); + if ( event.GetSetChecked() ) + ToggleButton(id, event.GetChecked()); + if ( event.GetSetText() ) + { + btn.label = event.GetText(); + rerealize = true; + } + } + } + + if ( rerealize ) + Realize(); +} + void wxRibbonButtonBar::OnEraseBackground(wxEraseEvent& WXUNUSED(evt)) { // All painting done in main paint handler to minimise flicker @@ -584,7 +760,7 @@ void wxRibbonButtonBar::OnPaint(wxPaintEvent& WXUNUSED(evt)) bitmap_small = &base->bitmap_small_disabled; } wxRect rect(button.position + m_layout_offset, base->sizes[button.size].size); - + m_art->DrawButtonBarButton(dc, this, rect, base->kind, base->state | button.size, base->label, *bitmap, *bitmap_small); } @@ -624,10 +800,21 @@ void wxRibbonButtonBar::CommonInit(long WXUNUSED(style)) m_hovered_button = NULL; m_active_button = NULL; m_lock_active_state = false; + m_show_tooltips_for_disabled = false; SetBackgroundStyle(wxBG_STYLE_CUSTOM); } +void wxRibbonButtonBar::SetShowToolTipsForDisabled(bool show) +{ + m_show_tooltips_for_disabled = show; +} + +bool wxRibbonButtonBar::GetShowToolTipsForDisabled() const +{ + return m_show_tooltips_for_disabled; +} + wxSize wxRibbonButtonBar::GetMinSize() const { return m_layouts.Last()->overall_size; @@ -758,7 +945,7 @@ bool wxRibbonButtonBar::TryCollapseLayout(wxRibbonButtonBarLayout* original, // If height isn't preserved (i.e. it is reduced), then the minimum // size for the button bar will decrease, preventing the original // layout from being used (in some cases). - // It may be a good idea to always preverse the height, but for now + // It may be a good idea to always preserve the height, but for now // it is only done when the first button is involved in a collapse. preserve_height = true; } @@ -803,6 +990,7 @@ void wxRibbonButtonBar::OnMouseMove(wxMouseEvent& evt) { wxPoint cursor(evt.GetPosition()); wxRibbonButtonBarButtonInstance* new_hovered = NULL; + wxRibbonButtonBarButtonInstance* tooltipButton = NULL; long new_hovered_state = 0; wxRibbonButtonBarLayout* layout = m_layouts.Item(m_current_layout); @@ -817,23 +1005,42 @@ void wxRibbonButtonBar::OnMouseMove(wxMouseEvent& evt) btn_rect.SetSize(size.size); if(btn_rect.Contains(cursor)) { - new_hovered = &instance; - new_hovered_state = instance.base->state; - new_hovered_state &= ~wxRIBBON_BUTTONBAR_BUTTON_HOVER_MASK; - wxPoint offset(cursor); - offset -= btn_rect.GetTopLeft(); - if(size.normal_region.Contains(offset)) + if((instance.base->state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) == 0) { - new_hovered_state |= wxRIBBON_BUTTONBAR_BUTTON_NORMAL_HOVERED; + tooltipButton = &instance; + new_hovered = &instance; + new_hovered_state = instance.base->state; + new_hovered_state &= ~wxRIBBON_BUTTONBAR_BUTTON_HOVER_MASK; + wxPoint offset(cursor); + offset -= btn_rect.GetTopLeft(); + if(size.normal_region.Contains(offset)) + { + new_hovered_state |= wxRIBBON_BUTTONBAR_BUTTON_NORMAL_HOVERED; + } + if(size.dropdown_region.Contains(offset)) + { + new_hovered_state |= wxRIBBON_BUTTONBAR_BUTTON_DROPDOWN_HOVERED; + } + break; } - if(size.dropdown_region.Contains(offset)) + else if (m_show_tooltips_for_disabled) { - new_hovered_state |= wxRIBBON_BUTTONBAR_BUTTON_DROPDOWN_HOVERED; + tooltipButton = &instance; } - break; } } +#if wxUSE_TOOLTIPS + if(tooltipButton == NULL && GetToolTip()) + { + UnsetToolTip(); + } + if(tooltipButton) + { + SetToolTip(tooltipButton->base->help_string); + } +#endif + if(new_hovered != m_hovered_button || (m_hovered_button != NULL && new_hovered_state != m_hovered_button->base->state)) { @@ -896,16 +1103,19 @@ void wxRibbonButtonBar::OnMouseDown(wxMouseEvent& evt) btn_rect.SetSize(size.size); if(btn_rect.Contains(cursor)) { - m_active_button = &instance; - cursor -= btn_rect.GetTopLeft(); - long state = 0; - if(size.normal_region.Contains(cursor)) - state = wxRIBBON_BUTTONBAR_BUTTON_NORMAL_ACTIVE; - else if(size.dropdown_region.Contains(cursor)) - state = wxRIBBON_BUTTONBAR_BUTTON_DROPDOWN_ACTIVE; - instance.base->state |= state; - Refresh(false); - break; + if((instance.base->state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) == 0) + { + m_active_button = &instance; + cursor -= btn_rect.GetTopLeft(); + long state = 0; + if(size.normal_region.Contains(cursor)) + state = wxRIBBON_BUTTONBAR_BUTTON_NORMAL_ACTIVE; + else if(size.dropdown_region.Contains(cursor)) + state = wxRIBBON_BUTTONBAR_BUTTON_DROPDOWN_ACTIVE; + instance.base->state |= state; + Refresh(false); + break; + } } } } @@ -935,11 +1145,21 @@ void wxRibbonButtonBar::OnMouseUp(wxMouseEvent& evt) else break; wxRibbonButtonBarEvent notification(event_type, id); + if(m_active_button->base->kind == wxRIBBON_BUTTON_TOGGLE) + { + m_active_button->base->state ^= + wxRIBBON_BUTTONBAR_BUTTON_TOGGLED; + notification.SetInt(m_active_button->base->state & + wxRIBBON_BUTTONBAR_BUTTON_TOGGLED); + } notification.SetEventObject(this); notification.SetBar(this); + notification.SetButton(m_active_button->base); m_lock_active_state = true; ProcessWindowEvent(notification); m_lock_active_state = false; + + wxStaticCast(m_parent, wxRibbonPanel)->HideIfExpanded(); } while(false); if(m_active_button) // may have been NULLed by event handler { @@ -977,6 +1197,45 @@ void wxRibbonButtonBar::OnMouseLeave(wxMouseEvent& WXUNUSED(evt)) Refresh(false); } +wxRibbonButtonBarButtonBase *wxRibbonButtonBar::GetActiveItem() const +{ + return m_active_button == NULL ? NULL : m_active_button->base; +} + + +wxRibbonButtonBarButtonBase *wxRibbonButtonBar::GetHoveredItem() const +{ + return m_hovered_button == NULL ? NULL : m_hovered_button->base; +} + + +wxRibbonButtonBarButtonBase *wxRibbonButtonBar::GetItem(size_t n) const +{ + wxCHECK_MSG(n < m_buttons.GetCount(), NULL, "wxRibbonButtonBar item's index is out of bound"); + return m_buttons.Item(n); +} + +wxRibbonButtonBarButtonBase *wxRibbonButtonBar::GetItemById(int button_id) const +{ + size_t count = m_buttons.GetCount(); + for ( size_t i = 0; i < count; ++i ) + { + wxRibbonButtonBarButtonBase* button = m_buttons.Item(i); + if ( button->id == button_id ) + return button; + } + + return NULL; + +} + +int wxRibbonButtonBar::GetItemId(wxRibbonButtonBarButtonBase *item) const +{ + wxCHECK_MSG(item != NULL, wxNOT_FOUND, "wxRibbonButtonBar item should not be NULL"); + return item->id; +} + + bool wxRibbonButtonBarEvent::PopupMenu(wxMenu* menu) { wxPoint pos = wxDefaultPosition;