]> git.saurik.com Git - wxWidgets.git/blame - src/aui/auibar.cpp
Avoid useless iteration on all pages in wxBookCtrlBase::DoGetBestSize().
[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 657void wxAuiDefaultToolBarArt::DrawOverflowButton(wxDC& dc,
36307fdf 658 wxWindow* /*wnd*/,
1154f91b
BW
659 const wxRect& rect,
660 int state)
661{
662 if (state & wxAUI_BUTTON_STATE_HOVER ||
663 state & wxAUI_BUTTON_STATE_PRESSED)
664 {
9a29fe70 665 wxColor light_gray_bg = m_highlightColour.ChangeLightness(170);
eecf97a5 666
1154f91b
BW
667 if (m_flags & wxAUI_TB_VERTICAL)
668 {
9a29fe70 669 dc.SetPen(wxPen(m_highlightColour));
1154f91b
BW
670 dc.DrawLine(rect.x, rect.y, rect.x+rect.width, rect.y);
671 dc.SetPen(wxPen(light_gray_bg));
672 dc.SetBrush(wxBrush(light_gray_bg));
673 dc.DrawRectangle(rect.x, rect.y+1, rect.width, rect.height);
674 }
675 else
676 {
9a29fe70 677 dc.SetPen(wxPen(m_highlightColour));
1154f91b
BW
678 dc.DrawLine(rect.x, rect.y, rect.x, rect.y+rect.height);
679 dc.SetPen(wxPen(light_gray_bg));
680 dc.SetBrush(wxBrush(light_gray_bg));
681 dc.DrawRectangle(rect.x+1, rect.y, rect.width, rect.height);
682 }
683 }
684
9a29fe70
VZ
685 int x = rect.x+1+(rect.width-m_overflowBmp.GetWidth())/2;
686 int y = rect.y+1+(rect.height-m_overflowBmp.GetHeight())/2;
687 dc.DrawBitmap(m_overflowBmp, x, y, true);
1154f91b
BW
688}
689
690int wxAuiDefaultToolBarArt::GetElementSize(int element_id)
691{
692 switch (element_id)
693 {
9a29fe70
VZ
694 case wxAUI_TBART_SEPARATOR_SIZE: return m_separatorSize;
695 case wxAUI_TBART_GRIPPER_SIZE: return m_gripperSize;
696 case wxAUI_TBART_OVERFLOW_SIZE: return m_overflowSize;
1154f91b
BW
697 default: return 0;
698 }
699}
700
701void wxAuiDefaultToolBarArt::SetElementSize(int element_id, int size)
702{
703 switch (element_id)
704 {
9a29fe70
VZ
705 case wxAUI_TBART_SEPARATOR_SIZE: m_separatorSize = size; break;
706 case wxAUI_TBART_GRIPPER_SIZE: m_gripperSize = size; break;
707 case wxAUI_TBART_OVERFLOW_SIZE: m_overflowSize = size; break;
1154f91b
BW
708 }
709}
710
711int wxAuiDefaultToolBarArt::ShowDropDown(wxWindow* wnd,
712 const wxAuiToolBarItemArray& items)
713{
714 wxMenu menuPopup;
715
716 size_t items_added = 0;
eecf97a5 717
1154f91b
BW
718 size_t i, count = items.GetCount();
719 for (i = 0; i < count; ++i)
720 {
721 wxAuiToolBarItem& item = items.Item(i);
eecf97a5 722
e42f2c16 723 if (item.GetKind() == wxITEM_NORMAL)
1154f91b 724 {
e42f2c16 725 wxString text = item.GetShortHelp();
1154f91b 726 if (text.empty())
e42f2c16 727 text = item.GetLabel();
eecf97a5 728
1154f91b
BW
729 if (text.empty())
730 text = wxT(" ");
eecf97a5 731
e42f2c16 732 wxMenuItem* m = new wxMenuItem(&menuPopup, item.GetId(), text, item.GetShortHelp());
1154f91b 733
e42f2c16 734 m->SetBitmap(item.GetBitmap());
1154f91b
BW
735 menuPopup.Append(m);
736 items_added++;
737 }
e42f2c16 738 else if (item.GetKind() == wxITEM_SEPARATOR)
1154f91b
BW
739 {
740 if (items_added > 0)
741 menuPopup.AppendSeparator();
742 }
743 }
744
745 // find out where to put the popup menu of window items
746 wxPoint pt = ::wxGetMousePosition();
747 pt = wnd->ScreenToClient(pt);
748
749 // find out the screen coordinate at the bottom of the tab ctrl
750 wxRect cli_rect = wnd->GetClientRect();
751 pt.y = cli_rect.y + cli_rect.height;
752
753 ToolbarCommandCapture* cc = new ToolbarCommandCapture;
754 wnd->PushEventHandler(cc);
755 wnd->PopupMenu(&menuPopup, pt);
756 int command = cc->GetCommandId();
757 wnd->PopEventHandler(true);
758
759 return command;
760}
761
762
763
764
e5dcae09
VZ
765static wxOrientation GetOrientation(long& style)
766{
767 switch (style & wxAUI_ORIENTATION_MASK)
768 {
769 case wxAUI_TB_HORIZONTAL:
770 return wxHORIZONTAL;
771 case wxAUI_TB_VERTICAL:
772 return wxVERTICAL;
773 default:
774 wxFAIL_MSG("toolbar cannot be locked in both horizontal and vertical orientations (maybe no lock was intended?)");
775 // fall through
776 case 0:
777 return wxBOTH;
778 }
779}
780
1154f91b
BW
781BEGIN_EVENT_TABLE(wxAuiToolBar, wxControl)
782 EVT_SIZE(wxAuiToolBar::OnSize)
783 EVT_IDLE(wxAuiToolBar::OnIdle)
784 EVT_ERASE_BACKGROUND(wxAuiToolBar::OnEraseBackground)
785 EVT_PAINT(wxAuiToolBar::OnPaint)
786 EVT_LEFT_DOWN(wxAuiToolBar::OnLeftDown)
787 EVT_LEFT_DCLICK(wxAuiToolBar::OnLeftDown)
788 EVT_LEFT_UP(wxAuiToolBar::OnLeftUp)
789 EVT_RIGHT_DOWN(wxAuiToolBar::OnRightDown)
790 EVT_RIGHT_DCLICK(wxAuiToolBar::OnRightDown)
791 EVT_RIGHT_UP(wxAuiToolBar::OnRightUp)
792 EVT_MIDDLE_DOWN(wxAuiToolBar::OnMiddleDown)
793 EVT_MIDDLE_DCLICK(wxAuiToolBar::OnMiddleDown)
794 EVT_MIDDLE_UP(wxAuiToolBar::OnMiddleUp)
795 EVT_MOTION(wxAuiToolBar::OnMotion)
796 EVT_LEAVE_WINDOW(wxAuiToolBar::OnLeaveWindow)
4a21ea9d 797 EVT_MOUSE_CAPTURE_LOST(wxAuiToolBar::OnCaptureLost)
1154f91b
BW
798 EVT_SET_CURSOR(wxAuiToolBar::OnSetCursor)
799END_EVENT_TABLE()
800
801
802wxAuiToolBar::wxAuiToolBar(wxWindow* parent,
803 wxWindowID id,
804 const wxPoint& position,
805 const wxSize& size,
806 long style)
807 : wxControl(parent,
808 id,
809 position,
810 size,
811 style | wxBORDER_NONE)
812{
813 m_sizer = new wxBoxSizer(wxHORIZONTAL);
9a29fe70
VZ
814 m_buttonWidth = -1;
815 m_buttonHeight = -1;
816 m_sizerElementCount = 0;
817 m_actionPos = wxPoint(-1,-1);
818 m_actionItem = NULL;
819 m_tipItem = NULL;
1154f91b 820 m_art = new wxAuiDefaultToolBarArt;
9a29fe70
VZ
821 m_toolPacking = 2;
822 m_toolBorderPadding = 3;
823 m_toolTextOrientation = wxAUI_TBTOOL_TEXT_BOTTOM;
824 m_gripperSizerItem = NULL;
825 m_overflowSizerItem = NULL;
1154f91b 826 m_dragging = false;
e5dcae09
VZ
827 m_orientation = GetOrientation(style);
828 if (m_orientation == wxBOTH)
829 {
830 m_orientation = wxHORIZONTAL;
831 }
af2a1b42 832 m_style = style | wxBORDER_NONE;
9a29fe70
VZ
833 m_gripperVisible = (m_style & wxAUI_TB_GRIPPER) ? true : false;
834 m_overflowVisible = (m_style & wxAUI_TB_OVERFLOW) ? true : false;
835 m_overflowState = 0;
1154f91b
BW
836 SetMargins(5, 5, 2, 2);
837 SetFont(*wxNORMAL_FONT);
e5dcae09 838 SetArtFlags();
1154f91b 839 SetExtraStyle(wxWS_EX_PROCESS_IDLE);
9578058d 840 if (style & wxAUI_TB_HORZ_LAYOUT)
1154f91b 841 SetToolTextOrientation(wxAUI_TBTOOL_TEXT_RIGHT);
66ad3095 842 SetBackgroundStyle(wxBG_STYLE_CUSTOM);
1154f91b
BW
843}
844
845
846wxAuiToolBar::~wxAuiToolBar()
847{
848 delete m_art;
849 delete m_sizer;
850}
851
852void wxAuiToolBar::SetWindowStyleFlag(long style)
853{
e5dcae09
VZ
854 GetOrientation(style); // assert if style is invalid
855 wxCHECK_RET(IsPaneValid(style),
856 "window settings and pane settings are incompatible");
857
1154f91b
BW
858 wxControl::SetWindowStyleFlag(style);
859
860 m_style = style;
eecf97a5 861
1154f91b
BW
862 if (m_art)
863 {
e5dcae09 864 SetArtFlags();
1154f91b 865 }
eecf97a5 866
1154f91b 867 if (m_style & wxAUI_TB_GRIPPER)
9a29fe70 868 m_gripperVisible = true;
8b385bf8 869 else
9a29fe70 870 m_gripperVisible = false;
1154f91b
BW
871
872
873 if (m_style & wxAUI_TB_OVERFLOW)
9a29fe70 874 m_overflowVisible = true;
8b385bf8 875 else
9a29fe70 876 m_overflowVisible = false;
eecf97a5 877
9578058d 878 if (style & wxAUI_TB_HORZ_LAYOUT)
1154f91b 879 SetToolTextOrientation(wxAUI_TBTOOL_TEXT_RIGHT);
8b385bf8 880 else
1154f91b
BW
881 SetToolTextOrientation(wxAUI_TBTOOL_TEXT_BOTTOM);
882}
883
e7b8af65
BW
884long wxAuiToolBar::GetWindowStyleFlag() const
885{
886 return m_style;
887}
1154f91b
BW
888
889void wxAuiToolBar::SetArtProvider(wxAuiToolBarArt* art)
890{
891 delete m_art;
eecf97a5 892
1154f91b 893 m_art = art;
eecf97a5 894
1154f91b
BW
895 if (m_art)
896 {
e5dcae09 897 SetArtFlags();
9a29fe70 898 m_art->SetTextOrientation(m_toolTextOrientation);
1154f91b
BW
899 }
900}
901
902wxAuiToolBarArt* wxAuiToolBar::GetArtProvider() const
903{
904 return m_art;
905}
906
907
908
909
7bce8439 910wxAuiToolBarItem* wxAuiToolBar::AddTool(int tool_id,
1154f91b
BW
911 const wxString& label,
912 const wxBitmap& bitmap,
9a29fe70 913 const wxString& shortHelp_string,
1154f91b
BW
914 wxItemKind kind)
915{
7bce8439 916 return AddTool(tool_id,
1154f91b
BW
917 label,
918 bitmap,
919 wxNullBitmap,
920 kind,
9a29fe70 921 shortHelp_string,
1154f91b
BW
922 wxEmptyString,
923 NULL);
924}
925
926
7bce8439 927wxAuiToolBarItem* wxAuiToolBar::AddTool(int tool_id,
1154f91b
BW
928 const wxString& label,
929 const wxBitmap& bitmap,
9a29fe70 930 const wxBitmap& disabledBitmap,
1154f91b 931 wxItemKind kind,
9a29fe70
VZ
932 const wxString& shortHelpString,
933 const wxString& longHelpString,
1154f91b
BW
934 wxObject* WXUNUSED(client_data))
935{
936 wxAuiToolBarItem item;
9a29fe70
VZ
937 item.m_window = NULL;
938 item.m_label = label;
939 item.m_bitmap = bitmap;
940 item.m_disabledBitmap = disabledBitmap;
941 item.m_shortHelp = shortHelpString;
942 item.m_longHelp = longHelpString;
943 item.m_active = true;
944 item.m_dropDown = false;
945 item.m_spacerPixels = 0;
946 item.m_toolId = tool_id;
947 item.m_state = 0;
948 item.m_proportion = 0;
949 item.m_kind = kind;
950 item.m_sizerItem = NULL;
951 item.m_minSize = wxDefaultSize;
952 item.m_userData = 0;
953 item.m_sticky = false;
954
955 if (item.m_toolId == wxID_ANY)
956 item.m_toolId = wxNewId();
957
958 if (!item.m_disabledBitmap.IsOk())
1154f91b
BW
959 {
960 // no disabled bitmap specified, we need to make one
9a29fe70 961 if (item.m_bitmap.IsOk())
1154f91b 962 {
9a29fe70 963 item.m_disabledBitmap = item.m_bitmap.ConvertToDisabled();
1154f91b
BW
964 }
965 }
1154f91b 966 m_items.Add(item);
7bce8439 967 return &m_items.Last();
1154f91b
BW
968}
969
7bce8439 970wxAuiToolBarItem* wxAuiToolBar::AddControl(wxControl* control,
1154f91b
BW
971 const wxString& label)
972{
973 wxAuiToolBarItem item;
9a29fe70
VZ
974 item.m_window = (wxWindow*)control;
975 item.m_label = label;
976 item.m_bitmap = wxNullBitmap;
977 item.m_disabledBitmap = wxNullBitmap;
978 item.m_active = true;
979 item.m_dropDown = false;
980 item.m_spacerPixels = 0;
981 item.m_toolId = control->GetId();
982 item.m_state = 0;
983 item.m_proportion = 0;
984 item.m_kind = wxITEM_CONTROL;
985 item.m_sizerItem = NULL;
986 item.m_minSize = control->GetEffectiveMinSize();
987 item.m_userData = 0;
988 item.m_sticky = false;
1154f91b
BW
989
990 m_items.Add(item);
7bce8439 991 return &m_items.Last();
1154f91b
BW
992}
993
7bce8439 994wxAuiToolBarItem* wxAuiToolBar::AddLabel(int tool_id,
1154f91b
BW
995 const wxString& label,
996 const int width)
997{
998 wxSize min_size = wxDefaultSize;
999 if (width != -1)
1000 min_size.x = width;
eecf97a5 1001
1154f91b 1002 wxAuiToolBarItem item;
9a29fe70
VZ
1003 item.m_window = NULL;
1004 item.m_label = label;
1005 item.m_bitmap = wxNullBitmap;
1006 item.m_disabledBitmap = wxNullBitmap;
1007 item.m_active = true;
1008 item.m_dropDown = false;
1009 item.m_spacerPixels = 0;
1010 item.m_toolId = tool_id;
1011 item.m_state = 0;
1012 item.m_proportion = 0;
1013 item.m_kind = wxITEM_LABEL;
1014 item.m_sizerItem = NULL;
1015 item.m_minSize = min_size;
1016 item.m_userData = 0;
1017 item.m_sticky = false;
1018
1019 if (item.m_toolId == wxID_ANY)
1020 item.m_toolId = wxNewId();
45496810 1021
1154f91b 1022 m_items.Add(item);
7bce8439 1023 return &m_items.Last();
1154f91b
BW
1024}
1025
7bce8439 1026wxAuiToolBarItem* wxAuiToolBar::AddSeparator()
1154f91b
BW
1027{
1028 wxAuiToolBarItem item;
9a29fe70
VZ
1029 item.m_window = NULL;
1030 item.m_label = wxEmptyString;
1031 item.m_bitmap = wxNullBitmap;
1032 item.m_disabledBitmap = wxNullBitmap;
1033 item.m_active = true;
1034 item.m_dropDown = false;
1035 item.m_toolId = -1;
1036 item.m_state = 0;
1037 item.m_proportion = 0;
1038 item.m_kind = wxITEM_SEPARATOR;
1039 item.m_sizerItem = NULL;
1040 item.m_minSize = wxDefaultSize;
1041 item.m_userData = 0;
1042 item.m_sticky = false;
1154f91b
BW
1043
1044 m_items.Add(item);
7bce8439 1045 return &m_items.Last();
1154f91b
BW
1046}
1047
7bce8439 1048wxAuiToolBarItem* wxAuiToolBar::AddSpacer(int pixels)
1154f91b
BW
1049{
1050 wxAuiToolBarItem item;
9a29fe70
VZ
1051 item.m_window = NULL;
1052 item.m_label = wxEmptyString;
1053 item.m_bitmap = wxNullBitmap;
1054 item.m_disabledBitmap = wxNullBitmap;
1055 item.m_active = true;
1056 item.m_dropDown = false;
1057 item.m_spacerPixels = pixels;
1058 item.m_toolId = -1;
1059 item.m_state = 0;
1060 item.m_proportion = 0;
1061 item.m_kind = wxITEM_SPACER;
1062 item.m_sizerItem = NULL;
1063 item.m_minSize = wxDefaultSize;
1064 item.m_userData = 0;
1065 item.m_sticky = false;
1154f91b
BW
1066
1067 m_items.Add(item);
7bce8439 1068 return &m_items.Last();
1154f91b
BW
1069}
1070
7bce8439 1071wxAuiToolBarItem* wxAuiToolBar::AddStretchSpacer(int proportion)
1154f91b
BW
1072{
1073 wxAuiToolBarItem item;
9a29fe70
VZ
1074 item.m_window = NULL;
1075 item.m_label = wxEmptyString;
1076 item.m_bitmap = wxNullBitmap;
1077 item.m_disabledBitmap = wxNullBitmap;
1078 item.m_active = true;
1079 item.m_dropDown = false;
1080 item.m_spacerPixels = 0;
1081 item.m_toolId = -1;
1082 item.m_state = 0;
1083 item.m_proportion = proportion;
1084 item.m_kind = wxITEM_SPACER;
1085 item.m_sizerItem = NULL;
1086 item.m_minSize = wxDefaultSize;
1087 item.m_userData = 0;
1088 item.m_sticky = false;
1154f91b
BW
1089
1090 m_items.Add(item);
7bce8439 1091 return &m_items.Last();
1154f91b
BW
1092}
1093
1094void wxAuiToolBar::Clear()
1095{
1096 m_items.Clear();
9a29fe70 1097 m_sizerElementCount = 0;
1154f91b
BW
1098}
1099
1100bool wxAuiToolBar::DeleteTool(int tool_id)
1101{
1102 int idx = GetToolIndex(tool_id);
1103 if (idx >= 0 && idx < (int)m_items.GetCount())
1104 {
1105 m_items.RemoveAt(idx);
1106 Realize();
1107 return true;
1108 }
eecf97a5 1109
1154f91b
BW
1110 return false;
1111}
1112
1113bool wxAuiToolBar::DeleteByIndex(int idx)
1114{
1115 if (idx >= 0 && idx < (int)m_items.GetCount())
1116 {
1117 m_items.RemoveAt(idx);
1118 Realize();
1119 return true;
1120 }
eecf97a5 1121
1154f91b
BW
1122 return false;
1123}
1124
1125
1126wxControl* wxAuiToolBar::FindControl(int id)
1127{
1128 wxWindow* wnd = FindWindow(id);
1129 return (wxControl*)wnd;
1130}
1131
1132wxAuiToolBarItem* wxAuiToolBar::FindTool(int tool_id) const
1133{
1134 size_t i, count;
1135 for (i = 0, count = m_items.GetCount(); i < count; ++i)
1136 {
1137 wxAuiToolBarItem& item = m_items.Item(i);
9a29fe70 1138 if (item.m_toolId == tool_id)
1154f91b
BW
1139 return &item;
1140 }
eecf97a5 1141
1154f91b
BW
1142 return NULL;
1143}
1144
1145wxAuiToolBarItem* wxAuiToolBar::FindToolByPosition(wxCoord x, wxCoord y) const
1146{
1147 size_t i, count;
1148 for (i = 0, count = m_items.GetCount(); i < count; ++i)
1149 {
1150 wxAuiToolBarItem& item = m_items.Item(i);
eecf97a5 1151
9a29fe70 1152 if (!item.m_sizerItem)
1154f91b 1153 continue;
eecf97a5 1154
9a29fe70 1155 wxRect rect = item.m_sizerItem->GetRect();
1154f91b
BW
1156 if (rect.Contains(x,y))
1157 {
1158 // if the item doesn't fit on the toolbar, return NULL
1159 if (!GetToolFitsByIndex(i))
1160 return NULL;
eecf97a5 1161
1154f91b
BW
1162 return &item;
1163 }
1164 }
eecf97a5 1165
1154f91b
BW
1166 return NULL;
1167}
1168
1169wxAuiToolBarItem* wxAuiToolBar::FindToolByPositionWithPacking(wxCoord x, wxCoord y) const
1170{
1171 size_t i, count;
1172 for (i = 0, count = m_items.GetCount(); i < count; ++i)
1173 {
1174 wxAuiToolBarItem& item = m_items.Item(i);
eecf97a5 1175
9a29fe70 1176 if (!item.m_sizerItem)
1154f91b 1177 continue;
eecf97a5 1178
9a29fe70 1179 wxRect rect = item.m_sizerItem->GetRect();
eecf97a5 1180
1154f91b
BW
1181 // apply tool packing
1182 if (i+1 < count)
9a29fe70 1183 rect.width += m_toolPacking;
eecf97a5 1184
1154f91b
BW
1185 if (rect.Contains(x,y))
1186 {
1187 // if the item doesn't fit on the toolbar, return NULL
1188 if (!GetToolFitsByIndex(i))
1189 return NULL;
eecf97a5 1190
1154f91b
BW
1191 return &item;
1192 }
1193 }
eecf97a5 1194
1154f91b
BW
1195 return NULL;
1196}
1197
1198wxAuiToolBarItem* wxAuiToolBar::FindToolByIndex(int idx) const
1199{
1200 if (idx < 0)
1201 return NULL;
eecf97a5 1202
1154f91b
BW
1203 if (idx >= (int)m_items.size())
1204 return NULL;
eecf97a5 1205
1154f91b
BW
1206 return &(m_items[idx]);
1207}
1208
1209void wxAuiToolBar::SetToolBitmapSize(const wxSize& WXUNUSED(size))
1210{
1211 // TODO: wxToolBar compatibility
1212}
1213
1214wxSize wxAuiToolBar::GetToolBitmapSize() const
1215{
1216 // TODO: wxToolBar compatibility
1217 return wxSize(16,15);
1218}
eecf97a5 1219
1154f91b
BW
1220void wxAuiToolBar::SetToolProportion(int tool_id, int proportion)
1221{
1222 wxAuiToolBarItem* item = FindTool(tool_id);
1223 if (!item)
1224 return;
eecf97a5 1225
9a29fe70 1226 item->m_proportion = proportion;
1154f91b
BW
1227}
1228
1229int wxAuiToolBar::GetToolProportion(int tool_id) const
1230{
1231 wxAuiToolBarItem* item = FindTool(tool_id);
1232 if (!item)
1233 return 0;
eecf97a5 1234
9a29fe70 1235 return item->m_proportion;
1154f91b
BW
1236}
1237
1238void wxAuiToolBar::SetToolSeparation(int separation)
1239{
1240 if (m_art)
1241 m_art->SetElementSize(wxAUI_TBART_SEPARATOR_SIZE, separation);
1242}
1243
1244int wxAuiToolBar::GetToolSeparation() const
1245{
1246 if (m_art)
1247 return m_art->GetElementSize(wxAUI_TBART_SEPARATOR_SIZE);
8b385bf8 1248 else
1154f91b
BW
1249 return 5;
1250}
eecf97a5 1251
1154f91b
BW
1252
1253void wxAuiToolBar::SetToolDropDown(int tool_id, bool dropdown)
1254{
eecf97a5 1255 wxAuiToolBarItem* item = FindTool(tool_id);
1154f91b
BW
1256 if (!item)
1257 return;
1258
9a29fe70 1259 item->m_dropDown = dropdown;
1154f91b
BW
1260}
1261
1262bool wxAuiToolBar::GetToolDropDown(int tool_id) const
1263{
1264 wxAuiToolBarItem* item = FindTool(tool_id);
1265 if (!item)
1266 return 0;
eecf97a5 1267
9a29fe70 1268 return item->m_dropDown;
1154f91b
BW
1269}
1270
1271void wxAuiToolBar::SetToolSticky(int tool_id, bool sticky)
1272{
1273 // ignore separators
1274 if (tool_id == -1)
1275 return;
eecf97a5
VZ
1276
1277 wxAuiToolBarItem* item = FindTool(tool_id);
1154f91b
BW
1278 if (!item)
1279 return;
eecf97a5 1280
9a29fe70 1281 if (item->m_sticky == sticky)
1154f91b 1282 return;
eecf97a5 1283
9a29fe70 1284 item->m_sticky = sticky;
eecf97a5 1285
1154f91b
BW
1286 Refresh(false);
1287 Update();
1288}
1289
1290bool wxAuiToolBar::GetToolSticky(int tool_id) const
1291{
1292 wxAuiToolBarItem* item = FindTool(tool_id);
1293 if (!item)
1294 return 0;
eecf97a5 1295
9a29fe70 1296 return item->m_sticky;
1154f91b
BW
1297}
1298
1299
1300
1301
1302void wxAuiToolBar::SetToolBorderPadding(int padding)
1303{
9a29fe70 1304 m_toolBorderPadding = padding;
1154f91b
BW
1305}
1306
1307int wxAuiToolBar::GetToolBorderPadding() const
1308{
9a29fe70 1309 return m_toolBorderPadding;
1154f91b
BW
1310}
1311
1312void wxAuiToolBar::SetToolTextOrientation(int orientation)
1313{
9a29fe70 1314 m_toolTextOrientation = orientation;
1154f91b
BW
1315
1316 if (m_art)
1317 {
1318 m_art->SetTextOrientation(orientation);
1319 }
1320}
1321
1322int wxAuiToolBar::GetToolTextOrientation() const
1323{
9a29fe70 1324 return m_toolTextOrientation;
1154f91b
BW
1325}
1326
1327void wxAuiToolBar::SetToolPacking(int packing)
1328{
9a29fe70 1329 m_toolPacking = packing;
1154f91b
BW
1330}
1331
1332int wxAuiToolBar::GetToolPacking() const
1333{
9a29fe70 1334 return m_toolPacking;
1154f91b
BW
1335}
1336
1337
e5dcae09 1338void wxAuiToolBar::SetOrientation(int orientation)
1154f91b 1339{
e5dcae09
VZ
1340 wxCHECK_RET(orientation == wxHORIZONTAL ||
1341 orientation == wxVERTICAL,
1342 "invalid orientation value");
1343 if (orientation != m_orientation)
1344 {
1345 m_orientation = wxOrientation(orientation);
1346 SetArtFlags();
1347 }
1154f91b
BW
1348}
1349
1350void wxAuiToolBar::SetMargins(int left, int right, int top, int bottom)
1351{
1352 if (left != -1)
9a29fe70 1353 m_leftPadding = left;
1154f91b 1354 if (right != -1)
9a29fe70 1355 m_rightPadding = right;
1154f91b 1356 if (top != -1)
9a29fe70 1357 m_topPadding = top;
1154f91b 1358 if (bottom != -1)
9a29fe70 1359 m_bottomPadding = bottom;
1154f91b
BW
1360}
1361
1362bool wxAuiToolBar::GetGripperVisible() const
1363{
9a29fe70 1364 return m_gripperVisible;
1154f91b
BW
1365}
1366
1367void wxAuiToolBar::SetGripperVisible(bool visible)
1368{
9a29fe70 1369 m_gripperVisible = visible;
1154f91b
BW
1370 if (visible)
1371 m_style |= wxAUI_TB_GRIPPER;
e7b8af65
BW
1372 else
1373 m_style &= ~wxAUI_TB_GRIPPER;
1154f91b
BW
1374 Realize();
1375 Refresh(false);
1376}
1377
1378
1379bool wxAuiToolBar::GetOverflowVisible() const
1380{
9a29fe70 1381 return m_overflowVisible;
1154f91b
BW
1382}
1383
1384void wxAuiToolBar::SetOverflowVisible(bool visible)
1385{
9a29fe70 1386 m_overflowVisible = visible;
1154f91b
BW
1387 if (visible)
1388 m_style |= wxAUI_TB_OVERFLOW;
e7b8af65
BW
1389 else
1390 m_style &= ~wxAUI_TB_OVERFLOW;
1154f91b
BW
1391 Refresh(false);
1392}
1393
1394bool wxAuiToolBar::SetFont(const wxFont& font)
1395{
1396 bool res = wxWindow::SetFont(font);
eecf97a5 1397
1154f91b
BW
1398 if (m_art)
1399 {
1400 m_art->SetFont(font);
1401 }
eecf97a5 1402
1154f91b
BW
1403 return res;
1404}
1405
1406
1407void wxAuiToolBar::SetHoverItem(wxAuiToolBarItem* pitem)
1408{
c2211811
VZ
1409 if (pitem && (pitem->m_state & wxAUI_BUTTON_STATE_DISABLED))
1410 pitem = NULL;
1411
1154f91b 1412 wxAuiToolBarItem* former_hover = NULL;
eecf97a5 1413
1154f91b
BW
1414 size_t i, count;
1415 for (i = 0, count = m_items.GetCount(); i < count; ++i)
1416 {
1417 wxAuiToolBarItem& item = m_items.Item(i);
9a29fe70 1418 if (item.m_state & wxAUI_BUTTON_STATE_HOVER)
1154f91b 1419 former_hover = &item;
9a29fe70 1420 item.m_state &= ~wxAUI_BUTTON_STATE_HOVER;
1154f91b 1421 }
eecf97a5 1422
1154f91b
BW
1423 if (pitem)
1424 {
9a29fe70 1425 pitem->m_state |= wxAUI_BUTTON_STATE_HOVER;
1154f91b 1426 }
eecf97a5 1427
1154f91b
BW
1428 if (former_hover != pitem)
1429 {
1430 Refresh(false);
1431 Update();
1432 }
1433}
1434
1435void wxAuiToolBar::SetPressedItem(wxAuiToolBarItem* pitem)
1436{
1437 wxAuiToolBarItem* former_item = NULL;
eecf97a5 1438
1154f91b
BW
1439 size_t i, count;
1440 for (i = 0, count = m_items.GetCount(); i < count; ++i)
1441 {
1442 wxAuiToolBarItem& item = m_items.Item(i);
9a29fe70 1443 if (item.m_state & wxAUI_BUTTON_STATE_PRESSED)
1154f91b 1444 former_item = &item;
9a29fe70 1445 item.m_state &= ~wxAUI_BUTTON_STATE_PRESSED;
1154f91b 1446 }
eecf97a5 1447
1154f91b
BW
1448 if (pitem)
1449 {
9a29fe70
VZ
1450 pitem->m_state &= ~wxAUI_BUTTON_STATE_HOVER;
1451 pitem->m_state |= wxAUI_BUTTON_STATE_PRESSED;
1154f91b 1452 }
eecf97a5 1453
1154f91b
BW
1454 if (former_item != pitem)
1455 {
1456 Refresh(false);
1457 Update();
1458 }
1459}
1460
1461void wxAuiToolBar::RefreshOverflowState()
1462{
9a29fe70 1463 if (!m_overflowSizerItem)
1154f91b 1464 {
9a29fe70 1465 m_overflowState = 0;
1154f91b
BW
1466 return;
1467 }
eecf97a5 1468
1154f91b 1469 int overflow_state = 0;
eecf97a5 1470
1154f91b
BW
1471 wxRect overflow_rect = GetOverflowRect();
1472
eecf97a5 1473
1154f91b
BW
1474 // find out the mouse's current position
1475 wxPoint pt = ::wxGetMousePosition();
1476 pt = this->ScreenToClient(pt);
eecf97a5 1477
1154f91b
BW
1478 // find out if the mouse cursor is inside the dropdown rectangle
1479 if (overflow_rect.Contains(pt.x, pt.y))
1480 {
45496810 1481 if (::wxGetMouseState().LeftIsDown())
1154f91b 1482 overflow_state = wxAUI_BUTTON_STATE_PRESSED;
8b385bf8 1483 else
1154f91b
BW
1484 overflow_state = wxAUI_BUTTON_STATE_HOVER;
1485 }
eecf97a5 1486
9a29fe70 1487 if (overflow_state != m_overflowState)
1154f91b 1488 {
9a29fe70 1489 m_overflowState = overflow_state;
1154f91b
BW
1490 Refresh(false);
1491 Update();
1492 }
eecf97a5 1493
9a29fe70 1494 m_overflowState = overflow_state;
1154f91b
BW
1495}
1496
1497void wxAuiToolBar::ToggleTool(int tool_id, bool state)
1498{
1499 wxAuiToolBarItem* tool = FindTool(tool_id);
eecf97a5 1500
9a29fe70 1501 if (tool && (tool->m_kind == wxITEM_CHECK || tool->m_kind == wxITEM_RADIO))
1154f91b 1502 {
9a29fe70 1503 if (tool->m_kind == wxITEM_RADIO)
cae51973
BW
1504 {
1505 int i, idx, count;
1506 idx = GetToolIndex(tool_id);
1507 count = (int)m_items.GetCount();
45496810 1508
cae51973
BW
1509 if (idx >= 0 && idx < count)
1510 {
587151f7 1511 for (i = idx + 1; i < count; ++i)
cae51973 1512 {
9a29fe70 1513 if (m_items[i].m_kind != wxITEM_RADIO)
cae51973 1514 break;
9a29fe70 1515 m_items[i].m_state &= ~wxAUI_BUTTON_STATE_CHECKED;
cae51973 1516 }
587151f7 1517 for (i = idx - 1; i >= 0; i--)
cae51973 1518 {
9a29fe70 1519 if (m_items[i].m_kind != wxITEM_RADIO)
cae51973 1520 break;
9a29fe70 1521 m_items[i].m_state &= ~wxAUI_BUTTON_STATE_CHECKED;
cae51973
BW
1522 }
1523 }
45496810 1524
9a29fe70 1525 tool->m_state |= wxAUI_BUTTON_STATE_CHECKED;
cae51973 1526 }
9a29fe70 1527 else if (tool->m_kind == wxITEM_CHECK)
cae51973
BW
1528 {
1529 if (state == true)
9a29fe70 1530 tool->m_state |= wxAUI_BUTTON_STATE_CHECKED;
cae51973 1531 else
9a29fe70 1532 tool->m_state &= ~wxAUI_BUTTON_STATE_CHECKED;
cae51973 1533 }
1154f91b
BW
1534 }
1535}
1536
1537bool wxAuiToolBar::GetToolToggled(int tool_id) const
1538{
1539 wxAuiToolBarItem* tool = FindTool(tool_id);
eecf97a5 1540
1154f91b
BW
1541 if (tool)
1542 {
9a29fe70 1543 if ( (tool->m_kind != wxITEM_CHECK) && (tool->m_kind != wxITEM_RADIO) )
1154f91b 1544 return false;
eecf97a5 1545
9a29fe70 1546 return (tool->m_state & wxAUI_BUTTON_STATE_CHECKED) ? true : false;
1154f91b 1547 }
eecf97a5 1548
1154f91b
BW
1549 return false;
1550}
1551
1552void wxAuiToolBar::EnableTool(int tool_id, bool state)
1553{
1554 wxAuiToolBarItem* tool = FindTool(tool_id);
eecf97a5 1555
1154f91b
BW
1556 if (tool)
1557 {
1558 if (state == true)
9a29fe70 1559 tool->m_state &= ~wxAUI_BUTTON_STATE_DISABLED;
8b385bf8 1560 else
9a29fe70 1561 tool->m_state |= wxAUI_BUTTON_STATE_DISABLED;
1154f91b
BW
1562 }
1563}
1564
1565bool wxAuiToolBar::GetToolEnabled(int tool_id) const
1566{
1567 wxAuiToolBarItem* tool = FindTool(tool_id);
eecf97a5 1568
1154f91b 1569 if (tool)
9a29fe70 1570 return (tool->m_state & wxAUI_BUTTON_STATE_DISABLED) ? false : true;
eecf97a5 1571
1154f91b
BW
1572 return false;
1573}
1574
1575wxString wxAuiToolBar::GetToolLabel(int tool_id) const
1576{
1577 wxAuiToolBarItem* tool = FindTool(tool_id);
1578 wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array"));
1579 if (!tool)
1580 return wxEmptyString;
eecf97a5 1581
9a29fe70 1582 return tool->m_label;
1154f91b
BW
1583}
1584
1585void wxAuiToolBar::SetToolLabel(int tool_id, const wxString& label)
1586{
1587 wxAuiToolBarItem* tool = FindTool(tool_id);
1588 if (tool)
1589 {
9a29fe70 1590 tool->m_label = label;
1154f91b
BW
1591 }
1592}
1593
1594wxBitmap wxAuiToolBar::GetToolBitmap(int tool_id) const
1595{
1596 wxAuiToolBarItem* tool = FindTool(tool_id);
1597 wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array"));
1598 if (!tool)
1599 return wxNullBitmap;
eecf97a5 1600
9a29fe70 1601 return tool->m_bitmap;
1154f91b
BW
1602}
1603
1604void wxAuiToolBar::SetToolBitmap(int tool_id, const wxBitmap& bitmap)
1605{
1606 wxAuiToolBarItem* tool = FindTool(tool_id);
1607 if (tool)
1608 {
9a29fe70 1609 tool->m_bitmap = bitmap;
1154f91b
BW
1610 }
1611}
1612
1613wxString wxAuiToolBar::GetToolShortHelp(int tool_id) const
1614{
1615 wxAuiToolBarItem* tool = FindTool(tool_id);
1616 wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array"));
1617 if (!tool)
1618 return wxEmptyString;
eecf97a5 1619
9a29fe70 1620 return tool->m_shortHelp;
1154f91b
BW
1621}
1622
1623void wxAuiToolBar::SetToolShortHelp(int tool_id, const wxString& help_string)
1624{
1625 wxAuiToolBarItem* tool = FindTool(tool_id);
1626 if (tool)
1627 {
9a29fe70 1628 tool->m_shortHelp = help_string;
1154f91b
BW
1629 }
1630}
1631
1632wxString wxAuiToolBar::GetToolLongHelp(int tool_id) const
1633{
1634 wxAuiToolBarItem* tool = FindTool(tool_id);
1635 wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array"));
1636 if (!tool)
1637 return wxEmptyString;
eecf97a5 1638
9a29fe70 1639 return tool->m_longHelp;
1154f91b
BW
1640}
1641
1642void wxAuiToolBar::SetToolLongHelp(int tool_id, const wxString& help_string)
1643{
1644 wxAuiToolBarItem* tool = FindTool(tool_id);
1645 if (tool)
1646 {
9a29fe70 1647 tool->m_longHelp = help_string;
1154f91b
BW
1648 }
1649}
1650
1651void wxAuiToolBar::SetCustomOverflowItems(const wxAuiToolBarItemArray& prepend,
1652 const wxAuiToolBarItemArray& append)
1653{
9a29fe70
VZ
1654 m_customOverflowPrepend = prepend;
1655 m_customOverflowAppend = append;
1154f91b
BW
1656}
1657
e5dcae09
VZ
1658// get size of hint rectangle for a particular dock location
1659wxSize wxAuiToolBar::GetHintSize(int dock_direction) const
1660{
1661 switch (dock_direction)
1662 {
1663 case wxAUI_DOCK_TOP:
1664 case wxAUI_DOCK_BOTTOM:
1665 return m_horzHintSize;
1666 case wxAUI_DOCK_RIGHT:
1667 case wxAUI_DOCK_LEFT:
1668 return m_vertHintSize;
1669 default:
71929371 1670 wxFAIL_MSG("invalid dock location value");
e5dcae09 1671 }
71929371 1672 return wxDefaultSize;
e5dcae09
VZ
1673}
1674
1675bool wxAuiToolBar::IsPaneValid(const wxAuiPaneInfo& pane) const
1676{
1677 return IsPaneValid(m_style, pane);
1678}
1679
1680bool wxAuiToolBar::IsPaneValid(long style, const wxAuiPaneInfo& pane)
1681{
1682 if (style & wxAUI_TB_HORIZONTAL)
1683 {
1684 if (pane.IsLeftDockable() || pane.IsRightDockable())
1685 {
1686 return false;
1687 }
1688 }
1689 else if (style & wxAUI_TB_VERTICAL)
1690 {
1691 if (pane.IsTopDockable() || pane.IsBottomDockable())
1692 {
1693 return false;
1694 }
1695 }
1696 return true;
1697}
1698
1699bool wxAuiToolBar::IsPaneValid(long style) const
1700{
1701 wxAuiManager* manager = wxAuiManager::GetManager(const_cast<wxAuiToolBar*>(this));
1702 if (manager)
1703 {
1704 return IsPaneValid(style, manager->GetPane(const_cast<wxAuiToolBar*>(this)));
1705 }
1706 return true;
1707}
1708
1709void wxAuiToolBar::SetArtFlags() const
1710{
1711 unsigned int artflags = m_style & ~wxAUI_ORIENTATION_MASK;
1712 if (m_orientation == wxVERTICAL)
1713 {
1714 artflags |= wxAUI_TB_VERTICAL;
1715 }
1716 m_art->SetFlags(artflags);
1717}
1154f91b
BW
1718
1719size_t wxAuiToolBar::GetToolCount() const
1720{
1721 return m_items.size();
1722}
1723
1724int wxAuiToolBar::GetToolIndex(int tool_id) const
1725{
1726 // this will prevent us from returning the index of the
1727 // first separator in the toolbar since its id is equal to -1
1728 if (tool_id == -1)
1729 return wxNOT_FOUND;
eecf97a5 1730
1154f91b
BW
1731 size_t i, count = m_items.GetCount();
1732 for (i = 0; i < count; ++i)
1733 {
1734 wxAuiToolBarItem& item = m_items.Item(i);
9a29fe70 1735 if (item.m_toolId == tool_id)
1154f91b
BW
1736 return i;
1737 }
eecf97a5 1738
1154f91b
BW
1739 return wxNOT_FOUND;
1740}
1741
1742bool wxAuiToolBar::GetToolFitsByIndex(int tool_idx) const
1743{
1744 if (tool_idx < 0 || tool_idx >= (int)m_items.GetCount())
1745 return false;
eecf97a5 1746
9a29fe70 1747 if (!m_items[tool_idx].m_sizerItem)
1154f91b 1748 return false;
eecf97a5 1749
1154f91b
BW
1750 int cli_w, cli_h;
1751 GetClientSize(&cli_w, &cli_h);
eecf97a5 1752
9a29fe70 1753 wxRect rect = m_items[tool_idx].m_sizerItem->GetRect();
eecf97a5 1754
e5dcae09 1755 if (m_orientation == wxVERTICAL)
1154f91b
BW
1756 {
1757 // take the dropdown size into account
9a29fe70
VZ
1758 if (m_overflowVisible)
1759 cli_h -= m_overflowSizerItem->GetSize().y;
eecf97a5 1760
1154f91b
BW
1761 if (rect.y+rect.height < cli_h)
1762 return true;
1763 }
8b385bf8 1764 else
1154f91b
BW
1765 {
1766 // take the dropdown size into account
9a29fe70
VZ
1767 if (m_overflowVisible)
1768 cli_w -= m_overflowSizerItem->GetSize().x;
eecf97a5 1769
1154f91b
BW
1770 if (rect.x+rect.width < cli_w)
1771 return true;
1772 }
1773
1774 return false;
1775}
1776
1777
1778bool wxAuiToolBar::GetToolFits(int tool_id) const
1779{
1780 return GetToolFitsByIndex(GetToolIndex(tool_id));
1781}
1782
1783wxRect wxAuiToolBar::GetToolRect(int tool_id) const
1784{
1785 wxAuiToolBarItem* tool = FindTool(tool_id);
9a29fe70 1786 if (tool && tool->m_sizerItem)
1154f91b 1787 {
9a29fe70 1788 return tool->m_sizerItem->GetRect();
1154f91b 1789 }
eecf97a5 1790
1154f91b
BW
1791 return wxRect();
1792}
1793
1794bool wxAuiToolBar::GetToolBarFits() const
1795{
1796 if (m_items.GetCount() == 0)
1797 {
1798 // empty toolbar always 'fits'
1799 return true;
1800 }
eecf97a5 1801
1154f91b
BW
1802 // entire toolbar content fits if the last tool fits
1803 return GetToolFitsByIndex(m_items.GetCount() - 1);
1804}
1805
1806bool wxAuiToolBar::Realize()
1807{
1808 wxClientDC dc(this);
1809 if (!dc.IsOk())
1810 return false;
1811
e5dcae09
VZ
1812 // calculate hint sizes for both horizontal and vertical
1813 // in the order that leaves toolbar in correct final state
1814 bool retval = false;
1815 if (m_orientation == wxHORIZONTAL)
1816 {
1817 if (RealizeHelper(dc, false))
1818 {
1819 m_vertHintSize = GetSize();
1820 if (RealizeHelper(dc, true))
1821 {
1822 m_horzHintSize = GetSize();
1823 retval = true;
1824 }
1825 }
1826 }
1827 else
1828 {
1829 if (RealizeHelper(dc, true))
1830 {
1831 m_horzHintSize = GetSize();
1832 if (RealizeHelper(dc, false))
1833 {
1834 m_vertHintSize = GetSize();
1835 retval = true;
1836 }
1837 }
1838 }
eecf97a5 1839
e5dcae09
VZ
1840 Refresh(false);
1841 return retval;
1842}
eecf97a5 1843
e5dcae09
VZ
1844bool wxAuiToolBar::RealizeHelper(wxClientDC& dc, bool horizontal)
1845{
1154f91b
BW
1846 // create the new sizer to add toolbar elements to
1847 wxBoxSizer* sizer = new wxBoxSizer(horizontal ? wxHORIZONTAL : wxVERTICAL);
eecf97a5 1848
1154f91b 1849 // add gripper area
9a29fe70
VZ
1850 int separatorSize = m_art->GetElementSize(wxAUI_TBART_SEPARATOR_SIZE);
1851 int gripperSize = m_art->GetElementSize(wxAUI_TBART_GRIPPER_SIZE);
1852 if (gripperSize > 0 && m_gripperVisible)
1154f91b
BW
1853 {
1854 if (horizontal)
9a29fe70 1855 m_gripperSizerItem = sizer->Add(gripperSize, 1, 0, wxEXPAND);
8b385bf8 1856 else
9a29fe70 1857 m_gripperSizerItem = sizer->Add(1, gripperSize, 0, wxEXPAND);
1154f91b 1858 }
8b385bf8 1859 else
1154f91b 1860 {
9a29fe70 1861 m_gripperSizerItem = NULL;
1154f91b 1862 }
eecf97a5 1863
1154f91b 1864 // add "left" padding
9a29fe70 1865 if (m_leftPadding > 0)
1154f91b
BW
1866 {
1867 if (horizontal)
9a29fe70 1868 sizer->Add(m_leftPadding, 1);
8b385bf8 1869 else
9a29fe70 1870 sizer->Add(1, m_leftPadding);
1154f91b 1871 }
eecf97a5 1872
1154f91b
BW
1873 size_t i, count;
1874 for (i = 0, count = m_items.GetCount(); i < count; ++i)
1875 {
1876 wxAuiToolBarItem& item = m_items.Item(i);
9a29fe70 1877 wxSizerItem* m_sizerItem = NULL;
eecf97a5 1878
9a29fe70 1879 switch (item.m_kind)
eecf97a5 1880 {
1154f91b
BW
1881 case wxITEM_LABEL:
1882 {
1883 wxSize size = m_art->GetLabelSize(dc, this, item);
9a29fe70
VZ
1884 m_sizerItem = sizer->Add(size.x + (m_toolBorderPadding*2),
1885 size.y + (m_toolBorderPadding*2),
1886 item.m_proportion,
1887 item.m_alignment);
1154f91b
BW
1888 if (i+1 < count)
1889 {
9a29fe70 1890 sizer->AddSpacer(m_toolPacking);
1154f91b 1891 }
eecf97a5 1892
1154f91b
BW
1893 break;
1894 }
eecf97a5 1895
1154f91b
BW
1896 case wxITEM_CHECK:
1897 case wxITEM_NORMAL:
cae51973 1898 case wxITEM_RADIO:
1154f91b
BW
1899 {
1900 wxSize size = m_art->GetToolSize(dc, this, item);
9a29fe70
VZ
1901 m_sizerItem = sizer->Add(size.x + (m_toolBorderPadding*2),
1902 size.y + (m_toolBorderPadding*2),
1154f91b 1903 0,
9a29fe70 1904 item.m_alignment);
1154f91b
BW
1905 // add tool packing
1906 if (i+1 < count)
1907 {
9a29fe70 1908 sizer->AddSpacer(m_toolPacking);
1154f91b 1909 }
eecf97a5 1910
1154f91b
BW
1911 break;
1912 }
eecf97a5 1913
1154f91b
BW
1914 case wxITEM_SEPARATOR:
1915 {
1916 if (horizontal)
9a29fe70 1917 m_sizerItem = sizer->Add(separatorSize, 1, 0, wxEXPAND);
8b385bf8 1918 else
9a29fe70 1919 m_sizerItem = sizer->Add(1, separatorSize, 0, wxEXPAND);
1154f91b
BW
1920
1921 // add tool packing
1922 if (i+1 < count)
1923 {
9a29fe70 1924 sizer->AddSpacer(m_toolPacking);
1154f91b 1925 }
eecf97a5 1926
1154f91b
BW
1927 break;
1928 }
eecf97a5 1929
1154f91b 1930 case wxITEM_SPACER:
9a29fe70
VZ
1931 if (item.m_proportion > 0)
1932 m_sizerItem = sizer->AddStretchSpacer(item.m_proportion);
8b385bf8 1933 else
9a29fe70 1934 m_sizerItem = sizer->Add(item.m_spacerPixels, 1);
1154f91b 1935 break;
eecf97a5 1936
1154f91b
BW
1937 case wxITEM_CONTROL:
1938 {
9a29fe70
VZ
1939 //m_sizerItem = sizer->Add(item.m_window, item.m_proportion, wxEXPAND);
1940 wxSizerItem* ctrl_m_sizerItem;
eecf97a5 1941
1154f91b
BW
1942 wxBoxSizer* vert_sizer = new wxBoxSizer(wxVERTICAL);
1943 vert_sizer->AddStretchSpacer(1);
9a29fe70 1944 ctrl_m_sizerItem = vert_sizer->Add(item.m_window, 0, wxEXPAND);
1154f91b 1945 vert_sizer->AddStretchSpacer(1);
23511cdb 1946 if ( (m_style & wxAUI_TB_TEXT) &&
9a29fe70 1947 m_toolTextOrientation == wxAUI_TBTOOL_TEXT_BOTTOM &&
23511cdb 1948 !item.GetLabel().empty() )
1154f91b 1949 {
e42f2c16 1950 wxSize s = GetLabelSize(item.GetLabel());
1154f91b
BW
1951 vert_sizer->Add(1, s.y);
1952 }
eecf97a5
VZ
1953
1954
9a29fe70 1955 m_sizerItem = sizer->Add(vert_sizer, item.m_proportion, wxEXPAND);
eecf97a5 1956
9a29fe70 1957 wxSize min_size = item.m_minSize;
eecf97a5 1958
1154f91b
BW
1959
1960 // proportional items will disappear from the toolbar if
1961 // their min width is not set to something really small
9a29fe70 1962 if (item.m_proportion != 0)
1154f91b
BW
1963 {
1964 min_size.x = 1;
1965 }
eecf97a5 1966
1154f91b
BW
1967 if (min_size.IsFullySpecified())
1968 {
9a29fe70
VZ
1969 m_sizerItem->SetMinSize(min_size);
1970 ctrl_m_sizerItem->SetMinSize(min_size);
1154f91b
BW
1971 }
1972
1973 // add tool packing
1974 if (i+1 < count)
1975 {
9a29fe70 1976 sizer->AddSpacer(m_toolPacking);
1154f91b
BW
1977 }
1978 }
1979 }
eecf97a5 1980
9a29fe70 1981 item.m_sizerItem = m_sizerItem;
1154f91b
BW
1982 }
1983
1984 // add "right" padding
9a29fe70 1985 if (m_rightPadding > 0)
1154f91b
BW
1986 {
1987 if (horizontal)
9a29fe70 1988 sizer->Add(m_rightPadding, 1);
8b385bf8 1989 else
9a29fe70 1990 sizer->Add(1, m_rightPadding);
1154f91b 1991 }
eecf97a5 1992
1154f91b 1993 // add drop down area
9a29fe70 1994 m_overflowSizerItem = NULL;
eecf97a5 1995
1154f91b
BW
1996 if (m_style & wxAUI_TB_OVERFLOW)
1997 {
1998 int overflow_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
9a29fe70 1999 if (overflow_size > 0 && m_overflowVisible)
1154f91b
BW
2000 {
2001 if (horizontal)
9a29fe70 2002 m_overflowSizerItem = sizer->Add(overflow_size, 1, 0, wxEXPAND);
8b385bf8 2003 else
9a29fe70 2004 m_overflowSizerItem = sizer->Add(1, overflow_size, 0, wxEXPAND);
1154f91b 2005 }
8b385bf8 2006 else
1154f91b 2007 {
9a29fe70 2008 m_overflowSizerItem = NULL;
1154f91b
BW
2009 }
2010 }
eecf97a5 2011
1154f91b
BW
2012
2013 // the outside sizer helps us apply the "top" and "bottom" padding
2014 wxBoxSizer* outside_sizer = new wxBoxSizer(horizontal ? wxVERTICAL : wxHORIZONTAL);
eecf97a5 2015
1154f91b 2016 // add "top" padding
9a29fe70 2017 if (m_topPadding > 0)
1154f91b
BW
2018 {
2019 if (horizontal)
9a29fe70 2020 outside_sizer->Add(1, m_topPadding);
8b385bf8 2021 else
9a29fe70 2022 outside_sizer->Add(m_topPadding, 1);
1154f91b
BW
2023 }
2024
2025 // add the sizer that contains all of the toolbar elements
2026 outside_sizer->Add(sizer, 1, wxEXPAND);
eecf97a5 2027
1154f91b 2028 // add "bottom" padding
9a29fe70 2029 if (m_bottomPadding > 0)
1154f91b
BW
2030 {
2031 if (horizontal)
9a29fe70 2032 outside_sizer->Add(1, m_bottomPadding);
8b385bf8 2033 else
9a29fe70 2034 outside_sizer->Add(m_bottomPadding, 1);
1154f91b 2035 }
eecf97a5 2036
1154f91b
BW
2037 delete m_sizer; // remove old sizer
2038 m_sizer = outside_sizer;
eecf97a5 2039
1154f91b
BW
2040 // calculate the rock-bottom minimum size
2041 for (i = 0, count = m_items.GetCount(); i < count; ++i)
2042 {
2043 wxAuiToolBarItem& item = m_items.Item(i);
9a29fe70
VZ
2044 if (item.m_sizerItem && item.m_proportion > 0 && item.m_minSize.IsFullySpecified())
2045 item.m_sizerItem->SetMinSize(0,0);
1154f91b 2046 }
eecf97a5 2047
9a29fe70 2048 m_absoluteMinSize = m_sizer->GetMinSize();
eecf97a5 2049
1154f91b
BW
2050 // reset the min sizes to what they were
2051 for (i = 0, count = m_items.GetCount(); i < count; ++i)
2052 {
2053 wxAuiToolBarItem& item = m_items.Item(i);
9a29fe70
VZ
2054 if (item.m_sizerItem && item.m_proportion > 0 && item.m_minSize.IsFullySpecified())
2055 item.m_sizerItem->SetMinSize(item.m_minSize);
eecf97a5 2056 }
1154f91b
BW
2057
2058 // set control size
2059 wxSize size = m_sizer->GetMinSize();
2060 m_minWidth = size.x;
2061 m_minHeight = size.y;
eecf97a5 2062
1154f91b
BW
2063 if ((m_style & wxAUI_TB_NO_AUTORESIZE) == 0)
2064 {
9a29fe70 2065 wxSize curSize = GetClientSize();
1154f91b 2066 wxSize new_size = GetMinSize();
9a29fe70 2067 if (new_size != curSize)
1154f91b
BW
2068 {
2069 SetClientSize(new_size);
2070 }
8b385bf8 2071 else
1154f91b 2072 {
9a29fe70 2073 m_sizer->SetDimension(0, 0, curSize.x, curSize.y);
1154f91b 2074 }
eecf97a5 2075 }
8b385bf8 2076 else
1154f91b 2077 {
9a29fe70
VZ
2078 wxSize curSize = GetClientSize();
2079 m_sizer->SetDimension(0, 0, curSize.x, curSize.y);
1154f91b 2080 }
eecf97a5 2081
1154f91b
BW
2082 return true;
2083}
2084
2085int wxAuiToolBar::GetOverflowState() const
2086{
9a29fe70 2087 return m_overflowState;
1154f91b
BW
2088}
2089
2090wxRect wxAuiToolBar::GetOverflowRect() const
eecf97a5 2091{
1154f91b 2092 wxRect cli_rect(wxPoint(0,0), GetClientSize());
9a29fe70 2093 wxRect overflow_rect = m_overflowSizerItem->GetRect();
1154f91b
BW
2094 int overflow_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
2095
e5dcae09 2096 if (m_orientation == wxVERTICAL)
1154f91b
BW
2097 {
2098 overflow_rect.y = cli_rect.height - overflow_size;
2099 overflow_rect.x = 0;
2100 overflow_rect.width = cli_rect.width;
2101 overflow_rect.height = overflow_size;
2102 }
8b385bf8 2103 else
1154f91b
BW
2104 {
2105 overflow_rect.x = cli_rect.width - overflow_size;
2106 overflow_rect.y = 0;
2107 overflow_rect.width = overflow_size;
2108 overflow_rect.height = cli_rect.height;
2109 }
eecf97a5 2110
1154f91b
BW
2111 return overflow_rect;
2112}
2113
2114wxSize wxAuiToolBar::GetLabelSize(const wxString& label)
2115{
2116 wxClientDC dc(this);
eecf97a5 2117
1154f91b 2118 int tx, ty;
9a29fe70 2119 int textWidth = 0, textHeight = 0;
1154f91b
BW
2120
2121 dc.SetFont(m_font);
eecf97a5 2122
1154f91b 2123 // get the text height
9a29fe70 2124 dc.GetTextExtent(wxT("ABCDHgj"), &tx, &textHeight);
1154f91b
BW
2125
2126 // get the text width
9a29fe70 2127 dc.GetTextExtent(label, &textWidth, &ty);
1154f91b 2128
9a29fe70 2129 return wxSize(textWidth, textHeight);
1154f91b
BW
2130}
2131
2132
2133void wxAuiToolBar::DoIdleUpdate()
2134{
2135 wxEvtHandler* handler = GetEventHandler();
2136
2137 bool need_refresh = false;
2138
2139 size_t i, count;
2140 for (i = 0, count = m_items.GetCount(); i < count; ++i)
2141 {
2142 wxAuiToolBarItem& item = m_items.Item(i);
eecf97a5 2143
9a29fe70 2144 if (item.m_toolId == -1)
1154f91b 2145 continue;
eecf97a5 2146
9a29fe70 2147 wxUpdateUIEvent evt(item.m_toolId);
1154f91b
BW
2148 evt.SetEventObject(this);
2149
2150 if (handler->ProcessEvent(evt))
2151 {
2152 if (evt.GetSetEnabled())
2153 {
2154 bool is_enabled;
9a29fe70 2155 if (item.m_window)
03dc350f 2156 is_enabled = item.m_window->IsThisEnabled();
8b385bf8 2157 else
9a29fe70 2158 is_enabled = (item.m_state & wxAUI_BUTTON_STATE_DISABLED) ? false : true;
eecf97a5 2159
1154f91b
BW
2160 bool new_enabled = evt.GetEnabled();
2161 if (new_enabled != is_enabled)
2162 {
9a29fe70 2163 if (item.m_window)
1154f91b 2164 {
9a29fe70 2165 item.m_window->Enable(new_enabled);
1154f91b 2166 }
8b385bf8 2167 else
1154f91b
BW
2168 {
2169 if (new_enabled)
9a29fe70 2170 item.m_state &= ~wxAUI_BUTTON_STATE_DISABLED;
8b385bf8 2171 else
9a29fe70 2172 item.m_state |= wxAUI_BUTTON_STATE_DISABLED;
1154f91b
BW
2173 }
2174 need_refresh = true;
2175 }
2176 }
eecf97a5 2177
1154f91b
BW
2178 if (evt.GetSetChecked())
2179 {
2180 // make sure we aren't checking an item that can't be
9a29fe70 2181 if (item.m_kind != wxITEM_CHECK && item.m_kind != wxITEM_RADIO)
1154f91b
BW
2182 continue;
2183
9a29fe70 2184 bool is_checked = (item.m_state & wxAUI_BUTTON_STATE_CHECKED) ? true : false;
1154f91b
BW
2185 bool new_checked = evt.GetChecked();
2186
2187 if (new_checked != is_checked)
2188 {
2189 if (new_checked)
9a29fe70 2190 item.m_state |= wxAUI_BUTTON_STATE_CHECKED;
8b385bf8 2191 else
9a29fe70 2192 item.m_state &= ~wxAUI_BUTTON_STATE_CHECKED;
eecf97a5 2193
1154f91b
BW
2194 need_refresh = true;
2195 }
2196 }
2197
2198 }
2199 }
eecf97a5 2200
1154f91b
BW
2201
2202 if (need_refresh)
2203 {
2204 Refresh(false);
2205 }
2206}
2207
2208
2209void wxAuiToolBar::OnSize(wxSizeEvent& WXUNUSED(evt))
2210{
2211 int x, y;
2212 GetClientSize(&x, &y);
2213
9a29fe70
VZ
2214 if (((x >= y) && m_absoluteMinSize.x > x) ||
2215 ((y > x) && m_absoluteMinSize.y > y))
1154f91b
BW
2216 {
2217 // hide all flexible items
2218 size_t i, count;
2219 for (i = 0, count = m_items.GetCount(); i < count; ++i)
2220 {
2221 wxAuiToolBarItem& item = m_items.Item(i);
9a29fe70 2222 if (item.m_sizerItem && item.m_proportion > 0 && item.m_sizerItem->IsShown())
1154f91b 2223 {
9a29fe70
VZ
2224 item.m_sizerItem->Show(false);
2225 item.m_sizerItem->SetProportion(0);
1154f91b
BW
2226 }
2227 }
2228 }
8b385bf8 2229 else
1154f91b
BW
2230 {
2231 // show all flexible items
2232 size_t i, count;
2233 for (i = 0, count = m_items.GetCount(); i < count; ++i)
2234 {
2235 wxAuiToolBarItem& item = m_items.Item(i);
9a29fe70 2236 if (item.m_sizerItem && item.m_proportion > 0 && !item.m_sizerItem->IsShown())
1154f91b 2237 {
9a29fe70
VZ
2238 item.m_sizerItem->Show(true);
2239 item.m_sizerItem->SetProportion(item.m_proportion);
1154f91b
BW
2240 }
2241 }
2242 }
2243
2244 m_sizer->SetDimension(0, 0, x, y);
2245
2246 Refresh(false);
2247 Update();
e5dcae09
VZ
2248
2249 // idle events aren't sent while user is resizing frame (why?),
2250 // but resizing toolbar here causes havoc,
2251 // so force idle handler to run after size handling complete
2252 QueueEvent(new wxIdleEvent);
1154f91b
BW
2253}
2254
2255
2256
2257void wxAuiToolBar::DoSetSize(int x,
2258 int y,
2259 int width,
2260 int height,
2261 int sizeFlags)
2262{
2263 wxSize parent_size = GetParent()->GetClientSize();
2264 if (x + width > parent_size.x)
2265 width = wxMax(0, parent_size.x - x);
2266 if (y + height > parent_size.y)
2267 height = wxMax(0, parent_size.y - y);
2268
2269 wxWindow::DoSetSize(x, y, width, height, sizeFlags);
2270}
2271
2272
2273void wxAuiToolBar::OnIdle(wxIdleEvent& evt)
2274{
e5dcae09
VZ
2275 // if orientation doesn't match dock, fix it
2276 wxAuiManager* manager = wxAuiManager::GetManager(this);
2277 if (manager)
2278 {
2279 wxAuiPaneInfo& pane = manager->GetPane(this);
2280 // pane state member is public, so it might have been changed
2281 // without going through wxPaneInfo::SetFlag() check
2282 bool ok = pane.IsOk();
2283 wxCHECK2_MSG(!ok || IsPaneValid(m_style, pane), ok = false,
2284 "window settings and pane settings are incompatible");
2285 if (ok)
2286 {
2287 wxOrientation newOrientation = m_orientation;
2288 if (pane.IsDocked())
2289 {
2290 switch (pane.dock_direction)
2291 {
2292 case wxAUI_DOCK_TOP:
2293 case wxAUI_DOCK_BOTTOM:
2294 newOrientation = wxHORIZONTAL;
2295 break;
2296 case wxAUI_DOCK_LEFT:
2297 case wxAUI_DOCK_RIGHT:
2298 newOrientation = wxVERTICAL;
2299 break;
2300 default:
2301 wxFAIL_MSG("invalid dock location value");
2302 }
2303 }
2304 else if (pane.IsResizable() &&
2305 GetOrientation(m_style) == wxBOTH)
2306 {
2307 // changing orientation in OnSize causes havoc
2308 int x, y;
2309 GetClientSize(&x, &y);
2310
2311 if (x > y)
2312 {
2313 newOrientation = wxHORIZONTAL;
2314 }
2315 else
2316 {
2317 newOrientation = wxVERTICAL;
2318 }
2319 }
2320 if (newOrientation != m_orientation)
2321 {
2322 SetOrientation(newOrientation);
2323 Realize();
2324 if (newOrientation == wxHORIZONTAL)
2325 {
2326 pane.best_size = GetHintSize(wxAUI_DOCK_TOP);
2327 }
2328 else
2329 {
2330 pane.best_size = GetHintSize(wxAUI_DOCK_LEFT);
2331 }
2332 if (pane.IsDocked())
2333 {
2334 pane.floating_size = wxDefaultSize;
2335 }
2336 else
2337 {
2338 SetSize(GetParent()->GetClientSize());
2339 }
2340 manager->Update();
2341 }
2342 }
2343 }
1154f91b
BW
2344 evt.Skip();
2345}
2346
3ac17397
VZ
2347void wxAuiToolBar::UpdateWindowUI(long flags)
2348{
2349 if ( flags & wxUPDATE_UI_FROMIDLE )
2350 {
2351 DoIdleUpdate();
2352 }
2353
2354 wxControl::UpdateWindowUI(flags);
2355}
2356
1154f91b
BW
2357void wxAuiToolBar::OnPaint(wxPaintEvent& WXUNUSED(evt))
2358{
66ad3095 2359 wxAutoBufferedPaintDC dc(this);
1154f91b 2360 wxRect cli_rect(wxPoint(0,0), GetClientSize());
eecf97a5
VZ
2361
2362
e5dcae09 2363 bool horizontal = m_orientation == wxHORIZONTAL;
1154f91b
BW
2364
2365
2366 m_art->DrawBackground(dc, this, cli_rect);
eecf97a5 2367
9a29fe70 2368 int gripperSize = m_art->GetElementSize(wxAUI_TBART_GRIPPER_SIZE);
1154f91b 2369 int dropdown_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
eecf97a5 2370
1154f91b 2371 // paint the gripper
9a29fe70 2372 if (gripperSize > 0 && m_gripperSizerItem)
1154f91b 2373 {
9a29fe70 2374 wxRect gripper_rect = m_gripperSizerItem->GetRect();
1154f91b 2375 if (horizontal)
9a29fe70 2376 gripper_rect.width = gripperSize;
8b385bf8 2377 else
9a29fe70 2378 gripper_rect.height = gripperSize;
1154f91b
BW
2379 m_art->DrawGripper(dc, this, gripper_rect);
2380 }
eecf97a5 2381
1154f91b
BW
2382 // calculated how far we can draw items
2383 int last_extent;
2384 if (horizontal)
2385 last_extent = cli_rect.width;
8b385bf8 2386 else
1154f91b 2387 last_extent = cli_rect.height;
9a29fe70 2388 if (m_overflowVisible)
1154f91b 2389 last_extent -= dropdown_size;
eecf97a5 2390
1154f91b
BW
2391 // paint each individual tool
2392 size_t i, count = m_items.GetCount();
2393 for (i = 0; i < count; ++i)
2394 {
2395 wxAuiToolBarItem& item = m_items.Item(i);
eecf97a5 2396
9a29fe70 2397 if (!item.m_sizerItem)
1154f91b 2398 continue;
eecf97a5 2399
9a29fe70 2400 wxRect item_rect = item.m_sizerItem->GetRect();
eecf97a5
VZ
2401
2402
1154f91b
BW
2403 if ((horizontal && item_rect.x + item_rect.width >= last_extent) ||
2404 (!horizontal && item_rect.y + item_rect.height >= last_extent))
2405 {
2406 break;
2407 }
eecf97a5 2408
9a29fe70 2409 if (item.m_kind == wxITEM_SEPARATOR)
1154f91b
BW
2410 {
2411 // draw a separator
2412 m_art->DrawSeparator(dc, this, item_rect);
2413 }
9a29fe70 2414 else if (item.m_kind == wxITEM_LABEL)
1154f91b
BW
2415 {
2416 // draw a text label only
2417 m_art->DrawLabel(dc, this, item, item_rect);
2418 }
9a29fe70 2419 else if (item.m_kind == wxITEM_NORMAL)
1154f91b
BW
2420 {
2421 // draw a regular button or dropdown button
9a29fe70 2422 if (!item.m_dropDown)
1154f91b 2423 m_art->DrawButton(dc, this, item, item_rect);
8b385bf8 2424 else
1154f91b
BW
2425 m_art->DrawDropDownButton(dc, this, item, item_rect);
2426 }
9a29fe70 2427 else if (item.m_kind == wxITEM_CHECK)
1154f91b 2428 {
026c6eff 2429 // draw either a regular or dropdown toggle button
9a29fe70 2430 if (!item.m_dropDown)
026c6eff
VZ
2431 m_art->DrawButton(dc, this, item, item_rect);
2432 else
2433 m_art->DrawDropDownButton(dc, this, item, item_rect);
1154f91b 2434 }
9a29fe70 2435 else if (item.m_kind == wxITEM_RADIO)
cae51973
BW
2436 {
2437 // draw a toggle button
2438 m_art->DrawButton(dc, this, item, item_rect);
2439 }
9a29fe70 2440 else if (item.m_kind == wxITEM_CONTROL)
1154f91b
BW
2441 {
2442 // draw the control's label
2443 m_art->DrawControlLabel(dc, this, item, item_rect);
2444 }
2445
2446 // fire a signal to see if the item wants to be custom-rendered
2447 OnCustomRender(dc, item, item_rect);
2448 }
eecf97a5 2449
1154f91b 2450 // paint the overflow button
9a29fe70 2451 if (dropdown_size > 0 && m_overflowSizerItem)
1154f91b 2452 {
9a29fe70
VZ
2453 wxRect dropDownRect = GetOverflowRect();
2454 m_art->DrawOverflowButton(dc, this, dropDownRect, m_overflowState);
1154f91b
BW
2455 }
2456}
2457
2458void wxAuiToolBar::OnEraseBackground(wxEraseEvent& WXUNUSED(evt))
2459{
2460 // empty
2461}
2462
2463void wxAuiToolBar::OnLeftDown(wxMouseEvent& evt)
2464{
2465 wxRect cli_rect(wxPoint(0,0), GetClientSize());
eecf97a5 2466
9a29fe70 2467 if (m_gripperSizerItem)
1154f91b 2468 {
9a29fe70 2469 wxRect gripper_rect = m_gripperSizerItem->GetRect();
1154f91b
BW
2470 if (gripper_rect.Contains(evt.GetX(), evt.GetY()))
2471 {
2472 // find aui manager
2473 wxAuiManager* manager = wxAuiManager::GetManager(this);
2474 if (!manager)
2475 return;
eecf97a5 2476
1154f91b
BW
2477 int x_drag_offset = evt.GetX() - gripper_rect.GetX();
2478 int y_drag_offset = evt.GetY() - gripper_rect.GetY();
eecf97a5 2479
1154f91b
BW
2480 // gripper was clicked
2481 manager->StartPaneDrag(this, wxPoint(x_drag_offset, y_drag_offset));
2482 return;
2483 }
2484 }
eecf97a5 2485
9a29fe70 2486 if (m_overflowSizerItem)
1154f91b
BW
2487 {
2488 wxRect overflow_rect = GetOverflowRect();
eecf97a5
VZ
2489
2490 if (m_art &&
9a29fe70 2491 m_overflowVisible &&
1154f91b
BW
2492 overflow_rect.Contains(evt.m_x, evt.m_y))
2493 {
2494 wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_OVERFLOW_CLICK, -1);
2495 e.SetEventObject(this);
2496 e.SetToolId(-1);
2497 e.SetClickPoint(wxPoint(evt.GetX(), evt.GetY()));
004867db 2498 bool processed = GetEventHandler()->ProcessEvent(e);
eecf97a5 2499
1154f91b
BW
2500 if (processed)
2501 {
2502 DoIdleUpdate();
2503 }
8b385bf8 2504 else
1154f91b
BW
2505 {
2506 size_t i, count;
2507 wxAuiToolBarItemArray overflow_items;
eecf97a5 2508
1154f91b
BW
2509
2510 // add custom overflow prepend items, if any
9a29fe70 2511 count = m_customOverflowPrepend.GetCount();
1154f91b 2512 for (i = 0; i < count; ++i)
9a29fe70 2513 overflow_items.Add(m_customOverflowPrepend[i]);
eecf97a5 2514
1154f91b
BW
2515 // only show items that don't fit in the dropdown
2516 count = m_items.GetCount();
2517 for (i = 0; i < count; ++i)
2518 {
2519 if (!GetToolFitsByIndex(i))
2520 overflow_items.Add(m_items[i]);
2521 }
2522
2523 // add custom overflow append items, if any
9a29fe70 2524 count = m_customOverflowAppend.GetCount();
1154f91b 2525 for (i = 0; i < count; ++i)
9a29fe70 2526 overflow_items.Add(m_customOverflowAppend[i]);
eecf97a5 2527
1154f91b 2528 int res = m_art->ShowDropDown(this, overflow_items);
9a29fe70 2529 m_overflowState = 0;
1154f91b
BW
2530 Refresh(false);
2531 if (res != -1)
2532 {
2533 wxCommandEvent e(wxEVT_COMMAND_MENU_SELECTED, res);
2534 e.SetEventObject(this);
004867db 2535 GetParent()->GetEventHandler()->ProcessEvent(e);
1154f91b
BW
2536 }
2537 }
eecf97a5 2538
1154f91b
BW
2539 return;
2540 }
2541 }
eecf97a5 2542
1154f91b 2543 m_dragging = false;
9a29fe70
VZ
2544 m_actionPos = wxPoint(evt.GetX(), evt.GetY());
2545 m_actionItem = FindToolByPosition(evt.GetX(), evt.GetY());
eecf97a5 2546
9a29fe70 2547 if (m_actionItem)
1154f91b 2548 {
9a29fe70 2549 if (m_actionItem->m_state & wxAUI_BUTTON_STATE_DISABLED)
1154f91b 2550 {
9a29fe70
VZ
2551 m_actionPos = wxPoint(-1,-1);
2552 m_actionItem = NULL;
1154f91b
BW
2553 return;
2554 }
eecf97a5 2555
4a21ea9d 2556 UnsetToolTip();
eecf97a5 2557
1154f91b 2558 // fire the tool dropdown event
9a29fe70 2559 wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_TOOL_DROPDOWN, m_actionItem->m_toolId);
1154f91b 2560 e.SetEventObject(this);
9a29fe70 2561 e.SetToolId(m_actionItem->m_toolId);
eecf97a5 2562
1154f91b 2563 int mouse_x = evt.GetX();
9a29fe70
VZ
2564 wxRect rect = m_actionItem->m_sizerItem->GetRect();
2565 const bool dropDownHit = m_actionItem->m_dropDown &&
4a21ea9d
VZ
2566 mouse_x >= (rect.x+rect.width-BUTTON_DROPDOWN_WIDTH-1) &&
2567 mouse_x < (rect.x+rect.width);
2568 e.SetDropDownClicked(dropDownHit);
2569
2570 e.SetClickPoint(evt.GetPosition());
2571 e.SetItemRect(rect);
2572
2573 // we only set the 'pressed button' state if we hit the actual button
2574 // and not just the drop-down
9a29fe70 2575 SetPressedItem(dropDownHit ? 0 : m_actionItem);
eecf97a5 2576
4a21ea9d 2577 if(dropDownHit)
1154f91b 2578 {
9a29fe70
VZ
2579 m_actionPos = wxPoint(-1,-1);
2580 m_actionItem = NULL;
1154f91b 2581 }
eecf97a5 2582
4a21ea9d
VZ
2583 if(!GetEventHandler()->ProcessEvent(e) || e.GetSkipped())
2584 CaptureMouse();
2585
c2211811
VZ
2586 // Ensure hovered item is really ok, as mouse may have moved during
2587 // event processing
2588 wxPoint cursor_pos_after_evt = ScreenToClient(wxGetMousePosition());
2589 SetHoverItem(FindToolByPosition(cursor_pos_after_evt.x, cursor_pos_after_evt.y));
2590
1154f91b
BW
2591 DoIdleUpdate();
2592 }
2593}
2594
2595void wxAuiToolBar::OnLeftUp(wxMouseEvent& evt)
2596{
4a21ea9d
VZ
2597 if (!HasCapture())
2598 return;
2599
1154f91b
BW
2600 SetPressedItem(NULL);
2601
c2211811
VZ
2602 wxAuiToolBarItem* hitItem;
2603 hitItem = FindToolByPosition(evt.GetX(), evt.GetY());
2604 SetHoverItem(hitItem);
1154f91b 2605
1154f91b
BW
2606 if (m_dragging)
2607 {
4a21ea9d
VZ
2608 // TODO: it would make sense to send out an 'END_DRAG' event here,
2609 // otherwise a client would never know what to do with the 'BEGIN_DRAG'
2610 // event
2611
2612 // OnCaptureLost() will be called now and this will reset all our state
2613 // tracking variables
2614 ReleaseMouse();
1154f91b 2615 }
8b385bf8 2616 else
1154f91b 2617 {
9a29fe70 2618 if (m_actionItem && hitItem == m_actionItem)
1154f91b 2619 {
8b385bf8 2620 UnsetToolTip();
eecf97a5 2621
9a29fe70 2622 wxCommandEvent e(wxEVT_COMMAND_MENU_SELECTED, m_actionItem->m_toolId);
4a21ea9d
VZ
2623 e.SetEventObject(this);
2624
9a29fe70 2625 if (hitItem->m_kind == wxITEM_CHECK || hitItem->m_kind == wxITEM_RADIO)
1154f91b 2626 {
9a29fe70 2627 const bool toggle = !(m_actionItem->m_state & wxAUI_BUTTON_STATE_CHECKED);
eecf97a5 2628
9a29fe70 2629 ToggleTool(m_actionItem->m_toolId, toggle);
45496810 2630
cae51973
BW
2631 // repaint immediately
2632 Refresh(false);
2633 Update();
45496810 2634
4a21ea9d 2635 e.SetInt(toggle);
1154f91b 2636 }
4a21ea9d
VZ
2637
2638 // we have to release the mouse *before* sending the event, because
2639 // we don't know what a handler might do. It could open up a popup
2640 // menu for example and that would make us lose our capture anyway.
2641
2642 ReleaseMouse();
2643
2644 GetEventHandler()->ProcessEvent(e);
c2211811
VZ
2645
2646 // Ensure hovered item is really ok, as mouse may have moved during
2647 // event processing
2648 wxPoint cursor_pos_after_evt = ScreenToClient(wxGetMousePosition());
2649 SetHoverItem(FindToolByPosition(cursor_pos_after_evt.x, cursor_pos_after_evt.y));
2650
4a21ea9d 2651 DoIdleUpdate();
1154f91b 2652 }
4a21ea9d
VZ
2653 else
2654 ReleaseMouse();
1154f91b 2655 }
1154f91b
BW
2656}
2657
2658void wxAuiToolBar::OnRightDown(wxMouseEvent& evt)
2659{
2660 wxRect cli_rect(wxPoint(0,0), GetClientSize());
eecf97a5 2661
9a29fe70 2662 if (m_gripperSizerItem)
1154f91b 2663 {
9a29fe70 2664 wxRect gripper_rect = m_gripperSizerItem->GetRect();
1154f91b
BW
2665 if (gripper_rect.Contains(evt.GetX(), evt.GetY()))
2666 return;
2667 }
eecf97a5 2668
f90b69e0 2669 if (m_overflowSizerItem && m_art)
1154f91b
BW
2670 {
2671 int dropdown_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
2672 if (dropdown_size > 0 &&
2673 evt.m_x > cli_rect.width - dropdown_size &&
2674 evt.m_y >= 0 &&
f90b69e0 2675 evt.m_y < cli_rect.height)
1154f91b
BW
2676 {
2677 return;
2678 }
2679 }
eecf97a5 2680
9a29fe70
VZ
2681 m_actionPos = wxPoint(evt.GetX(), evt.GetY());
2682 m_actionItem = FindToolByPosition(evt.GetX(), evt.GetY());
eecf97a5 2683
9a29fe70 2684 if (m_actionItem && m_actionItem->m_state & wxAUI_BUTTON_STATE_DISABLED)
1154f91b 2685 {
9a29fe70
VZ
2686 m_actionPos = wxPoint(-1,-1);
2687 m_actionItem = NULL;
4a21ea9d 2688 return;
1154f91b 2689 }
4a21ea9d
VZ
2690
2691 UnsetToolTip();
1154f91b
BW
2692}
2693
2694void wxAuiToolBar::OnRightUp(wxMouseEvent& evt)
2695{
9a29fe70
VZ
2696 wxAuiToolBarItem* hitItem;
2697 hitItem = FindToolByPosition(evt.GetX(), evt.GetY());
eecf97a5 2698
9a29fe70 2699 if (m_actionItem && hitItem == m_actionItem)
1154f91b 2700 {
f5fccd52
VZ
2701 wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_RIGHT_CLICK, m_actionItem->m_toolId);
2702 e.SetEventObject(this);
2703 e.SetToolId(m_actionItem->m_toolId);
2704 e.SetClickPoint(m_actionPos);
2705 GetEventHandler()->ProcessEvent(e);
2706 DoIdleUpdate();
1154f91b 2707 }
8b385bf8 2708 else
1154f91b
BW
2709 {
2710 // right-clicked on the invalid area of the toolbar
2711 wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_RIGHT_CLICK, -1);
2712 e.SetEventObject(this);
2713 e.SetToolId(-1);
9a29fe70 2714 e.SetClickPoint(m_actionPos);
004867db 2715 GetEventHandler()->ProcessEvent(e);
1154f91b
BW
2716 DoIdleUpdate();
2717 }
2718
2719 // reset member variables
9a29fe70
VZ
2720 m_actionPos = wxPoint(-1,-1);
2721 m_actionItem = NULL;
1154f91b
BW
2722}
2723
2724void wxAuiToolBar::OnMiddleDown(wxMouseEvent& evt)
2725{
2726 wxRect cli_rect(wxPoint(0,0), GetClientSize());
eecf97a5 2727
9a29fe70 2728 if (m_gripperSizerItem)
1154f91b 2729 {
9a29fe70 2730 wxRect gripper_rect = m_gripperSizerItem->GetRect();
1154f91b
BW
2731 if (gripper_rect.Contains(evt.GetX(), evt.GetY()))
2732 return;
2733 }
eecf97a5 2734
f90b69e0 2735 if (m_overflowSizerItem && m_art)
1154f91b
BW
2736 {
2737 int dropdown_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
2738 if (dropdown_size > 0 &&
2739 evt.m_x > cli_rect.width - dropdown_size &&
2740 evt.m_y >= 0 &&
f90b69e0 2741 evt.m_y < cli_rect.height)
1154f91b
BW
2742 {
2743 return;
2744 }
2745 }
eecf97a5 2746
9a29fe70
VZ
2747 m_actionPos = wxPoint(evt.GetX(), evt.GetY());
2748 m_actionItem = FindToolByPosition(evt.GetX(), evt.GetY());
eecf97a5 2749
9a29fe70 2750 if (m_actionItem)
1154f91b 2751 {
9a29fe70 2752 if (m_actionItem->m_state & wxAUI_BUTTON_STATE_DISABLED)
1154f91b 2753 {
9a29fe70
VZ
2754 m_actionPos = wxPoint(-1,-1);
2755 m_actionItem = NULL;
1154f91b
BW
2756 return;
2757 }
2758 }
4a21ea9d
VZ
2759
2760 UnsetToolTip();
1154f91b
BW
2761}
2762
2763void wxAuiToolBar::OnMiddleUp(wxMouseEvent& evt)
2764{
9a29fe70
VZ
2765 wxAuiToolBarItem* hitItem;
2766 hitItem = FindToolByPosition(evt.GetX(), evt.GetY());
eecf97a5 2767
9a29fe70 2768 if (m_actionItem && hitItem == m_actionItem)
1154f91b 2769 {
9a29fe70 2770 if (hitItem->m_kind == wxITEM_NORMAL)
1154f91b 2771 {
9a29fe70 2772 wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_MIDDLE_CLICK, m_actionItem->m_toolId);
1154f91b 2773 e.SetEventObject(this);
9a29fe70
VZ
2774 e.SetToolId(m_actionItem->m_toolId);
2775 e.SetClickPoint(m_actionPos);
004867db 2776 GetEventHandler()->ProcessEvent(e);
1154f91b
BW
2777 DoIdleUpdate();
2778 }
2779 }
2780
2781 // reset member variables
9a29fe70
VZ
2782 m_actionPos = wxPoint(-1,-1);
2783 m_actionItem = NULL;
1154f91b
BW
2784}
2785
2786void wxAuiToolBar::OnMotion(wxMouseEvent& evt)
2787{
4a21ea9d
VZ
2788 const bool button_pressed = HasCapture();
2789
1154f91b 2790 // start a drag event
4a21ea9d 2791 if (!m_dragging && button_pressed &&
9a29fe70 2792 abs(evt.GetX() - m_actionPos.x) + abs(evt.GetY() - m_actionPos.y) > 5)
1154f91b 2793 {
4a21ea9d
VZ
2794 // TODO: sending this event only makes sense if there is an 'END_DRAG'
2795 // event sent sometime in the future (see OnLeftUp())
1154f91b
BW
2796 wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_BEGIN_DRAG, GetId());
2797 e.SetEventObject(this);
9a29fe70 2798 e.SetToolId(m_actionItem->m_toolId);
4a21ea9d
VZ
2799 m_dragging = GetEventHandler()->ProcessEvent(e) && !e.GetSkipped();
2800
1154f91b 2801 DoIdleUpdate();
1154f91b
BW
2802 }
2803
4a21ea9d
VZ
2804 if(m_dragging)
2805 return;
2806
9a29fe70 2807 wxAuiToolBarItem* hitItem = FindToolByPosition(evt.GetX(), evt.GetY());
4a21ea9d 2808 if(button_pressed)
1154f91b 2809 {
4a21ea9d
VZ
2810 // if we have a button pressed we want it to be shown in 'depressed'
2811 // state unless we move the mouse outside the button, then we want it
2812 // to show as just 'highlighted'
9a29fe70
VZ
2813 if (hitItem == m_actionItem)
2814 SetPressedItem(m_actionItem);
8b385bf8 2815 else
4a21ea9d
VZ
2816 {
2817 SetPressedItem(NULL);
9a29fe70 2818 SetHoverItem(m_actionItem);
4a21ea9d 2819 }
1154f91b 2820 }
8b385bf8 2821 else
1154f91b 2822 {
c2211811 2823 SetHoverItem(hitItem);
eecf97a5 2824
4a21ea9d 2825 // tooltips handling
9a29fe70
VZ
2826 wxAuiToolBarItem* packingHitItem;
2827 packingHitItem = FindToolByPositionWithPacking(evt.GetX(), evt.GetY());
2828 if (packingHitItem)
1154f91b 2829 {
9a29fe70 2830 if (packingHitItem != m_tipItem)
4a21ea9d 2831 {
9a29fe70 2832 m_tipItem = packingHitItem;
eecf97a5 2833
9a29fe70
VZ
2834 if ( !packingHitItem->m_shortHelp.empty() )
2835 SetToolTip(packingHitItem->m_shortHelp);
4a21ea9d
VZ
2836 else
2837 UnsetToolTip();
2838 }
1154f91b 2839 }
8b385bf8 2840 else
4a21ea9d
VZ
2841 {
2842 UnsetToolTip();
9a29fe70 2843 m_tipItem = NULL;
4a21ea9d 2844 }
eecf97a5 2845
4a21ea9d
VZ
2846 // figure out the dropdown button state (are we hovering or pressing it?)
2847 RefreshOverflowState();
2848 }
1154f91b
BW
2849}
2850
4a21ea9d 2851void wxAuiToolBar::DoResetMouseState()
1154f91b
BW
2852{
2853 RefreshOverflowState();
2854 SetHoverItem(NULL);
2855 SetPressedItem(NULL);
eecf97a5 2856
9a29fe70 2857 m_tipItem = NULL;
4a21ea9d
VZ
2858
2859 // we have to reset those here, because the mouse-up handlers which do
2860 // it usually won't be called if we let go of a mouse button while we
2861 // are outside of the window
9a29fe70
VZ
2862 m_actionPos = wxPoint(-1,-1);
2863 m_actionItem = NULL;
1154f91b
BW
2864}
2865
4a21ea9d
VZ
2866void wxAuiToolBar::OnLeaveWindow(wxMouseEvent& evt)
2867{
2868 if(HasCapture())
2869 {
2870 evt.Skip();
2871 return;
2872 }
2873
2874 DoResetMouseState();
2875}
2876
2877void wxAuiToolBar::OnCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(evt))
2878{
2879 m_dragging = false;
2880
2881 DoResetMouseState();
2882}
1154f91b
BW
2883
2884void wxAuiToolBar::OnSetCursor(wxSetCursorEvent& evt)
2885{
2886 wxCursor cursor = wxNullCursor;
eecf97a5 2887
9a29fe70 2888 if (m_gripperSizerItem)
1154f91b 2889 {
9a29fe70 2890 wxRect gripper_rect = m_gripperSizerItem->GetRect();
1154f91b
BW
2891 if (gripper_rect.Contains(evt.GetX(), evt.GetY()))
2892 {
2893 cursor = wxCursor(wxCURSOR_SIZING);
2894 }
2895 }
eecf97a5 2896
1154f91b
BW
2897 evt.SetCursor(cursor);
2898}
2899
2900
2901#endif // wxUSE_AUI
2902