X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b7ae02541f7b77c82308884e02873a4fc52c676b..769c3372a2bd68c45d1a4afc8462d3b7939decb1:/src/aui/auibar.cpp diff --git a/src/aui/auibar.cpp b/src/aui/auibar.cpp index 6634ee8b85..9d86d69a0c 100644 --- a/src/aui/auibar.cpp +++ b/src/aui/auibar.cpp @@ -1,11 +1,11 @@ /////////////////////////////////////////////////////////////////////////////// -// Name: src/aui/dockart.cpp +// Name: src/aui/auibar.cpp // Purpose: wxaui: wx advanced user interface - docking window manager // Author: Benjamin I. Williams // Modified by: // Created: 2005-05-17 -// RCS-ID: $Id: dockart.cpp 48848 2007-09-21 10:19:53Z SC $ +// RCS-ID: $Id$ // Copyright: (C) Copyright 2005-2006, Kirix Corporation, All Rights Reserved // Licence: wxWindows Library Licence, Version 3.1 /////////////////////////////////////////////////////////////////////////////// @@ -36,19 +36,19 @@ #include "wx/aui/auibar.h" #include "wx/aui/framemanager.h" -#ifdef __WXMAC__ -#include "wx/osx/private.h" +#ifdef __WXMAC__ +#include "wx/osx/private.h" #endif #include "wx/arrimpl.cpp" WX_DEFINE_OBJARRAY(wxAuiToolBarItemArray) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUITOOLBAR_TOOL_DROPDOWN) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUITOOLBAR_OVERFLOW_CLICK) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUITOOLBAR_RIGHT_CLICK) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUITOOLBAR_MIDDLE_CLICK) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUITOOLBAR_BEGIN_DRAG) +wxDEFINE_EVENT( wxEVT_COMMAND_AUITOOLBAR_TOOL_DROPDOWN, wxAuiToolBarEvent ); +wxDEFINE_EVENT( wxEVT_COMMAND_AUITOOLBAR_OVERFLOW_CLICK, wxAuiToolBarEvent ); +wxDEFINE_EVENT( wxEVT_COMMAND_AUITOOLBAR_RIGHT_CLICK, wxAuiToolBarEvent ); +wxDEFINE_EVENT( wxEVT_COMMAND_AUITOOLBAR_MIDDLE_CLICK, wxAuiToolBarEvent ); +wxDEFINE_EVENT( wxEVT_COMMAND_AUITOOLBAR_BEGIN_DRAG, wxAuiToolBarEvent ); IMPLEMENT_CLASS(wxAuiToolBar, wxControl) @@ -69,13 +69,10 @@ const int BUTTON_DROPDOWN_WIDTH = 10; wxBitmap wxAuiBitmapFromBits(const unsigned char bits[], int w, int h, const wxColour& color); -double wxAuiBlendColour(double fg, double bg, double alpha); -wxColor wxAuiStepColour(const wxColor& c, int percent); - static wxBitmap MakeDisabledBitmap(wxBitmap& bmp) { wxImage image = bmp.ConvertToImage(); - + int mr, mg, mb; mr = image.GetMaskRed(); mg = image.GetMaskGreen(); @@ -98,9 +95,9 @@ static wxBitmap MakeDisabledBitmap(wxBitmap& bmp) if (has_mask && *r == mr && *g == mg && *b == mb) continue; - *r = (unsigned char)wxAuiBlendColour((double)*r, 255.0, 0.4); - *g = (unsigned char)wxAuiBlendColour((double)*g, 255.0, 0.4); - *b = (unsigned char)wxAuiBlendColour((double)*b, 255.0, 0.4); + *r = wxColour::AlphaBlend(*r, 255, 0.4); + *g = wxColour::AlphaBlend(*g, 255, 0.4); + *b = wxColour::AlphaBlend(*b, 255, 0.4); } } @@ -110,24 +107,22 @@ static wxBitmap MakeDisabledBitmap(wxBitmap& bmp) static wxColor GetBaseColor() { -#ifdef __WXMAC__ - wxBrush toolbarbrush; - toolbarbrush.MacSetTheme( kThemeBrushToolbarBackground ); - wxColor base_color = toolbarbrush.GetColour(); +#if defined( __WXMAC__ ) && wxOSX_USE_COCOA_OR_CARBON + wxColor base_colour = wxColour( wxMacCreateCGColorFromHITheme(kThemeBrushToolbarBackground)); #else - wxColor base_color = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); + wxColor base_colour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); #endif // the base_colour is too pale to use as our base colour, // so darken it a bit -- - if ((255-base_color.Red()) + - (255-base_color.Green()) + - (255-base_color.Blue()) < 60) + if ((255-base_colour.Red()) + + (255-base_colour.Green()) + + (255-base_colour.Blue()) < 60) { - base_color = wxAuiStepColour(base_color, 92); + base_colour = base_colour.ChangeLightness(92); } - return base_color; + return base_colour; } @@ -159,10 +154,11 @@ private: -const wxColour DISABLED_TEXT_COLOR = wxColour(wxAuiBlendColour(0,255,0.4), - wxAuiBlendColour(0,255,0.4), - wxAuiBlendColour(0,255,0.4)); - +static const unsigned char + DISABLED_TEXT_GREY_HUE = wxColour::AlphaBlend(0, 255, 0.4); +const wxColour DISABLED_TEXT_COLOR(DISABLED_TEXT_GREY_HUE, + DISABLED_TEXT_GREY_HUE, + DISABLED_TEXT_GREY_HUE); wxAuiDefaultToolBarArt::wxAuiDefaultToolBarArt() { @@ -171,24 +167,24 @@ wxAuiDefaultToolBarArt::wxAuiDefaultToolBarArt() m_flags = 0; m_text_orientation = wxAUI_TBTOOL_TEXT_BOTTOM; m_highlight_colour = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT); - + m_separator_size = 7; m_gripper_size = 7; m_overflow_size = 16; - wxColor darker1_colour = wxAuiStepColour(m_base_colour, 85); - wxColor darker2_colour = wxAuiStepColour(m_base_colour, 75); - wxColor darker3_colour = wxAuiStepColour(m_base_colour, 60); - wxColor darker4_colour = wxAuiStepColour(m_base_colour, 50); - wxColor darker5_colour = wxAuiStepColour(m_base_colour, 40); + wxColor darker1_colour = m_base_colour.ChangeLightness(85); + wxColor darker2_colour = m_base_colour.ChangeLightness(75); + wxColor darker3_colour = m_base_colour.ChangeLightness(60); + wxColor darker4_colour = m_base_colour.ChangeLightness(50); + wxColor darker5_colour = m_base_colour.ChangeLightness(40); m_gripper_pen1 = wxPen(darker5_colour); m_gripper_pen2 = wxPen(darker3_colour); m_gripper_pen3 = *wxWHITE_PEN; - - static unsigned char button_dropdown_bits[] = { 0xe0, 0xf1, 0xfb }; - static unsigned char overflow_bits[] = { 0x80, 0xff, 0x80, 0xc1, 0xe3, 0xf7 }; - + + static const unsigned char button_dropdown_bits[] = { 0xe0, 0xf1, 0xfb }; + static const unsigned char overflow_bits[] = { 0x80, 0xff, 0x80, 0xc1, 0xe3, 0xf7 }; + m_button_dropdown_bmp = wxAuiBitmapFromBits(button_dropdown_bits, 5, 3, *wxBLACK); m_disabled_button_dropdown_bmp = wxAuiBitmapFromBits( @@ -226,6 +222,21 @@ void wxAuiDefaultToolBarArt::SetTextOrientation(int orientation) m_text_orientation = orientation; } +unsigned int wxAuiDefaultToolBarArt::GetFlags() +{ + return m_flags; +} + +wxFont wxAuiDefaultToolBarArt::GetFont() +{ + return m_font; +} + +int wxAuiDefaultToolBarArt::GetTextOrientation() +{ + return m_text_orientation; +} + void wxAuiDefaultToolBarArt::DrawBackground( wxDC& dc, wxWindow* WXUNUSED(wnd), @@ -233,8 +244,8 @@ void wxAuiDefaultToolBarArt::DrawBackground( { wxRect rect = _rect; rect.height++; - wxColour start_colour = wxAuiStepColour(m_base_colour, 150); - wxColour end_colour = wxAuiStepColour(m_base_colour, 90); + wxColour start_colour = m_base_colour.ChangeLightness(150); + wxColour end_colour = m_base_colour.ChangeLightness(90); dc.GradientFillLinear(rect, start_colour, end_colour, wxSOUTH); } @@ -260,7 +271,7 @@ void wxAuiDefaultToolBarArt::DrawLabel( int text_x, text_y; text_x = rect.x + 1; text_y = rect.y + (rect.height-text_height)/2; - dc.DrawText(item.label, text_x, text_y); + dc.DrawText(item.GetLabel(), text_x, text_y); dc.DestroyClippingRegion(); } @@ -272,98 +283,96 @@ void wxAuiDefaultToolBarArt::DrawButton( const wxRect& rect) { int text_width = 0, text_height = 0; - + if (m_flags & wxAUI_TB_TEXT) { dc.SetFont(m_font); - + int tx, ty; dc.GetTextExtent(wxT("ABCDHgj"), &tx, &text_height); text_width = 0; - dc.GetTextExtent(item.label, &text_width, &ty); + dc.GetTextExtent(item.GetLabel(), &text_width, &ty); } int bmp_x = 0, bmp_y = 0; int text_x = 0, text_y = 0; - + if (m_text_orientation == wxAUI_TBTOOL_TEXT_BOTTOM) { bmp_x = rect.x + (rect.width/2) - - (item.bitmap.GetWidth()/2); - + (item.GetBitmap().GetWidth()/2); + bmp_y = rect.y + ((rect.height-text_height)/2) - - (item.bitmap.GetHeight()/2); - + (item.GetBitmap().GetHeight()/2); + text_x = rect.x + (rect.width/2) - (text_width/2) + 1; text_y = rect.y + rect.height - text_height - 1; } - else if (m_text_orientation == wxAUI_TBTOOL_TEXT_RIGHT) + else if (m_text_orientation == wxAUI_TBTOOL_TEXT_RIGHT) { bmp_x = rect.x + 3; - + bmp_y = rect.y + (rect.height/2) - - (item.bitmap.GetHeight()/2); - - text_x = bmp_x + 3 + item.bitmap.GetWidth(); + (item.GetBitmap().GetHeight()/2); + + text_x = bmp_x + 3 + item.GetBitmap().GetWidth(); text_y = rect.y + (rect.height/2) - (text_height/2); } - if (!(item.state & wxAUI_BUTTON_STATE_DISABLED)) + if (!(item.GetState() & wxAUI_BUTTON_STATE_DISABLED)) { - if (item.state & wxAUI_BUTTON_STATE_PRESSED) + if (item.GetState() & wxAUI_BUTTON_STATE_PRESSED) { dc.SetPen(wxPen(m_highlight_colour)); - dc.SetBrush(wxBrush(wxAuiStepColour(m_highlight_colour, 150))); + dc.SetBrush(wxBrush(m_highlight_colour.ChangeLightness(150))); dc.DrawRectangle(rect); } - else if ((item.state & wxAUI_BUTTON_STATE_HOVER) || item.sticky == true) + else if ((item.GetState() & wxAUI_BUTTON_STATE_HOVER) || item.IsSticky()) { dc.SetPen(wxPen(m_highlight_colour)); - dc.SetBrush(wxBrush(wxAuiStepColour(m_highlight_colour, 170))); - + dc.SetBrush(wxBrush(m_highlight_colour.ChangeLightness(170))); + // draw an even lighter background for checked item hovers (since // the hover background is the same color as the check background) - if (item.state & wxAUI_BUTTON_STATE_CHECKED) - dc.SetBrush(wxBrush(wxAuiStepColour(m_highlight_colour, 180))); - + if (item.GetState() & wxAUI_BUTTON_STATE_CHECKED) + dc.SetBrush(wxBrush(m_highlight_colour.ChangeLightness(180))); + dc.DrawRectangle(rect); } - else if (item.state & wxAUI_BUTTON_STATE_CHECKED) + else if (item.GetState() & wxAUI_BUTTON_STATE_CHECKED) { // it's important to put this code in an else statment after the // hover, otherwise hovers won't draw properly for checked items dc.SetPen(wxPen(m_highlight_colour)); - dc.SetBrush(wxBrush(wxAuiStepColour(m_highlight_colour, 170))); + dc.SetBrush(wxBrush(m_highlight_colour.ChangeLightness(170))); dc.DrawRectangle(rect); } } wxBitmap bmp; - if (item.state & wxAUI_BUTTON_STATE_DISABLED) - bmp = item.disabled_bitmap; - else - bmp = item.bitmap; - - if (!bmp.IsOk()) - return; - - dc.DrawBitmap(bmp, bmp_x, bmp_y, true); + if (item.GetState() & wxAUI_BUTTON_STATE_DISABLED) + bmp = item.GetDisabledBitmap(); + else + bmp = item.GetBitmap(); + + if ( bmp.IsOk() ) + dc.DrawBitmap(bmp, bmp_x, bmp_y, true); // set the item's text color based on if it is disabled dc.SetTextForeground(*wxBLACK); - if (item.state & wxAUI_BUTTON_STATE_DISABLED) + if (item.GetState() & wxAUI_BUTTON_STATE_DISABLED) dc.SetTextForeground(DISABLED_TEXT_COLOR); - - if ((m_flags & wxAUI_TB_TEXT) && item.label.Length() > 0) + + if ( (m_flags & wxAUI_TB_TEXT) && !item.GetLabel().empty() ) { - dc.DrawText(item.label, text_x, text_y); + dc.DrawText(item.GetLabel(), text_x, text_y); } } @@ -376,7 +385,7 @@ void wxAuiDefaultToolBarArt::DrawDropDownButton( { int text_width = 0, text_height = 0, text_x = 0, text_y = 0; int bmp_x = 0, bmp_y = 0, dropbmp_x = 0, dropbmp_y = 0; - + wxRect button_rect = wxRect(rect.x, rect.y, rect.width-BUTTON_DROPDOWN_WIDTH, @@ -385,101 +394,112 @@ void wxAuiDefaultToolBarArt::DrawDropDownButton( rect.y, BUTTON_DROPDOWN_WIDTH+1, rect.height); - + if (m_flags & wxAUI_TB_TEXT) { dc.SetFont(m_font); - + int tx, ty; if (m_flags & wxAUI_TB_TEXT) { dc.GetTextExtent(wxT("ABCDHgj"), &tx, &text_height); text_width = 0; - } - - dc.GetTextExtent(item.label, &text_width, &ty); + } + + dc.GetTextExtent(item.GetLabel(), &text_width, &ty); } - + dropbmp_x = dropdown_rect.x + (dropdown_rect.width/2) - (m_button_dropdown_bmp.GetWidth()/2); dropbmp_y = dropdown_rect.y + (dropdown_rect.height/2) - (m_button_dropdown_bmp.GetHeight()/2); - - + + if (m_text_orientation == wxAUI_TBTOOL_TEXT_BOTTOM) { bmp_x = button_rect.x + (button_rect.width/2) - - (item.bitmap.GetWidth()/2); + (item.GetBitmap().GetWidth()/2); bmp_y = button_rect.y + ((button_rect.height-text_height)/2) - - (item.bitmap.GetHeight()/2); - + (item.GetBitmap().GetHeight()/2); + text_x = rect.x + (rect.width/2) - (text_width/2) + 1; text_y = rect.y + rect.height - text_height - 1; } - else if (m_text_orientation == wxAUI_TBTOOL_TEXT_RIGHT) + else if (m_text_orientation == wxAUI_TBTOOL_TEXT_RIGHT) { bmp_x = rect.x + 3; - + bmp_y = rect.y + (rect.height/2) - - (item.bitmap.GetHeight()/2); - - text_x = bmp_x + 3 + item.bitmap.GetWidth(); + (item.GetBitmap().GetHeight()/2); + + text_x = bmp_x + 3 + item.GetBitmap().GetWidth(); text_y = rect.y + (rect.height/2) - (text_height/2); } - - - if (item.state & wxAUI_BUTTON_STATE_PRESSED) + + + if (item.GetState() & wxAUI_BUTTON_STATE_PRESSED) { dc.SetPen(wxPen(m_highlight_colour)); - dc.SetBrush(wxBrush(wxAuiStepColour(m_highlight_colour, 140))); + dc.SetBrush(wxBrush(m_highlight_colour.ChangeLightness(140))); dc.DrawRectangle(button_rect); + + dc.SetBrush(wxBrush(m_highlight_colour.ChangeLightness(170))); dc.DrawRectangle(dropdown_rect); } - else if (item.state & wxAUI_BUTTON_STATE_HOVER || - item.sticky == true) + else if (item.GetState() & wxAUI_BUTTON_STATE_HOVER || + item.IsSticky()) { dc.SetPen(wxPen(m_highlight_colour)); - dc.SetBrush(wxBrush(wxAuiStepColour(m_highlight_colour, 170))); + dc.SetBrush(wxBrush(m_highlight_colour.ChangeLightness(170))); + dc.DrawRectangle(button_rect); + dc.DrawRectangle(dropdown_rect); + } + else if (item.GetState() & wxAUI_BUTTON_STATE_CHECKED) + { + // Notice that this branch must come after the hover one to ensure the + // correct appearance when the mouse hovers over a checked item. + dc.SetPen(wxPen(m_highlight_colour)); + dc.SetBrush(wxBrush(m_highlight_colour.ChangeLightness(170))); dc.DrawRectangle(button_rect); dc.DrawRectangle(dropdown_rect); } wxBitmap bmp; wxBitmap dropbmp; - if (item.state & wxAUI_BUTTON_STATE_DISABLED) + if (item.GetState() & wxAUI_BUTTON_STATE_DISABLED) { - bmp = item.disabled_bitmap; + bmp = item.GetDisabledBitmap(); dropbmp = m_disabled_button_dropdown_bmp; } - else + else { - bmp = item.bitmap; + bmp = item.GetBitmap(); dropbmp = m_button_dropdown_bmp; } - + if (!bmp.IsOk()) return; - + dc.DrawBitmap(bmp, bmp_x, bmp_y, true); dc.DrawBitmap(dropbmp, dropbmp_x, dropbmp_y, true); // set the item's text color based on if it is disabled dc.SetTextForeground(*wxBLACK); - if (item.state & wxAUI_BUTTON_STATE_DISABLED) + if (item.GetState() & wxAUI_BUTTON_STATE_DISABLED) dc.SetTextForeground(DISABLED_TEXT_COLOR); - - if ((m_flags & wxAUI_TB_TEXT) && item.label.Length() > 0) + + if ( (m_flags & wxAUI_TB_TEXT) && !item.GetLabel().empty() ) { - dc.DrawText(item.label, text_x, text_y); + dc.DrawText(item.GetLabel(), text_x, text_y); } } @@ -494,34 +514,34 @@ void wxAuiDefaultToolBarArt::DrawControlLabel( if (m_text_orientation != wxAUI_TBTOOL_TEXT_BOTTOM) return; - + int text_x = 0, text_y = 0; int text_width = 0, text_height = 0; dc.SetFont(m_font); - + int tx, ty; if (m_flags & wxAUI_TB_TEXT) { dc.GetTextExtent(wxT("ABCDHgj"), &tx, &text_height); text_width = 0; - } - - dc.GetTextExtent(item.label, &text_width, &ty); - + } + + dc.GetTextExtent(item.GetLabel(), &text_width, &ty); + // don't draw the label if it is wider than the item width if (text_width > rect.width) return; - + // set the label's text color dc.SetTextForeground(*wxBLACK); - + text_x = rect.x + (rect.width/2) - (text_width/2) + 1; text_y = rect.y + rect.height - text_height - 1; - - if ((m_flags & wxAUI_TB_TEXT) && item.label.Length() > 0) + + if ( (m_flags & wxAUI_TB_TEXT) && !item.GetLabel().empty() ) { - dc.DrawText(item.label, text_x, text_y); + dc.DrawText(item.GetLabel(), text_x, text_y); } } @@ -537,8 +557,14 @@ wxSize wxAuiDefaultToolBarArt::GetLabelSize( dc.GetTextExtent(wxT("ABCDHgj"), &width, &height); // get item's width - width = item.min_size.GetWidth(); - + width = item.GetMinSize().GetWidth(); + + if (width == -1) + { + // no width specified, measure the text ourselves + width = dc.GetTextExtent(item.GetLabel()).GetX(); + } + return wxSize(width, height); } @@ -547,46 +573,47 @@ wxSize wxAuiDefaultToolBarArt::GetToolSize( wxWindow* WXUNUSED(wnd), const wxAuiToolBarItem& item) { - if (!item.bitmap.IsOk() && !(m_flags & wxAUI_TB_TEXT)) + if (!item.GetBitmap().IsOk() && !(m_flags & wxAUI_TB_TEXT)) return wxSize(16,16); - - int width = item.bitmap.GetWidth(); - int height = item.bitmap.GetHeight(); - + + int width = item.GetBitmap().GetWidth(); + int height = item.GetBitmap().GetHeight(); + if (m_flags & wxAUI_TB_TEXT) { dc.SetFont(m_font); int tx, ty; - + if (m_text_orientation == wxAUI_TBTOOL_TEXT_BOTTOM) { dc.GetTextExtent(wxT("ABCDHgj"), &tx, &ty); height += ty; - - if (item.label.Length() > 0) + + if ( !item.GetLabel().empty() ) { - dc.GetTextExtent(item.label, &tx, &ty); + dc.GetTextExtent(item.GetLabel(), &tx, &ty); width = wxMax(width, tx+6); } } - else if (m_text_orientation == wxAUI_TBTOOL_TEXT_RIGHT && item.label.Length() > 0) + else if ( m_text_orientation == wxAUI_TBTOOL_TEXT_RIGHT && + !item.GetLabel().empty() ) { width += 3; // space between left border and bitmap width += 3; // space between bitmap and text - - if (item.label.Length() > 0) + + if ( !item.GetLabel().empty() ) { - dc.GetTextExtent(item.label, &tx, &ty); + dc.GetTextExtent(item.GetLabel(), &tx, &ty); width += tx; height = wxMax(height, ty); } } - } + } // if the tool has a dropdown button, add it to the width - if (item.dropdown == true) + if (item.HasDropDown()) width += (BUTTON_DROPDOWN_WIDTH+4); - + return wxSize(width, height); } @@ -598,9 +625,9 @@ void wxAuiDefaultToolBarArt::DrawSeparator( bool horizontal = true; if (m_flags & wxAUI_TB_VERTICAL) horizontal = false; - + wxRect rect = _rect; - + if (horizontal) { rect.x += (rect.width/2); @@ -609,7 +636,7 @@ void wxAuiDefaultToolBarArt::DrawSeparator( rect.y += (rect.height/2) - (new_height/2); rect.height = new_height; } - else + else { rect.y += (rect.height/2); rect.height = 1; @@ -617,12 +644,12 @@ void wxAuiDefaultToolBarArt::DrawSeparator( rect.x += (rect.width/2) - (new_width/2); rect.width = new_width; } - - wxColour start_colour = wxAuiStepColour(m_base_colour, 80); - wxColour end_colour = wxAuiStepColour(m_base_colour, 80); + + wxColour start_colour = m_base_colour.ChangeLightness(80); + wxColour end_colour = m_base_colour.ChangeLightness(80); dc.GradientFillLinear(rect, start_colour, end_colour, horizontal ? wxSOUTH : wxEAST); } - + void wxAuiDefaultToolBarArt::DrawGripper(wxDC& dc, wxWindow* WXUNUSED(wnd), const wxRect& rect) @@ -631,7 +658,7 @@ void wxAuiDefaultToolBarArt::DrawGripper(wxDC& dc, while (1) { int x, y; - + if (m_flags & wxAUI_TB_VERTICAL) { x = rect.x + (i*4) + 5; @@ -639,14 +666,14 @@ void wxAuiDefaultToolBarArt::DrawGripper(wxDC& dc, if (x > rect.GetWidth()-5) break; } - else + else { x = rect.x + 3; y = rect.y + (i*4) + 5; if (y > rect.GetHeight()-5) break; } - + dc.SetPen(m_gripper_pen1); dc.DrawPoint(x, y); dc.SetPen(m_gripper_pen2); @@ -661,7 +688,7 @@ void wxAuiDefaultToolBarArt::DrawGripper(wxDC& dc, } } - + void wxAuiDefaultToolBarArt::DrawOverflowButton(wxDC& dc, wxWindow* wnd, const wxRect& rect, @@ -671,8 +698,8 @@ void wxAuiDefaultToolBarArt::DrawOverflowButton(wxDC& dc, state & wxAUI_BUTTON_STATE_PRESSED) { wxRect cli_rect = wnd->GetClientRect(); - wxColor light_gray_bg = wxAuiStepColour(m_highlight_colour, 170); - + wxColor light_gray_bg = m_highlight_colour.ChangeLightness(170); + if (m_flags & wxAUI_TB_VERTICAL) { dc.SetPen(wxPen(m_highlight_colour)); @@ -711,9 +738,9 @@ void wxAuiDefaultToolBarArt::SetElementSize(int element_id, int size) { switch (element_id) { - case wxAUI_TBART_SEPARATOR_SIZE: m_separator_size = size; - case wxAUI_TBART_GRIPPER_SIZE: m_gripper_size = size; - case wxAUI_TBART_OVERFLOW_SIZE: m_overflow_size = size; + case wxAUI_TBART_SEPARATOR_SIZE: m_separator_size = size; break; + case wxAUI_TBART_GRIPPER_SIZE: m_gripper_size = size; break; + case wxAUI_TBART_OVERFLOW_SIZE: m_overflow_size = size; break; } } @@ -723,32 +750,28 @@ int wxAuiDefaultToolBarArt::ShowDropDown(wxWindow* wnd, wxMenu menuPopup; size_t items_added = 0; - + size_t i, count = items.GetCount(); for (i = 0; i < count; ++i) { wxAuiToolBarItem& item = items.Item(i); - - if (item.kind == wxITEM_NORMAL) + + if (item.GetKind() == wxITEM_NORMAL) { - wxString text = item.short_help; + wxString text = item.GetShortHelp(); if (text.empty()) - text = item.label; - + text = item.GetLabel(); + if (text.empty()) text = wxT(" "); - - #ifdef __WXMAC__ - wxMenuItem* m = new wxMenuItem(&menuPopup, item.id, text, item.short_help); - #else - wxMenuItem* m = new wxMenuItem(&menuPopup, item.id, text, item.short_help, false); - #endif - - m->SetBitmap(item.bitmap); + + wxMenuItem* m = new wxMenuItem(&menuPopup, item.GetId(), text, item.GetShortHelp()); + + m->SetBitmap(item.GetBitmap()); menuPopup.Append(m); items_added++; } - else if (item.kind == wxITEM_SEPARATOR) + else if (item.GetKind() == wxITEM_SEPARATOR) { if (items_added > 0) menuPopup.AppendSeparator(); @@ -775,6 +798,22 @@ int wxAuiDefaultToolBarArt::ShowDropDown(wxWindow* wnd, +static wxOrientation GetOrientation(long& style) +{ + switch (style & wxAUI_ORIENTATION_MASK) + { + case wxAUI_TB_HORIZONTAL: + return wxHORIZONTAL; + case wxAUI_TB_VERTICAL: + return wxVERTICAL; + default: + wxFAIL_MSG("toolbar cannot be locked in both horizontal and vertical orientations (maybe no lock was intended?)"); + // fall through + case 0: + return wxBOTH; + } +} + BEGIN_EVENT_TABLE(wxAuiToolBar, wxControl) EVT_SIZE(wxAuiToolBar::OnSize) EVT_IDLE(wxAuiToolBar::OnIdle) @@ -791,6 +830,7 @@ BEGIN_EVENT_TABLE(wxAuiToolBar, wxControl) EVT_MIDDLE_UP(wxAuiToolBar::OnMiddleUp) EVT_MOTION(wxAuiToolBar::OnMotion) EVT_LEAVE_WINDOW(wxAuiToolBar::OnLeaveWindow) + EVT_MOUSE_CAPTURE_LOST(wxAuiToolBar::OnCaptureLost) EVT_SET_CURSOR(wxAuiToolBar::OnSetCursor) END_EVENT_TABLE() @@ -820,16 +860,22 @@ wxAuiToolBar::wxAuiToolBar(wxWindow* parent, m_gripper_sizer_item = NULL; m_overflow_sizer_item = NULL; m_dragging = false; - m_style = style; + m_orientation = GetOrientation(style); + if (m_orientation == wxBOTH) + { + m_orientation = wxHORIZONTAL; + } + m_style = style | wxBORDER_NONE; m_gripper_visible = (m_style & wxAUI_TB_GRIPPER) ? true : false; m_overflow_visible = (m_style & wxAUI_TB_OVERFLOW) ? true : false; m_overflow_state = 0; SetMargins(5, 5, 2, 2); SetFont(*wxNORMAL_FONT); - m_art->SetFlags((unsigned int)m_style); + SetArtFlags(); SetExtraStyle(wxWS_EX_PROCESS_IDLE); - if (style & wxAUI_TB_HORZ_TEXT) + if (style & wxAUI_TB_HORZ_LAYOUT) SetToolTextOrientation(wxAUI_TBTOOL_TEXT_RIGHT); + SetBackgroundStyle(wxBG_STYLE_CUSTOM); } @@ -841,42 +887,50 @@ wxAuiToolBar::~wxAuiToolBar() void wxAuiToolBar::SetWindowStyleFlag(long style) { + GetOrientation(style); // assert if style is invalid + wxCHECK_RET(IsPaneValid(style), + "window settings and pane settings are incompatible"); + wxControl::SetWindowStyleFlag(style); m_style = style; - + if (m_art) { - m_art->SetFlags((unsigned int)m_style); + SetArtFlags(); } - + if (m_style & wxAUI_TB_GRIPPER) m_gripper_visible = true; - else + else m_gripper_visible = false; if (m_style & wxAUI_TB_OVERFLOW) m_overflow_visible = true; - else + else m_overflow_visible = false; - - if (style & wxAUI_TB_HORZ_TEXT) + + if (style & wxAUI_TB_HORZ_LAYOUT) SetToolTextOrientation(wxAUI_TBTOOL_TEXT_RIGHT); - else + else SetToolTextOrientation(wxAUI_TBTOOL_TEXT_BOTTOM); } +long wxAuiToolBar::GetWindowStyleFlag() const +{ + return m_style; +} void wxAuiToolBar::SetArtProvider(wxAuiToolBarArt* art) { delete m_art; - + m_art = art; - + if (m_art) { - m_art->SetFlags((unsigned int)m_style); + SetArtFlags(); m_art->SetTextOrientation(m_tool_text_orientation); } } @@ -889,13 +943,13 @@ wxAuiToolBarArt* wxAuiToolBar::GetArtProvider() const -void wxAuiToolBar::AddTool(int tool_id, +wxAuiToolBarItem* wxAuiToolBar::AddTool(int tool_id, const wxString& label, const wxBitmap& bitmap, const wxString& short_help_string, wxItemKind kind) { - AddTool(tool_id, + return AddTool(tool_id, label, bitmap, wxNullBitmap, @@ -906,13 +960,13 @@ void wxAuiToolBar::AddTool(int tool_id, } -void wxAuiToolBar::AddTool(int tool_id, +wxAuiToolBarItem* wxAuiToolBar::AddTool(int tool_id, const wxString& label, const wxBitmap& bitmap, const wxBitmap& disabled_bitmap, wxItemKind kind, - const wxString& WXUNUSED(short_help_string), - const wxString& WXUNUSED(long_help_string), + const wxString& short_help_string, + const wxString& long_help_string, wxObject* WXUNUSED(client_data)) { wxAuiToolBarItem item; @@ -920,10 +974,12 @@ void wxAuiToolBar::AddTool(int tool_id, item.label = label; item.bitmap = bitmap; item.disabled_bitmap = disabled_bitmap; + item.short_help = short_help_string; + item.long_help = long_help_string; item.active = true; item.dropdown = false; - item.space_pixels = 0; - item.id = tool_id; + item.spacer_pixels = 0; + item.toolid = tool_id; item.state = 0; item.proportion = 0; item.kind = kind; @@ -931,7 +987,10 @@ void wxAuiToolBar::AddTool(int tool_id, item.min_size = wxDefaultSize; item.user_data = 0; item.sticky = false; - + + if (item.toolid == wxID_ANY) + item.toolid = wxNewId(); + if (!item.disabled_bitmap.IsOk()) { // no disabled bitmap specified, we need to make one @@ -943,11 +1002,11 @@ void wxAuiToolBar::AddTool(int tool_id, item.disabled_bitmap = MakeDisabledBitmap(item.bitmap); } } - m_items.Add(item); + return &m_items.Last(); } -void wxAuiToolBar::AddControl(wxControl* control, +wxAuiToolBarItem* wxAuiToolBar::AddControl(wxControl* control, const wxString& label) { wxAuiToolBarItem item; @@ -957,8 +1016,8 @@ void wxAuiToolBar::AddControl(wxControl* control, item.disabled_bitmap = wxNullBitmap; item.active = true; item.dropdown = false; - item.space_pixels = 0; - item.id = control->GetId(); + item.spacer_pixels = 0; + item.toolid = control->GetId(); item.state = 0; item.proportion = 0; item.kind = wxITEM_CONTROL; @@ -968,16 +1027,17 @@ void wxAuiToolBar::AddControl(wxControl* control, item.sticky = false; m_items.Add(item); + return &m_items.Last(); } -void wxAuiToolBar::AddLabel(int tool_id, +wxAuiToolBarItem* wxAuiToolBar::AddLabel(int tool_id, const wxString& label, const int width) { wxSize min_size = wxDefaultSize; if (width != -1) min_size.x = width; - + wxAuiToolBarItem item; item.window = NULL; item.label = label; @@ -985,8 +1045,8 @@ void wxAuiToolBar::AddLabel(int tool_id, item.disabled_bitmap = wxNullBitmap; item.active = true; item.dropdown = false; - item.space_pixels = 0; - item.id = tool_id; + item.spacer_pixels = 0; + item.toolid = tool_id; item.state = 0; item.proportion = 0; item.kind = wxITEM_LABEL; @@ -995,10 +1055,14 @@ void wxAuiToolBar::AddLabel(int tool_id, item.user_data = 0; item.sticky = false; + if (item.toolid == wxID_ANY) + item.toolid = wxNewId(); + m_items.Add(item); + return &m_items.Last(); } -void wxAuiToolBar::AddSeparator() +wxAuiToolBarItem* wxAuiToolBar::AddSeparator() { wxAuiToolBarItem item; item.window = NULL; @@ -1007,7 +1071,7 @@ void wxAuiToolBar::AddSeparator() item.disabled_bitmap = wxNullBitmap; item.active = true; item.dropdown = false; - item.id = -1; + item.toolid = -1; item.state = 0; item.proportion = 0; item.kind = wxITEM_SEPARATOR; @@ -1017,9 +1081,10 @@ void wxAuiToolBar::AddSeparator() item.sticky = false; m_items.Add(item); + return &m_items.Last(); } -void wxAuiToolBar::AddSpacer(int pixels) +wxAuiToolBarItem* wxAuiToolBar::AddSpacer(int pixels) { wxAuiToolBarItem item; item.window = NULL; @@ -1028,8 +1093,8 @@ void wxAuiToolBar::AddSpacer(int pixels) item.disabled_bitmap = wxNullBitmap; item.active = true; item.dropdown = false; - item.space_pixels = pixels; - item.id = -1; + item.spacer_pixels = pixels; + item.toolid = -1; item.state = 0; item.proportion = 0; item.kind = wxITEM_SPACER; @@ -1039,9 +1104,10 @@ void wxAuiToolBar::AddSpacer(int pixels) item.sticky = false; m_items.Add(item); + return &m_items.Last(); } -void wxAuiToolBar::AddStretchSpacer(int proportion) +wxAuiToolBarItem* wxAuiToolBar::AddStretchSpacer(int proportion) { wxAuiToolBarItem item; item.window = NULL; @@ -1050,8 +1116,8 @@ void wxAuiToolBar::AddStretchSpacer(int proportion) item.disabled_bitmap = wxNullBitmap; item.active = true; item.dropdown = false; - item.space_pixels = 0; - item.id = -1; + item.spacer_pixels = 0; + item.toolid = -1; item.state = 0; item.proportion = proportion; item.kind = wxITEM_SPACER; @@ -1061,6 +1127,7 @@ void wxAuiToolBar::AddStretchSpacer(int proportion) item.sticky = false; m_items.Add(item); + return &m_items.Last(); } void wxAuiToolBar::Clear() @@ -1078,7 +1145,7 @@ bool wxAuiToolBar::DeleteTool(int tool_id) Realize(); return true; } - + return false; } @@ -1090,7 +1157,7 @@ bool wxAuiToolBar::DeleteByIndex(int idx) Realize(); return true; } - + return false; } @@ -1107,10 +1174,10 @@ wxAuiToolBarItem* wxAuiToolBar::FindTool(int tool_id) const for (i = 0, count = m_items.GetCount(); i < count; ++i) { wxAuiToolBarItem& item = m_items.Item(i); - if (item.id == tool_id) + if (item.toolid == tool_id) return &item; } - + return NULL; } @@ -1120,21 +1187,21 @@ wxAuiToolBarItem* wxAuiToolBar::FindToolByPosition(wxCoord x, wxCoord y) const for (i = 0, count = m_items.GetCount(); i < count; ++i) { wxAuiToolBarItem& item = m_items.Item(i); - + if (!item.sizer_item) continue; - + wxRect rect = item.sizer_item->GetRect(); if (rect.Contains(x,y)) { // if the item doesn't fit on the toolbar, return NULL if (!GetToolFitsByIndex(i)) return NULL; - + return &item; } } - + return NULL; } @@ -1144,26 +1211,26 @@ wxAuiToolBarItem* wxAuiToolBar::FindToolByPositionWithPacking(wxCoord x, wxCoord for (i = 0, count = m_items.GetCount(); i < count; ++i) { wxAuiToolBarItem& item = m_items.Item(i); - + if (!item.sizer_item) continue; - + wxRect rect = item.sizer_item->GetRect(); - + // apply tool packing if (i+1 < count) rect.width += m_tool_packing; - + if (rect.Contains(x,y)) { // if the item doesn't fit on the toolbar, return NULL if (!GetToolFitsByIndex(i)) return NULL; - + return &item; } } - + return NULL; } @@ -1171,10 +1238,10 @@ wxAuiToolBarItem* wxAuiToolBar::FindToolByIndex(int idx) const { if (idx < 0) return NULL; - + if (idx >= (int)m_items.size()) return NULL; - + return &(m_items[idx]); } @@ -1188,13 +1255,13 @@ wxSize wxAuiToolBar::GetToolBitmapSize() const // TODO: wxToolBar compatibility return wxSize(16,15); } - + void wxAuiToolBar::SetToolProportion(int tool_id, int proportion) { wxAuiToolBarItem* item = FindTool(tool_id); if (!item) return; - + item->proportion = proportion; } @@ -1203,7 +1270,7 @@ int wxAuiToolBar::GetToolProportion(int tool_id) const wxAuiToolBarItem* item = FindTool(tool_id); if (!item) return 0; - + return item->proportion; } @@ -1217,14 +1284,14 @@ int wxAuiToolBar::GetToolSeparation() const { if (m_art) return m_art->GetElementSize(wxAUI_TBART_SEPARATOR_SIZE); - else + else return 5; } - + void wxAuiToolBar::SetToolDropDown(int tool_id, bool dropdown) { - wxAuiToolBarItem* item = FindTool(tool_id); + wxAuiToolBarItem* item = FindTool(tool_id); if (!item) return; @@ -1236,7 +1303,7 @@ bool wxAuiToolBar::GetToolDropDown(int tool_id) const wxAuiToolBarItem* item = FindTool(tool_id); if (!item) return 0; - + return item->dropdown; } @@ -1245,16 +1312,16 @@ void wxAuiToolBar::SetToolSticky(int tool_id, bool sticky) // ignore separators if (tool_id == -1) return; - - wxAuiToolBarItem* item = FindTool(tool_id); + + wxAuiToolBarItem* item = FindTool(tool_id); if (!item) return; - + if (item->sticky == sticky) return; - + item->sticky = sticky; - + Refresh(false); Update(); } @@ -1264,7 +1331,7 @@ bool wxAuiToolBar::GetToolSticky(int tool_id) const wxAuiToolBarItem* item = FindTool(tool_id); if (!item) return 0; - + return item->sticky; } @@ -1307,8 +1374,16 @@ int wxAuiToolBar::GetToolPacking() const } -void wxAuiToolBar::SetOrientation(int WXUNUSED(orientation)) +void wxAuiToolBar::SetOrientation(int orientation) { + wxCHECK_RET(orientation == wxHORIZONTAL || + orientation == wxVERTICAL, + "invalid orientation value"); + if (orientation != m_orientation) + { + m_orientation = wxOrientation(orientation); + SetArtFlags(); + } } void wxAuiToolBar::SetMargins(int left, int right, int top, int bottom) @@ -1333,6 +1408,8 @@ void wxAuiToolBar::SetGripperVisible(bool visible) m_gripper_visible = visible; if (visible) m_style |= wxAUI_TB_GRIPPER; + else + m_style &= ~wxAUI_TB_GRIPPER; Realize(); Refresh(false); } @@ -1348,18 +1425,20 @@ void wxAuiToolBar::SetOverflowVisible(bool visible) m_overflow_visible = visible; if (visible) m_style |= wxAUI_TB_OVERFLOW; + else + m_style &= ~wxAUI_TB_OVERFLOW; Refresh(false); } bool wxAuiToolBar::SetFont(const wxFont& font) { bool res = wxWindow::SetFont(font); - + if (m_art) { m_art->SetFont(font); } - + return res; } @@ -1367,7 +1446,7 @@ bool wxAuiToolBar::SetFont(const wxFont& font) void wxAuiToolBar::SetHoverItem(wxAuiToolBarItem* pitem) { wxAuiToolBarItem* former_hover = NULL; - + size_t i, count; for (i = 0, count = m_items.GetCount(); i < count; ++i) { @@ -1376,12 +1455,12 @@ void wxAuiToolBar::SetHoverItem(wxAuiToolBarItem* pitem) former_hover = &item; item.state &= ~wxAUI_BUTTON_STATE_HOVER; } - + if (pitem) { pitem->state |= wxAUI_BUTTON_STATE_HOVER; } - + if (former_hover != pitem) { Refresh(false); @@ -1392,7 +1471,7 @@ void wxAuiToolBar::SetHoverItem(wxAuiToolBarItem* pitem) void wxAuiToolBar::SetPressedItem(wxAuiToolBarItem* pitem) { wxAuiToolBarItem* former_item = NULL; - + size_t i, count; for (i = 0, count = m_items.GetCount(); i < count; ++i) { @@ -1401,13 +1480,13 @@ void wxAuiToolBar::SetPressedItem(wxAuiToolBarItem* pitem) former_item = &item; item.state &= ~wxAUI_BUTTON_STATE_PRESSED; } - + if (pitem) { pitem->state &= ~wxAUI_BUTTON_STATE_HOVER; pitem->state |= wxAUI_BUTTON_STATE_PRESSED; } - + if (former_item != pitem) { Refresh(false); @@ -1422,75 +1501,99 @@ void wxAuiToolBar::RefreshOverflowState() m_overflow_state = 0; return; } - + int overflow_state = 0; - + wxRect overflow_rect = GetOverflowRect(); - + // find out the mouse's current position wxPoint pt = ::wxGetMousePosition(); pt = this->ScreenToClient(pt); - + // find out if the mouse cursor is inside the dropdown rectangle if (overflow_rect.Contains(pt.x, pt.y)) { - if (::wxGetMouseState().LeftDown()) + if (::wxGetMouseState().LeftIsDown()) overflow_state = wxAUI_BUTTON_STATE_PRESSED; - else + else overflow_state = wxAUI_BUTTON_STATE_HOVER; } - + if (overflow_state != m_overflow_state) { m_overflow_state = overflow_state; Refresh(false); Update(); } - + m_overflow_state = overflow_state; } void wxAuiToolBar::ToggleTool(int tool_id, bool state) { wxAuiToolBarItem* tool = FindTool(tool_id); - - if (tool) + + if (tool && (tool->kind == wxITEM_CHECK || tool->kind == wxITEM_RADIO)) { - if (tool->kind != wxITEM_CHECK) - return; - - if (state == true) + if (tool->kind == wxITEM_RADIO) + { + int i, idx, count; + idx = GetToolIndex(tool_id); + count = (int)m_items.GetCount(); + + if (idx >= 0 && idx < count) + { + for (i = idx + 1; i < count; ++i) + { + if (m_items[i].kind != wxITEM_RADIO) + break; + m_items[i].state &= ~wxAUI_BUTTON_STATE_CHECKED; + } + for (i = idx - 1; i >= 0; i--) + { + if (m_items[i].kind != wxITEM_RADIO) + break; + m_items[i].state &= ~wxAUI_BUTTON_STATE_CHECKED; + } + } + tool->state |= wxAUI_BUTTON_STATE_CHECKED; - else - tool->state &= ~wxAUI_BUTTON_STATE_CHECKED; + } + else if (tool->kind == wxITEM_CHECK) + { + if (state == true) + tool->state |= wxAUI_BUTTON_STATE_CHECKED; + else + tool->state &= ~wxAUI_BUTTON_STATE_CHECKED; + } } } bool wxAuiToolBar::GetToolToggled(int tool_id) const { wxAuiToolBarItem* tool = FindTool(tool_id); - + if (tool) { - if (tool->kind != wxITEM_CHECK) + if ( (tool->kind != wxITEM_CHECK) && (tool->kind != wxITEM_RADIO) ) return false; - + return (tool->state & wxAUI_BUTTON_STATE_CHECKED) ? true : false; } - + return false; } void wxAuiToolBar::EnableTool(int tool_id, bool state) { wxAuiToolBarItem* tool = FindTool(tool_id); - + if (tool) { if (state == true) tool->state &= ~wxAUI_BUTTON_STATE_DISABLED; - else + else tool->state |= wxAUI_BUTTON_STATE_DISABLED; } } @@ -1498,10 +1601,10 @@ void wxAuiToolBar::EnableTool(int tool_id, bool state) bool wxAuiToolBar::GetToolEnabled(int tool_id) const { wxAuiToolBarItem* tool = FindTool(tool_id); - + if (tool) return (tool->state & wxAUI_BUTTON_STATE_DISABLED) ? false : true; - + return false; } @@ -1511,7 +1614,7 @@ wxString wxAuiToolBar::GetToolLabel(int tool_id) const wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array")); if (!tool) return wxEmptyString; - + return tool->label; } @@ -1530,7 +1633,7 @@ wxBitmap wxAuiToolBar::GetToolBitmap(int tool_id) const wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array")); if (!tool) return wxNullBitmap; - + return tool->bitmap; } @@ -1549,7 +1652,7 @@ wxString wxAuiToolBar::GetToolShortHelp(int tool_id) const wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array")); if (!tool) return wxEmptyString; - + return tool->short_help; } @@ -1568,7 +1671,7 @@ wxString wxAuiToolBar::GetToolLongHelp(int tool_id) const wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array")); if (!tool) return wxEmptyString; - + return tool->long_help; } @@ -1588,6 +1691,65 @@ void wxAuiToolBar::SetCustomOverflowItems(const wxAuiToolBarItemArray& prepend, m_custom_overflow_append = append; } +// get size of hint rectangle for a particular dock location +wxSize wxAuiToolBar::GetHintSize(int dock_direction) const +{ + switch (dock_direction) + { + case wxAUI_DOCK_TOP: + case wxAUI_DOCK_BOTTOM: + return m_horzHintSize; + case wxAUI_DOCK_RIGHT: + case wxAUI_DOCK_LEFT: + return m_vertHintSize; + default: + wxCHECK_MSG(false, wxDefaultSize, "invalid dock location value"); + } +} + +bool wxAuiToolBar::IsPaneValid(const wxAuiPaneInfo& pane) const +{ + return IsPaneValid(m_style, pane); +} + +bool wxAuiToolBar::IsPaneValid(long style, const wxAuiPaneInfo& pane) +{ + if (style & wxAUI_TB_HORIZONTAL) + { + if (pane.IsLeftDockable() || pane.IsRightDockable()) + { + return false; + } + } + else if (style & wxAUI_TB_VERTICAL) + { + if (pane.IsTopDockable() || pane.IsBottomDockable()) + { + return false; + } + } + return true; +} + +bool wxAuiToolBar::IsPaneValid(long style) const +{ + wxAuiManager* manager = wxAuiManager::GetManager(const_cast(this)); + if (manager) + { + return IsPaneValid(style, manager->GetPane(const_cast(this))); + } + return true; +} + +void wxAuiToolBar::SetArtFlags() const +{ + unsigned int artflags = m_style & ~wxAUI_ORIENTATION_MASK; + if (m_orientation == wxVERTICAL) + { + artflags |= wxAUI_TB_VERTICAL; + } + m_art->SetFlags(artflags); +} size_t wxAuiToolBar::GetToolCount() const { @@ -1600,15 +1762,15 @@ int wxAuiToolBar::GetToolIndex(int tool_id) const // first separator in the toolbar since its id is equal to -1 if (tool_id == -1) return wxNOT_FOUND; - + size_t i, count = m_items.GetCount(); for (i = 0; i < count; ++i) { wxAuiToolBarItem& item = m_items.Item(i); - if (item.id == tool_id) + if (item.toolid == tool_id) return i; } - + return wxNOT_FOUND; } @@ -1616,30 +1778,30 @@ bool wxAuiToolBar::GetToolFitsByIndex(int tool_idx) const { if (tool_idx < 0 || tool_idx >= (int)m_items.GetCount()) return false; - + if (!m_items[tool_idx].sizer_item) return false; - + int cli_w, cli_h; GetClientSize(&cli_w, &cli_h); - + wxRect rect = m_items[tool_idx].sizer_item->GetRect(); - - if (m_style & wxAUI_TB_VERTICAL) + + if (m_orientation == wxVERTICAL) { // take the dropdown size into account if (m_overflow_visible) cli_h -= m_overflow_sizer_item->GetSize().y; - + if (rect.y+rect.height < cli_h) return true; } - else + else { // take the dropdown size into account if (m_overflow_visible) cli_w -= m_overflow_sizer_item->GetSize().x; - + if (rect.x+rect.width < cli_w) return true; } @@ -1660,7 +1822,7 @@ wxRect wxAuiToolBar::GetToolRect(int tool_id) const { return tool->sizer_item->GetRect(); } - + return wxRect(); } @@ -1671,7 +1833,7 @@ bool wxAuiToolBar::GetToolBarFits() const // empty toolbar always 'fits' return true; } - + // entire toolbar content fits if the last tool fits return GetToolFitsByIndex(m_items.GetCount() - 1); } @@ -1682,14 +1844,43 @@ bool wxAuiToolBar::Realize() if (!dc.IsOk()) return false; - bool horizontal = true; - if (m_style & wxAUI_TB_VERTICAL) - horizontal = false; - - + // calculate hint sizes for both horizontal and vertical + // in the order that leaves toolbar in correct final state + bool retval = false; + if (m_orientation == wxHORIZONTAL) + { + if (RealizeHelper(dc, false)) + { + m_vertHintSize = GetSize(); + if (RealizeHelper(dc, true)) + { + m_horzHintSize = GetSize(); + retval = true; + } + } + } + else + { + if (RealizeHelper(dc, true)) + { + m_horzHintSize = GetSize(); + if (RealizeHelper(dc, false)) + { + m_vertHintSize = GetSize(); + retval = true; + } + } + } + + Refresh(false); + return retval; +} + +bool wxAuiToolBar::RealizeHelper(wxClientDC& dc, bool horizontal) +{ // create the new sizer to add toolbar elements to wxBoxSizer* sizer = new wxBoxSizer(horizontal ? wxHORIZONTAL : wxVERTICAL); - + // add gripper area int separator_size = m_art->GetElementSize(wxAUI_TBART_SEPARATOR_SIZE); int gripper_size = m_art->GetElementSize(wxAUI_TBART_GRIPPER_SIZE); @@ -1697,68 +1888,69 @@ bool wxAuiToolBar::Realize() { if (horizontal) m_gripper_sizer_item = sizer->Add(gripper_size, 1, 0, wxEXPAND); - else + else m_gripper_sizer_item = sizer->Add(1, gripper_size, 0, wxEXPAND); } - else + else { m_gripper_sizer_item = NULL; } - + // add "left" padding if (m_left_padding > 0) { if (horizontal) sizer->Add(m_left_padding, 1); - else + else sizer->Add(1, m_left_padding); } - + size_t i, count; for (i = 0, count = m_items.GetCount(); i < count; ++i) { wxAuiToolBarItem& item = m_items.Item(i); wxSizerItem* sizer_item = NULL; - + switch (item.kind) - { + { case wxITEM_LABEL: { wxSize size = m_art->GetLabelSize(dc, this, item); sizer_item = sizer->Add(size.x + (m_tool_border_padding*2), size.y + (m_tool_border_padding*2), item.proportion, - wxALIGN_CENTER); + item.alignment); if (i+1 < count) { sizer->AddSpacer(m_tool_packing); } - + break; } - + case wxITEM_CHECK: case wxITEM_NORMAL: + case wxITEM_RADIO: { wxSize size = m_art->GetToolSize(dc, this, item); sizer_item = sizer->Add(size.x + (m_tool_border_padding*2), size.y + (m_tool_border_padding*2), 0, - wxALIGN_CENTER); + item.alignment); // add tool packing if (i+1 < count) { sizer->AddSpacer(m_tool_packing); } - + break; } - + case wxITEM_SEPARATOR: { if (horizontal) sizer_item = sizer->Add(separator_size, 1, 0, wxEXPAND); - else + else sizer_item = sizer->Add(1, separator_size, 0, wxEXPAND); // add tool packing @@ -1766,37 +1958,39 @@ bool wxAuiToolBar::Realize() { sizer->AddSpacer(m_tool_packing); } - + break; } - + case wxITEM_SPACER: if (item.proportion > 0) sizer_item = sizer->AddStretchSpacer(item.proportion); - else - sizer_item = sizer->Add(item.space_pixels, 1); + else + sizer_item = sizer->Add(item.spacer_pixels, 1); break; - + case wxITEM_CONTROL: { //sizer_item = sizer->Add(item.window, item.proportion, wxEXPAND); wxSizerItem* ctrl_sizer_item; - + wxBoxSizer* vert_sizer = new wxBoxSizer(wxVERTICAL); vert_sizer->AddStretchSpacer(1); ctrl_sizer_item = vert_sizer->Add(item.window, 0, wxEXPAND); vert_sizer->AddStretchSpacer(1); - if ((m_style & wxAUI_TB_TEXT) && item.label.Length() > 0) + if ( (m_style & wxAUI_TB_TEXT) && + m_tool_text_orientation == wxAUI_TBTOOL_TEXT_BOTTOM && + !item.GetLabel().empty() ) { - wxSize s = GetLabelSize(item.label); + wxSize s = GetLabelSize(item.GetLabel()); vert_sizer->Add(1, s.y); } - - + + sizer_item = sizer->Add(vert_sizer, item.proportion, wxEXPAND); - + wxSize min_size = item.min_size; - + // proportional items will disappear from the toolbar if // their min width is not set to something really small @@ -1804,10 +1998,10 @@ bool wxAuiToolBar::Realize() { min_size.x = 1; } - + if (min_size.IsFullySpecified()) { - sizer_item->SetMinSize(min_size); + sizer_item->SetMinSize(min_size); ctrl_sizer_item->SetMinSize(min_size); } @@ -1818,7 +2012,7 @@ bool wxAuiToolBar::Realize() } } } - + item.sizer_item = sizer_item; } @@ -1827,13 +2021,13 @@ bool wxAuiToolBar::Realize() { if (horizontal) sizer->Add(m_right_padding, 1); - else + else sizer->Add(1, m_right_padding); } - + // add drop down area m_overflow_sizer_item = NULL; - + if (m_style & wxAUI_TB_OVERFLOW) { int overflow_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE); @@ -1841,43 +2035,43 @@ bool wxAuiToolBar::Realize() { if (horizontal) m_overflow_sizer_item = sizer->Add(overflow_size, 1, 0, wxEXPAND); - else + else m_overflow_sizer_item = sizer->Add(1, overflow_size, 0, wxEXPAND); } - else + else { m_overflow_sizer_item = NULL; } } - + // the outside sizer helps us apply the "top" and "bottom" padding wxBoxSizer* outside_sizer = new wxBoxSizer(horizontal ? wxVERTICAL : wxHORIZONTAL); - + // add "top" padding if (m_top_padding > 0) { if (horizontal) outside_sizer->Add(1, m_top_padding); - else + else outside_sizer->Add(m_top_padding, 1); } // add the sizer that contains all of the toolbar elements outside_sizer->Add(sizer, 1, wxEXPAND); - + // add "bottom" padding if (m_bottom_padding > 0) { if (horizontal) outside_sizer->Add(1, m_bottom_padding); - else + else outside_sizer->Add(m_bottom_padding, 1); } - + delete m_sizer; // remove old sizer m_sizer = outside_sizer; - + // calculate the rock-bottom minimum size for (i = 0, count = m_items.GetCount(); i < count; ++i) { @@ -1885,22 +2079,22 @@ bool wxAuiToolBar::Realize() if (item.sizer_item && item.proportion > 0 && item.min_size.IsFullySpecified()) item.sizer_item->SetMinSize(0,0); } - + m_absolute_min_size = m_sizer->GetMinSize(); - + // reset the min sizes to what they were for (i = 0, count = m_items.GetCount(); i < count; ++i) { wxAuiToolBarItem& item = m_items.Item(i); if (item.sizer_item && item.proportion > 0 && item.min_size.IsFullySpecified()) item.sizer_item->SetMinSize(item.min_size); - } + } // set control size wxSize size = m_sizer->GetMinSize(); m_minWidth = size.x; m_minHeight = size.y; - + if ((m_style & wxAUI_TB_NO_AUTORESIZE) == 0) { wxSize cur_size = GetClientSize(); @@ -1909,18 +2103,17 @@ bool wxAuiToolBar::Realize() { SetClientSize(new_size); } - else + else { m_sizer->SetDimension(0, 0, cur_size.x, cur_size.y); } - } - else + } + else { wxSize cur_size = GetClientSize(); m_sizer->SetDimension(0, 0, cur_size.x, cur_size.y); } - - Refresh(false); + return true; } @@ -1930,38 +2123,38 @@ int wxAuiToolBar::GetOverflowState() const } wxRect wxAuiToolBar::GetOverflowRect() const -{ +{ wxRect cli_rect(wxPoint(0,0), GetClientSize()); wxRect overflow_rect = m_overflow_sizer_item->GetRect(); int overflow_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE); - if (m_style & wxAUI_TB_VERTICAL) + if (m_orientation == wxVERTICAL) { overflow_rect.y = cli_rect.height - overflow_size; overflow_rect.x = 0; overflow_rect.width = cli_rect.width; overflow_rect.height = overflow_size; } - else + else { overflow_rect.x = cli_rect.width - overflow_size; overflow_rect.y = 0; overflow_rect.width = overflow_size; overflow_rect.height = cli_rect.height; } - + return overflow_rect; } wxSize wxAuiToolBar::GetLabelSize(const wxString& label) { wxClientDC dc(this); - + int tx, ty; int text_width = 0, text_height = 0; dc.SetFont(m_font); - + // get the text height dc.GetTextExtent(wxT("ABCDHgj"), &tx, &text_height); @@ -1982,11 +2175,11 @@ void wxAuiToolBar::DoIdleUpdate() for (i = 0, count = m_items.GetCount(); i < count; ++i) { wxAuiToolBarItem& item = m_items.Item(i); - - if (item.id == -1) + + if (item.toolid == -1) continue; - - wxUpdateUIEvent evt(item.id); + + wxUpdateUIEvent evt(item.toolid); evt.SetEventObject(this); if (handler->ProcessEvent(evt)) @@ -1996,9 +2189,9 @@ void wxAuiToolBar::DoIdleUpdate() bool is_enabled; if (item.window) is_enabled = item.window->IsEnabled(); - else + else is_enabled = (item.state & wxAUI_BUTTON_STATE_DISABLED) ? false : true; - + bool new_enabled = evt.GetEnabled(); if (new_enabled != is_enabled) { @@ -2006,17 +2199,17 @@ void wxAuiToolBar::DoIdleUpdate() { item.window->Enable(new_enabled); } - else + else { if (new_enabled) item.state &= ~wxAUI_BUTTON_STATE_DISABLED; - else + else item.state |= wxAUI_BUTTON_STATE_DISABLED; } need_refresh = true; } } - + if (evt.GetSetChecked()) { // make sure we aren't checking an item that can't be @@ -2030,16 +2223,16 @@ void wxAuiToolBar::DoIdleUpdate() { if (new_checked) item.state |= wxAUI_BUTTON_STATE_CHECKED; - else + else item.state &= ~wxAUI_BUTTON_STATE_CHECKED; - + need_refresh = true; } } } } - + if (need_refresh) { @@ -2053,11 +2246,6 @@ void wxAuiToolBar::OnSize(wxSizeEvent& WXUNUSED(evt)) int x, y; GetClientSize(&x, &y); - if (x > y) - SetOrientation(wxHORIZONTAL); - else - SetOrientation(wxVERTICAL); - if (((x >= y) && m_absolute_min_size.x > x) || ((y > x) && m_absolute_min_size.y > y)) { @@ -2073,7 +2261,7 @@ void wxAuiToolBar::OnSize(wxSizeEvent& WXUNUSED(evt)) } } } - else + else { // show all flexible items size_t i, count; @@ -2092,6 +2280,11 @@ void wxAuiToolBar::OnSize(wxSizeEvent& WXUNUSED(evt)) Refresh(false); Update(); + + // idle events aren't sent while user is resizing frame (why?), + // but resizing toolbar here causes havoc, + // so force idle handler to run after size handling complete + QueueEvent(new wxIdleEvent); } @@ -2114,88 +2307,164 @@ void wxAuiToolBar::DoSetSize(int x, void wxAuiToolBar::OnIdle(wxIdleEvent& evt) { + // if orientation doesn't match dock, fix it + wxAuiManager* manager = wxAuiManager::GetManager(this); + if (manager) + { + wxAuiPaneInfo& pane = manager->GetPane(this); + // pane state member is public, so it might have been changed + // without going through wxPaneInfo::SetFlag() check + bool ok = pane.IsOk(); + wxCHECK2_MSG(!ok || IsPaneValid(m_style, pane), ok = false, + "window settings and pane settings are incompatible"); + if (ok) + { + wxOrientation newOrientation = m_orientation; + if (pane.IsDocked()) + { + switch (pane.dock_direction) + { + case wxAUI_DOCK_TOP: + case wxAUI_DOCK_BOTTOM: + newOrientation = wxHORIZONTAL; + break; + case wxAUI_DOCK_LEFT: + case wxAUI_DOCK_RIGHT: + newOrientation = wxVERTICAL; + break; + default: + wxFAIL_MSG("invalid dock location value"); + } + } + else if (pane.IsResizable() && + GetOrientation(m_style) == wxBOTH) + { + // changing orientation in OnSize causes havoc + int x, y; + GetClientSize(&x, &y); + + if (x > y) + { + newOrientation = wxHORIZONTAL; + } + else + { + newOrientation = wxVERTICAL; + } + } + if (newOrientation != m_orientation) + { + SetOrientation(newOrientation); + Realize(); + if (newOrientation == wxHORIZONTAL) + { + pane.best_size = GetHintSize(wxAUI_DOCK_TOP); + } + else + { + pane.best_size = GetHintSize(wxAUI_DOCK_LEFT); + } + if (pane.IsDocked()) + { + pane.floating_size = wxDefaultSize; + } + else + { + SetSize(GetParent()->GetClientSize()); + } + manager->Update(); + } + } + } + DoIdleUpdate(); evt.Skip(); } void wxAuiToolBar::OnPaint(wxPaintEvent& WXUNUSED(evt)) { - wxBufferedPaintDC dc(this); + wxAutoBufferedPaintDC dc(this); wxRect cli_rect(wxPoint(0,0), GetClientSize()); - - - bool horizontal = true; - if (m_style & wxAUI_TB_VERTICAL) - horizontal = false; + + + bool horizontal = m_orientation == wxHORIZONTAL; m_art->DrawBackground(dc, this, cli_rect); - + int gripper_size = m_art->GetElementSize(wxAUI_TBART_GRIPPER_SIZE); int dropdown_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE); - + // paint the gripper if (gripper_size > 0 && m_gripper_sizer_item) { wxRect gripper_rect = m_gripper_sizer_item->GetRect(); if (horizontal) gripper_rect.width = gripper_size; - else + else gripper_rect.height = gripper_size; m_art->DrawGripper(dc, this, gripper_rect); } - + // calculated how far we can draw items int last_extent; if (horizontal) last_extent = cli_rect.width; - else + else last_extent = cli_rect.height; if (m_overflow_visible) last_extent -= dropdown_size; - + // paint each individual tool size_t i, count = m_items.GetCount(); for (i = 0; i < count; ++i) { wxAuiToolBarItem& item = m_items.Item(i); - + if (!item.sizer_item) continue; - + wxRect item_rect = item.sizer_item->GetRect(); - - + + if ((horizontal && item_rect.x + item_rect.width >= last_extent) || (!horizontal && item_rect.y + item_rect.height >= last_extent)) { break; } - + if (item.kind == wxITEM_SEPARATOR) { // draw a separator m_art->DrawSeparator(dc, this, item_rect); } - else if (item.kind == wxITEM_LABEL) + else if (item.kind == wxITEM_LABEL) { // draw a text label only m_art->DrawLabel(dc, this, item, item_rect); } - else if (item.kind == wxITEM_NORMAL) + else if (item.kind == wxITEM_NORMAL) { // draw a regular button or dropdown button if (!item.dropdown) m_art->DrawButton(dc, this, item, item_rect); - else + else m_art->DrawDropDownButton(dc, this, item, item_rect); } - else if (item.kind == wxITEM_CHECK) + else if (item.kind == wxITEM_CHECK) + { + // draw either a regular or dropdown toggle button + if (!item.dropdown) + m_art->DrawButton(dc, this, item, item_rect); + else + m_art->DrawDropDownButton(dc, this, item, item_rect); + } + else if (item.kind == wxITEM_RADIO) { // draw a toggle button m_art->DrawButton(dc, this, item, item_rect); } - else if (item.kind == wxITEM_CONTROL) + else if (item.kind == wxITEM_CONTROL) { // draw the control's label m_art->DrawControlLabel(dc, this, item, item_rect); @@ -2204,7 +2473,7 @@ void wxAuiToolBar::OnPaint(wxPaintEvent& WXUNUSED(evt)) // fire a signal to see if the item wants to be custom-rendered OnCustomRender(dc, item, item_rect); } - + // paint the overflow button if (dropdown_size > 0 && m_overflow_sizer_item) { @@ -2221,7 +2490,7 @@ void wxAuiToolBar::OnEraseBackground(wxEraseEvent& WXUNUSED(evt)) void wxAuiToolBar::OnLeftDown(wxMouseEvent& evt) { wxRect cli_rect(wxPoint(0,0), GetClientSize()); - + if (m_gripper_sizer_item) { wxRect gripper_rect = m_gripper_sizer_item->GetRect(); @@ -2231,21 +2500,21 @@ void wxAuiToolBar::OnLeftDown(wxMouseEvent& evt) wxAuiManager* manager = wxAuiManager::GetManager(this); if (!manager) return; - + int x_drag_offset = evt.GetX() - gripper_rect.GetX(); int y_drag_offset = evt.GetY() - gripper_rect.GetY(); - + // gripper was clicked manager->StartPaneDrag(this, wxPoint(x_drag_offset, y_drag_offset)); return; } } - + if (m_overflow_sizer_item) { wxRect overflow_rect = GetOverflowRect(); - - if (m_art && + + if (m_art && m_overflow_visible && overflow_rect.Contains(evt.m_x, evt.m_y)) { @@ -2253,23 +2522,23 @@ void wxAuiToolBar::OnLeftDown(wxMouseEvent& evt) e.SetEventObject(this); e.SetToolId(-1); e.SetClickPoint(wxPoint(evt.GetX(), evt.GetY())); - bool processed = ProcessEvent(e); - + bool processed = GetEventHandler()->ProcessEvent(e); + if (processed) { DoIdleUpdate(); } - else + else { size_t i, count; wxAuiToolBarItemArray overflow_items; - + // add custom overflow prepend items, if any count = m_custom_overflow_prepend.GetCount(); for (i = 0; i < count; ++i) - overflow_items.Add(m_custom_overflow_prepend[i]); - + overflow_items.Add(m_custom_overflow_prepend[i]); + // only show items that don't fit in the dropdown count = m_items.GetCount(); for (i = 0; i < count; ++i) @@ -2282,7 +2551,7 @@ void wxAuiToolBar::OnLeftDown(wxMouseEvent& evt) count = m_custom_overflow_append.GetCount(); for (i = 0; i < count; ++i) overflow_items.Add(m_custom_overflow_append[i]); - + int res = m_art->ShowDropDown(this, overflow_items); m_overflow_state = 0; Refresh(false); @@ -2290,18 +2559,18 @@ void wxAuiToolBar::OnLeftDown(wxMouseEvent& evt) { wxCommandEvent e(wxEVT_COMMAND_MENU_SELECTED, res); e.SetEventObject(this); - GetParent()->ProcessEvent(e); + GetParent()->GetEventHandler()->ProcessEvent(e); } } - + return; } } - + m_dragging = false; m_action_pos = wxPoint(evt.GetX(), evt.GetY()); m_action_item = FindToolByPosition(evt.GetX(), evt.GetY()); - + if (m_action_item) { if (m_action_item->state & wxAUI_BUTTON_STATE_DISABLED) @@ -2310,34 +2579,46 @@ void wxAuiToolBar::OnLeftDown(wxMouseEvent& evt) m_action_item = NULL; return; } - - SetPressedItem(m_action_item); - + + UnsetToolTip(); + // fire the tool dropdown event - wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_TOOL_DROPDOWN, m_action_item->id); + wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_TOOL_DROPDOWN, m_action_item->toolid); e.SetEventObject(this); - e.SetToolId(m_action_item->id); - e.SetDropDownClicked(false); - + e.SetToolId(m_action_item->toolid); + int mouse_x = evt.GetX(); wxRect rect = m_action_item->sizer_item->GetRect(); - - if (m_action_item->dropdown && - mouse_x >= (rect.x+rect.width-BUTTON_DROPDOWN_WIDTH-1) && - mouse_x < (rect.x+rect.width)) - { - e.SetDropDownClicked(true); - } - + const bool dropDownHit = m_action_item->dropdown && + mouse_x >= (rect.x+rect.width-BUTTON_DROPDOWN_WIDTH-1) && + mouse_x < (rect.x+rect.width); + e.SetDropDownClicked(dropDownHit); + e.SetClickPoint(evt.GetPosition()); e.SetItemRect(rect); - ProcessEvent(e); + + // we only set the 'pressed button' state if we hit the actual button + // and not just the drop-down + SetPressedItem(dropDownHit ? 0 : m_action_item); + + if(dropDownHit) + { + m_action_pos = wxPoint(-1,-1); + m_action_item = NULL; + } + + if(!GetEventHandler()->ProcessEvent(e) || e.GetSkipped()) + CaptureMouse(); + DoIdleUpdate(); } } void wxAuiToolBar::OnLeftUp(wxMouseEvent& evt) { + if (!HasCapture()) + return; + SetPressedItem(NULL); wxAuiToolBarItem* hit_item = FindToolByPosition(evt.GetX(), evt.GetY()); @@ -2346,67 +2627,66 @@ void wxAuiToolBar::OnLeftUp(wxMouseEvent& evt) SetHoverItem(hit_item); } - if (m_dragging) { - // reset drag and drop member variables - m_dragging = false; - m_action_pos = wxPoint(-1,-1); - m_action_item = NULL; - return; + // TODO: it would make sense to send out an 'END_DRAG' event here, + // otherwise a client would never know what to do with the 'BEGIN_DRAG' + // event + + // OnCaptureLost() will be called now and this will reset all our state + // tracking variables + ReleaseMouse(); } - else + else { wxAuiToolBarItem* hit_item; hit_item = FindToolByPosition(evt.GetX(), evt.GetY()); - + if (m_action_item && hit_item == m_action_item) { - SetToolTip(NULL); - - if (hit_item->kind == wxITEM_CHECK) - { - bool toggle = false; - - if (m_action_item->state & wxAUI_BUTTON_STATE_CHECKED) - toggle = false; - else - toggle = true; - - ToggleTool(m_action_item->id, toggle); - - wxCommandEvent e(wxEVT_COMMAND_MENU_SELECTED, m_action_item->id); - e.SetEventObject(this); - ProcessEvent(e); - DoIdleUpdate(); - } - else + UnsetToolTip(); + + wxCommandEvent e(wxEVT_COMMAND_MENU_SELECTED, m_action_item->toolid); + e.SetEventObject(this); + + if (hit_item->kind == wxITEM_CHECK || hit_item->kind == wxITEM_RADIO) { - wxCommandEvent e(wxEVT_COMMAND_MENU_SELECTED, m_action_item->id); - e.SetEventObject(this); - ProcessEvent(e); - DoIdleUpdate(); + const bool toggle = !(m_action_item->state & wxAUI_BUTTON_STATE_CHECKED); + + ToggleTool(m_action_item->toolid, toggle); + + // repaint immediately + Refresh(false); + Update(); + + e.SetInt(toggle); } + + // we have to release the mouse *before* sending the event, because + // we don't know what a handler might do. It could open up a popup + // menu for example and that would make us lose our capture anyway. + + ReleaseMouse(); + + GetEventHandler()->ProcessEvent(e); + DoIdleUpdate(); } + else + ReleaseMouse(); } - - // reset drag and drop member variables - m_dragging = false; - m_action_pos = wxPoint(-1,-1); - m_action_item = NULL; } void wxAuiToolBar::OnRightDown(wxMouseEvent& evt) { wxRect cli_rect(wxPoint(0,0), GetClientSize()); - + if (m_gripper_sizer_item) { wxRect gripper_rect = m_gripper_sizer_item->GetRect(); if (gripper_rect.Contains(evt.GetX(), evt.GetY())) return; } - + if (m_overflow_sizer_item) { int dropdown_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE); @@ -2419,46 +2699,45 @@ void wxAuiToolBar::OnRightDown(wxMouseEvent& evt) return; } } - + m_action_pos = wxPoint(evt.GetX(), evt.GetY()); m_action_item = FindToolByPosition(evt.GetX(), evt.GetY()); - - if (m_action_item) + + if (m_action_item && m_action_item->state & wxAUI_BUTTON_STATE_DISABLED) { - if (m_action_item->state & wxAUI_BUTTON_STATE_DISABLED) - { - m_action_pos = wxPoint(-1,-1); - m_action_item = NULL; - return; - } + m_action_pos = wxPoint(-1,-1); + m_action_item = NULL; + return; } + + UnsetToolTip(); } void wxAuiToolBar::OnRightUp(wxMouseEvent& evt) { wxAuiToolBarItem* hit_item; hit_item = FindToolByPosition(evt.GetX(), evt.GetY()); - + if (m_action_item && hit_item == m_action_item) { if (hit_item->kind == wxITEM_NORMAL) { - wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_RIGHT_CLICK, m_action_item->id); + wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_RIGHT_CLICK, m_action_item->toolid); e.SetEventObject(this); - e.SetToolId(m_action_item->id); + e.SetToolId(m_action_item->toolid); e.SetClickPoint(m_action_pos); - ProcessEvent(e); + GetEventHandler()->ProcessEvent(e); DoIdleUpdate(); } } - else + else { // right-clicked on the invalid area of the toolbar wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_RIGHT_CLICK, -1); e.SetEventObject(this); e.SetToolId(-1); e.SetClickPoint(m_action_pos); - ProcessEvent(e); + GetEventHandler()->ProcessEvent(e); DoIdleUpdate(); } @@ -2470,14 +2749,14 @@ void wxAuiToolBar::OnRightUp(wxMouseEvent& evt) void wxAuiToolBar::OnMiddleDown(wxMouseEvent& evt) { wxRect cli_rect(wxPoint(0,0), GetClientSize()); - + if (m_gripper_sizer_item) { wxRect gripper_rect = m_gripper_sizer_item->GetRect(); if (gripper_rect.Contains(evt.GetX(), evt.GetY())) return; } - + if (m_overflow_sizer_item) { int dropdown_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE); @@ -2490,10 +2769,10 @@ void wxAuiToolBar::OnMiddleDown(wxMouseEvent& evt) return; } } - + m_action_pos = wxPoint(evt.GetX(), evt.GetY()); m_action_item = FindToolByPosition(evt.GetX(), evt.GetY()); - + if (m_action_item) { if (m_action_item->state & wxAUI_BUTTON_STATE_DISABLED) @@ -2503,22 +2782,24 @@ void wxAuiToolBar::OnMiddleDown(wxMouseEvent& evt) return; } } + + UnsetToolTip(); } void wxAuiToolBar::OnMiddleUp(wxMouseEvent& evt) { wxAuiToolBarItem* hit_item; hit_item = FindToolByPosition(evt.GetX(), evt.GetY()); - + if (m_action_item && hit_item == m_action_item) { if (hit_item->kind == wxITEM_NORMAL) { - wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_MIDDLE_CLICK, m_action_item->id); + wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_MIDDLE_CLICK, m_action_item->toolid); e.SetEventObject(this); - e.SetToolId(m_action_item->id); + e.SetToolId(m_action_item->toolid); e.SetClickPoint(m_action_pos); - ProcessEvent(e); + GetEventHandler()->ProcessEvent(e); DoIdleUpdate(); } } @@ -2530,87 +2811,109 @@ void wxAuiToolBar::OnMiddleUp(wxMouseEvent& evt) void wxAuiToolBar::OnMotion(wxMouseEvent& evt) { + const bool button_pressed = HasCapture(); + // start a drag event - if (!m_dragging && - m_action_item != NULL && - m_action_pos != wxPoint(-1,-1) && - abs(evt.m_x - m_action_pos.x) + abs(evt.m_y - m_action_pos.y) > 5) - { - SetToolTip(NULL); - - m_dragging = true; - + if (!m_dragging && button_pressed && + abs(evt.GetX() - m_action_pos.x) + abs(evt.GetY() - m_action_pos.y) > 5) + { + // TODO: sending this event only makes sense if there is an 'END_DRAG' + // event sent sometime in the future (see OnLeftUp()) wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_BEGIN_DRAG, GetId()); e.SetEventObject(this); - e.SetToolId(m_action_item->id); - ProcessEvent(e); + e.SetToolId(m_action_item->toolid); + m_dragging = GetEventHandler()->ProcessEvent(e) && !e.GetSkipped(); + DoIdleUpdate(); - return; } + if(m_dragging) + return; + wxAuiToolBarItem* hit_item = FindToolByPosition(evt.GetX(), evt.GetY()); - if (hit_item) + if(button_pressed) { - if (!(hit_item->state & wxAUI_BUTTON_STATE_DISABLED)) - SetHoverItem(hit_item); - else - SetHoverItem(NULL); - } - else - { - // no hit item, remove any hit item - SetHoverItem(hit_item); - } - - // figure out tooltips - wxAuiToolBarItem* packing_hit_item; - packing_hit_item = FindToolByPositionWithPacking(evt.GetX(), evt.GetY()); - if (packing_hit_item) - { - if (packing_hit_item != m_tip_item) + // if we have a button pressed we want it to be shown in 'depressed' + // state unless we move the mouse outside the button, then we want it + // to show as just 'highlighted' + if (hit_item == m_action_item) + SetPressedItem(m_action_item); + else { - m_tip_item = packing_hit_item; - - if (packing_hit_item->short_help.Length() > 0) - SetToolTip(packing_hit_item->short_help); - else - SetToolTip(NULL); + SetPressedItem(NULL); + SetHoverItem(m_action_item); } } - else + else { - SetToolTip(NULL); - m_tip_item = NULL; - } - - // if we've pressed down an item and we're hovering - // over it, make sure it's state is set to pressed - if (m_action_item) - { - if (m_action_item == hit_item) - SetPressedItem(m_action_item); - else - SetPressedItem(NULL); + if (hit_item && (hit_item->state & wxAUI_BUTTON_STATE_DISABLED)) + SetHoverItem(NULL); + else + SetHoverItem(hit_item); + + // tooltips handling + wxAuiToolBarItem* packing_hit_item; + packing_hit_item = FindToolByPositionWithPacking(evt.GetX(), evt.GetY()); + if (packing_hit_item) + { + if (packing_hit_item != m_tip_item) + { + m_tip_item = packing_hit_item; + + if ( !packing_hit_item->short_help.empty() ) + SetToolTip(packing_hit_item->short_help); + else + UnsetToolTip(); + } + } + else + { + UnsetToolTip(); + m_tip_item = NULL; + } + + // figure out the dropdown button state (are we hovering or pressing it?) + RefreshOverflowState(); } - - // figure out the dropdown button state (are we hovering or pressing it?) - RefreshOverflowState(); } -void wxAuiToolBar::OnLeaveWindow(wxMouseEvent& WXUNUSED(evt)) +void wxAuiToolBar::DoResetMouseState() { RefreshOverflowState(); SetHoverItem(NULL); SetPressedItem(NULL); - + m_tip_item = NULL; + + // we have to reset those here, because the mouse-up handlers which do + // it usually won't be called if we let go of a mouse button while we + // are outside of the window + m_action_pos = wxPoint(-1,-1); + m_action_item = NULL; +} + +void wxAuiToolBar::OnLeaveWindow(wxMouseEvent& evt) +{ + if(HasCapture()) + { + evt.Skip(); + return; + } + + DoResetMouseState(); } +void wxAuiToolBar::OnCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(evt)) +{ + m_dragging = false; + + DoResetMouseState(); +} void wxAuiToolBar::OnSetCursor(wxSetCursorEvent& evt) { wxCursor cursor = wxNullCursor; - + if (m_gripper_sizer_item) { wxRect gripper_rect = m_gripper_sizer_item->GetRect(); @@ -2619,7 +2922,7 @@ void wxAuiToolBar::OnSetCursor(wxSetCursorEvent& evt) cursor = wxCursor(wxCURSOR_SIZING); } } - + evt.SetCursor(cursor); }