wxOS2 with Open Watcom: correct PCH usage, missing headers, warning fixes, source...
[wxWidgets.git] / src / os2 / toolbar.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: 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 #ifndef WX_PRECOMP
18 #include "wx/settings.h"
19 #include "wx/window.h"
20 #include "wx/frame.h"
21 #include "wx/app.h"
22 #include "wx/dcclient.h"
23 #include "wx/dcmemory.h"
24 #endif
25
26 #include "wx/tooltip.h"
27 #include "wx/toolbar.h"
28
29 bool wxToolBar::m_bInitialized = FALSE;
30
31 // ----------------------------------------------------------------------------
32 // private classes
33 // ----------------------------------------------------------------------------
34
35 class wxToolBarTool : public wxToolBarToolBase
36 {
37 public:
38 inline wxToolBarTool( wxToolBar* pTbar
39 ,int vId
40 ,const wxString& rsLabel
41 ,const wxBitmap& rBitmap1
42 ,const wxBitmap& rBitmap2
43 ,wxItemKind vKind
44 ,wxObject* pClientData
45 ,const wxString& rsShortHelpString
46 ,const wxString& rsLongHelpString
47 ) : wxToolBarToolBase( pTbar
48 ,vId
49 ,rsLabel
50 ,rBitmap1
51 ,rBitmap2
52 ,vKind
53 ,pClientData
54 ,rsShortHelpString
55 ,rsLongHelpString
56 )
57 {
58 }
59
60 inline wxToolBarTool( wxToolBar* pTbar
61 ,wxControl* pControl
62 ) : wxToolBarToolBase( pTbar
63 ,pControl
64 )
65 {
66 }
67
68 void SetSize(const wxSize& rSize)
69 {
70 m_vWidth = rSize.x;
71 m_vHeight = rSize.y;
72 }
73
74 wxCoord GetWidth(void) const { return m_vWidth; }
75 wxCoord GetHeight(void) const { return m_vHeight; }
76
77 wxCoord m_vX;
78 wxCoord m_vY;
79 wxCoord m_vWidth;
80 wxCoord m_vHeight;
81 }; // end of CLASS wxToolBarTool
82
83 // ----------------------------------------------------------------------------
84 // wxWin macros
85 // ----------------------------------------------------------------------------
86
87 IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl)
88
89 BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
90 EVT_SIZE(wxToolBar::OnSize)
91 EVT_PAINT(wxToolBar::OnPaint)
92 EVT_KILL_FOCUS(wxToolBar::OnKillFocus)
93 EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent)
94 EVT_TIMER(-1, wxToolBar::OnTimer)
95 END_EVENT_TABLE()
96
97 // ============================================================================
98 // implementation
99 // ============================================================================
100
101 // ----------------------------------------------------------------------------
102 // tool bar tools creation
103 // ----------------------------------------------------------------------------
104
105 wxToolBarToolBase* wxToolBar::CreateTool(
106 int nId
107 , const wxString& rsLabel
108 , const wxBitmap& rBmpNormal
109 , const wxBitmap& rBmpDisabled
110 , wxItemKind eKind
111 , wxObject* pClientData
112 , const wxString& rsShortHelp
113 , const wxString& rsLongHelp
114 )
115 {
116 return new wxToolBarTool( this
117 ,nId
118 ,rsLabel
119 ,rBmpNormal
120 ,rBmpDisabled
121 ,eKind
122 ,pClientData
123 ,rsShortHelp
124 ,rsLongHelp
125 );
126 } // end of wxToolBarSimple::CreateTool
127
128 wxToolBarToolBase *wxToolBar::CreateTool(
129 wxControl* pControl
130 )
131 {
132 return new wxToolBarTool( this
133 ,pControl
134 );
135 } // end of wxToolBarSimple::CreateTool
136
137 // ----------------------------------------------------------------------------
138 // wxToolBarSimple creation
139 // ----------------------------------------------------------------------------
140
141 void wxToolBar::Init()
142 {
143 m_nCurrentRowsOrColumns = 0;
144
145 m_vLastX = m_vLastY = 0;
146 m_vMaxWidth = m_vMaxHeight = 0;
147 m_nPressedTool = m_nCurrentTool = -1;
148 m_vXPos = m_vYPos = -1;
149 m_vTextX = m_vTextY = 0;
150
151 m_toolPacking = 1;
152 m_toolSeparation = 5;
153
154 m_defaultWidth = 16;
155 m_defaultHeight = 15;
156
157 m_pToolTip = NULL;
158 } // end of wxToolBar::Init
159
160 wxToolBarToolBase* wxToolBar::DoAddTool(
161 int vId
162 , const wxString& rsLabel
163 , const wxBitmap& rBitmap
164 , const wxBitmap& rBmpDisabled
165 , wxItemKind eKind
166 , const wxString& rsShortHelp
167 , const wxString& rsLongHelp
168 , wxObject* pClientData
169 , wxCoord vXPos
170 , wxCoord vYPos
171 )
172 {
173 //
174 // Rememeber the position for DoInsertTool()
175 //
176 m_vXPos = vXPos;
177 m_vYPos = vYPos;
178
179 return wxToolBarBase::DoAddTool( vId
180 ,rsLabel
181 ,rBitmap
182 ,rBmpDisabled
183 ,eKind
184 ,rsShortHelp
185 ,rsLongHelp
186 ,pClientData
187 ,vXPos
188 ,vYPos
189 );
190 } // end of wxToolBar::DoAddTool
191
192 bool wxToolBar::DeleteTool(
193 int nId
194 )
195 {
196 bool bOk = wxToolBarBase::DeleteTool(nId);
197
198 if (bOk)
199 {
200 Realize();
201 }
202 return bOk;
203 } // end of wxToolBar::DeleteTool
204
205 bool wxToolBar::DeleteToolByPos(
206 size_t nPos
207 )
208 {
209 bool bOk = wxToolBarBase::DeleteToolByPos(nPos);
210
211 if (bOk)
212 {
213 Realize();
214 }
215 return bOk;
216 } // end of wxToolBar::DeleteTool
217
218 wxToolBarToolBase* wxToolBar::InsertControl(
219 size_t nPos
220 , wxControl* pControl
221 )
222 {
223 wxToolBarToolBase* pTool = wxToolBarBase::InsertControl( nPos
224 ,pControl
225 );
226 if (m_bInitialized)
227 {
228 Realize();
229 Refresh();
230 }
231 return pTool;
232 } // end of wxToolBar::InsertControl
233
234 wxToolBarToolBase* wxToolBar::InsertSeparator(
235 size_t nPos
236 )
237 {
238 wxToolBarToolBase* pTool = wxToolBarBase::InsertSeparator(nPos);
239
240 if (m_bInitialized)
241 {
242 Realize();
243 Refresh();
244 }
245 return pTool;
246 } // end of wxToolBar::InsertSeparator
247
248 wxToolBarToolBase* wxToolBar::InsertTool(
249 size_t nPos
250 , int nId
251 , const wxString& rsLabel
252 , const wxBitmap& rBitmap
253 , const wxBitmap& rBmpDisabled
254 , wxItemKind eKind
255 , const wxString& rsShortHelp
256 , const wxString& rsLongHelp
257 , wxObject* pClientData
258 )
259 {
260 wxToolBarToolBase* pTool = wxToolBarBase::InsertTool( nPos
261 ,nId
262 ,rsLabel
263 ,rBitmap
264 ,rBmpDisabled
265 ,eKind
266 ,rsShortHelp
267 ,rsLongHelp
268 ,pClientData
269 );
270 if (m_bInitialized)
271 {
272 Realize();
273 Refresh();
274 }
275 return pTool;
276 } // end of wxToolBar::InsertTool
277
278 bool wxToolBar::DoInsertTool(
279 size_t WXUNUSED(nPos)
280 , wxToolBarToolBase* pToolBase
281 )
282 {
283 wxToolBarTool* pTool = (wxToolBarTool *)pToolBase;
284
285 pTool->m_vX = m_vXPos;
286 if (pTool->m_vX == -1)
287 pTool->m_vX = m_xMargin;
288
289 pTool->m_vY = m_vYPos;
290 if (pTool->m_vY == -1)
291 pTool->m_vX = m_yMargin;
292
293 pTool->SetSize(GetToolSize());
294
295 if (pTool->IsButton())
296 {
297 //
298 // Calculate reasonable max size in case Layout() not called
299 //
300 if ((pTool->m_vX + pTool->GetNormalBitmap().GetWidth() + m_xMargin) > m_vMaxWidth)
301 m_vMaxWidth = (wxCoord)((pTool->m_vX + pTool->GetWidth() + m_xMargin));
302
303 if ((pTool->m_vY + pTool->GetNormalBitmap().GetHeight() + m_yMargin) > m_vMaxHeight)
304 m_vMaxHeight = (wxCoord)((pTool->m_vY + pTool->GetHeight() + m_yMargin));
305 }
306 return TRUE;
307 } // end of wxToolBar::DoInsertTool
308
309 bool wxToolBar::DoDeleteTool(
310 size_t WXUNUSED(nPos)
311 , wxToolBarToolBase* pTool
312 )
313 {
314 pTool->Detach();
315 Refresh();
316 return TRUE;
317 } // end of wxToolBar::DoDeleteTool
318
319 bool wxToolBar::Create(
320 wxWindow* pParent
321 , wxWindowID vId
322 , const wxPoint& rPos
323 , const wxSize& rSize
324 , long lStyle
325 , const wxString& rsName
326 )
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_VERTICAL)
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_HORIZONTAL)
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_HORIZONTAL)
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_HORIZONTAL)
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_HORIZONTAL )
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 ::WinFillRect(vDc.GetHPS(), &vDc.m_vRclPaint, GetBackgroundColour().GetPixel());
606 for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
607 node;
608 node = node->GetNext() )
609 {
610 wxToolBarTool* pTool = (wxToolBarTool*)node->GetData();
611
612 if (pTool->IsButton() )
613 DrawTool(vDc, pTool);
614 if (pTool->IsSeparator())
615 {
616 wxColour gray85(85, 85, 85);
617 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
618 int nX;
619 int nY;
620 int nHeight = 0;
621 int nWidth = 0;
622
623 vDc.SetPen(vDarkGreyPen);
624 if (HasFlag(wxTB_TEXT))
625 {
626 if (HasFlag(wxTB_HORIZONTAL))
627 {
628 nX = pTool->m_vX;
629 nY = pTool->m_vY - (m_vTextY - 6);
630 nHeight = (m_vTextY - 2) + pTool->GetHeight();
631 }
632 else
633 {
634 nX = pTool->m_vX + m_xMargin + 10;
635 nY = pTool->m_vY + m_vTextY + m_toolSeparation;
636 nWidth = pTool->GetWidth() > m_vTextX ? pTool->GetWidth() : m_vTextX;
637 }
638 }
639 else
640 {
641 nX = pTool->m_vX;
642 nY = pTool->m_vY;
643 if (HasFlag(wxTB_HORIZONTAL))
644 nHeight = pTool->GetHeight() - 2;
645 else
646 {
647 nX += m_xMargin + 10;
648 nY += m_yMargin + m_toolSeparation;
649 nWidth = pTool->GetWidth();
650 }
651 }
652 vDc.DrawLine(nX, nY, nX + nWidth, nY + nHeight);
653 }
654 }
655 nCount--;
656 } // end of wxToolBar::OnPaint
657
658 void wxToolBar::OnSize (
659 wxSizeEvent& WXUNUSED(rEvent)
660 )
661 {
662 #if wxUSE_CONSTRAINTS
663 if (GetAutoLayout())
664 Layout();
665 #endif
666 } // end of wxToolBar::OnSize
667
668 void wxToolBar::OnKillFocus(
669 wxFocusEvent& WXUNUSED(rEvent)
670 )
671 {
672 OnMouseEnter(m_nPressedTool = m_nCurrentTool = -1);
673 } // end of wxToolBar::OnKillFocus
674
675 void wxToolBar::OnMouseEvent(
676 wxMouseEvent& rEvent
677 )
678 {
679 POINTL vPoint;
680 HWND hWnd;
681 wxCoord vX;
682 wxCoord vY;
683 HPOINTER hPtr = ::WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE);
684
685 ::WinSetPointer(HWND_DESKTOP, hPtr);
686 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
687 hWnd = ::WinWindowFromPoint(HWND_DESKTOP, &vPoint, TRUE);
688 if (hWnd != (HWND)GetHwnd())
689 {
690 m_vToolTimer.Stop();
691 return;
692 }
693
694 rEvent.GetPosition(&vX, &vY);
695
696 wxToolBarTool* pTool = (wxToolBarTool *)FindToolForPosition( vX
697 ,vY
698 );
699
700 if (rEvent.LeftDown())
701 {
702 CaptureMouse();
703 }
704 if (rEvent.LeftUp())
705 {
706 ReleaseMouse();
707 }
708
709 if (!pTool)
710 {
711 m_vToolTimer.Stop();
712 if (m_nCurrentTool > -1)
713 {
714 if (rEvent.LeftIsDown())
715 SpringUpButton(m_nCurrentTool);
716 pTool = (wxToolBarTool *)FindById(m_nCurrentTool);
717 if (pTool && !pTool->IsToggled())
718 {
719 RaiseTool( pTool
720 ,FALSE
721 );
722 }
723 m_nCurrentTool = -1;
724 OnMouseEnter(-1);
725 }
726 return;
727 }
728 if (!rEvent.IsButton())
729 {
730 if (pTool->GetId() != m_nCurrentTool)
731 {
732 //
733 // If the left button is kept down and moved over buttons,
734 // press those buttons.
735 //
736 if (rEvent.LeftIsDown() && pTool->IsEnabled())
737 {
738 SpringUpButton(m_nCurrentTool);
739 if (pTool->CanBeToggled())
740 {
741 pTool->Toggle();
742 }
743 DrawTool(pTool);
744 }
745 wxToolBarTool* pOldTool = (wxToolBarTool*)FindById(m_nCurrentTool);
746
747 if (pOldTool && !pTool->IsToggled())
748 RaiseTool( pOldTool
749 ,FALSE
750 );
751 m_nCurrentTool = pTool->GetId();
752 OnMouseEnter(m_nCurrentTool);
753 if (!pTool->GetShortHelp().empty())
754 {
755 if (m_pToolTip)
756 delete m_pToolTip;
757 m_pToolTip = new wxToolTip(pTool->GetShortHelp());
758 m_vXMouse = (wxCoord)vPoint.x;
759 m_vYMouse = (wxCoord)vPoint.y;
760 m_vToolTimer.Start(1000L, TRUE);
761 }
762 if (!pTool->IsToggled())
763 RaiseTool(pTool);
764 }
765 return;
766 }
767
768 // Left button pressed.
769 if (rEvent.LeftDown() && pTool->IsEnabled())
770 {
771 if (pTool->CanBeToggled())
772 {
773 pTool->Toggle();
774 }
775 DrawTool(pTool);
776 }
777 else if (rEvent.RightDown())
778 {
779 OnRightClick( pTool->GetId()
780 ,vX
781 ,vY
782 );
783 }
784
785 //
786 // Left Button Released. Only this action confirms selection.
787 // If the button is enabled and it is not a toggle tool and it is
788 // in the pressed state, then raise the button and call OnLeftClick.
789 //
790 if (rEvent.LeftUp() && pTool->IsEnabled() )
791 {
792 //
793 // Pass the OnLeftClick event to tool
794 //
795 if (!OnLeftClick( pTool->GetId()
796 ,pTool->IsToggled()) &&
797 pTool->CanBeToggled())
798 {
799 //
800 // If it was a toggle, and OnLeftClick says No Toggle allowed,
801 // then change it back
802 //
803 pTool->Toggle();
804 }
805 DrawTool(pTool);
806 }
807 } // end of wxToolBar::OnMouseEvent
808
809 // ----------------------------------------------------------------------------
810 // drawing
811 // ----------------------------------------------------------------------------
812
813 void wxToolBar::DrawTool(
814 wxToolBarToolBase* pTool
815 )
816 {
817 wxClientDC vDc(this);
818
819 DrawTool( vDc
820 ,pTool
821 );
822 } // end of wxToolBar::DrawTool
823
824 void wxToolBar::DrawTool(
825 wxDC& rDc
826 , wxToolBarToolBase* pToolBase
827 )
828 {
829 wxToolBarTool* pTool = (wxToolBarTool *)pToolBase;
830 wxColour gray85( 85,85,85 );
831 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
832 wxBitmap vBitmap = pTool->GetNormalBitmap();
833 bool bUseMask = FALSE;
834 wxMask* pMask = NULL;
835
836 PrepareDC(rDc);
837
838 if (!vBitmap.Ok())
839 return;
840 if ((pMask = vBitmap.GetMask()) != NULL)
841 if (pMask->GetMaskBitmap() != NULLHANDLE)
842 bUseMask = TRUE;
843
844 if (!pTool->IsToggled())
845 {
846 LowerTool(pTool, FALSE);
847 if (!pTool->IsEnabled())
848 {
849 wxColour vColor(wxT("GREY"));
850
851 rDc.SetTextForeground(vColor);
852 if (!pTool->GetDisabledBitmap().Ok())
853 pTool->SetDisabledBitmap(wxDisableBitmap( vBitmap
854 ,(long)GetBackgroundColour().GetPixel()
855 ));
856 rDc.DrawBitmap( pTool->GetDisabledBitmap()
857 ,pTool->m_vX
858 ,pTool->m_vY
859 ,bUseMask
860 );
861 }
862 else
863 {
864 rDc.SetTextForeground(*wxBLACK);
865 rDc.DrawBitmap( vBitmap
866 ,pTool->m_vX
867 ,pTool->m_vY
868 ,bUseMask
869 );
870 }
871 if (m_windowStyle & wxTB_3DBUTTONS)
872 {
873 RaiseTool(pTool);
874 }
875 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
876 {
877 wxCoord vX;
878 wxCoord vY;
879 wxCoord vLeft = pTool->m_vX - (int)(pTool->GetWidth()/2);
880
881 rDc.SetFont(GetFont());
882 rDc.GetTextExtent( pTool->GetLabel()
883 ,&vX
884 ,&vY
885 );
886 if (pTool->GetWidth() > vX) // large tools
887 {
888 vLeft = pTool->m_vX + (pTool->GetWidth() - vX);
889 GetSize(&vX, &vY);
890 rDc.DrawText( pTool->GetLabel()
891 ,vLeft
892 ,vY - (m_vTextY - 2)
893 );
894 }
895 else // normal tools
896 {
897 vLeft += (wxCoord)((m_vTextX - vX)/2);
898 rDc.DrawText( pTool->GetLabel()
899 ,vLeft
900 ,pTool->m_vY + m_vTextY + 4 // a bit of margin
901 );
902 }
903 }
904 }
905 else
906 {
907 wxColour vColor(wxT("GREY"));
908
909 LowerTool(pTool);
910 rDc.SetTextForeground(vColor);
911 if (!pTool->GetDisabledBitmap().Ok())
912 pTool->SetDisabledBitmap(wxDisableBitmap( vBitmap
913 ,(long)GetBackgroundColour().GetPixel()
914 ));
915 rDc.DrawBitmap( pTool->GetDisabledBitmap()
916 ,pTool->m_vX
917 ,pTool->m_vY
918 ,bUseMask
919 );
920 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
921 {
922 wxCoord vX;
923 wxCoord vY;
924 wxCoord vLeft = pTool->m_vX - (int)(pTool->GetWidth()/2);
925
926 rDc.SetFont(GetFont());
927 rDc.GetTextExtent( pTool->GetLabel()
928 ,&vX
929 ,&vY
930 );
931 vLeft += (wxCoord)((m_vTextX - vX)/2);
932 rDc.DrawText( pTool->GetLabel()
933 ,vLeft
934 ,pTool->m_vY + m_vTextY + 4 // a bit of margin
935 );
936 }
937 }
938 } // end of wxToolBar::DrawTool
939
940 // ----------------------------------------------------------------------------
941 // toolbar geometry
942 // ----------------------------------------------------------------------------
943
944 void wxToolBar::SetRows(
945 int nRows
946 )
947 {
948 wxCHECK_RET( nRows != 0, _T("max number of rows must be > 0") );
949
950 m_maxCols = (GetToolsCount() + nRows - 1) / nRows;
951 Refresh();
952 } // end of wxToolBar::SetRows
953
954 wxToolBarToolBase* wxToolBar::FindToolForPosition(
955 wxCoord vX
956 , wxCoord vY
957 ) const
958 {
959 wxCoord vTBarHeight = 0;
960
961 GetSize( NULL
962 ,&vTBarHeight
963 );
964 vY = vTBarHeight - vY;
965 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
966 while (node)
967 {
968 wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
969
970 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
971 {
972 if ((vX >= (pTool->m_vX - ((wxCoord)(pTool->GetWidth()/2) - 2))) &&
973 (vY >= (pTool->m_vY - 2)) &&
974 (vX <= (pTool->m_vX + pTool->GetWidth())) &&
975 (vY <= (pTool->m_vY + pTool->GetHeight() + m_vTextY + 2)))
976 {
977 return pTool;
978 }
979 }
980 else
981 {
982 if ((vX >= pTool->m_vX) &&
983 (vY >= pTool->m_vY) &&
984 (vX <= (pTool->m_vX + pTool->GetWidth())) &&
985 (vY <= (pTool->m_vY + pTool->GetHeight())))
986 {
987 return pTool;
988 }
989 }
990 node = node->GetNext();
991 }
992 return (wxToolBarToolBase *)NULL;
993 } // end of wxToolBar::FindToolForPosition
994
995 // ----------------------------------------------------------------------------
996 // tool state change handlers
997 // ----------------------------------------------------------------------------
998
999 void wxToolBar::DoEnableTool(
1000 wxToolBarToolBase* pTool
1001 , bool WXUNUSED(bEnable)
1002 )
1003 {
1004 DrawTool(pTool);
1005 } // end of wxToolBar::DoEnableTool
1006
1007 void wxToolBar::DoToggleTool(
1008 wxToolBarToolBase* pTool
1009 , bool WXUNUSED(bToggle)
1010 )
1011 {
1012 DrawTool(pTool);
1013 } // end of wxToolBar::DoToggleTool
1014
1015 void wxToolBar::DoSetToggle(
1016 wxToolBarToolBase* WXUNUSED(pTool)
1017 , bool WXUNUSED(bToggle)
1018 )
1019 {
1020 // nothing to do
1021 } // end of wxToolBar::DoSetToggle
1022
1023 //
1024 // Okay, so we've left the tool we're in ... we must check if the tool we're
1025 // leaving was a 'sprung push button' and if so, spring it back to the up
1026 // state.
1027 //
1028 void wxToolBar::SpringUpButton(
1029 int vId
1030 )
1031 {
1032 wxToolBarToolBase* pTool = FindById(vId);
1033
1034 if (pTool && pTool->CanBeToggled())
1035 {
1036 if (pTool->IsToggled())
1037 pTool->Toggle();
1038
1039 DrawTool(pTool);
1040 }
1041 } // end of wxToolBar::SpringUpButton
1042
1043 // ----------------------------------------------------------------------------
1044 // private helpers
1045 // ----------------------------------------------------------------------------
1046
1047 void wxToolBar::LowerTool ( wxToolBarToolBase* pToolBase,
1048 bool bLower )
1049 {
1050 wxToolBarTool* pTool = (wxToolBarTool*)pToolBase;
1051 wxCoord vX;
1052 wxCoord vY;
1053 wxCoord vWidth;
1054 wxCoord vHeight;
1055 wxColour gray85( 85,85,85 );
1056 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
1057 wxPen vClearPen( GetBackgroundColour(), 1, wxSOLID );
1058 wxClientDC vDC(this);
1059
1060 if (!pTool)
1061 return;
1062
1063 if (pTool->IsSeparator())
1064 return;
1065
1066 //
1067 // We only do this for flat toolbars
1068 //
1069 if (!HasFlag(wxTB_FLAT))
1070 return;
1071
1072 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty())
1073 {
1074 if (pTool->GetWidth() > m_vTextX)
1075 {
1076 vX = pTool->m_vX - 2;
1077 vWidth = pTool->GetWidth() + 4;
1078 }
1079 else
1080 {
1081 vX = pTool->m_vX - (wxCoord)(pTool->GetWidth()/2);
1082 vWidth = m_vTextX + 4;
1083 }
1084 vY = pTool->m_vY - 2;
1085 vHeight = pTool->GetHeight() + m_vTextY + 2;
1086 }
1087 else
1088 {
1089 vX = pTool->m_vX - 2;
1090 vY = pTool->m_vY - 2;
1091 vWidth = pTool->GetWidth() + 4;
1092 vHeight = pTool->GetHeight() + 4;
1093 }
1094 if (bLower)
1095 {
1096 vDC.SetPen(*wxWHITE_PEN);
1097 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1098 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1099 vDC.SetPen(vDarkGreyPen);
1100 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1101 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1102 }
1103 else
1104 {
1105 vDC.SetPen(vClearPen);
1106 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1107 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1108 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1109 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1110 }
1111 } // end of WinGuiBase_CToolBarTool::LowerTool
1112
1113 void wxToolBar::RaiseTool ( wxToolBarToolBase* pToolBase,
1114 bool bRaise )
1115 {
1116 wxToolBarTool* pTool = (wxToolBarTool*)pToolBase;
1117 wxCoord vX;
1118 wxCoord vY;
1119 wxCoord vWidth;
1120 wxCoord vHeight;
1121 wxColour gray85( 85,85,85 );
1122 wxPen vDarkGreyPen( gray85, 1, wxSOLID );
1123 wxPen vClearPen( GetBackgroundColour(), 1, wxSOLID );
1124 wxClientDC vDC(this);
1125
1126 if (!pTool)
1127 return;
1128
1129 if (pTool->IsSeparator())
1130 return;
1131
1132 if (!pTool->IsEnabled())
1133 return;
1134
1135 //
1136 // We only do this for flat toolbars
1137 //
1138 if (!HasFlag(wxTB_FLAT))
1139 return;
1140
1141 if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty())
1142 {
1143 if (pTool->GetWidth() > m_vTextX)
1144 {
1145 vX = pTool->m_vX - 2;
1146 vWidth = pTool->GetWidth() + 4;
1147 }
1148 else
1149 {
1150 vX = pTool->m_vX - (wxCoord)(pTool->GetWidth()/2);
1151 vWidth = m_vTextX + 4;
1152 }
1153 vY = pTool->m_vY - 2;
1154 vHeight = pTool->GetHeight() + m_vTextY + 2;
1155 }
1156 else
1157 {
1158 vX = pTool->m_vX - 2;
1159 vY = pTool->m_vY - 2;
1160 vWidth = pTool->GetWidth() + 4;
1161 vHeight = pTool->GetHeight() + 4;
1162 }
1163 if (bRaise)
1164 {
1165 vDC.SetPen(vDarkGreyPen);
1166 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1167 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1168 vDC.SetPen(*wxWHITE_PEN);
1169 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1170 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1171 }
1172 else
1173 {
1174 vDC.SetPen(vClearPen);
1175 vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
1176 vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
1177 vDC.DrawLine(vX, vY, vX + vWidth, vY);
1178 vDC.DrawLine(vX, vY + vHeight, vX, vY);
1179 }
1180 } // end of wxToolBar::RaiseTool
1181
1182 void wxToolBar::OnTimer (
1183 wxTimerEvent& rEvent
1184 )
1185 {
1186 if (rEvent.GetId() == m_vToolTimer.GetTimerId())
1187 {
1188 wxPoint vPos( m_vXMouse
1189 ,m_vYMouse
1190 );
1191
1192 m_pToolTip->DisplayToolTipWindow(vPos);
1193 m_vToolTimer.Stop();
1194 m_vToolExpTimer.Start(4000L, TRUE);
1195 }
1196 else if (rEvent.GetId() == m_vToolExpTimer.GetTimerId())
1197 {
1198 m_pToolTip->HideToolTipWindow();
1199 GetParent()->Refresh();
1200 m_vToolExpTimer.Stop();
1201 }
1202 } // end of wxToolBar::OnTimer
1203
1204 #endif // ndef for wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE