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 / barhintspl.cpp < prev    next >
C/C++ Source or Header  |  2002-06-12  |  15KB  |  569 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        barhintspl.h
  3. // Purpose:     Implementation for cbBarHintsPlugin
  4. // Author:      Aleksandras Gluchovas
  5. // Modified by:
  6. // Created:     30/11/98 (my 22th birthday :-)
  7. // RCS-ID:      $Id: barhintspl.cpp,v 1.4 2002/06/12 08:29:12 JS Exp $
  8. // Copyright:   (c) Aleksandras Gluchovas
  9. // Licence:     wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #ifdef __GNUG__
  13.     #pragma implementation "barhintspl.h"
  14. #endif
  15.  
  16. // For compilers that support precompilation, includes "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"
  28. #include "wx/fl/barhintspl.h"
  29.  
  30. // fixed settings
  31.  
  32. #define GROOVE_WIDTH         3  // left shade + middle line + right shade
  33. #define GROOVE_TO_GROOVE_GAP 1  
  34. #define BOX_T_BOX_GAP        2
  35. #define BOX_TO_GROOVE_GAP    3
  36.  
  37. #define BOXES_IN_HINT        2
  38. #define CLOSE_BOX_IDX        0
  39. #define COLLAPSE_BOX_IDX     1
  40.  
  41. // used interally 
  42.  
  43. #define CLOSE_BOX_HITTED    1
  44. #define COLLAPSE_BOX_HITTED 2
  45.  
  46. /***** Implementation fro class cbBarHintsPlugin *****/
  47.  
  48. IMPLEMENT_DYNAMIC_CLASS( cbBarHintsPlugin, cbPluginBase )
  49.  
  50. BEGIN_EVENT_TABLE( cbBarHintsPlugin, cbPluginBase )
  51.  
  52.     EVT_PL_SIZE_BAR_WND  ( cbBarHintsPlugin::OnSizeBarWindow )
  53.     EVT_PL_DRAW_BAR_DECOR( cbBarHintsPlugin::OnDrawBarDecorations )
  54.  
  55.     EVT_PL_LEFT_DOWN( cbBarHintsPlugin::OnLeftDown )
  56.     EVT_PL_LEFT_UP  ( cbBarHintsPlugin::OnLeftUp   )
  57.     EVT_PL_MOTION   ( cbBarHintsPlugin::OnMotion   )
  58.  
  59. END_EVENT_TABLE()
  60.  
  61. cbBarHintsPlugin::cbBarHintsPlugin(void)
  62.  
  63.     : mpPane( 0 ),
  64.       mBtnPressed   ( FALSE ),
  65.       mCloseBoxOn   ( TRUE ),
  66.       mCollapseBoxOn( TRUE ),
  67.       mGrooveCount  ( 2 ),
  68.       mHintGap      ( 4 ),
  69.       mXWeight      ( 2 )
  70. {
  71.     mBoxes[CLOSE_BOX_IDX]    = NULL;
  72.     mBoxes[COLLAPSE_BOX_IDX] = NULL;
  73. }
  74.  
  75. cbBarHintsPlugin::cbBarHintsPlugin( wxFrameLayout* pLayout, int paneMask )
  76.  
  77.     : cbPluginBase( pLayout, paneMask ),
  78.       mpPane( 0 ),
  79.       mBtnPressed   ( FALSE ),
  80.       mCloseBoxOn   ( TRUE ),
  81.       mCollapseBoxOn( TRUE ),
  82.       mGrooveCount  ( 2 ),
  83.       mHintGap      ( 5 ),
  84.       mXWeight      ( 2 )
  85. {
  86.     mBoxes[CLOSE_BOX_IDX]    = NULL;
  87.     mBoxes[COLLAPSE_BOX_IDX] = NULL;
  88. }
  89.  
  90.  
  91. cbBarHintsPlugin::~cbBarHintsPlugin()
  92. {
  93.     if (mBoxes[CLOSE_BOX_IDX])
  94.         delete mBoxes[CLOSE_BOX_IDX];
  95.  
  96.     if (mBoxes[COLLAPSE_BOX_IDX])
  97.         delete mBoxes[COLLAPSE_BOX_IDX];
  98. }  // cbBarHintsPlugin destructor
  99.  
  100.  
  101. void cbBarHintsPlugin::SetGrooveCount( int nGrooves )
  102. {
  103.     mGrooveCount = nGrooves;
  104. }
  105.  
  106. void cbBarHintsPlugin::CreateBoxes()
  107. {
  108.     cbCloseBox*    box1 = new cbCloseBox();
  109.     cbCollapseBox* box2 = new cbCollapseBox();
  110.  
  111.     mBoxes[CLOSE_BOX_IDX]    = box1;
  112.     mBoxes[COLLAPSE_BOX_IDX] = box2;
  113.  
  114.     int i;
  115.     for ( i = 0; i != BOXES_IN_HINT; ++i )
  116.     {
  117.         mBoxes[i]->mpLayout = mpLayout;
  118.         mBoxes[i]->mpPlugin = this;
  119.         mBoxes[i]->mpWnd    = NULL;
  120.     }
  121. }
  122.  
  123.  
  124. void cbBarHintsPlugin::Draw3DBox( wxDC& dc, const wxPoint& pos, bool pressed )
  125. {
  126. }
  127.  
  128. void cbBarHintsPlugin::DrawCloseBox( wxDC& dc, const wxPoint& pos, bool pressed )
  129. {
  130. }
  131.  
  132. void cbBarHintsPlugin::DrawCollapseBox( wxDC& dc, const wxPoint& pos, 
  133.                                         bool atLeft, bool disabled, bool pressed )
  134. {
  135. }
  136.  
  137. void cbBarHintsPlugin::DrawGrooves( wxDC& dc, const wxPoint& pos, int length )
  138. {
  139.     int ofs = 0;
  140.  
  141.     int i;
  142.     for ( i = 0; i != mGrooveCount; ++i, ofs += ( GROOVE_WIDTH + GROOVE_TO_GROOVE_GAP ) )
  143.     {
  144.         if ( mpPane->IsHorizontal() )
  145.         {
  146.             dc.SetPen( mpLayout->mLightPen );
  147.             dc.DrawLine( pos.x + ofs, pos.y, pos.x + ofs, pos.y + length - 1 );
  148.             dc.DrawPoint( pos.x + ofs + 1, pos.y );
  149.  
  150.             dc.SetPen( mpLayout->mDarkPen );
  151.             dc.DrawLine( pos.x + ofs + 2, pos.y, pos.x + ofs + 2, pos.y + length );
  152.             dc.DrawPoint( pos.x + ofs + 1, pos.y + length - 1 );
  153.             dc.DrawPoint( pos.x + ofs,     pos.y + length - 1 );
  154.         }
  155.         else
  156.         {
  157.             dc.SetPen( mpLayout->mLightPen );
  158.             dc.DrawLine( pos.x, pos.y + ofs, pos.x + length - 1, pos.y + ofs );
  159.             dc.DrawPoint( pos.x, pos.y + ofs + 1 );
  160.  
  161.             dc.SetPen( mpLayout->mDarkPen );
  162.             dc.DrawLine( pos.x, pos.y + ofs + 2, pos.x + length, pos.y + ofs + 2 );
  163.             dc.DrawPoint( pos.x + length - 1, pos.y + ofs + 1 );
  164.             dc.DrawPoint( pos.x + length - 1, pos.y + ofs );
  165.         }
  166.     }
  167. }
  168.  
  169. void cbBarHintsPlugin::ExcludeHints( wxRect& rect, cbBarInfo& info )
  170. {
  171.     int boxHeight = BTN_BOX_HEIGHT;
  172.  
  173.     // collapse and close box are not placed on fixed bars
  174.  
  175.     if ( info.IsFixed() || ( !mCloseBoxOn && !mCollapseBoxOn ) )
  176.  
  177.         boxHeight = 0;
  178.  
  179.     int height = wxMax( mGrooveCount*(GROOVE_WIDTH + GROOVE_TO_GROOVE_GAP) 
  180.                         - GROOVE_TO_GROOVE_GAP, 
  181.                         boxHeight 
  182.                       );
  183.  
  184.     if ( mpPane->IsHorizontal() )
  185.     {
  186.         rect.x     += ( mHintGap*2 + height );
  187.         rect.width -= (height + 2*mHintGap);
  188.  
  189.         rect.x     -= info.mDimInfo.mHorizGap + 2;
  190.         rect.width += info.mDimInfo.mHorizGap + 2;
  191.     }
  192.     else
  193.     {
  194.         rect.y      += (mHintGap*2 + height);
  195.         rect.height -= (height + 2*mHintGap);
  196.  
  197.         rect.y      -= info.mDimInfo.mVertGap + 2;
  198.         rect.height += info.mDimInfo.mVertGap + 2;
  199.     }
  200. }
  201.  
  202. void cbBarHintsPlugin::DoDrawHint( wxDC& dc, wxRect& rect, 
  203.                                    int pos, int boxOfs, int grooveOfs,
  204.                                    bool isFixed )
  205. {
  206.     if ( !isFixed )
  207.     {
  208.         if ( mpPane->IsHorizontal() )
  209.         {
  210.             if ( mCloseBoxOn )
  211.  
  212.                 mBoxes[CLOSE_BOX_IDX]->Draw( dc );
  213.  
  214.             if ( mCollapseBoxOn )
  215.             
  216.                 mBoxes[COLLAPSE_BOX_IDX]->Draw( dc );
  217.         }
  218.         else
  219.         {
  220.             if ( mCloseBoxOn )
  221.             
  222.                 mBoxes[CLOSE_BOX_IDX]->Draw( dc );
  223.  
  224.             if ( mCollapseBoxOn )
  225.             
  226.                 mBoxes[COLLAPSE_BOX_IDX]->Draw( dc );
  227.         }
  228.     }
  229.  
  230.     if ( mpPane->IsHorizontal() )
  231.     
  232.         DrawGrooves( dc, wxPoint( rect.x + mHintGap + grooveOfs, pos ), 
  233.                      rect.height - (pos - rect.y) - mHintGap );
  234.     else
  235.         DrawGrooves( dc, wxPoint( rect.x + mHintGap, rect.y + mHintGap + grooveOfs ), 
  236.                      (pos - rect.x) - mHintGap );
  237. }
  238.  
  239. void cbBarHintsPlugin::GetHintsLayout( wxRect& rect, cbBarInfo& info, 
  240.                                        int& boxOfs, int& grooveOfs, int& pos )
  241. {
  242.     int boxHeight = BTN_BOX_HEIGHT;
  243. //  int boxWidth  = BTN_BOX_WIDTH + BOX_TO_GROOVE_GAP + BTN_BOX_WIDTH;
  244.  
  245.     // collapse and close box are not placed on fixed bars
  246.  
  247.     if ( info.IsFixed() || ( !mCloseBoxOn && !mCollapseBoxOn ) )
  248.     {
  249.         boxHeight = 0;
  250. //      boxWidth = 0;
  251.     }
  252. /*
  253.     else
  254.     if ( !mCloseBoxOn || !mCollapseBoxOn )
  255.  
  256.         boxWidth = BTN_BOX_WIDTH;
  257. */
  258.     int grooveHeight = mGrooveCount*(GROOVE_WIDTH + GROOVE_TO_GROOVE_GAP) 
  259.                        - GROOVE_TO_GROOVE_GAP;
  260.  
  261.     int height = wxMax( grooveHeight, boxHeight );
  262.  
  263.     // center boxs and groves with respect to each other
  264.  
  265.     boxOfs    = ( height - boxHeight    ) / 2;
  266.     grooveOfs = ( height - grooveHeight ) / 2;
  267.  
  268.     pos = ( mpPane->IsHorizontal() ) ? rect.y + mHintGap
  269.                                      : rect.x + rect.width - mHintGap;
  270.  
  271.     // setup positions for boxes
  272.  
  273.     if ( !info.IsFixed() )
  274.     {
  275.         // what direction "collapse-triangle" should look at?
  276.  
  277.         bool& isAtLeft = ((cbCollapseBox*)(mBoxes[COLLAPSE_BOX_IDX]))->mIsAtLeft;
  278.          
  279.         isAtLeft= info.mBounds.x <= mpPane->mPaneWidth - ( info.mBounds.x + info.mBounds.width );
  280.  
  281.         if ( info.IsExpanded() )
  282.         {
  283.             isAtLeft = FALSE;
  284.  
  285.             cbBarInfo* pCur = info.mpPrev;
  286.  
  287.             while( pCur )
  288.             {
  289.                 if ( !pCur->IsFixed() )
  290.                 {
  291.                     isAtLeft = TRUE; break;
  292.                 }
  293.  
  294.                 pCur = pCur->mpPrev;
  295.             }
  296.         }
  297.  
  298.         // collapse/expand works only when more not-fixed bars are present in the same row
  299.  
  300.         mBoxes[COLLAPSE_BOX_IDX]->Enable( info.mpRow->mNotFixedBarsCnt > 1 );
  301.  
  302.         int i;
  303.         for ( i = 0; i != BOXES_IN_HINT; ++i )
  304.         {
  305.             mBoxes[i]->mpPane = mpPane;
  306.         }
  307.  
  308.         if ( mpPane->IsHorizontal() )
  309.         {
  310.             if ( mCloseBoxOn )
  311.             {
  312.                 mBoxes[CLOSE_BOX_IDX]->mPos = wxPoint( rect.x + mHintGap + boxOfs, pos );
  313.  
  314.                 pos += BTN_BOX_HEIGHT;
  315.             }
  316.  
  317.             if ( mCollapseBoxOn )
  318.             {
  319.                 if ( mCloseBoxOn ) pos += BOX_T_BOX_GAP;
  320.  
  321.                 mBoxes[COLLAPSE_BOX_IDX]->mPos = wxPoint( rect.x + mHintGap + boxOfs, pos );
  322.  
  323.                 pos += BTN_BOX_HEIGHT;
  324.  
  325.                 pos += BOX_TO_GROOVE_GAP;
  326.             }
  327.         }
  328.         else
  329.         {
  330.             if ( mCloseBoxOn )
  331.             {
  332.                 pos -= BTN_BOX_WIDTH;
  333.  
  334.                 mBoxes[CLOSE_BOX_IDX]->mPos = wxPoint( pos , rect.y + mHintGap + boxOfs );
  335.             }
  336.  
  337.             if ( mCollapseBoxOn )
  338.             {
  339.                 if ( mCloseBoxOn ) pos -= BOX_T_BOX_GAP;
  340.  
  341.                 pos -= BTN_BOX_WIDTH;
  342.  
  343.                 mBoxes[COLLAPSE_BOX_IDX]->mPos = wxPoint( pos, rect.y + mHintGap + boxOfs );
  344.  
  345.                 pos -= BOX_TO_GROOVE_GAP;
  346.             }
  347.         }
  348.     }
  349. }
  350.  
  351. static inline bool is_in_box( const wxPoint& rectPos, const wxPoint& mousePos )
  352. {
  353.     return ( mousePos.x >= rectPos.x &&
  354.              mousePos.y >= rectPos.y &&
  355.              mousePos.x < rectPos.x + BTN_BOX_WIDTH &&
  356.              mousePos.y < rectPos.y + BTN_BOX_HEIGHT );
  357. }
  358.  
  359. int cbBarHintsPlugin::HitTestHints( cbBarInfo& info, const wxPoint& pos )
  360. {
  361.     wxPoint inPane = pos;
  362.     mpPane->PaneToFrame( &inPane.x, &inPane.y );
  363.  
  364.     wxRect& rect = info.mBoundsInParent;
  365.  
  366.     if ( info.IsFixed() ) return FALSE;
  367.  
  368.     int boxOfs, grooveOfs, coord;
  369.  
  370.     GetHintsLayout( rect, info, boxOfs, grooveOfs, coord );
  371.  
  372.     if ( mpPane->IsHorizontal() )
  373.     {
  374.         if ( mCloseBoxOn )
  375.         {
  376.             if ( is_in_box( wxPoint( rect.x + mHintGap + boxOfs, coord ), inPane ) )
  377.  
  378.                 return CLOSE_BOX_HITTED;
  379.  
  380.             coord += BTN_BOX_HEIGHT;
  381.         }
  382.  
  383.         if ( mCollapseBoxOn )
  384.         {
  385.             if ( mCloseBoxOn ) coord += BOX_T_BOX_GAP;
  386.  
  387.             if ( is_in_box( wxPoint( rect.x + mHintGap + boxOfs, coord ), inPane ) )
  388.  
  389.                 return COLLAPSE_BOX_HITTED;
  390.  
  391.             coord += BTN_BOX_HEIGHT;
  392.         }
  393.     }
  394.     else
  395.     {
  396.         if ( mCloseBoxOn )
  397.         {
  398.             coord -= BTN_BOX_WIDTH;
  399.  
  400.             if ( is_in_box( wxPoint( coord , rect.y + mHintGap + boxOfs ), inPane ) )
  401.  
  402.                 return CLOSE_BOX_HITTED;
  403.         }
  404.  
  405.         if ( mCollapseBoxOn )
  406.         {
  407.             if ( mCloseBoxOn ) coord -= BOX_T_BOX_GAP;
  408.             coord -= BTN_BOX_WIDTH;
  409.  
  410.             if ( is_in_box( wxPoint( coord, rect.y + mHintGap + boxOfs ), inPane ) )
  411.  
  412.                 return COLLAPSE_BOX_HITTED;
  413.         }
  414.     }
  415.  
  416.     return FALSE;
  417. }
  418.  
  419. // handlers for plugin-events
  420.  
  421. void cbBarHintsPlugin::OnSizeBarWindow( cbSizeBarWndEvent& event )
  422. {
  423.     wxRect& rect     = event.mBoundsInParent;
  424.     mpPane           = event.mpPane;
  425.  
  426.     ExcludeHints( rect, *event.mpBar );
  427.  
  428.     event.Skip(); // pass event to the next plugin in the chain
  429. }
  430.  
  431. void cbBarHintsPlugin::OnDrawBarDecorations( cbDrawBarDecorEvent& event )
  432. {
  433.     wxRect& rect     = event.mBoundsInParent;
  434.     mpPane           = event.mpPane;
  435.  
  436.     int boxOfs, grooveOfs, pos;
  437.  
  438.     GetHintsLayout( rect, *event.mpBar, boxOfs, grooveOfs, pos );
  439.  
  440.     DoDrawHint( *event.mpDc, rect, pos, boxOfs, grooveOfs, event.mpBar->IsFixed() );
  441.  
  442.     // let other plugins add on their decorations
  443.  
  444.     event.Skip();
  445. }
  446.  
  447. void cbBarHintsPlugin::OnLeftDown( cbLeftDownEvent& event )
  448. {
  449.     mpPane           = event.mpPane;
  450.     wxPoint inFrame = event.mPos;
  451.  
  452.     mpPane->PaneToFrame( &inFrame.x, &inFrame.y );
  453.  
  454.     wxBarIterator iter( mpPane->GetRowList() );
  455.  
  456.     mpClickedBar = NULL;
  457.  
  458.     while ( iter.Next() )
  459.     {
  460.         cbBarInfo& bar = iter.BarInfo();
  461.  
  462.         int boxOfs, grooveOfs, pos;
  463.  
  464.         GetHintsLayout( bar.mBoundsInParent, bar, boxOfs, grooveOfs, pos );
  465.  
  466.         if ( !bar.IsFixed() )
  467.         {
  468.             int i;
  469.             for ( i = 0; i != BOXES_IN_HINT; ++i )
  470.             {
  471.                 mBoxes[i]->mPressed = FALSE;
  472.                 mBoxes[i]->mWasClicked = FALSE;
  473.             }
  474.             for ( i = 0; i != BOXES_IN_HINT; ++i )
  475.             {
  476.                 mBoxes[i]->OnLeftDown( inFrame );
  477.  
  478.                 if ( mBoxes[i]->mPressed )
  479.                 {
  480.                     mBtnPressed = TRUE;
  481.                     mpClickedBar = &bar;
  482.  
  483.                     return; // event handled
  484.                 }
  485.             }
  486.         }
  487.     }
  488.  
  489.     event.Skip();
  490. }
  491.  
  492. void cbBarHintsPlugin::OnLeftUp( cbLeftUpEvent&   event )
  493. {
  494.     if ( mBtnPressed )
  495.     {
  496.         wxPoint inFrame = event.mPos;
  497.         mpPane->PaneToFrame( &inFrame.x, &inFrame.y );
  498.  
  499.         int boxOfs, grooveOfs, pos;
  500.  
  501.         GetHintsLayout( mpClickedBar->mBoundsInParent, *mpClickedBar, boxOfs, grooveOfs, pos );
  502.  
  503.         int result = HitTestHints( *mpClickedBar, event.mPos );
  504.  
  505.         int i;
  506.         for ( i = 0; i != BOXES_IN_HINT; ++i )
  507.         {
  508.             mBoxes[i]->OnLeftUp( inFrame );
  509.  
  510.             if ( mBoxes[i]->WasClicked() )
  511.             {
  512.                 if ( i == 0 )
  513.                 {
  514.                     mpLayout->SetBarState( mpClickedBar, wxCBAR_HIDDEN, TRUE );
  515.                 }
  516.                 else
  517.                 {
  518.                     if ( mpClickedBar->IsExpanded() )
  519.                         mpPane->ContractBar( mpClickedBar );
  520.                     else
  521.                         mpPane->ExpandBar( mpClickedBar );
  522.                 }
  523.             }
  524.         }
  525.  
  526.         mBtnPressed = FALSE;
  527.         return;
  528.     }
  529.     else
  530.         event.Skip();
  531. }
  532.  
  533. void cbBarHintsPlugin::OnMotion( cbMotionEvent&   event )
  534. {
  535.     if ( mBtnPressed )
  536.     {
  537.         wxPoint inFrame = event.mPos;
  538.         mpPane->PaneToFrame( &inFrame.x, &inFrame.y );
  539.  
  540.         mpPane = event.mpPane;
  541.  
  542.         int i;
  543.         for ( i = 0; i != BOXES_IN_HINT; ++i )
  544.         {
  545.             mBoxes[i]->OnMotion( inFrame );
  546.         }
  547.     }
  548.     else
  549.         event.Skip();
  550. }
  551.  
  552. void cbBarHintsPlugin::OnInitPlugin()
  553. {
  554.     cbPluginBase::OnInitPlugin();
  555.  
  556.     cbDockPane** panes = mpLayout->GetPanesArray();
  557.  
  558.     int i;
  559.     for ( i = 0; i != MAX_PANES; ++i )
  560.     {    
  561.         if ( panes[i]->MatchesMask( mPaneMask ) )
  562.         {
  563.             panes[i]->mProps.mMinCBarDim.x = 25;
  564.             panes[i]->mProps.mMinCBarDim.y = 16;
  565.         }
  566.     }
  567.     CreateBoxes();
  568. }
  569.