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