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