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