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