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