]> git.saurik.com Git - wxWidgets.git/blob - src/os2/toolbar.cpp
Fix for crash when opening empty node
[wxWidgets.git] / src / os2 / toolbar.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/toolbar.cpp
3 // Purpose: wxToolBar
4 // Author: David Webster
5 // Modified by:
6 // Created: 06/30/02
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #if wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE
16
17 #include "wx/toolbar.h"
18
19 #ifndef WX_PRECOMP
20 #include "wx/settings.h"
21 #include "wx/window.h"
22 #include "wx/frame.h"
23 #include "wx/app.h"
24 #include "wx/dcclient.h"
25 #include "wx/dcmemory.h"
26 #endif
27
28 #include "wx/tooltip.h"
29
30 bool wxToolBar::m_bInitialized = false;
31
32 // ----------------------------------------------------------------------------
33 // private classes
34 // ----------------------------------------------------------------------------
35
36 class wxToolBarTool : public wxToolBarToolBase
37 {
38 public:
39 inline wxToolBarTool( wxToolBar* pTbar
40 ,int vId
41 ,const wxString& rsLabel
42 ,const wxBitmap& rBitmap1
43 ,const wxBitmap& rBitmap2
44 ,wxItemKind vKind
45 ,wxObject* pClientData
46 ,const wxString& rsShortHelpString
47 ,const wxString& rsLongHelpString
48 ) : wxToolBarToolBase( pTbar
49 ,vId
50 ,rsLabel
51 ,rBitmap1
52 ,rBitmap2
53 ,vKind
54 ,pClientData
55 ,rsShortHelpString
56 ,rsLongHelpString
57 )
58 {
59 }
60
61 inline wxToolBarTool( wxToolBar* pTbar
62 ,wxControl* pControl
63 ,const wxString& label
64 ) : wxToolBarToolBase( pTbar
65 ,pControl
66 ,label
67 )
68 {
69 }
70
71 void SetSize(const wxSize& rSize)
72 {
73 m_vWidth = rSize.x;
74 m_vHeight = rSize.y;
75 }
76
77 wxCoord GetWidth(void) const { return m_vWidth; }
78 wxCoord GetHeight(void) const { return m_vHeight; }
79
80 wxCoord m_vX;
81 wxCoord m_vY;
82 wxCoord m_vWidth;
83 wxCoord m_vHeight;
84 }; // end of CLASS wxToolBarTool
85
86 // ----------------------------------------------------------------------------
87 // wxWin macros
88 // ----------------------------------------------------------------------------
89
90 IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl)
91
92 BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
93 EVT_SIZE(wxToolBar::OnSize)
94 EVT_PAINT(wxToolBar::OnPaint)
95 EVT_KILL_FOCUS(wxToolBar::OnKillFocus)
96 EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent)
97 EVT_TIMER(-1, wxToolBar::OnTimer)
98 END_EVENT_TABLE()
99
100 // ============================================================================
101 // implementation
102 // ============================================================================
103
104 // ----------------------------------------------------------------------------
105 // tool bar tools creation
106 // ----------------------------------------------------------------------------
107
108 wxToolBarToolBase* wxToolBar::CreateTool(
109 int nId
110 , const wxString& rsLabel
111 , const wxBitmap& rBmpNormal
112 , const wxBitmap& rBmpDisabled
113 , wxItemKind eKind
114 , wxObject* pClientData
115 , const wxString& rsShortHelp
116 , const wxString& rsLongHelp
117 )
118 {
119 return new wxToolBarTool( this
120 ,nId
121 ,rsLabel
122 ,rBmpNormal
123 ,rBmpDisabled
124 ,eKind
125 ,pClientData
126 ,rsShortHelp
127 ,rsLongHelp
128 );
129 } // end of wxToolBarSimple::CreateTool
130
131 wxToolBarToolBase *wxToolBar::CreateTool(
132 wxControl* pControl
133 , const wxString& label
134 )
135 {
136 return new wxToolBarTool( this
137 ,pControl
138 ,label
139 );
140 } // end of wxToolBarSimple::CreateTool
141
142 // ----------------------------------------------------------------------------
143 // wxToolBarSimple creation
144 // ----------------------------------------------------------------------------
145
146 void wxToolBar::Init()
147 {
148 m_nCurrentRowsOrColumns = 0;
149
150 m_vLastX = m_vLastY = 0;
151 m_vMaxWidth = m_vMaxHeight = 0;
152 m_nPressedTool = m_nCurrentTool = -1;
153 m_vXPos = m_vYPos = -1;
154 m_vTextX = m_vTextY = 0;
155
156 m_toolPacking = 1;
157 m_toolSeparation = 5;
158
159 m_defaultWidth = 16;
160 m_defaultHeight = 15;
161
162 m_pToolTip = NULL;
163 } // end of wxToolBar::Init
164
165 wxToolBarToolBase* wxToolBar::DoAddTool(
166 int vId
167 , const wxString& rsLabel
168 , const wxBitmap& rBitmap
169 , const wxBitmap& rBmpDisabled
170 , wxItemKind eKind
171 , const wxString& rsShortHelp
172 , const wxString& rsLongHelp
173 , wxObject* pClientData
174 , wxCoord vXPos
175 , wxCoord vYPos
176 )
177 {
178 //
179 // Rememeber the position for DoInsertTool()
180 //
181 m_vXPos = vXPos;
182 m_vYPos = vYPos;
183
184 return wxToolBarBase::DoAddTool( vId
185 ,rsLabel
186 ,rBitmap
187 ,rBmpDisabled
188 ,eKind
189 ,rsShortHelp
190 ,rsLongHelp
191 ,pClientData
192 ,vXPos
193 ,vYPos
194 );
195 } // end of wxToolBar::DoAddTool
196
197 bool wxToolBar::DeleteTool(
198 int nId
199 )
200 {
201 bool bOk = wxToolBarBase::DeleteTool(nId);
202
203 if (bOk)
204 {
205 Realize();
206 }
207 return bOk;
208 } // end of wxToolBar::DeleteTool
209
210 bool wxToolBar::DeleteToolByPos(
211 size_t nPos
212 )
213 {
214 bool bOk = wxToolBarBase::DeleteToolByPos(nPos);
215
216 if (bOk)
217 {
218 Realize();
219 }
220 return bOk;
221 } // end of wxToolBar::DeleteTool
222
223 wxToolBarToolBase* wxToolBar::InsertControl(
224 size_t nPos
225 , wxControl* pControl
226 )
227 {
228 wxToolBarToolBase* pTool = wxToolBarBase::InsertControl( nPos
229 ,pControl
230 );
231 if (m_bInitialized)
232 {
233 Realize();
234 Refresh();
235 }
236 return pTool;
237 } // end of wxToolBar::InsertControl
238
239 wxToolBarToolBase* wxToolBar::InsertSeparator(
240 size_t nPos
241 )
242 {
243 wxToolBarToolBase* pTool = wxToolBarBase::InsertSeparator(nPos);
244
245 if (m_bInitialized)
246 {
247 Realize();
248 Refresh();
249 }
250 return pTool;
251 } // end of wxToolBar::InsertSeparator
252
253 wxToolBarToolBase* wxToolBar::InsertTool(
254 size_t nPos
255 , int nId
256 , const wxString& rsLabel
257 , const wxBitmap& rBitmap
258 , const wxBitmap& rBmpDisabled
259 , wxItemKind eKind
260 , const wxString& rsShortHelp
261 , const wxString& rsLongHelp
262 , wxObject* pClientData
263 )
264 {
265 wxToolBarToolBase* pTool = wxToolBarBase::InsertTool( nPos
266 ,nId
267 ,rsLabel
268 ,rBitmap
269 ,rBmpDisabled
270 ,eKind
271 ,rsShortHelp
272 ,rsLongHelp
273 ,pClientData
274 );
275 if (m_bInitialized)
276 {
277 Realize();
278 Refresh();
279 }
280 return pTool;
281 } // end of wxToolBar::InsertTool
282
283 bool wxToolBar::DoInsertTool( size_t WXUNUSED(nPos),
284 wxToolBarToolBase* pToolBase )
285 {
286 wxToolBarTool* pTool = (wxToolBarTool *)pToolBase;
287
288 pTool->m_vX = m_vXPos;
289 if (pTool->m_vX == -1)
290 pTool->m_vX = m_xMargin;
291
292 pTool->m_vY = m_vYPos;
293 if (pTool->m_vY == -1)
294 pTool->m_vX = m_yMargin;
295
296 pTool->SetSize(GetToolSize());
297
298 if (pTool->IsButton())
299 {
300 //
301 // Calculate reasonable max size in case Layout() not called
302 //
303 if ((pTool->m_vX + pTool->GetNormalBitmap().GetWidth() + m_xMargin) > m_vMaxWidth)
304 m_vMaxWidth = (wxCoord)((pTool->m_vX + pTool->GetWidth() + m_xMargin));
305
306 if ((pTool->m_vY + pTool->GetNormalBitmap().GetHeight() + m_yMargin) > m_vMaxHeight)
307 m_vMaxHeight = (wxCoord)((pTool->m_vY + pTool->GetHeight() + m_yMargin));
308 }
309 return true;
310 } // end of wxToolBar::DoInsertTool
311
312 bool wxToolBar::DoDeleteTool( size_t WXUNUSED(nPos),
313 wxToolBarToolBase* pTool )
314 {
315 pTool->Detach();
316 Refresh();
317 return true;
318 } // end of wxToolBar::DoDeleteTool
319
320 bool wxToolBar::Create( wxWindow* pParent,
321 wxWindowID vId,
322 const wxPoint& rPos,
323 const wxSize& rSize,
324 long lStyle,
325 const wxString& rsName )
326 {
327 if ( !wxWindow::Create( pParent
328 ,vId
329 ,rPos
330 ,rSize
331 ,lStyle
332 ,rsName
333 ))
334 return false;
335
336 // Set it to grey (or other 3D face colour)
337 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENUBAR));
338 SetFont(*wxSMALL_FONT);
339
340 if (GetWindowStyleFlag() & (wxTB_LEFT | wxTB_RIGHT))
341 {
342 m_vLastX = 7;
343 m_vLastY = 3;
344
345 m_maxRows = 32000; // a lot
346 m_maxCols = 1;
347 }
348 else
349 {
350 m_vLastX = 3;
351 m_vLastY = 7;
352
353 m_maxRows = 1;
354 m_maxCols = 32000; // a lot
355 }
356 SetCursor(*wxSTANDARD_CURSOR);
357
358 //
359 // The toolbar's tools, if they have labels and the winTB_TEXT
360 // style is set, then we need to take into account the size of
361 // the text when drawing tool bitmaps and the text
362 //
363 if (HasFlag(wxTB_TEXT))
364 {
365 wxClientDC vDC(this);
366
367 vDC.SetFont(GetFont());
368 vDC.GetTextExtent( wxT("XXXX")
369 ,&m_vTextX
370 ,&m_vTextY
371 );
372 }
373
374 //
375 // Position it
376 //
377 int nX = rPos.x;
378 int nY = rPos.y;
379 int nWidth = rSize.x;
380 int nHeight = rSize.y;
381
382 if (lStyle & (wxTB_TOP | wxTB_BOTTOM))
383 {
384 if (nWidth <= 0)
385 {
386 nWidth = pParent->GetClientSize().x;
387 }
388 if (nHeight <= 0)
389 {
390 if (lStyle & wxTB_TEXT)
391 nHeight = m_defaultHeight + m_vTextY;
392 else
393 nHeight = m_defaultHeight;
394 }
395 }
396 else
397 {
398 if (nHeight <= 0)
399 {
400 nHeight = pParent->GetClientSize().y;
401 }
402 if (nWidth <= 0)
403 {
404 if (lStyle & wxTB_TEXT)
405 nWidth = m_vTextX + (int)(m_vTextX/2); // a little margin
406 else
407 nWidth = m_defaultWidth + (int)(m_defaultWidth/2); // a little margin
408 }
409 }
410 if (nX < 0)
411 nX = 0;
412 if (nY < 0)
413 nY = 0;
414
415 SetSize( nX
416 ,nY
417 ,nWidth
418 ,nHeight
419 );
420 return true;
421 } // end of wxToolBar::Create
422
423 wxToolBar::~wxToolBar()
424 {
425 if (m_pToolTip)
426 {
427 delete m_pToolTip;
428 m_pToolTip = NULL;
429 }
430 } // end of wxToolBar::~wxToolBar
431
432 bool wxToolBar::Realize()
433 {
434 int nMaxToolWidth = 0;
435 int nMaxToolHeight = 0;
436
437 m_nCurrentRowsOrColumns = 0;
438 m_vLastX = m_xMargin;
439 m_vLastY = m_yMargin;
440 m_vMaxWidth = 0;
441 m_vMaxHeight = 0;
442
443
444 //
445 // Find the maximum tool width and height
446 //
447 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
448
449 while (node )
450 {
451 wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
452
453 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty())
454 {
455 //
456 // Set the height according to the font and the border size
457 //
458 if (pTool->GetWidth() > m_vTextX)
459 nMaxToolWidth = pTool->GetWidth() + 4;
460 else
461 nMaxToolWidth = m_vTextX;
462 if (pTool->GetHeight() + m_vTextY > nMaxToolHeight)
463 nMaxToolHeight = pTool->GetHeight() + m_vTextY;
464 }
465 else
466 {
467 if (pTool->GetWidth() > nMaxToolWidth )
468 nMaxToolWidth = pTool->GetWidth() + 4;
469 if (pTool->GetHeight() > nMaxToolHeight)
470 nMaxToolHeight = pTool->GetHeight();
471 }
472 node = node->GetNext();
473 }
474
475 wxCoord vTbWidth = 0L;
476 wxCoord vTbHeight = 0L;
477
478 GetSize( &vTbWidth
479 ,&vTbHeight
480 );
481 if (vTbHeight < nMaxToolHeight)
482 {
483 SetSize( -1L
484 ,-1L
485 ,vTbWidth
486 ,nMaxToolHeight + 4
487 );
488 if (GetParent()->IsKindOf(CLASSINFO(wxFrame)))
489 {
490 wxFrame* pFrame = wxDynamicCast(GetParent(), wxFrame);
491
492 if (pFrame)
493 pFrame->PositionToolBar();
494 }
495 }
496
497 int nSeparatorSize = m_toolSeparation;
498
499 node = m_tools.GetFirst();
500 while (node)
501 {
502 wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
503
504 if (pTool->IsSeparator())
505 {
506 if (GetWindowStyleFlag() & (wxTB_TOP | wxTB_BOTTOM))
507 {
508 pTool->m_vX = m_vLastX + nSeparatorSize;
509 pTool->m_vHeight = m_defaultHeight + m_vTextY;
510 if (m_nCurrentRowsOrColumns >= m_maxCols)
511 m_vLastY += nSeparatorSize;
512 else
513 m_vLastX += nSeparatorSize * 4;
514 }
515 else
516 {
517 pTool->m_vY = m_vLastY + nSeparatorSize;
518 pTool->m_vHeight = m_defaultHeight + m_vTextY;
519 if (m_nCurrentRowsOrColumns >= m_maxRows)
520 m_vLastX += nSeparatorSize;
521 else
522 m_vLastY += nSeparatorSize * 4;
523 }
524 }
525 else if (pTool->IsButton())
526 {
527 if (GetWindowStyleFlag() & (wxTB_TOP | wxTB_BOTTOM))
528 {
529 if (m_nCurrentRowsOrColumns >= m_maxCols)
530 {
531 m_nCurrentRowsOrColumns = 0;
532 m_vLastX = m_xMargin;
533 m_vLastY += nMaxToolHeight + m_toolPacking;
534 }
535 pTool->m_vX = m_vLastX + (nMaxToolWidth - ((int)(nMaxToolWidth/2) + (int)(pTool->GetWidth()/2)));
536 if (HasFlag(wxTB_TEXT))
537 pTool->m_vY = m_vLastY + nSeparatorSize - 2; // just bit of adjustment
538 else
539 pTool->m_vY = m_vLastY + (nMaxToolHeight - (int)(pTool->GetHeight()/2));
540 m_vLastX += nMaxToolWidth + m_toolPacking + m_toolSeparation;
541 }
542 else
543 {
544 if (m_nCurrentRowsOrColumns >= m_maxRows)
545 {
546 m_nCurrentRowsOrColumns = 0;
547 m_vLastX += (nMaxToolWidth + m_toolPacking);
548 m_vLastY = m_yMargin;
549 }
550 pTool->m_vX = m_vLastX + pTool->GetWidth();
551 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
552 pTool->m_vY = m_vLastY + (nMaxToolHeight - m_vTextY) + m_toolPacking;
553 else
554 pTool->m_vY = m_vLastY + (nMaxToolHeight - (int)(pTool->GetHeight()/2));
555 m_vLastY += nMaxToolHeight + m_toolPacking + m_toolSeparation;
556 }
557 m_nCurrentRowsOrColumns++;
558 }
559 else
560 {
561 // TODO: support the controls
562 }
563
564 if (m_vLastX > m_maxWidth)
565 m_maxWidth = m_vLastX;
566 if (m_vLastY > m_maxHeight)
567 m_maxHeight = m_vLastY;
568
569 node = node->GetNext();
570 }
571
572 if (GetWindowStyleFlag() & (wxTB_TOP | wxTB_BOTTOM))
573 m_maxWidth += nMaxToolWidth;
574 else
575 m_maxHeight += nMaxToolHeight;
576
577 m_maxWidth += m_xMargin;
578 m_maxHeight += m_yMargin;
579 m_bInitialized = true;
580 return true;
581 } // end of wxToolBar::Realize
582
583 // ----------------------------------------------------------------------------
584 // event handlers
585 // ----------------------------------------------------------------------------
586
587 void wxToolBar::OnPaint (
588 wxPaintEvent& WXUNUSED(rEvent)
589 )
590 {
591 wxPaintDC vDc(this);
592
593 PrepareDC(vDc);
594
595 static int nCount = 0;
596
597 //
598 // Prevent reentry of OnPaint which would cause wxMemoryDC errors.
599 //
600 if (nCount > 0)
601 return;
602 nCount++;
603
604 ::WinFillRect(vDc.GetHPS(), &vDc.m_vRclPaint, GetBackgroundColour().GetPixel());
605 for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
606 node;
607 node = node->GetNext() )
608 {
609 wxToolBarTool* pTool = (wxToolBarTool*)node->GetData();
610
611 if (pTool->IsButton() )
612 DrawTool(vDc, pTool);
613 if (pTool->IsSeparator())
614 {
615 wxColour gray85(85, 85, 85);
616 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
617 int nX;
618 int nY;
619 int nHeight = 0;
620 int nWidth = 0;
621
622 vDc.SetPen(vDarkGreyPen);
623 if (HasFlag(wxTB_TEXT))
624 {
625 if (HasFlag(wxTB_TOP) || HasFlag(wxTB_BOTTOM))
626 {
627 nX = pTool->m_vX;
628 nY = pTool->m_vY - (m_vTextY - 6);
629 nHeight = (m_vTextY - 2) + pTool->GetHeight();
630 }
631 else
632 {
633 nX = pTool->m_vX + m_xMargin + 10;
634 nY = pTool->m_vY + m_vTextY + m_toolSeparation;
635 nWidth = pTool->GetWidth() > m_vTextX ? pTool->GetWidth() : m_vTextX;
636 }
637 }
638 else
639 {
640 nX = pTool->m_vX;
641 nY = pTool->m_vY;
642 if (HasFlag(wxTB_TOP) || HasFlag(wxTB_BOTTOM))
643 nHeight = pTool->GetHeight() - 2;
644 else
645 {
646 nX += m_xMargin + 10;
647 nY += m_yMargin + m_toolSeparation;
648 nWidth = pTool->GetWidth();
649 }
650 }
651 vDc.DrawLine(nX, nY, nX + nWidth, nY + nHeight);
652 }
653 }
654 nCount--;
655 } // end of wxToolBar::OnPaint
656
657 void wxToolBar::OnSize (
658 wxSizeEvent& WXUNUSED(rEvent)
659 )
660 {
661 #if wxUSE_CONSTRAINTS
662 if (GetAutoLayout())
663 Layout();
664 #endif
665 } // end of wxToolBar::OnSize
666
667 void wxToolBar::OnKillFocus(
668 wxFocusEvent& WXUNUSED(rEvent)
669 )
670 {
671 OnMouseEnter(m_nPressedTool = m_nCurrentTool = -1);
672 } // end of wxToolBar::OnKillFocus
673
674 void wxToolBar::OnMouseEvent(
675 wxMouseEvent& rEvent
676 )
677 {
678 POINTL vPoint;
679 HWND hWnd;
680 wxCoord vX;
681 wxCoord vY;
682 HPOINTER hPtr = ::WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE);
683
684 ::WinSetPointer(HWND_DESKTOP, hPtr);
685 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
686 hWnd = ::WinWindowFromPoint(HWND_DESKTOP, &vPoint, TRUE);
687 if (hWnd != (HWND)GetHwnd())
688 {
689 m_vToolTimer.Stop();
690 return;
691 }
692
693 rEvent.GetPosition(&vX, &vY);
694
695 wxToolBarTool* pTool = (wxToolBarTool *)FindToolForPosition( vX
696 ,vY
697 );
698
699 if (rEvent.LeftDown())
700 {
701 CaptureMouse();
702 }
703 if (rEvent.LeftUp())
704 {
705 ReleaseMouse();
706 }
707
708 if (!pTool)
709 {
710 m_vToolTimer.Stop();
711 if (m_nCurrentTool > -1)
712 {
713 if (rEvent.LeftIsDown())
714 SpringUpButton(m_nCurrentTool);
715 pTool = (wxToolBarTool *)FindById(m_nCurrentTool);
716 if (pTool && !pTool->IsToggled())
717 {
718 RaiseTool( pTool, FALSE );
719 }
720 m_nCurrentTool = -1;
721 OnMouseEnter(-1);
722 }
723 return;
724 }
725 if (!rEvent.IsButton())
726 {
727 if (pTool->GetId() != m_nCurrentTool)
728 {
729 //
730 // If the left button is kept down and moved over buttons,
731 // press those buttons.
732 //
733 if (rEvent.LeftIsDown() && pTool->IsEnabled())
734 {
735 SpringUpButton(m_nCurrentTool);
736 if (pTool->CanBeToggled())
737 {
738 pTool->Toggle();
739 }
740 DrawTool(pTool);
741 }
742 wxToolBarTool* pOldTool = (wxToolBarTool*)FindById(m_nCurrentTool);
743
744 if (pOldTool && !pTool->IsToggled())
745 RaiseTool( pOldTool, FALSE );
746 m_nCurrentTool = pTool->GetId();
747 OnMouseEnter(m_nCurrentTool);
748 if (!pTool->GetShortHelp().empty())
749 {
750 if (m_pToolTip)
751 delete m_pToolTip;
752 m_pToolTip = new wxToolTip(pTool->GetShortHelp());
753 m_vXMouse = (wxCoord)vPoint.x;
754 m_vYMouse = (wxCoord)vPoint.y;
755 m_vToolTimer.Start(1000L, TRUE);
756 }
757 if (!pTool->IsToggled())
758 RaiseTool(pTool);
759 }
760 return;
761 }
762
763 // Left button pressed.
764 if (rEvent.LeftDown() && pTool->IsEnabled())
765 {
766 if (pTool->CanBeToggled())
767 {
768 pTool->Toggle();
769 }
770 DrawTool(pTool);
771 }
772 else if (rEvent.RightDown())
773 {
774 OnRightClick( pTool->GetId()
775 ,vX
776 ,vY
777 );
778 }
779
780 //
781 // Left Button Released. Only this action confirms selection.
782 // If the button is enabled and it is not a toggle tool and it is
783 // in the pressed state, then raise the button and call OnLeftClick.
784 //
785 if (rEvent.LeftUp() && pTool->IsEnabled() )
786 {
787 //
788 // Pass the OnLeftClick event to tool
789 //
790 if (!OnLeftClick( pTool->GetId()
791 ,pTool->IsToggled()) &&
792 pTool->CanBeToggled())
793 {
794 //
795 // If it was a toggle, and OnLeftClick says No Toggle allowed,
796 // then change it back
797 //
798 pTool->Toggle();
799 }
800 DrawTool(pTool);
801 }
802 } // end of wxToolBar::OnMouseEvent
803
804 // ----------------------------------------------------------------------------
805 // drawing
806 // ----------------------------------------------------------------------------
807
808 void wxToolBar::DrawTool( wxToolBarToolBase* pTool )
809 {
810 wxClientDC vDc(this);
811
812 DrawTool( vDc, pTool );
813 } // end of wxToolBar::DrawTool
814
815 void wxToolBar::DrawTool( wxDC& rDc, wxToolBarToolBase* pToolBase )
816 {
817 wxToolBarTool* pTool = (wxToolBarTool *)pToolBase;
818 wxColour gray85( 85,85,85 );
819 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
820 wxBitmap vBitmap = pTool->GetNormalBitmap();
821 bool bUseMask = false;
822 wxMask* pMask = NULL;
823
824 PrepareDC(rDc);
825
826 if (!vBitmap.Ok())
827 return;
828 if ((pMask = vBitmap.GetMask()) != NULL)
829 if (pMask->GetMaskBitmap() != NULLHANDLE)
830 bUseMask = true;
831
832 if (!pTool->IsToggled())
833 {
834 LowerTool(pTool, FALSE);
835 if (!pTool->IsEnabled())
836 {
837 wxColour vColor(wxT("GREY"));
838
839 rDc.SetTextForeground(vColor);
840 if (!pTool->GetDisabledBitmap().Ok())
841 pTool->SetDisabledBitmap(wxDisableBitmap( vBitmap
842 ,(long)GetBackgroundColour().GetPixel()
843 ));
844 rDc.DrawBitmap( pTool->GetDisabledBitmap()
845 ,pTool->m_vX
846 ,pTool->m_vY
847 ,bUseMask
848 );
849 }
850 else
851 {
852 rDc.SetTextForeground(*wxBLACK);
853 rDc.DrawBitmap( vBitmap
854 ,pTool->m_vX
855 ,pTool->m_vY
856 ,bUseMask
857 );
858 }
859 if (m_windowStyle & wxTB_3DBUTTONS)
860 {
861 RaiseTool(pTool);
862 }
863 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
864 {
865 wxCoord vX;
866 wxCoord vY;
867 wxCoord vLeft = pTool->m_vX - (int)(pTool->GetWidth()/2);
868
869 rDc.SetFont(GetFont());
870 rDc.GetTextExtent( pTool->GetLabel()
871 ,&vX
872 ,&vY
873 );
874 if (pTool->GetWidth() > vX) // large tools
875 {
876 vLeft = pTool->m_vX + (pTool->GetWidth() - vX);
877 GetSize(&vX, &vY);
878 rDc.DrawText( pTool->GetLabel()
879 ,vLeft
880 ,vY - m_vTextY - 1
881 );
882 }
883 else // normal tools
884 {
885 vLeft += (wxCoord)((m_vTextX - vX)/2);
886 rDc.DrawText( pTool->GetLabel()
887 ,vLeft
888 ,pTool->m_vY + m_vTextY - 1 // a bit of margin
889 );
890 }
891 }
892 }
893 else
894 {
895 wxColour vColor(wxT("GREY"));
896
897 LowerTool(pTool);
898 rDc.SetTextForeground(vColor);
899 if (!pTool->GetDisabledBitmap().Ok())
900 pTool->SetDisabledBitmap(wxDisableBitmap( vBitmap
901 ,(long)GetBackgroundColour().GetPixel()
902 ));
903 rDc.DrawBitmap( pTool->GetDisabledBitmap()
904 ,pTool->m_vX
905 ,pTool->m_vY
906 ,bUseMask
907 );
908 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
909 {
910 wxCoord vX;
911 wxCoord vY;
912 wxCoord vLeft = pTool->m_vX - (int)(pTool->GetWidth()/2);
913
914 rDc.SetFont(GetFont());
915 rDc.GetTextExtent( pTool->GetLabel()
916 ,&vX
917 ,&vY
918 );
919 vLeft += (wxCoord)((m_vTextX - vX)/2);
920 rDc.DrawText( pTool->GetLabel()
921 ,vLeft
922 ,pTool->m_vY + m_vTextY - 1 // a bit of margin
923 );
924 }
925 }
926 } // end of wxToolBar::DrawTool
927
928 // ----------------------------------------------------------------------------
929 // toolbar geometry
930 // ----------------------------------------------------------------------------
931
932 void wxToolBar::SetRows(
933 int nRows
934 )
935 {
936 wxCHECK_RET( nRows != 0, _T("max number of rows must be > 0") );
937
938 m_maxCols = (GetToolsCount() + nRows - 1) / nRows;
939 Refresh();
940 } // end of wxToolBar::SetRows
941
942 wxToolBarToolBase* wxToolBar::FindToolForPosition(
943 wxCoord vX
944 , wxCoord vY
945 ) const
946 {
947 wxCoord vTBarHeight = 0;
948
949 GetSize( NULL
950 ,&vTBarHeight
951 );
952 vY = vTBarHeight - vY;
953 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
954 while (node)
955 {
956 wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
957
958 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
959 {
960 if ((vX >= (pTool->m_vX - ((wxCoord)(pTool->GetWidth()/2) - 2))) &&
961 (vY >= (pTool->m_vY - 2)) &&
962 (vX <= (pTool->m_vX + pTool->GetWidth())) &&
963 (vY <= (pTool->m_vY + pTool->GetHeight() + m_vTextY + 2)))
964 {
965 return pTool;
966 }
967 }
968 else
969 {
970 if ((vX >= pTool->m_vX) &&
971 (vY >= pTool->m_vY) &&
972 (vX <= (pTool->m_vX + pTool->GetWidth())) &&
973 (vY <= (pTool->m_vY + pTool->GetHeight())))
974 {
975 return pTool;
976 }
977 }
978 node = node->GetNext();
979 }
980 return (wxToolBarToolBase *)NULL;
981 } // end of wxToolBar::FindToolForPosition
982
983 // ----------------------------------------------------------------------------
984 // tool state change handlers
985 // ----------------------------------------------------------------------------
986
987 void wxToolBar::DoEnableTool(
988 wxToolBarToolBase* pTool
989 , bool WXUNUSED(bEnable)
990 )
991 {
992 DrawTool(pTool);
993 } // end of wxToolBar::DoEnableTool
994
995 void wxToolBar::DoToggleTool(
996 wxToolBarToolBase* pTool
997 , bool WXUNUSED(bToggle)
998 )
999 {
1000 DrawTool(pTool);
1001 } // end of wxToolBar::DoToggleTool
1002
1003 void wxToolBar::DoSetToggle(
1004 wxToolBarToolBase* WXUNUSED(pTool)
1005 , bool WXUNUSED(bToggle)
1006 )
1007 {
1008 // nothing to do
1009 } // end of wxToolBar::DoSetToggle
1010
1011 //
1012 // Okay, so we've left the tool we're in ... we must check if the tool we're
1013 // leaving was a 'sprung push button' and if so, spring it back to the up
1014 // state.
1015 //
1016 void wxToolBar::SpringUpButton(
1017 int vId
1018 )
1019 {
1020 wxToolBarToolBase* pTool = FindById(vId);
1021
1022 if (pTool && pTool->CanBeToggled())
1023 {
1024 if (pTool->IsToggled())
1025 pTool->Toggle();
1026
1027 DrawTool(pTool);
1028 }
1029 } // end of wxToolBar::SpringUpButton
1030
1031 // ----------------------------------------------------------------------------
1032 // private helpers
1033 // ----------------------------------------------------------------------------
1034
1035 void wxToolBar::LowerTool ( wxToolBarToolBase* pToolBase,
1036 bool bLower )
1037 {
1038 wxToolBarTool* pTool = (wxToolBarTool*)pToolBase;
1039 wxCoord vX;
1040 wxCoord vY;
1041 wxCoord vWidth;
1042 wxCoord vHeight;
1043 wxColour gray85( 85,85,85 );
1044 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
1045 wxPen vClearPen( GetBackgroundColour(), 1, wxSOLID );
1046 wxClientDC vDC(this);
1047
1048 if (!pTool)
1049 return;
1050
1051 if (pTool->IsSeparator())
1052 return;
1053
1054 //
1055 // We only do this for flat toolbars
1056 //
1057 if (!HasFlag(wxTB_FLAT))
1058 return;
1059
1060 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty())
1061 {
1062 if (pTool->GetWidth() > m_vTextX)
1063 {
1064 vX = pTool->m_vX - 2;
1065 vWidth = pTool->GetWidth() + 4;
1066 }
1067 else
1068 {
1069 vX = pTool->m_vX - (wxCoord)(pTool->GetWidth()/2);
1070 vWidth = m_vTextX + 4;
1071 }
1072 vY = pTool->m_vY - 2;
1073 vHeight = pTool->GetHeight() + m_vTextY + 2;
1074 }
1075 else
1076 {
1077 vX = pTool->m_vX - 2;
1078 vY = pTool->m_vY - 2;
1079 vWidth = pTool->GetWidth() + 4;
1080 vHeight = pTool->GetHeight() + 4;
1081 }
1082 if (bLower)
1083 {
1084 vDC.SetPen(*wxWHITE_PEN);
1085 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1086 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1087 vDC.SetPen(vDarkGreyPen);
1088 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1089 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1090 }
1091 else
1092 {
1093 vDC.SetPen(vClearPen);
1094 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1095 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1096 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1097 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1098 }
1099 } // end of WinGuiBase_CToolBarTool::LowerTool
1100
1101 void wxToolBar::RaiseTool ( wxToolBarToolBase* pToolBase,
1102 bool bRaise )
1103 {
1104 wxToolBarTool* pTool = (wxToolBarTool*)pToolBase;
1105 wxCoord vX;
1106 wxCoord vY;
1107 wxCoord vWidth;
1108 wxCoord vHeight;
1109 wxColour gray85( 85,85,85 );
1110 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
1111 wxPen vClearPen( GetBackgroundColour(), 1, wxSOLID );
1112 wxClientDC vDC(this);
1113
1114 if (!pTool)
1115 return;
1116
1117 if (pTool->IsSeparator())
1118 return;
1119
1120 if (!pTool->IsEnabled())
1121 return;
1122
1123 //
1124 // We only do this for flat toolbars
1125 //
1126 if (!HasFlag(wxTB_FLAT))
1127 return;
1128
1129 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty())
1130 {
1131 if (pTool->GetWidth() > m_vTextX)
1132 {
1133 vX = pTool->m_vX - 2;
1134 vWidth = pTool->GetWidth() + 4;
1135 }
1136 else
1137 {
1138 vX = pTool->m_vX - (wxCoord)(pTool->GetWidth()/2);
1139 vWidth = m_vTextX + 4;
1140 }
1141 vY = pTool->m_vY - 2;
1142 vHeight = pTool->GetHeight() + m_vTextY + 2;
1143 }
1144 else
1145 {
1146 vX = pTool->m_vX - 2;
1147 vY = pTool->m_vY - 2;
1148 vWidth = pTool->GetWidth() + 4;
1149 vHeight = pTool->GetHeight() + 4;
1150 }
1151 if (bRaise)
1152 {
1153 vDC.SetPen(vDarkGreyPen);
1154 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1155 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1156 vDC.SetPen(*wxWHITE_PEN);
1157 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1158 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1159 }
1160 else
1161 {
1162 vDC.SetPen(vClearPen);
1163 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1164 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1165 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1166 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1167 }
1168 } // end of wxToolBar::RaiseTool
1169
1170 void wxToolBar::OnTimer ( wxTimerEvent& rEvent )
1171 {
1172 if (rEvent.GetId() == m_vToolTimer.GetId())
1173 {
1174 wxPoint vPos( m_vXMouse, m_vYMouse );
1175
1176 m_pToolTip->DisplayToolTipWindow(vPos);
1177 m_vToolTimer.Stop();
1178 m_vToolExpTimer.Start(4000L, TRUE);
1179 }
1180 else if (rEvent.GetId() == m_vToolExpTimer.GetId())
1181 {
1182 m_pToolTip->HideToolTipWindow();
1183 GetParent()->Refresh();
1184 m_vToolExpTimer.Stop();
1185 }
1186 } // end of wxToolBar::OnTimer
1187
1188 #endif // ndef for wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE