BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent)
EVT_SYS_COLOUR_CHANGED(wxToolBar::OnSysColourChanged)
+ EVT_ERASE_BACKGROUND(wxToolBar::OnEraseBackground)
END_EVENT_TABLE()
// ----------------------------------------------------------------------------
// in WM_ERASEBKGND too (by default this won't be done but if the toolbar
// has a non default background colour, then it would be used in both
// places resulting in flicker)
- SetBackgroundStyle(wxBG_STYLE_PAINT);
+ if (wxApp::GetComCtl32Version() >= 600)
+ {
+ SetBackgroundStyle(wxBG_STYLE_PAINT);
+ }
return true;
}
m_hBitmap = 0;
}
- if ( m_disabledImgList )
- {
- delete m_disabledImgList;
- m_disabledImgList = NULL;
- }
+ wxDELETE(m_disabledImgList);
Realize();
}
// get the size of the button we're going to delete
const RECT r = wxGetTBItemRect(GetHwnd(), pos);
- int width = r.right - r.left;
+ int delta = IsVertical() ? r.bottom - r.top : r.right - r.left;
if ( tool->IsControl() )
{
nButtonsToDelete = ((wxToolBarTool *)tool)->GetSeparatorsCount();
- width *= nButtonsToDelete;
+
+ if ( !IsVertical() )
+ delta *= nButtonsToDelete;
}
+ m_totalFixedSize -= delta;
+
// do delete all buttons
m_nButtons -= nButtonsToDelete;
while ( nButtonsToDelete-- > 0 )
}
}
- // and finally reposition all the controls after this button (the toolbar
- // takes care of all normal items)
- for ( /* node -> first after deleted */ ; node; node = node->GetNext() )
+ // and finally rearrange the tools
+
+ // search for any stretch spacers before the removed tool
+ bool hasPrecedingStrechables = false;
+ for ( wxToolBarToolsList::compatibility_iterator nodeStch = m_tools.GetFirst();
+ nodeStch != node; nodeStch = nodeStch->GetNext() )
{
- wxToolBarTool *tool2 = (wxToolBarTool*)node->GetData();
- if ( tool2->IsControl() )
+ if ( ((wxToolBarTool*)nodeStch->GetData())->IsStretchable() )
{
- tool2->MoveBy(-width);
+ hasPrecedingStrechables = true;
+ break;
+ }
+ }
+
+ if ( hasPrecedingStrechables )
+ {
+ // if the removed tool is preceded by stretch spacers
+ // just redistribute the space
+ UpdateStretchableSpacersSize();
+ }
+ else
+ {
+ // reposition all the controls after this button but before any
+ // stretch spacer (the toolbar takes care of all normal items)
+ for ( /* node -> first after deleted */ ; node; node = node->GetNext() )
+ {
+ wxToolBarTool *tool2 = (wxToolBarTool*)node->GetData();
+
+ if ( tool2->IsControl() )
+ {
+ tool2->MoveBy(-delta);
+ }
+
+ // if a stretch spacer is found just redistribute the available space
+ else if ( tool2->IsStretchable() )
+ {
+ UpdateStretchableSpacersSize();
+ break;
+ }
}
}
void wxToolBar::CreateDisabledImageList()
{
- if (m_disabledImgList != NULL)
- {
- delete m_disabledImgList;
- m_disabledImgList = NULL;
- }
+ wxDELETE(m_disabledImgList);
// as we can't use disabled image list with older versions of comctl32.dll,
// don't even bother creating it
{
wxToolBarToolBase *tool = node->GetData();
wxBitmap bmpDisabled = tool->GetDisabledBitmap();
- if ( bmpDisabled.Ok() )
+ if ( bmpDisabled.IsOk() )
{
+ const wxSize sizeBitmap = bmpDisabled.GetSize();
m_disabledImgList = new wxImageList
(
- m_defaultWidth,
- m_defaultHeight,
+ sizeBitmap.x,
+ sizeBitmap.y,
bmpDisabled.GetMask() != NULL,
GetToolsCount()
);
const int w = bmp.GetWidth();
const int h = bmp.GetHeight();
- if ( bmp.Ok() )
+ if ( bmp.IsOk() )
{
int xOffset = wxMax(0, (m_defaultWidth - w)/2);
int yOffset = wxMax(0, (m_defaultHeight - h)/2);
{
wxBitmap bmpDisabled = tool->GetDisabledBitmap();
#if wxUSE_IMAGE && wxUSE_WXDIB
- if ( !bmpDisabled.Ok() )
+ if ( !bmpDisabled.IsOk() )
{
// no disabled bitmap specified but we still need to
// fill the space in the image list with something, so
{
const wxString& label = tool->GetLabel();
if ( !label.empty() )
- button.iString = (INT_PTR)label.wx_str();
+ button.iString = (INT_PTR) wxMSW_CONV_LPCTSTR(label);
}
button.idCommand = tool->GetId();
break;
}
+ // Instead of using fixed widths for all buttons, size them
+ // automatically according to the size of their bitmap and text
+ // label, if present. This particularly matters for toolbars
+ // with the wxTB_HORZ_LAYOUT style: they look hideously ugly
+ // without autosizing when the labels have even slightly
+ // different lengths.
+ button.fsStyle |= TBSTYLE_AUTOSIZE;
+
bitmapId++;
break;
}
// reduce their size if there is not enough place for all tools
const int totalSize = IsVertical() ? GetClientSize().y : GetClientSize().x;
const int extraSize = totalSize - m_totalFixedSize;
- const int sizeSpacer = extraSize > 0 ? extraSize / numSpaces : 0;
+ const int sizeSpacer = extraSize > 0 ? extraSize / numSpaces : 1;
// the last spacer should consume all remaining space if we have too much
// of it (which can be greater than sizeSpacer because of the rounding)
const int sizeLastSpacer = extraSize > 0
? extraSize - (numSpaces - 1)*sizeSpacer
- : 0;
+ : 1;
// cumulated offset by which we need to move all the following controls to
// the right: while the toolbar takes care of the normal items, we must
// Without the two lines of code below, if the toolbar was repainted during
// OnLeftClick(), then it could end up without the tool bitmap temporarily
// (see http://lists.nongnu.org/archive/html/lmi/2008-10/msg00014.html).
- // The Update() call bellow ensures that this won't happen, by repainting
+ // The Update() call below ensures that this won't happen, by repainting
// invalidated areas of the toolbar immediately.
//
// To complicate matters, the tool would be drawn in depressed state (this
::SendMessage(GetHwnd(), TB_SETSTATE, id, MAKELONG(state, 0));
// OnLeftClick() can veto the button state change - for buttons which
- // may be toggled only, of couse
+ // may be toggled only, of course.
if ( !allowLeftClick && tool->CanBeToggled() )
{
// revert back
}
}
+// This handler is needed to fix problems with painting the background of
+// toolbar icons with comctl32.dll < 6.0.
+void wxToolBar::OnEraseBackground(wxEraseEvent& event)
+{
+#ifdef wxHAS_MSW_BACKGROUND_ERASE_HOOK
+ MSWDoEraseBackground(event.GetDC()->GetHDC());
+#endif // wxHAS_MSW_BACKGROUND_ERASE_HOOK
+}
+
bool wxToolBar::HandleSize(WXWPARAM WXUNUSED(wParam), WXLPARAM lParam)
{
// wait until we have some tools
{
// for some reason TB_GETITEMRECT returns a rectangle 1 pixel
// shorter than the full window size (at least under Windows 7)
- // but we need to erase the full height below
+ // but we need to erase the full width/height below
RECT rcItem = wxGetTBItemRect(GetHwnd(), toolIndex);
- rcItem.top = 0;
- rcItem.bottom = rectTotal.height;
+ if ( IsVertical() )
+ {
+ rcItem.left = 0;
+ rcItem.right = rectTotal.width;
+ }
+ else
+ {
+ rcItem.top = 0;
+ rcItem.bottom = rectTotal.height;
+ }
rgnDummySeps.Union(wxRectFromRECT(rcItem));
}
wxBrush * const
brush = wxTheBrushList->FindOrCreateBrush(colBg);
- return brush ? brush->GetResourceHandle() : 0;
+ return brush ? static_cast<WXHBRUSH>(brush->GetResourceHandle()) : 0;
}
WXHBRUSH wxToolBar::MSWGetBgBrushForChild(WXHDC hDC, wxWindowMSW *child)