The code could crash if m_overflowVisible was true but m_overflowSizerItem was NULL. Ideally this shouldn't happen in the first place, but it did, so at least fix the crash for now -- and hopefully this code will be refactored to make it more clear later. Closes #15747. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@75400 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2917 lines
77 KiB
C++
2917 lines
77 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Name: src/aui/auibar.cpp
|
|
// Purpose: wxaui: wx advanced user interface - docking window manager
|
|
// Author: Benjamin I. Williams
|
|
// Modified by:
|
|
// Created: 2005-05-17
|
|
// Copyright: (C) Copyright 2005-2006, Kirix Corporation, All Rights Reserved
|
|
// Licence: wxWindows Library Licence, Version 3.1
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// ============================================================================
|
|
// declarations
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// headers
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#if wxUSE_AUI
|
|
|
|
#include "wx/statline.h"
|
|
#include "wx/dcbuffer.h"
|
|
#include "wx/sizer.h"
|
|
#include "wx/image.h"
|
|
#include "wx/settings.h"
|
|
#include "wx/menu.h"
|
|
|
|
#include "wx/aui/auibar.h"
|
|
#include "wx/aui/framemanager.h"
|
|
|
|
#ifdef __WXMAC__
|
|
#include "wx/osx/private.h"
|
|
#endif
|
|
|
|
#include "wx/arrimpl.cpp"
|
|
WX_DEFINE_OBJARRAY(wxAuiToolBarItemArray)
|
|
|
|
|
|
wxDEFINE_EVENT( wxEVT_AUITOOLBAR_TOOL_DROPDOWN, wxAuiToolBarEvent );
|
|
wxDEFINE_EVENT( wxEVT_AUITOOLBAR_OVERFLOW_CLICK, wxAuiToolBarEvent );
|
|
wxDEFINE_EVENT( wxEVT_AUITOOLBAR_RIGHT_CLICK, wxAuiToolBarEvent );
|
|
wxDEFINE_EVENT( wxEVT_AUITOOLBAR_MIDDLE_CLICK, wxAuiToolBarEvent );
|
|
wxDEFINE_EVENT( wxEVT_AUITOOLBAR_BEGIN_DRAG, wxAuiToolBarEvent );
|
|
|
|
|
|
IMPLEMENT_CLASS(wxAuiToolBar, wxControl)
|
|
IMPLEMENT_DYNAMIC_CLASS(wxAuiToolBarEvent, wxEvent)
|
|
|
|
|
|
// missing wxITEM_* items
|
|
enum
|
|
{
|
|
wxITEM_CONTROL = wxITEM_MAX,
|
|
wxITEM_LABEL,
|
|
wxITEM_SPACER
|
|
};
|
|
|
|
const int BUTTON_DROPDOWN_WIDTH = 10;
|
|
|
|
|
|
wxBitmap wxAuiBitmapFromBits(const unsigned char bits[], int w, int h,
|
|
const wxColour& color);
|
|
|
|
static wxColor GetBaseColor()
|
|
{
|
|
|
|
#if defined( __WXMAC__ ) && wxOSX_USE_COCOA_OR_CARBON
|
|
wxColor baseColour = wxColour( wxMacCreateCGColorFromHITheme(kThemeBrushToolbarBackground));
|
|
#else
|
|
wxColor baseColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
|
|
#endif
|
|
|
|
// the baseColour is too pale to use as our base colour,
|
|
// so darken it a bit --
|
|
if ((255-baseColour.Red()) +
|
|
(255-baseColour.Green()) +
|
|
(255-baseColour.Blue()) < 60)
|
|
{
|
|
baseColour = baseColour.ChangeLightness(92);
|
|
}
|
|
|
|
return baseColour;
|
|
}
|
|
|
|
|
|
|
|
class ToolbarCommandCapture : public wxEvtHandler
|
|
{
|
|
public:
|
|
|
|
ToolbarCommandCapture() { m_lastId = 0; }
|
|
int GetCommandId() const { return m_lastId; }
|
|
|
|
bool ProcessEvent(wxEvent& evt)
|
|
{
|
|
if (evt.GetEventType() == wxEVT_MENU)
|
|
{
|
|
m_lastId = evt.GetId();
|
|
return true;
|
|
}
|
|
|
|
if (GetNextHandler())
|
|
return GetNextHandler()->ProcessEvent(evt);
|
|
|
|
return false;
|
|
}
|
|
|
|
private:
|
|
int m_lastId;
|
|
};
|
|
|
|
|
|
|
|
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()
|
|
{
|
|
m_baseColour = GetBaseColor();
|
|
|
|
m_flags = 0;
|
|
m_textOrientation = wxAUI_TBTOOL_TEXT_BOTTOM;
|
|
m_highlightColour = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
|
|
|
|
m_separatorSize = 7;
|
|
m_gripperSize = 7;
|
|
m_overflowSize = 16;
|
|
|
|
wxColor darker1Colour = m_baseColour.ChangeLightness(85);
|
|
wxColor darker2Colour = m_baseColour.ChangeLightness(75);
|
|
wxColor darker3Colour = m_baseColour.ChangeLightness(60);
|
|
wxColor darker4Colour = m_baseColour.ChangeLightness(50);
|
|
wxColor darker5Colour = m_baseColour.ChangeLightness(40);
|
|
|
|
m_gripperPen1 = wxPen(darker5Colour);
|
|
m_gripperPen2 = wxPen(darker3Colour);
|
|
m_gripperPen3 = *wxWHITE_PEN;
|
|
|
|
static const unsigned char buttonDropdownBits[] = { 0xe0, 0xf1, 0xfb };
|
|
static const unsigned char overflowBits[] = { 0x80, 0xff, 0x80, 0xc1, 0xe3, 0xf7 };
|
|
|
|
m_buttonDropDownBmp = wxAuiBitmapFromBits(buttonDropdownBits, 5, 3,
|
|
*wxBLACK);
|
|
m_disabledButtonDropDownBmp = wxAuiBitmapFromBits(
|
|
buttonDropdownBits, 5, 3,
|
|
wxColor(128,128,128));
|
|
m_overflowBmp = wxAuiBitmapFromBits(overflowBits, 7, 6, *wxBLACK);
|
|
m_disabledOverflowBmp = wxAuiBitmapFromBits(overflowBits, 7, 6, wxColor(128,128,128));
|
|
|
|
m_font = *wxNORMAL_FONT;
|
|
}
|
|
|
|
wxAuiDefaultToolBarArt::~wxAuiDefaultToolBarArt()
|
|
{
|
|
m_font = *wxNORMAL_FONT;
|
|
}
|
|
|
|
|
|
wxAuiToolBarArt* wxAuiDefaultToolBarArt::Clone()
|
|
{
|
|
return static_cast<wxAuiToolBarArt*>(new wxAuiDefaultToolBarArt);
|
|
}
|
|
|
|
void wxAuiDefaultToolBarArt::SetFlags(unsigned int flags)
|
|
{
|
|
m_flags = flags;
|
|
}
|
|
|
|
void wxAuiDefaultToolBarArt::SetFont(const wxFont& font)
|
|
{
|
|
m_font = font;
|
|
}
|
|
|
|
void wxAuiDefaultToolBarArt::SetTextOrientation(int orientation)
|
|
{
|
|
m_textOrientation = orientation;
|
|
}
|
|
|
|
unsigned int wxAuiDefaultToolBarArt::GetFlags()
|
|
{
|
|
return m_flags;
|
|
}
|
|
|
|
wxFont wxAuiDefaultToolBarArt::GetFont()
|
|
{
|
|
return m_font;
|
|
}
|
|
|
|
int wxAuiDefaultToolBarArt::GetTextOrientation()
|
|
{
|
|
return m_textOrientation;
|
|
}
|
|
|
|
void wxAuiDefaultToolBarArt::DrawBackground(
|
|
wxDC& dc,
|
|
wxWindow* WXUNUSED(wnd),
|
|
const wxRect& _rect)
|
|
{
|
|
wxRect rect = _rect;
|
|
rect.height++;
|
|
wxColour startColour = m_baseColour.ChangeLightness(150);
|
|
wxColour endColour = m_baseColour.ChangeLightness(90);
|
|
dc.GradientFillLinear(rect, startColour, endColour, wxSOUTH);
|
|
}
|
|
|
|
void wxAuiDefaultToolBarArt::DrawPlainBackground(wxDC& dc,
|
|
wxWindow* WXUNUSED(wnd),
|
|
const wxRect& _rect)
|
|
{
|
|
wxRect rect = _rect;
|
|
rect.height++;
|
|
|
|
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
|
|
|
|
dc.DrawRectangle(rect.GetX() - 1, rect.GetY() - 1,
|
|
rect.GetWidth() + 2, rect.GetHeight() + 1);
|
|
}
|
|
|
|
void wxAuiDefaultToolBarArt::DrawLabel(
|
|
wxDC& dc,
|
|
wxWindow* WXUNUSED(wnd),
|
|
const wxAuiToolBarItem& item,
|
|
const wxRect& rect)
|
|
{
|
|
dc.SetFont(m_font);
|
|
dc.SetTextForeground(*wxBLACK);
|
|
|
|
// we only care about the text height here since the text
|
|
// will get cropped based on the width of the item
|
|
int textWidth = 0, textHeight = 0;
|
|
dc.GetTextExtent(wxT("ABCDHgj"), &textWidth, &textHeight);
|
|
|
|
// set the clipping region
|
|
wxRect clipRect = rect;
|
|
clipRect.width -= 1;
|
|
dc.SetClippingRegion(clipRect);
|
|
|
|
int textX, textY;
|
|
textX = rect.x + 1;
|
|
textY = rect.y + (rect.height-textHeight)/2;
|
|
dc.DrawText(item.GetLabel(), textX, textY);
|
|
dc.DestroyClippingRegion();
|
|
}
|
|
|
|
|
|
void wxAuiDefaultToolBarArt::DrawButton(
|
|
wxDC& dc,
|
|
wxWindow* WXUNUSED(wnd),
|
|
const wxAuiToolBarItem& item,
|
|
const wxRect& rect)
|
|
{
|
|
int textWidth = 0, textHeight = 0;
|
|
|
|
if (m_flags & wxAUI_TB_TEXT)
|
|
{
|
|
dc.SetFont(m_font);
|
|
|
|
int tx, ty;
|
|
|
|
dc.GetTextExtent(wxT("ABCDHgj"), &tx, &textHeight);
|
|
textWidth = 0;
|
|
dc.GetTextExtent(item.GetLabel(), &textWidth, &ty);
|
|
}
|
|
|
|
int bmpX = 0, bmpY = 0;
|
|
int textX = 0, textY = 0;
|
|
|
|
if (m_textOrientation == wxAUI_TBTOOL_TEXT_BOTTOM)
|
|
{
|
|
bmpX = rect.x +
|
|
(rect.width/2) -
|
|
(item.GetBitmap().GetWidth()/2);
|
|
|
|
bmpY = rect.y +
|
|
((rect.height-textHeight)/2) -
|
|
(item.GetBitmap().GetHeight()/2);
|
|
|
|
textX = rect.x + (rect.width/2) - (textWidth/2) + 1;
|
|
textY = rect.y + rect.height - textHeight - 1;
|
|
}
|
|
else if (m_textOrientation == wxAUI_TBTOOL_TEXT_RIGHT)
|
|
{
|
|
bmpX = rect.x + 3;
|
|
|
|
bmpY = rect.y +
|
|
(rect.height/2) -
|
|
(item.GetBitmap().GetHeight()/2);
|
|
|
|
textX = bmpX + 3 + item.GetBitmap().GetWidth();
|
|
textY = rect.y +
|
|
(rect.height/2) -
|
|
(textHeight/2);
|
|
}
|
|
|
|
|
|
if (!(item.GetState() & wxAUI_BUTTON_STATE_DISABLED))
|
|
{
|
|
if (item.GetState() & wxAUI_BUTTON_STATE_PRESSED)
|
|
{
|
|
dc.SetPen(wxPen(m_highlightColour));
|
|
dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(150)));
|
|
dc.DrawRectangle(rect);
|
|
}
|
|
else if ((item.GetState() & wxAUI_BUTTON_STATE_HOVER) || item.IsSticky())
|
|
{
|
|
dc.SetPen(wxPen(m_highlightColour));
|
|
dc.SetBrush(wxBrush(m_highlightColour.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.GetState() & wxAUI_BUTTON_STATE_CHECKED)
|
|
dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(180)));
|
|
|
|
dc.DrawRectangle(rect);
|
|
}
|
|
else if (item.GetState() & wxAUI_BUTTON_STATE_CHECKED)
|
|
{
|
|
// it's important to put this code in an else statement after the
|
|
// hover, otherwise hovers won't draw properly for checked items
|
|
dc.SetPen(wxPen(m_highlightColour));
|
|
dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(170)));
|
|
dc.DrawRectangle(rect);
|
|
}
|
|
}
|
|
|
|
wxBitmap bmp;
|
|
if (item.GetState() & wxAUI_BUTTON_STATE_DISABLED)
|
|
bmp = item.GetDisabledBitmap();
|
|
else
|
|
bmp = item.GetBitmap();
|
|
|
|
if ( bmp.IsOk() )
|
|
dc.DrawBitmap(bmp, bmpX, bmpY, true);
|
|
|
|
// set the item's text color based on if it is disabled
|
|
dc.SetTextForeground(*wxBLACK);
|
|
if (item.GetState() & wxAUI_BUTTON_STATE_DISABLED)
|
|
dc.SetTextForeground(DISABLED_TEXT_COLOR);
|
|
|
|
if ( (m_flags & wxAUI_TB_TEXT) && !item.GetLabel().empty() )
|
|
{
|
|
dc.DrawText(item.GetLabel(), textX, textY);
|
|
}
|
|
}
|
|
|
|
|
|
void wxAuiDefaultToolBarArt::DrawDropDownButton(
|
|
wxDC& dc,
|
|
wxWindow* WXUNUSED(wnd),
|
|
const wxAuiToolBarItem& item,
|
|
const wxRect& rect)
|
|
{
|
|
int textWidth = 0, textHeight = 0, textX = 0, textY = 0;
|
|
int bmpX = 0, bmpY = 0, dropBmpX = 0, dropBmpY = 0;
|
|
|
|
wxRect buttonRect = wxRect(rect.x,
|
|
rect.y,
|
|
rect.width-BUTTON_DROPDOWN_WIDTH,
|
|
rect.height);
|
|
wxRect dropDownRect = wxRect(rect.x+rect.width-BUTTON_DROPDOWN_WIDTH-1,
|
|
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, &textHeight);
|
|
textWidth = 0;
|
|
}
|
|
|
|
dc.GetTextExtent(item.GetLabel(), &textWidth, &ty);
|
|
}
|
|
|
|
|
|
|
|
dropBmpX = dropDownRect.x +
|
|
(dropDownRect.width/2) -
|
|
(m_buttonDropDownBmp.GetWidth()/2);
|
|
dropBmpY = dropDownRect.y +
|
|
(dropDownRect.height/2) -
|
|
(m_buttonDropDownBmp.GetHeight()/2);
|
|
|
|
|
|
if (m_textOrientation == wxAUI_TBTOOL_TEXT_BOTTOM)
|
|
{
|
|
bmpX = buttonRect.x +
|
|
(buttonRect.width/2) -
|
|
(item.GetBitmap().GetWidth()/2);
|
|
bmpY = buttonRect.y +
|
|
((buttonRect.height-textHeight)/2) -
|
|
(item.GetBitmap().GetHeight()/2);
|
|
|
|
textX = rect.x + (rect.width/2) - (textWidth/2) + 1;
|
|
textY = rect.y + rect.height - textHeight - 1;
|
|
}
|
|
else if (m_textOrientation == wxAUI_TBTOOL_TEXT_RIGHT)
|
|
{
|
|
bmpX = rect.x + 3;
|
|
|
|
bmpY = rect.y +
|
|
(rect.height/2) -
|
|
(item.GetBitmap().GetHeight()/2);
|
|
|
|
textX = bmpX + 3 + item.GetBitmap().GetWidth();
|
|
textY = rect.y +
|
|
(rect.height/2) -
|
|
(textHeight/2);
|
|
}
|
|
|
|
|
|
if (item.GetState() & wxAUI_BUTTON_STATE_PRESSED)
|
|
{
|
|
dc.SetPen(wxPen(m_highlightColour));
|
|
dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(140)));
|
|
dc.DrawRectangle(buttonRect);
|
|
|
|
dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(170)));
|
|
dc.DrawRectangle(dropDownRect);
|
|
}
|
|
else if (item.GetState() & wxAUI_BUTTON_STATE_HOVER ||
|
|
item.IsSticky())
|
|
{
|
|
dc.SetPen(wxPen(m_highlightColour));
|
|
dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(170)));
|
|
dc.DrawRectangle(buttonRect);
|
|
dc.DrawRectangle(dropDownRect);
|
|
}
|
|
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.m_
|
|
dc.SetPen(wxPen(m_highlightColour));
|
|
dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(170)));
|
|
dc.DrawRectangle(buttonRect);
|
|
dc.DrawRectangle(dropDownRect);
|
|
}
|
|
|
|
wxBitmap bmp;
|
|
wxBitmap dropbmp;
|
|
if (item.GetState() & wxAUI_BUTTON_STATE_DISABLED)
|
|
{
|
|
bmp = item.GetDisabledBitmap();
|
|
dropbmp = m_disabledButtonDropDownBmp;
|
|
}
|
|
else
|
|
{
|
|
bmp = item.GetBitmap();
|
|
dropbmp = m_buttonDropDownBmp;
|
|
}
|
|
|
|
if (!bmp.IsOk())
|
|
return;
|
|
|
|
dc.DrawBitmap(bmp, bmpX, bmpY, true);
|
|
dc.DrawBitmap(dropbmp, dropBmpX, dropBmpY, true);
|
|
|
|
// set the item's text color based on if it is disabled
|
|
dc.SetTextForeground(*wxBLACK);
|
|
if (item.GetState() & wxAUI_BUTTON_STATE_DISABLED)
|
|
dc.SetTextForeground(DISABLED_TEXT_COLOR);
|
|
|
|
if ( (m_flags & wxAUI_TB_TEXT) && !item.GetLabel().empty() )
|
|
{
|
|
dc.DrawText(item.GetLabel(), textX, textY);
|
|
}
|
|
}
|
|
|
|
void wxAuiDefaultToolBarArt::DrawControlLabel(
|
|
wxDC& dc,
|
|
wxWindow* WXUNUSED(wnd),
|
|
const wxAuiToolBarItem& item,
|
|
const wxRect& rect)
|
|
{
|
|
if (!(m_flags & wxAUI_TB_TEXT))
|
|
return;
|
|
|
|
if (m_textOrientation != wxAUI_TBTOOL_TEXT_BOTTOM)
|
|
return;
|
|
|
|
int textX = 0, textY = 0;
|
|
int textWidth = 0, textHeight = 0;
|
|
|
|
dc.SetFont(m_font);
|
|
|
|
int tx, ty;
|
|
if (m_flags & wxAUI_TB_TEXT)
|
|
{
|
|
dc.GetTextExtent(wxT("ABCDHgj"), &tx, &textHeight);
|
|
textWidth = 0;
|
|
}
|
|
|
|
dc.GetTextExtent(item.GetLabel(), &textWidth, &ty);
|
|
|
|
// don't draw the label if it is wider than the item width
|
|
if (textWidth > rect.width)
|
|
return;
|
|
|
|
// set the label's text color
|
|
dc.SetTextForeground(*wxBLACK);
|
|
|
|
textX = rect.x + (rect.width/2) - (textWidth/2) + 1;
|
|
textY = rect.y + rect.height - textHeight - 1;
|
|
|
|
if ( (m_flags & wxAUI_TB_TEXT) && !item.GetLabel().empty() )
|
|
{
|
|
dc.DrawText(item.GetLabel(), textX, textY);
|
|
}
|
|
}
|
|
|
|
wxSize wxAuiDefaultToolBarArt::GetLabelSize(
|
|
wxDC& dc,
|
|
wxWindow* WXUNUSED(wnd),
|
|
const wxAuiToolBarItem& item)
|
|
{
|
|
dc.SetFont(m_font);
|
|
|
|
// get label's height
|
|
int width = 0, height = 0;
|
|
dc.GetTextExtent(wxT("ABCDHgj"), &width, &height);
|
|
|
|
// get item's width
|
|
width = item.GetMinSize().GetWidth();
|
|
|
|
if (width == -1)
|
|
{
|
|
// no width specified, measure the text ourselves
|
|
width = dc.GetTextExtent(item.GetLabel()).GetX();
|
|
}
|
|
|
|
return wxSize(width, height);
|
|
}
|
|
|
|
wxSize wxAuiDefaultToolBarArt::GetToolSize(
|
|
wxDC& dc,
|
|
wxWindow* WXUNUSED(wnd),
|
|
const wxAuiToolBarItem& item)
|
|
{
|
|
if (!item.GetBitmap().IsOk() && !(m_flags & wxAUI_TB_TEXT))
|
|
return wxSize(16,16);
|
|
|
|
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_textOrientation == wxAUI_TBTOOL_TEXT_BOTTOM)
|
|
{
|
|
dc.GetTextExtent(wxT("ABCDHgj"), &tx, &ty);
|
|
height += ty;
|
|
|
|
if ( !item.GetLabel().empty() )
|
|
{
|
|
dc.GetTextExtent(item.GetLabel(), &tx, &ty);
|
|
width = wxMax(width, tx+6);
|
|
}
|
|
}
|
|
else if ( m_textOrientation == wxAUI_TBTOOL_TEXT_RIGHT &&
|
|
!item.GetLabel().empty() )
|
|
{
|
|
width += 3; // space between left border and bitmap
|
|
width += 3; // space between bitmap and text
|
|
|
|
if ( !item.GetLabel().empty() )
|
|
{
|
|
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.HasDropDown())
|
|
width += (BUTTON_DROPDOWN_WIDTH+4);
|
|
|
|
return wxSize(width, height);
|
|
}
|
|
|
|
void wxAuiDefaultToolBarArt::DrawSeparator(
|
|
wxDC& dc,
|
|
wxWindow* WXUNUSED(wnd),
|
|
const wxRect& _rect)
|
|
{
|
|
bool horizontal = true;
|
|
if (m_flags & wxAUI_TB_VERTICAL)
|
|
horizontal = false;
|
|
|
|
wxRect rect = _rect;
|
|
|
|
if (horizontal)
|
|
{
|
|
rect.x += (rect.width/2);
|
|
rect.width = 1;
|
|
int new_height = (rect.height*3)/4;
|
|
rect.y += (rect.height/2) - (new_height/2);
|
|
rect.height = new_height;
|
|
}
|
|
else
|
|
{
|
|
rect.y += (rect.height/2);
|
|
rect.height = 1;
|
|
int new_width = (rect.width*3)/4;
|
|
rect.x += (rect.width/2) - (new_width/2);
|
|
rect.width = new_width;
|
|
}
|
|
|
|
wxColour startColour = m_baseColour.ChangeLightness(80);
|
|
wxColour endColour = m_baseColour.ChangeLightness(80);
|
|
dc.GradientFillLinear(rect, startColour, endColour, horizontal ? wxSOUTH : wxEAST);
|
|
}
|
|
|
|
void wxAuiDefaultToolBarArt::DrawGripper(wxDC& dc,
|
|
wxWindow* WXUNUSED(wnd),
|
|
const wxRect& rect)
|
|
{
|
|
int i = 0;
|
|
while (1)
|
|
{
|
|
int x, y;
|
|
|
|
if (m_flags & wxAUI_TB_VERTICAL)
|
|
{
|
|
x = rect.x + (i*4) + 5;
|
|
y = rect.y + 3;
|
|
if (x > rect.GetWidth()-5)
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
x = rect.x + 3;
|
|
y = rect.y + (i*4) + 5;
|
|
if (y > rect.GetHeight()-5)
|
|
break;
|
|
}
|
|
|
|
dc.SetPen(m_gripperPen1);
|
|
dc.DrawPoint(x, y);
|
|
dc.SetPen(m_gripperPen2);
|
|
dc.DrawPoint(x, y+1);
|
|
dc.DrawPoint(x+1, y);
|
|
dc.SetPen(m_gripperPen3);
|
|
dc.DrawPoint(x+2, y+1);
|
|
dc.DrawPoint(x+2, y+2);
|
|
dc.DrawPoint(x+1, y+2);
|
|
|
|
i++;
|
|
}
|
|
|
|
}
|
|
|
|
void wxAuiDefaultToolBarArt::DrawOverflowButton(wxDC& dc,
|
|
wxWindow* /*wnd*/,
|
|
const wxRect& rect,
|
|
int state)
|
|
{
|
|
if (state & wxAUI_BUTTON_STATE_HOVER ||
|
|
state & wxAUI_BUTTON_STATE_PRESSED)
|
|
{
|
|
wxColor light_gray_bg = m_highlightColour.ChangeLightness(170);
|
|
|
|
if (m_flags & wxAUI_TB_VERTICAL)
|
|
{
|
|
dc.SetPen(wxPen(m_highlightColour));
|
|
dc.DrawLine(rect.x, rect.y, rect.x+rect.width, rect.y);
|
|
dc.SetPen(wxPen(light_gray_bg));
|
|
dc.SetBrush(wxBrush(light_gray_bg));
|
|
dc.DrawRectangle(rect.x, rect.y+1, rect.width, rect.height);
|
|
}
|
|
else
|
|
{
|
|
dc.SetPen(wxPen(m_highlightColour));
|
|
dc.DrawLine(rect.x, rect.y, rect.x, rect.y+rect.height);
|
|
dc.SetPen(wxPen(light_gray_bg));
|
|
dc.SetBrush(wxBrush(light_gray_bg));
|
|
dc.DrawRectangle(rect.x+1, rect.y, rect.width, rect.height);
|
|
}
|
|
}
|
|
|
|
int x = rect.x+1+(rect.width-m_overflowBmp.GetWidth())/2;
|
|
int y = rect.y+1+(rect.height-m_overflowBmp.GetHeight())/2;
|
|
dc.DrawBitmap(m_overflowBmp, x, y, true);
|
|
}
|
|
|
|
int wxAuiDefaultToolBarArt::GetElementSize(int element_id)
|
|
{
|
|
switch (element_id)
|
|
{
|
|
case wxAUI_TBART_SEPARATOR_SIZE: return m_separatorSize;
|
|
case wxAUI_TBART_GRIPPER_SIZE: return m_gripperSize;
|
|
case wxAUI_TBART_OVERFLOW_SIZE: return m_overflowSize;
|
|
default: return 0;
|
|
}
|
|
}
|
|
|
|
void wxAuiDefaultToolBarArt::SetElementSize(int element_id, int size)
|
|
{
|
|
switch (element_id)
|
|
{
|
|
case wxAUI_TBART_SEPARATOR_SIZE: m_separatorSize = size; break;
|
|
case wxAUI_TBART_GRIPPER_SIZE: m_gripperSize = size; break;
|
|
case wxAUI_TBART_OVERFLOW_SIZE: m_overflowSize = size; break;
|
|
}
|
|
}
|
|
|
|
int wxAuiDefaultToolBarArt::ShowDropDown(wxWindow* wnd,
|
|
const wxAuiToolBarItemArray& items)
|
|
{
|
|
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.GetKind() == wxITEM_NORMAL)
|
|
{
|
|
wxString text = item.GetShortHelp();
|
|
if (text.empty())
|
|
text = item.GetLabel();
|
|
|
|
if (text.empty())
|
|
text = wxT(" ");
|
|
|
|
wxMenuItem* m = new wxMenuItem(&menuPopup, item.GetId(), text, item.GetShortHelp());
|
|
|
|
m->SetBitmap(item.GetBitmap());
|
|
menuPopup.Append(m);
|
|
items_added++;
|
|
}
|
|
else if (item.GetKind() == wxITEM_SEPARATOR)
|
|
{
|
|
if (items_added > 0)
|
|
menuPopup.AppendSeparator();
|
|
}
|
|
}
|
|
|
|
// find out where to put the popup menu of window items
|
|
wxPoint pt = ::wxGetMousePosition();
|
|
pt = wnd->ScreenToClient(pt);
|
|
|
|
// find out the screen coordinate at the bottom of the tab ctrl
|
|
wxRect cli_rect = wnd->GetClientRect();
|
|
pt.y = cli_rect.y + cli_rect.height;
|
|
|
|
ToolbarCommandCapture* cc = new ToolbarCommandCapture;
|
|
wnd->PushEventHandler(cc);
|
|
wnd->PopupMenu(&menuPopup, pt);
|
|
int command = cc->GetCommandId();
|
|
wnd->PopEventHandler(true);
|
|
|
|
return command;
|
|
}
|
|
|
|
|
|
|
|
|
|
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)
|
|
EVT_ERASE_BACKGROUND(wxAuiToolBar::OnEraseBackground)
|
|
EVT_PAINT(wxAuiToolBar::OnPaint)
|
|
EVT_LEFT_DOWN(wxAuiToolBar::OnLeftDown)
|
|
EVT_LEFT_DCLICK(wxAuiToolBar::OnLeftDown)
|
|
EVT_LEFT_UP(wxAuiToolBar::OnLeftUp)
|
|
EVT_RIGHT_DOWN(wxAuiToolBar::OnRightDown)
|
|
EVT_RIGHT_DCLICK(wxAuiToolBar::OnRightDown)
|
|
EVT_RIGHT_UP(wxAuiToolBar::OnRightUp)
|
|
EVT_MIDDLE_DOWN(wxAuiToolBar::OnMiddleDown)
|
|
EVT_MIDDLE_DCLICK(wxAuiToolBar::OnMiddleDown)
|
|
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()
|
|
|
|
void wxAuiToolBar::Init()
|
|
{
|
|
m_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
m_buttonWidth = -1;
|
|
m_buttonHeight = -1;
|
|
m_sizerElementCount = 0;
|
|
m_actionPos = wxDefaultPosition;
|
|
m_actionItem = NULL;
|
|
m_tipItem = NULL;
|
|
m_art = new wxAuiDefaultToolBarArt;
|
|
m_toolPacking = 2;
|
|
m_toolBorderPadding = 3;
|
|
m_toolTextOrientation = wxAUI_TBTOOL_TEXT_BOTTOM;
|
|
m_gripperSizerItem = NULL;
|
|
m_overflowSizerItem = NULL;
|
|
m_dragging = false;
|
|
m_gripperVisible = false;
|
|
m_overflowVisible = false;
|
|
m_overflowState = 0;
|
|
m_orientation = wxHORIZONTAL;
|
|
}
|
|
|
|
bool wxAuiToolBar::Create(wxWindow* parent,
|
|
wxWindowID id,
|
|
const wxPoint& pos,
|
|
const wxSize& size,
|
|
long style)
|
|
{
|
|
style = style|wxBORDER_NONE;
|
|
|
|
if (!wxControl::Create(parent, id, pos, size, style))
|
|
return false;
|
|
|
|
m_windowStyle = style;
|
|
|
|
m_gripperVisible = (style & wxAUI_TB_GRIPPER) ? true : false;
|
|
m_overflowVisible = (style & wxAUI_TB_OVERFLOW) ? true : false;
|
|
|
|
m_orientation = GetOrientation(style);
|
|
if (m_orientation == wxBOTH)
|
|
{
|
|
m_orientation = wxHORIZONTAL;
|
|
}
|
|
|
|
SetMargins(5, 5, 2, 2);
|
|
SetFont(*wxNORMAL_FONT);
|
|
SetArtFlags();
|
|
SetExtraStyle(wxWS_EX_PROCESS_IDLE);
|
|
if (style & wxAUI_TB_HORZ_LAYOUT)
|
|
SetToolTextOrientation(wxAUI_TBTOOL_TEXT_RIGHT);
|
|
SetBackgroundStyle(wxBG_STYLE_CUSTOM);
|
|
|
|
return true;
|
|
}
|
|
|
|
wxAuiToolBar::~wxAuiToolBar()
|
|
{
|
|
delete m_art;
|
|
delete m_sizer;
|
|
}
|
|
|
|
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_windowStyle = style;
|
|
|
|
if (m_art)
|
|
{
|
|
SetArtFlags();
|
|
}
|
|
|
|
if (m_windowStyle & wxAUI_TB_GRIPPER)
|
|
m_gripperVisible = true;
|
|
else
|
|
m_gripperVisible = false;
|
|
|
|
|
|
if (m_windowStyle & wxAUI_TB_OVERFLOW)
|
|
m_overflowVisible = true;
|
|
else
|
|
m_overflowVisible = false;
|
|
|
|
if (style & wxAUI_TB_HORZ_LAYOUT)
|
|
SetToolTextOrientation(wxAUI_TBTOOL_TEXT_RIGHT);
|
|
else
|
|
SetToolTextOrientation(wxAUI_TBTOOL_TEXT_BOTTOM);
|
|
}
|
|
|
|
void wxAuiToolBar::SetArtProvider(wxAuiToolBarArt* art)
|
|
{
|
|
delete m_art;
|
|
|
|
m_art = art;
|
|
|
|
if (m_art)
|
|
{
|
|
SetArtFlags();
|
|
m_art->SetTextOrientation(m_toolTextOrientation);
|
|
}
|
|
}
|
|
|
|
wxAuiToolBarArt* wxAuiToolBar::GetArtProvider() const
|
|
{
|
|
return m_art;
|
|
}
|
|
|
|
|
|
|
|
|
|
wxAuiToolBarItem* wxAuiToolBar::AddTool(int tool_id,
|
|
const wxString& label,
|
|
const wxBitmap& bitmap,
|
|
const wxString& shortHelp_string,
|
|
wxItemKind kind)
|
|
{
|
|
return AddTool(tool_id,
|
|
label,
|
|
bitmap,
|
|
wxNullBitmap,
|
|
kind,
|
|
shortHelp_string,
|
|
wxEmptyString,
|
|
NULL);
|
|
}
|
|
|
|
|
|
wxAuiToolBarItem* wxAuiToolBar::AddTool(int tool_id,
|
|
const wxString& label,
|
|
const wxBitmap& bitmap,
|
|
const wxBitmap& disabledBitmap,
|
|
wxItemKind kind,
|
|
const wxString& shortHelpString,
|
|
const wxString& longHelpString,
|
|
wxObject* WXUNUSED(client_data))
|
|
{
|
|
wxAuiToolBarItem item;
|
|
item.m_window = NULL;
|
|
item.m_label = label;
|
|
item.m_bitmap = bitmap;
|
|
item.m_disabledBitmap = disabledBitmap;
|
|
item.m_shortHelp = shortHelpString;
|
|
item.m_longHelp = longHelpString;
|
|
item.m_active = true;
|
|
item.m_dropDown = false;
|
|
item.m_spacerPixels = 0;
|
|
item.m_toolId = tool_id;
|
|
item.m_state = 0;
|
|
item.m_proportion = 0;
|
|
item.m_kind = kind;
|
|
item.m_sizerItem = NULL;
|
|
item.m_minSize = wxDefaultSize;
|
|
item.m_userData = 0;
|
|
item.m_sticky = false;
|
|
|
|
if (item.m_toolId == wxID_ANY)
|
|
item.m_toolId = wxNewId();
|
|
|
|
if (!item.m_disabledBitmap.IsOk())
|
|
{
|
|
// no disabled bitmap specified, we need to make one
|
|
if (item.m_bitmap.IsOk())
|
|
{
|
|
item.m_disabledBitmap = item.m_bitmap.ConvertToDisabled();
|
|
}
|
|
}
|
|
m_items.Add(item);
|
|
return &m_items.Last();
|
|
}
|
|
|
|
wxAuiToolBarItem* wxAuiToolBar::AddControl(wxControl* control,
|
|
const wxString& label)
|
|
{
|
|
wxAuiToolBarItem item;
|
|
item.m_window = (wxWindow*)control;
|
|
item.m_label = label;
|
|
item.m_bitmap = wxNullBitmap;
|
|
item.m_disabledBitmap = wxNullBitmap;
|
|
item.m_active = true;
|
|
item.m_dropDown = false;
|
|
item.m_spacerPixels = 0;
|
|
item.m_toolId = control->GetId();
|
|
item.m_state = 0;
|
|
item.m_proportion = 0;
|
|
item.m_kind = wxITEM_CONTROL;
|
|
item.m_sizerItem = NULL;
|
|
item.m_minSize = control->GetEffectiveMinSize();
|
|
item.m_userData = 0;
|
|
item.m_sticky = false;
|
|
|
|
m_items.Add(item);
|
|
return &m_items.Last();
|
|
}
|
|
|
|
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.m_window = NULL;
|
|
item.m_label = label;
|
|
item.m_bitmap = wxNullBitmap;
|
|
item.m_disabledBitmap = wxNullBitmap;
|
|
item.m_active = true;
|
|
item.m_dropDown = false;
|
|
item.m_spacerPixels = 0;
|
|
item.m_toolId = tool_id;
|
|
item.m_state = 0;
|
|
item.m_proportion = 0;
|
|
item.m_kind = wxITEM_LABEL;
|
|
item.m_sizerItem = NULL;
|
|
item.m_minSize = min_size;
|
|
item.m_userData = 0;
|
|
item.m_sticky = false;
|
|
|
|
if (item.m_toolId == wxID_ANY)
|
|
item.m_toolId = wxNewId();
|
|
|
|
m_items.Add(item);
|
|
return &m_items.Last();
|
|
}
|
|
|
|
wxAuiToolBarItem* wxAuiToolBar::AddSeparator()
|
|
{
|
|
wxAuiToolBarItem item;
|
|
item.m_window = NULL;
|
|
item.m_label = wxEmptyString;
|
|
item.m_bitmap = wxNullBitmap;
|
|
item.m_disabledBitmap = wxNullBitmap;
|
|
item.m_active = true;
|
|
item.m_dropDown = false;
|
|
item.m_toolId = -1;
|
|
item.m_state = 0;
|
|
item.m_proportion = 0;
|
|
item.m_kind = wxITEM_SEPARATOR;
|
|
item.m_sizerItem = NULL;
|
|
item.m_minSize = wxDefaultSize;
|
|
item.m_userData = 0;
|
|
item.m_sticky = false;
|
|
|
|
m_items.Add(item);
|
|
return &m_items.Last();
|
|
}
|
|
|
|
wxAuiToolBarItem* wxAuiToolBar::AddSpacer(int pixels)
|
|
{
|
|
wxAuiToolBarItem item;
|
|
item.m_window = NULL;
|
|
item.m_label = wxEmptyString;
|
|
item.m_bitmap = wxNullBitmap;
|
|
item.m_disabledBitmap = wxNullBitmap;
|
|
item.m_active = true;
|
|
item.m_dropDown = false;
|
|
item.m_spacerPixels = pixels;
|
|
item.m_toolId = -1;
|
|
item.m_state = 0;
|
|
item.m_proportion = 0;
|
|
item.m_kind = wxITEM_SPACER;
|
|
item.m_sizerItem = NULL;
|
|
item.m_minSize = wxDefaultSize;
|
|
item.m_userData = 0;
|
|
item.m_sticky = false;
|
|
|
|
m_items.Add(item);
|
|
return &m_items.Last();
|
|
}
|
|
|
|
wxAuiToolBarItem* wxAuiToolBar::AddStretchSpacer(int proportion)
|
|
{
|
|
wxAuiToolBarItem item;
|
|
item.m_window = NULL;
|
|
item.m_label = wxEmptyString;
|
|
item.m_bitmap = wxNullBitmap;
|
|
item.m_disabledBitmap = wxNullBitmap;
|
|
item.m_active = true;
|
|
item.m_dropDown = false;
|
|
item.m_spacerPixels = 0;
|
|
item.m_toolId = -1;
|
|
item.m_state = 0;
|
|
item.m_proportion = proportion;
|
|
item.m_kind = wxITEM_SPACER;
|
|
item.m_sizerItem = NULL;
|
|
item.m_minSize = wxDefaultSize;
|
|
item.m_userData = 0;
|
|
item.m_sticky = false;
|
|
|
|
m_items.Add(item);
|
|
return &m_items.Last();
|
|
}
|
|
|
|
void wxAuiToolBar::Clear()
|
|
{
|
|
m_items.Clear();
|
|
m_sizerElementCount = 0;
|
|
}
|
|
|
|
bool wxAuiToolBar::DeleteTool(int tool_id)
|
|
{
|
|
int idx = GetToolIndex(tool_id);
|
|
if (idx >= 0 && idx < (int)m_items.GetCount())
|
|
{
|
|
m_items.RemoveAt(idx);
|
|
Realize();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool wxAuiToolBar::DeleteByIndex(int idx)
|
|
{
|
|
if (idx >= 0 && idx < (int)m_items.GetCount())
|
|
{
|
|
m_items.RemoveAt(idx);
|
|
Realize();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
wxControl* wxAuiToolBar::FindControl(int id)
|
|
{
|
|
wxWindow* wnd = FindWindow(id);
|
|
return (wxControl*)wnd;
|
|
}
|
|
|
|
wxAuiToolBarItem* wxAuiToolBar::FindTool(int tool_id) const
|
|
{
|
|
size_t i, count;
|
|
for (i = 0, count = m_items.GetCount(); i < count; ++i)
|
|
{
|
|
wxAuiToolBarItem& item = m_items.Item(i);
|
|
if (item.m_toolId == tool_id)
|
|
return &item;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
wxAuiToolBarItem* wxAuiToolBar::FindToolByPosition(wxCoord x, wxCoord y) const
|
|
{
|
|
size_t i, count;
|
|
for (i = 0, count = m_items.GetCount(); i < count; ++i)
|
|
{
|
|
wxAuiToolBarItem& item = m_items.Item(i);
|
|
|
|
if (!item.m_sizerItem)
|
|
continue;
|
|
|
|
wxRect rect = item.m_sizerItem->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;
|
|
}
|
|
|
|
wxAuiToolBarItem* wxAuiToolBar::FindToolByPositionWithPacking(wxCoord x, wxCoord y) const
|
|
{
|
|
size_t i, count;
|
|
for (i = 0, count = m_items.GetCount(); i < count; ++i)
|
|
{
|
|
wxAuiToolBarItem& item = m_items.Item(i);
|
|
|
|
if (!item.m_sizerItem)
|
|
continue;
|
|
|
|
wxRect rect = item.m_sizerItem->GetRect();
|
|
|
|
// apply tool packing
|
|
if (i+1 < count)
|
|
rect.width += m_toolPacking;
|
|
|
|
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;
|
|
}
|
|
|
|
wxAuiToolBarItem* wxAuiToolBar::FindToolByIndex(int idx) const
|
|
{
|
|
if (idx < 0)
|
|
return NULL;
|
|
|
|
if (idx >= (int)m_items.size())
|
|
return NULL;
|
|
|
|
return &(m_items[idx]);
|
|
}
|
|
|
|
void wxAuiToolBar::SetToolBitmapSize(const wxSize& WXUNUSED(size))
|
|
{
|
|
// TODO: wxToolBar compatibility
|
|
}
|
|
|
|
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->m_proportion = proportion;
|
|
}
|
|
|
|
int wxAuiToolBar::GetToolProportion(int tool_id) const
|
|
{
|
|
wxAuiToolBarItem* item = FindTool(tool_id);
|
|
if (!item)
|
|
return 0;
|
|
|
|
return item->m_proportion;
|
|
}
|
|
|
|
void wxAuiToolBar::SetToolSeparation(int separation)
|
|
{
|
|
if (m_art)
|
|
m_art->SetElementSize(wxAUI_TBART_SEPARATOR_SIZE, separation);
|
|
}
|
|
|
|
int wxAuiToolBar::GetToolSeparation() const
|
|
{
|
|
if (m_art)
|
|
return m_art->GetElementSize(wxAUI_TBART_SEPARATOR_SIZE);
|
|
else
|
|
return 5;
|
|
}
|
|
|
|
|
|
void wxAuiToolBar::SetToolDropDown(int tool_id, bool dropdown)
|
|
{
|
|
wxAuiToolBarItem* item = FindTool(tool_id);
|
|
if (!item)
|
|
return;
|
|
|
|
item->SetHasDropDown(dropdown);
|
|
}
|
|
|
|
bool wxAuiToolBar::GetToolDropDown(int tool_id) const
|
|
{
|
|
wxAuiToolBarItem* item = FindTool(tool_id);
|
|
if (!item)
|
|
return false;
|
|
|
|
return item->HasDropDown();
|
|
}
|
|
|
|
void wxAuiToolBar::SetToolSticky(int tool_id, bool sticky)
|
|
{
|
|
// ignore separators
|
|
if (tool_id == -1)
|
|
return;
|
|
|
|
wxAuiToolBarItem* item = FindTool(tool_id);
|
|
if (!item)
|
|
return;
|
|
|
|
if (item->m_sticky == sticky)
|
|
return;
|
|
|
|
item->m_sticky = sticky;
|
|
|
|
Refresh(false);
|
|
Update();
|
|
}
|
|
|
|
bool wxAuiToolBar::GetToolSticky(int tool_id) const
|
|
{
|
|
wxAuiToolBarItem* item = FindTool(tool_id);
|
|
if (!item)
|
|
return 0;
|
|
|
|
return item->m_sticky;
|
|
}
|
|
|
|
|
|
|
|
|
|
void wxAuiToolBar::SetToolBorderPadding(int padding)
|
|
{
|
|
m_toolBorderPadding = padding;
|
|
}
|
|
|
|
int wxAuiToolBar::GetToolBorderPadding() const
|
|
{
|
|
return m_toolBorderPadding;
|
|
}
|
|
|
|
void wxAuiToolBar::SetToolTextOrientation(int orientation)
|
|
{
|
|
m_toolTextOrientation = orientation;
|
|
|
|
if (m_art)
|
|
{
|
|
m_art->SetTextOrientation(orientation);
|
|
}
|
|
}
|
|
|
|
int wxAuiToolBar::GetToolTextOrientation() const
|
|
{
|
|
return m_toolTextOrientation;
|
|
}
|
|
|
|
void wxAuiToolBar::SetToolPacking(int packing)
|
|
{
|
|
m_toolPacking = packing;
|
|
}
|
|
|
|
int wxAuiToolBar::GetToolPacking() const
|
|
{
|
|
return m_toolPacking;
|
|
}
|
|
|
|
|
|
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)
|
|
{
|
|
if (left != -1)
|
|
m_leftPadding = left;
|
|
if (right != -1)
|
|
m_rightPadding = right;
|
|
if (top != -1)
|
|
m_topPadding = top;
|
|
if (bottom != -1)
|
|
m_bottomPadding = bottom;
|
|
}
|
|
|
|
bool wxAuiToolBar::GetGripperVisible() const
|
|
{
|
|
return m_gripperVisible;
|
|
}
|
|
|
|
void wxAuiToolBar::SetGripperVisible(bool visible)
|
|
{
|
|
m_gripperVisible = visible;
|
|
if (visible)
|
|
m_windowStyle |= wxAUI_TB_GRIPPER;
|
|
else
|
|
m_windowStyle &= ~wxAUI_TB_GRIPPER;
|
|
Realize();
|
|
Refresh(false);
|
|
}
|
|
|
|
|
|
bool wxAuiToolBar::GetOverflowVisible() const
|
|
{
|
|
return m_overflowVisible;
|
|
}
|
|
|
|
void wxAuiToolBar::SetOverflowVisible(bool visible)
|
|
{
|
|
m_overflowVisible = visible;
|
|
if (visible)
|
|
m_windowStyle |= wxAUI_TB_OVERFLOW;
|
|
else
|
|
m_windowStyle &= ~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;
|
|
}
|
|
|
|
|
|
void wxAuiToolBar::SetHoverItem(wxAuiToolBarItem* pitem)
|
|
{
|
|
if (pitem && (pitem->m_state & wxAUI_BUTTON_STATE_DISABLED))
|
|
pitem = NULL;
|
|
|
|
wxAuiToolBarItem* former_hover = NULL;
|
|
|
|
size_t i, count;
|
|
for (i = 0, count = m_items.GetCount(); i < count; ++i)
|
|
{
|
|
wxAuiToolBarItem& item = m_items.Item(i);
|
|
if (item.m_state & wxAUI_BUTTON_STATE_HOVER)
|
|
former_hover = &item;
|
|
item.m_state &= ~wxAUI_BUTTON_STATE_HOVER;
|
|
}
|
|
|
|
if (pitem)
|
|
{
|
|
pitem->m_state |= wxAUI_BUTTON_STATE_HOVER;
|
|
}
|
|
|
|
if (former_hover != pitem)
|
|
{
|
|
Refresh(false);
|
|
Update();
|
|
}
|
|
}
|
|
|
|
void wxAuiToolBar::SetPressedItem(wxAuiToolBarItem* pitem)
|
|
{
|
|
wxAuiToolBarItem* former_item = NULL;
|
|
|
|
size_t i, count;
|
|
for (i = 0, count = m_items.GetCount(); i < count; ++i)
|
|
{
|
|
wxAuiToolBarItem& item = m_items.Item(i);
|
|
if (item.m_state & wxAUI_BUTTON_STATE_PRESSED)
|
|
former_item = &item;
|
|
item.m_state &= ~wxAUI_BUTTON_STATE_PRESSED;
|
|
}
|
|
|
|
if (pitem)
|
|
{
|
|
pitem->m_state &= ~wxAUI_BUTTON_STATE_HOVER;
|
|
pitem->m_state |= wxAUI_BUTTON_STATE_PRESSED;
|
|
}
|
|
|
|
if (former_item != pitem)
|
|
{
|
|
Refresh(false);
|
|
Update();
|
|
}
|
|
}
|
|
|
|
void wxAuiToolBar::RefreshOverflowState()
|
|
{
|
|
if (!m_overflowSizerItem)
|
|
{
|
|
m_overflowState = 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().LeftIsDown())
|
|
overflow_state = wxAUI_BUTTON_STATE_PRESSED;
|
|
else
|
|
overflow_state = wxAUI_BUTTON_STATE_HOVER;
|
|
}
|
|
|
|
if (overflow_state != m_overflowState)
|
|
{
|
|
m_overflowState = overflow_state;
|
|
Refresh(false);
|
|
Update();
|
|
}
|
|
|
|
m_overflowState = overflow_state;
|
|
}
|
|
|
|
void wxAuiToolBar::ToggleTool(int tool_id, bool state)
|
|
{
|
|
wxAuiToolBarItem* tool = FindTool(tool_id);
|
|
|
|
if (tool && (tool->m_kind == wxITEM_CHECK || tool->m_kind == wxITEM_RADIO))
|
|
{
|
|
if (tool->m_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].m_kind != wxITEM_RADIO)
|
|
break;
|
|
m_items[i].m_state &= ~wxAUI_BUTTON_STATE_CHECKED;
|
|
}
|
|
for (i = idx - 1; i >= 0; i--)
|
|
{
|
|
if (m_items[i].m_kind != wxITEM_RADIO)
|
|
break;
|
|
m_items[i].m_state &= ~wxAUI_BUTTON_STATE_CHECKED;
|
|
}
|
|
}
|
|
|
|
tool->m_state |= wxAUI_BUTTON_STATE_CHECKED;
|
|
}
|
|
else if (tool->m_kind == wxITEM_CHECK)
|
|
{
|
|
if (state == true)
|
|
tool->m_state |= wxAUI_BUTTON_STATE_CHECKED;
|
|
else
|
|
tool->m_state &= ~wxAUI_BUTTON_STATE_CHECKED;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool wxAuiToolBar::GetToolToggled(int tool_id) const
|
|
{
|
|
wxAuiToolBarItem* tool = FindTool(tool_id);
|
|
|
|
if (tool)
|
|
{
|
|
if ( (tool->m_kind != wxITEM_CHECK) && (tool->m_kind != wxITEM_RADIO) )
|
|
return false;
|
|
|
|
return (tool->m_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->m_state &= ~wxAUI_BUTTON_STATE_DISABLED;
|
|
else
|
|
tool->m_state |= wxAUI_BUTTON_STATE_DISABLED;
|
|
}
|
|
}
|
|
|
|
bool wxAuiToolBar::GetToolEnabled(int tool_id) const
|
|
{
|
|
wxAuiToolBarItem* tool = FindTool(tool_id);
|
|
|
|
if (tool)
|
|
return (tool->m_state & wxAUI_BUTTON_STATE_DISABLED) ? false : true;
|
|
|
|
return false;
|
|
}
|
|
|
|
wxString wxAuiToolBar::GetToolLabel(int tool_id) const
|
|
{
|
|
wxAuiToolBarItem* tool = FindTool(tool_id);
|
|
wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array"));
|
|
if (!tool)
|
|
return wxEmptyString;
|
|
|
|
return tool->m_label;
|
|
}
|
|
|
|
void wxAuiToolBar::SetToolLabel(int tool_id, const wxString& label)
|
|
{
|
|
wxAuiToolBarItem* tool = FindTool(tool_id);
|
|
if (tool)
|
|
{
|
|
tool->m_label = label;
|
|
}
|
|
}
|
|
|
|
wxBitmap wxAuiToolBar::GetToolBitmap(int tool_id) const
|
|
{
|
|
wxAuiToolBarItem* tool = FindTool(tool_id);
|
|
wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array"));
|
|
if (!tool)
|
|
return wxNullBitmap;
|
|
|
|
return tool->m_bitmap;
|
|
}
|
|
|
|
void wxAuiToolBar::SetToolBitmap(int tool_id, const wxBitmap& bitmap)
|
|
{
|
|
wxAuiToolBarItem* tool = FindTool(tool_id);
|
|
if (tool)
|
|
{
|
|
tool->m_bitmap = bitmap;
|
|
}
|
|
}
|
|
|
|
wxString wxAuiToolBar::GetToolShortHelp(int tool_id) const
|
|
{
|
|
wxAuiToolBarItem* tool = FindTool(tool_id);
|
|
wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array"));
|
|
if (!tool)
|
|
return wxEmptyString;
|
|
|
|
return tool->m_shortHelp;
|
|
}
|
|
|
|
void wxAuiToolBar::SetToolShortHelp(int tool_id, const wxString& help_string)
|
|
{
|
|
wxAuiToolBarItem* tool = FindTool(tool_id);
|
|
if (tool)
|
|
{
|
|
tool->m_shortHelp = help_string;
|
|
}
|
|
}
|
|
|
|
wxString wxAuiToolBar::GetToolLongHelp(int tool_id) const
|
|
{
|
|
wxAuiToolBarItem* tool = FindTool(tool_id);
|
|
wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array"));
|
|
if (!tool)
|
|
return wxEmptyString;
|
|
|
|
return tool->m_longHelp;
|
|
}
|
|
|
|
void wxAuiToolBar::SetToolLongHelp(int tool_id, const wxString& help_string)
|
|
{
|
|
wxAuiToolBarItem* tool = FindTool(tool_id);
|
|
if (tool)
|
|
{
|
|
tool->m_longHelp = help_string;
|
|
}
|
|
}
|
|
|
|
void wxAuiToolBar::SetCustomOverflowItems(const wxAuiToolBarItemArray& prepend,
|
|
const wxAuiToolBarItemArray& append)
|
|
{
|
|
m_customOverflowPrepend = prepend;
|
|
m_customOverflowAppend = 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:
|
|
wxFAIL_MSG("invalid dock location value");
|
|
}
|
|
return wxDefaultSize;
|
|
}
|
|
|
|
bool wxAuiToolBar::IsPaneValid(const wxAuiPaneInfo& pane) const
|
|
{
|
|
return IsPaneValid(m_windowStyle, 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<wxAuiToolBar*>(this));
|
|
if (manager)
|
|
{
|
|
return IsPaneValid(style, manager->GetPane(const_cast<wxAuiToolBar*>(this)));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void wxAuiToolBar::SetArtFlags() const
|
|
{
|
|
unsigned int artflags = m_windowStyle & ~wxAUI_ORIENTATION_MASK;
|
|
if (m_orientation == wxVERTICAL)
|
|
{
|
|
artflags |= wxAUI_TB_VERTICAL;
|
|
}
|
|
m_art->SetFlags(artflags);
|
|
}
|
|
|
|
size_t wxAuiToolBar::GetToolCount() const
|
|
{
|
|
return m_items.size();
|
|
}
|
|
|
|
int wxAuiToolBar::GetToolIndex(int tool_id) const
|
|
{
|
|
// this will prevent us from returning the index of the
|
|
// 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.m_toolId == tool_id)
|
|
return i;
|
|
}
|
|
|
|
return wxNOT_FOUND;
|
|
}
|
|
|
|
bool wxAuiToolBar::GetToolFitsByIndex(int tool_idx) const
|
|
{
|
|
if (tool_idx < 0 || tool_idx >= (int)m_items.GetCount())
|
|
return false;
|
|
|
|
if (!m_items[tool_idx].m_sizerItem)
|
|
return false;
|
|
|
|
int cli_w, cli_h;
|
|
GetClientSize(&cli_w, &cli_h);
|
|
|
|
wxRect rect = m_items[tool_idx].m_sizerItem->GetRect();
|
|
|
|
if (m_orientation == wxVERTICAL)
|
|
{
|
|
// take the dropdown size into account
|
|
if (m_overflowVisible && m_overflowSizerItem)
|
|
cli_h -= m_overflowSizerItem->GetSize().y;
|
|
|
|
if (rect.y+rect.height < cli_h)
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
// take the dropdown size into account
|
|
if (m_overflowVisible && m_overflowSizerItem)
|
|
cli_w -= m_overflowSizerItem->GetSize().x;
|
|
|
|
if (rect.x+rect.width < cli_w)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool wxAuiToolBar::GetToolFits(int tool_id) const
|
|
{
|
|
return GetToolFitsByIndex(GetToolIndex(tool_id));
|
|
}
|
|
|
|
wxRect wxAuiToolBar::GetToolRect(int tool_id) const
|
|
{
|
|
wxAuiToolBarItem* tool = FindTool(tool_id);
|
|
if (tool && tool->m_sizerItem)
|
|
{
|
|
return tool->m_sizerItem->GetRect();
|
|
}
|
|
|
|
return wxRect();
|
|
}
|
|
|
|
bool wxAuiToolBar::GetToolBarFits() const
|
|
{
|
|
if (m_items.GetCount() == 0)
|
|
{
|
|
// empty toolbar always 'fits'
|
|
return true;
|
|
}
|
|
|
|
// entire toolbar content fits if the last tool fits
|
|
return GetToolFitsByIndex(m_items.GetCount() - 1);
|
|
}
|
|
|
|
bool wxAuiToolBar::Realize()
|
|
{
|
|
wxClientDC dc(this);
|
|
if (!dc.IsOk())
|
|
return 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 separatorSize = m_art->GetElementSize(wxAUI_TBART_SEPARATOR_SIZE);
|
|
int gripperSize = m_art->GetElementSize(wxAUI_TBART_GRIPPER_SIZE);
|
|
if (gripperSize > 0 && m_gripperVisible)
|
|
{
|
|
if (horizontal)
|
|
m_gripperSizerItem = sizer->Add(gripperSize, 1, 0, wxEXPAND);
|
|
else
|
|
m_gripperSizerItem = sizer->Add(1, gripperSize, 0, wxEXPAND);
|
|
}
|
|
else
|
|
{
|
|
m_gripperSizerItem = NULL;
|
|
}
|
|
|
|
// add "left" padding
|
|
if (m_leftPadding > 0)
|
|
{
|
|
if (horizontal)
|
|
sizer->Add(m_leftPadding, 1);
|
|
else
|
|
sizer->Add(1, m_leftPadding);
|
|
}
|
|
|
|
size_t i, count;
|
|
for (i = 0, count = m_items.GetCount(); i < count; ++i)
|
|
{
|
|
wxAuiToolBarItem& item = m_items.Item(i);
|
|
wxSizerItem* m_sizerItem = NULL;
|
|
|
|
switch (item.m_kind)
|
|
{
|
|
case wxITEM_LABEL:
|
|
{
|
|
wxSize size = m_art->GetLabelSize(dc, this, item);
|
|
m_sizerItem = sizer->Add(size.x + (m_toolBorderPadding*2),
|
|
size.y + (m_toolBorderPadding*2),
|
|
item.m_proportion,
|
|
item.m_alignment);
|
|
if (i+1 < count)
|
|
{
|
|
sizer->AddSpacer(m_toolPacking);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case wxITEM_CHECK:
|
|
case wxITEM_NORMAL:
|
|
case wxITEM_RADIO:
|
|
{
|
|
wxSize size = m_art->GetToolSize(dc, this, item);
|
|
m_sizerItem = sizer->Add(size.x + (m_toolBorderPadding*2),
|
|
size.y + (m_toolBorderPadding*2),
|
|
0,
|
|
item.m_alignment);
|
|
// add tool packing
|
|
if (i+1 < count)
|
|
{
|
|
sizer->AddSpacer(m_toolPacking);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case wxITEM_SEPARATOR:
|
|
{
|
|
if (horizontal)
|
|
m_sizerItem = sizer->Add(separatorSize, 1, 0, wxEXPAND);
|
|
else
|
|
m_sizerItem = sizer->Add(1, separatorSize, 0, wxEXPAND);
|
|
|
|
// add tool packing
|
|
if (i+1 < count)
|
|
{
|
|
sizer->AddSpacer(m_toolPacking);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case wxITEM_SPACER:
|
|
if (item.m_proportion > 0)
|
|
m_sizerItem = sizer->AddStretchSpacer(item.m_proportion);
|
|
else
|
|
m_sizerItem = sizer->Add(item.m_spacerPixels, 1);
|
|
break;
|
|
|
|
case wxITEM_CONTROL:
|
|
{
|
|
//m_sizerItem = sizer->Add(item.m_window, item.m_proportion, wxEXPAND);
|
|
wxSizerItem* ctrl_m_sizerItem;
|
|
|
|
wxBoxSizer* vert_sizer = new wxBoxSizer(wxVERTICAL);
|
|
vert_sizer->AddStretchSpacer(1);
|
|
ctrl_m_sizerItem = vert_sizer->Add(item.m_window, 0, wxEXPAND);
|
|
vert_sizer->AddStretchSpacer(1);
|
|
if ( (m_windowStyle & wxAUI_TB_TEXT) &&
|
|
m_toolTextOrientation == wxAUI_TBTOOL_TEXT_BOTTOM &&
|
|
!item.GetLabel().empty() )
|
|
{
|
|
wxSize s = GetLabelSize(item.GetLabel());
|
|
vert_sizer->Add(1, s.y);
|
|
}
|
|
|
|
|
|
m_sizerItem = sizer->Add(vert_sizer, item.m_proportion, wxEXPAND);
|
|
|
|
wxSize min_size = item.m_minSize;
|
|
|
|
|
|
// proportional items will disappear from the toolbar if
|
|
// their min width is not set to something really small
|
|
if (item.m_proportion != 0)
|
|
{
|
|
min_size.x = 1;
|
|
}
|
|
|
|
if (min_size.IsFullySpecified())
|
|
{
|
|
m_sizerItem->SetMinSize(min_size);
|
|
ctrl_m_sizerItem->SetMinSize(min_size);
|
|
}
|
|
|
|
// add tool packing
|
|
if (i+1 < count)
|
|
{
|
|
sizer->AddSpacer(m_toolPacking);
|
|
}
|
|
}
|
|
}
|
|
|
|
item.m_sizerItem = m_sizerItem;
|
|
}
|
|
|
|
// add "right" padding
|
|
if (m_rightPadding > 0)
|
|
{
|
|
if (horizontal)
|
|
sizer->Add(m_rightPadding, 1);
|
|
else
|
|
sizer->Add(1, m_rightPadding);
|
|
}
|
|
|
|
// add drop down area
|
|
m_overflowSizerItem = NULL;
|
|
|
|
if (m_windowStyle & wxAUI_TB_OVERFLOW)
|
|
{
|
|
int overflow_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
|
|
if (overflow_size > 0 && m_overflowVisible)
|
|
{
|
|
if (horizontal)
|
|
m_overflowSizerItem = sizer->Add(overflow_size, 1, 0, wxEXPAND);
|
|
else
|
|
m_overflowSizerItem = sizer->Add(1, overflow_size, 0, wxEXPAND);
|
|
}
|
|
else
|
|
{
|
|
m_overflowSizerItem = 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_topPadding > 0)
|
|
{
|
|
if (horizontal)
|
|
outside_sizer->Add(1, m_topPadding);
|
|
else
|
|
outside_sizer->Add(m_topPadding, 1);
|
|
}
|
|
|
|
// add the sizer that contains all of the toolbar elements
|
|
outside_sizer->Add(sizer, 1, wxEXPAND);
|
|
|
|
// add "bottom" padding
|
|
if (m_bottomPadding > 0)
|
|
{
|
|
if (horizontal)
|
|
outside_sizer->Add(1, m_bottomPadding);
|
|
else
|
|
outside_sizer->Add(m_bottomPadding, 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)
|
|
{
|
|
wxAuiToolBarItem& item = m_items.Item(i);
|
|
if (item.m_sizerItem && item.m_proportion > 0 && item.m_minSize.IsFullySpecified())
|
|
item.m_sizerItem->SetMinSize(0,0);
|
|
}
|
|
|
|
m_absoluteMinSize = 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.m_sizerItem && item.m_proportion > 0 && item.m_minSize.IsFullySpecified())
|
|
item.m_sizerItem->SetMinSize(item.m_minSize);
|
|
}
|
|
|
|
// set control size
|
|
wxSize size = m_sizer->GetMinSize();
|
|
m_minWidth = size.x;
|
|
m_minHeight = size.y;
|
|
|
|
if ((m_windowStyle & wxAUI_TB_NO_AUTORESIZE) == 0)
|
|
{
|
|
wxSize curSize = GetClientSize();
|
|
wxSize new_size = GetMinSize();
|
|
if (new_size != curSize)
|
|
{
|
|
SetClientSize(new_size);
|
|
}
|
|
else
|
|
{
|
|
m_sizer->SetDimension(0, 0, curSize.x, curSize.y);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wxSize curSize = GetClientSize();
|
|
m_sizer->SetDimension(0, 0, curSize.x, curSize.y);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
int wxAuiToolBar::GetOverflowState() const
|
|
{
|
|
return m_overflowState;
|
|
}
|
|
|
|
wxRect wxAuiToolBar::GetOverflowRect() const
|
|
{
|
|
wxRect cli_rect(wxPoint(0,0), GetClientSize());
|
|
wxRect overflow_rect = m_overflowSizerItem->GetRect();
|
|
int overflow_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
|
|
|
|
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
|
|
{
|
|
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 textWidth = 0, textHeight = 0;
|
|
|
|
dc.SetFont(m_font);
|
|
|
|
// get the text height
|
|
dc.GetTextExtent(wxT("ABCDHgj"), &tx, &textHeight);
|
|
|
|
// get the text width
|
|
dc.GetTextExtent(label, &textWidth, &ty);
|
|
|
|
return wxSize(textWidth, textHeight);
|
|
}
|
|
|
|
|
|
void wxAuiToolBar::DoIdleUpdate()
|
|
{
|
|
wxEvtHandler* handler = GetEventHandler();
|
|
|
|
bool need_refresh = false;
|
|
|
|
size_t i, count;
|
|
for (i = 0, count = m_items.GetCount(); i < count; ++i)
|
|
{
|
|
wxAuiToolBarItem& item = m_items.Item(i);
|
|
|
|
if (item.m_toolId == -1)
|
|
continue;
|
|
|
|
wxUpdateUIEvent evt(item.m_toolId);
|
|
evt.SetEventObject(this);
|
|
|
|
if (handler->ProcessEvent(evt))
|
|
{
|
|
if (evt.GetSetEnabled())
|
|
{
|
|
bool is_enabled;
|
|
if (item.m_window)
|
|
is_enabled = item.m_window->IsThisEnabled();
|
|
else
|
|
is_enabled = (item.m_state & wxAUI_BUTTON_STATE_DISABLED) ? false : true;
|
|
|
|
bool new_enabled = evt.GetEnabled();
|
|
if (new_enabled != is_enabled)
|
|
{
|
|
if (item.m_window)
|
|
{
|
|
item.m_window->Enable(new_enabled);
|
|
}
|
|
else
|
|
{
|
|
if (new_enabled)
|
|
item.m_state &= ~wxAUI_BUTTON_STATE_DISABLED;
|
|
else
|
|
item.m_state |= wxAUI_BUTTON_STATE_DISABLED;
|
|
}
|
|
need_refresh = true;
|
|
}
|
|
}
|
|
|
|
if (evt.GetSetChecked())
|
|
{
|
|
// make sure we aren't checking an item that can't be
|
|
if (item.m_kind != wxITEM_CHECK && item.m_kind != wxITEM_RADIO)
|
|
continue;
|
|
|
|
bool is_checked = (item.m_state & wxAUI_BUTTON_STATE_CHECKED) ? true : false;
|
|
bool new_checked = evt.GetChecked();
|
|
|
|
if (new_checked != is_checked)
|
|
{
|
|
if (new_checked)
|
|
item.m_state |= wxAUI_BUTTON_STATE_CHECKED;
|
|
else
|
|
item.m_state &= ~wxAUI_BUTTON_STATE_CHECKED;
|
|
|
|
need_refresh = true;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
if (need_refresh)
|
|
{
|
|
Refresh(false);
|
|
}
|
|
}
|
|
|
|
|
|
void wxAuiToolBar::OnSize(wxSizeEvent& WXUNUSED(evt))
|
|
{
|
|
int x, y;
|
|
GetClientSize(&x, &y);
|
|
|
|
if (((x >= y) && m_absoluteMinSize.x > x) ||
|
|
((y > x) && m_absoluteMinSize.y > y))
|
|
{
|
|
// hide all flexible items
|
|
size_t i, count;
|
|
for (i = 0, count = m_items.GetCount(); i < count; ++i)
|
|
{
|
|
wxAuiToolBarItem& item = m_items.Item(i);
|
|
if (item.m_sizerItem && item.m_proportion > 0 && item.m_sizerItem->IsShown())
|
|
{
|
|
item.m_sizerItem->Show(false);
|
|
item.m_sizerItem->SetProportion(0);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// show all flexible items
|
|
size_t i, count;
|
|
for (i = 0, count = m_items.GetCount(); i < count; ++i)
|
|
{
|
|
wxAuiToolBarItem& item = m_items.Item(i);
|
|
if (item.m_sizerItem && item.m_proportion > 0 && !item.m_sizerItem->IsShown())
|
|
{
|
|
item.m_sizerItem->Show(true);
|
|
item.m_sizerItem->SetProportion(item.m_proportion);
|
|
}
|
|
}
|
|
}
|
|
|
|
m_sizer->SetDimension(0, 0, x, y);
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
|
|
void wxAuiToolBar::DoSetSize(int x,
|
|
int y,
|
|
int width,
|
|
int height,
|
|
int sizeFlags)
|
|
{
|
|
wxSize parent_size = GetParent()->GetClientSize();
|
|
if (x + width > parent_size.x)
|
|
width = wxMax(0, parent_size.x - x);
|
|
if (y + height > parent_size.y)
|
|
height = wxMax(0, parent_size.y - y);
|
|
|
|
wxWindow::DoSetSize(x, y, width, height, sizeFlags);
|
|
}
|
|
|
|
|
|
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_windowStyle, 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_windowStyle) == 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();
|
|
}
|
|
}
|
|
}
|
|
evt.Skip();
|
|
}
|
|
|
|
void wxAuiToolBar::UpdateWindowUI(long flags)
|
|
{
|
|
if ( flags & wxUPDATE_UI_FROMIDLE )
|
|
{
|
|
DoIdleUpdate();
|
|
}
|
|
|
|
wxControl::UpdateWindowUI(flags);
|
|
}
|
|
|
|
void wxAuiToolBar::OnPaint(wxPaintEvent& WXUNUSED(evt))
|
|
{
|
|
wxAutoBufferedPaintDC dc(this);
|
|
wxRect cli_rect(wxPoint(0,0), GetClientSize());
|
|
|
|
|
|
bool horizontal = m_orientation == wxHORIZONTAL;
|
|
|
|
if (m_windowStyle & wxAUI_TB_PLAIN_BACKGROUND)
|
|
m_art->DrawPlainBackground(dc, this, cli_rect);
|
|
else
|
|
m_art->DrawBackground(dc, this, cli_rect);
|
|
|
|
int gripperSize = m_art->GetElementSize(wxAUI_TBART_GRIPPER_SIZE);
|
|
int dropdown_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
|
|
|
|
// paint the gripper
|
|
if (gripperSize > 0 && m_gripperSizerItem)
|
|
{
|
|
wxRect gripper_rect = m_gripperSizerItem->GetRect();
|
|
if (horizontal)
|
|
gripper_rect.width = gripperSize;
|
|
else
|
|
gripper_rect.height = gripperSize;
|
|
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
|
|
last_extent = cli_rect.height;
|
|
if (m_overflowVisible)
|
|
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.m_sizerItem)
|
|
continue;
|
|
|
|
wxRect item_rect = item.m_sizerItem->GetRect();
|
|
|
|
|
|
if ((horizontal && item_rect.x + item_rect.width >= last_extent) ||
|
|
(!horizontal && item_rect.y + item_rect.height >= last_extent))
|
|
{
|
|
break;
|
|
}
|
|
|
|
switch ( item.m_kind )
|
|
{
|
|
case wxITEM_NORMAL:
|
|
// draw a regular or dropdown button
|
|
if (!item.m_dropDown)
|
|
m_art->DrawButton(dc, this, item, item_rect);
|
|
else
|
|
m_art->DrawDropDownButton(dc, this, item, item_rect);
|
|
break;
|
|
|
|
case wxITEM_CHECK:
|
|
case wxITEM_RADIO:
|
|
// draw a toggle button
|
|
m_art->DrawButton(dc, this, item, item_rect);
|
|
break;
|
|
|
|
case wxITEM_SEPARATOR:
|
|
// draw a separator
|
|
m_art->DrawSeparator(dc, this, item_rect);
|
|
break;
|
|
|
|
case wxITEM_LABEL:
|
|
// draw a text label only
|
|
m_art->DrawLabel(dc, this, item, item_rect);
|
|
break;
|
|
|
|
case wxITEM_CONTROL:
|
|
// draw the control's label
|
|
m_art->DrawControlLabel(dc, this, item, item_rect);
|
|
break;
|
|
}
|
|
|
|
// 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_overflowSizerItem)
|
|
{
|
|
wxRect dropDownRect = GetOverflowRect();
|
|
m_art->DrawOverflowButton(dc, this, dropDownRect, m_overflowState);
|
|
}
|
|
}
|
|
|
|
void wxAuiToolBar::OnEraseBackground(wxEraseEvent& WXUNUSED(evt))
|
|
{
|
|
// empty
|
|
}
|
|
|
|
void wxAuiToolBar::OnLeftDown(wxMouseEvent& evt)
|
|
{
|
|
wxRect cli_rect(wxPoint(0,0), GetClientSize());
|
|
|
|
if (m_gripperSizerItem)
|
|
{
|
|
wxRect gripper_rect = m_gripperSizerItem->GetRect();
|
|
if (gripper_rect.Contains(evt.GetX(), evt.GetY()))
|
|
{
|
|
// find aui manager
|
|
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_overflowSizerItem)
|
|
{
|
|
wxRect overflow_rect = GetOverflowRect();
|
|
|
|
if (m_art &&
|
|
m_overflowVisible &&
|
|
overflow_rect.Contains(evt.m_x, evt.m_y))
|
|
{
|
|
wxAuiToolBarEvent e(wxEVT_AUITOOLBAR_OVERFLOW_CLICK, -1);
|
|
e.SetEventObject(this);
|
|
e.SetToolId(-1);
|
|
e.SetClickPoint(wxPoint(evt.GetX(), evt.GetY()));
|
|
bool processed = GetEventHandler()->ProcessEvent(e);
|
|
|
|
if (processed)
|
|
{
|
|
DoIdleUpdate();
|
|
}
|
|
else
|
|
{
|
|
size_t i, count;
|
|
wxAuiToolBarItemArray overflow_items;
|
|
|
|
|
|
// add custom overflow prepend items, if any
|
|
count = m_customOverflowPrepend.GetCount();
|
|
for (i = 0; i < count; ++i)
|
|
overflow_items.Add(m_customOverflowPrepend[i]);
|
|
|
|
// only show items that don't fit in the dropdown
|
|
count = m_items.GetCount();
|
|
for (i = 0; i < count; ++i)
|
|
{
|
|
if (!GetToolFitsByIndex(i))
|
|
overflow_items.Add(m_items[i]);
|
|
}
|
|
|
|
// add custom overflow append items, if any
|
|
count = m_customOverflowAppend.GetCount();
|
|
for (i = 0; i < count; ++i)
|
|
overflow_items.Add(m_customOverflowAppend[i]);
|
|
|
|
int res = m_art->ShowDropDown(this, overflow_items);
|
|
m_overflowState = 0;
|
|
Refresh(false);
|
|
if (res != -1)
|
|
{
|
|
wxCommandEvent event(wxEVT_MENU, res);
|
|
event.SetEventObject(this);
|
|
GetParent()->GetEventHandler()->ProcessEvent(event);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
m_dragging = false;
|
|
m_actionPos = wxPoint(evt.GetX(), evt.GetY());
|
|
m_actionItem = FindToolByPosition(evt.GetX(), evt.GetY());
|
|
|
|
if (m_actionItem)
|
|
{
|
|
if (m_actionItem->m_state & wxAUI_BUTTON_STATE_DISABLED)
|
|
{
|
|
m_actionPos = wxPoint(-1,-1);
|
|
m_actionItem = NULL;
|
|
return;
|
|
}
|
|
|
|
UnsetToolTip();
|
|
|
|
// fire the tool dropdown event
|
|
wxAuiToolBarEvent e(wxEVT_AUITOOLBAR_TOOL_DROPDOWN, m_actionItem->m_toolId);
|
|
e.SetEventObject(this);
|
|
e.SetToolId(m_actionItem->m_toolId);
|
|
|
|
int mouse_x = evt.GetX();
|
|
wxRect rect = m_actionItem->m_sizerItem->GetRect();
|
|
const bool dropDownHit = m_actionItem->m_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);
|
|
|
|
// we only set the 'pressed button' state if we hit the actual button
|
|
// and not just the drop-down
|
|
SetPressedItem(dropDownHit ? 0 : m_actionItem);
|
|
|
|
if(dropDownHit)
|
|
{
|
|
m_actionPos = wxPoint(-1,-1);
|
|
m_actionItem = NULL;
|
|
}
|
|
|
|
if(!GetEventHandler()->ProcessEvent(e) || e.GetSkipped())
|
|
CaptureMouse();
|
|
|
|
// Ensure hovered item is really ok, as mouse may have moved during
|
|
// event processing
|
|
wxPoint cursor_pos_after_evt = ScreenToClient(wxGetMousePosition());
|
|
SetHoverItem(FindToolByPosition(cursor_pos_after_evt.x, cursor_pos_after_evt.y));
|
|
|
|
DoIdleUpdate();
|
|
}
|
|
}
|
|
|
|
void wxAuiToolBar::OnLeftUp(wxMouseEvent& evt)
|
|
{
|
|
if (!HasCapture())
|
|
return;
|
|
|
|
SetPressedItem(NULL);
|
|
|
|
wxAuiToolBarItem* hitItem;
|
|
hitItem = FindToolByPosition(evt.GetX(), evt.GetY());
|
|
SetHoverItem(hitItem);
|
|
|
|
if (m_dragging)
|
|
{
|
|
// 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
|
|
{
|
|
if (m_actionItem && hitItem == m_actionItem)
|
|
{
|
|
UnsetToolTip();
|
|
|
|
wxCommandEvent e(wxEVT_MENU, m_actionItem->m_toolId);
|
|
e.SetEventObject(this);
|
|
|
|
if (hitItem->m_kind == wxITEM_CHECK || hitItem->m_kind == wxITEM_RADIO)
|
|
{
|
|
const bool toggle = !(m_actionItem->m_state & wxAUI_BUTTON_STATE_CHECKED);
|
|
|
|
ToggleTool(m_actionItem->m_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);
|
|
|
|
// Ensure hovered item is really ok, as mouse may have moved during
|
|
// event processing
|
|
wxPoint cursor_pos_after_evt = ScreenToClient(wxGetMousePosition());
|
|
SetHoverItem(FindToolByPosition(cursor_pos_after_evt.x, cursor_pos_after_evt.y));
|
|
|
|
DoIdleUpdate();
|
|
}
|
|
else
|
|
ReleaseMouse();
|
|
}
|
|
}
|
|
|
|
void wxAuiToolBar::OnRightDown(wxMouseEvent& evt)
|
|
{
|
|
wxRect cli_rect(wxPoint(0,0), GetClientSize());
|
|
|
|
if (m_gripperSizerItem)
|
|
{
|
|
wxRect gripper_rect = m_gripperSizerItem->GetRect();
|
|
if (gripper_rect.Contains(evt.GetX(), evt.GetY()))
|
|
return;
|
|
}
|
|
|
|
if (m_overflowSizerItem && m_art)
|
|
{
|
|
int dropdown_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
|
|
if (dropdown_size > 0 &&
|
|
evt.m_x > cli_rect.width - dropdown_size &&
|
|
evt.m_y >= 0 &&
|
|
evt.m_y < cli_rect.height)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
m_actionPos = wxPoint(evt.GetX(), evt.GetY());
|
|
m_actionItem = FindToolByPosition(evt.GetX(), evt.GetY());
|
|
|
|
if (m_actionItem && m_actionItem->m_state & wxAUI_BUTTON_STATE_DISABLED)
|
|
{
|
|
m_actionPos = wxPoint(-1,-1);
|
|
m_actionItem = NULL;
|
|
return;
|
|
}
|
|
|
|
UnsetToolTip();
|
|
}
|
|
|
|
void wxAuiToolBar::OnRightUp(wxMouseEvent& evt)
|
|
{
|
|
wxAuiToolBarItem* hitItem;
|
|
hitItem = FindToolByPosition(evt.GetX(), evt.GetY());
|
|
|
|
if (m_actionItem && hitItem == m_actionItem)
|
|
{
|
|
wxAuiToolBarEvent e(wxEVT_AUITOOLBAR_RIGHT_CLICK, m_actionItem->m_toolId);
|
|
e.SetEventObject(this);
|
|
e.SetToolId(m_actionItem->m_toolId);
|
|
e.SetClickPoint(m_actionPos);
|
|
GetEventHandler()->ProcessEvent(e);
|
|
DoIdleUpdate();
|
|
}
|
|
else
|
|
{
|
|
// right-clicked on the invalid area of the toolbar
|
|
wxAuiToolBarEvent e(wxEVT_AUITOOLBAR_RIGHT_CLICK, -1);
|
|
e.SetEventObject(this);
|
|
e.SetToolId(-1);
|
|
e.SetClickPoint(m_actionPos);
|
|
GetEventHandler()->ProcessEvent(e);
|
|
DoIdleUpdate();
|
|
}
|
|
|
|
// reset member variables
|
|
m_actionPos = wxPoint(-1,-1);
|
|
m_actionItem = NULL;
|
|
}
|
|
|
|
void wxAuiToolBar::OnMiddleDown(wxMouseEvent& evt)
|
|
{
|
|
wxRect cli_rect(wxPoint(0,0), GetClientSize());
|
|
|
|
if (m_gripperSizerItem)
|
|
{
|
|
wxRect gripper_rect = m_gripperSizerItem->GetRect();
|
|
if (gripper_rect.Contains(evt.GetX(), evt.GetY()))
|
|
return;
|
|
}
|
|
|
|
if (m_overflowSizerItem && m_art)
|
|
{
|
|
int dropdown_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
|
|
if (dropdown_size > 0 &&
|
|
evt.m_x > cli_rect.width - dropdown_size &&
|
|
evt.m_y >= 0 &&
|
|
evt.m_y < cli_rect.height)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
m_actionPos = wxPoint(evt.GetX(), evt.GetY());
|
|
m_actionItem = FindToolByPosition(evt.GetX(), evt.GetY());
|
|
|
|
if (m_actionItem)
|
|
{
|
|
if (m_actionItem->m_state & wxAUI_BUTTON_STATE_DISABLED)
|
|
{
|
|
m_actionPos = wxPoint(-1,-1);
|
|
m_actionItem = NULL;
|
|
return;
|
|
}
|
|
}
|
|
|
|
UnsetToolTip();
|
|
}
|
|
|
|
void wxAuiToolBar::OnMiddleUp(wxMouseEvent& evt)
|
|
{
|
|
wxAuiToolBarItem* hitItem;
|
|
hitItem = FindToolByPosition(evt.GetX(), evt.GetY());
|
|
|
|
if (m_actionItem && hitItem == m_actionItem)
|
|
{
|
|
if (hitItem->m_kind == wxITEM_NORMAL)
|
|
{
|
|
wxAuiToolBarEvent e(wxEVT_AUITOOLBAR_MIDDLE_CLICK, m_actionItem->m_toolId);
|
|
e.SetEventObject(this);
|
|
e.SetToolId(m_actionItem->m_toolId);
|
|
e.SetClickPoint(m_actionPos);
|
|
GetEventHandler()->ProcessEvent(e);
|
|
DoIdleUpdate();
|
|
}
|
|
}
|
|
|
|
// reset member variables
|
|
m_actionPos = wxPoint(-1,-1);
|
|
m_actionItem = NULL;
|
|
}
|
|
|
|
void wxAuiToolBar::OnMotion(wxMouseEvent& evt)
|
|
{
|
|
const bool button_pressed = HasCapture();
|
|
|
|
// start a drag event
|
|
if (!m_dragging && button_pressed &&
|
|
abs(evt.GetX() - m_actionPos.x) + abs(evt.GetY() - m_actionPos.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_AUITOOLBAR_BEGIN_DRAG, GetId());
|
|
e.SetEventObject(this);
|
|
e.SetToolId(m_actionItem->m_toolId);
|
|
m_dragging = GetEventHandler()->ProcessEvent(e) && !e.GetSkipped();
|
|
|
|
DoIdleUpdate();
|
|
}
|
|
|
|
if(m_dragging)
|
|
return;
|
|
|
|
wxAuiToolBarItem* hitItem = FindToolByPosition(evt.GetX(), evt.GetY());
|
|
if(button_pressed)
|
|
{
|
|
// 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 (hitItem == m_actionItem)
|
|
SetPressedItem(m_actionItem);
|
|
else
|
|
{
|
|
SetPressedItem(NULL);
|
|
SetHoverItem(m_actionItem);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetHoverItem(hitItem);
|
|
|
|
// tooltips handling
|
|
wxAuiToolBarItem* packingHitItem;
|
|
packingHitItem = FindToolByPositionWithPacking(evt.GetX(), evt.GetY());
|
|
if (packingHitItem)
|
|
{
|
|
if (packingHitItem != m_tipItem)
|
|
{
|
|
m_tipItem = packingHitItem;
|
|
|
|
if ( !packingHitItem->m_shortHelp.empty() )
|
|
SetToolTip(packingHitItem->m_shortHelp);
|
|
else
|
|
UnsetToolTip();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UnsetToolTip();
|
|
m_tipItem = NULL;
|
|
}
|
|
|
|
// figure out the dropdown button state (are we hovering or pressing it?)
|
|
RefreshOverflowState();
|
|
}
|
|
}
|
|
|
|
void wxAuiToolBar::DoResetMouseState()
|
|
{
|
|
RefreshOverflowState();
|
|
SetHoverItem(NULL);
|
|
SetPressedItem(NULL);
|
|
|
|
m_tipItem = 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_actionPos = wxPoint(-1,-1);
|
|
m_actionItem = 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_gripperSizerItem)
|
|
{
|
|
wxRect gripper_rect = m_gripperSizerItem->GetRect();
|
|
if (gripper_rect.Contains(evt.GetX(), evt.GetY()))
|
|
{
|
|
cursor = wxCursor(wxCURSOR_SIZING);
|
|
}
|
|
}
|
|
|
|
evt.SetCursor(cursor);
|
|
}
|
|
|
|
|
|
#endif // wxUSE_AUI
|
|
|