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