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