X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/370efbe74165c03642ea7620d35d9e0be8572d74..64ea838d8f4d1853b7d850db93ee565e901d099a:/src/univ/toolbar.cpp diff --git a/src/univ/toolbar.cpp b/src/univ/toolbar.cpp index bdd436fc04..da03781e9c 100644 --- a/src/univ/toolbar.cpp +++ b/src/univ/toolbar.cpp @@ -35,11 +35,35 @@ #include "wx/log.h" #include "wx/frame.h" #include "wx/dc.h" + #include "wx/image.h" #endif #include "wx/univ/renderer.h" -#include "wx/image.h" +// ---------------------------------------------------------------------------- +// wxStdToolbarInputHandler: translates SPACE and ENTER keys and the left mouse +// click into button press/release actions +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxStdToolbarInputHandler : public wxStdInputHandler +{ +public: + wxStdToolbarInputHandler(wxInputHandler *inphand); + + virtual bool HandleKey(wxInputConsumer *consumer, + const wxKeyEvent& event, + bool pressed); + virtual bool HandleMouse(wxInputConsumer *consumer, + const wxMouseEvent& event); + virtual bool HandleMouseMove(wxInputConsumer *consumer, const wxMouseEvent& event); + virtual bool HandleFocus(wxInputConsumer *consumer, const wxFocusEvent& event); + virtual bool HandleActivation(wxInputConsumer *consumer, bool activated); + +private: + wxWindow *m_winCapture; + wxToolBarToolBase *m_toolCapture; + wxToolBarToolBase *m_toolLast; +}; // ---------------------------------------------------------------------------- // constants @@ -80,8 +104,8 @@ public: m_underMouse = false; } - wxToolBarTool(wxToolBar *tbar, wxControl *control) - : wxToolBarToolBase(tbar, control) + wxToolBarTool(wxToolBar *tbar, wxControl *control, const wxString& label) + : wxToolBarToolBase(tbar, control, label) { // no position yet m_x = @@ -166,9 +190,11 @@ bool wxToolBar::Create(wxWindow *parent, return false; } + FixupStyle(); + CreateInputHandler(wxINP_HANDLER_TOOLBAR); - SetBestSize(size); + SetInitialSize(size); return true; } @@ -234,7 +260,7 @@ void wxToolBar::SetToolShortHelp(int id, const wxString& help) { wxToolBarToolBase *tool = FindById(id); - wxCHECK_RET( tool, _T("SetToolShortHelp: no such tool") ); + wxCHECK_RET( tool, wxT("SetToolShortHelp: no such tool") ); tool->SetShortHelp(help); } @@ -264,59 +290,15 @@ bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), void wxToolBar::DoEnableTool(wxToolBarToolBase *tool, bool enable) { +#if wxUSE_IMAGE // created disabled-state bitmap on demand - if ( !enable && !tool->GetDisabledBitmap().Ok() ) + if ( !enable && !tool->GetDisabledBitmap().IsOk() ) { - wxImage image( tool->GetNormalBitmap().ConvertToImage() ); - - // TODO: don't hardcode 180 - unsigned char bg_red = 180; - unsigned char bg_green = 180; - unsigned char bg_blue = 180; - - unsigned char mask_red = image.GetMaskRed(); - unsigned char mask_green = image.GetMaskGreen(); - unsigned char mask_blue = image.GetMaskBlue(); - - bool has_mask = image.HasMask(); - - int x,y; - for (y = 0; y < image.GetHeight(); y++) - { - for (x = 0; x < image.GetWidth(); x++) - { - unsigned char red = image.GetRed(x,y); - unsigned char green = image.GetGreen(x,y); - unsigned char blue = image.GetBlue(x,y); - if (!has_mask || red != mask_red || green != mask_green || blue != mask_blue) - { - red = (unsigned char)((((wxInt32) red - bg_red) >> 1) + bg_red); - green = (unsigned char)((((wxInt32) green - bg_green) >> 1) + bg_green); - blue = (unsigned char)((((wxInt32) blue - bg_blue) >> 1) + bg_blue); - image.SetRGB( x, y, red, green, blue ); - } - } - } + wxImage image(tool->GetNormalBitmap().ConvertToImage()); - for (y = 0; y < image.GetHeight(); y++) - { - for (x = y % 2; x < image.GetWidth(); x += 2) - { - unsigned char red = image.GetRed(x,y); - unsigned char green = image.GetGreen(x,y); - unsigned char blue = image.GetBlue(x,y); - if (!has_mask || red != mask_red || green != mask_green || blue != mask_blue) - { - red = (unsigned char)((((wxInt32) red - bg_red) >> 1) + bg_red); - green = (unsigned char)((((wxInt32) green - bg_green) >> 1) + bg_green); - blue = (unsigned char)((((wxInt32) blue - bg_blue) >> 1) + bg_blue); - image.SetRGB( x, y, red, green, blue ); - } - } - } - - tool->SetDisabledBitmap(image); + tool->SetDisabledBitmap(image.ConvertToGreyscale()); } +#endif // wxUSE_IMAGE RefreshTool(tool); } @@ -346,9 +328,10 @@ wxToolBarToolBase *wxToolBar::CreateTool(int id, clientData, shortHelp, longHelp); } -wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control) +wxToolBarToolBase * +wxToolBar::CreateTool(wxControl *control, const wxString& label) { - return new wxToolBarTool(this, control); + return new wxToolBarTool(this, control, label); } // ---------------------------------------------------------------------------- @@ -361,7 +344,7 @@ wxRect wxToolBar::GetToolRect(wxToolBarToolBase *toolBase) const wxRect rect; - wxCHECK_MSG( tool, rect, _T("GetToolRect: NULL tool") ); + wxCHECK_MSG( tool, rect, wxT("GetToolRect: NULL tool") ); // ensure that we always have the valid tool position if ( m_needsLayout ) @@ -441,7 +424,30 @@ bool wxToolBar::Realize() m_needsLayout = true; DoLayout(); - SetBestSize(wxDefaultSize); + // the first item in the radio group is checked by default to be consistent + // with wxGTK and the menu radio items + int radioGroupCount = 0; + + for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst(); + node; + node = node->GetNext() ) + { + wxToolBarTool *tool = (wxToolBarTool*) node->GetData(); + + if ( !tool->IsButton() || tool->GetKind() != wxITEM_RADIO ) + { + radioGroupCount = 0; + continue; + } + + bool toggle = !radioGroupCount++; + if ( tool->Toggle(toggle) ) + { + DoToggleTool(tool, toggle); + } + } + + SetInitialSize(wxDefaultSize); return true; } @@ -457,7 +463,7 @@ void wxToolBar::SetWindowStyleFlag( long style ) void wxToolBar::DoLayout() { - wxASSERT_MSG( m_needsLayout, _T("why are we called?") ); + wxASSERT_MSG( m_needsLayout, wxT("why are we called?") ); m_needsLayout = false; @@ -581,13 +587,7 @@ void wxToolBar::DoSetSize(int x, int y, int width, int height, int sizeFlags) // otherwise the toolbar can be shown incorrectly if ( old_width != width || old_height != height ) { - // But before we send the size event check it - // we have a frame that is not being deleted. - wxFrame *frame = wxDynamicCast(GetParent(), wxFrame); - if ( frame && !frame->IsBeingDeleted() ) - { - frame->SendSizeEvent(); - } + SendSizeEventToParent(); } } @@ -604,7 +604,7 @@ void wxToolBar::GetRectLimits(const wxRect& rect, wxCoord *start, wxCoord *end) const { - wxCHECK_RET( start && end, _T("NULL pointer in GetRectLimits") ); + wxCHECK_RET( start && end, wxT("NULL pointer in GetRectLimits") ); if ( IsVertical() ) { @@ -691,26 +691,26 @@ void wxToolBar::DoDraw(wxControlRenderer *renderer) { label = tool->GetLabel(); bitmap = tool->GetBitmap(); + + if ( !bitmap.IsOk() ) + { + // it's better not to draw anything than to assert inside + // drawing code as this results in an almost guaranteed crash + // as we're likely to be called by a paint event handler and so + // the assert is going to be triggered again and again and ... + continue; + } } //else: leave both the label and the bitmap invalid to draw a separator if ( !tool->IsControl() ) { - int tbStyle = 0; - if(HasFlag(wxTB_TEXT)) - { + int tbStyle = HasFlag(wxTB_VERTICAL) ? wxTB_VERTICAL : wxTB_HORIZONTAL; + if ( HasFlag(wxTB_TEXT) ) tbStyle |= wxTB_TEXT; - } - if(HasFlag(wxTB_VERTICAL)) - { - tbStyle |= wxTB_VERTICAL; - } - else - { - tbStyle |= wxTB_HORIZONTAL; - } - rend->DrawToolBarButton(dc, label, bitmap, rectTool, flags, tool->GetStyle(), tbStyle); + rend->DrawToolBarButton(dc, label, bitmap, rectTool, flags, + tool->GetStyle(), tbStyle); } else // control { @@ -738,25 +738,13 @@ bool wxToolBar::PerformAction(const wxControlAction& action, PerformAction( wxACTION_BUTTON_CLICK, numArg ); - // Write by Danny Raynor to change state again. - // Check button still pressed or not - if ( tool->CanBeToggled() && tool->IsToggled() ) - { - tool->Toggle(false); - } - - if( tool->IsInverted() ) - { - PerformAction( wxACTION_TOOLBAR_RELEASE, numArg ); - } - // Set mouse leave toolbar button range (If still in the range, // toolbar button would get focus again PerformAction( wxACTION_TOOLBAR_LEAVE, numArg ); } else if ( action == wxACTION_TOOLBAR_PRESS ) { - wxLogTrace(_T("toolbar"), _T("Button '%s' pressed."), tool->GetShortHelp().c_str()); + wxLogTrace(wxT("toolbar"), wxT("Button '%s' pressed."), tool->GetShortHelp().c_str()); tool->Invert(); @@ -764,11 +752,14 @@ bool wxToolBar::PerformAction(const wxControlAction& action, } else if ( action == wxACTION_TOOLBAR_RELEASE ) { - wxLogTrace(_T("toolbar"), _T("Button '%s' released."), tool->GetShortHelp().c_str()); + wxLogTrace(wxT("toolbar"), wxT("Button '%s' released."), tool->GetShortHelp().c_str()); - wxASSERT_MSG( tool->IsInverted(), _T("release unpressed button?") ); + wxASSERT_MSG( tool->IsInverted(), wxT("release unpressed button?") ); - tool->Invert(); + if(tool->IsInverted()) + { + tool->Invert(); + } RefreshTool( tool ); } @@ -777,7 +768,15 @@ bool wxToolBar::PerformAction(const wxControlAction& action, bool isToggled; if ( tool->CanBeToggled() ) { - tool->Toggle(); + if ( tool->IsButton() && tool->GetKind() == wxITEM_RADIO ) + { + UnToggleRadioGroup(tool); + tool->Toggle(true); + } + else + { + tool->Toggle(); + } RefreshTool( tool ); @@ -791,7 +790,7 @@ bool wxToolBar::PerformAction(const wxControlAction& action, } else if ( action == wxACTION_TOOLBAR_ENTER ) { - wxCHECK_MSG( tool, false, _T("no tool to enter?") ); + wxCHECK_MSG( tool, false, wxT("no tool to enter?") ); if ( HasFlag(wxTB_FLAT) && tool->IsEnabled() ) { @@ -803,7 +802,7 @@ bool wxToolBar::PerformAction(const wxControlAction& action, } else if ( action == wxACTION_TOOLBAR_LEAVE ) { - wxCHECK_MSG( tool, false, _T("no tool to leave?") ); + wxCHECK_MSG( tool, false, wxT("no tool to leave?") ); if ( HasFlag(wxTB_FLAT) && tool->IsEnabled() ) { @@ -819,6 +818,14 @@ bool wxToolBar::PerformAction(const wxControlAction& action, return true; } +/* static */ +wxInputHandler *wxToolBar::GetStdInputHandler(wxInputHandler *handlerDef) +{ + static wxStdToolbarInputHandler s_handler(handlerDef); + + return &s_handler; +} + // ============================================================================ // wxStdToolbarInputHandler implementation // ============================================================================