home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / generic / tbarsmpl.cpp < prev    next >
C/C++ Source or Header  |  2002-12-16  |  31KB  |  1,012 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        generic/tbarsmpl.cpp
  3. // Purpose:     wxToolBarSimple
  4. // Author:      Julian Smart
  5. // Modified by: VZ on 14.12.99 during wxToolBarSimple reorganization
  6. // Created:     04/01/98
  7. // RCS-ID:      $Id: tbarsmpl.cpp,v 1.19.2.2 2002/12/16 10:50:49 JS Exp $
  8. // Copyright:   (c) Julian Smart and Markus Holzem
  9. // Licence:     wxWindows license
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. // ============================================================================
  13. // declarations
  14. // ============================================================================
  15.  
  16. // ----------------------------------------------------------------------------
  17. // headers
  18. // ----------------------------------------------------------------------------
  19.  
  20. #ifdef __GNUG__
  21.     #pragma implementation "tbarsmpl.h"
  22. #endif
  23.  
  24. // For compilers that support precompilation, includes "wx.h".
  25. #include "wx/wxprec.h"
  26.  
  27. #ifdef __BORLANDC__
  28.     #pragma hdrstop
  29. #endif
  30.  
  31. #if wxUSE_TOOLBAR_SIMPLE
  32.  
  33. #ifndef WX_PRECOMP
  34.     #include "wx/settings.h"
  35.     #include "wx/window.h"
  36.     #include "wx/dcclient.h"
  37.     #include "wx/dcmemory.h"
  38. #endif
  39.  
  40. #include "wx/tbarsmpl.h"
  41.  
  42. // ----------------------------------------------------------------------------
  43. // private classes
  44. // ----------------------------------------------------------------------------
  45.  
  46. class WXDLLEXPORT wxToolBarToolSimple : public wxToolBarToolBase
  47. {
  48. public:
  49.     wxToolBarToolSimple(wxToolBarSimple *tbar,
  50.                         int id,
  51.                         const wxString& label,
  52.                         const wxBitmap& bmpNormal,
  53.                         const wxBitmap& bmpDisabled,
  54.                         wxItemKind kind,
  55.                         wxObject *clientData,
  56.                         const wxString& shortHelp,
  57.                         const wxString& longHelp)
  58.         : wxToolBarToolBase(tbar, id, label, bmpNormal, bmpDisabled, kind,
  59.                             clientData, shortHelp, longHelp)
  60.     {
  61.     }
  62.  
  63.     wxToolBarToolSimple(wxToolBarSimple *tbar, wxControl *control)
  64.         : wxToolBarToolBase(tbar, control)
  65.     {
  66.     }
  67.  
  68.     void SetSize(const wxSize& size)
  69.     {
  70.         m_width = size.x;
  71.         m_height = size.y;
  72.     }
  73.  
  74.     wxCoord GetWidth() const { return m_width; }
  75.     wxCoord GetHeight() const { return m_height; }
  76.  
  77.     wxCoord m_x;
  78.     wxCoord m_y;
  79.     wxCoord m_width;
  80.     wxCoord m_height;
  81. };
  82.  
  83. // ----------------------------------------------------------------------------
  84. // wxWin macros
  85. // ----------------------------------------------------------------------------
  86.  
  87. IMPLEMENT_DYNAMIC_CLASS(wxToolBarSimple, wxToolBarBase)
  88.  
  89. #if !defined(wxUSE_TOOLBAR_NATIVE) && !defined(__WXUNIVERSAL__)
  90.     #include "wx/toolbar.h"
  91.  
  92.     IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarSimple)
  93. #endif
  94.  
  95. BEGIN_EVENT_TABLE(wxToolBarSimple, wxToolBarBase)
  96.     EVT_SIZE(wxToolBarSimple::OnSize)
  97.     EVT_SCROLL(wxToolBarSimple::OnScroll)
  98.     EVT_PAINT(wxToolBarSimple::OnPaint)
  99.     EVT_KILL_FOCUS(wxToolBarSimple::OnKillFocus)
  100.     EVT_MOUSE_EVENTS(wxToolBarSimple::OnMouseEvent)
  101. END_EVENT_TABLE()
  102.  
  103. // ============================================================================
  104. // implementation
  105. // ============================================================================
  106.  
  107. // ----------------------------------------------------------------------------
  108. // tool bar tools creation
  109. // ----------------------------------------------------------------------------
  110.  
  111. wxToolBarToolBase *wxToolBarSimple::CreateTool(int id,
  112.                                                const wxString& label,
  113.                                                const wxBitmap& bmpNormal,
  114.                                                const wxBitmap& bmpDisabled,
  115.                                                wxItemKind kind,
  116.                                                wxObject *clientData,
  117.                                                const wxString& shortHelp,
  118.                                                const wxString& longHelp)
  119. {
  120.     return new wxToolBarToolSimple(this, id, label, bmpNormal, bmpDisabled,
  121.                                    kind, clientData, shortHelp, longHelp);
  122. }
  123.  
  124. wxToolBarToolBase *wxToolBarSimple::CreateTool(wxControl *control)
  125. {
  126.     return new wxToolBarToolSimple(this, control);
  127. }
  128.  
  129. // ----------------------------------------------------------------------------
  130. // wxToolBarSimple creation
  131. // ----------------------------------------------------------------------------
  132.  
  133. void wxToolBarSimple::Init()
  134. {
  135.     m_currentRowsOrColumns = 0;
  136.  
  137.     m_lastX =
  138.     m_lastY = 0;
  139.  
  140.     m_maxWidth =
  141.     m_maxHeight = 0;
  142.  
  143.     m_pressedTool =
  144.     m_currentTool = -1;
  145.  
  146.     m_xPos =
  147.     m_yPos = -1;
  148.  
  149.     m_toolPacking = 1;
  150.     m_toolSeparation = 5;
  151.  
  152.     m_defaultWidth = 16;
  153.     m_defaultHeight = 15;
  154.  
  155.     m_xScrollPixelsPerLine = 1;
  156.     m_yScrollPixelsPerLine = 1;
  157.     m_xScrollingEnabled = FALSE;
  158.     m_yScrollingEnabled = FALSE;
  159.     m_xScrollPosition = 0;
  160.     m_yScrollPosition = 0;
  161.     m_xScrollLines = 0;
  162.     m_yScrollLines = 0;
  163.     m_xScrollLinesPerPage = 0;
  164.     m_yScrollLinesPerPage = 0;
  165. }
  166.  
  167. wxToolBarToolBase *wxToolBarSimple::DoAddTool(int id,
  168.                                               const wxString& label,
  169.                                               const wxBitmap& bitmap,
  170.                                               const wxBitmap& bmpDisabled,
  171.                                               wxItemKind kind,
  172.                                               const wxString& shortHelp,
  173.                                               const wxString& longHelp,
  174.                                               wxObject *clientData,
  175.                                               wxCoord xPos,
  176.                                               wxCoord yPos)
  177. {
  178.     // rememeber the position for DoInsertTool()
  179.     m_xPos = xPos;
  180.     m_yPos = yPos;
  181.  
  182.     return wxToolBarBase::DoAddTool(id, label, bitmap, bmpDisabled, kind,
  183.                                     shortHelp, longHelp,
  184.                                     clientData, xPos, yPos);
  185. }
  186.  
  187. bool wxToolBarSimple::DoInsertTool(size_t WXUNUSED(pos),
  188.                                    wxToolBarToolBase *toolBase)
  189. {
  190.     wxToolBarToolSimple *tool = (wxToolBarToolSimple *)toolBase;
  191.  
  192.     wxCHECK_MSG( !tool->IsControl(), FALSE,
  193.                  _T("generic wxToolBarSimple doesn't support controls") );
  194.  
  195.     tool->m_x = m_xPos;
  196.     if ( tool->m_x == -1 )
  197.         tool->m_x = m_xMargin;
  198.  
  199.     tool->m_y = m_yPos;
  200.     if ( tool->m_y == -1 )
  201.         tool->m_y = m_yMargin;
  202.  
  203.     tool->SetSize(GetToolSize());
  204.  
  205.     if ( tool->IsButton() )
  206.     {
  207.         // Calculate reasonable max size in case Layout() not called
  208.         if ((tool->m_x + tool->GetNormalBitmap().GetWidth() + m_xMargin) > m_maxWidth)
  209.             m_maxWidth = (wxCoord)((tool->m_x + tool->GetWidth() + m_xMargin));
  210.  
  211.         if ((tool->m_y + tool->GetNormalBitmap().GetHeight() + m_yMargin) > m_maxHeight)
  212.             m_maxHeight = (wxCoord)((tool->m_y + tool->GetHeight() + m_yMargin));
  213.     }
  214.  
  215.     return TRUE;
  216. }
  217.  
  218. bool wxToolBarSimple::DoDeleteTool(size_t WXUNUSED(pos),
  219.                                    wxToolBarToolBase *tool)
  220. {
  221.     // VZ: didn't test whether it works, but why not...
  222.     tool->Detach();
  223.  
  224.     Refresh();
  225.  
  226.     return TRUE;
  227. }
  228.  
  229. bool wxToolBarSimple::Create(wxWindow *parent,
  230.                              wxWindowID id,
  231.                              const wxPoint& pos,
  232.                              const wxSize& size,
  233.                              long style,
  234.                              const wxString& name)
  235. {
  236.     if ( !wxWindow::Create(parent, id, pos, size, style, name) )
  237.         return FALSE;
  238.  
  239.     // Set it to grey (or other 3D face colour)
  240.     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
  241.  
  242.     if ( GetWindowStyleFlag() & wxTB_VERTICAL )
  243.     {
  244.         m_lastX = 7;
  245.         m_lastY = 3;
  246.  
  247.         m_maxRows = 32000;      // a lot
  248.         m_maxCols = 1;
  249.     }
  250.     else
  251.     {
  252.         m_lastX = 3;
  253.         m_lastY = 7;
  254.  
  255.         m_maxRows = 1;
  256.         m_maxCols = 32000;      // a lot
  257.     }
  258.  
  259.     SetCursor(*wxSTANDARD_CURSOR);
  260.  
  261.     return TRUE;
  262. }
  263.  
  264. wxToolBarSimple::~wxToolBarSimple()
  265. {
  266. }
  267.  
  268. bool wxToolBarSimple::Realize()
  269. {
  270.     m_currentRowsOrColumns = 0;
  271.     m_lastX = m_xMargin;
  272.     m_lastY = m_yMargin;
  273.     m_maxWidth = 0;
  274.     m_maxHeight = 0;
  275.  
  276.     int maxToolWidth = 0;
  277.     int maxToolHeight = 0;
  278.  
  279.     // Find the maximum tool width and height
  280.     wxToolBarToolsList::Node *node = m_tools.GetFirst();
  281.     while ( node )
  282.     {
  283.         wxToolBarToolSimple *tool = (wxToolBarToolSimple *)node->GetData();
  284.         if ( tool->GetWidth() > maxToolWidth )
  285.             maxToolWidth = tool->GetWidth();
  286.         if (tool->GetHeight() > maxToolHeight)
  287.             maxToolHeight = tool->GetHeight();
  288.  
  289.         node = node->GetNext();
  290.     }
  291.  
  292.     int separatorSize = m_toolSeparation;
  293.  
  294.     node = m_tools.GetFirst();
  295.     while ( node )
  296.     {
  297.         wxToolBarToolSimple *tool = (wxToolBarToolSimple *)node->GetData();
  298.         if ( tool->IsSeparator() )
  299.         {
  300.             if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
  301.             {
  302.                 if (m_currentRowsOrColumns >= m_maxCols)
  303.                     m_lastY += separatorSize;
  304.                 else
  305.                     m_lastX += separatorSize;
  306.             }
  307.             else
  308.             {
  309.                 if (m_currentRowsOrColumns >= m_maxRows)
  310.                     m_lastX += separatorSize;
  311.                 else
  312.                     m_lastY += separatorSize;
  313.             }
  314.         }
  315.         else if ( tool->IsButton() )
  316.         {
  317.             if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
  318.             {
  319.                 if (m_currentRowsOrColumns >= m_maxCols)
  320.                 {
  321.                     m_currentRowsOrColumns = 0;
  322.                     m_lastX = m_xMargin;
  323.                     m_lastY += maxToolHeight + m_toolPacking;
  324.                 }
  325.                 tool->m_x = (wxCoord)(m_lastX + (maxToolWidth - tool->GetWidth())/2.0);
  326.                 tool->m_y = (wxCoord)(m_lastY + (maxToolHeight - tool->GetHeight())/2.0);
  327.  
  328.                 m_lastX += maxToolWidth + m_toolPacking;
  329.             }
  330.             else
  331.             {
  332.                 if (m_currentRowsOrColumns >= m_maxRows)
  333.                 {
  334.                     m_currentRowsOrColumns = 0;
  335.                     m_lastX += (maxToolWidth + m_toolPacking);
  336.                     m_lastY = m_yMargin;
  337.                 }
  338.                 tool->m_x = (wxCoord)(m_lastX + (maxToolWidth - tool->GetWidth())/2.0);
  339.                 tool->m_y = (wxCoord)(m_lastY + (maxToolHeight - tool->GetHeight())/2.0);
  340.  
  341.                 m_lastY += maxToolHeight + m_toolPacking;
  342.             }
  343.             m_currentRowsOrColumns ++;
  344.         }
  345.         else
  346.         {
  347.             // TODO: support the controls
  348.         }
  349.  
  350.         if (m_lastX > m_maxWidth)
  351.             m_maxWidth = m_lastX;
  352.         if (m_lastY > m_maxHeight)
  353.             m_maxHeight = m_lastY;
  354.  
  355.         node = node->GetNext();
  356.     }
  357.  
  358.     if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
  359.         m_maxHeight += maxToolHeight;
  360.     else
  361.         m_maxWidth += maxToolWidth;
  362.  
  363.     m_maxWidth += m_xMargin;
  364.     m_maxHeight += m_yMargin;
  365.  
  366.     SetSize(m_maxWidth, m_maxHeight);
  367.  
  368.     return TRUE;
  369. }
  370.  
  371. // ----------------------------------------------------------------------------
  372. // event handlers
  373. // ----------------------------------------------------------------------------
  374.  
  375. void wxToolBarSimple::OnPaint (wxPaintEvent& WXUNUSED(event))
  376. {
  377.     wxPaintDC dc(this);
  378.     PrepareDC(dc);
  379.  
  380.     static int count = 0;
  381.     // Prevent reentry of OnPaint which would cause wxMemoryDC errors.
  382.     if ( count > 0 )
  383.         return;
  384.     count++;
  385.  
  386.     for ( wxToolBarToolsList::Node *node = m_tools.GetFirst();
  387.           node;
  388.           node = node->GetNext() )
  389.     {
  390.         wxToolBarToolBase *tool = node->GetData();
  391.         if ( tool->IsButton() )
  392.             DrawTool(dc, tool);
  393.     }
  394.  
  395.     count--;
  396. }
  397.  
  398. void wxToolBarSimple::OnSize (wxSizeEvent& WXUNUSED(event))
  399. {
  400. #if wxUSE_CONSTRAINTS
  401.     if (GetAutoLayout())
  402.         Layout();
  403. #endif
  404.  
  405.     AdjustScrollbars();
  406. }
  407.  
  408. void wxToolBarSimple::OnKillFocus(wxFocusEvent& WXUNUSED(event))
  409. {
  410.     OnMouseEnter(m_pressedTool = m_currentTool = -1);
  411. }
  412.  
  413. void wxToolBarSimple::OnMouseEvent(wxMouseEvent & event)
  414. {
  415.     wxCoord x, y;
  416.     event.GetPosition(&x, &y);
  417.     wxToolBarToolSimple *tool = (wxToolBarToolSimple *)FindToolForPosition(x, y);
  418.  
  419.     if (event.LeftDown())
  420.     {
  421.         CaptureMouse();
  422.     }
  423.     if (event.LeftUp())
  424.     {
  425.         ReleaseMouse();
  426.     }
  427.  
  428.     if (!tool)
  429.     {
  430.         if (m_currentTool > -1)
  431.         {
  432.             if (event.LeftIsDown())
  433.                 SpringUpButton(m_currentTool);
  434.             m_currentTool = -1;
  435.             OnMouseEnter(-1);
  436.         }
  437.         return;
  438.     }
  439.  
  440.     if (!event.IsButton())
  441.     {
  442.         if ( tool->GetId() != m_currentTool )
  443.         {
  444.             // If the left button is kept down and moved over buttons,
  445.             // press those buttons.
  446.             if ( event.LeftIsDown() && tool->IsEnabled() )
  447.             {
  448.                 SpringUpButton(m_currentTool);
  449.  
  450.                 if ( tool->CanBeToggled() )
  451.                 {
  452.                     tool->Toggle();
  453.                 }
  454.  
  455.                 DrawTool(tool);
  456.             }
  457.  
  458.             m_currentTool = tool->GetId();
  459.             OnMouseEnter(m_currentTool);
  460.         }
  461.         return;
  462.     }
  463.  
  464.     // Left button pressed.
  465.     if ( event.LeftDown() && tool->IsEnabled() )
  466.     {
  467.         if ( tool->CanBeToggled() )
  468.         {
  469.             tool->Toggle();
  470.         }
  471.  
  472.         DrawTool(tool);
  473.     }
  474.     else if (event.RightDown())
  475.     {
  476.         OnRightClick(tool->GetId(), x, y);
  477.     }
  478.  
  479.     // Left Button Released.  Only this action confirms selection.
  480.     // If the button is enabled and it is not a toggle tool and it is
  481.     // in the pressed state, then raise the button and call OnLeftClick.
  482.     //
  483.     if ( event.LeftUp() && tool->IsEnabled() )
  484.     {
  485.         // Pass the OnLeftClick event to tool
  486.         if ( !OnLeftClick(tool->GetId(), tool->IsToggled()) &&
  487.                           tool->CanBeToggled() )
  488.         {
  489.             // If it was a toggle, and OnLeftClick says No Toggle allowed,
  490.             // then change it back
  491.             tool->Toggle();
  492.         }
  493.  
  494.         DrawTool(tool);
  495.     }
  496. }
  497.  
  498. // ----------------------------------------------------------------------------
  499. // drawing
  500. // ----------------------------------------------------------------------------
  501.  
  502. void wxToolBarSimple::DrawTool(wxToolBarToolBase *tool)
  503. {
  504.     wxClientDC dc(this);
  505.     DrawTool(dc, tool);
  506. }
  507.  
  508. void wxToolBarSimple::DrawTool(wxDC& dc, wxToolBarToolBase *toolBase)
  509. {
  510.     wxToolBarToolSimple *tool = (wxToolBarToolSimple *)toolBase;
  511.  
  512.     wxMemoryDC memDC;
  513.     PrepareDC(dc);
  514.  
  515.     wxPen dark_grey_pen(wxColour( 85,85,85 ), 1, wxSOLID);
  516.     wxPen white_pen(wxT("WHITE"), 1, wxSOLID);
  517.     wxPen black_pen(wxT("BLACK"), 1, wxSOLID);
  518.  
  519.     wxBitmap bitmap = tool->GetNormalBitmap();
  520.     if (!bitmap.Ok())
  521.         return;
  522.  
  523.     if ( !tool->IsToggled() )
  524.     {
  525. #if wxUSE_PALETTE
  526. #ifndef __WXGTK__
  527.         if (bitmap.GetPalette())
  528.             memDC.SetPalette(*bitmap.GetPalette());
  529. #endif
  530. #endif // wxUSE_PALETTE
  531.  
  532.         int ax = (int)tool->m_x,
  533.         ay = (int)tool->m_y,
  534.         bx = (int)(tool->m_x+tool->GetWidth()),
  535.         by = (int)(tool->m_y+tool->GetHeight());
  536.  
  537.         memDC.SelectObject(bitmap);
  538.         if (m_windowStyle & wxTB_3DBUTTONS)
  539.         {
  540.             dc.SetClippingRegion(ax, ay, (bx-ax+1), (by-ay+1));
  541.             dc.Blit((ax+1), (ay+1), (bx-ax-2), (by-ay-2), &memDC, 0, 0);
  542.             wxPen * old_pen = & dc.GetPen();
  543.             dc.SetPen( white_pen );
  544.             dc.DrawLine(ax,(by-1),ax,ay);
  545.             dc.DrawLine(ax,ay,(bx-1),ay);
  546.             dc.SetPen( dark_grey_pen );
  547.             dc.DrawLine((bx-1),(ay+1),(bx-1),(by-1));
  548.             dc.DrawLine((bx-1),(by-1),(ax+1),(by-1));
  549.             dc.SetPen( black_pen );
  550.             dc.DrawLine(bx,ay,bx,by);
  551.             dc.DrawLine(bx,by,ax,by);
  552.             dc.SetPen( *old_pen );
  553.             dc.DestroyClippingRegion();
  554.             // Select bitmap out of the DC
  555.         }
  556.         else
  557.         {
  558.             dc.Blit(tool->m_x, tool->m_y,
  559.                     bitmap.GetWidth(), bitmap.GetHeight(),
  560.                     &memDC, 0, 0);
  561.         }
  562.         memDC.SelectObject(wxNullBitmap);
  563.  
  564. #if wxUSE_PALETTE
  565. #ifndef __WXGTK__
  566.         if (bitmap.GetPalette())
  567.             memDC.SetPalette(wxNullPalette);
  568. #endif
  569. #endif // wxUSE_PALETTE
  570.     }
  571.     // No second bitmap, so draw a thick line around bitmap, or invert if mono
  572.     else if ( tool->IsToggled() )
  573.     {
  574.         bool drawBorder = FALSE;
  575. #ifdef __X__ // X doesn't invert properly on colour
  576.         drawBorder = wxColourDisplay();
  577. #else       // Inversion works fine under Windows
  578.         drawBorder = FALSE;
  579. #endif
  580.  
  581.         if (!drawBorder)
  582.         {
  583.             memDC.SelectObject(tool->GetNormalBitmap());
  584.             dc.Blit(tool->m_x, tool->m_y, tool->GetWidth(), tool->GetHeight(),
  585.                     &memDC, 0, 0, wxSRC_INVERT);
  586.             memDC.SelectObject(wxNullBitmap);
  587.         }
  588.         else
  589.         {
  590.             bitmap = tool->GetNormalBitmap();
  591.  
  592.             if (m_windowStyle & wxTB_3DBUTTONS)
  593.             {
  594.                 int ax = (int)tool->m_x,
  595.                 ay = (int)tool->m_y,
  596.                 bx = (int)(tool->m_x+tool->GetWidth()),
  597.                 by = (int)(tool->m_y+tool->GetHeight());
  598.  
  599.                 memDC.SelectObject(bitmap);
  600.                 dc.SetClippingRegion(ax, ay, (bx-ax+1), (by-ay+1));
  601.                 dc.Blit((ax+2), (ay+2), (bx-ax-2), (by-ay-2), &memDC, 0, 0);
  602.                 wxPen * old_pen = & dc.GetPen();
  603.                 dc.SetPen( black_pen );
  604.                 dc.DrawLine(ax,(by-1),ax,ay);
  605.                 dc.DrawLine(ax,ay,(bx-1),ay);
  606.                 dc.SetPen( dark_grey_pen );
  607.                 dc.DrawLine((ax+1),(by-2),(ax+1),(ay+1));
  608.                 dc.DrawLine((ax+1),(ay+1),(bx-2),(ay+1));
  609.                 dc.SetPen( white_pen );
  610.                 dc.DrawLine(bx,ay,bx,by);
  611.                 dc.DrawLine(bx,by,ax,by);
  612.                 dc.SetPen( *old_pen );
  613.                 dc.DestroyClippingRegion();
  614.                 memDC.SelectObject(wxNullBitmap);
  615.             }
  616.             else
  617.             {
  618.                 wxCoord x = tool->m_x;
  619.                 wxCoord y = tool->m_y;
  620.                 wxCoord w = bitmap.GetWidth();
  621.                 wxCoord h = bitmap.GetHeight();
  622.                 wxPen thick_black_pen(wxT("BLACK"), 3, wxSOLID);
  623.  
  624.                 memDC.SelectObject(bitmap);
  625.                 dc.SetClippingRegion(tool->m_x, tool->m_y, w, h);
  626.                 dc.Blit(tool->m_x, tool->m_y, w, h,
  627.                         &memDC, 0, 0);
  628.                 dc.SetPen(thick_black_pen);
  629.                 dc.SetBrush(*wxTRANSPARENT_BRUSH);
  630.                 dc.DrawRectangle(x, y, w-1, h-1);
  631.                 dc.DestroyClippingRegion();
  632.                 memDC.SelectObject(wxNullBitmap);
  633.             }
  634.         }
  635.     }
  636. }
  637.  
  638. // ----------------------------------------------------------------------------
  639. // toolbar geometry
  640. // ----------------------------------------------------------------------------
  641.  
  642. void wxToolBarSimple::SetRows(int nRows)
  643. {
  644.     wxCHECK_RET( nRows != 0, _T("max number of rows must be > 0") );
  645.  
  646.     m_maxCols = (GetToolsCount() + nRows - 1) / nRows;
  647.  
  648.     AdjustScrollbars();
  649.     Refresh();
  650. }
  651.  
  652. wxToolBarToolBase *wxToolBarSimple::FindToolForPosition(wxCoord x,
  653.                                                         wxCoord y) const
  654. {
  655.     wxToolBarToolsList::Node *node = m_tools.GetFirst();
  656.     while (node)
  657.     {
  658.         wxToolBarToolSimple *tool = (wxToolBarToolSimple *)node->GetData();
  659.         if ((x >= tool->m_x) && (y >= tool->m_y) &&
  660.             (x <= (tool->m_x + tool->GetWidth())) &&
  661.             (y <= (tool->m_y + tool->GetHeight())))
  662.         {
  663.             return tool;
  664.         }
  665.  
  666.         node = node->GetNext();
  667.     }
  668.  
  669.     return (wxToolBarToolBase *)NULL;
  670. }
  671.  
  672. // ----------------------------------------------------------------------------
  673. // tool state change handlers
  674. // ----------------------------------------------------------------------------
  675.  
  676. void wxToolBarSimple::DoEnableTool(wxToolBarToolBase *tool,
  677.                                    bool WXUNUSED(enable))
  678. {
  679.     DrawTool(tool);
  680. }
  681.  
  682. void wxToolBarSimple::DoToggleTool(wxToolBarToolBase *tool,
  683.                                    bool WXUNUSED(toggle))
  684. {
  685.     DrawTool(tool);
  686. }
  687.  
  688. void wxToolBarSimple::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool),
  689.                                   bool WXUNUSED(toggle))
  690. {
  691.     // nothing to do
  692. }
  693.  
  694. // Okay, so we've left the tool we're in ... we must check if the tool we're
  695. // leaving was a 'sprung push button' and if so, spring it back to the up
  696. // state.
  697. void wxToolBarSimple::SpringUpButton(int id)
  698. {
  699.     wxToolBarToolBase *tool = FindById(id);
  700.  
  701.     if ( tool && tool->CanBeToggled() )
  702.     {
  703.         if (tool->IsToggled())
  704.             tool->Toggle();
  705.  
  706.         DrawTool(tool);
  707.     }
  708. }
  709.  
  710. // ----------------------------------------------------------------------------
  711. // scrolling implementation
  712. // ----------------------------------------------------------------------------
  713.  
  714. /*
  715.  * pixelsPerUnitX/pixelsPerUnitY: number of pixels per unit (e.g. pixels per text line)
  716.  * noUnitsX/noUnitsY:        : no. units per scrollbar
  717.  */
  718. void wxToolBarSimple::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY,
  719.                                    int noUnitsX, int noUnitsY,
  720.                                    int xPos, int yPos)
  721. {
  722.     m_xScrollPixelsPerLine = pixelsPerUnitX;
  723.     m_yScrollPixelsPerLine = pixelsPerUnitY;
  724.     m_xScrollLines = noUnitsX;
  725.     m_yScrollLines = noUnitsY;
  726.  
  727.     int w, h;
  728.     GetSize(&w, &h);
  729.  
  730.     // Recalculate scroll bar range and position
  731.     if (m_xScrollLines > 0)
  732.     {
  733.         m_xScrollPosition = xPos;
  734.         SetScrollPos (wxHORIZONTAL, m_xScrollPosition, TRUE);
  735.     }
  736.     else
  737.     {
  738.         SetScrollbar(wxHORIZONTAL, 0, 0, 0, FALSE);
  739.         m_xScrollPosition = 0;
  740.     }
  741.  
  742.     if (m_yScrollLines > 0)
  743.     {
  744.         m_yScrollPosition = yPos;
  745.         SetScrollPos (wxVERTICAL, m_yScrollPosition, TRUE);
  746.     }
  747.     else
  748.     {
  749.         SetScrollbar(wxVERTICAL, 0, 0, 0, FALSE);
  750.         m_yScrollPosition = 0;
  751.     }
  752.     AdjustScrollbars();
  753.     Refresh();
  754.  
  755. #if 0 //def __WXMSW__
  756.     ::UpdateWindow ((HWND) GetHWND());
  757. #endif
  758. }
  759.  
  760. void wxToolBarSimple::OnScroll(wxScrollEvent& event)
  761. {
  762.     int orient = event.GetOrientation();
  763.  
  764.     int nScrollInc = CalcScrollInc(event);
  765.     if (nScrollInc == 0)
  766.         return;
  767.  
  768.     if (orient == wxHORIZONTAL)
  769.     {
  770.         int newPos = m_xScrollPosition + nScrollInc;
  771.         SetScrollPos(wxHORIZONTAL, newPos, TRUE );
  772.     }
  773.     else
  774.     {
  775.         int newPos = m_yScrollPosition + nScrollInc;
  776.         SetScrollPos(wxVERTICAL, newPos, TRUE );
  777.     }
  778.  
  779.     if (orient == wxHORIZONTAL)
  780.     {
  781.         if (m_xScrollingEnabled)
  782.             ScrollWindow(-m_xScrollPixelsPerLine * nScrollInc, 0, NULL);
  783.         else
  784.             Refresh();
  785.     }
  786.     else
  787.     {
  788.         if (m_yScrollingEnabled)
  789.             ScrollWindow(0, -m_yScrollPixelsPerLine * nScrollInc, NULL);
  790.         else
  791.             Refresh();
  792.     }
  793.  
  794.     if (orient == wxHORIZONTAL)
  795.     {
  796.         m_xScrollPosition += nScrollInc;
  797.     }
  798.     else
  799.     {
  800.         m_yScrollPosition += nScrollInc;
  801.     }
  802.  
  803. }
  804.  
  805. int wxToolBarSimple::CalcScrollInc(wxScrollEvent& event)
  806. {
  807.     int pos = event.GetPosition();
  808.     int orient = event.GetOrientation();
  809.  
  810.     int nScrollInc = 0;
  811.     if (event.GetEventType() == wxEVT_SCROLL_TOP)
  812.     {
  813.             if (orient == wxHORIZONTAL)
  814.                 nScrollInc = - m_xScrollPosition;
  815.             else
  816.                 nScrollInc = - m_yScrollPosition;
  817.     } else
  818.     if (event.GetEventType() == wxEVT_SCROLL_BOTTOM)
  819.     {
  820.             if (orient == wxHORIZONTAL)
  821.                 nScrollInc = m_xScrollLines - m_xScrollPosition;
  822.             else
  823.                 nScrollInc = m_yScrollLines - m_yScrollPosition;
  824.     } else
  825.     if (event.GetEventType() == wxEVT_SCROLL_LINEUP)
  826.     {
  827.             nScrollInc = -1;
  828.     } else
  829.     if (event.GetEventType() == wxEVT_SCROLL_LINEDOWN)
  830.     {
  831.             nScrollInc = 1;
  832.     } else
  833.     if (event.GetEventType() == wxEVT_SCROLL_PAGEUP)
  834.     {
  835.             if (orient == wxHORIZONTAL)
  836.                 nScrollInc = -GetScrollPageSize(wxHORIZONTAL);
  837.             else
  838.                 nScrollInc = -GetScrollPageSize(wxVERTICAL);
  839.     } else
  840.     if (event.GetEventType() == wxEVT_SCROLL_PAGEDOWN)
  841.     {
  842.             if (orient == wxHORIZONTAL)
  843.                 nScrollInc = GetScrollPageSize(wxHORIZONTAL);
  844.             else
  845.                 nScrollInc = GetScrollPageSize(wxVERTICAL);
  846.     } else
  847.     if ((event.GetEventType() == wxEVT_SCROLL_THUMBTRACK) ||
  848.         (event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE))
  849.     {
  850.             if (orient == wxHORIZONTAL)
  851.                 nScrollInc = pos - m_xScrollPosition;
  852.             else
  853.                 nScrollInc = pos - m_yScrollPosition;
  854.     }
  855.     
  856.     if (orient == wxHORIZONTAL)
  857.     {
  858.         int w, h;
  859.         GetClientSize(&w, &h);
  860.  
  861.         int nMaxWidth = m_xScrollLines*m_xScrollPixelsPerLine;
  862.         int noPositions = (int) ( ((nMaxWidth - w)/(float)m_xScrollPixelsPerLine) + 0.5 );
  863.         if (noPositions < 0)
  864.             noPositions = 0;
  865.  
  866.         if ( (m_xScrollPosition + nScrollInc) < 0 )
  867.             nScrollInc = -m_xScrollPosition; // As -ve as we can go
  868.         else if ( (m_xScrollPosition + nScrollInc) > noPositions )
  869.             nScrollInc = noPositions - m_xScrollPosition; // As +ve as we can go
  870.  
  871.         return nScrollInc;
  872.     }
  873.     else
  874.     {
  875.         int w, h;
  876.         GetClientSize(&w, &h);
  877.  
  878.         int nMaxHeight = m_yScrollLines*m_yScrollPixelsPerLine;
  879.         int noPositions = (int) ( ((nMaxHeight - h)/(float)m_yScrollPixelsPerLine) + 0.5 );
  880.         if (noPositions < 0)
  881.             noPositions = 0;
  882.  
  883.         if ( (m_yScrollPosition + nScrollInc) < 0 )
  884.             nScrollInc = -m_yScrollPosition; // As -ve as we can go
  885.         else if ( (m_yScrollPosition + nScrollInc) > noPositions )
  886.             nScrollInc = noPositions - m_yScrollPosition; // As +ve as we can go
  887.  
  888.         return nScrollInc;
  889.     }
  890. }
  891.  
  892. // Adjust the scrollbars - new version.
  893. void wxToolBarSimple::AdjustScrollbars()
  894. {
  895.     int w, h;
  896.     GetClientSize(&w, &h);
  897.  
  898.     // Recalculate scroll bar range and position
  899.     if (m_xScrollLines > 0)
  900.     {
  901.         int nMaxWidth = m_xScrollLines*m_xScrollPixelsPerLine;
  902.         int newRange = (int) ( ((nMaxWidth)/(float)m_xScrollPixelsPerLine) + 0.5 );
  903.         if (newRange < 0)
  904.             newRange = 0;
  905.  
  906.         m_xScrollPosition = wxMin(newRange, m_xScrollPosition);
  907.  
  908.         // Calculate page size i.e. number of scroll units you get on the
  909.         // current client window
  910.         int noPagePositions = (int) ( (w/(float)m_xScrollPixelsPerLine) + 0.5 );
  911.         if (noPagePositions < 1)
  912.             noPagePositions = 1;
  913.  
  914.         SetScrollbar(wxHORIZONTAL, m_xScrollPosition, noPagePositions, newRange);
  915.         SetScrollPageSize(wxHORIZONTAL, noPagePositions);
  916.     }
  917.     if (m_yScrollLines > 0)
  918.     {
  919.         int nMaxHeight = m_yScrollLines*m_yScrollPixelsPerLine;
  920.         int newRange = (int) ( ((nMaxHeight)/(float)m_yScrollPixelsPerLine) + 0.5 );
  921.         if (newRange < 0)
  922.             newRange = 0;
  923.  
  924.         m_yScrollPosition = wxMin(newRange, m_yScrollPosition);
  925.  
  926.         // Calculate page size i.e. number of scroll units you get on the
  927.         // current client window
  928.         int noPagePositions = (int) ( (h/(float)m_yScrollPixelsPerLine) + 0.5 );
  929.         if (noPagePositions < 1)
  930.             noPagePositions = 1;
  931.  
  932.         SetScrollbar(wxVERTICAL, m_yScrollPosition, noPagePositions, newRange);
  933.         SetScrollPageSize(wxVERTICAL, noPagePositions);
  934.     }
  935. }
  936.  
  937. // Prepare the DC by translating it according to the current scroll position
  938. void wxToolBarSimple::PrepareDC(wxDC& dc)
  939. {
  940.     dc.SetDeviceOrigin(- m_xScrollPosition * m_xScrollPixelsPerLine, - m_yScrollPosition * m_yScrollPixelsPerLine);
  941. }
  942.  
  943. void wxToolBarSimple::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const
  944. {
  945.       *x_unit = m_xScrollPixelsPerLine;
  946.       *y_unit = m_yScrollPixelsPerLine;
  947. }
  948.  
  949. int wxToolBarSimple::GetScrollPageSize(int orient) const
  950. {
  951.     if ( orient == wxHORIZONTAL )
  952.         return m_xScrollLinesPerPage;
  953.     else
  954.         return m_yScrollLinesPerPage;
  955. }
  956.  
  957. void wxToolBarSimple::SetScrollPageSize(int orient, int pageSize)
  958. {
  959.     if ( orient == wxHORIZONTAL )
  960.         m_xScrollLinesPerPage = pageSize;
  961.     else
  962.         m_yScrollLinesPerPage = pageSize;
  963. }
  964.  
  965. /*
  966.  * Scroll to given position (scroll position, not pixel position)
  967.  */
  968. void wxToolBarSimple::Scroll (int x_pos, int y_pos)
  969. {
  970.     int old_x, old_y;
  971.     ViewStart (&old_x, &old_y);
  972.     if (((x_pos == -1) || (x_pos == old_x)) && ((y_pos == -1) || (y_pos == old_y)))
  973.         return;
  974.  
  975.     if (x_pos > -1)
  976.     {
  977.         m_xScrollPosition = x_pos;
  978.         SetScrollPos (wxHORIZONTAL, x_pos, TRUE);
  979.     }
  980.     if (y_pos > -1)
  981.     {
  982.         m_yScrollPosition = y_pos;
  983.         SetScrollPos (wxVERTICAL, y_pos, TRUE);
  984.     }
  985.     Refresh();
  986.  
  987. #if 0 //def __WXMSW__
  988.     UpdateWindow ((HWND) GetHWND());
  989. #endif
  990. }
  991.  
  992. void wxToolBarSimple::EnableScrolling (bool x_scroll, bool y_scroll)
  993. {
  994.     m_xScrollingEnabled = x_scroll;
  995.     m_yScrollingEnabled = y_scroll;
  996. }
  997.  
  998. void wxToolBarSimple::GetVirtualSize (int *x, int *y) const
  999. {
  1000.     *x = m_xScrollPixelsPerLine * m_xScrollLines;
  1001.     *y = m_yScrollPixelsPerLine * m_yScrollLines;
  1002. }
  1003.  
  1004. // Where the current view starts from
  1005. void wxToolBarSimple::ViewStart (int *x, int *y) const
  1006. {
  1007.     *x = m_xScrollPosition;
  1008.     *y = m_yScrollPosition;
  1009. }
  1010.  
  1011. #endif // wxUSE_TOOLBAR_SIMPLE
  1012.