home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / contrib / src / fl / dyntbar.cpp < prev    next >
C/C++ Source or Header  |  2002-03-29  |  17KB  |  609 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        dyntbar.cpp
  3. // Purpose:     wxDynamicToolBar implementation
  4. // Author:      Aleksandras Gluchovas
  5. // Modified by:
  6. // Created:     ??/10/98
  7. // RCS-ID:      $Id: dyntbar.cpp,v 1.8 2002/03/29 09:39:18 VZ Exp $
  8. // Copyright:   (c) Aleksandras Gluchovas
  9. // Licence:       wxWindows license
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #ifdef __GNUG__
  13.     #pragma implementation "dyntbar.h"
  14. #endif
  15.  
  16. // For compilers that support precompilation, includes "wx/wx.h".
  17. #include "wx/wxprec.h"
  18.  
  19. #ifdef __BORLANDC__
  20. #pragma hdrstop
  21. #endif
  22.  
  23. #ifndef WX_PRECOMP
  24. #include "wx/wx.h"
  25. #endif
  26.  
  27. #include "wx/utils.h"     // import wxMin,wxMax macros
  28.  
  29. #include "wx/fl/dyntbar.h"
  30. #include "wx/fl/newbmpbtn.h"
  31.  
  32. IMPLEMENT_DYNAMIC_CLASS( wxDynamicToolBar, wxToolBarBase )
  33.  
  34. BEGIN_EVENT_TABLE( wxDynamicToolBar, wxToolBarBase )
  35.  
  36.     EVT_SIZE ( wxDynamicToolBar::OnSize  )
  37.     EVT_PAINT( wxDynamicToolBar::OnPaint )
  38.     //EVT_ERASE_BACKGROUND( wxDynamicToolBar::OnEraseBackground )
  39.  
  40. END_EVENT_TABLE()
  41.  
  42. /***** Implementation for class wxToolLayoutItem *****/
  43.         
  44. IMPLEMENT_DYNAMIC_CLASS(wxToolLayoutItem, wxObject)
  45.  
  46.  
  47. /***** Implementation for class wxDynToolInfo *****/
  48.         
  49. IMPLEMENT_DYNAMIC_CLASS(wxDynToolInfo, wxToolLayoutItem)
  50.  
  51. /***** Implementation for class wxDynamicToolBar *****/
  52.  
  53. wxDynamicToolBar::wxDynamicToolBar()
  54.     : mpLayoutMan( NULL ),
  55.       mSepartorSize( 8 ),
  56.       mVertGap ( 0 ),
  57.       mHorizGap( 0 )
  58. {
  59. }
  60.  
  61. wxDynamicToolBar::wxDynamicToolBar(wxWindow *parent, const wxWindowID id, 
  62.                                    const wxPoint& pos, const wxSize& size,
  63.                                    const long style, const int orientation,
  64.                                    const int RowsOrColumns, const wxString& name )
  65.     : mpLayoutMan( NULL ),
  66.       mSepartorSize( 8 ),
  67.       mVertGap ( 0 ),
  68.       mHorizGap( 0 )
  69. {
  70.     Create(parent, id, pos, size, style, orientation, RowsOrColumns, name);
  71.  
  72.     SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE) );
  73. }
  74.  
  75. bool wxDynamicToolBar::Create(wxWindow *parent, const wxWindowID id, 
  76.                               const wxPoint& pos, 
  77.                               const wxSize& size,
  78.                               const long style, 
  79.                               const int orientation, const int RowsOrColumns, 
  80.                               const wxString& name)
  81. {
  82.     // cut&pasted from wxtbatsmpl.h
  83.  
  84.     if ( ! wxWindow::Create(parent, id, pos, size, style, name) )
  85.         return FALSE;
  86.  
  87.     SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE ));
  88.  
  89.     return TRUE;
  90. }
  91.  
  92. bool wxDynamicToolBar::Realize(void)
  93. {
  94.     // FOR NOW:: nothing
  95.     return TRUE;
  96. }
  97.  
  98. wxDynamicToolBar::~wxDynamicToolBar(void)
  99. {
  100.     if ( mpLayoutMan )
  101.         delete mpLayoutMan;
  102.  
  103.     size_t i;
  104.     for( i = 0; i != mTools.Count(); ++i )
  105.     {
  106.         delete mTools[i];
  107.     }
  108. }
  109.  
  110. void wxDynamicToolBar::AddTool( int toolIndex, 
  111.                                 wxWindow* pToolWindow, 
  112.                                 const wxSize& size
  113.                               )
  114. {
  115.     wxDynToolInfo* pInfo = new wxDynToolInfo();
  116.  
  117.     pInfo->mpToolWnd    = pToolWindow;
  118.     pInfo->mIndex       = toolIndex;
  119.     pInfo->mIsSeparator    = FALSE;
  120.  
  121.     int x,y;
  122.     pToolWindow->GetSize( &x, &y );
  123.     pInfo->mRealSize.x = x;
  124.     pInfo->mRealSize.y = y;
  125.     pInfo->mRect.width = x;
  126.     pInfo->mRect.height = y;
  127.  
  128.     mTools.Add( pInfo );
  129. }
  130.  
  131. void wxDynamicToolBar::AddTool( int toolIndex, 
  132.                                 const wxString& imageFileName,
  133.                                 wxBitmapType imageFileType, 
  134.                                 const wxString& labelText, bool alignTextRight,
  135.                                 bool isFlat )
  136. {
  137.     wxNewBitmapButton* pBtn =
  138.  
  139.       new wxNewBitmapButton( imageFileName, imageFileType,
  140.                              labelText, 
  141.                              ( alignTextRight ) 
  142.                              ? NB_ALIGN_TEXT_RIGHT 
  143.                              : NB_ALIGN_TEXT_BOTTOM,
  144.                              isFlat
  145.                            );
  146.  
  147.     pBtn->Create( this, toolIndex );
  148.  
  149.     pBtn->Reshape();
  150.     
  151.     AddTool( toolIndex, pBtn );
  152. }
  153. void wxDynamicToolBar::AddTool( int toolIndex, wxBitmap labelBmp,
  154.                                 const wxString& labelText, bool alignTextRight,
  155.                                 bool isFlat )
  156. {
  157.     wxNewBitmapButton* pBtn =
  158.  
  159.       new wxNewBitmapButton( labelBmp,
  160.                              labelText, 
  161.                              ( alignTextRight ) 
  162.                              ? NB_ALIGN_TEXT_RIGHT 
  163.                              : NB_ALIGN_TEXT_BOTTOM,
  164.                              isFlat
  165.                            );
  166.  
  167.     pBtn->Create( this, toolIndex );
  168.  
  169.     pBtn->Reshape();
  170.     
  171.     AddTool( toolIndex, pBtn );
  172. }
  173.  
  174.  
  175. wxToolBarToolBase* 
  176.       wxDynamicToolBar::AddTool(const int toolIndex, const wxBitmap& bitmap, 
  177.                                 const wxBitmap& pushedBitmap,
  178.                                 const bool toggle, const long xPos, 
  179.                                 const long yPos, wxObject *clientData,
  180.                                 const wxString& helpString1, const wxString& helpString2)
  181. {
  182.     wxNewBitmapButton* pBmpBtn = new wxNewBitmapButton( bitmap );
  183.  
  184.     pBmpBtn->Create( this, toolIndex );
  185.  
  186.     pBmpBtn->Reshape();
  187.  
  188. #if wxUSE_TOOLTIPS
  189.     pBmpBtn->SetToolTip( helpString1 );
  190. #endif  // wxUSE_TOOLTIPS
  191.  
  192.     AddTool( toolIndex, pBmpBtn );
  193.  
  194.     return NULL;
  195. }
  196.  
  197.  
  198. wxDynToolInfo* wxDynamicToolBar::GetToolInfo( int toolIndex )
  199. {
  200.     size_t i;
  201.     for( i = 0; i != mTools.Count(); ++i )
  202.     {
  203.         if ( mTools[i]->mIndex == toolIndex )
  204.             return mTools[i];
  205.     }
  206.  
  207.     return NULL;
  208. }
  209.  
  210. void wxDynamicToolBar::RemveTool( int toolIndex )
  211. {
  212.     size_t i;
  213.     for( i = 0; i != mTools.Count(); ++i )
  214.     {
  215.         if ( mTools[i]->mIndex == toolIndex ) 
  216.         {
  217.             if ( mTools[i]->mpToolWnd )
  218.             {
  219.                 mTools[i]->mpToolWnd->Destroy();
  220.             }
  221.             delete mTools[i]; // HVL To be tested!!!
  222. #if wxCHECK_VERSION(2,3,2)
  223.             mTools.RemoveAt(i);
  224. #else
  225.             mTools.Remove(i);
  226. #endif
  227.             Layout();
  228.  
  229.             return;
  230.         }
  231.     }
  232.     // TODO:: if not found, should it be an assertion?
  233. }
  234.  
  235. void wxDynamicToolBar::AddSeparator( wxWindow* pSepartorWnd )
  236. {
  237.     wxDynToolInfo* pInfo = new wxDynToolInfo();
  238.  
  239.     pInfo->mpToolWnd    = pSepartorWnd;
  240.     pInfo->mIndex       = -1;
  241.     pInfo->mIsSeparator = TRUE;
  242.  
  243.     // Do we draw a separator or is a other object?
  244.     if ( pSepartorWnd )
  245.     {
  246.         // hvl => Is there a way to know if it was already created?
  247.         // hvl => shouldn't the pSepartorWnd be created? (like one should expect?)
  248.         // pSepartorWnd->Create( this, -1 );
  249.  
  250.         int x,y;
  251.         pSepartorWnd->GetSize( &x, &y );
  252.         pInfo->mRealSize.x = x;
  253.         pInfo->mRealSize.y = y;
  254.  
  255.         pInfo->mRect.width = x;
  256.         pInfo->mRect.height = y;
  257.     }
  258.     else
  259.     {
  260.         // Init x and y to the default.
  261.         pInfo->mRealSize.x = 0;
  262.         pInfo->mRealSize.y = 0;
  263.  
  264.         // Init height and width to the normal size of a separator.
  265.         pInfo->mRect.width  = mSepartorSize;
  266.         pInfo->mRect.height = mSepartorSize;
  267.     }
  268.  
  269.     mTools.Add( pInfo );
  270. }
  271.  
  272. void wxDynamicToolBar::OnEraseBackground( wxEraseEvent& event )
  273. {
  274.     // FOR NOW:: nothing
  275. }
  276.  
  277. void wxDynamicToolBar::OnSize( wxSizeEvent& event )
  278. {
  279.     //SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE ) );
  280.  
  281.     Layout();
  282. }
  283.  
  284. void wxDynamicToolBar::DrawSeparator( wxDynToolInfo& info, wxDC& dc )
  285. {
  286.     // check the orientation of separator
  287.     if ( info.mRect.width < info.mRect.height )
  288.     {
  289.         int midX = info.mRect.x + info.mRect.width/2 - 1;
  290.  
  291.         dc.SetPen( *wxGREY_PEN );
  292.         dc.DrawLine( midX, info.mRect.y,
  293.                      midX, info.mRect.y + info.mRect.height+1 );
  294.  
  295.         dc.SetPen( *wxWHITE_PEN );
  296.         dc.DrawLine( midX+1, info.mRect.y,
  297.                      midX+1, info.mRect.y + info.mRect.height+1 );
  298.     }
  299.     else
  300.     {
  301.         int midY = info.mRect.y + info.mRect.height/2 - 1;
  302.  
  303.         dc.SetPen( *wxGREY_PEN );
  304.         dc.DrawLine( info.mRect.x, midY,
  305.                      info.mRect.x + info.mRect.width+1, midY );
  306.  
  307.         dc.SetPen( *wxWHITE_PEN );
  308.         dc.DrawLine( info.mRect.x, midY + 1,
  309.                      info.mRect.x + info.mRect.width+1, midY + 1 );
  310.     }
  311. }
  312.  
  313. void wxDynamicToolBar::OnPaint( wxPaintEvent& event )
  314. {
  315.     // draw separators if any
  316.     wxPaintDC dc(this);
  317.  
  318.     size_t i;
  319.     for( i = 0; i != mTools.Count(); ++i )
  320.     {
  321.         if ( mTools[i]->mIsSeparator ) 
  322.         {
  323.             // check if separator doesn't have it's own window
  324.             // if so, then draw it using built-in drawing method
  325.             if ( !mTools[i]->mpToolWnd )
  326.                 DrawSeparator( *mTools[i], dc );
  327.         }
  328.     }
  329. }
  330.  
  331. // FOR NOW:: quick fix
  332. #include "wx/choice.h"
  333.  
  334. void wxDynamicToolBar::SizeToolWindows()
  335. {
  336.     bool bStateCheckDone = FALSE;
  337.     bool bHorzSeparator  = FALSE;
  338.     int maxWidth         = 0;
  339.     int maxHeight        = 0;
  340.  
  341.     size_t i;
  342.     for( i = 0; i != mTools.Count(); ++i )
  343.     {
  344.         wxDynToolInfo& info = *mTools[i];
  345.  
  346.         if ( !info.mIsSeparator ) 
  347.         {
  348.             // center real rectangle within the rectangle 
  349.             // provided by the layout manager
  350.  
  351.             int x = info.mRect.x;
  352.             int y = info.mRect.y + (info.mRect.height - info.mRealSize.y)/2;
  353.  
  354.             // FOR NOW FOR NOW:: quick & dirty fix
  355.             if ( info.mpToolWnd->IsKindOf( CLASSINFO( wxChoice ) ) )
  356.             {
  357.                 info.mpToolWnd->SetSize( x, y, 
  358.                                          info.mRealSize.x - 3, 
  359.                                          info.mRealSize.y);
  360.             }
  361.             else
  362.             {
  363.                 info.mpToolWnd->SetSize( x, y, 
  364.                                          info.mRealSize.x, 
  365.                                          info.mRealSize.y );
  366.             }
  367.         }
  368.         else
  369.         {
  370.             // We performer this code here, so we only execute it when we have 
  371.             // separators and we do it only once (all to do with performance...)
  372.             if (!bStateCheckDone)
  373.             {
  374.                 bStateCheckDone = TRUE;
  375.                 
  376.                 size_t j;
  377.                 wxDynToolInfo *pInfo = NULL;
  378.                 wxDynToolInfo *pPrevInfo = NULL;
  379.                 int nVertSeparators = 0;
  380.  
  381.                 for( j = 0; j != mTools.Count(); ++j )
  382.                 {
  383.                     pInfo = mTools[j];
  384.                     
  385.                     // Count all Vert Separators.
  386.                     if ( pInfo->mIsSeparator ) 
  387.                         nVertSeparators++;
  388.  
  389.                     // Check if the new row starts with a Separator.
  390.                     if ( pPrevInfo && pInfo->mIsSeparator &&
  391.                          // pPrevInfo->mRect.x >= pInfo->mRect.x &&
  392.                          pPrevInfo->mRect.y < pInfo->mRect.y)
  393.                     {
  394.                         // If the Separator is shown on the next row and it's 
  395.                         // the only object on the row it would mean that the 
  396.                         // Separator should be shown as Horizontal one.
  397.                         if (j+1 != mTools.Count())
  398.                         {
  399.                             if (pInfo->mRect.y < mTools[j+1]->mRect.y)
  400.                                 nVertSeparators--;
  401.                         }
  402.                         else
  403.                         {
  404.                             nVertSeparators--;
  405.                         }
  406.                     }
  407.  
  408.                     pPrevInfo = pInfo;
  409.  
  410.                     maxWidth = wxMax(pInfo->mRect.width, maxWidth);
  411.                     maxHeight = wxMax(pInfo->mRect.height, maxHeight);
  412.                 }
  413.                 
  414.                 bHorzSeparator = nVertSeparators == 0;
  415.             }
  416.             
  417.             // Check if we should draw Horz or Vert...
  418.             if ( !bHorzSeparator )
  419.             {
  420.                 info.mRect.width = mSepartorSize;
  421.                 info.mRect.height = maxHeight;
  422.             }
  423.             else
  424.             {
  425.                 info.mRect.width = maxWidth;
  426.                 info.mRect.height = mSepartorSize;
  427.             }
  428.  
  429.             // Do we need to set a new size to a seperator object?
  430.             if ( info.mpToolWnd )
  431.             {
  432.                 info.mpToolWnd->SetSize( info.mRect.x,
  433.                                          info.mRect.y, 
  434.                                          info.mRect.width, 
  435.                                          info.mRect.height);
  436.             }
  437.  
  438.         }
  439.     }
  440. }
  441.  
  442. bool wxDynamicToolBar::Layout()
  443. {
  444.     int x,y;
  445.     GetSize( &x, &y );
  446.     wxSize wndDim(x,y);
  447.     wxSize result;
  448.     size_t i;
  449.     wxDynToolInfo *pInfo;
  450.  
  451.     // Reset the size of separators...
  452.     for( i = 0; i != mTools.Count(); ++i )
  453.     {
  454.         pInfo = mTools[i];
  455.         
  456.         if ( pInfo->mIsSeparator ) 
  457.         {
  458.             pInfo->mRect.width  = mSepartorSize;
  459.             pInfo->mRect.height = mSepartorSize;
  460.         }
  461.     }
  462.  
  463.     // Calc and set the best layout
  464.     GetPreferredDim( wndDim, result );
  465.  
  466.     SizeToolWindows();
  467.     return TRUE;
  468. }
  469.  
  470. void wxDynamicToolBar::GetPreferredDim( const wxSize& givenDim, wxSize& prefDim )
  471. {
  472.     if ( !mpLayoutMan )
  473.         mpLayoutMan = CreateDefaultLayout();
  474.  
  475.     wxLayoutItemArrayT items;
  476.  
  477.     // safe conversion
  478.     size_t i;
  479.     for( i = 0; i != mTools.Count(); ++i )
  480.         items.Add( mTools[i] );
  481.  
  482.     mpLayoutMan->Layout( givenDim, prefDim, items, mVertGap, mHorizGap );
  483. }
  484.  
  485. void wxDynamicToolBar::SetLayout( LayoutManagerBase* pLayout )
  486. {
  487.     if ( mpLayoutMan )
  488.         delete mpLayoutMan;
  489.  
  490.     mpLayoutMan = pLayout;
  491.  
  492.     Layout();
  493. }
  494.  
  495. void wxDynamicToolBar::EnableTool(const int toolIndex, const bool enable )
  496. {
  497.     wxDynToolInfo* pInfo = GetToolInfo( toolIndex );
  498.  
  499.     if ( !pInfo )
  500.         return;
  501.  
  502.     if ( pInfo->mIsSeparator || !pInfo->mpToolWnd )
  503.         return;
  504.  
  505.     pInfo->mpToolWnd->Enable( enable );
  506. }
  507.  
  508. /***** Implementation for class BagLayout *****/
  509.  
  510. void BagLayout::Layout(  const wxSize&       parentDim, 
  511.                          wxSize&             resultingDim,
  512.                          wxLayoutItemArrayT& items,
  513.                          int                 horizGap,
  514.                          int                 vertGap  
  515.                       )
  516. {
  517.     int maxWidth = 0;
  518.     int curY  = 0;
  519.     int nRows = 0;
  520.  
  521.     size_t i = 0;
  522.  
  523.     while( i < items.Count() )
  524.     {
  525.         int curX   = 0;
  526.         int height = 0;
  527.         // int nItems = 0;
  528.  
  529.         // int firstItem  = i;
  530.         int itemsInRow = 0;
  531.  
  532.         if ( nRows > 0 )
  533.             curY += vertGap;
  534.  
  535.         // step #1 - arrange horizontal positions of items in the row
  536.  
  537.         do
  538.         {
  539.             if ( itemsInRow > 0 )
  540.                 curX += horizGap;
  541.  
  542.             wxRect& r = items[i]->mRect;
  543.  
  544.             if ( curX + r.width > parentDim.x )
  545.             {
  546.                 if ( itemsInRow > 0 ) 
  547.                     break;
  548.             }
  549.             r.x = curX;
  550.             r.y = curY;
  551.  
  552.             curX += r.width;
  553.  
  554.             height = wxMax( height, r.height );
  555.  
  556.             ++itemsInRow;
  557.             ++i;
  558.  
  559.         } while( i < items.Count() );
  560.  
  561.         curY += height;
  562.  
  563.         maxWidth = wxMax( maxWidth, curX );
  564.     }
  565.  
  566.     resultingDim.x = maxWidth;
  567.     resultingDim.y = curY;
  568. }
  569.  
  570. //////// stuff from 2.1.15 ///////////
  571.  
  572. wxToolBarToolBase* wxDynamicToolBar::FindToolForPosition( wxCoord x, wxCoord y ) const
  573. {
  574.     return NULL;
  575. }
  576.  
  577. bool wxDynamicToolBar::DoInsertTool( size_t pos, wxToolBarToolBase* tool )
  578. {
  579.     return TRUE;
  580. }
  581.  
  582. bool wxDynamicToolBar::DoDeleteTool( size_t pos, wxToolBarToolBase* tool )
  583. {
  584.     return TRUE;
  585. }
  586.  
  587. void wxDynamicToolBar::DoEnableTool( wxToolBarToolBase* tool, bool enable )
  588. {
  589. }
  590.  
  591. void wxDynamicToolBar::DoToggleTool( wxToolBarToolBase* tool, bool toggle )
  592. {
  593. }
  594.  
  595. void wxDynamicToolBar::DoSetToggle( wxToolBarToolBase* tool, bool toggle )
  596. {
  597. }
  598.  
  599. wxToolBarToolBase* wxDynamicToolBar::CreateTool( int id, const wxString& label, const wxBitmap& bmpNormal, const wxBitmap& bmpDisabled, wxItemKind kind, wxObject *clientData, const wxString& shortHelp, const wxString& longHelp)
  600. {
  601.     return NULL;
  602. }
  603.  
  604. wxToolBarToolBase* wxDynamicToolBar::CreateTool( wxControl* control )
  605. {
  606.     return NULL;
  607. }
  608.  
  609.