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