]> git.saurik.com Git - wxWidgets.git/blame - src/aui/auibar.cpp
Perform wxAuiToolBar idle updates from UpdateWindowUI(), not OnIdle().
[wxWidgets.git] / src / aui / auibar.cpp
CommitLineData
1154f91b
BW
1///////////////////////////////////////////////////////////////////////////////
2
80fdcdb9 3// Name: src/aui/auibar.cpp
1154f91b
BW
4// Purpose: wxaui: wx advanced user interface - docking window manager
5// Author: Benjamin I. Williams
6// Modified by:
7// Created: 2005-05-17
054f177b 8// RCS-ID: $Id$
1154f91b
BW
9// Copyright: (C) Copyright 2005-2006, Kirix Corporation, All Rights Reserved
10// Licence: wxWindows Library Licence, Version 3.1
11///////////////////////////////////////////////////////////////////////////////
12
13// ============================================================================
14// declarations
15// ============================================================================
16
17// ----------------------------------------------------------------------------
18// headers
19// ----------------------------------------------------------------------------
20
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#if wxUSE_AUI
28
29#include "wx/statline.h"
30#include "wx/dcbuffer.h"
31#include "wx/sizer.h"
32#include "wx/image.h"
33#include "wx/settings.h"
34#include "wx/menu.h"
35
36#include "wx/aui/auibar.h"
37#include "wx/aui/framemanager.h"
38
eecf97a5
VZ
39#ifdef __WXMAC__
40#include "wx/osx/private.h"
1154f91b
BW
41#endif
42
43#include "wx/arrimpl.cpp"
44WX_DEFINE_OBJARRAY(wxAuiToolBarItemArray)
45
46
9b11752c
VZ
47wxDEFINE_EVENT( wxEVT_COMMAND_AUITOOLBAR_TOOL_DROPDOWN, wxAuiToolBarEvent );
48wxDEFINE_EVENT( wxEVT_COMMAND_AUITOOLBAR_OVERFLOW_CLICK, wxAuiToolBarEvent );
49wxDEFINE_EVENT( wxEVT_COMMAND_AUITOOLBAR_RIGHT_CLICK, wxAuiToolBarEvent );
50wxDEFINE_EVENT( wxEVT_COMMAND_AUITOOLBAR_MIDDLE_CLICK, wxAuiToolBarEvent );
51wxDEFINE_EVENT( wxEVT_COMMAND_AUITOOLBAR_BEGIN_DRAG, wxAuiToolBarEvent );
1154f91b
BW
52
53
54IMPLEMENT_CLASS(wxAuiToolBar, wxControl)
55IMPLEMENT_DYNAMIC_CLASS(wxAuiToolBarEvent, wxEvent)
56
57
58// missing wxITEM_* items
59enum
60{
61 wxITEM_CONTROL = wxITEM_MAX,
62 wxITEM_LABEL,
63 wxITEM_SPACER
64};
65
66const int BUTTON_DROPDOWN_WIDTH = 10;
67
68
69wxBitmap wxAuiBitmapFromBits(const unsigned char bits[], int w, int h,
70 const wxColour& color);
71
1154f91b
BW
72static wxColor GetBaseColor()
73{
74
eecf97a5 75#if defined( __WXMAC__ ) && wxOSX_USE_COCOA_OR_CARBON
9a29fe70 76 wxColor baseColour = wxColour( wxMacCreateCGColorFromHITheme(kThemeBrushToolbarBackground));
1154f91b 77#else
9a29fe70 78 wxColor baseColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
1154f91b
BW
79#endif
80
9a29fe70 81 // the baseColour is too pale to use as our base colour,
1154f91b 82 // so darken it a bit --
9a29fe70
VZ
83 if ((255-baseColour.Red()) +
84 (255-baseColour.Green()) +
85 (255-baseColour.Blue()) < 60)
1154f91b 86 {
9a29fe70 87 baseColour = baseColour.ChangeLightness(92);
1154f91b
BW
88 }
89
9a29fe70 90 return baseColour;
1154f91b
BW
91}
92
93
94
95class ToolbarCommandCapture : public wxEvtHandler
96{
97public:
98
9a29fe70
VZ
99 ToolbarCommandCapture() { m_lastId = 0; }
100 int GetCommandId() const { return m_lastId; }
1154f91b
BW
101
102 bool ProcessEvent(wxEvent& evt)
103 {
104 if (evt.GetEventType() == wxEVT_COMMAND_MENU_SELECTED)
105 {
9a29fe70 106 m_lastId = evt.GetId();
1154f91b
BW
107 return true;
108 }
109
110 if (GetNextHandler())
111 return GetNextHandler()->ProcessEvent(evt);
112
113 return false;
114 }
115
116private:
9a29fe70 117 int m_lastId;
1154f91b
BW
118};
119
120
121
eecf97a5 122static const unsigned char
a310c91c 123 DISABLED_TEXT_GREY_HUE = wxColour::AlphaBlend(0, 255, 0.4);
eecf97a5
VZ
124const wxColour DISABLED_TEXT_COLOR(DISABLED_TEXT_GREY_HUE,
125 DISABLED_TEXT_GREY_HUE,
126 DISABLED_TEXT_GREY_HUE);
1154f91b
BW
127
128wxAuiDefaultToolBarArt::wxAuiDefaultToolBarArt()
129{
9a29fe70 130 m_baseColour = GetBaseColor();
1154f91b
BW
131
132 m_flags = 0;
9a29fe70
VZ
133 m_textOrientation = wxAUI_TBTOOL_TEXT_BOTTOM;
134 m_highlightColour = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
eecf97a5 135
9a29fe70
VZ
136 m_separatorSize = 7;
137 m_gripperSize = 7;
138 m_overflowSize = 16;
1154f91b 139
9a29fe70
VZ
140 wxColor darker1Colour = m_baseColour.ChangeLightness(85);
141 wxColor darker2Colour = m_baseColour.ChangeLightness(75);
142 wxColor darker3Colour = m_baseColour.ChangeLightness(60);
143 wxColor darker4Colour = m_baseColour.ChangeLightness(50);
144 wxColor darker5Colour = m_baseColour.ChangeLightness(40);
1154f91b 145
9a29fe70
VZ
146 m_gripperPen1 = wxPen(darker5Colour);
147 m_gripperPen2 = wxPen(darker3Colour);
148 m_gripperPen3 = *wxWHITE_PEN;
eecf97a5 149
9a29fe70
VZ
150 static const unsigned char buttonDropdownBits[] = { 0xe0, 0xf1, 0xfb };
151 static const unsigned char overflowBits[] = { 0x80, 0xff, 0x80, 0xc1, 0xe3, 0xf7 };
eecf97a5 152
9a29fe70 153 m_buttonDropDownBmp = wxAuiBitmapFromBits(buttonDropdownBits, 5, 3,
1154f91b 154 *wxBLACK);
9a29fe70
VZ
155 m_disabledButtonDropDownBmp = wxAuiBitmapFromBits(
156 buttonDropdownBits, 5, 3,
1154f91b 157 wxColor(128,128,128));
9a29fe70
VZ
158 m_overflowBmp = wxAuiBitmapFromBits(overflowBits, 7, 6, *wxBLACK);
159 m_disabledOverflowBmp = wxAuiBitmapFromBits(overflowBits, 7, 6, wxColor(128,128,128));
1154f91b
BW
160
161 m_font = *wxNORMAL_FONT;
162}
163
164wxAuiDefaultToolBarArt::~wxAuiDefaultToolBarArt()
165{
166 m_font = *wxNORMAL_FONT;
167}
168
169
170wxAuiToolBarArt* wxAuiDefaultToolBarArt::Clone()
171{
172 return static_cast<wxAuiToolBarArt*>(new wxAuiDefaultToolBarArt);
173}
174
175void wxAuiDefaultToolBarArt::SetFlags(unsigned int flags)
176{
177 m_flags = flags;
178}
179
180void wxAuiDefaultToolBarArt::SetFont(const wxFont& font)
181{
182 m_font = font;
183}
184
185void wxAuiDefaultToolBarArt::SetTextOrientation(int orientation)
186{
9a29fe70 187 m_textOrientation = orientation;
1154f91b
BW
188}
189
8bc10f32
BW
190unsigned int wxAuiDefaultToolBarArt::GetFlags()
191{
192 return m_flags;
193}
194
195wxFont wxAuiDefaultToolBarArt::GetFont()
196{
197 return m_font;
198}
199
200int wxAuiDefaultToolBarArt::GetTextOrientation()
201{
9a29fe70 202 return m_textOrientation;
8bc10f32
BW
203}
204
1154f91b
BW
205void wxAuiDefaultToolBarArt::DrawBackground(
206 wxDC& dc,
207 wxWindow* WXUNUSED(wnd),
208 const wxRect& _rect)
209{
210 wxRect rect = _rect;
211 rect.height++;
9a29fe70
VZ
212 wxColour startColour = m_baseColour.ChangeLightness(150);
213 wxColour endColour = m_baseColour.ChangeLightness(90);
214 dc.GradientFillLinear(rect, startColour, endColour, wxSOUTH);
1154f91b
BW
215}
216
217void wxAuiDefaultToolBarArt::DrawLabel(
218 wxDC& dc,
219 wxWindow* WXUNUSED(wnd),
220 const wxAuiToolBarItem& item,
221 const wxRect& rect)
222{
223 dc.SetFont(m_font);
224 dc.SetTextForeground(*wxBLACK);
225
226 // we only care about the text height here since the text
227 // will get cropped based on the width of the item
9a29fe70
VZ
228 int textWidth = 0, textHeight = 0;
229 dc.GetTextExtent(wxT("ABCDHgj"), &textWidth, &textHeight);
1154f91b
BW
230
231 // set the clipping region
9a29fe70
VZ
232 wxRect clipRect = rect;
233 clipRect.width -= 1;
234 dc.SetClippingRegion(clipRect);
235
236 int textX, textY;
237 textX = rect.x + 1;
238 textY = rect.y + (rect.height-textHeight)/2;
239 dc.DrawText(item.GetLabel(), textX, textY);
1154f91b
BW
240 dc.DestroyClippingRegion();
241}
242
243
244void wxAuiDefaultToolBarArt::DrawButton(
245 wxDC& dc,
246 wxWindow* WXUNUSED(wnd),
247 const wxAuiToolBarItem& item,
248 const wxRect& rect)
249{
9a29fe70 250 int textWidth = 0, textHeight = 0;
eecf97a5 251
1154f91b
BW
252 if (m_flags & wxAUI_TB_TEXT)
253 {
254 dc.SetFont(m_font);
eecf97a5 255
1154f91b
BW
256 int tx, ty;
257
9a29fe70
VZ
258 dc.GetTextExtent(wxT("ABCDHgj"), &tx, &textHeight);
259 textWidth = 0;
260 dc.GetTextExtent(item.GetLabel(), &textWidth, &ty);
1154f91b
BW
261 }
262
9a29fe70
VZ
263 int bmpX = 0, bmpY = 0;
264 int textX = 0, textY = 0;
eecf97a5 265
9a29fe70 266 if (m_textOrientation == wxAUI_TBTOOL_TEXT_BOTTOM)
1154f91b 267 {
9a29fe70 268 bmpX = rect.x +
1154f91b 269 (rect.width/2) -
e42f2c16 270 (item.GetBitmap().GetWidth()/2);
eecf97a5 271
9a29fe70
VZ
272 bmpY = rect.y +
273 ((rect.height-textHeight)/2) -
e42f2c16 274 (item.GetBitmap().GetHeight()/2);
eecf97a5 275
9a29fe70
VZ
276 textX = rect.x + (rect.width/2) - (textWidth/2) + 1;
277 textY = rect.y + rect.height - textHeight - 1;
1154f91b 278 }
9a29fe70 279 else if (m_textOrientation == wxAUI_TBTOOL_TEXT_RIGHT)
1154f91b 280 {
9a29fe70 281 bmpX = rect.x + 3;
eecf97a5 282
9a29fe70 283 bmpY = rect.y +
1154f91b 284 (rect.height/2) -
e42f2c16 285 (item.GetBitmap().GetHeight()/2);
eecf97a5 286
9a29fe70
VZ
287 textX = bmpX + 3 + item.GetBitmap().GetWidth();
288 textY = rect.y +
1154f91b 289 (rect.height/2) -
9a29fe70 290 (textHeight/2);
1154f91b
BW
291 }
292
293
e42f2c16 294 if (!(item.GetState() & wxAUI_BUTTON_STATE_DISABLED))
1154f91b 295 {
e42f2c16 296 if (item.GetState() & wxAUI_BUTTON_STATE_PRESSED)
1154f91b 297 {
9a29fe70
VZ
298 dc.SetPen(wxPen(m_highlightColour));
299 dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(150)));
1154f91b
BW
300 dc.DrawRectangle(rect);
301 }
e42f2c16 302 else if ((item.GetState() & wxAUI_BUTTON_STATE_HOVER) || item.IsSticky())
1154f91b 303 {
9a29fe70
VZ
304 dc.SetPen(wxPen(m_highlightColour));
305 dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(170)));
eecf97a5 306
1154f91b
BW
307 // draw an even lighter background for checked item hovers (since
308 // the hover background is the same color as the check background)
e42f2c16 309 if (item.GetState() & wxAUI_BUTTON_STATE_CHECKED)
9a29fe70 310 dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(180)));
eecf97a5 311
1154f91b
BW
312 dc.DrawRectangle(rect);
313 }
e42f2c16 314 else if (item.GetState() & wxAUI_BUTTON_STATE_CHECKED)
1154f91b
BW
315 {
316 // it's important to put this code in an else statment after the
317 // hover, otherwise hovers won't draw properly for checked items
9a29fe70
VZ
318 dc.SetPen(wxPen(m_highlightColour));
319 dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(170)));
1154f91b
BW
320 dc.DrawRectangle(rect);
321 }
322 }
323
324 wxBitmap bmp;
e42f2c16
BW
325 if (item.GetState() & wxAUI_BUTTON_STATE_DISABLED)
326 bmp = item.GetDisabledBitmap();
8b385bf8 327 else
e42f2c16 328 bmp = item.GetBitmap();
eecf97a5 329
2347971e 330 if ( bmp.IsOk() )
9a29fe70 331 dc.DrawBitmap(bmp, bmpX, bmpY, true);
1154f91b
BW
332
333 // set the item's text color based on if it is disabled
334 dc.SetTextForeground(*wxBLACK);
e42f2c16 335 if (item.GetState() & wxAUI_BUTTON_STATE_DISABLED)
1154f91b 336 dc.SetTextForeground(DISABLED_TEXT_COLOR);
eecf97a5 337
e42f2c16 338 if ( (m_flags & wxAUI_TB_TEXT) && !item.GetLabel().empty() )
1154f91b 339 {
9a29fe70 340 dc.DrawText(item.GetLabel(), textX, textY);
1154f91b
BW
341 }
342}
343
344
345void wxAuiDefaultToolBarArt::DrawDropDownButton(
346 wxDC& dc,
347 wxWindow* WXUNUSED(wnd),
348 const wxAuiToolBarItem& item,
349 const wxRect& rect)
350{
9a29fe70
VZ
351 int textWidth = 0, textHeight = 0, textX = 0, textY = 0;
352 int bmpX = 0, bmpY = 0, dropBmpX = 0, dropBmpY = 0;
eecf97a5 353
9a29fe70 354 wxRect buttonRect = wxRect(rect.x,
1154f91b
BW
355 rect.y,
356 rect.width-BUTTON_DROPDOWN_WIDTH,
357 rect.height);
9a29fe70 358 wxRect dropDownRect = wxRect(rect.x+rect.width-BUTTON_DROPDOWN_WIDTH-1,
1154f91b
BW
359 rect.y,
360 BUTTON_DROPDOWN_WIDTH+1,
361 rect.height);
eecf97a5 362
1154f91b
BW
363 if (m_flags & wxAUI_TB_TEXT)
364 {
365 dc.SetFont(m_font);
eecf97a5 366
1154f91b
BW
367 int tx, ty;
368 if (m_flags & wxAUI_TB_TEXT)
369 {
9a29fe70
VZ
370 dc.GetTextExtent(wxT("ABCDHgj"), &tx, &textHeight);
371 textWidth = 0;
eecf97a5
VZ
372 }
373
9a29fe70 374 dc.GetTextExtent(item.GetLabel(), &textWidth, &ty);
1154f91b
BW
375 }
376
377
eecf97a5 378
9a29fe70
VZ
379 dropBmpX = dropDownRect.x +
380 (dropDownRect.width/2) -
381 (m_buttonDropDownBmp.GetWidth()/2);
382 dropBmpY = dropDownRect.y +
383 (dropDownRect.height/2) -
384 (m_buttonDropDownBmp.GetHeight()/2);
eecf97a5
VZ
385
386
9a29fe70 387 if (m_textOrientation == wxAUI_TBTOOL_TEXT_BOTTOM)
1154f91b 388 {
9a29fe70
VZ
389 bmpX = buttonRect.x +
390 (buttonRect.width/2) -
e42f2c16 391 (item.GetBitmap().GetWidth()/2);
9a29fe70
VZ
392 bmpY = buttonRect.y +
393 ((buttonRect.height-textHeight)/2) -
e42f2c16 394 (item.GetBitmap().GetHeight()/2);
eecf97a5 395
9a29fe70
VZ
396 textX = rect.x + (rect.width/2) - (textWidth/2) + 1;
397 textY = rect.y + rect.height - textHeight - 1;
1154f91b 398 }
9a29fe70 399 else if (m_textOrientation == wxAUI_TBTOOL_TEXT_RIGHT)
1154f91b 400 {
9a29fe70 401 bmpX = rect.x + 3;
eecf97a5 402
9a29fe70 403 bmpY = rect.y +
1154f91b 404 (rect.height/2) -
e42f2c16 405 (item.GetBitmap().GetHeight()/2);
eecf97a5 406
9a29fe70
VZ
407 textX = bmpX + 3 + item.GetBitmap().GetWidth();
408 textY = rect.y +
1154f91b 409 (rect.height/2) -
9a29fe70 410 (textHeight/2);
1154f91b 411 }
eecf97a5
VZ
412
413
e42f2c16 414 if (item.GetState() & wxAUI_BUTTON_STATE_PRESSED)
1154f91b 415 {
9a29fe70
VZ
416 dc.SetPen(wxPen(m_highlightColour));
417 dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(140)));
418 dc.DrawRectangle(buttonRect);
4a21ea9d 419
9a29fe70
VZ
420 dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(170)));
421 dc.DrawRectangle(dropDownRect);
1154f91b 422 }
e42f2c16
BW
423 else if (item.GetState() & wxAUI_BUTTON_STATE_HOVER ||
424 item.IsSticky())
1154f91b 425 {
9a29fe70
VZ
426 dc.SetPen(wxPen(m_highlightColour));
427 dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(170)));
428 dc.DrawRectangle(buttonRect);
429 dc.DrawRectangle(dropDownRect);
1154f91b 430 }
026c6eff
VZ
431 else if (item.GetState() & wxAUI_BUTTON_STATE_CHECKED)
432 {
433 // Notice that this branch must come after the hover one to ensure the
9a29fe70
VZ
434 // correct appearance when the mouse hovers over a checked item.m_
435 dc.SetPen(wxPen(m_highlightColour));
436 dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(170)));
437 dc.DrawRectangle(buttonRect);
438 dc.DrawRectangle(dropDownRect);
026c6eff 439 }
1154f91b
BW
440
441 wxBitmap bmp;
442 wxBitmap dropbmp;
e42f2c16 443 if (item.GetState() & wxAUI_BUTTON_STATE_DISABLED)
1154f91b 444 {
e42f2c16 445 bmp = item.GetDisabledBitmap();
9a29fe70 446 dropbmp = m_disabledButtonDropDownBmp;
1154f91b 447 }
8b385bf8 448 else
1154f91b 449 {
e42f2c16 450 bmp = item.GetBitmap();
9a29fe70 451 dropbmp = m_buttonDropDownBmp;
1154f91b 452 }
eecf97a5 453
1154f91b
BW
454 if (!bmp.IsOk())
455 return;
eecf97a5 456
9a29fe70
VZ
457 dc.DrawBitmap(bmp, bmpX, bmpY, true);
458 dc.DrawBitmap(dropbmp, dropBmpX, dropBmpY, true);
1154f91b
BW
459
460 // set the item's text color based on if it is disabled
461 dc.SetTextForeground(*wxBLACK);
e42f2c16 462 if (item.GetState() & wxAUI_BUTTON_STATE_DISABLED)
1154f91b 463 dc.SetTextForeground(DISABLED_TEXT_COLOR);
eecf97a5 464
e42f2c16 465 if ( (m_flags & wxAUI_TB_TEXT) && !item.GetLabel().empty() )
1154f91b 466 {
9a29fe70 467 dc.DrawText(item.GetLabel(), textX, textY);
1154f91b
BW
468 }
469}
470
471void wxAuiDefaultToolBarArt::DrawControlLabel(
472 wxDC& dc,
473 wxWindow* WXUNUSED(wnd),
474 const wxAuiToolBarItem& item,
475 const wxRect& rect)
476{
477 if (!(m_flags & wxAUI_TB_TEXT))
478 return;
479
9a29fe70 480 if (m_textOrientation != wxAUI_TBTOOL_TEXT_BOTTOM)
1154f91b 481 return;
eecf97a5 482
9a29fe70
VZ
483 int textX = 0, textY = 0;
484 int textWidth = 0, textHeight = 0;
1154f91b
BW
485
486 dc.SetFont(m_font);
eecf97a5 487
1154f91b
BW
488 int tx, ty;
489 if (m_flags & wxAUI_TB_TEXT)
490 {
9a29fe70
VZ
491 dc.GetTextExtent(wxT("ABCDHgj"), &tx, &textHeight);
492 textWidth = 0;
eecf97a5
VZ
493 }
494
9a29fe70 495 dc.GetTextExtent(item.GetLabel(), &textWidth, &ty);
eecf97a5 496
1154f91b 497 // don't draw the label if it is wider than the item width
9a29fe70 498 if (textWidth > rect.width)
1154f91b 499 return;
eecf97a5 500
1154f91b
BW
501 // set the label's text color
502 dc.SetTextForeground(*wxBLACK);
eecf97a5 503
9a29fe70
VZ
504 textX = rect.x + (rect.width/2) - (textWidth/2) + 1;
505 textY = rect.y + rect.height - textHeight - 1;
eecf97a5 506
e42f2c16 507 if ( (m_flags & wxAUI_TB_TEXT) && !item.GetLabel().empty() )
1154f91b 508 {
9a29fe70 509 dc.DrawText(item.GetLabel(), textX, textY);
1154f91b
BW
510 }
511}
512
513wxSize wxAuiDefaultToolBarArt::GetLabelSize(
514 wxDC& dc,
515 wxWindow* WXUNUSED(wnd),
516 const wxAuiToolBarItem& item)
517{
518 dc.SetFont(m_font);
519
520 // get label's height
521 int width = 0, height = 0;
522 dc.GetTextExtent(wxT("ABCDHgj"), &width, &height);
523
524 // get item's width
e42f2c16 525 width = item.GetMinSize().GetWidth();
45496810 526
e54e92e6
BW
527 if (width == -1)
528 {
529 // no width specified, measure the text ourselves
530 width = dc.GetTextExtent(item.GetLabel()).GetX();
531 }
45496810 532
1154f91b
BW
533 return wxSize(width, height);
534}
535
536wxSize wxAuiDefaultToolBarArt::GetToolSize(
537 wxDC& dc,
538 wxWindow* WXUNUSED(wnd),
539 const wxAuiToolBarItem& item)
540{
e42f2c16 541 if (!item.GetBitmap().IsOk() && !(m_flags & wxAUI_TB_TEXT))
1154f91b 542 return wxSize(16,16);
eecf97a5 543
e42f2c16
BW
544 int width = item.GetBitmap().GetWidth();
545 int height = item.GetBitmap().GetHeight();
eecf97a5 546
1154f91b
BW
547 if (m_flags & wxAUI_TB_TEXT)
548 {
549 dc.SetFont(m_font);
550 int tx, ty;
eecf97a5 551
9a29fe70 552 if (m_textOrientation == wxAUI_TBTOOL_TEXT_BOTTOM)
1154f91b
BW
553 {
554 dc.GetTextExtent(wxT("ABCDHgj"), &tx, &ty);
555 height += ty;
eecf97a5 556
e42f2c16 557 if ( !item.GetLabel().empty() )
1154f91b 558 {
e42f2c16 559 dc.GetTextExtent(item.GetLabel(), &tx, &ty);
1154f91b
BW
560 width = wxMax(width, tx+6);
561 }
562 }
9a29fe70 563 else if ( m_textOrientation == wxAUI_TBTOOL_TEXT_RIGHT &&
e42f2c16 564 !item.GetLabel().empty() )
1154f91b
BW
565 {
566 width += 3; // space between left border and bitmap
567 width += 3; // space between bitmap and text
eecf97a5 568
e42f2c16 569 if ( !item.GetLabel().empty() )
1154f91b 570 {
e42f2c16 571 dc.GetTextExtent(item.GetLabel(), &tx, &ty);
1154f91b
BW
572 width += tx;
573 height = wxMax(height, ty);
574 }
575 }
eecf97a5 576 }
1154f91b
BW
577
578 // if the tool has a dropdown button, add it to the width
e42f2c16 579 if (item.HasDropDown())
1154f91b 580 width += (BUTTON_DROPDOWN_WIDTH+4);
eecf97a5 581
1154f91b
BW
582 return wxSize(width, height);
583}
584
585void wxAuiDefaultToolBarArt::DrawSeparator(
586 wxDC& dc,
587 wxWindow* WXUNUSED(wnd),
588 const wxRect& _rect)
589{
590 bool horizontal = true;
591 if (m_flags & wxAUI_TB_VERTICAL)
592 horizontal = false;
eecf97a5 593
1154f91b 594 wxRect rect = _rect;
eecf97a5 595
1154f91b
BW
596 if (horizontal)
597 {
598 rect.x += (rect.width/2);
599 rect.width = 1;
600 int new_height = (rect.height*3)/4;
601 rect.y += (rect.height/2) - (new_height/2);
602 rect.height = new_height;
603 }
8b385bf8 604 else
1154f91b
BW
605 {
606 rect.y += (rect.height/2);
607 rect.height = 1;
608 int new_width = (rect.width*3)/4;
609 rect.x += (rect.width/2) - (new_width/2);
610 rect.width = new_width;
611 }
eecf97a5 612
9a29fe70
VZ
613 wxColour startColour = m_baseColour.ChangeLightness(80);
614 wxColour endColour = m_baseColour.ChangeLightness(80);
615 dc.GradientFillLinear(rect, startColour, endColour, horizontal ? wxSOUTH : wxEAST);
1154f91b 616}
eecf97a5 617
1154f91b
BW
618void wxAuiDefaultToolBarArt::DrawGripper(wxDC& dc,
619 wxWindow* WXUNUSED(wnd),
620 const wxRect& rect)
621{
622 int i = 0;
623 while (1)
624 {
625 int x, y;
eecf97a5 626
1154f91b
BW
627 if (m_flags & wxAUI_TB_VERTICAL)
628 {
629 x = rect.x + (i*4) + 5;
630 y = rect.y + 3;
631 if (x > rect.GetWidth()-5)
632 break;
633 }
8b385bf8 634 else
1154f91b
BW
635 {
636 x = rect.x + 3;
637 y = rect.y + (i*4) + 5;
638 if (y > rect.GetHeight()-5)
639 break;
640 }
eecf97a5 641
9a29fe70 642 dc.SetPen(m_gripperPen1);
1154f91b 643 dc.DrawPoint(x, y);
9a29fe70 644 dc.SetPen(m_gripperPen2);
1154f91b
BW
645 dc.DrawPoint(x, y+1);
646 dc.DrawPoint(x+1, y);
9a29fe70 647 dc.SetPen(m_gripperPen3);
1154f91b
BW
648 dc.DrawPoint(x+2, y+1);
649 dc.DrawPoint(x+2, y+2);
650 dc.DrawPoint(x+1, y+2);
651
652 i++;
653 }
654
655}
eecf97a5 656
1154f91b
BW
657void wxAuiDefaultToolBarArt::DrawOverflowButton(wxDC& dc,
658 wxWindow* wnd,
659 const wxRect& rect,
660 int state)
661{
662 if (state & wxAUI_BUTTON_STATE_HOVER ||
663 state & wxAUI_BUTTON_STATE_PRESSED)
664 {
665 wxRect cli_rect = wnd->GetClientRect();
9a29fe70 666 wxColor light_gray_bg = m_highlightColour.ChangeLightness(170);
eecf97a5 667
1154f91b
BW
668 if (m_flags & wxAUI_TB_VERTICAL)
669 {
9a29fe70 670 dc.SetPen(wxPen(m_highlightColour));
1154f91b
BW
671 dc.DrawLine(rect.x, rect.y, rect.x+rect.width, rect.y);
672 dc.SetPen(wxPen(light_gray_bg));
673 dc.SetBrush(wxBrush(light_gray_bg));
674 dc.DrawRectangle(rect.x, rect.y+1, rect.width, rect.height);
675 }
676 else
677 {
9a29fe70 678 dc.SetPen(wxPen(m_highlightColour));
1154f91b
BW
679 dc.DrawLine(rect.x, rect.y, rect.x, rect.y+rect.height);
680 dc.SetPen(wxPen(light_gray_bg));
681 dc.SetBrush(wxBrush(light_gray_bg));
682 dc.DrawRectangle(rect.x+1, rect.y, rect.width, rect.height);
683 }
684 }
685
9a29fe70
VZ
686 int x = rect.x+1+(rect.width-m_overflowBmp.GetWidth())/2;
687 int y = rect.y+1+(rect.height-m_overflowBmp.GetHeight())/2;
688 dc.DrawBitmap(m_overflowBmp, x, y, true);
1154f91b
BW
689}
690
691int wxAuiDefaultToolBarArt::GetElementSize(int element_id)
692{
693 switch (element_id)
694 {
9a29fe70
VZ
695 case wxAUI_TBART_SEPARATOR_SIZE: return m_separatorSize;
696 case wxAUI_TBART_GRIPPER_SIZE: return m_gripperSize;
697 case wxAUI_TBART_OVERFLOW_SIZE: return m_overflowSize;
1154f91b
BW
698 default: return 0;
699 }
700}
701
702void wxAuiDefaultToolBarArt::SetElementSize(int element_id, int size)
703{
704 switch (element_id)
705 {
9a29fe70
VZ
706 case wxAUI_TBART_SEPARATOR_SIZE: m_separatorSize = size; break;
707 case wxAUI_TBART_GRIPPER_SIZE: m_gripperSize = size; break;
708 case wxAUI_TBART_OVERFLOW_SIZE: m_overflowSize = size; break;
1154f91b
BW
709 }
710}
711
712int wxAuiDefaultToolBarArt::ShowDropDown(wxWindow* wnd,
713 const wxAuiToolBarItemArray& items)
714{
715 wxMenu menuPopup;
716
717 size_t items_added = 0;
eecf97a5 718
1154f91b
BW
719 size_t i, count = items.GetCount();
720 for (i = 0; i < count; ++i)
721 {
722 wxAuiToolBarItem& item = items.Item(i);
eecf97a5 723
e42f2c16 724 if (item.GetKind() == wxITEM_NORMAL)
1154f91b 725 {
e42f2c16 726 wxString text = item.GetShortHelp();
1154f91b 727 if (text.empty())
e42f2c16 728 text = item.GetLabel();
eecf97a5 729
1154f91b
BW
730 if (text.empty())
731 text = wxT(" ");
eecf97a5 732
e42f2c16 733 wxMenuItem* m = new wxMenuItem(&menuPopup, item.GetId(), text, item.GetShortHelp());
1154f91b 734
e42f2c16 735 m->SetBitmap(item.GetBitmap());
1154f91b
BW
736 menuPopup.Append(m);
737 items_added++;
738 }
e42f2c16 739 else if (item.GetKind() == wxITEM_SEPARATOR)
1154f91b
BW
740 {
741 if (items_added > 0)
742 menuPopup.AppendSeparator();
743 }
744 }
745
746 // find out where to put the popup menu of window items
747 wxPoint pt = ::wxGetMousePosition();
748 pt = wnd->ScreenToClient(pt);
749
750 // find out the screen coordinate at the bottom of the tab ctrl
751 wxRect cli_rect = wnd->GetClientRect();
752 pt.y = cli_rect.y + cli_rect.height;
753
754 ToolbarCommandCapture* cc = new ToolbarCommandCapture;
755 wnd->PushEventHandler(cc);
756 wnd->PopupMenu(&menuPopup, pt);
757 int command = cc->GetCommandId();
758 wnd->PopEventHandler(true);
759
760 return command;
761}
762
763
764
765
e5dcae09
VZ
766static wxOrientation GetOrientation(long& style)
767{
768 switch (style & wxAUI_ORIENTATION_MASK)
769 {
770 case wxAUI_TB_HORIZONTAL:
771 return wxHORIZONTAL;
772 case wxAUI_TB_VERTICAL:
773 return wxVERTICAL;
774 default:
775 wxFAIL_MSG("toolbar cannot be locked in both horizontal and vertical orientations (maybe no lock was intended?)");
776 // fall through
777 case 0:
778 return wxBOTH;
779 }
780}
781
1154f91b
BW
782BEGIN_EVENT_TABLE(wxAuiToolBar, wxControl)
783 EVT_SIZE(wxAuiToolBar::OnSize)
784 EVT_IDLE(wxAuiToolBar::OnIdle)
785 EVT_ERASE_BACKGROUND(wxAuiToolBar::OnEraseBackground)
786 EVT_PAINT(wxAuiToolBar::OnPaint)
787 EVT_LEFT_DOWN(wxAuiToolBar::OnLeftDown)
788 EVT_LEFT_DCLICK(wxAuiToolBar::OnLeftDown)
789 EVT_LEFT_UP(wxAuiToolBar::OnLeftUp)
790 EVT_RIGHT_DOWN(wxAuiToolBar::OnRightDown)
791 EVT_RIGHT_DCLICK(wxAuiToolBar::OnRightDown)
792 EVT_RIGHT_UP(wxAuiToolBar::OnRightUp)
793 EVT_MIDDLE_DOWN(wxAuiToolBar::OnMiddleDown)
794 EVT_MIDDLE_DCLICK(wxAuiToolBar::OnMiddleDown)
795 EVT_MIDDLE_UP(wxAuiToolBar::OnMiddleUp)
796 EVT_MOTION(wxAuiToolBar::OnMotion)
797 EVT_LEAVE_WINDOW(wxAuiToolBar::OnLeaveWindow)
4a21ea9d 798 EVT_MOUSE_CAPTURE_LOST(wxAuiToolBar::OnCaptureLost)
1154f91b
BW
799 EVT_SET_CURSOR(wxAuiToolBar::OnSetCursor)
800END_EVENT_TABLE()
801
802
803wxAuiToolBar::wxAuiToolBar(wxWindow* parent,
804 wxWindowID id,
805 const wxPoint& position,
806 const wxSize& size,
807 long style)
808 : wxControl(parent,
809 id,
810 position,
811 size,
812 style | wxBORDER_NONE)
813{
814 m_sizer = new wxBoxSizer(wxHORIZONTAL);
9a29fe70
VZ
815 m_buttonWidth = -1;
816 m_buttonHeight = -1;
817 m_sizerElementCount = 0;
818 m_actionPos = wxPoint(-1,-1);
819 m_actionItem = NULL;
820 m_tipItem = NULL;
1154f91b 821 m_art = new wxAuiDefaultToolBarArt;
9a29fe70
VZ
822 m_toolPacking = 2;
823 m_toolBorderPadding = 3;
824 m_toolTextOrientation = wxAUI_TBTOOL_TEXT_BOTTOM;
825 m_gripperSizerItem = NULL;
826 m_overflowSizerItem = NULL;
1154f91b 827 m_dragging = false;
e5dcae09
VZ
828 m_orientation = GetOrientation(style);
829 if (m_orientation == wxBOTH)
830 {
831 m_orientation = wxHORIZONTAL;
832 }
af2a1b42 833 m_style = style | wxBORDER_NONE;
9a29fe70
VZ
834 m_gripperVisible = (m_style & wxAUI_TB_GRIPPER) ? true : false;
835 m_overflowVisible = (m_style & wxAUI_TB_OVERFLOW) ? true : false;
836 m_overflowState = 0;
1154f91b
BW
837 SetMargins(5, 5, 2, 2);
838 SetFont(*wxNORMAL_FONT);
e5dcae09 839 SetArtFlags();
1154f91b 840 SetExtraStyle(wxWS_EX_PROCESS_IDLE);
9578058d 841 if (style & wxAUI_TB_HORZ_LAYOUT)
1154f91b 842 SetToolTextOrientation(wxAUI_TBTOOL_TEXT_RIGHT);
66ad3095 843 SetBackgroundStyle(wxBG_STYLE_CUSTOM);
1154f91b
BW
844}
845
846
847wxAuiToolBar::~wxAuiToolBar()
848{
849 delete m_art;
850 delete m_sizer;
851}
852
853void wxAuiToolBar::SetWindowStyleFlag(long style)
854{
e5dcae09
VZ
855 GetOrientation(style); // assert if style is invalid
856 wxCHECK_RET(IsPaneValid(style),
857 "window settings and pane settings are incompatible");
858
1154f91b
BW
859 wxControl::SetWindowStyleFlag(style);
860
861 m_style = style;
eecf97a5 862
1154f91b
BW
863 if (m_art)
864 {
e5dcae09 865 SetArtFlags();
1154f91b 866 }
eecf97a5 867
1154f91b 868 if (m_style & wxAUI_TB_GRIPPER)
9a29fe70 869 m_gripperVisible = true;
8b385bf8 870 else
9a29fe70 871 m_gripperVisible = false;
1154f91b
BW
872
873
874 if (m_style & wxAUI_TB_OVERFLOW)
9a29fe70 875 m_overflowVisible = true;
8b385bf8 876 else
9a29fe70 877 m_overflowVisible = false;
eecf97a5 878
9578058d 879 if (style & wxAUI_TB_HORZ_LAYOUT)
1154f91b 880 SetToolTextOrientation(wxAUI_TBTOOL_TEXT_RIGHT);
8b385bf8 881 else
1154f91b
BW
882 SetToolTextOrientation(wxAUI_TBTOOL_TEXT_BOTTOM);
883}
884
e7b8af65
BW
885long wxAuiToolBar::GetWindowStyleFlag() const
886{
887 return m_style;
888}
1154f91b
BW
889
890void wxAuiToolBar::SetArtProvider(wxAuiToolBarArt* art)
891{
892 delete m_art;
eecf97a5 893
1154f91b 894 m_art = art;
eecf97a5 895
1154f91b
BW
896 if (m_art)
897 {
e5dcae09 898 SetArtFlags();
9a29fe70 899 m_art->SetTextOrientation(m_toolTextOrientation);
1154f91b
BW
900 }
901}
902
903wxAuiToolBarArt* wxAuiToolBar::GetArtProvider() const
904{
905 return m_art;
906}
907
908
909
910
7bce8439 911wxAuiToolBarItem* wxAuiToolBar::AddTool(int tool_id,
1154f91b
BW
912 const wxString& label,
913 const wxBitmap& bitmap,
9a29fe70 914 const wxString& shortHelp_string,
1154f91b
BW
915 wxItemKind kind)
916{
7bce8439 917 return AddTool(tool_id,
1154f91b
BW
918 label,
919 bitmap,
920 wxNullBitmap,
921 kind,
9a29fe70 922 shortHelp_string,
1154f91b
BW
923 wxEmptyString,
924 NULL);
925}
926
927
7bce8439 928wxAuiToolBarItem* wxAuiToolBar::AddTool(int tool_id,
1154f91b
BW
929 const wxString& label,
930 const wxBitmap& bitmap,
9a29fe70 931 const wxBitmap& disabledBitmap,
1154f91b 932 wxItemKind kind,
9a29fe70
VZ
933 const wxString& shortHelpString,
934 const wxString& longHelpString,
1154f91b
BW
935 wxObject* WXUNUSED(client_data))
936{
937 wxAuiToolBarItem item;
9a29fe70
VZ
938 item.m_window = NULL;
939 item.m_label = label;
940 item.m_bitmap = bitmap;
941 item.m_disabledBitmap = disabledBitmap;
942 item.m_shortHelp = shortHelpString;
943 item.m_longHelp = longHelpString;
944 item.m_active = true;
945 item.m_dropDown = false;
946 item.m_spacerPixels = 0;
947 item.m_toolId = tool_id;
948 item.m_state = 0;
949 item.m_proportion = 0;
950 item.m_kind = kind;
951 item.m_sizerItem = NULL;
952 item.m_minSize = wxDefaultSize;
953 item.m_userData = 0;
954 item.m_sticky = false;
955
956 if (item.m_toolId == wxID_ANY)
957 item.m_toolId = wxNewId();
958
959 if (!item.m_disabledBitmap.IsOk())
1154f91b
BW
960 {
961 // no disabled bitmap specified, we need to make one
9a29fe70 962 if (item.m_bitmap.IsOk())
1154f91b 963 {
9a29fe70 964 item.m_disabledBitmap = item.m_bitmap.ConvertToDisabled();
1154f91b
BW
965 }
966 }
1154f91b 967 m_items.Add(item);
7bce8439 968 return &m_items.Last();
1154f91b
BW
969}
970
7bce8439 971wxAuiToolBarItem* wxAuiToolBar::AddControl(wxControl* control,
1154f91b
BW
972 const wxString& label)
973{
974 wxAuiToolBarItem item;
9a29fe70
VZ
975 item.m_window = (wxWindow*)control;
976 item.m_label = label;
977 item.m_bitmap = wxNullBitmap;
978 item.m_disabledBitmap = wxNullBitmap;
979 item.m_active = true;
980 item.m_dropDown = false;
981 item.m_spacerPixels = 0;
982 item.m_toolId = control->GetId();
983 item.m_state = 0;
984 item.m_proportion = 0;
985 item.m_kind = wxITEM_CONTROL;
986 item.m_sizerItem = NULL;
987 item.m_minSize = control->GetEffectiveMinSize();
988 item.m_userData = 0;
989 item.m_sticky = false;
1154f91b
BW
990
991 m_items.Add(item);
7bce8439 992 return &m_items.Last();
1154f91b
BW
993}
994
7bce8439 995wxAuiToolBarItem* wxAuiToolBar::AddLabel(int tool_id,
1154f91b
BW
996 const wxString& label,
997 const int width)
998{
999 wxSize min_size = wxDefaultSize;
1000 if (width != -1)
1001 min_size.x = width;
eecf97a5 1002
1154f91b 1003 wxAuiToolBarItem item;
9a29fe70
VZ
1004 item.m_window = NULL;
1005 item.m_label = label;
1006 item.m_bitmap = wxNullBitmap;
1007 item.m_disabledBitmap = wxNullBitmap;
1008 item.m_active = true;
1009 item.m_dropDown = false;
1010 item.m_spacerPixels = 0;
1011 item.m_toolId = tool_id;
1012 item.m_state = 0;
1013 item.m_proportion = 0;
1014 item.m_kind = wxITEM_LABEL;
1015 item.m_sizerItem = NULL;
1016 item.m_minSize = min_size;
1017 item.m_userData = 0;
1018 item.m_sticky = false;
1019
1020 if (item.m_toolId == wxID_ANY)
1021 item.m_toolId = wxNewId();
45496810 1022
1154f91b 1023 m_items.Add(item);
7bce8439 1024 return &m_items.Last();
1154f91b
BW
1025}
1026
7bce8439 1027wxAuiToolBarItem* wxAuiToolBar::AddSeparator()
1154f91b
BW
1028{
1029 wxAuiToolBarItem item;
9a29fe70
VZ
1030 item.m_window = NULL;
1031 item.m_label = wxEmptyString;
1032 item.m_bitmap = wxNullBitmap;
1033 item.m_disabledBitmap = wxNullBitmap;
1034 item.m_active = true;
1035 item.m_dropDown = false;
1036 item.m_toolId = -1;
1037 item.m_state = 0;
1038 item.m_proportion = 0;
1039 item.m_kind = wxITEM_SEPARATOR;
1040 item.m_sizerItem = NULL;
1041 item.m_minSize = wxDefaultSize;
1042 item.m_userData = 0;
1043 item.m_sticky = false;
1154f91b
BW
1044
1045 m_items.Add(item);
7bce8439 1046 return &m_items.Last();
1154f91b
BW
1047}
1048
7bce8439 1049wxAuiToolBarItem* wxAuiToolBar::AddSpacer(int pixels)
1154f91b
BW
1050{
1051 wxAuiToolBarItem item;
9a29fe70
VZ
1052 item.m_window = NULL;
1053 item.m_label = wxEmptyString;
1054 item.m_bitmap = wxNullBitmap;
1055 item.m_disabledBitmap = wxNullBitmap;
1056 item.m_active = true;
1057 item.m_dropDown = false;
1058 item.m_spacerPixels = pixels;
1059 item.m_toolId = -1;
1060 item.m_state = 0;
1061 item.m_proportion = 0;
1062 item.m_kind = wxITEM_SPACER;
1063 item.m_sizerItem = NULL;
1064 item.m_minSize = wxDefaultSize;
1065 item.m_userData = 0;
1066 item.m_sticky = false;
1154f91b
BW
1067
1068 m_items.Add(item);
7bce8439 1069 return &m_items.Last();
1154f91b
BW
1070}
1071
7bce8439 1072wxAuiToolBarItem* wxAuiToolBar::AddStretchSpacer(int proportion)
1154f91b
BW
1073{
1074 wxAuiToolBarItem item;
9a29fe70
VZ
1075 item.m_window = NULL;
1076 item.m_label = wxEmptyString;
1077 item.m_bitmap = wxNullBitmap;
1078 item.m_disabledBitmap = wxNullBitmap;
1079 item.m_active = true;
1080 item.m_dropDown = false;
1081 item.m_spacerPixels = 0;
1082 item.m_toolId = -1;
1083 item.m_state = 0;
1084 item.m_proportion = proportion;
1085 item.m_kind = wxITEM_SPACER;
1086 item.m_sizerItem = NULL;
1087 item.m_minSize = wxDefaultSize;
1088 item.m_userData = 0;
1089 item.m_sticky = false;
1154f91b
BW
1090
1091 m_items.Add(item);
7bce8439 1092 return &m_items.Last();
1154f91b
BW
1093}
1094
1095void wxAuiToolBar::Clear()
1096{
1097 m_items.Clear();
9a29fe70 1098 m_sizerElementCount = 0;
1154f91b
BW
1099}
1100
1101bool wxAuiToolBar::DeleteTool(int tool_id)
1102{
1103 int idx = GetToolIndex(tool_id);
1104 if (idx >= 0 && idx < (int)m_items.GetCount())
1105 {
1106 m_items.RemoveAt(idx);
1107 Realize();
1108 return true;
1109 }
eecf97a5 1110
1154f91b
BW
1111 return false;
1112}
1113
1114bool wxAuiToolBar::DeleteByIndex(int idx)
1115{
1116 if (idx >= 0 && idx < (int)m_items.GetCount())
1117 {
1118 m_items.RemoveAt(idx);
1119 Realize();
1120 return true;
1121 }
eecf97a5 1122
1154f91b
BW
1123 return false;
1124}
1125
1126
1127wxControl* wxAuiToolBar::FindControl(int id)
1128{
1129 wxWindow* wnd = FindWindow(id);
1130 return (wxControl*)wnd;
1131}
1132
1133wxAuiToolBarItem* wxAuiToolBar::FindTool(int tool_id) const
1134{
1135 size_t i, count;
1136 for (i = 0, count = m_items.GetCount(); i < count; ++i)
1137 {
1138 wxAuiToolBarItem& item = m_items.Item(i);
9a29fe70 1139 if (item.m_toolId == tool_id)
1154f91b
BW
1140 return &item;
1141 }
eecf97a5 1142
1154f91b
BW
1143 return NULL;
1144}
1145
1146wxAuiToolBarItem* wxAuiToolBar::FindToolByPosition(wxCoord x, wxCoord y) const
1147{
1148 size_t i, count;
1149 for (i = 0, count = m_items.GetCount(); i < count; ++i)
1150 {
1151 wxAuiToolBarItem& item = m_items.Item(i);
eecf97a5 1152
9a29fe70 1153 if (!item.m_sizerItem)
1154f91b 1154 continue;
eecf97a5 1155
9a29fe70 1156 wxRect rect = item.m_sizerItem->GetRect();
1154f91b
BW
1157 if (rect.Contains(x,y))
1158 {
1159 // if the item doesn't fit on the toolbar, return NULL
1160 if (!GetToolFitsByIndex(i))
1161 return NULL;
eecf97a5 1162
1154f91b
BW
1163 return &item;
1164 }
1165 }
eecf97a5 1166
1154f91b
BW
1167 return NULL;
1168}
1169
1170wxAuiToolBarItem* wxAuiToolBar::FindToolByPositionWithPacking(wxCoord x, wxCoord y) const
1171{
1172 size_t i, count;
1173 for (i = 0, count = m_items.GetCount(); i < count; ++i)
1174 {
1175 wxAuiToolBarItem& item = m_items.Item(i);
eecf97a5 1176
9a29fe70 1177 if (!item.m_sizerItem)
1154f91b 1178 continue;
eecf97a5 1179
9a29fe70 1180 wxRect rect = item.m_sizerItem->GetRect();
eecf97a5 1181
1154f91b
BW
1182 // apply tool packing
1183 if (i+1 < count)
9a29fe70 1184 rect.width += m_toolPacking;
eecf97a5 1185
1154f91b
BW
1186 if (rect.Contains(x,y))
1187 {
1188 // if the item doesn't fit on the toolbar, return NULL
1189 if (!GetToolFitsByIndex(i))
1190 return NULL;
eecf97a5 1191
1154f91b
BW
1192 return &item;
1193 }
1194 }
eecf97a5 1195
1154f91b
BW
1196 return NULL;
1197}
1198
1199wxAuiToolBarItem* wxAuiToolBar::FindToolByIndex(int idx) const
1200{
1201 if (idx < 0)
1202 return NULL;
eecf97a5 1203
1154f91b
BW
1204 if (idx >= (int)m_items.size())
1205 return NULL;
eecf97a5 1206
1154f91b
BW
1207 return &(m_items[idx]);
1208}
1209
1210void wxAuiToolBar::SetToolBitmapSize(const wxSize& WXUNUSED(size))
1211{
1212 // TODO: wxToolBar compatibility
1213}
1214
1215wxSize wxAuiToolBar::GetToolBitmapSize() const
1216{
1217 // TODO: wxToolBar compatibility
1218 return wxSize(16,15);
1219}
eecf97a5 1220
1154f91b
BW
1221void wxAuiToolBar::SetToolProportion(int tool_id, int proportion)
1222{
1223 wxAuiToolBarItem* item = FindTool(tool_id);
1224 if (!item)
1225 return;
eecf97a5 1226
9a29fe70 1227 item->m_proportion = proportion;
1154f91b
BW
1228}
1229
1230int wxAuiToolBar::GetToolProportion(int tool_id) const
1231{
1232 wxAuiToolBarItem* item = FindTool(tool_id);
1233 if (!item)
1234 return 0;
eecf97a5 1235
9a29fe70 1236 return item->m_proportion;
1154f91b
BW
1237}
1238
1239void wxAuiToolBar::SetToolSeparation(int separation)
1240{
1241 if (m_art)
1242 m_art->SetElementSize(wxAUI_TBART_SEPARATOR_SIZE, separation);
1243}
1244
1245int wxAuiToolBar::GetToolSeparation() const
1246{
1247 if (m_art)
1248 return m_art->GetElementSize(wxAUI_TBART_SEPARATOR_SIZE);
8b385bf8 1249 else
1154f91b
BW
1250 return 5;
1251}
eecf97a5 1252
1154f91b
BW
1253
1254void wxAuiToolBar::SetToolDropDown(int tool_id, bool dropdown)
1255{
eecf97a5 1256 wxAuiToolBarItem* item = FindTool(tool_id);
1154f91b
BW
1257 if (!item)
1258 return;
1259
9a29fe70 1260 item->m_dropDown = dropdown;
1154f91b
BW
1261}
1262
1263bool wxAuiToolBar::GetToolDropDown(int tool_id) const
1264{
1265 wxAuiToolBarItem* item = FindTool(tool_id);
1266 if (!item)
1267 return 0;
eecf97a5 1268
9a29fe70 1269 return item->m_dropDown;
1154f91b
BW
1270}
1271
1272void wxAuiToolBar::SetToolSticky(int tool_id, bool sticky)
1273{
1274 // ignore separators
1275 if (tool_id == -1)
1276 return;
eecf97a5
VZ
1277
1278 wxAuiToolBarItem* item = FindTool(tool_id);
1154f91b
BW
1279 if (!item)
1280 return;
eecf97a5 1281
9a29fe70 1282 if (item->m_sticky == sticky)
1154f91b 1283 return;
eecf97a5 1284
9a29fe70 1285 item->m_sticky = sticky;
eecf97a5 1286
1154f91b
BW
1287 Refresh(false);
1288 Update();
1289}
1290
1291bool wxAuiToolBar::GetToolSticky(int tool_id) const
1292{
1293 wxAuiToolBarItem* item = FindTool(tool_id);
1294 if (!item)
1295 return 0;
eecf97a5 1296
9a29fe70 1297 return item->m_sticky;
1154f91b
BW
1298}
1299
1300
1301
1302
1303void wxAuiToolBar::SetToolBorderPadding(int padding)
1304{
9a29fe70 1305 m_toolBorderPadding = padding;
1154f91b
BW
1306}
1307
1308int wxAuiToolBar::GetToolBorderPadding() const
1309{
9a29fe70 1310 return m_toolBorderPadding;
1154f91b
BW
1311}
1312
1313void wxAuiToolBar::SetToolTextOrientation(int orientation)
1314{
9a29fe70 1315 m_toolTextOrientation = orientation;
1154f91b
BW
1316
1317 if (m_art)
1318 {
1319 m_art->SetTextOrientation(orientation);
1320 }
1321}
1322
1323int wxAuiToolBar::GetToolTextOrientation() const
1324{
9a29fe70 1325 return m_toolTextOrientation;
1154f91b
BW
1326}
1327
1328void wxAuiToolBar::SetToolPacking(int packing)
1329{
9a29fe70 1330 m_toolPacking = packing;
1154f91b
BW
1331}
1332
1333int wxAuiToolBar::GetToolPacking() const
1334{
9a29fe70 1335 return m_toolPacking;
1154f91b
BW
1336}
1337
1338
e5dcae09 1339void wxAuiToolBar::SetOrientation(int orientation)
1154f91b 1340{
e5dcae09
VZ
1341 wxCHECK_RET(orientation == wxHORIZONTAL ||
1342 orientation == wxVERTICAL,
1343 "invalid orientation value");
1344 if (orientation != m_orientation)
1345 {
1346 m_orientation = wxOrientation(orientation);
1347 SetArtFlags();
1348 }
1154f91b
BW
1349}
1350
1351void wxAuiToolBar::SetMargins(int left, int right, int top, int bottom)
1352{
1353 if (left != -1)
9a29fe70 1354 m_leftPadding = left;
1154f91b 1355 if (right != -1)
9a29fe70 1356 m_rightPadding = right;
1154f91b 1357 if (top != -1)
9a29fe70 1358 m_topPadding = top;
1154f91b 1359 if (bottom != -1)
9a29fe70 1360 m_bottomPadding = bottom;
1154f91b
BW
1361}
1362
1363bool wxAuiToolBar::GetGripperVisible() const
1364{
9a29fe70 1365 return m_gripperVisible;
1154f91b
BW
1366}
1367
1368void wxAuiToolBar::SetGripperVisible(bool visible)
1369{
9a29fe70 1370 m_gripperVisible = visible;
1154f91b
BW
1371 if (visible)
1372 m_style |= wxAUI_TB_GRIPPER;
e7b8af65
BW
1373 else
1374 m_style &= ~wxAUI_TB_GRIPPER;
1154f91b
BW
1375 Realize();
1376 Refresh(false);
1377}
1378
1379
1380bool wxAuiToolBar::GetOverflowVisible() const
1381{
9a29fe70 1382 return m_overflowVisible;
1154f91b
BW
1383}
1384
1385void wxAuiToolBar::SetOverflowVisible(bool visible)
1386{
9a29fe70 1387 m_overflowVisible = visible;
1154f91b
BW
1388 if (visible)
1389 m_style |= wxAUI_TB_OVERFLOW;
e7b8af65
BW
1390 else
1391 m_style &= ~wxAUI_TB_OVERFLOW;
1154f91b
BW
1392 Refresh(false);
1393}
1394
1395bool wxAuiToolBar::SetFont(const wxFont& font)
1396{
1397 bool res = wxWindow::SetFont(font);
eecf97a5 1398
1154f91b
BW
1399 if (m_art)
1400 {
1401 m_art->SetFont(font);
1402 }
eecf97a5 1403
1154f91b
BW
1404 return res;
1405}
1406
1407
1408void wxAuiToolBar::SetHoverItem(wxAuiToolBarItem* pitem)
1409{
1410 wxAuiToolBarItem* former_hover = NULL;
eecf97a5 1411
1154f91b
BW
1412 size_t i, count;
1413 for (i = 0, count = m_items.GetCount(); i < count; ++i)
1414 {
1415 wxAuiToolBarItem& item = m_items.Item(i);
9a29fe70 1416 if (item.m_state & wxAUI_BUTTON_STATE_HOVER)
1154f91b 1417 former_hover = &item;
9a29fe70 1418 item.m_state &= ~wxAUI_BUTTON_STATE_HOVER;
1154f91b 1419 }
eecf97a5 1420
1154f91b
BW
1421 if (pitem)
1422 {
9a29fe70 1423 pitem->m_state |= wxAUI_BUTTON_STATE_HOVER;
1154f91b 1424 }
eecf97a5 1425
1154f91b
BW
1426 if (former_hover != pitem)
1427 {
1428 Refresh(false);
1429 Update();
1430 }
1431}
1432
1433void wxAuiToolBar::SetPressedItem(wxAuiToolBarItem* pitem)
1434{
1435 wxAuiToolBarItem* former_item = NULL;
eecf97a5 1436
1154f91b
BW
1437 size_t i, count;
1438 for (i = 0, count = m_items.GetCount(); i < count; ++i)
1439 {
1440 wxAuiToolBarItem& item = m_items.Item(i);
9a29fe70 1441 if (item.m_state & wxAUI_BUTTON_STATE_PRESSED)
1154f91b 1442 former_item = &item;
9a29fe70 1443 item.m_state &= ~wxAUI_BUTTON_STATE_PRESSED;
1154f91b 1444 }
eecf97a5 1445
1154f91b
BW
1446 if (pitem)
1447 {
9a29fe70
VZ
1448 pitem->m_state &= ~wxAUI_BUTTON_STATE_HOVER;
1449 pitem->m_state |= wxAUI_BUTTON_STATE_PRESSED;
1154f91b 1450 }
eecf97a5 1451
1154f91b
BW
1452 if (former_item != pitem)
1453 {
1454 Refresh(false);
1455 Update();
1456 }
1457}
1458
1459void wxAuiToolBar::RefreshOverflowState()
1460{
9a29fe70 1461 if (!m_overflowSizerItem)
1154f91b 1462 {
9a29fe70 1463 m_overflowState = 0;
1154f91b
BW
1464 return;
1465 }
eecf97a5 1466
1154f91b 1467 int overflow_state = 0;
eecf97a5 1468
1154f91b
BW
1469 wxRect overflow_rect = GetOverflowRect();
1470
eecf97a5 1471
1154f91b
BW
1472 // find out the mouse's current position
1473 wxPoint pt = ::wxGetMousePosition();
1474 pt = this->ScreenToClient(pt);
eecf97a5 1475
1154f91b
BW
1476 // find out if the mouse cursor is inside the dropdown rectangle
1477 if (overflow_rect.Contains(pt.x, pt.y))
1478 {
45496810 1479 if (::wxGetMouseState().LeftIsDown())
1154f91b 1480 overflow_state = wxAUI_BUTTON_STATE_PRESSED;
8b385bf8 1481 else
1154f91b
BW
1482 overflow_state = wxAUI_BUTTON_STATE_HOVER;
1483 }
eecf97a5 1484
9a29fe70 1485 if (overflow_state != m_overflowState)
1154f91b 1486 {
9a29fe70 1487 m_overflowState = overflow_state;
1154f91b
BW
1488 Refresh(false);
1489 Update();
1490 }
eecf97a5 1491
9a29fe70 1492 m_overflowState = overflow_state;
1154f91b
BW
1493}
1494
1495void wxAuiToolBar::ToggleTool(int tool_id, bool state)
1496{
1497 wxAuiToolBarItem* tool = FindTool(tool_id);
eecf97a5 1498
9a29fe70 1499 if (tool && (tool->m_kind == wxITEM_CHECK || tool->m_kind == wxITEM_RADIO))
1154f91b 1500 {
9a29fe70 1501 if (tool->m_kind == wxITEM_RADIO)
cae51973
BW
1502 {
1503 int i, idx, count;
1504 idx = GetToolIndex(tool_id);
1505 count = (int)m_items.GetCount();
45496810 1506
cae51973
BW
1507 if (idx >= 0 && idx < count)
1508 {
587151f7 1509 for (i = idx + 1; i < count; ++i)
cae51973 1510 {
9a29fe70 1511 if (m_items[i].m_kind != wxITEM_RADIO)
cae51973 1512 break;
9a29fe70 1513 m_items[i].m_state &= ~wxAUI_BUTTON_STATE_CHECKED;
cae51973 1514 }
587151f7 1515 for (i = idx - 1; i >= 0; i--)
cae51973 1516 {
9a29fe70 1517 if (m_items[i].m_kind != wxITEM_RADIO)
cae51973 1518 break;
9a29fe70 1519 m_items[i].m_state &= ~wxAUI_BUTTON_STATE_CHECKED;
cae51973
BW
1520 }
1521 }
45496810 1522
9a29fe70 1523 tool->m_state |= wxAUI_BUTTON_STATE_CHECKED;
cae51973 1524 }
9a29fe70 1525 else if (tool->m_kind == wxITEM_CHECK)
cae51973
BW
1526 {
1527 if (state == true)
9a29fe70 1528 tool->m_state |= wxAUI_BUTTON_STATE_CHECKED;
cae51973 1529 else
9a29fe70 1530 tool->m_state &= ~wxAUI_BUTTON_STATE_CHECKED;
cae51973 1531 }
1154f91b
BW
1532 }
1533}
1534
1535bool wxAuiToolBar::GetToolToggled(int tool_id) const
1536{
1537 wxAuiToolBarItem* tool = FindTool(tool_id);
eecf97a5 1538
1154f91b
BW
1539 if (tool)
1540 {
9a29fe70 1541 if ( (tool->m_kind != wxITEM_CHECK) && (tool->m_kind != wxITEM_RADIO) )
1154f91b 1542 return false;
eecf97a5 1543
9a29fe70 1544 return (tool->m_state & wxAUI_BUTTON_STATE_CHECKED) ? true : false;
1154f91b 1545 }
eecf97a5 1546
1154f91b
BW
1547 return false;
1548}
1549
1550void wxAuiToolBar::EnableTool(int tool_id, bool state)
1551{
1552 wxAuiToolBarItem* tool = FindTool(tool_id);
eecf97a5 1553
1154f91b
BW
1554 if (tool)
1555 {
1556 if (state == true)
9a29fe70 1557 tool->m_state &= ~wxAUI_BUTTON_STATE_DISABLED;
8b385bf8 1558 else
9a29fe70 1559 tool->m_state |= wxAUI_BUTTON_STATE_DISABLED;
1154f91b
BW
1560 }
1561}
1562
1563bool wxAuiToolBar::GetToolEnabled(int tool_id) const
1564{
1565 wxAuiToolBarItem* tool = FindTool(tool_id);
eecf97a5 1566
1154f91b 1567 if (tool)
9a29fe70 1568 return (tool->m_state & wxAUI_BUTTON_STATE_DISABLED) ? false : true;
eecf97a5 1569
1154f91b
BW
1570 return false;
1571}
1572
1573wxString wxAuiToolBar::GetToolLabel(int tool_id) const
1574{
1575 wxAuiToolBarItem* tool = FindTool(tool_id);
1576 wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array"));
1577 if (!tool)
1578 return wxEmptyString;
eecf97a5 1579
9a29fe70 1580 return tool->m_label;
1154f91b
BW
1581}
1582
1583void wxAuiToolBar::SetToolLabel(int tool_id, const wxString& label)
1584{
1585 wxAuiToolBarItem* tool = FindTool(tool_id);
1586 if (tool)
1587 {
9a29fe70 1588 tool->m_label = label;
1154f91b
BW
1589 }
1590}
1591
1592wxBitmap wxAuiToolBar::GetToolBitmap(int tool_id) const
1593{
1594 wxAuiToolBarItem* tool = FindTool(tool_id);
1595 wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array"));
1596 if (!tool)
1597 return wxNullBitmap;
eecf97a5 1598
9a29fe70 1599 return tool->m_bitmap;
1154f91b
BW
1600}
1601
1602void wxAuiToolBar::SetToolBitmap(int tool_id, const wxBitmap& bitmap)
1603{
1604 wxAuiToolBarItem* tool = FindTool(tool_id);
1605 if (tool)
1606 {
9a29fe70 1607 tool->m_bitmap = bitmap;
1154f91b
BW
1608 }
1609}
1610
1611wxString wxAuiToolBar::GetToolShortHelp(int tool_id) const
1612{
1613 wxAuiToolBarItem* tool = FindTool(tool_id);
1614 wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array"));
1615 if (!tool)
1616 return wxEmptyString;
eecf97a5 1617
9a29fe70 1618 return tool->m_shortHelp;
1154f91b
BW
1619}
1620
1621void wxAuiToolBar::SetToolShortHelp(int tool_id, const wxString& help_string)
1622{
1623 wxAuiToolBarItem* tool = FindTool(tool_id);
1624 if (tool)
1625 {
9a29fe70 1626 tool->m_shortHelp = help_string;
1154f91b
BW
1627 }
1628}
1629
1630wxString wxAuiToolBar::GetToolLongHelp(int tool_id) const
1631{
1632 wxAuiToolBarItem* tool = FindTool(tool_id);
1633 wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array"));
1634 if (!tool)
1635 return wxEmptyString;
eecf97a5 1636
9a29fe70 1637 return tool->m_longHelp;
1154f91b
BW
1638}
1639
1640void wxAuiToolBar::SetToolLongHelp(int tool_id, const wxString& help_string)
1641{
1642 wxAuiToolBarItem* tool = FindTool(tool_id);
1643 if (tool)
1644 {
9a29fe70 1645 tool->m_longHelp = help_string;
1154f91b
BW
1646 }
1647}
1648
1649void wxAuiToolBar::SetCustomOverflowItems(const wxAuiToolBarItemArray& prepend,
1650 const wxAuiToolBarItemArray& append)
1651{
9a29fe70
VZ
1652 m_customOverflowPrepend = prepend;
1653 m_customOverflowAppend = append;
1154f91b
BW
1654}
1655
e5dcae09
VZ
1656// get size of hint rectangle for a particular dock location
1657wxSize wxAuiToolBar::GetHintSize(int dock_direction) const
1658{
1659 switch (dock_direction)
1660 {
1661 case wxAUI_DOCK_TOP:
1662 case wxAUI_DOCK_BOTTOM:
1663 return m_horzHintSize;
1664 case wxAUI_DOCK_RIGHT:
1665 case wxAUI_DOCK_LEFT:
1666 return m_vertHintSize;
1667 default:
1668 wxCHECK_MSG(false, wxDefaultSize, "invalid dock location value");
1669 }
1670}
1671
1672bool wxAuiToolBar::IsPaneValid(const wxAuiPaneInfo& pane) const
1673{
1674 return IsPaneValid(m_style, pane);
1675}
1676
1677bool wxAuiToolBar::IsPaneValid(long style, const wxAuiPaneInfo& pane)
1678{
1679 if (style & wxAUI_TB_HORIZONTAL)
1680 {
1681 if (pane.IsLeftDockable() || pane.IsRightDockable())
1682 {
1683 return false;
1684 }
1685 }
1686 else if (style & wxAUI_TB_VERTICAL)
1687 {
1688 if (pane.IsTopDockable() || pane.IsBottomDockable())
1689 {
1690 return false;
1691 }
1692 }
1693 return true;
1694}
1695
1696bool wxAuiToolBar::IsPaneValid(long style) const
1697{
1698 wxAuiManager* manager = wxAuiManager::GetManager(const_cast<wxAuiToolBar*>(this));
1699 if (manager)
1700 {
1701 return IsPaneValid(style, manager->GetPane(const_cast<wxAuiToolBar*>(this)));
1702 }
1703 return true;
1704}
1705
1706void wxAuiToolBar::SetArtFlags() const
1707{
1708 unsigned int artflags = m_style & ~wxAUI_ORIENTATION_MASK;
1709 if (m_orientation == wxVERTICAL)
1710 {
1711 artflags |= wxAUI_TB_VERTICAL;
1712 }
1713 m_art->SetFlags(artflags);
1714}
1154f91b
BW
1715
1716size_t wxAuiToolBar::GetToolCount() const
1717{
1718 return m_items.size();
1719}
1720
1721int wxAuiToolBar::GetToolIndex(int tool_id) const
1722{
1723 // this will prevent us from returning the index of the
1724 // first separator in the toolbar since its id is equal to -1
1725 if (tool_id == -1)
1726 return wxNOT_FOUND;
eecf97a5 1727
1154f91b
BW
1728 size_t i, count = m_items.GetCount();
1729 for (i = 0; i < count; ++i)
1730 {
1731 wxAuiToolBarItem& item = m_items.Item(i);
9a29fe70 1732 if (item.m_toolId == tool_id)
1154f91b
BW
1733 return i;
1734 }
eecf97a5 1735
1154f91b
BW
1736 return wxNOT_FOUND;
1737}
1738
1739bool wxAuiToolBar::GetToolFitsByIndex(int tool_idx) const
1740{
1741 if (tool_idx < 0 || tool_idx >= (int)m_items.GetCount())
1742 return false;
eecf97a5 1743
9a29fe70 1744 if (!m_items[tool_idx].m_sizerItem)
1154f91b 1745 return false;
eecf97a5 1746
1154f91b
BW
1747 int cli_w, cli_h;
1748 GetClientSize(&cli_w, &cli_h);
eecf97a5 1749
9a29fe70 1750 wxRect rect = m_items[tool_idx].m_sizerItem->GetRect();
eecf97a5 1751
e5dcae09 1752 if (m_orientation == wxVERTICAL)
1154f91b
BW
1753 {
1754 // take the dropdown size into account
9a29fe70
VZ
1755 if (m_overflowVisible)
1756 cli_h -= m_overflowSizerItem->GetSize().y;
eecf97a5 1757
1154f91b
BW
1758 if (rect.y+rect.height < cli_h)
1759 return true;
1760 }
8b385bf8 1761 else
1154f91b
BW
1762 {
1763 // take the dropdown size into account
9a29fe70
VZ
1764 if (m_overflowVisible)
1765 cli_w -= m_overflowSizerItem->GetSize().x;
eecf97a5 1766
1154f91b
BW
1767 if (rect.x+rect.width < cli_w)
1768 return true;
1769 }
1770
1771 return false;
1772}
1773
1774
1775bool wxAuiToolBar::GetToolFits(int tool_id) const
1776{
1777 return GetToolFitsByIndex(GetToolIndex(tool_id));
1778}
1779
1780wxRect wxAuiToolBar::GetToolRect(int tool_id) const
1781{
1782 wxAuiToolBarItem* tool = FindTool(tool_id);
9a29fe70 1783 if (tool && tool->m_sizerItem)
1154f91b 1784 {
9a29fe70 1785 return tool->m_sizerItem->GetRect();
1154f91b 1786 }
eecf97a5 1787
1154f91b
BW
1788 return wxRect();
1789}
1790
1791bool wxAuiToolBar::GetToolBarFits() const
1792{
1793 if (m_items.GetCount() == 0)
1794 {
1795 // empty toolbar always 'fits'
1796 return true;
1797 }
eecf97a5 1798
1154f91b
BW
1799 // entire toolbar content fits if the last tool fits
1800 return GetToolFitsByIndex(m_items.GetCount() - 1);
1801}
1802
1803bool wxAuiToolBar::Realize()
1804{
1805 wxClientDC dc(this);
1806 if (!dc.IsOk())
1807 return false;
1808
e5dcae09
VZ
1809 // calculate hint sizes for both horizontal and vertical
1810 // in the order that leaves toolbar in correct final state
1811 bool retval = false;
1812 if (m_orientation == wxHORIZONTAL)
1813 {
1814 if (RealizeHelper(dc, false))
1815 {
1816 m_vertHintSize = GetSize();
1817 if (RealizeHelper(dc, true))
1818 {
1819 m_horzHintSize = GetSize();
1820 retval = true;
1821 }
1822 }
1823 }
1824 else
1825 {
1826 if (RealizeHelper(dc, true))
1827 {
1828 m_horzHintSize = GetSize();
1829 if (RealizeHelper(dc, false))
1830 {
1831 m_vertHintSize = GetSize();
1832 retval = true;
1833 }
1834 }
1835 }
eecf97a5 1836
e5dcae09
VZ
1837 Refresh(false);
1838 return retval;
1839}
eecf97a5 1840
e5dcae09
VZ
1841bool wxAuiToolBar::RealizeHelper(wxClientDC& dc, bool horizontal)
1842{
1154f91b
BW
1843 // create the new sizer to add toolbar elements to
1844 wxBoxSizer* sizer = new wxBoxSizer(horizontal ? wxHORIZONTAL : wxVERTICAL);
eecf97a5 1845
1154f91b 1846 // add gripper area
9a29fe70
VZ
1847 int separatorSize = m_art->GetElementSize(wxAUI_TBART_SEPARATOR_SIZE);
1848 int gripperSize = m_art->GetElementSize(wxAUI_TBART_GRIPPER_SIZE);
1849 if (gripperSize > 0 && m_gripperVisible)
1154f91b
BW
1850 {
1851 if (horizontal)
9a29fe70 1852 m_gripperSizerItem = sizer->Add(gripperSize, 1, 0, wxEXPAND);
8b385bf8 1853 else
9a29fe70 1854 m_gripperSizerItem = sizer->Add(1, gripperSize, 0, wxEXPAND);
1154f91b 1855 }
8b385bf8 1856 else
1154f91b 1857 {
9a29fe70 1858 m_gripperSizerItem = NULL;
1154f91b 1859 }
eecf97a5 1860
1154f91b 1861 // add "left" padding
9a29fe70 1862 if (m_leftPadding > 0)
1154f91b
BW
1863 {
1864 if (horizontal)
9a29fe70 1865 sizer->Add(m_leftPadding, 1);
8b385bf8 1866 else
9a29fe70 1867 sizer->Add(1, m_leftPadding);
1154f91b 1868 }
eecf97a5 1869
1154f91b
BW
1870 size_t i, count;
1871 for (i = 0, count = m_items.GetCount(); i < count; ++i)
1872 {
1873 wxAuiToolBarItem& item = m_items.Item(i);
9a29fe70 1874 wxSizerItem* m_sizerItem = NULL;
eecf97a5 1875
9a29fe70 1876 switch (item.m_kind)
eecf97a5 1877 {
1154f91b
BW
1878 case wxITEM_LABEL:
1879 {
1880 wxSize size = m_art->GetLabelSize(dc, this, item);
9a29fe70
VZ
1881 m_sizerItem = sizer->Add(size.x + (m_toolBorderPadding*2),
1882 size.y + (m_toolBorderPadding*2),
1883 item.m_proportion,
1884 item.m_alignment);
1154f91b
BW
1885 if (i+1 < count)
1886 {
9a29fe70 1887 sizer->AddSpacer(m_toolPacking);
1154f91b 1888 }
eecf97a5 1889
1154f91b
BW
1890 break;
1891 }
eecf97a5 1892
1154f91b
BW
1893 case wxITEM_CHECK:
1894 case wxITEM_NORMAL:
cae51973 1895 case wxITEM_RADIO:
1154f91b
BW
1896 {
1897 wxSize size = m_art->GetToolSize(dc, this, item);
9a29fe70
VZ
1898 m_sizerItem = sizer->Add(size.x + (m_toolBorderPadding*2),
1899 size.y + (m_toolBorderPadding*2),
1154f91b 1900 0,
9a29fe70 1901 item.m_alignment);
1154f91b
BW
1902 // add tool packing
1903 if (i+1 < count)
1904 {
9a29fe70 1905 sizer->AddSpacer(m_toolPacking);
1154f91b 1906 }
eecf97a5 1907
1154f91b
BW
1908 break;
1909 }
eecf97a5 1910
1154f91b
BW
1911 case wxITEM_SEPARATOR:
1912 {
1913 if (horizontal)
9a29fe70 1914 m_sizerItem = sizer->Add(separatorSize, 1, 0, wxEXPAND);
8b385bf8 1915 else
9a29fe70 1916 m_sizerItem = sizer->Add(1, separatorSize, 0, wxEXPAND);
1154f91b
BW
1917
1918 // add tool packing
1919 if (i+1 < count)
1920 {
9a29fe70 1921 sizer->AddSpacer(m_toolPacking);
1154f91b 1922 }
eecf97a5 1923
1154f91b
BW
1924 break;
1925 }
eecf97a5 1926
1154f91b 1927 case wxITEM_SPACER:
9a29fe70
VZ
1928 if (item.m_proportion > 0)
1929 m_sizerItem = sizer->AddStretchSpacer(item.m_proportion);
8b385bf8 1930 else
9a29fe70 1931 m_sizerItem = sizer->Add(item.m_spacerPixels, 1);
1154f91b 1932 break;
eecf97a5 1933
1154f91b
BW
1934 case wxITEM_CONTROL:
1935 {
9a29fe70
VZ
1936 //m_sizerItem = sizer->Add(item.m_window, item.m_proportion, wxEXPAND);
1937 wxSizerItem* ctrl_m_sizerItem;
eecf97a5 1938
1154f91b
BW
1939 wxBoxSizer* vert_sizer = new wxBoxSizer(wxVERTICAL);
1940 vert_sizer->AddStretchSpacer(1);
9a29fe70 1941 ctrl_m_sizerItem = vert_sizer->Add(item.m_window, 0, wxEXPAND);
1154f91b 1942 vert_sizer->AddStretchSpacer(1);
23511cdb 1943 if ( (m_style & wxAUI_TB_TEXT) &&
9a29fe70 1944 m_toolTextOrientation == wxAUI_TBTOOL_TEXT_BOTTOM &&
23511cdb 1945 !item.GetLabel().empty() )
1154f91b 1946 {
e42f2c16 1947 wxSize s = GetLabelSize(item.GetLabel());
1154f91b
BW
1948 vert_sizer->Add(1, s.y);
1949 }
eecf97a5
VZ
1950
1951
9a29fe70 1952 m_sizerItem = sizer->Add(vert_sizer, item.m_proportion, wxEXPAND);
eecf97a5 1953
9a29fe70 1954 wxSize min_size = item.m_minSize;
eecf97a5 1955
1154f91b
BW
1956
1957 // proportional items will disappear from the toolbar if
1958 // their min width is not set to something really small
9a29fe70 1959 if (item.m_proportion != 0)
1154f91b
BW
1960 {
1961 min_size.x = 1;
1962 }
eecf97a5 1963
1154f91b
BW
1964 if (min_size.IsFullySpecified())
1965 {
9a29fe70
VZ
1966 m_sizerItem->SetMinSize(min_size);
1967 ctrl_m_sizerItem->SetMinSize(min_size);
1154f91b
BW
1968 }
1969
1970 // add tool packing
1971 if (i+1 < count)
1972 {
9a29fe70 1973 sizer->AddSpacer(m_toolPacking);
1154f91b
BW
1974 }
1975 }
1976 }
eecf97a5 1977
9a29fe70 1978 item.m_sizerItem = m_sizerItem;
1154f91b
BW
1979 }
1980
1981 // add "right" padding
9a29fe70 1982 if (m_rightPadding > 0)
1154f91b
BW
1983 {
1984 if (horizontal)
9a29fe70 1985 sizer->Add(m_rightPadding, 1);
8b385bf8 1986 else
9a29fe70 1987 sizer->Add(1, m_rightPadding);
1154f91b 1988 }
eecf97a5 1989
1154f91b 1990 // add drop down area
9a29fe70 1991 m_overflowSizerItem = NULL;
eecf97a5 1992
1154f91b
BW
1993 if (m_style & wxAUI_TB_OVERFLOW)
1994 {
1995 int overflow_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
9a29fe70 1996 if (overflow_size > 0 && m_overflowVisible)
1154f91b
BW
1997 {
1998 if (horizontal)
9a29fe70 1999 m_overflowSizerItem = sizer->Add(overflow_size, 1, 0, wxEXPAND);
8b385bf8 2000 else
9a29fe70 2001 m_overflowSizerItem = sizer->Add(1, overflow_size, 0, wxEXPAND);
1154f91b 2002 }
8b385bf8 2003 else
1154f91b 2004 {
9a29fe70 2005 m_overflowSizerItem = NULL;
1154f91b
BW
2006 }
2007 }
eecf97a5 2008
1154f91b
BW
2009
2010 // the outside sizer helps us apply the "top" and "bottom" padding
2011 wxBoxSizer* outside_sizer = new wxBoxSizer(horizontal ? wxVERTICAL : wxHORIZONTAL);
eecf97a5 2012
1154f91b 2013 // add "top" padding
9a29fe70 2014 if (m_topPadding > 0)
1154f91b
BW
2015 {
2016 if (horizontal)
9a29fe70 2017 outside_sizer->Add(1, m_topPadding);
8b385bf8 2018 else
9a29fe70 2019 outside_sizer->Add(m_topPadding, 1);
1154f91b
BW
2020 }
2021
2022 // add the sizer that contains all of the toolbar elements
2023 outside_sizer->Add(sizer, 1, wxEXPAND);
eecf97a5 2024
1154f91b 2025 // add "bottom" padding
9a29fe70 2026 if (m_bottomPadding > 0)
1154f91b
BW
2027 {
2028 if (horizontal)
9a29fe70 2029 outside_sizer->Add(1, m_bottomPadding);
8b385bf8 2030 else
9a29fe70 2031 outside_sizer->Add(m_bottomPadding, 1);
1154f91b 2032 }
eecf97a5 2033
1154f91b
BW
2034 delete m_sizer; // remove old sizer
2035 m_sizer = outside_sizer;
eecf97a5 2036
1154f91b
BW
2037 // calculate the rock-bottom minimum size
2038 for (i = 0, count = m_items.GetCount(); i < count; ++i)
2039 {
2040 wxAuiToolBarItem& item = m_items.Item(i);
9a29fe70
VZ
2041 if (item.m_sizerItem && item.m_proportion > 0 && item.m_minSize.IsFullySpecified())
2042 item.m_sizerItem->SetMinSize(0,0);
1154f91b 2043 }
eecf97a5 2044
9a29fe70 2045 m_absoluteMinSize = m_sizer->GetMinSize();
eecf97a5 2046
1154f91b
BW
2047 // reset the min sizes to what they were
2048 for (i = 0, count = m_items.GetCount(); i < count; ++i)
2049 {
2050 wxAuiToolBarItem& item = m_items.Item(i);
9a29fe70
VZ
2051 if (item.m_sizerItem && item.m_proportion > 0 && item.m_minSize.IsFullySpecified())
2052 item.m_sizerItem->SetMinSize(item.m_minSize);
eecf97a5 2053 }
1154f91b
BW
2054
2055 // set control size
2056 wxSize size = m_sizer->GetMinSize();
2057 m_minWidth = size.x;
2058 m_minHeight = size.y;
eecf97a5 2059
1154f91b
BW
2060 if ((m_style & wxAUI_TB_NO_AUTORESIZE) == 0)
2061 {
9a29fe70 2062 wxSize curSize = GetClientSize();
1154f91b 2063 wxSize new_size = GetMinSize();
9a29fe70 2064 if (new_size != curSize)
1154f91b
BW
2065 {
2066 SetClientSize(new_size);
2067 }
8b385bf8 2068 else
1154f91b 2069 {
9a29fe70 2070 m_sizer->SetDimension(0, 0, curSize.x, curSize.y);
1154f91b 2071 }
eecf97a5 2072 }
8b385bf8 2073 else
1154f91b 2074 {
9a29fe70
VZ
2075 wxSize curSize = GetClientSize();
2076 m_sizer->SetDimension(0, 0, curSize.x, curSize.y);
1154f91b 2077 }
eecf97a5 2078
1154f91b
BW
2079 return true;
2080}
2081
2082int wxAuiToolBar::GetOverflowState() const
2083{
9a29fe70 2084 return m_overflowState;
1154f91b
BW
2085}
2086
2087wxRect wxAuiToolBar::GetOverflowRect() const
eecf97a5 2088{
1154f91b 2089 wxRect cli_rect(wxPoint(0,0), GetClientSize());
9a29fe70 2090 wxRect overflow_rect = m_overflowSizerItem->GetRect();
1154f91b
BW
2091 int overflow_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
2092
e5dcae09 2093 if (m_orientation == wxVERTICAL)
1154f91b
BW
2094 {
2095 overflow_rect.y = cli_rect.height - overflow_size;
2096 overflow_rect.x = 0;
2097 overflow_rect.width = cli_rect.width;
2098 overflow_rect.height = overflow_size;
2099 }
8b385bf8 2100 else
1154f91b
BW
2101 {
2102 overflow_rect.x = cli_rect.width - overflow_size;
2103 overflow_rect.y = 0;
2104 overflow_rect.width = overflow_size;
2105 overflow_rect.height = cli_rect.height;
2106 }
eecf97a5 2107
1154f91b
BW
2108 return overflow_rect;
2109}
2110
2111wxSize wxAuiToolBar::GetLabelSize(const wxString& label)
2112{
2113 wxClientDC dc(this);
eecf97a5 2114
1154f91b 2115 int tx, ty;
9a29fe70 2116 int textWidth = 0, textHeight = 0;
1154f91b
BW
2117
2118 dc.SetFont(m_font);
eecf97a5 2119
1154f91b 2120 // get the text height
9a29fe70 2121 dc.GetTextExtent(wxT("ABCDHgj"), &tx, &textHeight);
1154f91b
BW
2122
2123 // get the text width
9a29fe70 2124 dc.GetTextExtent(label, &textWidth, &ty);
1154f91b 2125
9a29fe70 2126 return wxSize(textWidth, textHeight);
1154f91b
BW
2127}
2128
2129
2130void wxAuiToolBar::DoIdleUpdate()
2131{
2132 wxEvtHandler* handler = GetEventHandler();
2133
2134 bool need_refresh = false;
2135
2136 size_t i, count;
2137 for (i = 0, count = m_items.GetCount(); i < count; ++i)
2138 {
2139 wxAuiToolBarItem& item = m_items.Item(i);
eecf97a5 2140
9a29fe70 2141 if (item.m_toolId == -1)
1154f91b 2142 continue;
eecf97a5 2143
9a29fe70 2144 wxUpdateUIEvent evt(item.m_toolId);
1154f91b
BW
2145 evt.SetEventObject(this);
2146
2147 if (handler->ProcessEvent(evt))
2148 {
2149 if (evt.GetSetEnabled())
2150 {
2151 bool is_enabled;
9a29fe70
VZ
2152 if (item.m_window)
2153 is_enabled = item.m_window->IsEnabled();
8b385bf8 2154 else
9a29fe70 2155 is_enabled = (item.m_state & wxAUI_BUTTON_STATE_DISABLED) ? false : true;
eecf97a5 2156
1154f91b
BW
2157 bool new_enabled = evt.GetEnabled();
2158 if (new_enabled != is_enabled)
2159 {
9a29fe70 2160 if (item.m_window)
1154f91b 2161 {
9a29fe70 2162 item.m_window->Enable(new_enabled);
1154f91b 2163 }
8b385bf8 2164 else
1154f91b
BW
2165 {
2166 if (new_enabled)
9a29fe70 2167 item.m_state &= ~wxAUI_BUTTON_STATE_DISABLED;
8b385bf8 2168 else
9a29fe70 2169 item.m_state |= wxAUI_BUTTON_STATE_DISABLED;
1154f91b
BW
2170 }
2171 need_refresh = true;
2172 }
2173 }
eecf97a5 2174
1154f91b
BW
2175 if (evt.GetSetChecked())
2176 {
2177 // make sure we aren't checking an item that can't be
9a29fe70 2178 if (item.m_kind != wxITEM_CHECK && item.m_kind != wxITEM_RADIO)
1154f91b
BW
2179 continue;
2180
9a29fe70 2181 bool is_checked = (item.m_state & wxAUI_BUTTON_STATE_CHECKED) ? true : false;
1154f91b
BW
2182 bool new_checked = evt.GetChecked();
2183
2184 if (new_checked != is_checked)
2185 {
2186 if (new_checked)
9a29fe70 2187 item.m_state |= wxAUI_BUTTON_STATE_CHECKED;
8b385bf8 2188 else
9a29fe70 2189 item.m_state &= ~wxAUI_BUTTON_STATE_CHECKED;
eecf97a5 2190
1154f91b
BW
2191 need_refresh = true;
2192 }
2193 }
2194
2195 }
2196 }
eecf97a5 2197
1154f91b
BW
2198
2199 if (need_refresh)
2200 {
2201 Refresh(false);
2202 }
2203}
2204
2205
2206void wxAuiToolBar::OnSize(wxSizeEvent& WXUNUSED(evt))
2207{
2208 int x, y;
2209 GetClientSize(&x, &y);
2210
9a29fe70
VZ
2211 if (((x >= y) && m_absoluteMinSize.x > x) ||
2212 ((y > x) && m_absoluteMinSize.y > y))
1154f91b
BW
2213 {
2214 // hide all flexible items
2215 size_t i, count;
2216 for (i = 0, count = m_items.GetCount(); i < count; ++i)
2217 {
2218 wxAuiToolBarItem& item = m_items.Item(i);
9a29fe70 2219 if (item.m_sizerItem && item.m_proportion > 0 && item.m_sizerItem->IsShown())
1154f91b 2220 {
9a29fe70
VZ
2221 item.m_sizerItem->Show(false);
2222 item.m_sizerItem->SetProportion(0);
1154f91b
BW
2223 }
2224 }
2225 }
8b385bf8 2226 else
1154f91b
BW
2227 {
2228 // show all flexible items
2229 size_t i, count;
2230 for (i = 0, count = m_items.GetCount(); i < count; ++i)
2231 {
2232 wxAuiToolBarItem& item = m_items.Item(i);
9a29fe70 2233 if (item.m_sizerItem && item.m_proportion > 0 && !item.m_sizerItem->IsShown())
1154f91b 2234 {
9a29fe70
VZ
2235 item.m_sizerItem->Show(true);
2236 item.m_sizerItem->SetProportion(item.m_proportion);
1154f91b
BW
2237 }
2238 }
2239 }
2240
2241 m_sizer->SetDimension(0, 0, x, y);
2242
2243 Refresh(false);
2244 Update();
e5dcae09
VZ
2245
2246 // idle events aren't sent while user is resizing frame (why?),
2247 // but resizing toolbar here causes havoc,
2248 // so force idle handler to run after size handling complete
2249 QueueEvent(new wxIdleEvent);
1154f91b
BW
2250}
2251
2252
2253
2254void wxAuiToolBar::DoSetSize(int x,
2255 int y,
2256 int width,
2257 int height,
2258 int sizeFlags)
2259{
2260 wxSize parent_size = GetParent()->GetClientSize();
2261 if (x + width > parent_size.x)
2262 width = wxMax(0, parent_size.x - x);
2263 if (y + height > parent_size.y)
2264 height = wxMax(0, parent_size.y - y);
2265
2266 wxWindow::DoSetSize(x, y, width, height, sizeFlags);
2267}
2268
2269
2270void wxAuiToolBar::OnIdle(wxIdleEvent& evt)
2271{
e5dcae09
VZ
2272 // if orientation doesn't match dock, fix it
2273 wxAuiManager* manager = wxAuiManager::GetManager(this);
2274 if (manager)
2275 {
2276 wxAuiPaneInfo& pane = manager->GetPane(this);
2277 // pane state member is public, so it might have been changed
2278 // without going through wxPaneInfo::SetFlag() check
2279 bool ok = pane.IsOk();
2280 wxCHECK2_MSG(!ok || IsPaneValid(m_style, pane), ok = false,
2281 "window settings and pane settings are incompatible");
2282 if (ok)
2283 {
2284 wxOrientation newOrientation = m_orientation;
2285 if (pane.IsDocked())
2286 {
2287 switch (pane.dock_direction)
2288 {
2289 case wxAUI_DOCK_TOP:
2290 case wxAUI_DOCK_BOTTOM:
2291 newOrientation = wxHORIZONTAL;
2292 break;
2293 case wxAUI_DOCK_LEFT:
2294 case wxAUI_DOCK_RIGHT:
2295 newOrientation = wxVERTICAL;
2296 break;
2297 default:
2298 wxFAIL_MSG("invalid dock location value");
2299 }
2300 }
2301 else if (pane.IsResizable() &&
2302 GetOrientation(m_style) == wxBOTH)
2303 {
2304 // changing orientation in OnSize causes havoc
2305 int x, y;
2306 GetClientSize(&x, &y);
2307
2308 if (x > y)
2309 {
2310 newOrientation = wxHORIZONTAL;
2311 }
2312 else
2313 {
2314 newOrientation = wxVERTICAL;
2315 }
2316 }
2317 if (newOrientation != m_orientation)
2318 {
2319 SetOrientation(newOrientation);
2320 Realize();
2321 if (newOrientation == wxHORIZONTAL)
2322 {
2323 pane.best_size = GetHintSize(wxAUI_DOCK_TOP);
2324 }
2325 else
2326 {
2327 pane.best_size = GetHintSize(wxAUI_DOCK_LEFT);
2328 }
2329 if (pane.IsDocked())
2330 {
2331 pane.floating_size = wxDefaultSize;
2332 }
2333 else
2334 {
2335 SetSize(GetParent()->GetClientSize());
2336 }
2337 manager->Update();
2338 }
2339 }
2340 }
1154f91b
BW
2341 evt.Skip();
2342}
2343
3ac17397
VZ
2344void wxAuiToolBar::UpdateWindowUI(long flags)
2345{
2346 if ( flags & wxUPDATE_UI_FROMIDLE )
2347 {
2348 DoIdleUpdate();
2349 }
2350
2351 wxControl::UpdateWindowUI(flags);
2352}
2353
1154f91b
BW
2354void wxAuiToolBar::OnPaint(wxPaintEvent& WXUNUSED(evt))
2355{
66ad3095 2356 wxAutoBufferedPaintDC dc(this);
1154f91b 2357 wxRect cli_rect(wxPoint(0,0), GetClientSize());
eecf97a5
VZ
2358
2359
e5dcae09 2360 bool horizontal = m_orientation == wxHORIZONTAL;
1154f91b
BW
2361
2362
2363 m_art->DrawBackground(dc, this, cli_rect);
eecf97a5 2364
9a29fe70 2365 int gripperSize = m_art->GetElementSize(wxAUI_TBART_GRIPPER_SIZE);
1154f91b 2366 int dropdown_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
eecf97a5 2367
1154f91b 2368 // paint the gripper
9a29fe70 2369 if (gripperSize > 0 && m_gripperSizerItem)
1154f91b 2370 {
9a29fe70 2371 wxRect gripper_rect = m_gripperSizerItem->GetRect();
1154f91b 2372 if (horizontal)
9a29fe70 2373 gripper_rect.width = gripperSize;
8b385bf8 2374 else
9a29fe70 2375 gripper_rect.height = gripperSize;
1154f91b
BW
2376 m_art->DrawGripper(dc, this, gripper_rect);
2377 }
eecf97a5 2378
1154f91b
BW
2379 // calculated how far we can draw items
2380 int last_extent;
2381 if (horizontal)
2382 last_extent = cli_rect.width;
8b385bf8 2383 else
1154f91b 2384 last_extent = cli_rect.height;
9a29fe70 2385 if (m_overflowVisible)
1154f91b 2386 last_extent -= dropdown_size;
eecf97a5 2387
1154f91b
BW
2388 // paint each individual tool
2389 size_t i, count = m_items.GetCount();
2390 for (i = 0; i < count; ++i)
2391 {
2392 wxAuiToolBarItem& item = m_items.Item(i);
eecf97a5 2393
9a29fe70 2394 if (!item.m_sizerItem)
1154f91b 2395 continue;
eecf97a5 2396
9a29fe70 2397 wxRect item_rect = item.m_sizerItem->GetRect();
eecf97a5
VZ
2398
2399
1154f91b
BW
2400 if ((horizontal && item_rect.x + item_rect.width >= last_extent) ||
2401 (!horizontal && item_rect.y + item_rect.height >= last_extent))
2402 {
2403 break;
2404 }
eecf97a5 2405
9a29fe70 2406 if (item.m_kind == wxITEM_SEPARATOR)
1154f91b
BW
2407 {
2408 // draw a separator
2409 m_art->DrawSeparator(dc, this, item_rect);
2410 }
9a29fe70 2411 else if (item.m_kind == wxITEM_LABEL)
1154f91b
BW
2412 {
2413 // draw a text label only
2414 m_art->DrawLabel(dc, this, item, item_rect);
2415 }
9a29fe70 2416 else if (item.m_kind == wxITEM_NORMAL)
1154f91b
BW
2417 {
2418 // draw a regular button or dropdown button
9a29fe70 2419 if (!item.m_dropDown)
1154f91b 2420 m_art->DrawButton(dc, this, item, item_rect);
8b385bf8 2421 else
1154f91b
BW
2422 m_art->DrawDropDownButton(dc, this, item, item_rect);
2423 }
9a29fe70 2424 else if (item.m_kind == wxITEM_CHECK)
1154f91b 2425 {
026c6eff 2426 // draw either a regular or dropdown toggle button
9a29fe70 2427 if (!item.m_dropDown)
026c6eff
VZ
2428 m_art->DrawButton(dc, this, item, item_rect);
2429 else
2430 m_art->DrawDropDownButton(dc, this, item, item_rect);
1154f91b 2431 }
9a29fe70 2432 else if (item.m_kind == wxITEM_RADIO)
cae51973
BW
2433 {
2434 // draw a toggle button
2435 m_art->DrawButton(dc, this, item, item_rect);
2436 }
9a29fe70 2437 else if (item.m_kind == wxITEM_CONTROL)
1154f91b
BW
2438 {
2439 // draw the control's label
2440 m_art->DrawControlLabel(dc, this, item, item_rect);
2441 }
2442
2443 // fire a signal to see if the item wants to be custom-rendered
2444 OnCustomRender(dc, item, item_rect);
2445 }
eecf97a5 2446
1154f91b 2447 // paint the overflow button
9a29fe70 2448 if (dropdown_size > 0 && m_overflowSizerItem)
1154f91b 2449 {
9a29fe70
VZ
2450 wxRect dropDownRect = GetOverflowRect();
2451 m_art->DrawOverflowButton(dc, this, dropDownRect, m_overflowState);
1154f91b
BW
2452 }
2453}
2454
2455void wxAuiToolBar::OnEraseBackground(wxEraseEvent& WXUNUSED(evt))
2456{
2457 // empty
2458}
2459
2460void wxAuiToolBar::OnLeftDown(wxMouseEvent& evt)
2461{
2462 wxRect cli_rect(wxPoint(0,0), GetClientSize());
eecf97a5 2463
9a29fe70 2464 if (m_gripperSizerItem)
1154f91b 2465 {
9a29fe70 2466 wxRect gripper_rect = m_gripperSizerItem->GetRect();
1154f91b
BW
2467 if (gripper_rect.Contains(evt.GetX(), evt.GetY()))
2468 {
2469 // find aui manager
2470 wxAuiManager* manager = wxAuiManager::GetManager(this);
2471 if (!manager)
2472 return;
eecf97a5 2473
1154f91b
BW
2474 int x_drag_offset = evt.GetX() - gripper_rect.GetX();
2475 int y_drag_offset = evt.GetY() - gripper_rect.GetY();
eecf97a5 2476
1154f91b
BW
2477 // gripper was clicked
2478 manager->StartPaneDrag(this, wxPoint(x_drag_offset, y_drag_offset));
2479 return;
2480 }
2481 }
eecf97a5 2482
9a29fe70 2483 if (m_overflowSizerItem)
1154f91b
BW
2484 {
2485 wxRect overflow_rect = GetOverflowRect();
eecf97a5
VZ
2486
2487 if (m_art &&
9a29fe70 2488 m_overflowVisible &&
1154f91b
BW
2489 overflow_rect.Contains(evt.m_x, evt.m_y))
2490 {
2491 wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_OVERFLOW_CLICK, -1);
2492 e.SetEventObject(this);
2493 e.SetToolId(-1);
2494 e.SetClickPoint(wxPoint(evt.GetX(), evt.GetY()));
004867db 2495 bool processed = GetEventHandler()->ProcessEvent(e);
eecf97a5 2496
1154f91b
BW
2497 if (processed)
2498 {
2499 DoIdleUpdate();
2500 }
8b385bf8 2501 else
1154f91b
BW
2502 {
2503 size_t i, count;
2504 wxAuiToolBarItemArray overflow_items;
eecf97a5 2505
1154f91b
BW
2506
2507 // add custom overflow prepend items, if any
9a29fe70 2508 count = m_customOverflowPrepend.GetCount();
1154f91b 2509 for (i = 0; i < count; ++i)
9a29fe70 2510 overflow_items.Add(m_customOverflowPrepend[i]);
eecf97a5 2511
1154f91b
BW
2512 // only show items that don't fit in the dropdown
2513 count = m_items.GetCount();
2514 for (i = 0; i < count; ++i)
2515 {
2516 if (!GetToolFitsByIndex(i))
2517 overflow_items.Add(m_items[i]);
2518 }
2519
2520 // add custom overflow append items, if any
9a29fe70 2521 count = m_customOverflowAppend.GetCount();
1154f91b 2522 for (i = 0; i < count; ++i)
9a29fe70 2523 overflow_items.Add(m_customOverflowAppend[i]);
eecf97a5 2524
1154f91b 2525 int res = m_art->ShowDropDown(this, overflow_items);
9a29fe70 2526 m_overflowState = 0;
1154f91b
BW
2527 Refresh(false);
2528 if (res != -1)
2529 {
2530 wxCommandEvent e(wxEVT_COMMAND_MENU_SELECTED, res);
2531 e.SetEventObject(this);
004867db 2532 GetParent()->GetEventHandler()->ProcessEvent(e);
1154f91b
BW
2533 }
2534 }
eecf97a5 2535
1154f91b
BW
2536 return;
2537 }
2538 }
eecf97a5 2539
1154f91b 2540 m_dragging = false;
9a29fe70
VZ
2541 m_actionPos = wxPoint(evt.GetX(), evt.GetY());
2542 m_actionItem = FindToolByPosition(evt.GetX(), evt.GetY());
eecf97a5 2543
9a29fe70 2544 if (m_actionItem)
1154f91b 2545 {
9a29fe70 2546 if (m_actionItem->m_state & wxAUI_BUTTON_STATE_DISABLED)
1154f91b 2547 {
9a29fe70
VZ
2548 m_actionPos = wxPoint(-1,-1);
2549 m_actionItem = NULL;
1154f91b
BW
2550 return;
2551 }
eecf97a5 2552
4a21ea9d 2553 UnsetToolTip();
eecf97a5 2554
1154f91b 2555 // fire the tool dropdown event
9a29fe70 2556 wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_TOOL_DROPDOWN, m_actionItem->m_toolId);
1154f91b 2557 e.SetEventObject(this);
9a29fe70 2558 e.SetToolId(m_actionItem->m_toolId);
eecf97a5 2559
1154f91b 2560 int mouse_x = evt.GetX();
9a29fe70
VZ
2561 wxRect rect = m_actionItem->m_sizerItem->GetRect();
2562 const bool dropDownHit = m_actionItem->m_dropDown &&
4a21ea9d
VZ
2563 mouse_x >= (rect.x+rect.width-BUTTON_DROPDOWN_WIDTH-1) &&
2564 mouse_x < (rect.x+rect.width);
2565 e.SetDropDownClicked(dropDownHit);
2566
2567 e.SetClickPoint(evt.GetPosition());
2568 e.SetItemRect(rect);
2569
2570 // we only set the 'pressed button' state if we hit the actual button
2571 // and not just the drop-down
9a29fe70 2572 SetPressedItem(dropDownHit ? 0 : m_actionItem);
eecf97a5 2573
4a21ea9d 2574 if(dropDownHit)
1154f91b 2575 {
9a29fe70
VZ
2576 m_actionPos = wxPoint(-1,-1);
2577 m_actionItem = NULL;
1154f91b 2578 }
eecf97a5 2579
4a21ea9d
VZ
2580 if(!GetEventHandler()->ProcessEvent(e) || e.GetSkipped())
2581 CaptureMouse();
2582
1154f91b
BW
2583 DoIdleUpdate();
2584 }
2585}
2586
2587void wxAuiToolBar::OnLeftUp(wxMouseEvent& evt)
2588{
4a21ea9d
VZ
2589 if (!HasCapture())
2590 return;
2591
1154f91b
BW
2592 SetPressedItem(NULL);
2593
9a29fe70
VZ
2594 wxAuiToolBarItem* hitItem = FindToolByPosition(evt.GetX(), evt.GetY());
2595 if (hitItem && !(hitItem->m_state & wxAUI_BUTTON_STATE_DISABLED))
1154f91b 2596 {
9a29fe70 2597 SetHoverItem(hitItem);
1154f91b
BW
2598 }
2599
1154f91b
BW
2600 if (m_dragging)
2601 {
4a21ea9d
VZ
2602 // TODO: it would make sense to send out an 'END_DRAG' event here,
2603 // otherwise a client would never know what to do with the 'BEGIN_DRAG'
2604 // event
2605
2606 // OnCaptureLost() will be called now and this will reset all our state
2607 // tracking variables
2608 ReleaseMouse();
1154f91b 2609 }
8b385bf8 2610 else
1154f91b 2611 {
9a29fe70 2612 if (m_actionItem && hitItem == m_actionItem)
1154f91b 2613 {
8b385bf8 2614 UnsetToolTip();
eecf97a5 2615
9a29fe70 2616 wxCommandEvent e(wxEVT_COMMAND_MENU_SELECTED, m_actionItem->m_toolId);
4a21ea9d
VZ
2617 e.SetEventObject(this);
2618
9a29fe70 2619 if (hitItem->m_kind == wxITEM_CHECK || hitItem->m_kind == wxITEM_RADIO)
1154f91b 2620 {
9a29fe70 2621 const bool toggle = !(m_actionItem->m_state & wxAUI_BUTTON_STATE_CHECKED);
eecf97a5 2622
9a29fe70 2623 ToggleTool(m_actionItem->m_toolId, toggle);
45496810 2624
cae51973
BW
2625 // repaint immediately
2626 Refresh(false);
2627 Update();
45496810 2628
4a21ea9d 2629 e.SetInt(toggle);
1154f91b 2630 }
4a21ea9d
VZ
2631
2632 // we have to release the mouse *before* sending the event, because
2633 // we don't know what a handler might do. It could open up a popup
2634 // menu for example and that would make us lose our capture anyway.
2635
2636 ReleaseMouse();
2637
2638 GetEventHandler()->ProcessEvent(e);
2639 DoIdleUpdate();
1154f91b 2640 }
4a21ea9d
VZ
2641 else
2642 ReleaseMouse();
1154f91b 2643 }
1154f91b
BW
2644}
2645
2646void wxAuiToolBar::OnRightDown(wxMouseEvent& evt)
2647{
2648 wxRect cli_rect(wxPoint(0,0), GetClientSize());
eecf97a5 2649
9a29fe70 2650 if (m_gripperSizerItem)
1154f91b 2651 {
9a29fe70 2652 wxRect gripper_rect = m_gripperSizerItem->GetRect();
1154f91b
BW
2653 if (gripper_rect.Contains(evt.GetX(), evt.GetY()))
2654 return;
2655 }
eecf97a5 2656
9a29fe70 2657 if (m_overflowSizerItem)
1154f91b
BW
2658 {
2659 int dropdown_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
2660 if (dropdown_size > 0 &&
2661 evt.m_x > cli_rect.width - dropdown_size &&
2662 evt.m_y >= 0 &&
2663 evt.m_y < cli_rect.height &&
2664 m_art)
2665 {
2666 return;
2667 }
2668 }
eecf97a5 2669
9a29fe70
VZ
2670 m_actionPos = wxPoint(evt.GetX(), evt.GetY());
2671 m_actionItem = FindToolByPosition(evt.GetX(), evt.GetY());
eecf97a5 2672
9a29fe70 2673 if (m_actionItem && m_actionItem->m_state & wxAUI_BUTTON_STATE_DISABLED)
1154f91b 2674 {
9a29fe70
VZ
2675 m_actionPos = wxPoint(-1,-1);
2676 m_actionItem = NULL;
4a21ea9d 2677 return;
1154f91b 2678 }
4a21ea9d
VZ
2679
2680 UnsetToolTip();
1154f91b
BW
2681}
2682
2683void wxAuiToolBar::OnRightUp(wxMouseEvent& evt)
2684{
9a29fe70
VZ
2685 wxAuiToolBarItem* hitItem;
2686 hitItem = FindToolByPosition(evt.GetX(), evt.GetY());
eecf97a5 2687
9a29fe70 2688 if (m_actionItem && hitItem == m_actionItem)
1154f91b 2689 {
f5fccd52
VZ
2690 wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_RIGHT_CLICK, m_actionItem->m_toolId);
2691 e.SetEventObject(this);
2692 e.SetToolId(m_actionItem->m_toolId);
2693 e.SetClickPoint(m_actionPos);
2694 GetEventHandler()->ProcessEvent(e);
2695 DoIdleUpdate();
1154f91b 2696 }
8b385bf8 2697 else
1154f91b
BW
2698 {
2699 // right-clicked on the invalid area of the toolbar
2700 wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_RIGHT_CLICK, -1);
2701 e.SetEventObject(this);
2702 e.SetToolId(-1);
9a29fe70 2703 e.SetClickPoint(m_actionPos);
004867db 2704 GetEventHandler()->ProcessEvent(e);
1154f91b
BW
2705 DoIdleUpdate();
2706 }
2707
2708 // reset member variables
9a29fe70
VZ
2709 m_actionPos = wxPoint(-1,-1);
2710 m_actionItem = NULL;
1154f91b
BW
2711}
2712
2713void wxAuiToolBar::OnMiddleDown(wxMouseEvent& evt)
2714{
2715 wxRect cli_rect(wxPoint(0,0), GetClientSize());
eecf97a5 2716
9a29fe70 2717 if (m_gripperSizerItem)
1154f91b 2718 {
9a29fe70 2719 wxRect gripper_rect = m_gripperSizerItem->GetRect();
1154f91b
BW
2720 if (gripper_rect.Contains(evt.GetX(), evt.GetY()))
2721 return;
2722 }
eecf97a5 2723
9a29fe70 2724 if (m_overflowSizerItem)
1154f91b
BW
2725 {
2726 int dropdown_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
2727 if (dropdown_size > 0 &&
2728 evt.m_x > cli_rect.width - dropdown_size &&
2729 evt.m_y >= 0 &&
2730 evt.m_y < cli_rect.height &&
2731 m_art)
2732 {
2733 return;
2734 }
2735 }
eecf97a5 2736
9a29fe70
VZ
2737 m_actionPos = wxPoint(evt.GetX(), evt.GetY());
2738 m_actionItem = FindToolByPosition(evt.GetX(), evt.GetY());
eecf97a5 2739
9a29fe70 2740 if (m_actionItem)
1154f91b 2741 {
9a29fe70 2742 if (m_actionItem->m_state & wxAUI_BUTTON_STATE_DISABLED)
1154f91b 2743 {
9a29fe70
VZ
2744 m_actionPos = wxPoint(-1,-1);
2745 m_actionItem = NULL;
1154f91b
BW
2746 return;
2747 }
2748 }
4a21ea9d
VZ
2749
2750 UnsetToolTip();
1154f91b
BW
2751}
2752
2753void wxAuiToolBar::OnMiddleUp(wxMouseEvent& evt)
2754{
9a29fe70
VZ
2755 wxAuiToolBarItem* hitItem;
2756 hitItem = FindToolByPosition(evt.GetX(), evt.GetY());
eecf97a5 2757
9a29fe70 2758 if (m_actionItem && hitItem == m_actionItem)
1154f91b 2759 {
9a29fe70 2760 if (hitItem->m_kind == wxITEM_NORMAL)
1154f91b 2761 {
9a29fe70 2762 wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_MIDDLE_CLICK, m_actionItem->m_toolId);
1154f91b 2763 e.SetEventObject(this);
9a29fe70
VZ
2764 e.SetToolId(m_actionItem->m_toolId);
2765 e.SetClickPoint(m_actionPos);
004867db 2766 GetEventHandler()->ProcessEvent(e);
1154f91b
BW
2767 DoIdleUpdate();
2768 }
2769 }
2770
2771 // reset member variables
9a29fe70
VZ
2772 m_actionPos = wxPoint(-1,-1);
2773 m_actionItem = NULL;
1154f91b
BW
2774}
2775
2776void wxAuiToolBar::OnMotion(wxMouseEvent& evt)
2777{
4a21ea9d
VZ
2778 const bool button_pressed = HasCapture();
2779
1154f91b 2780 // start a drag event
4a21ea9d 2781 if (!m_dragging && button_pressed &&
9a29fe70 2782 abs(evt.GetX() - m_actionPos.x) + abs(evt.GetY() - m_actionPos.y) > 5)
1154f91b 2783 {
4a21ea9d
VZ
2784 // TODO: sending this event only makes sense if there is an 'END_DRAG'
2785 // event sent sometime in the future (see OnLeftUp())
1154f91b
BW
2786 wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_BEGIN_DRAG, GetId());
2787 e.SetEventObject(this);
9a29fe70 2788 e.SetToolId(m_actionItem->m_toolId);
4a21ea9d
VZ
2789 m_dragging = GetEventHandler()->ProcessEvent(e) && !e.GetSkipped();
2790
1154f91b 2791 DoIdleUpdate();
1154f91b
BW
2792 }
2793
4a21ea9d
VZ
2794 if(m_dragging)
2795 return;
2796
9a29fe70 2797 wxAuiToolBarItem* hitItem = FindToolByPosition(evt.GetX(), evt.GetY());
4a21ea9d 2798 if(button_pressed)
1154f91b 2799 {
4a21ea9d
VZ
2800 // if we have a button pressed we want it to be shown in 'depressed'
2801 // state unless we move the mouse outside the button, then we want it
2802 // to show as just 'highlighted'
9a29fe70
VZ
2803 if (hitItem == m_actionItem)
2804 SetPressedItem(m_actionItem);
8b385bf8 2805 else
4a21ea9d
VZ
2806 {
2807 SetPressedItem(NULL);
9a29fe70 2808 SetHoverItem(m_actionItem);
4a21ea9d 2809 }
1154f91b 2810 }
8b385bf8 2811 else
1154f91b 2812 {
9a29fe70 2813 if (hitItem && (hitItem->m_state & wxAUI_BUTTON_STATE_DISABLED))
4a21ea9d
VZ
2814 SetHoverItem(NULL);
2815 else
9a29fe70 2816 SetHoverItem(hitItem);
eecf97a5 2817
4a21ea9d 2818 // tooltips handling
9a29fe70
VZ
2819 wxAuiToolBarItem* packingHitItem;
2820 packingHitItem = FindToolByPositionWithPacking(evt.GetX(), evt.GetY());
2821 if (packingHitItem)
1154f91b 2822 {
9a29fe70 2823 if (packingHitItem != m_tipItem)
4a21ea9d 2824 {
9a29fe70 2825 m_tipItem = packingHitItem;
eecf97a5 2826
9a29fe70
VZ
2827 if ( !packingHitItem->m_shortHelp.empty() )
2828 SetToolTip(packingHitItem->m_shortHelp);
4a21ea9d
VZ
2829 else
2830 UnsetToolTip();
2831 }
1154f91b 2832 }
8b385bf8 2833 else
4a21ea9d
VZ
2834 {
2835 UnsetToolTip();
9a29fe70 2836 m_tipItem = NULL;
4a21ea9d 2837 }
eecf97a5 2838
4a21ea9d
VZ
2839 // figure out the dropdown button state (are we hovering or pressing it?)
2840 RefreshOverflowState();
2841 }
1154f91b
BW
2842}
2843
4a21ea9d 2844void wxAuiToolBar::DoResetMouseState()
1154f91b
BW
2845{
2846 RefreshOverflowState();
2847 SetHoverItem(NULL);
2848 SetPressedItem(NULL);
eecf97a5 2849
9a29fe70 2850 m_tipItem = NULL;
4a21ea9d
VZ
2851
2852 // we have to reset those here, because the mouse-up handlers which do
2853 // it usually won't be called if we let go of a mouse button while we
2854 // are outside of the window
9a29fe70
VZ
2855 m_actionPos = wxPoint(-1,-1);
2856 m_actionItem = NULL;
1154f91b
BW
2857}
2858
4a21ea9d
VZ
2859void wxAuiToolBar::OnLeaveWindow(wxMouseEvent& evt)
2860{
2861 if(HasCapture())
2862 {
2863 evt.Skip();
2864 return;
2865 }
2866
2867 DoResetMouseState();
2868}
2869
2870void wxAuiToolBar::OnCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(evt))
2871{
2872 m_dragging = false;
2873
2874 DoResetMouseState();
2875}
1154f91b
BW
2876
2877void wxAuiToolBar::OnSetCursor(wxSetCursorEvent& evt)
2878{
2879 wxCursor cursor = wxNullCursor;
eecf97a5 2880
9a29fe70 2881 if (m_gripperSizerItem)
1154f91b 2882 {
9a29fe70 2883 wxRect gripper_rect = m_gripperSizerItem->GetRect();
1154f91b
BW
2884 if (gripper_rect.Contains(evt.GetX(), evt.GetY()))
2885 {
2886 cursor = wxCursor(wxCURSOR_SIZING);
2887 }
2888 }
eecf97a5 2889
1154f91b
BW
2890 evt.SetCursor(cursor);
2891}
2892
2893
2894#endif // wxUSE_AUI
2895