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