home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 27 / IOPROG_27.ISO / SOFT / DYNASPLI.ZIP / DynSplitterWnd.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-10  |  6.3 KB  |  265 lines

  1. // SAGA Incorporated MFC Goodies
  2. //
  3. // SAGA Incorporated (saga@gis.net) MFC Goodies
  4. // Developed by Andrew Slivker for www.codeguru.com
  5. // 
  6. // DynSplitterWnd.cpp : implementation file
  7. //
  8. // Version:            1.0
  9. // Revision:        02/03/98
  10.  
  11. #include "stdafx.h"
  12. #include <afxext.h>
  13. #include "DynSplitterWnd.h"
  14.  
  15. #ifdef _DEBUG
  16. #define new DEBUG_NEW
  17. #undef THIS_FILE
  18. static char THIS_FILE[] = __FILE__;
  19. #endif
  20.  
  21. #define CX_BORDER    1
  22. #define CY_BORDER    1
  23.  
  24. #define FAR_POINT_XY        -10000
  25.  
  26.  
  27. /////////////////////////////////////////////////////////////////////////////
  28. // CDynSplitterWnd
  29.  
  30. CDynSplitterWnd::CDynSplitterWnd() 
  31.     :m_OldPoint(FAR_POINT_XY,FAR_POINT_XY), m_bDynSplit(TRUE)
  32. {
  33. }
  34.  
  35. CDynSplitterWnd::~CDynSplitterWnd()
  36. {
  37. }
  38.  
  39.  
  40. void CDynSplitterWnd::OnInvertTracker(const CRect& rect)
  41. {
  42.     if(!m_bDynSplit)
  43.         CSplitterWnd::OnInvertTracker(rect);
  44.     else
  45.         return;
  46. }
  47.  
  48. void CDynSplitterWnd::StartTracking(int ht)
  49. {
  50.     if(!m_bDynSplit)
  51.     {
  52.         CSplitterWnd::StartTracking(ht);
  53.         return;
  54.     }
  55.  
  56.     ASSERT_VALID(this);
  57.     if (ht == noHit)
  58.         return;
  59.  
  60.     // GetHitRect will restrict 'm_rectLimit' as appropriate
  61.     GetInsideRect(m_rectLimit);
  62.  
  63.     if (ht >= splitterIntersection1 && ht <= splitterIntersection225)
  64.     {
  65.         // split two directions (two tracking rectangles)
  66.         int row = (ht - splitterIntersection1) / 15;
  67.         int col = (ht - splitterIntersection1) % 15;
  68.  
  69.         GetHitRect(row + vSplitterBar1, m_rectTracker);
  70.         int yTrackOffset = m_ptTrackOffset.y;
  71.         m_bTracking2 = TRUE;
  72.         GetHitRect(col + hSplitterBar1, m_rectTracker2);
  73.         m_ptTrackOffset.y = yTrackOffset;
  74.     }
  75.     else if (ht == bothSplitterBox)
  76.     {
  77.         // hit on splitter boxes (for keyboard)
  78.         GetHitRect(vSplitterBox, m_rectTracker);
  79.         int yTrackOffset = m_ptTrackOffset.y;
  80.         m_bTracking2 = TRUE;
  81.         GetHitRect(hSplitterBox, m_rectTracker2);
  82.         m_ptTrackOffset.y = yTrackOffset;
  83.  
  84.         // center it
  85.         m_rectTracker.OffsetRect(0, m_rectLimit.Height()/2);
  86.         m_rectTracker2.OffsetRect(m_rectLimit.Width()/2, 0);
  87.     }
  88.     else
  89.     {
  90.         // only hit one bar
  91.         GetHitRect(ht, m_rectTracker);
  92.     }
  93.  
  94.     // steal focus and capture
  95.     SetCapture();
  96.  
  97.     // set tracking state and appropriate cursor
  98.     m_bTracking = TRUE;
  99.     m_htTrack = ht;
  100.     SetSplitCursor(ht);
  101. }
  102.  
  103.  
  104. void CDynSplitterWnd::StopTracking(BOOL bAccept)
  105. {
  106.     ASSERT_VALID(this);
  107.  
  108.     if (!m_bTracking)
  109.         return;
  110.  
  111.     ReleaseCapture();
  112.  
  113.     // erase tracker rectangle
  114.     OnInvertTracker(m_rectTracker);
  115.     if (m_bTracking2)
  116.         OnInvertTracker(m_rectTracker2);
  117.     m_bTracking = m_bTracking2 = FALSE;
  118.  
  119.     // save old active view
  120.     CWnd* pOldActiveView = GetActivePane();
  121.  
  122.     // m_rectTracker is set to the new splitter position (without border)
  123.     // (so, adjust relative to where the border will be)
  124.     m_rectTracker.OffsetRect(-CX_BORDER , -CY_BORDER);
  125.     m_rectTracker2.OffsetRect(-CX_BORDER, -CY_BORDER);
  126.  
  127.     if (bAccept)
  128.     {
  129.         if (m_htTrack == vSplitterBox)
  130.         {
  131.             SplitRow(m_rectTracker.top);
  132.         }
  133.         else if (m_htTrack >= vSplitterBar1 && m_htTrack <= vSplitterBar15)
  134.         {
  135.             // set row height
  136.             TrackRowSize(m_rectTracker.top, m_htTrack - vSplitterBar1);
  137.             RecalcLayout();
  138.         }
  139.         else if (m_htTrack == hSplitterBox)
  140.         {
  141.             SplitColumn(m_rectTracker.left);
  142.         }
  143.         else if (m_htTrack >= hSplitterBar1 && m_htTrack <= hSplitterBar15)
  144.         {
  145.             // set column width
  146.             TrackColumnSize(m_rectTracker.left, m_htTrack - hSplitterBar1);
  147.             RecalcLayout();
  148.         }
  149.         else if (m_htTrack >= splitterIntersection1 &&
  150.             m_htTrack <= splitterIntersection225)
  151.         {
  152.             // set row height and column width
  153.             int row = (m_htTrack - splitterIntersection1) / 15;
  154.             int col = (m_htTrack - splitterIntersection1) % 15;
  155.  
  156.             TrackRowSize(m_rectTracker.top, row);
  157.             TrackColumnSize(m_rectTracker2.left, col);
  158.             RecalcLayout();
  159.         }
  160.         else if (m_htTrack == bothSplitterBox)
  161.         {
  162.             // rectTracker is vSplitter (splits rows)
  163.             // rectTracker2 is hSplitter (splits cols)
  164.             SplitRow(m_rectTracker.top);
  165.             SplitColumn(m_rectTracker2.left);
  166.         }
  167.     }
  168.  
  169.     if ( (pOldActiveView == GetActivePane()) &&
  170.          (pOldActiveView != NULL)
  171.        )
  172.             SetActivePane(-1, -1, pOldActiveView); // re-activate
  173. }
  174.  
  175.  
  176. BEGIN_MESSAGE_MAP(CDynSplitterWnd, CSplitterWnd)
  177.     //{{AFX_MSG_MAP(CDynSplitterWnd)
  178.     ON_WM_MOUSEMOVE()
  179.     //}}AFX_MSG_MAP
  180. END_MESSAGE_MAP()
  181.  
  182.  
  183. /////////////////////////////////////////////////////////////////////////////
  184. // CDynSplitterWnd message handlers
  185.  
  186.  
  187. void CDynSplitterWnd::OnMouseMove(UINT nFlags, CPoint pt) 
  188. {
  189.     if(!m_bDynSplit)
  190.     {
  191.         CSplitterWnd::OnMouseMove(nFlags, pt);
  192.         return;
  193.     }
  194.  
  195.     if (GetCapture() != this)
  196.         StopTracking(FALSE);
  197.  
  198.     if (m_bTracking)
  199.     {
  200.         // move tracker to current cursor position
  201.         pt.Offset(m_ptTrackOffset); // pt is the upper right of hit detect
  202.         // limit the point to the valid split range
  203.         if (pt.y < m_rectLimit.top)
  204.             pt.y = m_rectLimit.top;
  205.         else if (pt.y > m_rectLimit.bottom)
  206.             pt.y = m_rectLimit.bottom;
  207.         if (pt.x < m_rectLimit.left)
  208.             pt.x = m_rectLimit.left;
  209.         else if (pt.x > m_rectLimit.right)
  210.             pt.x = m_rectLimit.right;
  211.  
  212.         if (m_htTrack == vSplitterBox ||
  213.             m_htTrack >= vSplitterBar1 && m_htTrack <= vSplitterBar15)
  214.         {
  215.             if (m_rectTracker.top != pt.y)
  216.             {
  217.                 OnInvertTracker(m_rectTracker);
  218.                 m_rectTracker.OffsetRect(0, pt.y - m_rectTracker.top);
  219.                 OnInvertTracker(m_rectTracker);
  220.             }
  221.         }
  222.         else if (m_htTrack == hSplitterBox ||
  223.             m_htTrack >= hSplitterBar1 && m_htTrack <= hSplitterBar15)
  224.         {
  225.             if (m_rectTracker.left != pt.x)
  226.             {
  227.                 OnInvertTracker(m_rectTracker);
  228.                 m_rectTracker.OffsetRect(pt.x - m_rectTracker.left, 0);
  229.                 OnInvertTracker(m_rectTracker);
  230.             }
  231.         }
  232.         else if (m_htTrack == bothSplitterBox ||
  233.            (m_htTrack >= splitterIntersection1 &&
  234.             m_htTrack <= splitterIntersection225))
  235.         {
  236.             if (m_rectTracker.top != pt.y)
  237.             {
  238.                 OnInvertTracker(m_rectTracker);
  239.                 m_rectTracker.OffsetRect(0, pt.y - m_rectTracker.top);
  240.                 OnInvertTracker(m_rectTracker);
  241.             }
  242.             if (m_rectTracker2.left != pt.x)
  243.             {
  244.                 OnInvertTracker(m_rectTracker2);
  245.                 m_rectTracker2.OffsetRect(pt.x - m_rectTracker2.left, 0);
  246.                 OnInvertTracker(m_rectTracker2);
  247.             }
  248.         }
  249.  
  250.         OnLButtonUp(MK_LBUTTON,pt);
  251.         OnLButtonDown(MK_LBUTTON,pt);
  252.         if(m_OldPoint != pt)
  253.         {
  254.             RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);
  255.             m_OldPoint = pt;
  256.         }
  257.     }
  258.     else
  259.     {
  260.         // simply hit-test and set appropriate cursor
  261.         int ht = HitTest(pt);
  262.         SetSplitCursor(ht);
  263.     }
  264. }
  265.