]> git.saurik.com Git - wxWidgets.git/blob - src/os2/toolbar.cpp
Don't crash when laying out wxGridBagSizer with only hidden elements.
[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 // Copyright: (c) David Webster
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
13
14 #if wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE
15
16 #include "wx/toolbar.h"
17
18 #ifndef WX_PRECOMP
19 #include "wx/settings.h"
20 #include "wx/window.h"
21 #include "wx/frame.h"
22 #include "wx/app.h"
23 #include "wx/dcclient.h"
24 #include "wx/dcmemory.h"
25 #endif
26
27 #include "wx/tooltip.h"
28 #include "wx/os2/dcclient.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 wxDELETE(m_pToolTip);
426 } // end of wxToolBar::~wxToolBar
427
428 bool wxToolBar::Realize()
429 {
430 int nMaxToolWidth = 0;
431 int nMaxToolHeight = 0;
432
433 m_nCurrentRowsOrColumns = 0;
434 m_vLastX = m_xMargin;
435 m_vLastY = m_yMargin;
436 m_vMaxWidth = 0;
437 m_vMaxHeight = 0;
438
439
440 //
441 // Find the maximum tool width and height
442 //
443 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
444
445 while (node )
446 {
447 wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
448
449 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty())
450 {
451 //
452 // Set the height according to the font and the border size
453 //
454 if (pTool->GetWidth() > m_vTextX)
455 nMaxToolWidth = pTool->GetWidth() + 4;
456 else
457 nMaxToolWidth = m_vTextX;
458 if (pTool->GetHeight() + m_vTextY > nMaxToolHeight)
459 nMaxToolHeight = pTool->GetHeight() + m_vTextY;
460 }
461 else
462 {
463 if (pTool->GetWidth() > nMaxToolWidth )
464 nMaxToolWidth = pTool->GetWidth() + 4;
465 if (pTool->GetHeight() > nMaxToolHeight)
466 nMaxToolHeight = pTool->GetHeight();
467 }
468 node = node->GetNext();
469 }
470
471 wxCoord vTbWidth = 0L;
472 wxCoord vTbHeight = 0L;
473
474 GetSize( &vTbWidth
475 ,&vTbHeight
476 );
477 if (vTbHeight < nMaxToolHeight)
478 {
479 SetSize( -1L
480 ,-1L
481 ,vTbWidth
482 ,nMaxToolHeight + 4
483 );
484 if (GetParent()->IsKindOf(CLASSINFO(wxFrame)))
485 {
486 wxFrame* pFrame = wxDynamicCast(GetParent(), wxFrame);
487
488 if (pFrame)
489 pFrame->PositionToolBar();
490 }
491 }
492
493 int nSeparatorSize = m_toolSeparation;
494
495 node = m_tools.GetFirst();
496 while (node)
497 {
498 wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
499
500 if (pTool->IsSeparator())
501 {
502 if (GetWindowStyleFlag() & (wxTB_TOP | wxTB_BOTTOM))
503 {
504 pTool->m_vX = m_vLastX + nSeparatorSize;
505 pTool->m_vHeight = m_defaultHeight + m_vTextY;
506 if (m_nCurrentRowsOrColumns >= m_maxCols)
507 m_vLastY += nSeparatorSize;
508 else
509 m_vLastX += nSeparatorSize * 4;
510 }
511 else
512 {
513 pTool->m_vY = m_vLastY + nSeparatorSize;
514 pTool->m_vHeight = m_defaultHeight + m_vTextY;
515 if (m_nCurrentRowsOrColumns >= m_maxRows)
516 m_vLastX += nSeparatorSize;
517 else
518 m_vLastY += nSeparatorSize * 4;
519 }
520 }
521 else if (pTool->IsButton())
522 {
523 if (GetWindowStyleFlag() & (wxTB_TOP | wxTB_BOTTOM))
524 {
525 if (m_nCurrentRowsOrColumns >= m_maxCols)
526 {
527 m_nCurrentRowsOrColumns = 0;
528 m_vLastX = m_xMargin;
529 m_vLastY += nMaxToolHeight + m_toolPacking;
530 }
531 pTool->m_vX = m_vLastX + (nMaxToolWidth - ((int)(nMaxToolWidth/2) + (int)(pTool->GetWidth()/2)));
532 if (HasFlag(wxTB_TEXT))
533 pTool->m_vY = m_vLastY + nSeparatorSize - 2; // just bit of adjustment
534 else
535 pTool->m_vY = m_vLastY + (nMaxToolHeight - (int)(pTool->GetHeight()/2));
536 m_vLastX += nMaxToolWidth + m_toolPacking + m_toolSeparation;
537 }
538 else
539 {
540 if (m_nCurrentRowsOrColumns >= m_maxRows)
541 {
542 m_nCurrentRowsOrColumns = 0;
543 m_vLastX += (nMaxToolWidth + m_toolPacking);
544 m_vLastY = m_yMargin;
545 }
546 pTool->m_vX = m_vLastX + pTool->GetWidth();
547 if ( HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty() )
548 pTool->m_vY = m_vLastY + (nMaxToolHeight - m_vTextY) + m_toolPacking;
549 else
550 pTool->m_vY = m_vLastY + (nMaxToolHeight - (int)(pTool->GetHeight()/2));
551 m_vLastY += nMaxToolHeight + m_toolPacking + m_toolSeparation;
552 }
553 m_nCurrentRowsOrColumns++;
554 }
555 else
556 {
557 // TODO: support the controls
558 }
559
560 if (m_vLastX > m_maxWidth)
561 m_maxWidth = m_vLastX;
562 if (m_vLastY > m_maxHeight)
563 m_maxHeight = m_vLastY;
564
565 node = node->GetNext();
566 }
567
568 if (GetWindowStyleFlag() & (wxTB_TOP | wxTB_BOTTOM))
569 m_maxWidth += nMaxToolWidth;
570 else
571 m_maxHeight += nMaxToolHeight;
572
573 m_maxWidth += m_xMargin;
574 m_maxHeight += m_yMargin;
575 m_bInitialized = true;
576 return true;
577 } // end of wxToolBar::Realize
578
579 // ----------------------------------------------------------------------------
580 // event handlers
581 // ----------------------------------------------------------------------------
582
583 void wxToolBar::OnPaint (
584 wxPaintEvent& WXUNUSED(rEvent)
585 )
586 {
587 wxPaintDC vDc(this);
588
589 PrepareDC(vDc);
590
591 static int nCount = 0;
592
593 //
594 // Prevent reentry of OnPaint which would cause wxMemoryDC errors.
595 //
596 if (nCount > 0)
597 return;
598 nCount++;
599
600 wxPMDCImpl *impl = (wxPMDCImpl*) vDc.GetImpl();
601 ::WinFillRect(impl->GetHPS(), &impl->m_vRclPaint, GetBackgroundColour().GetPixel());
602 for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
603 node;
604 node = node->GetNext() )
605 {
606 wxToolBarTool* pTool = (wxToolBarTool*)node->GetData();
607
608 if (pTool->IsButton() )
609 DrawTool(vDc, pTool);
610 if (pTool->IsSeparator())
611 {
612 wxColour gray85(85, 85, 85);
613 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
614 int nX;
615 int nY;
616 int nHeight = 0;
617 int nWidth = 0;
618
619 vDc.SetPen(vDarkGreyPen);
620 if (HasFlag(wxTB_TEXT))
621 {
622 if (HasFlag(wxTB_TOP) || HasFlag(wxTB_BOTTOM))
623 {
624 nX = pTool->m_vX;
625 nY = pTool->m_vY - (m_vTextY - 6);
626 nHeight = (m_vTextY - 2) + pTool->GetHeight();
627 }
628 else
629 {
630 nX = pTool->m_vX + m_xMargin + 10;
631 nY = pTool->m_vY + m_vTextY + m_toolSeparation;
632 nWidth = pTool->GetWidth() > m_vTextX ? pTool->GetWidth() : m_vTextX;
633 }
634 }
635 else
636 {
637 nX = pTool->m_vX;
638 nY = pTool->m_vY;
639 if (HasFlag(wxTB_TOP) || HasFlag(wxTB_BOTTOM))
640 nHeight = pTool->GetHeight() - 2;
641 else
642 {
643 nX += m_xMargin + 10;
644 nY += m_yMargin + m_toolSeparation;
645 nWidth = pTool->GetWidth();
646 }
647 }
648 vDc.DrawLine(nX, nY, nX + nWidth, nY + nHeight);
649 }
650 }
651 nCount--;
652 } // end of wxToolBar::OnPaint
653
654 void wxToolBar::OnSize (
655 wxSizeEvent& WXUNUSED(rEvent)
656 )
657 {
658 #if wxUSE_CONSTRAINTS
659 if (GetAutoLayout())
660 Layout();
661 #endif
662 } // end of wxToolBar::OnSize
663
664 void wxToolBar::OnKillFocus(
665 wxFocusEvent& WXUNUSED(rEvent)
666 )
667 {
668 OnMouseEnter(m_nPressedTool = m_nCurrentTool = -1);
669 } // end of wxToolBar::OnKillFocus
670
671 void wxToolBar::OnMouseEvent(
672 wxMouseEvent& rEvent
673 )
674 {
675 POINTL vPoint;
676 HWND hWnd;
677 wxCoord vX;
678 wxCoord vY;
679 HPOINTER hPtr = ::WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE);
680
681 ::WinSetPointer(HWND_DESKTOP, hPtr);
682 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
683 hWnd = ::WinWindowFromPoint(HWND_DESKTOP, &vPoint, TRUE);
684 if (hWnd != (HWND)GetHwnd())
685 {
686 m_vToolTimer.Stop();
687 return;
688 }
689
690 rEvent.GetPosition(&vX, &vY);
691
692 wxToolBarTool* pTool = (wxToolBarTool *)FindToolForPosition( vX
693 ,vY
694 );
695
696 if (rEvent.LeftDown())
697 {
698 CaptureMouse();
699 }
700 if (rEvent.LeftUp())
701 {
702 ReleaseMouse();
703 }
704
705 if (!pTool)
706 {
707 m_vToolTimer.Stop();
708 if (m_nCurrentTool > -1)
709 {
710 if (rEvent.LeftIsDown())
711 SpringUpButton(m_nCurrentTool);
712 pTool = (wxToolBarTool *)FindById(m_nCurrentTool);
713 if (pTool && !pTool->IsToggled())
714 {
715 RaiseTool( pTool, FALSE );
716 }
717 m_nCurrentTool = -1;
718 OnMouseEnter(-1);
719 }
720 return;
721 }
722 if (!rEvent.IsButton())
723 {
724 if (pTool->GetId() != m_nCurrentTool)
725 {
726 //
727 // If the left button is kept down and moved over buttons,
728 // press those buttons.
729 //
730 if (rEvent.LeftIsDown() && pTool->IsEnabled())
731 {
732 SpringUpButton(m_nCurrentTool);
733 if (pTool->CanBeToggled())
734 {
735 pTool->Toggle();
736 }
737 DrawTool(pTool);
738 }
739 wxToolBarTool* pOldTool = (wxToolBarTool*)FindById(m_nCurrentTool);
740
741 if (pOldTool && !pTool->IsToggled())
742 RaiseTool( pOldTool, FALSE );
743 m_nCurrentTool = pTool->GetId();
744 OnMouseEnter(m_nCurrentTool);
745 if (!pTool->GetShortHelp().empty())
746 {
747 if (m_pToolTip)
748 delete m_pToolTip;
749 m_pToolTip = new wxToolTip(pTool->GetShortHelp());
750 m_vXMouse = (wxCoord)vPoint.x;
751 m_vYMouse = (wxCoord)vPoint.y;
752 m_vToolTimer.Start(1000L, TRUE);
753 }
754 if (!pTool->IsToggled())
755 RaiseTool(pTool);
756 }
757 return;
758 }
759
760 // Left button pressed.
761 if (rEvent.LeftDown() && pTool->IsEnabled())
762 {
763 if (pTool->CanBeToggled())
764 {
765 pTool->Toggle();
766 }
767 DrawTool(pTool);
768 }
769 else if (rEvent.RightDown())
770 {
771 OnRightClick( pTool->GetId()
772 ,vX
773 ,vY
774 );
775 }
776
777 //
778 // Left Button Released. Only this action confirms selection.
779 // If the button is enabled and it is not a toggle tool and it is
780 // in the pressed state, then raise the button and call OnLeftClick.
781 //
782 if (rEvent.LeftUp() && pTool->IsEnabled() )
783 {
784 //
785 // Pass the OnLeftClick event to tool
786 //
787 if (!OnLeftClick( pTool->GetId()
788 ,pTool->IsToggled()) &&
789 pTool->CanBeToggled())
790 {
791 //
792 // If it was a toggle, and OnLeftClick says No Toggle allowed,
793 // then change it back
794 //
795 pTool->Toggle();
796 }
797 DrawTool(pTool);
798 }
799 } // end of wxToolBar::OnMouseEvent
800
801 // ----------------------------------------------------------------------------
802 // drawing
803 // ----------------------------------------------------------------------------
804
805 void wxToolBar::DrawTool( wxToolBarToolBase* pTool )
806 {
807 wxClientDC vDc(this);
808
809 DrawTool( vDc, pTool );
810 } // end of wxToolBar::DrawTool
811
812 void wxToolBar::DrawTool( wxDC& rDc, wxToolBarToolBase* pToolBase )
813 {
814 wxToolBarTool* pTool = (wxToolBarTool *)pToolBase;
815 wxColour gray85( 85,85,85 );
816 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
817 wxBitmap vBitmap = pTool->GetNormalBitmap();
818 bool bUseMask = false;
819 wxMask* pMask = NULL;
820
821 PrepareDC(rDc);
822
823 if (!vBitmap.IsOk())
824 return;
825 if ((pMask = vBitmap.GetMask()) != NULL)
826 if (pMask->GetMaskBitmap() != NULLHANDLE)
827 bUseMask = true;
828
829 if (!pTool->IsToggled())
830 {
831 LowerTool(pTool, FALSE);
832 if (!pTool->IsEnabled())
833 {
834 wxColour vColor(wxT("GREY"));
835
836 rDc.SetTextForeground(vColor);
837 if (!pTool->GetDisabledBitmap().IsOk())
838 pTool->SetDisabledBitmap(wxDisableBitmap( vBitmap
839 ,(long)GetBackgroundColour().GetPixel()
840 ));
841 rDc.DrawBitmap( pTool->GetDisabledBitmap()
842 ,pTool->m_vX
843 ,pTool->m_vY
844 ,bUseMask
845 );
846 }
847 else
848 {
849 rDc.SetTextForeground(*wxBLACK);
850 rDc.DrawBitmap( vBitmap
851 ,pTool->m_vX
852 ,pTool->m_vY
853 ,bUseMask
854 );
855 }
856 if (m_windowStyle & wxTB_3DBUTTONS)
857 {
858 RaiseTool(pTool);
859 }
860 if ( HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty() )
861 {
862 wxCoord vX;
863 wxCoord vY;
864 wxCoord vLeft = pTool->m_vX - (int)(pTool->GetWidth()/2);
865
866 rDc.SetFont(GetFont());
867 rDc.GetTextExtent( pTool->GetLabel()
868 ,&vX
869 ,&vY
870 );
871 if (pTool->GetWidth() > vX) // large tools
872 {
873 vLeft = pTool->m_vX + (pTool->GetWidth() - vX);
874 GetSize(&vX, &vY);
875 rDc.DrawText( pTool->GetLabel()
876 ,vLeft
877 ,vY - m_vTextY - 1
878 );
879 }
880 else // normal tools
881 {
882 vLeft += (wxCoord)((m_vTextX - vX)/2);
883 rDc.DrawText( pTool->GetLabel()
884 ,vLeft
885 ,pTool->m_vY + m_vTextY - 1 // a bit of margin
886 );
887 }
888 }
889 }
890 else
891 {
892 wxColour vColor(wxT("GREY"));
893
894 LowerTool(pTool);
895 rDc.SetTextForeground(vColor);
896 if (!pTool->GetDisabledBitmap().IsOk())
897 pTool->SetDisabledBitmap(wxDisableBitmap( vBitmap
898 ,(long)GetBackgroundColour().GetPixel()
899 ));
900 rDc.DrawBitmap( pTool->GetDisabledBitmap()
901 ,pTool->m_vX
902 ,pTool->m_vY
903 ,bUseMask
904 );
905 if ( HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty() )
906 {
907 wxCoord vX;
908 wxCoord vY;
909 wxCoord vLeft = pTool->m_vX - (int)(pTool->GetWidth()/2);
910
911 rDc.SetFont(GetFont());
912 rDc.GetTextExtent( pTool->GetLabel()
913 ,&vX
914 ,&vY
915 );
916 vLeft += (wxCoord)((m_vTextX - vX)/2);
917 rDc.DrawText( pTool->GetLabel()
918 ,vLeft
919 ,pTool->m_vY + m_vTextY - 1 // a bit of margin
920 );
921 }
922 }
923 } // end of wxToolBar::DrawTool
924
925 // ----------------------------------------------------------------------------
926 // toolbar geometry
927 // ----------------------------------------------------------------------------
928
929 void wxToolBar::SetRows(
930 int nRows
931 )
932 {
933 wxCHECK_RET( nRows != 0, wxT("max number of rows must be > 0") );
934
935 m_maxCols = (GetToolsCount() + nRows - 1) / nRows;
936 Refresh();
937 } // end of wxToolBar::SetRows
938
939 wxToolBarToolBase* wxToolBar::FindToolForPosition(
940 wxCoord vX
941 , wxCoord vY
942 ) const
943 {
944 wxCoord vTBarHeight = 0;
945
946 GetSize( NULL
947 ,&vTBarHeight
948 );
949 vY = vTBarHeight - vY;
950 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
951 while (node)
952 {
953 wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
954
955 if ( HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty() )
956 {
957 if ((vX >= (pTool->m_vX - ((wxCoord)(pTool->GetWidth()/2) - 2))) &&
958 (vY >= (pTool->m_vY - 2)) &&
959 (vX <= (pTool->m_vX + pTool->GetWidth())) &&
960 (vY <= (pTool->m_vY + pTool->GetHeight() + m_vTextY + 2)))
961 {
962 return pTool;
963 }
964 }
965 else
966 {
967 if ((vX >= pTool->m_vX) &&
968 (vY >= pTool->m_vY) &&
969 (vX <= (pTool->m_vX + pTool->GetWidth())) &&
970 (vY <= (pTool->m_vY + pTool->GetHeight())))
971 {
972 return pTool;
973 }
974 }
975 node = node->GetNext();
976 }
977 return NULL;
978 } // end of wxToolBar::FindToolForPosition
979
980 // ----------------------------------------------------------------------------
981 // tool state change handlers
982 // ----------------------------------------------------------------------------
983
984 void wxToolBar::DoEnableTool(
985 wxToolBarToolBase* pTool
986 , bool WXUNUSED(bEnable)
987 )
988 {
989 DrawTool(pTool);
990 } // end of wxToolBar::DoEnableTool
991
992 void wxToolBar::DoToggleTool(
993 wxToolBarToolBase* pTool
994 , bool WXUNUSED(bToggle)
995 )
996 {
997 DrawTool(pTool);
998 } // end of wxToolBar::DoToggleTool
999
1000 void wxToolBar::DoSetToggle(
1001 wxToolBarToolBase* WXUNUSED(pTool)
1002 , bool WXUNUSED(bToggle)
1003 )
1004 {
1005 // nothing to do
1006 } // end of wxToolBar::DoSetToggle
1007
1008 //
1009 // Okay, so we've left the tool we're in ... we must check if the tool we're
1010 // leaving was a 'sprung push button' and if so, spring it back to the up
1011 // state.
1012 //
1013 void wxToolBar::SpringUpButton(
1014 int vId
1015 )
1016 {
1017 wxToolBarToolBase* pTool = FindById(vId);
1018
1019 if (pTool && pTool->CanBeToggled())
1020 {
1021 if (pTool->IsToggled())
1022 pTool->Toggle();
1023
1024 DrawTool(pTool);
1025 }
1026 } // end of wxToolBar::SpringUpButton
1027
1028 // ----------------------------------------------------------------------------
1029 // private helpers
1030 // ----------------------------------------------------------------------------
1031
1032 void wxToolBar::LowerTool ( wxToolBarToolBase* pToolBase,
1033 bool bLower )
1034 {
1035 wxToolBarTool* pTool = (wxToolBarTool*)pToolBase;
1036 wxCoord vX;
1037 wxCoord vY;
1038 wxCoord vWidth;
1039 wxCoord vHeight;
1040 wxColour gray85( 85,85,85 );
1041 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
1042 wxPen vClearPen( GetBackgroundColour(), 1, wxSOLID );
1043 wxClientDC vDC(this);
1044
1045 if (!pTool)
1046 return;
1047
1048 if (pTool->IsSeparator())
1049 return;
1050
1051 //
1052 // We only do this for flat toolbars
1053 //
1054 if (!HasFlag(wxTB_FLAT))
1055 return;
1056
1057 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty())
1058 {
1059 if (pTool->GetWidth() > m_vTextX)
1060 {
1061 vX = pTool->m_vX - 2;
1062 vWidth = pTool->GetWidth() + 4;
1063 }
1064 else
1065 {
1066 vX = pTool->m_vX - (wxCoord)(pTool->GetWidth()/2);
1067 vWidth = m_vTextX + 4;
1068 }
1069 vY = pTool->m_vY - 2;
1070 vHeight = pTool->GetHeight() + m_vTextY + 2;
1071 }
1072 else
1073 {
1074 vX = pTool->m_vX - 2;
1075 vY = pTool->m_vY - 2;
1076 vWidth = pTool->GetWidth() + 4;
1077 vHeight = pTool->GetHeight() + 4;
1078 }
1079 if (bLower)
1080 {
1081 vDC.SetPen(*wxWHITE_PEN);
1082 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1083 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1084 vDC.SetPen(vDarkGreyPen);
1085 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1086 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1087 }
1088 else
1089 {
1090 vDC.SetPen(vClearPen);
1091 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1092 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1093 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1094 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1095 }
1096 } // end of WinGuiBase_CToolBarTool::LowerTool
1097
1098 void wxToolBar::RaiseTool ( wxToolBarToolBase* pToolBase,
1099 bool bRaise )
1100 {
1101 wxToolBarTool* pTool = (wxToolBarTool*)pToolBase;
1102 wxCoord vX;
1103 wxCoord vY;
1104 wxCoord vWidth;
1105 wxCoord vHeight;
1106 wxColour gray85( 85,85,85 );
1107 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
1108 wxPen vClearPen( GetBackgroundColour(), 1, wxSOLID );
1109 wxClientDC vDC(this);
1110
1111 if (!pTool)
1112 return;
1113
1114 if (pTool->IsSeparator())
1115 return;
1116
1117 if (!pTool->IsEnabled())
1118 return;
1119
1120 //
1121 // We only do this for flat toolbars
1122 //
1123 if (!HasFlag(wxTB_FLAT))
1124 return;
1125
1126 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty())
1127 {
1128 if (pTool->GetWidth() > m_vTextX)
1129 {
1130 vX = pTool->m_vX - 2;
1131 vWidth = pTool->GetWidth() + 4;
1132 }
1133 else
1134 {
1135 vX = pTool->m_vX - (wxCoord)(pTool->GetWidth()/2);
1136 vWidth = m_vTextX + 4;
1137 }
1138 vY = pTool->m_vY - 2;
1139 vHeight = pTool->GetHeight() + m_vTextY + 2;
1140 }
1141 else
1142 {
1143 vX = pTool->m_vX - 2;
1144 vY = pTool->m_vY - 2;
1145 vWidth = pTool->GetWidth() + 4;
1146 vHeight = pTool->GetHeight() + 4;
1147 }
1148 if (bRaise)
1149 {
1150 vDC.SetPen(vDarkGreyPen);
1151 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1152 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1153 vDC.SetPen(*wxWHITE_PEN);
1154 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1155 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1156 }
1157 else
1158 {
1159 vDC.SetPen(vClearPen);
1160 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1161 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1162 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1163 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1164 }
1165 } // end of wxToolBar::RaiseTool
1166
1167 void wxToolBar::OnTimer ( wxTimerEvent& rEvent )
1168 {
1169 if (rEvent.GetId() == m_vToolTimer.GetId())
1170 {
1171 wxPoint vPos( m_vXMouse, m_vYMouse );
1172
1173 m_pToolTip->DisplayToolTipWindow(vPos);
1174 m_vToolTimer.Stop();
1175 m_vToolExpTimer.Start(4000L, TRUE);
1176 }
1177 else if (rEvent.GetId() == m_vToolExpTimer.GetId())
1178 {
1179 m_pToolTip->HideToolTipWindow();
1180 GetParent()->Refresh();
1181 m_vToolExpTimer.Stop();
1182 }
1183 } // end of wxToolBar::OnTimer
1184
1185 #endif // ndef for wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE