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