]>
Commit | Line | Data |
---|---|---|
1 | ///////////////////////////////////////////////////////////////////////////// | |
2 | // Name: src/univ/toolbar.cpp | |
3 | // Purpose: implementation of wxToolBar for wxUniversal | |
4 | // Author: Robert Roebling, Vadim Zeitlin (universalization) | |
5 | // Modified by: | |
6 | // Created: 20.02.02 | |
7 | // Id: $Id$ | |
8 | // Copyright: (c) 2001 Robert Roebling, | |
9 | // (c) 2002 SciTech Software, Inc. (www.scitechsoft.com) | |
10 | // Licence: wxWindows licence | |
11 | ///////////////////////////////////////////////////////////////////////////// | |
12 | ||
13 | // ============================================================================ | |
14 | // declarations | |
15 | // ============================================================================ | |
16 | ||
17 | // ---------------------------------------------------------------------------- | |
18 | // headers | |
19 | // ---------------------------------------------------------------------------- | |
20 | ||
21 | #ifdef __GNUG__ | |
22 | #pragma implementation "univtoolbar.h" | |
23 | #endif | |
24 | ||
25 | // For compilers that support precompilation, includes "wx.h". | |
26 | #include "wx/wxprec.h" | |
27 | ||
28 | #ifdef __BORLANDC__ | |
29 | #pragma hdrstop | |
30 | #endif | |
31 | ||
32 | #ifndef WX_PRECOMP | |
33 | #include "wx/utils.h" | |
34 | #include "wx/app.h" | |
35 | ||
36 | #include "wx/univ/renderer.h" | |
37 | #endif | |
38 | ||
39 | #include "wx/toolbar.h" | |
40 | #include "wx/image.h" | |
41 | ||
42 | // ---------------------------------------------------------------------------- | |
43 | // constants | |
44 | // ---------------------------------------------------------------------------- | |
45 | ||
46 | // value meaning that m_widthSeparator is not initialized | |
47 | static const wxCoord INVALID_WIDTH = -1; | |
48 | ||
49 | // ---------------------------------------------------------------------------- | |
50 | // wxToolBarTool: our implementation of wxToolBarToolBase | |
51 | // ---------------------------------------------------------------------------- | |
52 | ||
53 | class WXDLLEXPORT wxToolBarTool : public wxToolBarToolBase | |
54 | { | |
55 | public: | |
56 | wxToolBarTool( wxToolBarBase *tbar = (wxToolBarBase *)NULL, | |
57 | int id = wxID_SEPARATOR, | |
58 | const wxBitmap& bitmap1 = wxNullBitmap, | |
59 | const wxBitmap& bitmap2 = wxNullBitmap, | |
60 | bool toggle = FALSE, | |
61 | wxObject *clientData = (wxObject *) NULL, | |
62 | const wxString& shortHelpString = wxEmptyString, | |
63 | const wxString& longHelpString = wxEmptyString ) | |
64 | : wxToolBarToolBase(tbar, id, bitmap1, bitmap2, toggle, clientData, | |
65 | shortHelpString, longHelpString) | |
66 | { | |
67 | // no position yet | |
68 | m_x = | |
69 | m_y = -1; | |
70 | ||
71 | // not pressed yet | |
72 | m_isInverted = FALSE; | |
73 | } | |
74 | ||
75 | // is this tool pressed, even temporarily? (this is different from being | |
76 | // permanently toggled which is what IsToggled() returns) | |
77 | bool IsPressed() const | |
78 | { return CanBeToggled() ? IsToggled() != m_isInverted : m_isInverted; } | |
79 | ||
80 | // are we temporarily pressed/unpressed? | |
81 | bool IsInverted() const { return m_isInverted; } | |
82 | ||
83 | // press the tool temporarily by inverting its toggle state | |
84 | void Invert() { m_isInverted = !m_isInverted; } | |
85 | ||
86 | public: | |
87 | // the tool position (the size is known by the toolbar itself) | |
88 | int m_x, | |
89 | m_y; | |
90 | ||
91 | private: | |
92 | // TRUE if the tool is pressed | |
93 | bool m_isInverted; | |
94 | }; | |
95 | ||
96 | // ============================================================================ | |
97 | // wxToolBar implementation | |
98 | // ============================================================================ | |
99 | ||
100 | IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl); | |
101 | ||
102 | // ---------------------------------------------------------------------------- | |
103 | // wxToolBar creation | |
104 | // ---------------------------------------------------------------------------- | |
105 | ||
106 | void wxToolBar::Init() | |
107 | { | |
108 | // no tools yet | |
109 | m_needsLayout = FALSE; | |
110 | ||
111 | // unknown widths for the tools and separators | |
112 | m_widthSeparator = INVALID_WIDTH; | |
113 | ||
114 | m_maxWidth = | |
115 | m_maxHeight = 0; | |
116 | ||
117 | m_toolPressed = NULL; | |
118 | m_toolCurrent = NULL; | |
119 | ||
120 | wxRenderer *renderer = GetRenderer(); | |
121 | ||
122 | SetToolBitmapSize(renderer->GetToolBarButtonSize(&m_widthSeparator)); | |
123 | SetMargins(renderer->GetToolBarMargin()); | |
124 | } | |
125 | ||
126 | bool wxToolBar::Create(wxWindow *parent, | |
127 | wxWindowID id, | |
128 | const wxPoint& pos, | |
129 | const wxSize& size, | |
130 | long style, | |
131 | const wxString& name) | |
132 | { | |
133 | if ( !wxToolBarBase::Create(parent, id, pos, size, style, | |
134 | wxDefaultValidator, name) ) | |
135 | { | |
136 | return FALSE; | |
137 | } | |
138 | ||
139 | CreateInputHandler(wxINP_HANDLER_TOOLBAR); | |
140 | ||
141 | SetBestSize(size); | |
142 | ||
143 | return TRUE; | |
144 | } | |
145 | ||
146 | wxToolBar::~wxToolBar() | |
147 | { | |
148 | } | |
149 | ||
150 | // ---------------------------------------------------------------------------- | |
151 | // wxToolBar tool-related methods | |
152 | // ---------------------------------------------------------------------------- | |
153 | ||
154 | wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const | |
155 | { | |
156 | // check the "other" direction first: it must be inside the toolbar or we | |
157 | // don't risk finding anything | |
158 | if ( IsVertical() ) | |
159 | { | |
160 | if ( x < 0 || x > m_maxWidth ) | |
161 | return NULL; | |
162 | ||
163 | // we always use x, even for a vertical toolbar, this makes the code | |
164 | // below simpler | |
165 | x = y; | |
166 | } | |
167 | else // horizontal | |
168 | { | |
169 | if ( y < 0 || y > m_maxHeight ) | |
170 | return NULL; | |
171 | } | |
172 | ||
173 | for ( wxToolBarToolsList::Node *node = m_tools.GetFirst(); | |
174 | node; | |
175 | node = node->GetNext() ) | |
176 | { | |
177 | wxToolBarToolBase *tool = node->GetData(); | |
178 | wxRect rectTool = GetToolRect(tool); | |
179 | ||
180 | wxCoord startTool, endTool; | |
181 | GetRectLimits(rectTool, &startTool, &endTool); | |
182 | ||
183 | if ( x >= startTool && x <= endTool ) | |
184 | { | |
185 | // don't return the separators from here, they don't accept any | |
186 | // input anyhow | |
187 | return tool->IsSeparator() ? NULL : tool; | |
188 | } | |
189 | } | |
190 | ||
191 | return NULL; | |
192 | } | |
193 | ||
194 | void wxToolBar::SetToolShortHelp(int id, const wxString& help) | |
195 | { | |
196 | wxToolBarToolBase *tool = FindById(id); | |
197 | ||
198 | wxCHECK_RET( tool, _T("SetToolShortHelp: no such tool") ); | |
199 | ||
200 | tool->SetShortHelp(help); | |
201 | } | |
202 | ||
203 | bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), | |
204 | wxToolBarToolBase * WXUNUSED(tool)) | |
205 | { | |
206 | // recalculate the toolbar geometry before redrawing it the next time | |
207 | m_needsLayout = TRUE; | |
208 | ||
209 | // and ensure that we indeed are going to redraw | |
210 | Refresh(); | |
211 | ||
212 | return TRUE; | |
213 | } | |
214 | ||
215 | bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), | |
216 | wxToolBarToolBase * WXUNUSED(tool)) | |
217 | { | |
218 | // as above | |
219 | m_needsLayout = TRUE; | |
220 | ||
221 | Refresh(); | |
222 | ||
223 | return TRUE; | |
224 | } | |
225 | ||
226 | void wxToolBar::DoEnableTool(wxToolBarToolBase *tool, bool enable) | |
227 | { | |
228 | // created disabled-state bitmap on demand | |
229 | if ( !enable && !tool->GetDisabledBitmap().Ok() ) | |
230 | { | |
231 | wxImage image( tool->GetNormalBitmap() ); | |
232 | ||
233 | // TODO: don't hardcode 180 | |
234 | unsigned char bg_red = 180; | |
235 | unsigned char bg_green = 180; | |
236 | unsigned char bg_blue = 180; | |
237 | ||
238 | unsigned char mask_red = image.GetMaskRed(); | |
239 | unsigned char mask_green = image.GetMaskGreen(); | |
240 | unsigned char mask_blue = image.GetMaskBlue(); | |
241 | ||
242 | bool has_mask = image.HasMask(); | |
243 | ||
244 | int x,y; | |
245 | for (y = 0; y < image.GetHeight(); y++) | |
246 | { | |
247 | for (x = 0; x < image.GetWidth(); x++) | |
248 | { | |
249 | unsigned char red = image.GetRed(x,y); | |
250 | unsigned char green = image.GetGreen(x,y); | |
251 | unsigned char blue = image.GetBlue(x,y); | |
252 | if (!has_mask || red != mask_red || green != mask_green || blue != mask_blue) | |
253 | { | |
254 | red = (((wxInt32) red - bg_red) >> 1) + bg_red; | |
255 | green = (((wxInt32) green - bg_green) >> 1) + bg_green; | |
256 | blue = (((wxInt32) blue - bg_blue) >> 1) + bg_blue; | |
257 | image.SetRGB( x, y, red, green, blue ); | |
258 | } | |
259 | } | |
260 | } | |
261 | ||
262 | for (y = 0; y < image.GetHeight(); y++) | |
263 | { | |
264 | for (x = y % 2; x < image.GetWidth(); x += 2) | |
265 | { | |
266 | unsigned char red = image.GetRed(x,y); | |
267 | unsigned char green = image.GetGreen(x,y); | |
268 | unsigned char blue = image.GetBlue(x,y); | |
269 | if (!has_mask || red != mask_red || green != mask_green || blue != mask_blue) | |
270 | { | |
271 | red = (((wxInt32) red - bg_red) >> 1) + bg_red; | |
272 | green = (((wxInt32) green - bg_green) >> 1) + bg_green; | |
273 | blue = (((wxInt32) blue - bg_blue) >> 1) + bg_blue; | |
274 | image.SetRGB( x, y, red, green, blue ); | |
275 | } | |
276 | } | |
277 | } | |
278 | ||
279 | tool->SetDisabledBitmap( image.ConvertToBitmap() ); | |
280 | } | |
281 | ||
282 | RefreshTool(tool); | |
283 | } | |
284 | ||
285 | void wxToolBar::DoToggleTool(wxToolBarToolBase *tool, bool WXUNUSED(toggle)) | |
286 | { | |
287 | // note that if we're called the tool did change state (the base class | |
288 | // checks for it), so it's not necessary to check for this again here | |
289 | RefreshTool(tool); | |
290 | } | |
291 | ||
292 | void wxToolBar::DoSetToggle(wxToolBarToolBase *tool, bool WXUNUSED(toggle)) | |
293 | { | |
294 | RefreshTool(tool); | |
295 | } | |
296 | ||
297 | wxToolBarToolBase *wxToolBar::CreateTool(int id, | |
298 | const wxBitmap& bitmap1, | |
299 | const wxBitmap& bitmap2, | |
300 | bool toggle, | |
301 | wxObject *clientData, | |
302 | const wxString& shortHelpString, | |
303 | const wxString& longHelpString) | |
304 | { | |
305 | return new wxToolBarTool( this, id, bitmap1, bitmap2, toggle, | |
306 | clientData, shortHelpString, longHelpString); | |
307 | } | |
308 | ||
309 | wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control) | |
310 | { | |
311 | wxFAIL_MSG( wxT("Toolbar doesn't support controls yet (TODO)") ); | |
312 | ||
313 | return NULL; | |
314 | } | |
315 | ||
316 | // ---------------------------------------------------------------------------- | |
317 | // wxToolBar geometry | |
318 | // ---------------------------------------------------------------------------- | |
319 | ||
320 | wxRect wxToolBar::GetToolRect(wxToolBarToolBase *toolBase) const | |
321 | { | |
322 | const wxToolBarTool *tool = (wxToolBarTool *)toolBase; | |
323 | ||
324 | wxRect rect; | |
325 | ||
326 | wxCHECK_MSG( tool, rect, _T("GetToolRect: NULL tool") ); | |
327 | ||
328 | // ensure that we always have the valid tool position | |
329 | if ( m_needsLayout ) | |
330 | { | |
331 | wxConstCast(this, wxToolBar)->DoLayout(); | |
332 | } | |
333 | ||
334 | rect.x = tool->m_x - m_xMargin; | |
335 | rect.y = tool->m_y - m_yMargin; | |
336 | ||
337 | if ( IsVertical() ) | |
338 | { | |
339 | rect.width = m_defaultWidth; | |
340 | rect.height = tool->IsSeparator() ? m_widthSeparator : m_defaultHeight; | |
341 | } | |
342 | else // horizontal | |
343 | { | |
344 | rect.width = tool->IsSeparator() ? m_widthSeparator : m_defaultWidth; | |
345 | rect.height = m_defaultHeight; | |
346 | } | |
347 | ||
348 | rect.width += 2*m_xMargin; | |
349 | rect.height += 2*m_yMargin; | |
350 | ||
351 | return rect; | |
352 | } | |
353 | ||
354 | bool wxToolBar::Realize() | |
355 | { | |
356 | if ( !wxToolBarBase::Realize() ) | |
357 | return FALSE; | |
358 | ||
359 | m_needsLayout = TRUE; | |
360 | DoLayout(); | |
361 | ||
362 | SetBestSize(wxDefaultSize); | |
363 | ||
364 | return TRUE; | |
365 | } | |
366 | ||
367 | void wxToolBar::DoLayout() | |
368 | { | |
369 | wxASSERT_MSG( m_needsLayout, _T("why are we called?") ); | |
370 | ||
371 | m_needsLayout = FALSE; | |
372 | ||
373 | wxCoord x = m_xMargin, | |
374 | y = m_yMargin; | |
375 | ||
376 | const wxCoord widthTool = IsVertical() ? m_defaultHeight : m_defaultWidth; | |
377 | wxCoord margin = IsVertical() ? m_xMargin : m_yMargin, | |
378 | *pCur = IsVertical() ? &y : &x; | |
379 | ||
380 | // calculate the positions of all elements | |
381 | for ( wxToolBarToolsList::Node *node = m_tools.GetFirst(); | |
382 | node; | |
383 | node = node->GetNext() ) | |
384 | { | |
385 | wxToolBarTool *tool = (wxToolBarTool *) node->GetData(); | |
386 | ||
387 | tool->m_x = x; | |
388 | tool->m_y = y; | |
389 | ||
390 | *pCur += (tool->IsSeparator() ? m_widthSeparator : widthTool) + margin; | |
391 | } | |
392 | ||
393 | // calculate the total toolbar size | |
394 | wxCoord xMin = m_defaultWidth + 2*m_xMargin, | |
395 | yMin = m_defaultHeight + 2*m_yMargin; | |
396 | ||
397 | m_maxWidth = x < xMin ? xMin : x; | |
398 | m_maxHeight = y < yMin ? yMin : y; | |
399 | } | |
400 | ||
401 | wxSize wxToolBar::DoGetBestClientSize() const | |
402 | { | |
403 | return wxSize(m_maxWidth, m_maxHeight); | |
404 | } | |
405 | ||
406 | // ---------------------------------------------------------------------------- | |
407 | // wxToolBar drawing | |
408 | // ---------------------------------------------------------------------------- | |
409 | ||
410 | void wxToolBar::RefreshTool(wxToolBarToolBase *tool) | |
411 | { | |
412 | RefreshRect(GetToolRect(tool)); | |
413 | } | |
414 | ||
415 | void wxToolBar::GetRectLimits(const wxRect& rect, | |
416 | wxCoord *start, | |
417 | wxCoord *end) const | |
418 | { | |
419 | wxCHECK_RET( start && end, _T("NULL pointer in GetRectLimits") ); | |
420 | ||
421 | if ( IsVertical() ) | |
422 | { | |
423 | *start = rect.GetTop(); | |
424 | *end = rect.GetBottom(); | |
425 | } | |
426 | else // horizontal | |
427 | { | |
428 | *start = rect.GetLeft(); | |
429 | *end = rect.GetRight(); | |
430 | } | |
431 | } | |
432 | ||
433 | void wxToolBar::DoDraw(wxControlRenderer *renderer) | |
434 | { | |
435 | // prepare the variables used below | |
436 | wxDC& dc = renderer->GetDC(); | |
437 | wxRenderer *rend = renderer->GetRenderer(); | |
438 | // dc.SetFont(GetFont()); -- uncomment when we support labels | |
439 | ||
440 | // draw the border separating us from the menubar (if there is no menubar | |
441 | // we probably shouldn't draw it?) | |
442 | if ( !IsVertical() ) | |
443 | { | |
444 | rend->DrawHorizontalLine(dc, 0, 0, GetClientSize().x); | |
445 | } | |
446 | ||
447 | // get the update rect and its limits depending on the orientation | |
448 | wxRect rectUpdate = GetUpdateClientRect(); | |
449 | wxCoord start, end; | |
450 | GetRectLimits(rectUpdate, &start, &end); | |
451 | ||
452 | // and redraw all the tools intersecting it | |
453 | for ( wxToolBarToolsList::Node *node = m_tools.GetFirst(); | |
454 | node; | |
455 | node = node->GetNext() ) | |
456 | { | |
457 | wxToolBarToolBase *tool = node->GetData(); | |
458 | wxRect rectTool = GetToolRect(tool); | |
459 | wxCoord startTool, endTool; | |
460 | GetRectLimits(rectTool, &startTool, &endTool); | |
461 | ||
462 | if ( endTool < start ) | |
463 | { | |
464 | // we're still to the left of the area to redraw | |
465 | continue; | |
466 | } | |
467 | ||
468 | if ( startTool > end ) | |
469 | { | |
470 | // we're beyond the area to redraw, nothing left to do | |
471 | break; | |
472 | } | |
473 | ||
474 | // deal with the flags | |
475 | int flags = 0; | |
476 | ||
477 | if ( tool->IsEnabled() ) | |
478 | { | |
479 | // the toolbars without wxTB_FLAT don't react to the mouse hovering | |
480 | if ( HasFlag(wxTB_FLAT) && (tool == m_toolCurrent) ) | |
481 | flags |= wxCONTROL_CURRENT; | |
482 | } | |
483 | else // disabled tool | |
484 | { | |
485 | flags |= wxCONTROL_DISABLED; | |
486 | } | |
487 | ||
488 | if ( tool == m_toolPressed ) | |
489 | flags |= wxCONTROL_FOCUSED; | |
490 | ||
491 | if ( ((wxToolBarTool *)tool)->IsPressed() ) | |
492 | flags |= wxCONTROL_PRESSED; | |
493 | ||
494 | wxString label; | |
495 | wxBitmap bitmap; | |
496 | if ( !tool->IsSeparator() ) | |
497 | { | |
498 | label = tool->GetLabel(); | |
499 | bitmap = tool->GetBitmap(); | |
500 | } | |
501 | //else: leave both the label and the bitmap invalid to draw a separator | |
502 | ||
503 | rend->DrawToolBarButton(dc, label, bitmap, rectTool, flags); | |
504 | } | |
505 | } | |
506 | ||
507 | // ---------------------------------------------------------------------------- | |
508 | // wxToolBar actions | |
509 | // ---------------------------------------------------------------------------- | |
510 | ||
511 | void wxToolBar::Press() | |
512 | { | |
513 | wxCHECK_RET( m_toolCurrent, _T("no tool to press?") ); | |
514 | ||
515 | wxLogTrace(_T("toolbar"), | |
516 | _T("Button '%s' pressed."), | |
517 | m_toolCurrent->GetShortHelp().c_str()); | |
518 | ||
519 | // this is the tool whose state is going to change | |
520 | m_toolPressed = (wxToolBarTool *)m_toolCurrent; | |
521 | ||
522 | // we must toggle it regardless of whether it is a checkable tool or not, | |
523 | // so use Invert() and not Toggle() here | |
524 | m_toolPressed->Invert(); | |
525 | ||
526 | RefreshTool(m_toolPressed); | |
527 | } | |
528 | ||
529 | void wxToolBar::Release() | |
530 | { | |
531 | wxCHECK_RET( m_toolPressed, _T("no tool to release?") ); | |
532 | ||
533 | wxLogTrace(_T("toolbar"), | |
534 | _T("Button '%s' released."), | |
535 | m_toolCurrent->GetShortHelp().c_str()); | |
536 | ||
537 | wxASSERT_MSG( m_toolPressed->IsInverted(), _T("release unpressed button?") ); | |
538 | ||
539 | m_toolPressed->Invert(); | |
540 | ||
541 | RefreshTool(m_toolPressed); | |
542 | } | |
543 | ||
544 | void wxToolBar::Toggle() | |
545 | { | |
546 | m_toolCurrent = m_toolPressed; | |
547 | ||
548 | Release(); | |
549 | ||
550 | Click(); | |
551 | } | |
552 | ||
553 | void wxToolBar::Click() | |
554 | { | |
555 | wxCHECK_RET( m_toolCurrent, _T("no tool to click?") ); | |
556 | ||
557 | bool isToggled; | |
558 | if ( m_toolCurrent->CanBeToggled() ) | |
559 | { | |
560 | m_toolCurrent->Toggle(); | |
561 | ||
562 | RefreshTool(m_toolCurrent); | |
563 | ||
564 | isToggled = m_toolCurrent->IsToggled(); | |
565 | } | |
566 | else // simple non-checkable tool | |
567 | { | |
568 | isToggled = FALSE; | |
569 | } | |
570 | ||
571 | OnLeftClick(m_toolCurrent->GetId(), isToggled); | |
572 | } | |
573 | ||
574 | bool wxToolBar::PerformAction(const wxControlAction& action, | |
575 | long numArg, | |
576 | const wxString& strArg) | |
577 | { | |
578 | if ( action == wxACTION_TOOLBAR_TOGGLE ) | |
579 | Toggle(); | |
580 | else if ( action == wxACTION_TOOLBAR_PRESS ) | |
581 | Press(); | |
582 | else if ( action == wxACTION_TOOLBAR_RELEASE ) | |
583 | Release(); | |
584 | else if ( action == wxACTION_TOOLBAR_CLICK ) | |
585 | Click(); | |
586 | else if ( action == wxACTION_TOOLBAR_ENTER ) | |
587 | { | |
588 | wxToolBarToolBase *toolCurrentOld = m_toolCurrent; | |
589 | m_toolCurrent = FindById((int)numArg); | |
590 | ||
591 | if ( m_toolCurrent != toolCurrentOld ) | |
592 | { | |
593 | // the appearance of the current tool only changes for the flat | |
594 | // toolbars | |
595 | if ( HasFlag(wxTB_FLAT) ) | |
596 | { | |
597 | // and only if the tool was/is enabled | |
598 | if ( toolCurrentOld && toolCurrentOld->IsEnabled() ) | |
599 | RefreshTool(toolCurrentOld); | |
600 | ||
601 | if ( m_toolCurrent ) | |
602 | { | |
603 | if ( m_toolCurrent->IsEnabled() ) | |
604 | RefreshTool(m_toolCurrent); | |
605 | } | |
606 | else | |
607 | { | |
608 | wxFAIL_MSG( _T("no current tool in wxACTION_TOOLBAR_ENTER?") ); | |
609 | } | |
610 | } | |
611 | } | |
612 | } | |
613 | else if ( action == wxACTION_TOOLBAR_LEAVE ) | |
614 | { | |
615 | if ( m_toolCurrent ) | |
616 | { | |
617 | wxToolBarToolBase *toolCurrentOld = m_toolCurrent; | |
618 | m_toolCurrent = NULL; | |
619 | ||
620 | RefreshTool(toolCurrentOld); | |
621 | } | |
622 | } | |
623 | else | |
624 | return wxControl::PerformAction(action, numArg, strArg); | |
625 | ||
626 | return TRUE; | |
627 | } | |
628 | ||
629 | // ============================================================================ | |
630 | // wxStdToolbarInputHandler implementation | |
631 | // ============================================================================ | |
632 | ||
633 | wxStdToolbarInputHandler::wxStdToolbarInputHandler(wxInputHandler *handler) | |
634 | : wxStdButtonInputHandler(handler) | |
635 | { | |
636 | } | |
637 | ||
638 | bool wxStdToolbarInputHandler::HandleKey(wxInputConsumer *consumer, | |
639 | const wxKeyEvent& event, | |
640 | bool pressed) | |
641 | { | |
642 | // TODO: when we have a current button we should allow the arrow | |
643 | // keys to move it | |
644 | return wxStdInputHandler::HandleKey(consumer, event, pressed); | |
645 | } | |
646 | ||
647 | bool wxStdToolbarInputHandler::HandleMouse(wxInputConsumer *consumer, | |
648 | const wxMouseEvent& event) | |
649 | { | |
650 | // don't let the base class press the disabled buttons but simply ignore | |
651 | // all events on them | |
652 | wxToolBar *tbar = wxStaticCast(consumer->GetInputWindow(), wxToolBar); | |
653 | wxToolBarToolBase *tool = tbar->FindToolForPosition(event.GetX(), event.GetY()); | |
654 | ||
655 | if ( tool && !tool->IsEnabled() ) | |
656 | return TRUE; | |
657 | ||
658 | return wxStdButtonInputHandler::HandleMouse(consumer, event); | |
659 | } | |
660 | ||
661 | bool wxStdToolbarInputHandler::HandleMouseMove(wxInputConsumer *consumer, | |
662 | const wxMouseEvent& event) | |
663 | { | |
664 | if ( !wxStdButtonInputHandler::HandleMouseMove(consumer, event) ) | |
665 | { | |
666 | wxToolBarToolBase *tool; | |
667 | ||
668 | if ( event.Leaving() ) | |
669 | { | |
670 | tool = NULL; | |
671 | } | |
672 | else | |
673 | { | |
674 | wxToolBar *tbar = wxStaticCast(consumer->GetInputWindow(), wxToolBar); | |
675 | tool = tbar->FindToolForPosition(event.GetX(), event.GetY()); | |
676 | } | |
677 | ||
678 | if ( tool ) | |
679 | consumer->PerformAction(wxACTION_TOOLBAR_ENTER, tool->GetId()); | |
680 | else | |
681 | consumer->PerformAction(wxACTION_TOOLBAR_LEAVE); | |
682 | ||
683 | return TRUE; | |
684 | } | |
685 | ||
686 | return FALSE; | |
687 | } | |
688 | ||
689 | bool wxStdToolbarInputHandler::HandleFocus(wxInputConsumer *consumer, | |
690 | const wxFocusEvent& event) | |
691 | { | |
692 | // we shouldn't be left with a highlighted button | |
693 | consumer->PerformAction(wxACTION_TOOLBAR_LEAVE); | |
694 | ||
695 | return TRUE; | |
696 | } | |
697 | ||
698 | bool wxStdToolbarInputHandler::HandleActivation(wxInputConsumer *consumer, | |
699 | bool activated) | |
700 | { | |
701 | // as above | |
702 | if ( !activated ) | |
703 | consumer->PerformAction(wxACTION_TOOLBAR_LEAVE); | |
704 | ||
705 | return TRUE; | |
706 | } | |
707 |