home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / os2 / toolbar.cpp < prev    next >
C/C++ Source or Header  |  2002-09-09  |  40KB  |  1,247 lines

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