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