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