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