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