home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / src / generic / tbarsmpl.cpp < prev    next >
C/C++ Source or Header  |  2002-04-08  |  30KB  |  1,010 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 2002/04/08 10:50:14 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 !wxUSE_TOOLBAR_NATIVE
  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_maxWidth += maxToolWidth;
  360.     else
  361.         m_maxHeight += maxToolHeight;
  362.  
  363.     m_maxWidth += m_xMargin;
  364.     m_maxHeight += m_yMargin;
  365.  
  366.     return TRUE;
  367. }
  368.  
  369. // ----------------------------------------------------------------------------
  370. // event handlers
  371. // ----------------------------------------------------------------------------
  372.  
  373. void wxToolBarSimple::OnPaint (wxPaintEvent& WXUNUSED(event))
  374. {
  375.     wxPaintDC dc(this);
  376.     PrepareDC(dc);
  377.  
  378.     static int count = 0;
  379.     // Prevent reentry of OnPaint which would cause wxMemoryDC errors.
  380.     if ( count > 0 )
  381.         return;
  382.     count++;
  383.  
  384.     for ( wxToolBarToolsList::Node *node = m_tools.GetFirst();
  385.           node;
  386.           node = node->GetNext() )
  387.     {
  388.         wxToolBarToolBase *tool = node->GetData();
  389.         if ( tool->IsButton() )
  390.             DrawTool(dc, tool);
  391.     }
  392.  
  393.     count--;
  394. }
  395.  
  396. void wxToolBarSimple::OnSize (wxSizeEvent& WXUNUSED(event))
  397. {
  398. #if wxUSE_CONSTRAINTS
  399.     if (GetAutoLayout())
  400.         Layout();
  401. #endif
  402.  
  403.     AdjustScrollbars();
  404. }
  405.  
  406. void wxToolBarSimple::OnKillFocus(wxFocusEvent& WXUNUSED(event))
  407. {
  408.     OnMouseEnter(m_pressedTool = m_currentTool = -1);
  409. }
  410.  
  411. void wxToolBarSimple::OnMouseEvent(wxMouseEvent & event)
  412. {
  413.     wxCoord x, y;
  414.     event.GetPosition(&x, &y);
  415.     wxToolBarToolSimple *tool = (wxToolBarToolSimple *)FindToolForPosition(x, y);
  416.  
  417.     if (event.LeftDown())
  418.     {
  419.         CaptureMouse();
  420.     }
  421.     if (event.LeftUp())
  422.     {
  423.         ReleaseMouse();
  424.     }
  425.  
  426.     if (!tool)
  427.     {
  428.         if (m_currentTool > -1)
  429.         {
  430.             if (event.LeftIsDown())
  431.                 SpringUpButton(m_currentTool);
  432.             m_currentTool = -1;
  433.             OnMouseEnter(-1);
  434.         }
  435.         return;
  436.     }
  437.  
  438.     if (!event.IsButton())
  439.     {
  440.         if ( tool->GetId() != m_currentTool )
  441.         {
  442.             // If the left button is kept down and moved over buttons,
  443.             // press those buttons.
  444.             if ( event.LeftIsDown() && tool->IsEnabled() )
  445.             {
  446.                 SpringUpButton(m_currentTool);
  447.  
  448.                 if ( tool->CanBeToggled() )
  449.                 {
  450.                     tool->Toggle();
  451.                 }
  452.  
  453.                 DrawTool(tool);
  454.             }
  455.  
  456.             m_currentTool = tool->GetId();
  457.             OnMouseEnter(m_currentTool);
  458.         }
  459.         return;
  460.     }
  461.  
  462.     // Left button pressed.
  463.     if ( event.LeftDown() && tool->IsEnabled() )
  464.     {
  465.         if ( tool->CanBeToggled() )
  466.         {
  467.             tool->Toggle();
  468.         }
  469.  
  470.         DrawTool(tool);
  471.     }
  472.     else if (event.RightDown())
  473.     {
  474.         OnRightClick(tool->GetId(), x, y);
  475.     }
  476.  
  477.     // Left Button Released.  Only this action confirms selection.
  478.     // If the button is enabled and it is not a toggle tool and it is
  479.     // in the pressed state, then raise the button and call OnLeftClick.
  480.     //
  481.     if ( event.LeftUp() && tool->IsEnabled() )
  482.     {
  483.         // Pass the OnLeftClick event to tool
  484.         if ( !OnLeftClick(tool->GetId(), tool->IsToggled()) &&
  485.                           tool->CanBeToggled() )
  486.         {
  487.             // If it was a toggle, and OnLeftClick says No Toggle allowed,
  488.             // then change it back
  489.             tool->Toggle();
  490.         }
  491.  
  492.         DrawTool(tool);
  493.     }
  494. }
  495.  
  496. // ----------------------------------------------------------------------------
  497. // drawing
  498. // ----------------------------------------------------------------------------
  499.  
  500. void wxToolBarSimple::DrawTool(wxToolBarToolBase *tool)
  501. {
  502.     wxClientDC dc(this);
  503.     DrawTool(dc, tool);
  504. }
  505.  
  506. void wxToolBarSimple::DrawTool(wxDC& dc, wxToolBarToolBase *toolBase)
  507. {
  508.     wxToolBarToolSimple *tool = (wxToolBarToolSimple *)toolBase;
  509.  
  510.     wxMemoryDC memDC;
  511.     PrepareDC(dc);
  512.  
  513.     wxPen dark_grey_pen(wxColour( 85,85,85 ), 1, wxSOLID);
  514.     wxPen white_pen(wxT("WHITE"), 1, wxSOLID);
  515.     wxPen black_pen(wxT("BLACK"), 1, wxSOLID);
  516.  
  517.     wxBitmap bitmap = tool->GetNormalBitmap();
  518.     if (!bitmap.Ok())
  519.         return;
  520.  
  521.     if ( !tool->IsToggled() )
  522.     {
  523. #if wxUSE_PALETTE
  524. #ifndef __WXGTK__
  525.         if (bitmap.GetPalette())
  526.             memDC.SetPalette(*bitmap.GetPalette());
  527. #endif
  528. #endif // wxUSE_PALETTE
  529.  
  530.         int ax = (int)tool->m_x,
  531.         ay = (int)tool->m_y,
  532.         bx = (int)(tool->m_x+tool->GetWidth()),
  533.         by = (int)(tool->m_y+tool->GetHeight());
  534.  
  535.         memDC.SelectObject(bitmap);
  536.         if (m_windowStyle & wxTB_3DBUTTONS)
  537.         {
  538.             dc.SetClippingRegion(ax, ay, (bx-ax+1), (by-ay+1));
  539.             dc.Blit((ax+1), (ay+1), (bx-ax-2), (by-ay-2), &memDC, 0, 0);
  540.             wxPen * old_pen = & dc.GetPen();
  541.             dc.SetPen( white_pen );
  542.             dc.DrawLine(ax,(by-1),ax,ay);
  543.             dc.DrawLine(ax,ay,(bx-1),ay);
  544.             dc.SetPen( dark_grey_pen );
  545.             dc.DrawLine((bx-1),(ay+1),(bx-1),(by-1));
  546.             dc.DrawLine((bx-1),(by-1),(ax+1),(by-1));
  547.             dc.SetPen( black_pen );
  548.             dc.DrawLine(bx,ay,bx,by);
  549.             dc.DrawLine(bx,by,ax,by);
  550.             dc.SetPen( *old_pen );
  551.             dc.DestroyClippingRegion();
  552.             // Select bitmap out of the DC
  553.         }
  554.         else
  555.         {
  556.             dc.Blit(tool->m_x, tool->m_y,
  557.                     bitmap.GetWidth(), bitmap.GetHeight(),
  558.                     &memDC, 0, 0);
  559.         }
  560.         memDC.SelectObject(wxNullBitmap);
  561.  
  562. #if wxUSE_PALETTE
  563. #ifndef __WXGTK__
  564.         if (bitmap.GetPalette())
  565.             memDC.SetPalette(wxNullPalette);
  566. #endif
  567. #endif // wxUSE_PALETTE
  568.     }
  569.     // No second bitmap, so draw a thick line around bitmap, or invert if mono
  570.     else if ( tool->IsToggled() )
  571.     {
  572.         bool drawBorder = FALSE;
  573. #ifdef __X__ // X doesn't invert properly on colour
  574.         drawBorder = wxColourDisplay();
  575. #else       // Inversion works fine under Windows
  576.         drawBorder = FALSE;
  577. #endif
  578.  
  579.         if (!drawBorder)
  580.         {
  581.             memDC.SelectObject(tool->GetNormalBitmap());
  582.             dc.Blit(tool->m_x, tool->m_y, tool->GetWidth(), tool->GetHeight(),
  583.                     &memDC, 0, 0, wxSRC_INVERT);
  584.             memDC.SelectObject(wxNullBitmap);
  585.         }
  586.         else
  587.         {
  588.             bitmap = tool->GetNormalBitmap();
  589.  
  590.             if (m_windowStyle & wxTB_3DBUTTONS)
  591.             {
  592.                 int ax = (int)tool->m_x,
  593.                 ay = (int)tool->m_y,
  594.                 bx = (int)(tool->m_x+tool->GetWidth()),
  595.                 by = (int)(tool->m_y+tool->GetHeight());
  596.  
  597.                 memDC.SelectObject(bitmap);
  598.                 dc.SetClippingRegion(ax, ay, (bx-ax+1), (by-ay+1));
  599.                 dc.Blit((ax+2), (ay+2), (bx-ax-2), (by-ay-2), &memDC, 0, 0);
  600.                 wxPen * old_pen = & dc.GetPen();
  601.                 dc.SetPen( black_pen );
  602.                 dc.DrawLine(ax,(by-1),ax,ay);
  603.                 dc.DrawLine(ax,ay,(bx-1),ay);
  604.                 dc.SetPen( dark_grey_pen );
  605.                 dc.DrawLine((ax+1),(by-2),(ax+1),(ay+1));
  606.                 dc.DrawLine((ax+1),(ay+1),(bx-2),(ay+1));
  607.                 dc.SetPen( white_pen );
  608.                 dc.DrawLine(bx,ay,bx,by);
  609.                 dc.DrawLine(bx,by,ax,by);
  610.                 dc.SetPen( *old_pen );
  611.                 dc.DestroyClippingRegion();
  612.                 memDC.SelectObject(wxNullBitmap);
  613.             }
  614.             else
  615.             {
  616.                 wxCoord x = tool->m_x;
  617.                 wxCoord y = tool->m_y;
  618.                 wxCoord w = bitmap.GetWidth();
  619.                 wxCoord h = bitmap.GetHeight();
  620.                 wxPen thick_black_pen(wxT("BLACK"), 3, wxSOLID);
  621.  
  622.                 memDC.SelectObject(bitmap);
  623.                 dc.SetClippingRegion(tool->m_x, tool->m_y, w, h);
  624.                 dc.Blit(tool->m_x, tool->m_y, w, h,
  625.                         &memDC, 0, 0);
  626.                 dc.SetPen(thick_black_pen);
  627.                 dc.SetBrush(*wxTRANSPARENT_BRUSH);
  628.                 dc.DrawRectangle(x, y, w-1, h-1);
  629.                 dc.DestroyClippingRegion();
  630.                 memDC.SelectObject(wxNullBitmap);
  631.             }
  632.         }
  633.     }
  634. }
  635.  
  636. // ----------------------------------------------------------------------------
  637. // toolbar geometry
  638. // ----------------------------------------------------------------------------
  639.  
  640. void wxToolBarSimple::SetRows(int nRows)
  641. {
  642.     wxCHECK_RET( nRows != 0, _T("max number of rows must be > 0") );
  643.  
  644.     m_maxCols = (GetToolsCount() + nRows - 1) / nRows;
  645.  
  646.     AdjustScrollbars();
  647.     Refresh();
  648. }
  649.  
  650. wxToolBarToolBase *wxToolBarSimple::FindToolForPosition(wxCoord x,
  651.                                                         wxCoord y) const
  652. {
  653.     wxToolBarToolsList::Node *node = m_tools.GetFirst();
  654.     while (node)
  655.     {
  656.         wxToolBarToolSimple *tool = (wxToolBarToolSimple *)node->GetData();
  657.         if ((x >= tool->m_x) && (y >= tool->m_y) &&
  658.             (x <= (tool->m_x + tool->GetWidth())) &&
  659.             (y <= (tool->m_y + tool->GetHeight())))
  660.         {
  661.             return tool;
  662.         }
  663.  
  664.         node = node->GetNext();
  665.     }
  666.  
  667.     return (wxToolBarToolBase *)NULL;
  668. }
  669.  
  670. // ----------------------------------------------------------------------------
  671. // tool state change handlers
  672. // ----------------------------------------------------------------------------
  673.  
  674. void wxToolBarSimple::DoEnableTool(wxToolBarToolBase *tool,
  675.                                    bool WXUNUSED(enable))
  676. {
  677.     DrawTool(tool);
  678. }
  679.  
  680. void wxToolBarSimple::DoToggleTool(wxToolBarToolBase *tool,
  681.                                    bool WXUNUSED(toggle))
  682. {
  683.     DrawTool(tool);
  684. }
  685.  
  686. void wxToolBarSimple::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool),
  687.                                   bool WXUNUSED(toggle))
  688. {
  689.     // nothing to do
  690. }
  691.  
  692. // Okay, so we've left the tool we're in ... we must check if the tool we're
  693. // leaving was a 'sprung push button' and if so, spring it back to the up
  694. // state.
  695. void wxToolBarSimple::SpringUpButton(int id)
  696. {
  697.     wxToolBarToolBase *tool = FindById(id);
  698.  
  699.     if ( tool && tool->CanBeToggled() )
  700.     {
  701.         if (tool->IsToggled())
  702.             tool->Toggle();
  703.  
  704.         DrawTool(tool);
  705.     }
  706. }
  707.  
  708. // ----------------------------------------------------------------------------
  709. // scrolling implementation
  710. // ----------------------------------------------------------------------------
  711.  
  712. /*
  713.  * pixelsPerUnitX/pixelsPerUnitY: number of pixels per unit (e.g. pixels per text line)
  714.  * noUnitsX/noUnitsY:        : no. units per scrollbar
  715.  */
  716. void wxToolBarSimple::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY,
  717.                                    int noUnitsX, int noUnitsY,
  718.                                    int xPos, int yPos)
  719. {
  720.     m_xScrollPixelsPerLine = pixelsPerUnitX;
  721.     m_yScrollPixelsPerLine = pixelsPerUnitY;
  722.     m_xScrollLines = noUnitsX;
  723.     m_yScrollLines = noUnitsY;
  724.  
  725.     int w, h;
  726.     GetSize(&w, &h);
  727.  
  728.     // Recalculate scroll bar range and position
  729.     if (m_xScrollLines > 0)
  730.     {
  731.         m_xScrollPosition = xPos;
  732.         SetScrollPos (wxHORIZONTAL, m_xScrollPosition, TRUE);
  733.     }
  734.     else
  735.     {
  736.         SetScrollbar(wxHORIZONTAL, 0, 0, 0, FALSE);
  737.         m_xScrollPosition = 0;
  738.     }
  739.  
  740.     if (m_yScrollLines > 0)
  741.     {
  742.         m_yScrollPosition = yPos;
  743.         SetScrollPos (wxVERTICAL, m_yScrollPosition, TRUE);
  744.     }
  745.     else
  746.     {
  747.         SetScrollbar(wxVERTICAL, 0, 0, 0, FALSE);
  748.         m_yScrollPosition = 0;
  749.     }
  750.     AdjustScrollbars();
  751.     Refresh();
  752.  
  753. #if 0 //def __WXMSW__
  754.     ::UpdateWindow ((HWND) GetHWND());
  755. #endif
  756. }
  757.  
  758. void wxToolBarSimple::OnScroll(wxScrollEvent& event)
  759. {
  760.     int orient = event.GetOrientation();
  761.  
  762.     int nScrollInc = CalcScrollInc(event);
  763.     if (nScrollInc == 0)
  764.         return;
  765.  
  766.     if (orient == wxHORIZONTAL)
  767.     {
  768.         int newPos = m_xScrollPosition + nScrollInc;
  769.         SetScrollPos(wxHORIZONTAL, newPos, TRUE );
  770.     }
  771.     else
  772.     {
  773.         int newPos = m_yScrollPosition + nScrollInc;
  774.         SetScrollPos(wxVERTICAL, newPos, TRUE );
  775.     }
  776.  
  777.     if (orient == wxHORIZONTAL)
  778.     {
  779.         if (m_xScrollingEnabled)
  780.             ScrollWindow(-m_xScrollPixelsPerLine * nScrollInc, 0, NULL);
  781.         else
  782.             Refresh();
  783.     }
  784.     else
  785.     {
  786.         if (m_yScrollingEnabled)
  787.             ScrollWindow(0, -m_yScrollPixelsPerLine * nScrollInc, NULL);
  788.         else
  789.             Refresh();
  790.     }
  791.  
  792.     if (orient == wxHORIZONTAL)
  793.     {
  794.         m_xScrollPosition += nScrollInc;
  795.     }
  796.     else
  797.     {
  798.         m_yScrollPosition += nScrollInc;
  799.     }
  800.  
  801. }
  802.  
  803. int wxToolBarSimple::CalcScrollInc(wxScrollEvent& event)
  804. {
  805.     int pos = event.GetPosition();
  806.     int orient = event.GetOrientation();
  807.  
  808.     int nScrollInc = 0;
  809.     if (event.GetEventType() == wxEVT_SCROLL_TOP)
  810.     {
  811.             if (orient == wxHORIZONTAL)
  812.                 nScrollInc = - m_xScrollPosition;
  813.             else
  814.                 nScrollInc = - m_yScrollPosition;
  815.     } else
  816.     if (event.GetEventType() == wxEVT_SCROLL_BOTTOM)
  817.     {
  818.             if (orient == wxHORIZONTAL)
  819.                 nScrollInc = m_xScrollLines - m_xScrollPosition;
  820.             else
  821.                 nScrollInc = m_yScrollLines - m_yScrollPosition;
  822.     } else
  823.     if (event.GetEventType() == wxEVT_SCROLL_LINEUP)
  824.     {
  825.             nScrollInc = -1;
  826.     } else
  827.     if (event.GetEventType() == wxEVT_SCROLL_LINEDOWN)
  828.     {
  829.             nScrollInc = 1;
  830.     } else
  831.     if (event.GetEventType() == wxEVT_SCROLL_PAGEUP)
  832.     {
  833.             if (orient == wxHORIZONTAL)
  834.                 nScrollInc = -GetScrollPageSize(wxHORIZONTAL);
  835.             else
  836.                 nScrollInc = -GetScrollPageSize(wxVERTICAL);
  837.     } else
  838.     if (event.GetEventType() == wxEVT_SCROLL_PAGEDOWN)
  839.     {
  840.             if (orient == wxHORIZONTAL)
  841.                 nScrollInc = GetScrollPageSize(wxHORIZONTAL);
  842.             else
  843.                 nScrollInc = GetScrollPageSize(wxVERTICAL);
  844.     } else
  845.     if ((event.GetEventType() == wxEVT_SCROLL_THUMBTRACK) ||
  846.         (event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE))
  847.     {
  848.             if (orient == wxHORIZONTAL)
  849.                 nScrollInc = pos - m_xScrollPosition;
  850.             else
  851.                 nScrollInc = pos - m_yScrollPosition;
  852.     }
  853.     
  854.     if (orient == wxHORIZONTAL)
  855.     {
  856.         int w, h;
  857.         GetClientSize(&w, &h);
  858.  
  859.         int nMaxWidth = m_xScrollLines*m_xScrollPixelsPerLine;
  860.         int noPositions = (int) ( ((nMaxWidth - w)/(float)m_xScrollPixelsPerLine) + 0.5 );
  861.         if (noPositions < 0)
  862.             noPositions = 0;
  863.  
  864.         if ( (m_xScrollPosition + nScrollInc) < 0 )
  865.             nScrollInc = -m_xScrollPosition; // As -ve as we can go
  866.         else if ( (m_xScrollPosition + nScrollInc) > noPositions )
  867.             nScrollInc = noPositions - m_xScrollPosition; // As +ve as we can go
  868.  
  869.         return nScrollInc;
  870.     }
  871.     else
  872.     {
  873.         int w, h;
  874.         GetClientSize(&w, &h);
  875.  
  876.         int nMaxHeight = m_yScrollLines*m_yScrollPixelsPerLine;
  877.         int noPositions = (int) ( ((nMaxHeight - h)/(float)m_yScrollPixelsPerLine) + 0.5 );
  878.         if (noPositions < 0)
  879.             noPositions = 0;
  880.  
  881.         if ( (m_yScrollPosition + nScrollInc) < 0 )
  882.             nScrollInc = -m_yScrollPosition; // As -ve as we can go
  883.         else if ( (m_yScrollPosition + nScrollInc) > noPositions )
  884.             nScrollInc = noPositions - m_yScrollPosition; // As +ve as we can go
  885.  
  886.         return nScrollInc;
  887.     }
  888. }
  889.  
  890. // Adjust the scrollbars - new version.
  891. void wxToolBarSimple::AdjustScrollbars()
  892. {
  893.     int w, h;
  894.     GetClientSize(&w, &h);
  895.  
  896.     // Recalculate scroll bar range and position
  897.     if (m_xScrollLines > 0)
  898.     {
  899.         int nMaxWidth = m_xScrollLines*m_xScrollPixelsPerLine;
  900.         int newRange = (int) ( ((nMaxWidth)/(float)m_xScrollPixelsPerLine) + 0.5 );
  901.         if (newRange < 0)
  902.             newRange = 0;
  903.  
  904.         m_xScrollPosition = wxMin(newRange, m_xScrollPosition);
  905.  
  906.         // Calculate page size i.e. number of scroll units you get on the
  907.         // current client window
  908.         int noPagePositions = (int) ( (w/(float)m_xScrollPixelsPerLine) + 0.5 );
  909.         if (noPagePositions < 1)
  910.             noPagePositions = 1;
  911.  
  912.         SetScrollbar(wxHORIZONTAL, m_xScrollPosition, noPagePositions, newRange);
  913.         SetScrollPageSize(wxHORIZONTAL, noPagePositions);
  914.     }
  915.     if (m_yScrollLines > 0)
  916.     {
  917.         int nMaxHeight = m_yScrollLines*m_yScrollPixelsPerLine;
  918.         int newRange = (int) ( ((nMaxHeight)/(float)m_yScrollPixelsPerLine) + 0.5 );
  919.         if (newRange < 0)
  920.             newRange = 0;
  921.  
  922.         m_yScrollPosition = wxMin(newRange, m_yScrollPosition);
  923.  
  924.         // Calculate page size i.e. number of scroll units you get on the
  925.         // current client window
  926.         int noPagePositions = (int) ( (h/(float)m_yScrollPixelsPerLine) + 0.5 );
  927.         if (noPagePositions < 1)
  928.             noPagePositions = 1;
  929.  
  930.         SetScrollbar(wxVERTICAL, m_yScrollPosition, noPagePositions, newRange);
  931.         SetScrollPageSize(wxVERTICAL, noPagePositions);
  932.     }
  933. }
  934.  
  935. // Prepare the DC by translating it according to the current scroll position
  936. void wxToolBarSimple::PrepareDC(wxDC& dc)
  937. {
  938.     dc.SetDeviceOrigin(- m_xScrollPosition * m_xScrollPixelsPerLine, - m_yScrollPosition * m_yScrollPixelsPerLine);
  939. }
  940.  
  941. void wxToolBarSimple::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const
  942. {
  943.       *x_unit = m_xScrollPixelsPerLine;
  944.       *y_unit = m_yScrollPixelsPerLine;
  945. }
  946.  
  947. int wxToolBarSimple::GetScrollPageSize(int orient) const
  948. {
  949.     if ( orient == wxHORIZONTAL )
  950.         return m_xScrollLinesPerPage;
  951.     else
  952.         return m_yScrollLinesPerPage;
  953. }
  954.  
  955. void wxToolBarSimple::SetScrollPageSize(int orient, int pageSize)
  956. {
  957.     if ( orient == wxHORIZONTAL )
  958.         m_xScrollLinesPerPage = pageSize;
  959.     else
  960.         m_yScrollLinesPerPage = pageSize;
  961. }
  962.  
  963. /*
  964.  * Scroll to given position (scroll position, not pixel position)
  965.  */
  966. void wxToolBarSimple::Scroll (int x_pos, int y_pos)
  967. {
  968.     int old_x, old_y;
  969.     ViewStart (&old_x, &old_y);
  970.     if (((x_pos == -1) || (x_pos == old_x)) && ((y_pos == -1) || (y_pos == old_y)))
  971.         return;
  972.  
  973.     if (x_pos > -1)
  974.     {
  975.         m_xScrollPosition = x_pos;
  976.         SetScrollPos (wxHORIZONTAL, x_pos, TRUE);
  977.     }
  978.     if (y_pos > -1)
  979.     {
  980.         m_yScrollPosition = y_pos;
  981.         SetScrollPos (wxVERTICAL, y_pos, TRUE);
  982.     }
  983.     Refresh();
  984.  
  985. #if 0 //def __WXMSW__
  986.     UpdateWindow ((HWND) GetHWND());
  987. #endif
  988. }
  989.  
  990. void wxToolBarSimple::EnableScrolling (bool x_scroll, bool y_scroll)
  991. {
  992.     m_xScrollingEnabled = x_scroll;
  993.     m_yScrollingEnabled = y_scroll;
  994. }
  995.  
  996. void wxToolBarSimple::GetVirtualSize (int *x, int *y) const
  997. {
  998.     *x = m_xScrollPixelsPerLine * m_xScrollLines;
  999.     *y = m_yScrollPixelsPerLine * m_yScrollLines;
  1000. }
  1001.  
  1002. // Where the current view starts from
  1003. void wxToolBarSimple::ViewStart (int *x, int *y) const
  1004. {
  1005.     *x = m_xScrollPosition;
  1006.     *y = m_yScrollPosition;
  1007. }
  1008.  
  1009. #endif // wxUSE_TOOLBAR_SIMPLE
  1010.