// Author: Robert Roebling, Vadim Zeitlin (universalization)
// Modified by:
// Created: 20.02.02
-// Id: $Id$
// Copyright: (c) 2001 Robert Roebling,
// (c) 2002 SciTech Software, Inc. (www.scitechsoft.com)
// Licence: wxWindows licence
#include "wx/utils.h"
#include "wx/app.h"
#include "wx/log.h"
+ #include "wx/frame.h"
+ #include "wx/dc.h"
+ #include "wx/image.h"
#endif
#include "wx/univ/renderer.h"
-#include "wx/frame.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
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 =
return false;
}
+ FixupStyle();
+
CreateInputHandler(wxINP_HANDLER_TOOLBAR);
- SetBestSize(size);
+ SetInitialSize(size);
return true;
}
{
wxToolBarToolBase *tool = FindById(id);
- wxCHECK_RET( tool, _T("SetToolShortHelp: no such tool") );
+ wxCHECK_RET( tool, wxT("SetToolShortHelp: no such tool") );
tool->SetShortHelp(help);
}
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();
+ wxImage image(tool->GetNormalBitmap().ConvertToImage());
- 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 );
- }
- }
- }
-
- 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);
}
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);
}
// ----------------------------------------------------------------------------
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 )
{
if (tool->IsButton())
{
- rect.width = m_defaultWidth;
- rect.height = m_defaultHeight;
+ if(!HasFlag(wxTB_TEXT))
+ {
+ rect.width = m_defaultWidth;
+ rect.height = m_defaultHeight;
+ }
+ else
+ {
+ rect.width = m_defaultWidth +
+ GetFont().GetPointSize() * tool->GetLabel().length();
+ rect.height = m_defaultHeight;
+ }
}
else if (tool->IsSeparator())
{
{
if (tool->IsButton())
{
- rect.width = m_defaultWidth;
- rect.height = m_defaultHeight;
+ if(!HasFlag(wxTB_TEXT))
+ {
+ rect.width = m_defaultWidth;
+ rect.height = m_defaultHeight;
+ }
+ else
+ {
+ rect.width = m_defaultWidth +
+ GetFont().GetPointSize() * tool->GetLabel().length();
+ rect.height = m_defaultHeight;
+ }
}
else if (tool->IsSeparator())
{
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;
}
+void wxToolBar::SetWindowStyleFlag( long style )
+{
+ wxToolBarBase::SetWindowStyleFlag(style);
+
+ m_needsLayout = true;
+
+ Refresh();
+}
+
void wxToolBar::DoLayout()
{
- wxASSERT_MSG( m_needsLayout, _T("why are we called?") );
+ wxASSERT_MSG( m_needsLayout, wxT("why are we called?") );
m_needsLayout = false;
wxCoord x = m_xMargin,
y = m_yMargin;
- const wxCoord widthTool = IsVertical() ? m_defaultHeight : m_defaultWidth;
+ wxCoord widthTool = 0, maxWidthTool = 0;
+ wxCoord heightTool = 0, maxHeightTool = 0;
wxCoord margin = IsVertical() ? m_xMargin : m_yMargin;
wxCoord *pCur = IsVertical() ? &y : &x;
// TODO ugly number fiddling
if (tool->IsButton())
{
+ if (IsVertical())
+ {
+ widthTool = m_defaultHeight;
+ heightTool = m_defaultWidth;
+ if(HasFlag(wxTB_TEXT))
+ heightTool += GetFont().GetPointSize() * tool->GetLabel().length();
+ }
+ else
+ {
+ widthTool = m_defaultWidth;
+ if(HasFlag(wxTB_TEXT))
+ widthTool += GetFont().GetPointSize() * tool->GetLabel().length();
+
+ heightTool = m_defaultHeight;
+ }
+
+ if(widthTool > maxWidthTool) // Record max width of tool
+ {
+ maxWidthTool = widthTool;
+ }
+
+ if(heightTool > maxHeightTool) // Record max width of tool
+ {
+ maxHeightTool = heightTool;
+ }
+
*pCur += widthTool;
}
else if (tool->IsSeparator())
}
// calculate the total toolbar size
- wxCoord xMin = m_defaultWidth + 2*m_xMargin,
- yMin = m_defaultHeight + 2*m_yMargin;
+ wxCoord xMin, yMin;
+
+ if(!HasFlag(wxTB_TEXT))
+ {
+ xMin = m_defaultWidth + 2*m_xMargin;
+ yMin = m_defaultHeight + 2*m_yMargin;
+ }
+ else
+ {
+ if (IsVertical())
+ {
+ xMin = heightTool + 2*m_xMargin;
+ yMin = widthTool + 2*m_xMargin;
+ }
+ else
+ {
+ xMin = maxWidthTool + 2*m_xMargin;
+ yMin = heightTool + 2*m_xMargin;
+ }
+ }
m_maxWidth = x < xMin ? xMin : x;
m_maxHeight = y < yMin ? yMin : y;
// 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();
}
}
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() )
{
// prepare the variables used below
wxDC& dc = renderer->GetDC();
wxRenderer *rend = renderer->GetRenderer();
- // dc.SetFont(GetFont()); -- uncomment when we support labels
+ dc.SetFont(GetFont());
// draw the border separating us from the menubar (if there is no menubar
// we probably shouldn't draw it?)
wxBitmap bitmap;
if ( !tool->IsSeparator() )
{
- // label = tool->GetLabel();
+ 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() )
{
- rend->DrawToolBarButton(dc, label, bitmap, rectTool, flags, tool->GetStyle());
+ int tbStyle = HasFlag(wxTB_VERTICAL) ? wxTB_VERTICAL : wxTB_HORIZONTAL;
+ if ( HasFlag(wxTB_TEXT) )
+ tbStyle |= wxTB_TEXT;
+
+ rend->DrawToolBarButton(dc, label, bitmap, rectTool, flags,
+ tool->GetStyle(), tbStyle);
}
else // control
{
PerformAction( wxACTION_BUTTON_CLICK, numArg );
- // Write by Danny Raynor to change state again.
- // Check button still pressed or not
- 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();
}
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 );
}
bool isToggled;
if ( tool->CanBeToggled() )
{
- tool->Toggle();
+ if ( tool->IsButton() && tool->GetKind() == wxITEM_RADIO )
+ {
+ UnToggleRadioGroup(tool);
+ tool->Toggle(true);
+ }
+ else
+ {
+ tool->Toggle();
+ }
RefreshTool( tool );
}
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() )
{
}
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() )
{
return true;
}
+/* static */
+wxInputHandler *wxToolBar::GetStdInputHandler(wxInputHandler *handlerDef)
+{
+ static wxStdToolbarInputHandler s_handler(handlerDef);
+
+ return &s_handler;
+}
+
// ============================================================================
// wxStdToolbarInputHandler implementation
// ============================================================================