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: auibar.cpp 66926 2011-02-16 23:25:21Z JS $
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/mac/carbon/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 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUITOOLBAR_TOOL_DROPDOWN)
50 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUITOOLBAR_OVERFLOW_CLICK)
51 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUITOOLBAR_RIGHT_CLICK)
52 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUITOOLBAR_MIDDLE_CLICK)
53 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUITOOLBAR_BEGIN_DRAG)
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 
MakeDisabledBitmap(wxBitmap & bmp)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 
GetBaseColor()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 
ToolbarCommandCapture()139     ToolbarCommandCapture() { m_last_id = 0; }
GetCommandId() const140     int GetCommandId() const { return m_last_id; }
141 
ProcessEvent(wxEvent & evt)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 
wxAuiDefaultToolBarArt()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 
~wxAuiDefaultToolBarArt()204 wxAuiDefaultToolBarArt::~wxAuiDefaultToolBarArt()
205 {
206     m_font = *wxNORMAL_FONT;
207 }
208 
209 
Clone()210 wxAuiToolBarArt* wxAuiDefaultToolBarArt::Clone()
211 {
212     return static_cast<wxAuiToolBarArt*>(new wxAuiDefaultToolBarArt);
213 }
214 
SetFlags(unsigned int flags)215 void wxAuiDefaultToolBarArt::SetFlags(unsigned int flags)
216 {
217     m_flags = flags;
218 }
219 
SetFont(const wxFont & font)220 void wxAuiDefaultToolBarArt::SetFont(const wxFont& font)
221 {
222     m_font = font;
223 }
224 
SetTextOrientation(int orientation)225 void wxAuiDefaultToolBarArt::SetTextOrientation(int orientation)
226 {
227     m_text_orientation = orientation;
228 }
229 
DrawBackground(wxDC & dc,wxWindow * WXUNUSED (wnd),const wxRect & _rect)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 
DrawLabel(wxDC & dc,wxWindow * WXUNUSED (wnd),const wxAuiToolBarItem & item,const wxRect & rect)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 
DrawButton(wxDC & dc,wxWindow * WXUNUSED (wnd),const wxAuiToolBarItem & item,const wxRect & rect)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 
DrawDropDownButton(wxDC & dc,wxWindow * WXUNUSED (wnd),const wxAuiToolBarItem & item,const wxRect & rect)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 
DrawControlLabel(wxDC & dc,wxWindow * WXUNUSED (wnd),const wxAuiToolBarItem & item,const wxRect & rect)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 
GetLabelSize(wxDC & dc,wxWindow * WXUNUSED (wnd),const wxAuiToolBarItem & item)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     if (width == -1)
544     {
545         // no width specified, measure the text ourselves
546         width = dc.GetTextExtent(item.GetLabel()).GetX();
547     }
548 
549     return wxSize(width, height);
550 }
551 
GetToolSize(wxDC & dc,wxWindow * WXUNUSED (wnd),const wxAuiToolBarItem & item)552 wxSize wxAuiDefaultToolBarArt::GetToolSize(
553                                         wxDC& dc,
554                                         wxWindow* WXUNUSED(wnd),
555                                         const wxAuiToolBarItem& item)
556 {
557     if (!item.GetBitmap().IsOk() && !(m_flags & wxAUI_TB_TEXT))
558         return wxSize(16,16);
559 
560     int width = item.GetBitmap().GetWidth();
561     int height = item.GetBitmap().GetHeight();
562 
563     if (m_flags & wxAUI_TB_TEXT)
564     {
565         dc.SetFont(m_font);
566         int tx, ty;
567 
568         if (m_text_orientation == wxAUI_TBTOOL_TEXT_BOTTOM)
569         {
570             dc.GetTextExtent(wxT("ABCDHgj"), &tx, &ty);
571             height += ty;
572 
573             if ( !item.GetLabel().empty() )
574             {
575                 dc.GetTextExtent(item.GetLabel(), &tx, &ty);
576                 width = wxMax(width, tx+6);
577             }
578         }
579         else if ( m_text_orientation == wxAUI_TBTOOL_TEXT_RIGHT &&
580                   !item.GetLabel().empty() )
581         {
582             width += 3; // space between left border and bitmap
583             width += 3; // space between bitmap and text
584 
585             if ( !item.GetLabel().empty() )
586             {
587                 dc.GetTextExtent(item.GetLabel(), &tx, &ty);
588                 width += tx;
589                 height = wxMax(height, ty);
590             }
591         }
592     }
593 
594     // if the tool has a dropdown button, add it to the width
595     if (item.HasDropDown())
596         width += (BUTTON_DROPDOWN_WIDTH+4);
597 
598     return wxSize(width, height);
599 }
600 
DrawSeparator(wxDC & dc,wxWindow * WXUNUSED (wnd),const wxRect & _rect)601 void wxAuiDefaultToolBarArt::DrawSeparator(
602                                     wxDC& dc,
603                                     wxWindow* WXUNUSED(wnd),
604                                     const wxRect& _rect)
605 {
606     bool horizontal = true;
607     if (m_flags & wxAUI_TB_VERTICAL)
608         horizontal = false;
609 
610     wxRect rect = _rect;
611 
612     if (horizontal)
613     {
614         rect.x += (rect.width/2);
615         rect.width = 1;
616         int new_height = (rect.height*3)/4;
617         rect.y += (rect.height/2) - (new_height/2);
618         rect.height = new_height;
619     }
620     else
621     {
622         rect.y += (rect.height/2);
623         rect.height = 1;
624         int new_width = (rect.width*3)/4;
625         rect.x += (rect.width/2) - (new_width/2);
626         rect.width = new_width;
627     }
628 
629     wxColour start_colour = wxAuiStepColour(m_base_colour, 80);
630     wxColour end_colour = wxAuiStepColour(m_base_colour, 80);
631     dc.GradientFillLinear(rect, start_colour, end_colour, horizontal ? wxSOUTH : wxEAST);
632 }
633 
DrawGripper(wxDC & dc,wxWindow * WXUNUSED (wnd),const wxRect & rect)634 void wxAuiDefaultToolBarArt::DrawGripper(wxDC& dc,
635                                     wxWindow* WXUNUSED(wnd),
636                                     const wxRect& rect)
637 {
638     int i = 0;
639     while (1)
640     {
641         int x, y;
642 
643         if (m_flags & wxAUI_TB_VERTICAL)
644         {
645             x = rect.x + (i*4) + 5;
646             y = rect.y + 3;
647             if (x > rect.GetWidth()-5)
648                 break;
649         }
650         else
651         {
652             x = rect.x + 3;
653             y = rect.y + (i*4) + 5;
654             if (y > rect.GetHeight()-5)
655                 break;
656         }
657 
658         dc.SetPen(m_gripper_pen1);
659         dc.DrawPoint(x, y);
660         dc.SetPen(m_gripper_pen2);
661         dc.DrawPoint(x, y+1);
662         dc.DrawPoint(x+1, y);
663         dc.SetPen(m_gripper_pen3);
664         dc.DrawPoint(x+2, y+1);
665         dc.DrawPoint(x+2, y+2);
666         dc.DrawPoint(x+1, y+2);
667 
668         i++;
669     }
670 
671 }
672 
DrawOverflowButton(wxDC & dc,wxWindow * wnd,const wxRect & rect,int state)673 void wxAuiDefaultToolBarArt::DrawOverflowButton(wxDC& dc,
674                                           wxWindow* wnd,
675                                           const wxRect& rect,
676                                           int state)
677 {
678     if (state & wxAUI_BUTTON_STATE_HOVER ||
679         state & wxAUI_BUTTON_STATE_PRESSED)
680     {
681         wxRect cli_rect = wnd->GetClientRect();
682         wxColor light_gray_bg = wxAuiStepColour(m_highlight_colour, 170);
683 
684         if (m_flags & wxAUI_TB_VERTICAL)
685         {
686             dc.SetPen(wxPen(m_highlight_colour));
687             dc.DrawLine(rect.x, rect.y, rect.x+rect.width, rect.y);
688             dc.SetPen(wxPen(light_gray_bg));
689             dc.SetBrush(wxBrush(light_gray_bg));
690             dc.DrawRectangle(rect.x, rect.y+1, rect.width, rect.height);
691         }
692         else
693         {
694             dc.SetPen(wxPen(m_highlight_colour));
695             dc.DrawLine(rect.x, rect.y, rect.x, rect.y+rect.height);
696             dc.SetPen(wxPen(light_gray_bg));
697             dc.SetBrush(wxBrush(light_gray_bg));
698             dc.DrawRectangle(rect.x+1, rect.y, rect.width, rect.height);
699         }
700     }
701 
702     int x = rect.x+1+(rect.width-m_overflow_bmp.GetWidth())/2;
703     int y = rect.y+1+(rect.height-m_overflow_bmp.GetHeight())/2;
704     dc.DrawBitmap(m_overflow_bmp, x, y, true);
705 }
706 
GetElementSize(int element_id)707 int wxAuiDefaultToolBarArt::GetElementSize(int element_id)
708 {
709     switch (element_id)
710     {
711         case wxAUI_TBART_SEPARATOR_SIZE: return m_separator_size;
712         case wxAUI_TBART_GRIPPER_SIZE:   return m_gripper_size;
713         case wxAUI_TBART_OVERFLOW_SIZE:  return m_overflow_size;
714         default: return 0;
715     }
716 }
717 
SetElementSize(int element_id,int size)718 void wxAuiDefaultToolBarArt::SetElementSize(int element_id, int size)
719 {
720     switch (element_id)
721     {
722         case wxAUI_TBART_SEPARATOR_SIZE: m_separator_size = size; break;
723         case wxAUI_TBART_GRIPPER_SIZE:   m_gripper_size = size; break;
724         case wxAUI_TBART_OVERFLOW_SIZE:  m_overflow_size = size; break;
725     }
726 }
727 
ShowDropDown(wxWindow * wnd,const wxAuiToolBarItemArray & items)728 int wxAuiDefaultToolBarArt::ShowDropDown(wxWindow* wnd,
729                                          const wxAuiToolBarItemArray& items)
730 {
731     wxMenu menuPopup;
732 
733     size_t items_added = 0;
734 
735     size_t i, count = items.GetCount();
736     for (i = 0; i < count; ++i)
737     {
738         wxAuiToolBarItem& item = items.Item(i);
739 
740         if (item.GetKind() == wxITEM_NORMAL)
741         {
742             wxString text = item.GetShortHelp();
743             if (text.empty())
744                 text = item.GetLabel();
745 
746             if (text.empty())
747                 text = wxT(" ");
748 
749             wxMenuItem* m =  new wxMenuItem(&menuPopup, item.GetId(), text, item.GetShortHelp());
750 
751             m->SetBitmap(item.GetBitmap());
752             menuPopup.Append(m);
753             items_added++;
754         }
755         else if (item.GetKind() == wxITEM_SEPARATOR)
756         {
757             if (items_added > 0)
758                 menuPopup.AppendSeparator();
759         }
760     }
761 
762     // find out where to put the popup menu of window items
763     wxPoint pt = ::wxGetMousePosition();
764     pt = wnd->ScreenToClient(pt);
765 
766     // find out the screen coordinate at the bottom of the tab ctrl
767     wxRect cli_rect = wnd->GetClientRect();
768     pt.y = cli_rect.y + cli_rect.height;
769 
770     ToolbarCommandCapture* cc = new ToolbarCommandCapture;
771     wnd->PushEventHandler(cc);
772     wnd->PopupMenu(&menuPopup, pt);
773     int command = cc->GetCommandId();
774     wnd->PopEventHandler(true);
775 
776     return command;
777 }
778 
779 
780 
781 
BEGIN_EVENT_TABLE(wxAuiToolBar,wxControl)782 BEGIN_EVENT_TABLE(wxAuiToolBar, wxControl)
783     EVT_SIZE(wxAuiToolBar::OnSize)
784     EVT_IDLE(wxAuiToolBar::OnIdle)
785     EVT_ERASE_BACKGROUND(wxAuiToolBar::OnEraseBackground)
786     EVT_PAINT(wxAuiToolBar::OnPaint)
787     EVT_LEFT_DOWN(wxAuiToolBar::OnLeftDown)
788     EVT_LEFT_DCLICK(wxAuiToolBar::OnLeftDown)
789     EVT_LEFT_UP(wxAuiToolBar::OnLeftUp)
790     EVT_RIGHT_DOWN(wxAuiToolBar::OnRightDown)
791     EVT_RIGHT_DCLICK(wxAuiToolBar::OnRightDown)
792     EVT_RIGHT_UP(wxAuiToolBar::OnRightUp)
793     EVT_MIDDLE_DOWN(wxAuiToolBar::OnMiddleDown)
794     EVT_MIDDLE_DCLICK(wxAuiToolBar::OnMiddleDown)
795     EVT_MIDDLE_UP(wxAuiToolBar::OnMiddleUp)
796     EVT_MOTION(wxAuiToolBar::OnMotion)
797     EVT_LEAVE_WINDOW(wxAuiToolBar::OnLeaveWindow)
798     EVT_SET_CURSOR(wxAuiToolBar::OnSetCursor)
799 END_EVENT_TABLE()
800 
801 
802 wxAuiToolBar::wxAuiToolBar(wxWindow* parent,
803                            wxWindowID id,
804                            const wxPoint& position,
805                            const wxSize& size,
806                            long style)
807                             : wxControl(parent,
808                                         id,
809                                         position,
810                                         size,
811                                         style | wxBORDER_NONE)
812 {
813     m_sizer = new wxBoxSizer(wxHORIZONTAL);
814     m_button_width = -1;
815     m_button_height = -1;
816     m_sizer_element_count = 0;
817     m_action_pos = wxPoint(-1,-1);
818     m_action_item = NULL;
819     m_tip_item = NULL;
820     m_art = new wxAuiDefaultToolBarArt;
821     m_tool_packing = 2;
822     m_tool_border_padding = 3;
823     m_tool_text_orientation = wxAUI_TBTOOL_TEXT_BOTTOM;
824     m_gripper_sizer_item = NULL;
825     m_overflow_sizer_item = NULL;
826     m_dragging = false;
827     m_style = style | wxBORDER_NONE;
828     m_gripper_visible = (m_style & wxAUI_TB_GRIPPER) ? true : false;
829     m_overflow_visible = (m_style & wxAUI_TB_OVERFLOW) ? true : false;
830     m_overflow_state = 0;
831     SetMargins(5, 5, 2, 2);
832     SetFont(*wxNORMAL_FONT);
833     m_art->SetFlags((unsigned int)m_style);
834     SetExtraStyle(wxWS_EX_PROCESS_IDLE);
835     if (style & wxAUI_TB_HORZ_LAYOUT)
836         SetToolTextOrientation(wxAUI_TBTOOL_TEXT_RIGHT);
837 }
838 
839 
~wxAuiToolBar()840 wxAuiToolBar::~wxAuiToolBar()
841 {
842     delete m_art;
843     delete m_sizer;
844 }
845 
SetWindowStyleFlag(long style)846 void wxAuiToolBar::SetWindowStyleFlag(long style)
847 {
848     wxControl::SetWindowStyleFlag(style);
849 
850     m_style = style;
851 
852     if (m_art)
853     {
854         m_art->SetFlags((unsigned int)m_style);
855     }
856 
857     if (m_style & wxAUI_TB_GRIPPER)
858         m_gripper_visible = true;
859     else
860         m_gripper_visible = false;
861 
862 
863     if (m_style & wxAUI_TB_OVERFLOW)
864         m_overflow_visible = true;
865     else
866         m_overflow_visible = false;
867 
868     if (style & wxAUI_TB_HORZ_LAYOUT)
869         SetToolTextOrientation(wxAUI_TBTOOL_TEXT_RIGHT);
870     else
871         SetToolTextOrientation(wxAUI_TBTOOL_TEXT_BOTTOM);
872 }
873 
GetWindowStyleFlag() const874 long wxAuiToolBar::GetWindowStyleFlag() const
875 {
876     return m_style;
877 }
878 
SetArtProvider(wxAuiToolBarArt * art)879 void wxAuiToolBar::SetArtProvider(wxAuiToolBarArt* art)
880 {
881     delete m_art;
882 
883     m_art = art;
884 
885     if (m_art)
886     {
887         m_art->SetFlags((unsigned int)m_style);
888         m_art->SetTextOrientation(m_tool_text_orientation);
889     }
890 }
891 
GetArtProvider() const892 wxAuiToolBarArt* wxAuiToolBar::GetArtProvider() const
893 {
894     return m_art;
895 }
896 
897 
898 
899 
AddTool(int tool_id,const wxString & label,const wxBitmap & bitmap,const wxString & short_help_string,wxItemKind kind)900 void wxAuiToolBar::AddTool(int tool_id,
901                            const wxString& label,
902                            const wxBitmap& bitmap,
903                            const wxString& short_help_string,
904                            wxItemKind kind)
905 {
906     AddTool(tool_id,
907             label,
908             bitmap,
909             wxNullBitmap,
910             kind,
911             short_help_string,
912             wxEmptyString,
913             NULL);
914 }
915 
916 
AddTool(int tool_id,const wxString & label,const wxBitmap & bitmap,const wxBitmap & disabled_bitmap,wxItemKind kind,const wxString & short_help_string,const wxString & long_help_string,wxObject * WXUNUSED (client_data))917 void wxAuiToolBar::AddTool(int tool_id,
918                            const wxString& label,
919                            const wxBitmap& bitmap,
920                            const wxBitmap& disabled_bitmap,
921                            wxItemKind kind,
922                            const wxString& short_help_string,
923                            const wxString& long_help_string,
924                            wxObject* WXUNUSED(client_data))
925 {
926     wxAuiToolBarItem item;
927     item.window = NULL;
928     item.label = label;
929     item.bitmap = bitmap;
930     item.disabled_bitmap = disabled_bitmap;
931     item.short_help = short_help_string;
932     item.long_help = long_help_string;
933     item.active = true;
934     item.dropdown = false;
935     item.spacer_pixels = 0;
936     item.id = tool_id;
937     item.state = 0;
938     item.proportion = 0;
939     item.kind = kind;
940     item.sizer_item = NULL;
941     item.min_size = wxDefaultSize;
942     item.user_data = 0;
943     item.sticky = false;
944 
945     if (item.id == wxID_ANY)
946         item.id = wxNewId();
947 
948     if (!item.disabled_bitmap.IsOk())
949     {
950         // no disabled bitmap specified, we need to make one
951         if (item.bitmap.IsOk())
952         {
953             //wxImage img = item.bitmap.ConvertToImage();
954             //wxImage grey_version = img.ConvertToGreyscale();
955             //item.disabled_bitmap = wxBitmap(grey_version);
956             item.disabled_bitmap = MakeDisabledBitmap(item.bitmap);
957         }
958     }
959 
960     m_items.Add(item);
961 }
962 
AddControl(wxControl * control,const wxString & label)963 void wxAuiToolBar::AddControl(wxControl* control,
964                               const wxString& label)
965 {
966     wxAuiToolBarItem item;
967     item.window = (wxWindow*)control;
968     item.label = label;
969     item.bitmap = wxNullBitmap;
970     item.disabled_bitmap = wxNullBitmap;
971     item.active = true;
972     item.dropdown = false;
973     item.spacer_pixels = 0;
974     item.id = control->GetId();
975     item.state = 0;
976     item.proportion = 0;
977     item.kind = wxITEM_CONTROL;
978     item.sizer_item = NULL;
979     item.min_size = control->GetEffectiveMinSize();
980     item.user_data = 0;
981     item.sticky = false;
982 
983     m_items.Add(item);
984 }
985 
AddLabel(int tool_id,const wxString & label,const int width)986 void wxAuiToolBar::AddLabel(int tool_id,
987                             const wxString& label,
988                             const int width)
989 {
990     wxSize min_size = wxDefaultSize;
991     if (width != -1)
992         min_size.x = width;
993 
994     wxAuiToolBarItem item;
995     item.window = NULL;
996     item.label = label;
997     item.bitmap = wxNullBitmap;
998     item.disabled_bitmap = wxNullBitmap;
999     item.active = true;
1000     item.dropdown = false;
1001     item.spacer_pixels = 0;
1002     item.id = tool_id;
1003     item.state = 0;
1004     item.proportion = 0;
1005     item.kind = wxITEM_LABEL;
1006     item.sizer_item = NULL;
1007     item.min_size = min_size;
1008     item.user_data = 0;
1009     item.sticky = false;
1010 
1011     if (item.id == wxID_ANY)
1012         item.id = wxNewId();
1013 
1014     m_items.Add(item);
1015 }
1016 
AddSeparator()1017 void wxAuiToolBar::AddSeparator()
1018 {
1019     wxAuiToolBarItem item;
1020     item.window = NULL;
1021     item.label = wxEmptyString;
1022     item.bitmap = wxNullBitmap;
1023     item.disabled_bitmap = wxNullBitmap;
1024     item.active = true;
1025     item.dropdown = false;
1026     item.id = -1;
1027     item.state = 0;
1028     item.proportion = 0;
1029     item.kind = wxITEM_SEPARATOR;
1030     item.sizer_item = NULL;
1031     item.min_size = wxDefaultSize;
1032     item.user_data = 0;
1033     item.sticky = false;
1034 
1035     m_items.Add(item);
1036 }
1037 
AddSpacer(int pixels)1038 void wxAuiToolBar::AddSpacer(int pixels)
1039 {
1040     wxAuiToolBarItem item;
1041     item.window = NULL;
1042     item.label = wxEmptyString;
1043     item.bitmap = wxNullBitmap;
1044     item.disabled_bitmap = wxNullBitmap;
1045     item.active = true;
1046     item.dropdown = false;
1047     item.spacer_pixels = pixels;
1048     item.id = -1;
1049     item.state = 0;
1050     item.proportion = 0;
1051     item.kind = wxITEM_SPACER;
1052     item.sizer_item = NULL;
1053     item.min_size = wxDefaultSize;
1054     item.user_data = 0;
1055     item.sticky = false;
1056 
1057     m_items.Add(item);
1058 }
1059 
AddStretchSpacer(int proportion)1060 void wxAuiToolBar::AddStretchSpacer(int proportion)
1061 {
1062     wxAuiToolBarItem item;
1063     item.window = NULL;
1064     item.label = wxEmptyString;
1065     item.bitmap = wxNullBitmap;
1066     item.disabled_bitmap = wxNullBitmap;
1067     item.active = true;
1068     item.dropdown = false;
1069     item.spacer_pixels = 0;
1070     item.id = -1;
1071     item.state = 0;
1072     item.proportion = proportion;
1073     item.kind = wxITEM_SPACER;
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);
1080 }
1081 
Clear()1082 void wxAuiToolBar::Clear()
1083 {
1084     m_items.Clear();
1085     m_sizer_element_count = 0;
1086 }
1087 
DeleteTool(int tool_id)1088 bool wxAuiToolBar::DeleteTool(int tool_id)
1089 {
1090     int idx = GetToolIndex(tool_id);
1091     if (idx >= 0 && idx < (int)m_items.GetCount())
1092     {
1093         m_items.RemoveAt(idx);
1094         Realize();
1095         return true;
1096     }
1097 
1098     return false;
1099 }
1100 
DeleteByIndex(int idx)1101 bool wxAuiToolBar::DeleteByIndex(int idx)
1102 {
1103     if (idx >= 0 && idx < (int)m_items.GetCount())
1104     {
1105         m_items.RemoveAt(idx);
1106         Realize();
1107         return true;
1108     }
1109 
1110     return false;
1111 }
1112 
1113 
FindControl(int id)1114 wxControl* wxAuiToolBar::FindControl(int id)
1115 {
1116     wxWindow* wnd = FindWindow(id);
1117     return (wxControl*)wnd;
1118 }
1119 
FindTool(int tool_id) const1120 wxAuiToolBarItem* wxAuiToolBar::FindTool(int tool_id) const
1121 {
1122     size_t i, count;
1123     for (i = 0, count = m_items.GetCount(); i < count; ++i)
1124     {
1125         wxAuiToolBarItem& item = m_items.Item(i);
1126         if (item.id == tool_id)
1127             return &item;
1128     }
1129 
1130     return NULL;
1131 }
1132 
FindToolByPosition(wxCoord x,wxCoord y) const1133 wxAuiToolBarItem* wxAuiToolBar::FindToolByPosition(wxCoord x, wxCoord y) const
1134 {
1135     size_t i, count;
1136     for (i = 0, count = m_items.GetCount(); i < count; ++i)
1137     {
1138         wxAuiToolBarItem& item = m_items.Item(i);
1139 
1140         if (!item.sizer_item)
1141             continue;
1142 
1143         wxRect rect = item.sizer_item->GetRect();
1144         if (rect.Contains(x,y))
1145         {
1146             // if the item doesn't fit on the toolbar, return NULL
1147             if (!GetToolFitsByIndex(i))
1148                 return NULL;
1149 
1150             return &item;
1151         }
1152     }
1153 
1154     return NULL;
1155 }
1156 
FindToolByPositionWithPacking(wxCoord x,wxCoord y) const1157 wxAuiToolBarItem* wxAuiToolBar::FindToolByPositionWithPacking(wxCoord x, wxCoord y) const
1158 {
1159     size_t i, count;
1160     for (i = 0, count = m_items.GetCount(); i < count; ++i)
1161     {
1162         wxAuiToolBarItem& item = m_items.Item(i);
1163 
1164         if (!item.sizer_item)
1165             continue;
1166 
1167         wxRect rect = item.sizer_item->GetRect();
1168 
1169         // apply tool packing
1170         if (i+1 < count)
1171             rect.width += m_tool_packing;
1172 
1173         if (rect.Contains(x,y))
1174         {
1175             // if the item doesn't fit on the toolbar, return NULL
1176             if (!GetToolFitsByIndex(i))
1177                 return NULL;
1178 
1179             return &item;
1180         }
1181     }
1182 
1183     return NULL;
1184 }
1185 
FindToolByIndex(int idx) const1186 wxAuiToolBarItem* wxAuiToolBar::FindToolByIndex(int idx) const
1187 {
1188     if (idx < 0)
1189         return NULL;
1190 
1191     if (idx >= (int)m_items.size())
1192         return NULL;
1193 
1194     return &(m_items[idx]);
1195 }
1196 
SetToolBitmapSize(const wxSize & WXUNUSED (size))1197 void wxAuiToolBar::SetToolBitmapSize(const wxSize& WXUNUSED(size))
1198 {
1199     // TODO: wxToolBar compatibility
1200 }
1201 
GetToolBitmapSize() const1202 wxSize wxAuiToolBar::GetToolBitmapSize() const
1203 {
1204     // TODO: wxToolBar compatibility
1205     return wxSize(16,15);
1206 }
1207 
SetToolProportion(int tool_id,int proportion)1208 void wxAuiToolBar::SetToolProportion(int tool_id, int proportion)
1209 {
1210     wxAuiToolBarItem* item = FindTool(tool_id);
1211     if (!item)
1212         return;
1213 
1214     item->proportion = proportion;
1215 }
1216 
GetToolProportion(int tool_id) const1217 int wxAuiToolBar::GetToolProportion(int tool_id) const
1218 {
1219     wxAuiToolBarItem* item = FindTool(tool_id);
1220     if (!item)
1221         return 0;
1222 
1223     return item->proportion;
1224 }
1225 
SetToolSeparation(int separation)1226 void wxAuiToolBar::SetToolSeparation(int separation)
1227 {
1228     if (m_art)
1229         m_art->SetElementSize(wxAUI_TBART_SEPARATOR_SIZE, separation);
1230 }
1231 
GetToolSeparation() const1232 int wxAuiToolBar::GetToolSeparation() const
1233 {
1234     if (m_art)
1235         return m_art->GetElementSize(wxAUI_TBART_SEPARATOR_SIZE);
1236     else
1237         return 5;
1238 }
1239 
1240 
SetToolDropDown(int tool_id,bool dropdown)1241 void wxAuiToolBar::SetToolDropDown(int tool_id, bool dropdown)
1242 {
1243     wxAuiToolBarItem* item = FindTool(tool_id);
1244     if (!item)
1245         return;
1246 
1247     item->dropdown = dropdown;
1248 }
1249 
GetToolDropDown(int tool_id) const1250 bool wxAuiToolBar::GetToolDropDown(int tool_id) const
1251 {
1252     wxAuiToolBarItem* item = FindTool(tool_id);
1253     if (!item)
1254         return 0;
1255 
1256     return item->dropdown;
1257 }
1258 
SetToolSticky(int tool_id,bool sticky)1259 void wxAuiToolBar::SetToolSticky(int tool_id, bool sticky)
1260 {
1261     // ignore separators
1262     if (tool_id == -1)
1263         return;
1264 
1265     wxAuiToolBarItem* item = FindTool(tool_id);
1266     if (!item)
1267         return;
1268 
1269     if (item->sticky == sticky)
1270         return;
1271 
1272     item->sticky = sticky;
1273 
1274     Refresh(false);
1275     Update();
1276 }
1277 
GetToolSticky(int tool_id) const1278 bool wxAuiToolBar::GetToolSticky(int tool_id) const
1279 {
1280     wxAuiToolBarItem* item = FindTool(tool_id);
1281     if (!item)
1282         return 0;
1283 
1284     return item->sticky;
1285 }
1286 
1287 
1288 
1289 
SetToolBorderPadding(int padding)1290 void wxAuiToolBar::SetToolBorderPadding(int padding)
1291 {
1292     m_tool_border_padding = padding;
1293 }
1294 
GetToolBorderPadding() const1295 int wxAuiToolBar::GetToolBorderPadding() const
1296 {
1297     return m_tool_border_padding;
1298 }
1299 
SetToolTextOrientation(int orientation)1300 void wxAuiToolBar::SetToolTextOrientation(int orientation)
1301 {
1302     m_tool_text_orientation = orientation;
1303 
1304     if (m_art)
1305     {
1306         m_art->SetTextOrientation(orientation);
1307     }
1308 }
1309 
GetToolTextOrientation() const1310 int wxAuiToolBar::GetToolTextOrientation() const
1311 {
1312     return m_tool_text_orientation;
1313 }
1314 
SetToolPacking(int packing)1315 void wxAuiToolBar::SetToolPacking(int packing)
1316 {
1317     m_tool_packing = packing;
1318 }
1319 
GetToolPacking() const1320 int wxAuiToolBar::GetToolPacking() const
1321 {
1322     return m_tool_packing;
1323 }
1324 
1325 
SetOrientation(int WXUNUSED (orientation))1326 void wxAuiToolBar::SetOrientation(int WXUNUSED(orientation))
1327 {
1328 }
1329 
SetMargins(int left,int right,int top,int bottom)1330 void wxAuiToolBar::SetMargins(int left, int right, int top, int bottom)
1331 {
1332     if (left != -1)
1333         m_left_padding = left;
1334     if (right != -1)
1335         m_right_padding = right;
1336     if (top != -1)
1337         m_top_padding = top;
1338     if (bottom != -1)
1339         m_bottom_padding = bottom;
1340 }
1341 
GetGripperVisible() const1342 bool wxAuiToolBar::GetGripperVisible() const
1343 {
1344     return m_gripper_visible;
1345 }
1346 
SetGripperVisible(bool visible)1347 void wxAuiToolBar::SetGripperVisible(bool visible)
1348 {
1349     m_gripper_visible = visible;
1350     if (visible)
1351         m_style |= wxAUI_TB_GRIPPER;
1352     else
1353         m_style &= ~wxAUI_TB_GRIPPER;
1354     Realize();
1355     Refresh(false);
1356 }
1357 
1358 
GetOverflowVisible() const1359 bool wxAuiToolBar::GetOverflowVisible() const
1360 {
1361     return m_overflow_visible;
1362 }
1363 
SetOverflowVisible(bool visible)1364 void wxAuiToolBar::SetOverflowVisible(bool visible)
1365 {
1366     m_overflow_visible = visible;
1367     if (visible)
1368         m_style |= wxAUI_TB_OVERFLOW;
1369     else
1370         m_style &= ~wxAUI_TB_OVERFLOW;
1371     Refresh(false);
1372 }
1373 
SetFont(const wxFont & font)1374 bool wxAuiToolBar::SetFont(const wxFont& font)
1375 {
1376     bool res = wxWindow::SetFont(font);
1377 
1378     if (m_art)
1379     {
1380         m_art->SetFont(font);
1381     }
1382 
1383     return res;
1384 }
1385 
1386 
SetHoverItem(wxAuiToolBarItem * pitem)1387 void wxAuiToolBar::SetHoverItem(wxAuiToolBarItem* pitem)
1388 {
1389     wxAuiToolBarItem* former_hover = NULL;
1390 
1391     size_t i, count;
1392     for (i = 0, count = m_items.GetCount(); i < count; ++i)
1393     {
1394         wxAuiToolBarItem& item = m_items.Item(i);
1395         if (item.state & wxAUI_BUTTON_STATE_HOVER)
1396             former_hover = &item;
1397         item.state &= ~wxAUI_BUTTON_STATE_HOVER;
1398     }
1399 
1400     if (pitem)
1401     {
1402         pitem->state |= wxAUI_BUTTON_STATE_HOVER;
1403     }
1404 
1405     if (former_hover != pitem)
1406     {
1407         Refresh(false);
1408         Update();
1409     }
1410 }
1411 
SetPressedItem(wxAuiToolBarItem * pitem)1412 void wxAuiToolBar::SetPressedItem(wxAuiToolBarItem* pitem)
1413 {
1414     wxAuiToolBarItem* former_item = NULL;
1415 
1416     size_t i, count;
1417     for (i = 0, count = m_items.GetCount(); i < count; ++i)
1418     {
1419         wxAuiToolBarItem& item = m_items.Item(i);
1420         if (item.state & wxAUI_BUTTON_STATE_PRESSED)
1421             former_item = &item;
1422         item.state &= ~wxAUI_BUTTON_STATE_PRESSED;
1423     }
1424 
1425     if (pitem)
1426     {
1427         pitem->state &= ~wxAUI_BUTTON_STATE_HOVER;
1428         pitem->state |= wxAUI_BUTTON_STATE_PRESSED;
1429     }
1430 
1431     if (former_item != pitem)
1432     {
1433         Refresh(false);
1434         Update();
1435     }
1436 }
1437 
RefreshOverflowState()1438 void wxAuiToolBar::RefreshOverflowState()
1439 {
1440     if (!m_overflow_sizer_item)
1441     {
1442         m_overflow_state = 0;
1443         return;
1444     }
1445 
1446     int overflow_state = 0;
1447 
1448     wxRect overflow_rect = GetOverflowRect();
1449 
1450 
1451     // find out the mouse's current position
1452     wxPoint pt = ::wxGetMousePosition();
1453     pt = this->ScreenToClient(pt);
1454 
1455     // find out if the mouse cursor is inside the dropdown rectangle
1456     if (overflow_rect.Contains(pt.x, pt.y))
1457     {
1458         if (::wxGetMouseState().LeftDown())
1459             overflow_state = wxAUI_BUTTON_STATE_PRESSED;
1460         else
1461             overflow_state = wxAUI_BUTTON_STATE_HOVER;
1462     }
1463 
1464     if (overflow_state != m_overflow_state)
1465     {
1466         m_overflow_state = overflow_state;
1467         Refresh(false);
1468         Update();
1469     }
1470 
1471     m_overflow_state = overflow_state;
1472 }
1473 
ToggleTool(int tool_id,bool state)1474 void wxAuiToolBar::ToggleTool(int tool_id, bool state)
1475 {
1476     wxAuiToolBarItem* tool = FindTool(tool_id);
1477 
1478     if (tool && (tool->kind == wxITEM_CHECK || tool->kind == wxITEM_RADIO))
1479     {
1480         if (tool->kind == wxITEM_RADIO)
1481         {
1482             int i, idx, count;
1483             idx = GetToolIndex(tool_id);
1484             count = (int)m_items.GetCount();
1485 
1486             if (idx >= 0 && idx < count)
1487             {
1488                 for (i = idx; i < count; ++i)
1489                 {
1490                     if (m_items[i].kind != wxITEM_RADIO)
1491                         break;
1492                     m_items[i].state &= ~wxAUI_BUTTON_STATE_CHECKED;
1493                 }
1494                 for (i = idx; i > 0; i--)
1495                 {
1496                     if (m_items[i].kind != wxITEM_RADIO)
1497                         break;
1498                     m_items[i].state &= ~wxAUI_BUTTON_STATE_CHECKED;
1499                 }
1500             }
1501 
1502             tool->state |= wxAUI_BUTTON_STATE_CHECKED;
1503         }
1504          else if (tool->kind == wxITEM_CHECK)
1505         {
1506             if (state == true)
1507                 tool->state |= wxAUI_BUTTON_STATE_CHECKED;
1508             else
1509                 tool->state &= ~wxAUI_BUTTON_STATE_CHECKED;
1510         }
1511     }
1512 }
1513 
GetToolToggled(int tool_id) const1514 bool wxAuiToolBar::GetToolToggled(int tool_id) const
1515 {
1516     wxAuiToolBarItem* tool = FindTool(tool_id);
1517 
1518     if (tool)
1519     {
1520         if ( (tool->kind != wxITEM_CHECK) && (tool->kind != wxITEM_RADIO) )
1521             return false;
1522 
1523         return (tool->state & wxAUI_BUTTON_STATE_CHECKED) ? true : false;
1524     }
1525 
1526     return false;
1527 }
1528 
EnableTool(int tool_id,bool state)1529 void wxAuiToolBar::EnableTool(int tool_id, bool state)
1530 {
1531     wxAuiToolBarItem* tool = FindTool(tool_id);
1532 
1533     if (tool)
1534     {
1535         if (state == true)
1536             tool->state &= ~wxAUI_BUTTON_STATE_DISABLED;
1537         else
1538             tool->state |= wxAUI_BUTTON_STATE_DISABLED;
1539     }
1540 }
1541 
GetToolEnabled(int tool_id) const1542 bool wxAuiToolBar::GetToolEnabled(int tool_id) const
1543 {
1544     wxAuiToolBarItem* tool = FindTool(tool_id);
1545 
1546     if (tool)
1547         return (tool->state & wxAUI_BUTTON_STATE_DISABLED) ? false : true;
1548 
1549     return false;
1550 }
1551 
GetToolLabel(int tool_id) const1552 wxString wxAuiToolBar::GetToolLabel(int tool_id) const
1553 {
1554     wxAuiToolBarItem* tool = FindTool(tool_id);
1555     wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array"));
1556     if (!tool)
1557         return wxEmptyString;
1558 
1559     return tool->label;
1560 }
1561 
SetToolLabel(int tool_id,const wxString & label)1562 void wxAuiToolBar::SetToolLabel(int tool_id, const wxString& label)
1563 {
1564     wxAuiToolBarItem* tool = FindTool(tool_id);
1565     if (tool)
1566     {
1567         tool->label = label;
1568     }
1569 }
1570 
GetToolBitmap(int tool_id) const1571 wxBitmap wxAuiToolBar::GetToolBitmap(int tool_id) const
1572 {
1573     wxAuiToolBarItem* tool = FindTool(tool_id);
1574     wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array"));
1575     if (!tool)
1576         return wxNullBitmap;
1577 
1578     return tool->bitmap;
1579 }
1580 
SetToolBitmap(int tool_id,const wxBitmap & bitmap)1581 void wxAuiToolBar::SetToolBitmap(int tool_id, const wxBitmap& bitmap)
1582 {
1583     wxAuiToolBarItem* tool = FindTool(tool_id);
1584     if (tool)
1585     {
1586         tool->bitmap = bitmap;
1587     }
1588 }
1589 
GetToolShortHelp(int tool_id) const1590 wxString wxAuiToolBar::GetToolShortHelp(int tool_id) const
1591 {
1592     wxAuiToolBarItem* tool = FindTool(tool_id);
1593     wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array"));
1594     if (!tool)
1595         return wxEmptyString;
1596 
1597     return tool->short_help;
1598 }
1599 
SetToolShortHelp(int tool_id,const wxString & help_string)1600 void wxAuiToolBar::SetToolShortHelp(int tool_id, const wxString& help_string)
1601 {
1602     wxAuiToolBarItem* tool = FindTool(tool_id);
1603     if (tool)
1604     {
1605         tool->short_help = help_string;
1606     }
1607 }
1608 
GetToolLongHelp(int tool_id) const1609 wxString wxAuiToolBar::GetToolLongHelp(int tool_id) const
1610 {
1611     wxAuiToolBarItem* tool = FindTool(tool_id);
1612     wxASSERT_MSG(tool, wxT("can't find tool in toolbar item array"));
1613     if (!tool)
1614         return wxEmptyString;
1615 
1616     return tool->long_help;
1617 }
1618 
SetToolLongHelp(int tool_id,const wxString & help_string)1619 void wxAuiToolBar::SetToolLongHelp(int tool_id, const wxString& help_string)
1620 {
1621     wxAuiToolBarItem* tool = FindTool(tool_id);
1622     if (tool)
1623     {
1624         tool->long_help = help_string;
1625     }
1626 }
1627 
SetCustomOverflowItems(const wxAuiToolBarItemArray & prepend,const wxAuiToolBarItemArray & append)1628 void wxAuiToolBar::SetCustomOverflowItems(const wxAuiToolBarItemArray& prepend,
1629                                           const wxAuiToolBarItemArray& append)
1630 {
1631     m_custom_overflow_prepend = prepend;
1632     m_custom_overflow_append = append;
1633 }
1634 
1635 
GetToolCount() const1636 size_t wxAuiToolBar::GetToolCount() const
1637 {
1638     return m_items.size();
1639 }
1640 
GetToolIndex(int tool_id) const1641 int wxAuiToolBar::GetToolIndex(int tool_id) const
1642 {
1643     // this will prevent us from returning the index of the
1644     // first separator in the toolbar since its id is equal to -1
1645     if (tool_id == -1)
1646         return wxNOT_FOUND;
1647 
1648     size_t i, count = m_items.GetCount();
1649     for (i = 0; i < count; ++i)
1650     {
1651         wxAuiToolBarItem& item = m_items.Item(i);
1652         if (item.id == tool_id)
1653             return i;
1654     }
1655 
1656     return wxNOT_FOUND;
1657 }
1658 
GetToolFitsByIndex(int tool_idx) const1659 bool wxAuiToolBar::GetToolFitsByIndex(int tool_idx) const
1660 {
1661     if (tool_idx < 0 || tool_idx >= (int)m_items.GetCount())
1662         return false;
1663 
1664     if (!m_items[tool_idx].sizer_item)
1665         return false;
1666 
1667     int cli_w, cli_h;
1668     GetClientSize(&cli_w, &cli_h);
1669 
1670     wxRect rect = m_items[tool_idx].sizer_item->GetRect();
1671 
1672     if (m_style & wxAUI_TB_VERTICAL)
1673     {
1674         // take the dropdown size into account
1675         if (m_overflow_visible)
1676             cli_h -= m_overflow_sizer_item->GetSize().y;
1677 
1678         if (rect.y+rect.height < cli_h)
1679             return true;
1680     }
1681     else
1682     {
1683         // take the dropdown size into account
1684         if (m_overflow_visible)
1685             cli_w -= m_overflow_sizer_item->GetSize().x;
1686 
1687         if (rect.x+rect.width < cli_w)
1688             return true;
1689     }
1690 
1691     return false;
1692 }
1693 
1694 
GetToolFits(int tool_id) const1695 bool wxAuiToolBar::GetToolFits(int tool_id) const
1696 {
1697     return GetToolFitsByIndex(GetToolIndex(tool_id));
1698 }
1699 
GetToolRect(int tool_id) const1700 wxRect wxAuiToolBar::GetToolRect(int tool_id) const
1701 {
1702     wxAuiToolBarItem* tool = FindTool(tool_id);
1703     if (tool && tool->sizer_item)
1704     {
1705         return tool->sizer_item->GetRect();
1706     }
1707 
1708     return wxRect();
1709 }
1710 
GetToolBarFits() const1711 bool wxAuiToolBar::GetToolBarFits() const
1712 {
1713     if (m_items.GetCount() == 0)
1714     {
1715         // empty toolbar always 'fits'
1716         return true;
1717     }
1718 
1719     // entire toolbar content fits if the last tool fits
1720     return GetToolFitsByIndex(m_items.GetCount() - 1);
1721 }
1722 
Realize()1723 bool wxAuiToolBar::Realize()
1724 {
1725     wxClientDC dc(this);
1726     if (!dc.IsOk())
1727         return false;
1728 
1729     bool horizontal = true;
1730     if (m_style & wxAUI_TB_VERTICAL)
1731         horizontal = false;
1732 
1733 
1734     // create the new sizer to add toolbar elements to
1735     wxBoxSizer* sizer = new wxBoxSizer(horizontal ? wxHORIZONTAL : wxVERTICAL);
1736 
1737     // add gripper area
1738     int separator_size = m_art->GetElementSize(wxAUI_TBART_SEPARATOR_SIZE);
1739     int gripper_size = m_art->GetElementSize(wxAUI_TBART_GRIPPER_SIZE);
1740     if (gripper_size > 0 && m_gripper_visible)
1741     {
1742         if (horizontal)
1743             m_gripper_sizer_item = sizer->Add(gripper_size, 1, 0, wxEXPAND);
1744         else
1745             m_gripper_sizer_item = sizer->Add(1, gripper_size, 0, wxEXPAND);
1746     }
1747     else
1748     {
1749         m_gripper_sizer_item = NULL;
1750     }
1751 
1752     // add "left" padding
1753     if (m_left_padding > 0)
1754     {
1755         if (horizontal)
1756             sizer->Add(m_left_padding, 1);
1757         else
1758             sizer->Add(1, m_left_padding);
1759     }
1760 
1761     size_t i, count;
1762     for (i = 0, count = m_items.GetCount(); i < count; ++i)
1763     {
1764         wxAuiToolBarItem& item = m_items.Item(i);
1765         wxSizerItem* sizer_item = NULL;
1766 
1767         switch (item.kind)
1768         {
1769             case wxITEM_LABEL:
1770             {
1771                 wxSize size = m_art->GetLabelSize(dc, this, item);
1772                 sizer_item = sizer->Add(size.x + (m_tool_border_padding*2),
1773                                         size.y + (m_tool_border_padding*2),
1774                                         item.proportion,
1775                                         wxALIGN_CENTER);
1776                 if (i+1 < count)
1777                 {
1778                     sizer->AddSpacer(m_tool_packing);
1779                 }
1780 
1781                 break;
1782             }
1783 
1784             case wxITEM_CHECK:
1785             case wxITEM_NORMAL:
1786             case wxITEM_RADIO:
1787             {
1788                 wxSize size = m_art->GetToolSize(dc, this, item);
1789                 sizer_item = sizer->Add(size.x + (m_tool_border_padding*2),
1790                                         size.y + (m_tool_border_padding*2),
1791                                         0,
1792                                         wxALIGN_CENTER);
1793                 // add tool packing
1794                 if (i+1 < count)
1795                 {
1796                     sizer->AddSpacer(m_tool_packing);
1797                 }
1798 
1799                 break;
1800             }
1801 
1802             case wxITEM_SEPARATOR:
1803             {
1804                 if (horizontal)
1805                     sizer_item = sizer->Add(separator_size, 1, 0, wxEXPAND);
1806                 else
1807                     sizer_item = sizer->Add(1, separator_size, 0, wxEXPAND);
1808 
1809                 // add tool packing
1810                 if (i+1 < count)
1811                 {
1812                     sizer->AddSpacer(m_tool_packing);
1813                 }
1814 
1815                 break;
1816             }
1817 
1818             case wxITEM_SPACER:
1819                 if (item.proportion > 0)
1820                     sizer_item = sizer->AddStretchSpacer(item.proportion);
1821                 else
1822                     sizer_item = sizer->Add(item.spacer_pixels, 1);
1823                 break;
1824 
1825             case wxITEM_CONTROL:
1826             {
1827                 //sizer_item = sizer->Add(item.window, item.proportion, wxEXPAND);
1828                 wxSizerItem* ctrl_sizer_item;
1829 
1830                 wxBoxSizer* vert_sizer = new wxBoxSizer(wxVERTICAL);
1831                 vert_sizer->AddStretchSpacer(1);
1832                 ctrl_sizer_item = vert_sizer->Add(item.window, 0, wxEXPAND);
1833                 vert_sizer->AddStretchSpacer(1);
1834                 if ( (m_style & wxAUI_TB_TEXT) &&
1835                      m_tool_text_orientation == wxAUI_TBTOOL_TEXT_BOTTOM &&
1836                      !item.GetLabel().empty() )
1837                 {
1838                     wxSize s = GetLabelSize(item.GetLabel());
1839                     vert_sizer->Add(1, s.y);
1840                 }
1841 
1842 
1843                 sizer_item = sizer->Add(vert_sizer, item.proportion, wxEXPAND);
1844 
1845                 wxSize min_size = item.min_size;
1846 
1847 
1848                 // proportional items will disappear from the toolbar if
1849                 // their min width is not set to something really small
1850                 if (item.proportion != 0)
1851                 {
1852                     min_size.x = 1;
1853                 }
1854 
1855                 if (min_size.IsFullySpecified())
1856                 {
1857                     sizer_item->SetMinSize(min_size);
1858                     ctrl_sizer_item->SetMinSize(min_size);
1859                 }
1860 
1861                 // add tool packing
1862                 if (i+1 < count)
1863                 {
1864                     sizer->AddSpacer(m_tool_packing);
1865                 }
1866             }
1867         }
1868 
1869         item.sizer_item = sizer_item;
1870     }
1871 
1872     // add "right" padding
1873     if (m_right_padding > 0)
1874     {
1875         if (horizontal)
1876             sizer->Add(m_right_padding, 1);
1877         else
1878             sizer->Add(1, m_right_padding);
1879     }
1880 
1881     // add drop down area
1882     m_overflow_sizer_item = NULL;
1883 
1884     if (m_style & wxAUI_TB_OVERFLOW)
1885     {
1886         int overflow_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
1887         if (overflow_size > 0 && m_overflow_visible)
1888         {
1889             if (horizontal)
1890                 m_overflow_sizer_item = sizer->Add(overflow_size, 1, 0, wxEXPAND);
1891             else
1892                 m_overflow_sizer_item = sizer->Add(1, overflow_size, 0, wxEXPAND);
1893         }
1894         else
1895         {
1896             m_overflow_sizer_item = NULL;
1897         }
1898     }
1899 
1900 
1901     // the outside sizer helps us apply the "top" and "bottom" padding
1902     wxBoxSizer* outside_sizer = new wxBoxSizer(horizontal ? wxVERTICAL : wxHORIZONTAL);
1903 
1904     // add "top" padding
1905     if (m_top_padding > 0)
1906     {
1907         if (horizontal)
1908             outside_sizer->Add(1, m_top_padding);
1909         else
1910             outside_sizer->Add(m_top_padding, 1);
1911     }
1912 
1913     // add the sizer that contains all of the toolbar elements
1914     outside_sizer->Add(sizer, 1, wxEXPAND);
1915 
1916     // add "bottom" padding
1917     if (m_bottom_padding > 0)
1918     {
1919         if (horizontal)
1920             outside_sizer->Add(1, m_bottom_padding);
1921         else
1922             outside_sizer->Add(m_bottom_padding, 1);
1923     }
1924 
1925     delete m_sizer; // remove old sizer
1926     m_sizer = outside_sizer;
1927 
1928     // calculate the rock-bottom minimum size
1929     for (i = 0, count = m_items.GetCount(); i < count; ++i)
1930     {
1931         wxAuiToolBarItem& item = m_items.Item(i);
1932         if (item.sizer_item && item.proportion > 0 && item.min_size.IsFullySpecified())
1933             item.sizer_item->SetMinSize(0,0);
1934     }
1935 
1936     m_absolute_min_size = m_sizer->GetMinSize();
1937 
1938     // reset the min sizes to what they were
1939     for (i = 0, count = m_items.GetCount(); i < count; ++i)
1940     {
1941         wxAuiToolBarItem& item = m_items.Item(i);
1942         if (item.sizer_item && item.proportion > 0 && item.min_size.IsFullySpecified())
1943             item.sizer_item->SetMinSize(item.min_size);
1944     }
1945 
1946     // set control size
1947     wxSize size = m_sizer->GetMinSize();
1948     m_minWidth = size.x;
1949     m_minHeight = size.y;
1950 
1951     if ((m_style & wxAUI_TB_NO_AUTORESIZE) == 0)
1952     {
1953         wxSize cur_size = GetClientSize();
1954         wxSize new_size = GetMinSize();
1955         if (new_size != cur_size)
1956         {
1957             SetClientSize(new_size);
1958         }
1959         else
1960         {
1961             m_sizer->SetDimension(0, 0, cur_size.x, cur_size.y);
1962         }
1963     }
1964     else
1965     {
1966         wxSize cur_size = GetClientSize();
1967         m_sizer->SetDimension(0, 0, cur_size.x, cur_size.y);
1968     }
1969 
1970     Refresh(false);
1971     return true;
1972 }
1973 
GetOverflowState() const1974 int wxAuiToolBar::GetOverflowState() const
1975 {
1976     return m_overflow_state;
1977 }
1978 
GetOverflowRect() const1979 wxRect wxAuiToolBar::GetOverflowRect() const
1980 {
1981     wxRect cli_rect(wxPoint(0,0), GetClientSize());
1982     wxRect overflow_rect = m_overflow_sizer_item->GetRect();
1983     int overflow_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
1984 
1985     if (m_style & wxAUI_TB_VERTICAL)
1986     {
1987         overflow_rect.y = cli_rect.height - overflow_size;
1988         overflow_rect.x = 0;
1989         overflow_rect.width = cli_rect.width;
1990         overflow_rect.height = overflow_size;
1991     }
1992     else
1993     {
1994         overflow_rect.x = cli_rect.width - overflow_size;
1995         overflow_rect.y = 0;
1996         overflow_rect.width = overflow_size;
1997         overflow_rect.height = cli_rect.height;
1998     }
1999 
2000     return overflow_rect;
2001 }
2002 
GetLabelSize(const wxString & label)2003 wxSize wxAuiToolBar::GetLabelSize(const wxString& label)
2004 {
2005     wxClientDC dc(this);
2006 
2007     int tx, ty;
2008     int text_width = 0, text_height = 0;
2009 
2010     dc.SetFont(m_font);
2011 
2012     // get the text height
2013     dc.GetTextExtent(wxT("ABCDHgj"), &tx, &text_height);
2014 
2015     // get the text width
2016     dc.GetTextExtent(label, &text_width, &ty);
2017 
2018     return wxSize(text_width, text_height);
2019 }
2020 
2021 
DoIdleUpdate()2022 void wxAuiToolBar::DoIdleUpdate()
2023 {
2024     wxEvtHandler* handler = GetEventHandler();
2025 
2026     bool need_refresh = false;
2027 
2028     size_t i, count;
2029     for (i = 0, count = m_items.GetCount(); i < count; ++i)
2030     {
2031         wxAuiToolBarItem& item = m_items.Item(i);
2032 
2033         if (item.id == -1)
2034             continue;
2035 
2036         wxUpdateUIEvent evt(item.id);
2037         evt.SetEventObject(this);
2038 
2039         if (handler->ProcessEvent(evt))
2040         {
2041             if (evt.GetSetEnabled())
2042             {
2043                 bool is_enabled;
2044                 if (item.window)
2045                     is_enabled = item.window->IsEnabled();
2046                 else
2047                     is_enabled = (item.state & wxAUI_BUTTON_STATE_DISABLED) ? false : true;
2048 
2049                 bool new_enabled = evt.GetEnabled();
2050                 if (new_enabled != is_enabled)
2051                 {
2052                     if (item.window)
2053                     {
2054                         item.window->Enable(new_enabled);
2055                     }
2056                     else
2057                     {
2058                         if (new_enabled)
2059                             item.state &= ~wxAUI_BUTTON_STATE_DISABLED;
2060                         else
2061                             item.state |= wxAUI_BUTTON_STATE_DISABLED;
2062                     }
2063                     need_refresh = true;
2064                 }
2065             }
2066 
2067             if (evt.GetSetChecked())
2068             {
2069                 // make sure we aren't checking an item that can't be
2070                 if (item.kind != wxITEM_CHECK && item.kind != wxITEM_RADIO)
2071                     continue;
2072 
2073                 bool is_checked = (item.state & wxAUI_BUTTON_STATE_CHECKED) ? true : false;
2074                 bool new_checked = evt.GetChecked();
2075 
2076                 if (new_checked != is_checked)
2077                 {
2078                     if (new_checked)
2079                         item.state |= wxAUI_BUTTON_STATE_CHECKED;
2080                     else
2081                         item.state &= ~wxAUI_BUTTON_STATE_CHECKED;
2082 
2083                     need_refresh = true;
2084                 }
2085             }
2086 
2087         }
2088     }
2089 
2090 
2091     if (need_refresh)
2092     {
2093         Refresh(false);
2094     }
2095 }
2096 
2097 
OnSize(wxSizeEvent & WXUNUSED (evt))2098 void wxAuiToolBar::OnSize(wxSizeEvent& WXUNUSED(evt))
2099 {
2100     int x, y;
2101     GetClientSize(&x, &y);
2102 
2103     if (x > y)
2104         SetOrientation(wxHORIZONTAL);
2105     else
2106         SetOrientation(wxVERTICAL);
2107 
2108     if (((x >= y) && m_absolute_min_size.x > x) ||
2109         ((y > x) && m_absolute_min_size.y > y))
2110     {
2111         // hide all flexible items
2112         size_t i, count;
2113         for (i = 0, count = m_items.GetCount(); i < count; ++i)
2114         {
2115             wxAuiToolBarItem& item = m_items.Item(i);
2116             if (item.sizer_item && item.proportion > 0 && item.sizer_item->IsShown())
2117             {
2118                 item.sizer_item->Show(false);
2119                 item.sizer_item->SetProportion(0);
2120             }
2121         }
2122     }
2123     else
2124     {
2125         // show all flexible items
2126         size_t i, count;
2127         for (i = 0, count = m_items.GetCount(); i < count; ++i)
2128         {
2129             wxAuiToolBarItem& item = m_items.Item(i);
2130             if (item.sizer_item && item.proportion > 0 && !item.sizer_item->IsShown())
2131             {
2132                 item.sizer_item->Show(true);
2133                 item.sizer_item->SetProportion(item.proportion);
2134             }
2135         }
2136     }
2137 
2138     m_sizer->SetDimension(0, 0, x, y);
2139 
2140     Refresh(false);
2141     Update();
2142 }
2143 
2144 
2145 
DoSetSize(int x,int y,int width,int height,int sizeFlags)2146 void wxAuiToolBar::DoSetSize(int x,
2147                              int y,
2148                              int width,
2149                              int height,
2150                              int sizeFlags)
2151 {
2152     wxSize parent_size = GetParent()->GetClientSize();
2153     if (x + width > parent_size.x)
2154         width = wxMax(0, parent_size.x - x);
2155     if (y + height > parent_size.y)
2156         height = wxMax(0, parent_size.y - y);
2157 
2158     wxWindow::DoSetSize(x, y, width, height, sizeFlags);
2159 }
2160 
2161 
OnIdle(wxIdleEvent & evt)2162 void wxAuiToolBar::OnIdle(wxIdleEvent& evt)
2163 {
2164     DoIdleUpdate();
2165     evt.Skip();
2166 }
2167 
OnPaint(wxPaintEvent & WXUNUSED (evt))2168 void wxAuiToolBar::OnPaint(wxPaintEvent& WXUNUSED(evt))
2169 {
2170     wxBufferedPaintDC dc(this);
2171     wxRect cli_rect(wxPoint(0,0), GetClientSize());
2172 
2173 
2174     bool horizontal = true;
2175     if (m_style & wxAUI_TB_VERTICAL)
2176         horizontal = false;
2177 
2178 
2179     m_art->DrawBackground(dc, this, cli_rect);
2180 
2181     int gripper_size = m_art->GetElementSize(wxAUI_TBART_GRIPPER_SIZE);
2182     int dropdown_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
2183 
2184     // paint the gripper
2185     if (gripper_size > 0 && m_gripper_sizer_item)
2186     {
2187         wxRect gripper_rect = m_gripper_sizer_item->GetRect();
2188         if (horizontal)
2189             gripper_rect.width = gripper_size;
2190         else
2191             gripper_rect.height = gripper_size;
2192         m_art->DrawGripper(dc, this, gripper_rect);
2193     }
2194 
2195     // calculated how far we can draw items
2196     int last_extent;
2197     if (horizontal)
2198         last_extent = cli_rect.width;
2199     else
2200         last_extent = cli_rect.height;
2201     if (m_overflow_visible)
2202         last_extent -= dropdown_size;
2203 
2204     // paint each individual tool
2205     size_t i, count = m_items.GetCount();
2206     for (i = 0; i < count; ++i)
2207     {
2208         wxAuiToolBarItem& item = m_items.Item(i);
2209 
2210         if (!item.sizer_item)
2211             continue;
2212 
2213         wxRect item_rect = item.sizer_item->GetRect();
2214 
2215 
2216         if ((horizontal  && item_rect.x + item_rect.width >= last_extent) ||
2217             (!horizontal && item_rect.y + item_rect.height >= last_extent))
2218         {
2219             break;
2220         }
2221 
2222         if (item.kind == wxITEM_SEPARATOR)
2223         {
2224             // draw a separator
2225             m_art->DrawSeparator(dc, this, item_rect);
2226         }
2227         else if (item.kind == wxITEM_LABEL)
2228         {
2229             // draw a text label only
2230             m_art->DrawLabel(dc, this, item, item_rect);
2231         }
2232         else if (item.kind == wxITEM_NORMAL)
2233         {
2234             // draw a regular button or dropdown button
2235             if (!item.dropdown)
2236                 m_art->DrawButton(dc, this, item, item_rect);
2237             else
2238                 m_art->DrawDropDownButton(dc, this, item, item_rect);
2239         }
2240         else if (item.kind == wxITEM_CHECK)
2241         {
2242             // draw a toggle button
2243             m_art->DrawButton(dc, this, item, item_rect);
2244         }
2245         else if (item.kind == wxITEM_RADIO)
2246         {
2247             // draw a toggle button
2248             m_art->DrawButton(dc, this, item, item_rect);
2249         }
2250         else if (item.kind == wxITEM_CONTROL)
2251         {
2252             // draw the control's label
2253             m_art->DrawControlLabel(dc, this, item, item_rect);
2254         }
2255 
2256         // fire a signal to see if the item wants to be custom-rendered
2257         OnCustomRender(dc, item, item_rect);
2258     }
2259 
2260     // paint the overflow button
2261     if (dropdown_size > 0 && m_overflow_sizer_item)
2262     {
2263         wxRect dropdown_rect = GetOverflowRect();
2264         m_art->DrawOverflowButton(dc, this, dropdown_rect, m_overflow_state);
2265     }
2266 }
2267 
OnEraseBackground(wxEraseEvent & WXUNUSED (evt))2268 void wxAuiToolBar::OnEraseBackground(wxEraseEvent& WXUNUSED(evt))
2269 {
2270     // empty
2271 }
2272 
OnLeftDown(wxMouseEvent & evt)2273 void wxAuiToolBar::OnLeftDown(wxMouseEvent& evt)
2274 {
2275     wxRect cli_rect(wxPoint(0,0), GetClientSize());
2276 
2277     if (m_gripper_sizer_item)
2278     {
2279         wxRect gripper_rect = m_gripper_sizer_item->GetRect();
2280         if (gripper_rect.Contains(evt.GetX(), evt.GetY()))
2281         {
2282             // find aui manager
2283             wxAuiManager* manager = wxAuiManager::GetManager(this);
2284             if (!manager)
2285                 return;
2286 
2287             int x_drag_offset = evt.GetX() - gripper_rect.GetX();
2288             int y_drag_offset = evt.GetY() - gripper_rect.GetY();
2289 
2290             // gripper was clicked
2291             manager->StartPaneDrag(this, wxPoint(x_drag_offset, y_drag_offset));
2292             return;
2293         }
2294     }
2295 
2296     if (m_overflow_sizer_item)
2297     {
2298         wxRect overflow_rect = GetOverflowRect();
2299 
2300         if (m_art &&
2301             m_overflow_visible &&
2302             overflow_rect.Contains(evt.m_x, evt.m_y))
2303         {
2304             wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_OVERFLOW_CLICK, -1);
2305             e.SetEventObject(this);
2306             e.SetToolId(-1);
2307             e.SetClickPoint(wxPoint(evt.GetX(), evt.GetY()));
2308             bool processed = ProcessEvent(e);
2309 
2310             if (processed)
2311             {
2312                 DoIdleUpdate();
2313             }
2314             else
2315             {
2316                 size_t i, count;
2317                 wxAuiToolBarItemArray overflow_items;
2318 
2319 
2320                 // add custom overflow prepend items, if any
2321                 count = m_custom_overflow_prepend.GetCount();
2322                 for (i = 0; i < count; ++i)
2323                     overflow_items.Add(m_custom_overflow_prepend[i]);
2324 
2325                 // only show items that don't fit in the dropdown
2326                 count = m_items.GetCount();
2327                 for (i = 0; i < count; ++i)
2328                 {
2329                     if (!GetToolFitsByIndex(i))
2330                         overflow_items.Add(m_items[i]);
2331                 }
2332 
2333                 // add custom overflow append items, if any
2334                 count = m_custom_overflow_append.GetCount();
2335                 for (i = 0; i < count; ++i)
2336                     overflow_items.Add(m_custom_overflow_append[i]);
2337 
2338                 int res = m_art->ShowDropDown(this, overflow_items);
2339                 m_overflow_state = 0;
2340                 Refresh(false);
2341                 if (res != -1)
2342                 {
2343                     wxCommandEvent e(wxEVT_COMMAND_MENU_SELECTED, res);
2344                     e.SetEventObject(this);
2345                     GetParent()->ProcessEvent(e);
2346                 }
2347             }
2348 
2349             return;
2350         }
2351     }
2352 
2353     m_dragging = false;
2354     m_action_pos = wxPoint(evt.GetX(), evt.GetY());
2355     m_action_item = FindToolByPosition(evt.GetX(), evt.GetY());
2356 
2357     if (m_action_item)
2358     {
2359         if (m_action_item->state & wxAUI_BUTTON_STATE_DISABLED)
2360         {
2361             m_action_pos = wxPoint(-1,-1);
2362             m_action_item = NULL;
2363             return;
2364         }
2365 
2366         SetPressedItem(m_action_item);
2367 
2368         // fire the tool dropdown event
2369         wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_TOOL_DROPDOWN, m_action_item->id);
2370         e.SetEventObject(this);
2371         e.SetToolId(m_action_item->id);
2372         e.SetDropDownClicked(false);
2373 
2374         int mouse_x = evt.GetX();
2375         wxRect rect = m_action_item->sizer_item->GetRect();
2376 
2377         if (m_action_item->dropdown &&
2378             mouse_x >= (rect.x+rect.width-BUTTON_DROPDOWN_WIDTH-1) &&
2379             mouse_x < (rect.x+rect.width))
2380         {
2381             e.SetDropDownClicked(true);
2382         }
2383 
2384         e.SetClickPoint(evt.GetPosition());
2385         e.SetItemRect(rect);
2386         ProcessEvent(e);
2387         DoIdleUpdate();
2388     }
2389 }
2390 
OnLeftUp(wxMouseEvent & evt)2391 void wxAuiToolBar::OnLeftUp(wxMouseEvent& evt)
2392 {
2393     SetPressedItem(NULL);
2394 
2395     wxAuiToolBarItem* hit_item = FindToolByPosition(evt.GetX(), evt.GetY());
2396     if (hit_item && !(hit_item->state & wxAUI_BUTTON_STATE_DISABLED))
2397     {
2398         SetHoverItem(hit_item);
2399     }
2400 
2401 
2402     if (m_dragging)
2403     {
2404         // reset drag and drop member variables
2405         m_dragging = false;
2406         m_action_pos = wxPoint(-1,-1);
2407         m_action_item = NULL;
2408         return;
2409     }
2410     else
2411     {
2412         wxAuiToolBarItem* hit_item;
2413         hit_item = FindToolByPosition(evt.GetX(), evt.GetY());
2414 
2415         if (m_action_item && hit_item == m_action_item)
2416         {
2417             UnsetToolTip();
2418 
2419             if (hit_item->kind == wxITEM_CHECK || hit_item->kind == wxITEM_RADIO)
2420             {
2421                 bool toggle = false;
2422 
2423                 if (m_action_item->state & wxAUI_BUTTON_STATE_CHECKED)
2424                     toggle = false;
2425                 else
2426                     toggle = true;
2427 
2428                 ToggleTool(m_action_item->id, toggle);
2429 
2430                 // repaint immediately
2431                 Refresh(false);
2432                 Update();
2433 
2434                 wxCommandEvent e(wxEVT_COMMAND_MENU_SELECTED, m_action_item->id);
2435                 e.SetEventObject(this);
2436                 e.SetInt(toggle);
2437                 ProcessEvent(e);
2438                 DoIdleUpdate();
2439             }
2440             else
2441             {
2442                 wxCommandEvent e(wxEVT_COMMAND_MENU_SELECTED, m_action_item->id);
2443                 e.SetEventObject(this);
2444                 ProcessEvent(e);
2445                 DoIdleUpdate();
2446             }
2447         }
2448     }
2449 
2450     // reset drag and drop member variables
2451     m_dragging = false;
2452     m_action_pos = wxPoint(-1,-1);
2453     m_action_item = NULL;
2454 }
2455 
OnRightDown(wxMouseEvent & evt)2456 void wxAuiToolBar::OnRightDown(wxMouseEvent& evt)
2457 {
2458     wxRect cli_rect(wxPoint(0,0), GetClientSize());
2459 
2460     if (m_gripper_sizer_item)
2461     {
2462         wxRect gripper_rect = m_gripper_sizer_item->GetRect();
2463         if (gripper_rect.Contains(evt.GetX(), evt.GetY()))
2464             return;
2465     }
2466 
2467     if (m_overflow_sizer_item)
2468     {
2469         int dropdown_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
2470         if (dropdown_size > 0 &&
2471             evt.m_x > cli_rect.width - dropdown_size &&
2472             evt.m_y >= 0 &&
2473             evt.m_y < cli_rect.height &&
2474             m_art)
2475         {
2476             return;
2477         }
2478     }
2479 
2480     m_action_pos = wxPoint(evt.GetX(), evt.GetY());
2481     m_action_item = FindToolByPosition(evt.GetX(), evt.GetY());
2482 
2483     if (m_action_item)
2484     {
2485         if (m_action_item->state & wxAUI_BUTTON_STATE_DISABLED)
2486         {
2487             m_action_pos = wxPoint(-1,-1);
2488             m_action_item = NULL;
2489             return;
2490         }
2491     }
2492 }
2493 
OnRightUp(wxMouseEvent & evt)2494 void wxAuiToolBar::OnRightUp(wxMouseEvent& evt)
2495 {
2496     wxAuiToolBarItem* hit_item;
2497     hit_item = FindToolByPosition(evt.GetX(), evt.GetY());
2498 
2499     if (m_action_item && hit_item == m_action_item)
2500     {
2501         wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_RIGHT_CLICK, m_action_item->id);
2502         e.SetEventObject(this);
2503         e.SetToolId(m_action_item->id);
2504         e.SetClickPoint(m_action_pos);
2505         ProcessEvent(e);
2506         DoIdleUpdate();
2507     }
2508     else
2509     {
2510         // right-clicked on the invalid area of the toolbar
2511         wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_RIGHT_CLICK, -1);
2512         e.SetEventObject(this);
2513         e.SetToolId(-1);
2514         e.SetClickPoint(m_action_pos);
2515         ProcessEvent(e);
2516         DoIdleUpdate();
2517     }
2518 
2519     // reset member variables
2520     m_action_pos = wxPoint(-1,-1);
2521     m_action_item = NULL;
2522 }
2523 
OnMiddleDown(wxMouseEvent & evt)2524 void wxAuiToolBar::OnMiddleDown(wxMouseEvent& evt)
2525 {
2526     wxRect cli_rect(wxPoint(0,0), GetClientSize());
2527 
2528     if (m_gripper_sizer_item)
2529     {
2530         wxRect gripper_rect = m_gripper_sizer_item->GetRect();
2531         if (gripper_rect.Contains(evt.GetX(), evt.GetY()))
2532             return;
2533     }
2534 
2535     if (m_overflow_sizer_item)
2536     {
2537         int dropdown_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
2538         if (dropdown_size > 0 &&
2539             evt.m_x > cli_rect.width - dropdown_size &&
2540             evt.m_y >= 0 &&
2541             evt.m_y < cli_rect.height &&
2542             m_art)
2543         {
2544             return;
2545         }
2546     }
2547 
2548     m_action_pos = wxPoint(evt.GetX(), evt.GetY());
2549     m_action_item = FindToolByPosition(evt.GetX(), evt.GetY());
2550 
2551     if (m_action_item)
2552     {
2553         if (m_action_item->state & wxAUI_BUTTON_STATE_DISABLED)
2554         {
2555             m_action_pos = wxPoint(-1,-1);
2556             m_action_item = NULL;
2557             return;
2558         }
2559     }
2560 }
2561 
OnMiddleUp(wxMouseEvent & evt)2562 void wxAuiToolBar::OnMiddleUp(wxMouseEvent& evt)
2563 {
2564     wxAuiToolBarItem* hit_item;
2565     hit_item = FindToolByPosition(evt.GetX(), evt.GetY());
2566 
2567     if (m_action_item && hit_item == m_action_item)
2568     {
2569         if (hit_item->kind == wxITEM_NORMAL)
2570         {
2571             wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_MIDDLE_CLICK, m_action_item->id);
2572             e.SetEventObject(this);
2573             e.SetToolId(m_action_item->id);
2574             e.SetClickPoint(m_action_pos);
2575             ProcessEvent(e);
2576             DoIdleUpdate();
2577         }
2578     }
2579 
2580     // reset member variables
2581     m_action_pos = wxPoint(-1,-1);
2582     m_action_item = NULL;
2583 }
2584 
OnMotion(wxMouseEvent & evt)2585 void wxAuiToolBar::OnMotion(wxMouseEvent& evt)
2586 {
2587     // start a drag event
2588     if (!m_dragging &&
2589         m_action_item != NULL &&
2590         m_action_pos != wxPoint(-1,-1) &&
2591         abs(evt.m_x - m_action_pos.x) + abs(evt.m_y - m_action_pos.y) > 5)
2592     {
2593         UnsetToolTip();
2594 
2595         m_dragging = true;
2596 
2597         wxAuiToolBarEvent e(wxEVT_COMMAND_AUITOOLBAR_BEGIN_DRAG, GetId());
2598         e.SetEventObject(this);
2599         e.SetToolId(m_action_item->id);
2600         ProcessEvent(e);
2601         DoIdleUpdate();
2602         return;
2603     }
2604 
2605     wxAuiToolBarItem* hit_item = FindToolByPosition(evt.GetX(), evt.GetY());
2606     if (hit_item)
2607     {
2608         if (!(hit_item->state & wxAUI_BUTTON_STATE_DISABLED))
2609             SetHoverItem(hit_item);
2610         else
2611             SetHoverItem(NULL);
2612     }
2613     else
2614     {
2615         // no hit item, remove any hit item
2616         SetHoverItem(hit_item);
2617     }
2618 
2619     // figure out tooltips
2620     wxAuiToolBarItem* packing_hit_item;
2621     packing_hit_item = FindToolByPositionWithPacking(evt.GetX(), evt.GetY());
2622     if (packing_hit_item)
2623     {
2624         if (packing_hit_item != m_tip_item)
2625         {
2626             m_tip_item = packing_hit_item;
2627 
2628             if ( !packing_hit_item->short_help.empty() )
2629                 SetToolTip(packing_hit_item->short_help);
2630             else
2631                 UnsetToolTip();
2632         }
2633     }
2634     else
2635     {
2636         UnsetToolTip();
2637         m_tip_item = NULL;
2638     }
2639 
2640     // if we've pressed down an item and we're hovering
2641     // over it, make sure it's state is set to pressed
2642     if (m_action_item)
2643     {
2644         if (m_action_item == hit_item)
2645             SetPressedItem(m_action_item);
2646         else
2647             SetPressedItem(NULL);
2648     }
2649 
2650     // figure out the dropdown button state (are we hovering or pressing it?)
2651     RefreshOverflowState();
2652 }
2653 
OnLeaveWindow(wxMouseEvent & WXUNUSED (evt))2654 void wxAuiToolBar::OnLeaveWindow(wxMouseEvent& WXUNUSED(evt))
2655 {
2656     RefreshOverflowState();
2657     SetHoverItem(NULL);
2658     SetPressedItem(NULL);
2659 
2660     m_tip_item = NULL;
2661 }
2662 
2663 
OnSetCursor(wxSetCursorEvent & evt)2664 void wxAuiToolBar::OnSetCursor(wxSetCursorEvent& evt)
2665 {
2666     wxCursor cursor = wxNullCursor;
2667 
2668     if (m_gripper_sizer_item)
2669     {
2670         wxRect gripper_rect = m_gripper_sizer_item->GetRect();
2671         if (gripper_rect.Contains(evt.GetX(), evt.GetY()))
2672         {
2673             cursor = wxCursor(wxCURSOR_SIZING);
2674         }
2675     }
2676 
2677     evt.SetCursor(cursor);
2678 }
2679 
2680 
2681 #endif // wxUSE_AUI
2682 
2683