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