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 / contrib / src / gizmos / splittree.cpp < prev   
C/C++ Source or Header  |  2002-03-05  |  20KB  |  708 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        splittree.cpp
  3. // Purpose:     Classes to achieve a remotely-scrolled tree in a splitter
  4. //              window that can be scrolled by a scrolled window higher in the
  5. //              hierarchy
  6. // Author:      Julian Smart
  7. // Modified by:
  8. // Created:     8/7/2000
  9. // RCS-ID:      $Id: splittree.cpp,v 1.20 2002/02/28 18:00:33 JS Exp $
  10. // Copyright:   (c) Julian Smart
  11. // Licence:     wxWindows licence
  12. /////////////////////////////////////////////////////////////////////////////
  13.  
  14. // ============================================================================
  15. // declarations
  16. // ============================================================================
  17.  
  18. // ----------------------------------------------------------------------------
  19. // headers
  20. // ----------------------------------------------------------------------------
  21. #ifdef __GNUG__
  22.     #pragma implementation "splittree.h"
  23. #endif
  24.  
  25. // For compilers that support precompilation, includes "wx/wx.h".
  26. #include "wx/wxprec.h"
  27.  
  28. #ifdef __BORLANDC__
  29.     #pragma hdrstop
  30. #endif
  31.  
  32. // for all others, include the necessary headers (this file is usually all you
  33. // need because it includes almost all "standard" wxWindows headers)
  34. #ifndef WX_PRECOMP
  35.     #include "wx/wx.h"
  36. #endif
  37.  
  38. #ifdef __WXMSW__
  39. #include <windows.h>
  40. #include "wx/msw/winundef.h"
  41. #endif
  42.  
  43. #include "wx/gizmos/splittree.h"
  44. #include <math.h>
  45.  
  46. /*
  47.  * wxRemotelyScrolledTreeCtrl
  48.  */
  49.  
  50. #if USE_GENERIC_TREECTRL
  51. IMPLEMENT_CLASS(wxRemotelyScrolledTreeCtrl, wxGenericTreeCtrl)
  52. #else
  53. IMPLEMENT_CLASS(wxRemotelyScrolledTreeCtrl, wxTreeCtrl)
  54. #endif
  55.  
  56. #if USE_GENERIC_TREECTRL
  57. BEGIN_EVENT_TABLE(wxRemotelyScrolledTreeCtrl, wxGenericTreeCtrl)
  58. #else
  59. BEGIN_EVENT_TABLE(wxRemotelyScrolledTreeCtrl, wxTreeCtrl)
  60. #endif
  61.     EVT_SIZE(wxRemotelyScrolledTreeCtrl::OnSize)
  62.     EVT_PAINT(wxRemotelyScrolledTreeCtrl::OnPaint)
  63.     EVT_TREE_ITEM_EXPANDED(-1, wxRemotelyScrolledTreeCtrl::OnExpand)
  64.     EVT_TREE_ITEM_COLLAPSED(-1, wxRemotelyScrolledTreeCtrl::OnExpand)
  65.     EVT_SCROLLWIN(wxRemotelyScrolledTreeCtrl::OnScroll)
  66. END_EVENT_TABLE()
  67.  
  68. wxRemotelyScrolledTreeCtrl::wxRemotelyScrolledTreeCtrl(
  69.     wxWindow* parent, wxWindowID id, const wxPoint& pt,
  70.     const wxSize& sz, long style)
  71.     : wxTreeCtrl(parent, id, pt, sz, style & ~wxTR_ROW_LINES)
  72. {
  73.     m_companionWindow = NULL;
  74.  
  75.     // We draw the row lines ourself so they match what's done
  76.     // by the companion window.  That is why the flag is turned
  77.     // off above, so wxGenericTreeCtrl doesn't draw them in a
  78.     // different colour.
  79.     m_drawRowLines = (style & wxTR_ROW_LINES) != 0;
  80. }
  81.  
  82. wxRemotelyScrolledTreeCtrl::~wxRemotelyScrolledTreeCtrl()
  83. {
  84. }
  85.  
  86. void wxRemotelyScrolledTreeCtrl::HideVScrollbar()
  87. {
  88. #if defined(__WXMSW__)
  89. #if USE_GENERIC_TREECTRL
  90.     if (!IsKindOf(CLASSINFO(wxGenericTreeCtrl)))
  91. #endif
  92.     {
  93.         ::ShowScrollBar((HWND) GetHWND(), SB_VERT, FALSE);
  94.     }
  95. #if USE_GENERIC_TREECTRL
  96.     else
  97.     {
  98.         // Implicit in overriding SetScrollbars
  99.     }
  100. #endif
  101. #endif
  102. }
  103.  
  104. // Number of pixels per user unit (0 or -1 for no scrollbar)
  105. // Length of virtual canvas in user units
  106. // Length of page in user units
  107. void wxRemotelyScrolledTreeCtrl::SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY,
  108.                              int noUnitsX, int noUnitsY,
  109.                              int xPos, int yPos,
  110.                              bool noRefresh)
  111. {
  112. #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)
  113.     if (IsKindOf(CLASSINFO(wxGenericTreeCtrl)))
  114.     {
  115.         wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this;
  116.         win->wxGenericTreeCtrl::SetScrollbars(pixelsPerUnitX, 0, noUnitsX, 0, xPos, 0, noRefresh);
  117.  
  118.         wxScrolledWindow* scrolledWindow = GetScrolledWindow();
  119.         if (scrolledWindow)
  120.         {
  121.             scrolledWindow->SetScrollbars(0, pixelsPerUnitY, 0, noUnitsY, 0, yPos, noRefresh);
  122.         }
  123.     }
  124. #endif
  125. }
  126.  
  127. // In case we're using the generic tree control.
  128. int wxRemotelyScrolledTreeCtrl::GetScrollPos(int orient) const
  129. {
  130.     wxScrolledWindow* scrolledWindow = GetScrolledWindow();
  131.  
  132. #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)
  133.     if (IsKindOf(CLASSINFO(wxGenericTreeCtrl)))
  134.     {
  135.         wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this;
  136.  
  137.         if (orient == wxHORIZONTAL)
  138.             return win->wxGenericTreeCtrl::GetScrollPos(orient);
  139.         else
  140.         {
  141.             return scrolledWindow->GetScrollPos(orient);
  142.         }
  143.     }
  144. #endif
  145.     return 0;
  146. }
  147.  
  148.  
  149. // In case we're using the generic tree control.
  150. // Get the view start
  151. void wxRemotelyScrolledTreeCtrl::GetViewStart(int *x, int *y) const
  152. {
  153.     wxScrolledWindow* scrolledWindow = GetScrolledWindow();
  154.  
  155. #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)
  156.     if (IsKindOf(CLASSINFO(wxGenericTreeCtrl)))
  157.     {
  158.  
  159.         wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this;
  160.         int x1, y1, x2, y2;
  161.         win->wxGenericTreeCtrl::GetViewStart(& x1, & y1);
  162.         * x = x1; * y = y1;
  163.         if (!scrolledWindow)
  164.             return;
  165.  
  166.         scrolledWindow->GetViewStart(& x2, & y2);
  167.         * y = y2;
  168.     }
  169.     else
  170. #endif
  171.     {
  172.         // x is wrong since the horizontal scrollbar is controlled by the
  173.         // tree control, but we probably don't need it.
  174.         scrolledWindow->GetViewStart(x, y);
  175.     }
  176. }
  177.  
  178. // In case we're using the generic tree control.
  179. void wxRemotelyScrolledTreeCtrl::PrepareDC(wxDC& dc)
  180. {
  181. #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)
  182.     if (IsKindOf(CLASSINFO(wxGenericTreeCtrl)))
  183.     {
  184.         wxScrolledWindow* scrolledWindow = GetScrolledWindow();
  185.  
  186.         wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this;
  187.  
  188.         int startX, startY;
  189.         GetViewStart(& startX, & startY);
  190.  
  191.         int xppu1, yppu1, xppu2, yppu2;
  192.         win->wxGenericTreeCtrl::GetScrollPixelsPerUnit(& xppu1, & yppu1);
  193.         scrolledWindow->GetScrollPixelsPerUnit(& xppu2, & yppu2);
  194.  
  195.         dc.SetDeviceOrigin( -startX * xppu1, -startY * yppu2 );
  196.         // dc.SetUserScale( win->GetScaleX(), win->GetScaleY() );
  197.     }
  198. #endif
  199. }
  200.  
  201. // Scroll to the given line (in scroll units where each unit is
  202. // the height of an item)
  203. void wxRemotelyScrolledTreeCtrl::ScrollToLine(int posHoriz, int posVert)
  204. {
  205. #ifdef __WXMSW__
  206. #if USE_GENERIC_TREECTRL
  207.     if (!IsKindOf(CLASSINFO(wxGenericTreeCtrl)))
  208. #endif
  209.     {
  210.         UINT sbCode = SB_THUMBPOSITION;
  211.         HWND vertScrollBar = 0;
  212.         MSWDefWindowProc((WXUINT) WM_VSCROLL, MAKELONG(sbCode, posVert), (WXHWND) vertScrollBar);
  213.     }
  214. #if USE_GENERIC_TREECTRL
  215.     else
  216. #endif
  217. #endif
  218. #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)
  219.     {
  220.         wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this;
  221.         win->Refresh();
  222.         /* Doesn't work yet because scrolling is ignored by Scroll
  223.         int xppu, yppu;
  224.         wxScrolledWindow* scrolledWindow = GetScrolledWindow();
  225.         if (scrolledWindow)
  226.         {
  227.             scrolledWindow->GetScrollPixelsPerUnit(& xppu, & yppu);
  228.             win->Scroll(-1, posVert*yppu);
  229.         }
  230.         */
  231.     }
  232. #endif
  233. }
  234.  
  235. void wxRemotelyScrolledTreeCtrl::OnSize(wxSizeEvent& event)
  236. {
  237.     HideVScrollbar();
  238.     AdjustRemoteScrollbars();
  239.     event.Skip();
  240. }
  241.  
  242. void wxRemotelyScrolledTreeCtrl::OnExpand(wxTreeEvent& event)
  243. {
  244.     AdjustRemoteScrollbars();
  245.     event.Skip();
  246.  
  247.     // If we don't have this, we get some bits of lines still remaining
  248.     if (event.GetEventType() == wxEVT_COMMAND_TREE_ITEM_COLLAPSED)
  249.         Refresh();
  250.  
  251.     // Pass on the event
  252.     if (m_companionWindow)
  253.         m_companionWindow->GetEventHandler()->ProcessEvent(event);
  254. }
  255.  
  256. void wxRemotelyScrolledTreeCtrl::OnPaint(wxPaintEvent& event)
  257. {
  258.     wxPaintDC dc(this);
  259.  
  260.     wxTreeCtrl::OnPaint(event);
  261.  
  262.     if (! m_drawRowLines)
  263.         return;
  264.  
  265.     // Reset the device origin since it may have been set
  266.     dc.SetDeviceOrigin(0, 0);
  267.  
  268.     wxPen pen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT), 1, wxSOLID);
  269.     dc.SetPen(pen);
  270.     dc.SetBrush(* wxTRANSPARENT_BRUSH);
  271.  
  272.     wxSize clientSize = GetClientSize();
  273.     wxRect itemRect;
  274.     int cy=0;
  275.     wxTreeItemId h, lastH;
  276.     for(h=GetFirstVisibleItem();h;h=GetNextVisible(h))
  277.     {
  278.         if (GetBoundingRect(h, itemRect))
  279.         {
  280.             cy = itemRect.GetTop();
  281.             dc.DrawLine(0, cy, clientSize.x, cy);
  282.             lastH = h;
  283.         }
  284.     }
  285.     if (lastH.IsOk() && GetBoundingRect(lastH, itemRect))
  286.     {
  287.         cy = itemRect.GetBottom();
  288.         dc.DrawLine(0, cy, clientSize.x, cy);
  289.     }
  290. }
  291.  
  292.  
  293. // Adjust the containing wxScrolledWindow's scrollbars appropriately
  294. void wxRemotelyScrolledTreeCtrl::AdjustRemoteScrollbars()
  295. {
  296. #if USE_GENERIC_TREECTRL || !defined(__WXMSW__)
  297.     if (IsKindOf(CLASSINFO(wxGenericTreeCtrl)))
  298.     {
  299.         // This is for the generic tree control.
  300.         // It calls SetScrollbars which has been overridden
  301.         // to adjust the parent scrolled window vertical
  302.         // scrollbar.
  303.         ((wxGenericTreeCtrl*) this)->AdjustMyScrollbars();
  304.         return;
  305.     }
  306.     else
  307. #endif
  308.     {
  309.         // This is for the wxMSW tree control
  310.         wxScrolledWindow* scrolledWindow = GetScrolledWindow();
  311.         if (scrolledWindow)
  312.         {
  313.             wxRect itemRect;
  314.             if (GetBoundingRect(GetRootItem(), itemRect))
  315.             {
  316.                 // Actually, the real height seems to be 1 less than reported
  317.                 // (e.g. 16 instead of 16)
  318.                 int itemHeight = itemRect.GetHeight() - 1;
  319.  
  320.                 int w, h;
  321.                 GetClientSize(&w, &h);
  322.  
  323.                 wxRect rect(0, 0, 0, 0);
  324.                 CalcTreeSize(rect);
  325.  
  326.                 double f = ((double) (rect.GetHeight()) / (double) itemHeight)  ;
  327.                 int treeViewHeight = (int) ceil(f);
  328.  
  329.                 int scrollPixelsPerLine = itemHeight;
  330.                 int scrollPos = - (itemRect.y / itemHeight);
  331.  
  332.                 scrolledWindow->SetScrollbars(0, scrollPixelsPerLine, 0, treeViewHeight, 0, scrollPos);
  333.  
  334.                 // Ensure that when a scrollbar becomes hidden or visible,
  335.                 // the contained window sizes are right.
  336.                 // Problem: this is called too early (?)
  337.                 wxSizeEvent event(scrolledWindow->GetSize(), scrolledWindow->GetId());
  338.                 scrolledWindow->GetEventHandler()->ProcessEvent(event);
  339.             }
  340.         }
  341.     }
  342. }
  343.  
  344.  
  345. // Calculate the area that contains both rectangles
  346. static wxRect CombineRectangles(const wxRect& rect1, const wxRect& rect2)
  347. {
  348.     wxRect rect;
  349.  
  350.     int right1 = rect1.GetRight();
  351.     int bottom1 = rect1.GetBottom();
  352.     int right2 = rect2.GetRight();
  353.     int bottom2 = rect2.GetBottom();
  354.  
  355.     wxPoint topLeft = wxPoint(wxMin(rect1.x, rect2.x), wxMin(rect1.y, rect2.y));
  356.     wxPoint bottomRight = wxPoint(wxMax(right1, right2), wxMax(bottom1, bottom2));
  357.  
  358.     rect.x = topLeft.x; rect.y = topLeft.y;
  359.     rect.SetRight(bottomRight.x);
  360.     rect.SetBottom(bottomRight.y);
  361.  
  362.     return rect;
  363. }
  364.  
  365.  
  366. // Calculate the tree overall size so we can set the scrollbar
  367. // correctly
  368. void wxRemotelyScrolledTreeCtrl::CalcTreeSize(wxRect& rect)
  369. {
  370.     CalcTreeSize(GetRootItem(), rect);
  371. }
  372.  
  373. void wxRemotelyScrolledTreeCtrl::CalcTreeSize(const wxTreeItemId& id, wxRect& rect)
  374. {
  375.     // More efficient implementation would be to find the last item (but how?)
  376.     // Q: is the bounding rect relative to the top of the virtual tree workspace
  377.     // or the top of the window? How would we convert?
  378.     wxRect itemSize;
  379.     if (GetBoundingRect(id, itemSize))
  380.     {
  381.         rect = CombineRectangles(rect, itemSize);
  382.     }
  383.  
  384.     long cookie;
  385.     wxTreeItemId childId = GetFirstChild(id, cookie);
  386.     while (childId != 0)
  387.     {
  388.         CalcTreeSize(childId, rect);
  389.         childId = GetNextChild(childId, cookie);
  390.     }
  391. }
  392.  
  393. // Find the scrolled window that contains this control
  394. wxScrolledWindow* wxRemotelyScrolledTreeCtrl::GetScrolledWindow() const
  395. {
  396.     wxWindow* parent = wxWindow::GetParent();
  397.     while (parent)
  398.     {
  399.         if (parent->IsKindOf(CLASSINFO(wxScrolledWindow)))
  400.             return (wxScrolledWindow*) parent;
  401.         parent = parent->GetParent();
  402.     }
  403.     return NULL;
  404. }
  405.  
  406. void wxRemotelyScrolledTreeCtrl::OnScroll(wxScrollWinEvent& event)
  407. {
  408.     int orient = event.GetOrientation();
  409.     if (orient == wxHORIZONTAL)
  410.     {
  411.         event.Skip();
  412.         return;
  413.     }
  414.     wxScrolledWindow* scrollWin = GetScrolledWindow();
  415.     if (!scrollWin)
  416.         return;
  417.  
  418.     int x, y;
  419.     scrollWin->GetViewStart(& x, & y);
  420.  
  421.     ScrollToLine(-1, y);
  422. }
  423.  
  424. /*
  425.  * wxTreeCompanionWindow
  426.  *
  427.  * A window displaying values associated with tree control items.
  428.  */
  429.  
  430. IMPLEMENT_CLASS(wxTreeCompanionWindow, wxWindow)
  431.  
  432. BEGIN_EVENT_TABLE(wxTreeCompanionWindow, wxWindow)
  433.     EVT_PAINT(wxTreeCompanionWindow::OnPaint)
  434.     EVT_SCROLLWIN(wxTreeCompanionWindow::OnScroll)
  435.     EVT_TREE_ITEM_EXPANDED(-1, wxTreeCompanionWindow::OnExpand)
  436.     EVT_TREE_ITEM_COLLAPSED(-1, wxTreeCompanionWindow::OnExpand)
  437. END_EVENT_TABLE()
  438.  
  439. wxTreeCompanionWindow::wxTreeCompanionWindow(wxWindow* parent, wxWindowID id,
  440.       const wxPoint& pos,
  441.       const wxSize& sz,
  442.       long style):
  443.     wxWindow(parent, id, pos, sz, style)
  444. {
  445.     m_treeCtrl = NULL;
  446. }
  447.  
  448. void wxTreeCompanionWindow::DrawItem(wxDC& dc, wxTreeItemId id, const wxRect& rect)
  449. {
  450.     // TEST CODE
  451. #if 1
  452.     if (m_treeCtrl)
  453.     {
  454.         wxString text = m_treeCtrl->GetItemText(id);
  455.         dc.SetTextForeground(* wxBLACK);
  456.         dc.SetBackgroundMode(wxTRANSPARENT);
  457.  
  458.         int textW, textH;
  459.         dc.GetTextExtent(text, & textW, & textH);
  460.  
  461.         int x = 5;
  462.         int y = rect.GetY() + wxMax(0, (rect.GetHeight() - textH) / 2);
  463.  
  464.         dc.DrawText(text, x, y);
  465.     }
  466. #endif
  467. }
  468.  
  469. void wxTreeCompanionWindow::OnPaint(wxPaintEvent& event)
  470. {
  471.     wxPaintDC dc(this);
  472.  
  473.     if (!m_treeCtrl)
  474.         return;
  475.  
  476.         wxPen pen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT), 1, wxSOLID);
  477.     dc.SetPen(pen);
  478.     dc.SetBrush(* wxTRANSPARENT_BRUSH);
  479.     wxFont font(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
  480.     dc.SetFont(font);
  481.  
  482.     wxSize clientSize = GetClientSize();
  483.     wxRect itemRect;
  484.     int cy=0;
  485.     wxTreeItemId h, lastH;
  486.     for(h=m_treeCtrl->GetFirstVisibleItem();h;h=m_treeCtrl->GetNextVisible(h))
  487.     {
  488.         if (m_treeCtrl->GetBoundingRect(h, itemRect))
  489.         {
  490.             cy = itemRect.GetTop();
  491.             wxRect drawItemRect(0, cy, clientSize.x, itemRect.GetHeight());
  492.  
  493.             lastH = h;
  494.  
  495.             // Draw the actual item
  496.             DrawItem(dc, h, drawItemRect);
  497.             dc.DrawLine(0, cy, clientSize.x, cy);
  498.         }
  499.     }
  500.     if (lastH.IsOk() && m_treeCtrl->GetBoundingRect(lastH, itemRect))
  501.     {
  502.         cy = itemRect.GetBottom();
  503.         dc.DrawLine(0, cy, clientSize.x, cy);
  504.     }
  505. }
  506.  
  507. void wxTreeCompanionWindow::OnScroll(wxScrollWinEvent& event)
  508. {
  509.     int orient = event.GetOrientation();
  510.     if (orient == wxHORIZONTAL)
  511.     {
  512.         event.Skip();
  513.         return;
  514.     }
  515.     if (!m_treeCtrl)
  516.         return;
  517.  
  518.     // TODO: scroll the window physically instead of just refreshing.
  519.     Refresh(TRUE);
  520. }
  521.  
  522. void wxTreeCompanionWindow::OnExpand(wxTreeEvent& event)
  523. {
  524.     // TODO: something more optimized than simply refresh the whole
  525.     // window when the tree is expanded/collapsed. Tricky.
  526.     Refresh();
  527. }
  528.  
  529. /*
  530.  * wxThinSplitterWindow
  531.  */
  532.  
  533. IMPLEMENT_CLASS(wxThinSplitterWindow, wxSplitterWindow)
  534.  
  535. BEGIN_EVENT_TABLE(wxThinSplitterWindow, wxSplitterWindow)
  536.     EVT_SIZE(wxThinSplitterWindow::OnSize)
  537. END_EVENT_TABLE()
  538.  
  539. wxThinSplitterWindow::wxThinSplitterWindow(wxWindow* parent, wxWindowID id,
  540.       const wxPoint& pos,
  541.       const wxSize& sz,
  542.       long style):
  543.       wxSplitterWindow(parent, id, pos, sz, style)
  544. {
  545. }
  546.  
  547. void wxThinSplitterWindow::SizeWindows()
  548. {
  549.     // The client size may have changed inbetween
  550.     // the sizing of the first window and the sizing of
  551.     // the second. So repeat SizeWindows.
  552.     wxSplitterWindow::SizeWindows();
  553.     wxSplitterWindow::SizeWindows();
  554. }
  555.  
  556. // Tests for x, y over sash
  557. bool wxThinSplitterWindow::SashHitTest(int x, int y, int tolerance)
  558. {
  559.     return wxSplitterWindow::SashHitTest(x, y, 4);
  560. }
  561.  
  562. void wxThinSplitterWindow::DrawSash(wxDC& dc)
  563. {
  564.     if ( m_sashPosition == 0 || !m_windowTwo)
  565.         return;
  566.     if (GetWindowStyle() & wxSP_NOSASH)
  567.         return;
  568.  
  569.     int w, h;
  570.     GetClientSize(&w, &h);
  571.  
  572.     if ( m_splitMode == wxSPLIT_VERTICAL )
  573.     {
  574.         dc.SetPen(* m_facePen);
  575.         dc.SetBrush(* m_faceBrush);
  576.         int h1 = h-1;
  577.         int y1 = 0;
  578.         if ( (GetWindowStyleFlag() & wxSP_BORDER) != wxSP_BORDER && (GetWindowStyleFlag() & wxSP_3DBORDER) != wxSP_3DBORDER )
  579.             h1 += 1; // Not sure why this is necessary...
  580.         if ( (GetWindowStyleFlag() & wxSP_3DBORDER) == wxSP_3DBORDER)
  581.         {
  582.             y1 = 2; h1 -= 3;
  583.         }
  584.         dc.DrawRectangle(m_sashPosition, y1, m_sashSize, h1);
  585.     }
  586.     else
  587.     {
  588.         dc.SetPen(* m_facePen);
  589.         dc.SetBrush(* m_faceBrush);
  590.         int w1 = w-1;
  591.         int x1 = 0;
  592.         if ( (GetWindowStyleFlag() & wxSP_BORDER) != wxSP_BORDER && (GetWindowStyleFlag() & wxSP_3DBORDER) != wxSP_3DBORDER )
  593.             w1 ++;
  594.         if ( (GetWindowStyleFlag() & wxSP_3DBORDER) == wxSP_3DBORDER)
  595.         {
  596.             x1 = 2; w1 -= 3;
  597.         }
  598.         dc.DrawRectangle(x1, m_sashPosition, w1, m_sashSize);
  599.     }
  600.  
  601.     dc.SetPen(wxNullPen);
  602.     dc.SetBrush(wxNullBrush);
  603. }
  604.  
  605. void wxThinSplitterWindow::OnSize(wxSizeEvent& event)
  606. {
  607.     wxSplitterWindow::OnSize(event);
  608. }
  609.  
  610. /*
  611.  * wxSplitterScrolledWindow
  612.  */
  613.  
  614. IMPLEMENT_CLASS(wxSplitterScrolledWindow, wxScrolledWindow)
  615.  
  616. BEGIN_EVENT_TABLE(wxSplitterScrolledWindow, wxScrolledWindow)
  617.     EVT_SCROLLWIN(wxSplitterScrolledWindow::OnScroll)
  618.     EVT_SIZE(wxSplitterScrolledWindow::OnSize)
  619. END_EVENT_TABLE()
  620.  
  621. wxSplitterScrolledWindow::wxSplitterScrolledWindow(wxWindow* parent, wxWindowID id,
  622.       const wxPoint& pos,
  623.       const wxSize& sz,
  624.       long style):
  625.       wxScrolledWindow(parent, id, pos, sz, style)
  626. {
  627. }
  628.  
  629. void wxSplitterScrolledWindow::OnSize(wxSizeEvent& event)
  630. {
  631.     wxSize sz = GetClientSize();
  632.     if (GetChildren().First())
  633.     {
  634.         ((wxWindow*) GetChildren().First()->Data())->SetSize(0, 0, sz.x, sz.y);
  635.     }
  636. }
  637.  
  638. void wxSplitterScrolledWindow::OnScroll(wxScrollWinEvent& event)
  639. {
  640.     // Ensure that events being propagated back up the window hierarchy
  641.     // don't cause an infinite loop
  642.     static bool inOnScroll = FALSE;
  643.     if (inOnScroll)
  644.     {
  645.         event.Skip();
  646.         return;
  647.     }
  648.     inOnScroll = TRUE;
  649.  
  650.     int orient = event.GetOrientation();
  651.  
  652.     int nScrollInc = CalcScrollInc(event);
  653.     if (nScrollInc == 0)
  654.     {
  655.         inOnScroll = FALSE;
  656.         return;
  657.     }
  658.  
  659.     if (orient == wxHORIZONTAL)
  660.     {
  661.         inOnScroll = FALSE;
  662.         event.Skip();
  663.         return;
  664. #if 0
  665.         int newPos = m_xScrollPosition + nScrollInc;
  666.         SetScrollPos(wxHORIZONTAL, newPos, TRUE );
  667. #endif
  668.     }
  669.     else
  670.     {
  671.         int newPos = m_yScrollPosition + nScrollInc;
  672.         SetScrollPos(wxVERTICAL, newPos, TRUE );
  673.     }
  674.  
  675.     if (orient == wxHORIZONTAL)
  676.     {
  677.         m_xScrollPosition += nScrollInc;
  678.     }
  679.     else
  680.     {
  681.         m_yScrollPosition += nScrollInc;
  682.     }
  683.  
  684.     // Find targets in splitter window and send the event to them
  685.     wxNode* node = GetChildren().First();
  686.     while (node)
  687.     {
  688.         wxWindow* child = (wxWindow*) node->Data();
  689.         if (child->IsKindOf(CLASSINFO(wxSplitterWindow)))
  690.         {
  691.             wxSplitterWindow* splitter = (wxSplitterWindow*) child;
  692.             if (splitter->GetWindow1())
  693.                 splitter->GetWindow1()->ProcessEvent(event);
  694.             if (splitter->GetWindow2())
  695.                 splitter->GetWindow2()->ProcessEvent(event);
  696.             break;
  697.         }
  698.         node = node->Next();
  699.     }
  700.  
  701. #ifdef __WXMAC__
  702.     m_targetWindow->MacUpdateImmediately() ;
  703. #endif
  704.  
  705.     inOnScroll = FALSE;
  706. }
  707.  
  708.