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