1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  15 #if wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE 
  18     #include "wx/settings.h" 
  19     #include "wx/window.h" 
  20     #include "wx/dcclient.h" 
  21     #include "wx/dcmemory.h" 
  24 #include "wx/tooltip.h" 
  25 #include "wx/toolbar.h" 
  27 bool                                wxToolBar::m_bInitialized 
= FALSE
; 
  29 // --------------------------------------------------------------------------- 
  30 // Helper for taking a regular bitmap and giving it a disabled look 
  31 // --------------------------------------------------------------------------- 
  32 wxBitmap 
wxDisableBitmap( 
  37     wxMask
*                         pMask 
= rBmp
.GetMask(); 
  42     DEVOPENSTRUC                    vDop  
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
  44     HDC                             hDC   
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
  45     HPS                             hPS   
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
  46     BITMAPINFOHEADER2               vHeader
; 
  50     HBITMAP                         hBitmap 
=  (HBITMAP
)rBmp
.GetHBITMAP(); 
  51     HBITMAP                         hOldBitmap 
= NULLHANDLE
; 
  52     HBITMAP                         hOldMask   
= NULLHANDLE
; 
  53     HBITMAP                         hMask 
= (HBITMAP
)rBmp
.GetMask()->GetMaskBitmap(); 
  54     unsigned char*                  pucBits
;     // buffer that will contain the bitmap data 
  55     unsigned char*                  pucData
;     // pointer to use to traverse bitmap data 
  56     unsigned char*                  pucBitsMask
; // buffer that will contain the mask data 
  57     unsigned char*                  pucDataMask
; // pointer to use to traverse mask data 
  60     bool                            bpp16 
= (wxDisplayDepth() == 16); 
  62     memset(&vHeader
, '\0', 16); 
  65     memset(&vInfo
, '\0', 16); 
  67     vInfo
.cx              
= (ULONG
)rBmp
.GetWidth(); 
  68     vInfo
.cy              
= (ULONG
)rBmp
.GetHeight(); 
  70     vInfo
.cBitCount       
= 24; // Set to desired count going in 
  73     // Create the buffers for data....all wxBitmaps are 24 bit internally 
  75     int                             nBytesPerLine 
= rBmp
.GetWidth() * 3; 
  76     int                             nSizeDWORD    
= sizeof(DWORD
); 
  77     int                             nLineBoundary 
= nBytesPerLine 
% nSizeDWORD
; 
  83     // Bitmap must be ina double-word alligned address so we may 
  84     // have some padding to worry about 
  86     if (nLineBoundary 
> 0) 
  88         nPadding     
= nSizeDWORD 
- nLineBoundary
; 
  89         nBytesPerLine 
+= nPadding
; 
  91     pucBits 
= (unsigned char *)malloc(nBytesPerLine 
* rBmp
.GetHeight()); 
  92     memset(pucBits
, '\0', (nBytesPerLine 
* rBmp
.GetHeight())); 
  93     pucBitsMask 
= (unsigned char *)malloc(nBytesPerLine 
* rBmp
.GetHeight()); 
  94     memset(pucBitsMask
, '\0', (nBytesPerLine 
* rBmp
.GetHeight())); 
  97     // Extract the bitmap and mask data 
  99     if ((hOldBitmap 
= ::GpiSetBitmap(hPS
, hBitmap
)) == HBM_ERROR
) 
 101         vError 
= ::WinGetLastError(vHabmain
); 
 102         sError 
= wxPMErrorToStr(vError
); 
 104     ::GpiQueryBitmapInfoHeader(hBitmap
, &vHeader
); 
 105     vInfo
.cBitCount 
= 24; 
 106     if ((lScans 
= ::GpiQueryBitmapBits( hPS
 
 108                                        ,(LONG
)rBmp
.GetHeight() 
 113         vError 
= ::WinGetLastError(vHabmain
); 
 114         sError 
= wxPMErrorToStr(vError
); 
 116     if ((hOldMask 
= ::GpiSetBitmap(hPS
, hMask
)) == HBM_ERROR
) 
 118         vError 
= ::WinGetLastError(vHabmain
); 
 119         sError 
= wxPMErrorToStr(vError
); 
 121     ::GpiQueryBitmapInfoHeader(hMask
, &vHeader
); 
 122     vInfo
.cBitCount 
= 24; 
 123     if ((lScans 
= ::GpiQueryBitmapBits( hPS
 
 125                                        ,(LONG
)rBmp
.GetHeight() 
 130         vError 
= ::WinGetLastError(vHabmain
); 
 131         sError 
= wxPMErrorToStr(vError
); 
 133     if (( hMask 
= ::GpiSetBitmap(hPS
, hOldMask
)) == HBM_ERROR
) 
 135         vError 
= ::WinGetLastError(vHabmain
); 
 136         sError 
= wxPMErrorToStr(vError
); 
 139     pucDataMask 
= pucBitsMask
; 
 142     // Get the mask value 
 144     for (i 
= 0; i 
< rBmp
.GetHeight(); i
++) 
 146         for (j 
= 0; j 
< rBmp
.GetWidth(); j
++) 
 149             if (bpp16 
&& *pucDataMask 
== 0xF8) // 16 bit display gobblygook 
 154             else if (*pucDataMask 
== 0xFF) // set to grey 
 161                 *pucData 
= ((unsigned char)(lColor 
>> 16)); 
 166             if (bpp16 
&& *(pucDataMask 
+ 1) == 0xFC) // 16 bit display gobblygook 
 171             else if (*(pucDataMask 
+ 1) == 0xFF) // set to grey 
 178                 *pucData 
= ((unsigned char)(lColor 
>> 8)); 
 183             if (bpp16 
&& *(pucDataMask 
+ 2) == 0xF8) // 16 bit display gobblygook 
 188             else if (*(pucDataMask 
+ 2) == 0xFF) // set to grey 
 195                 *pucData 
= ((unsigned char)lColor
); 
 200         for (j 
= 0; j 
< nPadding
; j
++) 
 208     // Create a new bitmap and set the modified bits 
 210     wxBitmap                        
vNewBmp( rBmp
.GetWidth() 
 214     HBITMAP                         hNewBmp 
= (HBITMAP
)vNewBmp
.GetHBITMAP(); 
 216     if ((hOldBitmap 
= ::GpiSetBitmap(hPS
, hNewBmp
)) == HBM_ERROR
) 
 218         vError 
= ::WinGetLastError(vHabmain
); 
 219         sError 
= wxPMErrorToStr(vError
); 
 221     if ((lScansSet 
= ::GpiSetBitmapBits( hPS
 
 223                                         ,(LONG
)rBmp
.GetHeight() 
 229         vError 
= ::WinGetLastError(vHabmain
); 
 230         sError 
= wxPMErrorToStr(vError
); 
 234     pNewMask 
= new wxMask(pMask
->GetMaskBitmap()); 
 235     vNewBmp
.SetMask(pNewMask
); 
 237     ::GpiSetBitmap(hPS
, NULLHANDLE
); 
 242     return(wxNullBitmap
); 
 243 } // end of wxDisableBitmap 
 245 // ---------------------------------------------------------------------------- 
 247 // ---------------------------------------------------------------------------- 
 249 class wxToolBarTool 
: public wxToolBarToolBase
 
 252     inline wxToolBarTool( wxToolBar
*      pTbar
 
 254                          ,const wxString
& rsLabel
 
 255                          ,const wxBitmap
& rBitmap1
 
 256                          ,const wxBitmap
& rBitmap2
 
 258                          ,wxObject
*       pClientData
 
 259                          ,const wxString
& rsShortHelpString
 
 260                          ,const wxString
& rsLongHelpString
 
 261                         ) : wxToolBarToolBase( pTbar
 
 274     inline wxToolBarTool( wxToolBar
* pTbar
 
 276                         ) : wxToolBarToolBase( pTbar
 
 282     void SetSize(const wxSize
& rSize
) 
 288     wxCoord 
GetWidth(void) const { return m_vWidth
; } 
 289     wxCoord 
GetHeight(void) const { return m_vHeight
; } 
 295 }; // end of CLASS wxToolBarTool 
 297 // ---------------------------------------------------------------------------- 
 299 // ---------------------------------------------------------------------------- 
 301 IMPLEMENT_DYNAMIC_CLASS(wxToolBar
, wxToolBarBase
) 
 303 BEGIN_EVENT_TABLE(wxToolBar
, wxToolBarBase
) 
 304     EVT_SIZE(wxToolBar::OnSize
) 
 305     EVT_PAINT(wxToolBar::OnPaint
) 
 306     EVT_KILL_FOCUS(wxToolBar::OnKillFocus
) 
 307     EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent
) 
 308     EVT_TIMER(-1, wxToolBar::OnTimer
) 
 311 // ============================================================================ 
 313 // ============================================================================ 
 315 // ---------------------------------------------------------------------------- 
 316 // tool bar tools creation 
 317 // ---------------------------------------------------------------------------- 
 319 wxToolBarToolBase
* wxToolBar::CreateTool( 
 321 , const wxString
&                   rsLabel
 
 322 , const wxBitmap
&                   rBmpNormal
 
 323 , const wxBitmap
&                   rBmpDisabled
 
 325 , wxObject
*                         pClientData
 
 326 , const wxString
&                   rsShortHelp
 
 327 , const wxString
&                   rsLongHelp
 
 330     return new wxToolBarTool( this 
 340 } // end of wxToolBarSimple::CreateTool 
 342 wxToolBarToolBase 
*wxToolBar::CreateTool( 
 346     return new wxToolBarTool( this 
 349 } // end of wxToolBarSimple::CreateTool 
 351 // ---------------------------------------------------------------------------- 
 352 // wxToolBarSimple creation 
 353 // ---------------------------------------------------------------------------- 
 355 void wxToolBar::Init() 
 357     m_nCurrentRowsOrColumns 
= 0; 
 359     m_vLastX 
= m_vLastY 
= 0; 
 360     m_vMaxWidth 
= m_vMaxHeight 
= 0; 
 361     m_nPressedTool 
= m_nCurrentTool 
= -1; 
 362     m_vXPos 
= m_vYPos 
= -1; 
 363     m_vTextX 
= m_vTextY 
= 0; 
 366     m_toolSeparation 
= 5; 
 369     m_defaultHeight 
= 15; 
 372 } // end of wxToolBar::Init 
 374 wxToolBarToolBase
* wxToolBar::DoAddTool( 
 376 , const wxString
&                   rsLabel
 
 377 , const wxBitmap
&                   rBitmap
 
 378 , const wxBitmap
&                   rBmpDisabled
 
 380 , const wxString
&                   rsShortHelp
 
 381 , const wxString
&                   rsLongHelp
 
 382 , wxObject
*                         pClientData
 
 388     // Rememeber the position for DoInsertTool() 
 393     return wxToolBarBase::DoAddTool( vId
 
 404 } // end of wxToolBar::DoAddTool 
 406 bool wxToolBar::DeleteTool( 
 410     bool                            bOk 
= wxToolBarBase::DeleteTool(nId
); 
 417 } // end of wxToolBar::DeleteTool 
 419 bool wxToolBar::DeleteToolByPos( 
 423     bool                            bOk 
= wxToolBarBase::DeleteToolByPos(nPos
); 
 430 } // end of wxToolBar::DeleteTool 
 432 wxToolBarToolBase
* wxToolBar::InsertControl( 
 434 , wxControl
*                        pControl
 
 437     wxToolBarToolBase
*              pTool 
= wxToolBarBase::InsertControl( nPos
 
 446 } // end of wxToolBar::InsertControl 
 448 wxToolBarToolBase
* wxToolBar::InsertSeparator( 
 452     wxToolBarToolBase
*              pTool 
= wxToolBarBase::InsertSeparator(nPos
); 
 460 } // end of wxToolBar::InsertSeparator 
 462 wxToolBarToolBase
* wxToolBar::InsertTool( 
 465 , const wxString
&                   rsLabel
 
 466 , const wxBitmap
&                   rBitmap
 
 467 , const wxBitmap
&                   rBmpDisabled
 
 469 , const wxString
&                   rsShortHelp
 
 470 , const wxString
&                   rsLongHelp
 
 471 , wxObject
*                         pClientData
 
 474     wxToolBarToolBase
*              pTool 
= wxToolBarBase::InsertTool( nPos
 
 490 } // end of wxToolBar::InsertTool 
 492 bool wxToolBar::DoInsertTool( 
 493   size_t                            WXUNUSED(nPos
) 
 494 , wxToolBarToolBase
*                pToolBase
 
 497     wxToolBarTool
*                  pTool 
= (wxToolBarTool 
*)pToolBase
; 
 499     pTool
->m_vX 
= m_vXPos
; 
 500     if (pTool
->m_vX 
== -1) 
 501         pTool
->m_vX 
= m_xMargin
; 
 503     pTool
->m_vY 
= m_vYPos
; 
 504     if (pTool
->m_vY 
== -1) 
 505         pTool
->m_vX 
= m_yMargin
; 
 507     pTool
->SetSize(GetToolSize()); 
 509     if (pTool
->IsButton()) 
 512         // Calculate reasonable max size in case Layout() not called 
 514         if ((pTool
->m_vX 
+ pTool
->GetNormalBitmap().GetWidth() + m_xMargin
) > m_vMaxWidth
) 
 515             m_vMaxWidth 
= (wxCoord
)((pTool
->m_vX 
+ pTool
->GetWidth() + m_xMargin
)); 
 517         if ((pTool
->m_vY 
+ pTool
->GetNormalBitmap().GetHeight() + m_yMargin
) > m_vMaxHeight
) 
 518             m_vMaxHeight 
= (wxCoord
)((pTool
->m_vY 
+ pTool
->GetHeight() + m_yMargin
)); 
 521 } // end of wxToolBar::DoInsertTool 
 523 bool wxToolBar::DoDeleteTool( 
 524   size_t                            WXUNUSED(nPos
) 
 525 , wxToolBarToolBase
*                pTool
 
 531 } // end of wxToolBar::DoDeleteTool 
 533 bool wxToolBar::Create( 
 536 , const wxPoint
&                    rPos
 
 537 , const wxSize
&                     rSize
 
 539 , const wxString
&                   rsName
 
 542     if ( !wxWindow::Create( pParent
 
 551     // Set it to grey (or other 3D face colour) 
 552     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENUBAR
)); 
 553     SetFont(*wxSMALL_FONT
); 
 555     if (GetWindowStyleFlag() & wxTB_VERTICAL
) 
 560         m_maxRows 
= 32000;      // a lot 
 569         m_maxCols 
= 32000;      // a lot 
 571     SetCursor(*wxSTANDARD_CURSOR
); 
 574     // The toolbar's tools, if they have labels and the winTB_TEXT 
 575     // style is set, then we need to take into account the size of 
 576     // the text when drawing tool bitmaps and the text 
 578     if (HasFlag(wxTB_TEXT
)) 
 580         wxClientDC                  
vDC(this); 
 582         vDC
.SetFont(GetFont()); 
 583         vDC
.GetTextExtent( "XXXX" 
 594     int                             nWidth  
= rSize
.x
; 
 595     int                             nHeight 
= rSize
.y
; 
 596     wxFrame
*                        pFrame 
= wxDynamicCast(GetParent(), wxFrame
); 
 598     if (lStyle 
& wxTB_HORIZONTAL
) 
 602             nWidth 
= pParent
->GetClientSize().x
; 
 606             if (lStyle 
& wxTB_TEXT
) 
 607                 nHeight 
= m_defaultHeight 
+ m_vTextY
; 
 609                 nHeight 
= m_defaultHeight
; 
 616             nHeight 
= pParent
->GetClientSize().y
; 
 620             if (lStyle 
& wxTB_TEXT
) 
 621                 nWidth 
= m_vTextX 
+ (int)(m_vTextX
/2); // a little margin 
 623                 nWidth 
= m_defaultWidth 
+ (int)(m_defaultWidth
/2); // a little margin 
 637 } // end of wxToolBar::Create 
 639 wxToolBar::~wxToolBar() 
 646 } // end of wxToolBar::~wxToolBar 
 648 bool wxToolBar::Realize() 
 650     int                             nMaxToolWidth  
= 0; 
 651     int                             nMaxToolHeight 
= 0; 
 655     m_nCurrentRowsOrColumns 
= 0; 
 656     m_vLastX               
= m_xMargin
; 
 657     m_vLastY               
= m_yMargin
; 
 663     // Find the maximum tool width and height 
 665     wxToolBarToolsList::Node
*       pNode 
= m_tools
.GetFirst(); 
 669         wxToolBarTool
*              pTool 
= (wxToolBarTool 
*)pNode
->GetData(); 
 671         if (HasFlag(wxTB_TEXT
) && !pTool
->GetLabel().IsEmpty()) 
 674             // Set the height according to the font and the border size 
 676             if (pTool
->GetWidth() > m_vTextX
) 
 677                 nMaxToolWidth 
= pTool
->GetWidth() + 4; 
 679                 nMaxToolWidth 
= m_vTextX
; 
 680             if (pTool
->GetHeight() + m_vTextY 
> nMaxToolHeight
) 
 681                 nMaxToolHeight 
= pTool
->GetHeight() + m_vTextY
; 
 685             if (pTool
->GetWidth() > nMaxToolWidth 
) 
 686                 nMaxToolWidth 
= pTool
->GetWidth() + 4; 
 687             if (pTool
->GetHeight() > nMaxToolHeight
) 
 688                 nMaxToolHeight 
= pTool
->GetHeight(); 
 690         pNode 
= pNode
->GetNext(); 
 693     wxCoord                         vTbWidth 
= 0L; 
 694     wxCoord                         vTbHeight 
= 0L; 
 699     if (vTbHeight 
< nMaxToolHeight
) 
 706         if (GetParent()->IsKindOf(CLASSINFO(wxFrame
))) 
 708             wxFrame
*            pFrame 
= wxDynamicCast(GetParent(), wxFrame
); 
 711                 pFrame
->PositionToolBar(); 
 715     int                             nSeparatorSize 
= m_toolSeparation
; 
 717     pNode 
= m_tools
.GetFirst(); 
 720         wxToolBarTool
*              pTool 
= (wxToolBarTool 
*)pNode
->GetData(); 
 722         if (pTool
->IsSeparator()) 
 724             if (GetWindowStyleFlag() & wxTB_HORIZONTAL
) 
 726                 pTool
->m_vX 
= m_vLastX 
+ nSeparatorSize
; 
 727                 pTool
->m_vHeight 
= m_defaultHeight 
+ m_vTextY
; 
 728                 if (m_nCurrentRowsOrColumns 
>= m_maxCols
) 
 729                     m_vLastY 
+= nSeparatorSize
; 
 731                     m_vLastX 
+= nSeparatorSize 
* 4; 
 735                 pTool
->m_vY 
= m_vLastY 
+ nSeparatorSize
; 
 736                 pTool
->m_vHeight 
= m_defaultHeight 
+ m_vTextY
; 
 737                 if (m_nCurrentRowsOrColumns 
>= m_maxRows
) 
 738                     m_vLastX 
+= nSeparatorSize
; 
 740                     m_vLastY 
+= nSeparatorSize 
* 4; 
 743         else if (pTool
->IsButton()) 
 745             if (GetWindowStyleFlag() & wxTB_HORIZONTAL
) 
 747                 if (m_nCurrentRowsOrColumns 
>= m_maxCols
) 
 749                     m_nCurrentRowsOrColumns 
= 0; 
 750                     m_vLastX                
= m_xMargin
; 
 751                     m_vLastY               
+= nMaxToolHeight 
+ m_toolPacking
; 
 753                 pTool
->m_vX 
= m_vLastX 
+ (nMaxToolWidth 
- ((int)(nMaxToolWidth
/2) + (int)(pTool
->GetWidth()/2))); 
 754                 if (HasFlag(wxTB_TEXT
)) 
 755                     pTool
->m_vY 
= m_vLastY 
+ nSeparatorSize 
- 2; // just bit of adjustment 
 757                     pTool
->m_vY 
= m_vLastY 
+ (nMaxToolHeight 
- (int)(pTool
->GetHeight()/2)); 
 758                 m_vLastX 
+= nMaxToolWidth 
+ m_toolPacking 
+ m_toolSeparation
; 
 762                 if (m_nCurrentRowsOrColumns 
>= m_maxRows
) 
 764                     m_nCurrentRowsOrColumns 
= 0; 
 765                     m_vLastX               
+= (nMaxToolWidth 
+ m_toolPacking
); 
 766                     m_vLastY                
= m_yMargin
; 
 768                 pTool
->m_vX 
= m_vLastX 
+ pTool
->GetWidth(); 
 769                 if (HasFlag(wxTB_TEXT
) && !pTool
->GetLabel().IsNull()) 
 770                     pTool
->m_vY 
= m_vLastY 
+ (nMaxToolHeight 
- m_vTextY
) + m_toolPacking
; 
 772                     pTool
->m_vY 
= m_vLastY 
+ (nMaxToolHeight 
- (int)(pTool
->GetHeight()/2)); 
 773                 m_vLastY 
+= nMaxToolHeight 
+ m_toolPacking 
+ m_toolSeparation
; 
 775             m_nCurrentRowsOrColumns
++; 
 779             // TODO: support the controls 
 782         if (m_vLastX 
> m_maxWidth
) 
 783             m_maxWidth 
= m_vLastX
; 
 784         if (m_vLastY 
> m_maxHeight
) 
 785             m_maxHeight 
= m_vLastY
; 
 787         pNode 
= pNode
->GetNext(); 
 790     if ( GetWindowStyleFlag() & wxTB_HORIZONTAL 
) 
 791         m_maxWidth 
+= nMaxToolWidth
; 
 793         m_maxHeight 
+= nMaxToolHeight
; 
 795     m_maxWidth 
+= m_xMargin
; 
 796     m_maxHeight 
+= m_yMargin
; 
 797     m_bInitialized 
= TRUE
; 
 799 } // end of wxToolBar::Realize 
 801 // ---------------------------------------------------------------------------- 
 803 // ---------------------------------------------------------------------------- 
 805 void wxToolBar::OnPaint ( 
 806   wxPaintEvent
&                     WXUNUSED(rEvent
) 
 813     static int                      nCount 
= 0; 
 816     // Prevent reentry of OnPaint which would cause wxMemoryDC errors. 
 822     ::WinFillRect(vDc
.GetHPS(), &vDc
.m_vRclPaint
, GetBackgroundColour().GetPixel()); 
 823     for ( wxToolBarToolsList::Node
* pNode 
= m_tools
.GetFirst(); 
 825           pNode 
= pNode
->GetNext() ) 
 827         wxToolBarTool
*              pTool 
= (wxToolBarTool
*)pNode
->GetData(); 
 829         if (pTool
->IsButton() ) 
 830             DrawTool(vDc
, pTool
); 
 831         if (pTool
->IsSeparator()) 
 833             wxPen                   
vDarkGreyPen( wxColour(85, 85, 85) 
 842             vDc
.SetPen(vDarkGreyPen
); 
 843             if (HasFlag(wxTB_TEXT
)) 
 845                 if (HasFlag(wxTB_HORIZONTAL
)) 
 848                     nY 
= pTool
->m_vY 
- (m_vTextY 
- 6); 
 849                     nHeight 
= (m_vTextY 
- 2) + pTool
->GetHeight(); 
 853                     nX 
= pTool
->m_vX 
+ m_xMargin 
+ 10; 
 854                     nY 
= pTool
->m_vY 
+ m_vTextY 
+ m_toolSeparation
; 
 855                     nWidth 
= pTool
->GetWidth() > m_vTextX 
? pTool
->GetWidth() : m_vTextX
; 
 862                 if (HasFlag(wxTB_HORIZONTAL
)) 
 863                     nHeight 
= pTool
->GetHeight() - 2; 
 866                     nX 
+= m_xMargin 
+ 10; 
 867                     nY 
+=  m_yMargin 
+ m_toolSeparation
; 
 868                     nWidth 
= pTool
->GetWidth(); 
 871             vDc
.DrawLine(nX
, nY
, nX 
+ nWidth
, nY 
+ nHeight
); 
 875 } // end of wxToolBar::OnPaint 
 877 void wxToolBar::OnSize ( 
 878   wxSizeEvent
&                      WXUNUSED(rEvent
) 
 881 #if wxUSE_CONSTRAINTS 
 885 } // end of wxToolBar::OnSize 
 887 void wxToolBar::OnKillFocus( 
 888   wxFocusEvent
&                     WXUNUSED(rEvent
) 
 891     OnMouseEnter(m_nPressedTool 
= m_nCurrentTool 
= -1); 
 892 } // end of wxToolBar::OnKillFocus 
 894 void wxToolBar::OnMouseEvent( 
 902     HPOINTER                        hPtr 
= ::WinQuerySysPointer(HWND_DESKTOP
, SPTR_ARROW
, FALSE
); 
 904     ::WinSetPointer(HWND_DESKTOP
, hPtr
); 
 905     ::WinQueryPointerPos(HWND_DESKTOP
, &vPoint
); 
 906     hWnd 
= ::WinWindowFromPoint(HWND_DESKTOP
, &vPoint
, TRUE
); 
 907     if (hWnd 
!= (HWND
)GetHwnd()) 
 913     rEvent
.GetPosition(&vX
, &vY
); 
 915     wxToolBarTool
*            pTool 
= (wxToolBarTool 
*)FindToolForPosition( vX
 
 919     if (rEvent
.LeftDown()) 
 931         if (m_nCurrentTool 
> -1) 
 933             if (rEvent
.LeftIsDown()) 
 934                 SpringUpButton(m_nCurrentTool
); 
 935             pTool 
= (wxToolBarTool 
*)FindById(m_nCurrentTool
); 
 936             if (pTool 
&& !pTool
->IsToggled()) 
 947     if (!rEvent
.IsButton()) 
 949         if (pTool
->GetId() != m_nCurrentTool
) 
 952             // If the left button is kept down and moved over buttons, 
 953             // press those buttons. 
 955             if (rEvent
.LeftIsDown() && pTool
->IsEnabled()) 
 957                 SpringUpButton(m_nCurrentTool
); 
 958                 if (pTool
->CanBeToggled()) 
 964             wxToolBarTool
*          pOldTool 
= (wxToolBarTool
*)FindById(m_nCurrentTool
); 
 966             if (pOldTool 
&& !pTool
->IsToggled()) 
 970             m_nCurrentTool 
= pTool
->GetId(); 
 971             OnMouseEnter(m_nCurrentTool
); 
 972             if (!pTool
->GetShortHelp().IsEmpty()) 
 976                 m_pToolTip 
= new wxToolTip(pTool
->GetShortHelp()); 
 977                 m_vXMouse 
= (wxCoord
)vPoint
.x
; 
 978                 m_vYMouse 
= (wxCoord
)vPoint
.y
; 
 979                 m_vToolTimer
.Start(3000L, TRUE
); 
 981             if (!pTool
->IsToggled()) 
 987     // Left button pressed. 
 988     if (rEvent
.LeftDown() && pTool
->IsEnabled()) 
 990         if (pTool
->CanBeToggled()) 
 996     else if (rEvent
.RightDown()) 
 998         OnRightClick( pTool
->GetId() 
1005     // Left Button Released.  Only this action confirms selection. 
1006     // If the button is enabled and it is not a toggle tool and it is 
1007     // in the pressed state, then raise the button and call OnLeftClick. 
1009     if (rEvent
.LeftUp() && pTool
->IsEnabled() ) 
1012         // Pass the OnLeftClick event to tool 
1014         if (!OnLeftClick( pTool
->GetId() 
1015                          ,pTool
->IsToggled()) && 
1016                           pTool
->CanBeToggled()) 
1019             // If it was a toggle, and OnLeftClick says No Toggle allowed, 
1020             // then change it back 
1026 } // end of wxToolBar::OnMouseEvent 
1028 // ---------------------------------------------------------------------------- 
1030 // ---------------------------------------------------------------------------- 
1032 void wxToolBar::DrawTool( 
1033   wxToolBarToolBase
*                pTool
 
1036     wxClientDC                      
vDc(this); 
1041 } // end of wxToolBar::DrawTool 
1043 void wxToolBar::DrawTool( 
1045 , wxToolBarToolBase
*                pToolBase
 
1048     wxToolBarTool
*                  pTool 
= (wxToolBarTool 
*)pToolBase
; 
1049     wxPen                           
vDarkGreyPen( wxColour( 85,85,85 ) 
1053     wxPen                           
vWhitePen( wxT("WHITE") 
1057     wxPen                           
vBlackPen( wxT("BLACK") 
1061     wxBitmap                        vBitmap 
= pTool
->GetNormalBitmap(); 
1062     bool                            bUseMask 
= FALSE
; 
1063     wxMask
*                         pMask 
= NULL
; 
1070     if ((pMask 
= vBitmap
.GetMask()) != NULL
) 
1071         if (pMask
->GetMaskBitmap() != NULLHANDLE
) 
1074     if (!pTool
->IsToggled()) 
1076         LowerTool(pTool
, FALSE
); 
1077         if (!pTool
->IsEnabled()) 
1079             wxColour                
vColor("GREY"); 
1081             rDc
.SetTextForeground(vColor
); 
1082             if (!pTool
->GetDisabledBitmap().Ok()) 
1083                 pTool
->SetDisabledBitmap(wxDisableBitmap( vBitmap
 
1084                                                          ,(long)GetBackgroundColour().GetPixel() 
1086             rDc
.DrawBitmap( pTool
->GetDisabledBitmap() 
1094             wxColour                
vColor("BLACK"); 
1096             rDc
.SetTextForeground(vColor
); 
1097             rDc
.DrawBitmap( vBitmap
 
1103         if (m_windowStyle 
& wxTB_3DBUTTONS
) 
1107         if (HasFlag(wxTB_TEXT
) && !pTool
->GetLabel().IsNull()) 
1111             wxCoord                 vLeft 
= pTool
->m_vX 
- (int)(pTool
->GetWidth()/2); 
1113             rDc
.SetFont(GetFont()); 
1114             rDc
.GetTextExtent( pTool
->GetLabel() 
1118             if (pTool
->GetWidth() > vX
) // large tools 
1120                 vLeft 
= pTool
->m_vX 
+ (pTool
->GetWidth() - vX
); 
1122                 rDc
.DrawText( pTool
->GetLabel() 
1124                              ,vY 
- (m_vTextY 
- 2) 
1127             else  // normal tools 
1129                 vLeft 
+= (wxCoord
)((m_vTextX 
- vX
)/2); 
1130                 rDc
.DrawText( pTool
->GetLabel() 
1132                              ,pTool
->m_vY 
+ m_vTextY 
+ 4 // a bit of margin 
1139         wxColour                    
vColor("GREY"); 
1142         rDc
.SetTextForeground(vColor
); 
1143         if (!pTool
->GetDisabledBitmap().Ok()) 
1144             pTool
->SetDisabledBitmap(wxDisableBitmap( vBitmap
 
1145                                                      ,(long)GetBackgroundColour().GetPixel() 
1147         rDc
.DrawBitmap( pTool
->GetDisabledBitmap() 
1152         if (HasFlag(wxTB_TEXT
) && !pTool
->GetLabel().IsNull()) 
1156             wxCoord                 vLeft 
= pTool
->m_vX 
- (int)(pTool
->GetWidth()/2); 
1158             rDc
.SetFont(GetFont()); 
1159             rDc
.GetTextExtent( pTool
->GetLabel() 
1163             vLeft 
+= (wxCoord
)((m_vTextX 
- vX
)/2); 
1164             rDc
.DrawText( pTool
->GetLabel() 
1166                          ,pTool
->m_vY 
+ m_vTextY 
+ 4 // a bit of margin 
1170 } // end of wxToolBar::DrawTool 
1172 // ---------------------------------------------------------------------------- 
1174 // ---------------------------------------------------------------------------- 
1176 void wxToolBar::SetRows( 
1180     wxCHECK_RET( nRows 
!= 0, _T("max number of rows must be > 0") ); 
1182     m_maxCols 
= (GetToolsCount() + nRows 
- 1) / nRows
; 
1184 } // end of wxToolBar::SetRows 
1186 wxToolBarToolBase
* wxToolBar::FindToolForPosition( 
1193     wxCoord                         vTBarHeight 
= 0; 
1198     vY 
= vTBarHeight 
- vY
; 
1199     wxToolBarToolsList::Node
* pNode 
= m_tools
.GetFirst(); 
1202         wxToolBarTool
*              pTool 
= (wxToolBarTool 
*)pNode
->GetData(); 
1204         if (HasFlag(wxTB_TEXT
) && !pTool
->GetLabel().IsNull()) 
1206             if ((vX 
>= (pTool
->m_vX 
- ((wxCoord
)(pTool
->GetWidth()/2) - 2))) && 
1207                 (vY 
>= (pTool
->m_vY 
- 2)) && 
1208                 (vX 
<= (pTool
->m_vX 
+ pTool
->GetWidth())) && 
1209                 (vY 
<= (pTool
->m_vY 
+ pTool
->GetHeight() + m_vTextY 
+ 2))) 
1216             if ((vX 
>= pTool
->m_vX
) && 
1217                 (vY 
>= pTool
->m_vY
) && 
1218                 (vX 
<= (pTool
->m_vX 
+ pTool
->GetWidth())) && 
1219                 (vY 
<= (pTool
->m_vY 
+ pTool
->GetHeight()))) 
1224         pNode 
= pNode
->GetNext(); 
1226     return (wxToolBarToolBase 
*)NULL
; 
1227 } // end of wxToolBar::FindToolForPosition 
1229 // ---------------------------------------------------------------------------- 
1230 // tool state change handlers 
1231 // ---------------------------------------------------------------------------- 
1233 void wxToolBar::DoEnableTool( 
1234   wxToolBarToolBase
*                pTool
 
1235 , bool                              WXUNUSED(bEnable
) 
1239 } // end of wxToolBar::DoEnableTool 
1241 void wxToolBar::DoToggleTool( 
1242   wxToolBarToolBase
*                pTool
 
1243 , bool                              WXUNUSED(bToggle
) 
1247 } // end of wxToolBar::DoToggleTool 
1249 void wxToolBar::DoSetToggle( 
1250   wxToolBarToolBase
*                WXUNUSED(pTool
) 
1251 , bool                              WXUNUSED(bToggle
) 
1255 } // end of wxToolBar::DoSetToggle 
1258 // Okay, so we've left the tool we're in ... we must check if the tool we're 
1259 // leaving was a 'sprung push button' and if so, spring it back to the up 
1262 void wxToolBar::SpringUpButton( 
1266     wxToolBarToolBase
*              pTool 
= FindById(vId
); 
1268     if (pTool 
&& pTool
->CanBeToggled()) 
1270         if (pTool
->IsToggled()) 
1275 } // end of wxToolBar::SpringUpButton 
1277 // ---------------------------------------------------------------------------- 
1279 // ---------------------------------------------------------------------------- 
1281 void wxToolBar::LowerTool ( 
1282   wxToolBarToolBase
*                pToolBase
 
1286     wxToolBarTool
*                  pTool 
= (wxToolBarTool
*)pToolBase
; 
1291     wxPen                           
vDarkGreyPen( wxColour(85, 85, 85) 
1295     wxPen                           
vWhitePen( "WHITE" 
1299     wxPen                           
vClearPen( GetBackgroundColour() 
1303     wxClientDC                      
vDC(this); 
1308     if (pTool
->IsSeparator()) 
1312     // We only do this for flat toolbars 
1314     if (!HasFlag(wxTB_FLAT
)) 
1317     if (HasFlag(wxTB_TEXT
) && !pTool
->GetLabel().IsEmpty()) 
1319         if (pTool
->GetWidth() > m_vTextX
) 
1321             vX 
= pTool
->m_vX 
- 2; 
1322             vWidth 
= pTool
->GetWidth() + 4; 
1326             vX 
= pTool
->m_vX 
- (wxCoord
)(pTool
->GetWidth()/2); 
1327             vWidth 
= m_vTextX 
+ 4; 
1329         vY 
= pTool
->m_vY 
- 2; 
1330         vHeight 
= pTool
->GetHeight() + m_vTextY 
+ 2; 
1334         vX 
= pTool
->m_vX 
- 2; 
1335         vY 
= pTool
->m_vY 
- 2; 
1336         vWidth 
= pTool
->GetWidth() + 4; 
1337         vHeight 
= pTool
->GetHeight() + 4; 
1341         vDC
.SetPen(vWhitePen
); 
1342         vDC
.DrawLine(vX 
+ vWidth
, vY 
+ vHeight
, vX
, vY 
+ vHeight
); 
1343         vDC
.DrawLine(vX 
+ vWidth
, vY
, vX 
+ vWidth
, vY 
+ vHeight
); 
1344         vDC
.SetPen(vDarkGreyPen
); 
1345         vDC
.DrawLine(vX
, vY
, vX 
+ vWidth
, vY
); 
1346         vDC
.DrawLine(vX
, vY 
+ vHeight
, vX
, vY
); 
1350         vDC
.SetPen(vClearPen
); 
1351         vDC
.DrawLine(vX 
+ vWidth
, vY 
+ vHeight
, vX
, vY 
+ vHeight
); 
1352         vDC
.DrawLine(vX 
+ vWidth
, vY
, vX 
+ vWidth
, vY 
+ vHeight
); 
1353         vDC
.DrawLine(vX
, vY
, vX 
+ vWidth
, vY
); 
1354         vDC
.DrawLine(vX
, vY 
+ vHeight
, vX
, vY
); 
1356 } // end of WinGuiBase_CToolBarTool::LowerTool 
1358 void wxToolBar::RaiseTool ( 
1359   wxToolBarToolBase
*                pToolBase
 
1363     wxToolBarTool
*                  pTool 
= (wxToolBarTool
*)pToolBase
; 
1368     wxPen                           
vDarkGreyPen( wxColour(85, 85, 85) 
1372     wxPen                           
vWhitePen( "WHITE" 
1376     wxPen                           
vClearPen( GetBackgroundColour() 
1380     wxClientDC                      
vDC(this); 
1385     if (pTool
->IsSeparator()) 
1388     if (!pTool
->IsEnabled()) 
1392     // We only do this for flat toolbars 
1394     if (!HasFlag(wxTB_FLAT
)) 
1397     if (HasFlag(wxTB_TEXT
) && !pTool
->GetLabel().IsEmpty()) 
1399         if (pTool
->GetWidth() > m_vTextX
) 
1401             vX 
= pTool
->m_vX 
- 2; 
1402             vWidth 
= pTool
->GetWidth() + 4; 
1406             vX 
= pTool
->m_vX 
- (wxCoord
)(pTool
->GetWidth()/2); 
1407             vWidth 
= m_vTextX 
+ 4; 
1409         vY 
= pTool
->m_vY 
- 2; 
1410         vHeight 
= pTool
->GetHeight() + m_vTextY 
+ 2; 
1414         vX 
= pTool
->m_vX 
- 2; 
1415         vY 
= pTool
->m_vY 
- 2; 
1416         vWidth 
= pTool
->GetWidth() + 4; 
1417         vHeight 
= pTool
->GetHeight() + 4; 
1421         vDC
.SetPen(vDarkGreyPen
); 
1422         vDC
.DrawLine(vX 
+ vWidth
, vY 
+ vHeight
, vX
, vY 
+ vHeight
); 
1423         vDC
.DrawLine(vX 
+ vWidth
, vY
, vX 
+ vWidth
, vY 
+ vHeight
); 
1424         vDC
.SetPen(vWhitePen
); 
1425         vDC
.DrawLine(vX
, vY
, vX 
+ vWidth
, vY
); 
1426         vDC
.DrawLine(vX
, vY 
+ vHeight
, vX
, vY
); 
1430         vDC
.SetPen(vClearPen
); 
1431         vDC
.DrawLine(vX 
+ vWidth
, vY 
+ vHeight
, vX
, vY 
+ vHeight
); 
1432         vDC
.DrawLine(vX 
+ vWidth
, vY
, vX 
+ vWidth
, vY 
+ vHeight
); 
1433         vDC
.DrawLine(vX
, vY
, vX 
+ vWidth
, vY
); 
1434         vDC
.DrawLine(vX
, vY 
+ vHeight
, vX
, vY
); 
1436 } // end of wxToolBar::RaiseTool 
1438 void wxToolBar::OnTimer ( 
1439   wxTimerEvent
&                     rEvent
 
1442     if (rEvent
.GetId() == (int)m_vToolTimer
.GetTimerId()) 
1444         wxPoint                     
vPos( m_vXMouse
 
1448         m_pToolTip
->DisplayToolTipWindow(vPos
); 
1449         m_vToolTimer
.Stop(); 
1450         m_vToolExpTimer
.Start(3000L, TRUE
); 
1452     else if (rEvent
.GetId() == (int)m_vToolExpTimer
.GetTimerId()) 
1454         m_pToolTip
->HideToolTipWindow(); 
1455         GetParent()->Refresh(); 
1456         m_vToolExpTimer
.Stop(); 
1458 } // end of wxToolBar::OnTimer 
1460 #endif // ndef for wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE