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