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