home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / include / wx / generic / splitter.h < prev    next >
C/C++ Source or Header  |  2002-11-04  |  15KB  |  408 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        wx/splitter.h
  3. // Purpose:     wxSplitterWindow class
  4. // Author:      Julian Smart
  5. // Modified by:
  6. // Created:     01/02/97
  7. // RCS-ID:      $Id: splitter.h,v 1.32.2.1 2002/10/29 21:47:27 RR Exp $
  8. // Copyright:   (c) Julian Smart and Markus Holzem
  9. // Licence:     wxWindows license
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #ifndef __SPLITTERH_G__
  13. #define __SPLITTERH_G__
  14.  
  15. #if defined(__GNUG__) && !defined(__APPLE__)
  16.     #pragma interface "splitter.h"
  17. #endif
  18.  
  19. #include "wx/window.h"                      // base class declaration
  20. #include "wx/containr.h"                    // wxControlContainer
  21.  
  22. class WXDLLEXPORT wxSplitterEvent;
  23.  
  24. // ---------------------------------------------------------------------------
  25. // splitter constants
  26. // ---------------------------------------------------------------------------
  27.  
  28. enum wxSplitMode
  29. {
  30.     wxSPLIT_HORIZONTAL = 1,
  31.     wxSPLIT_VERTICAL
  32. };
  33.  
  34. enum
  35. {
  36.     wxSPLIT_DRAG_NONE,
  37.     wxSPLIT_DRAG_DRAGGING,
  38.     wxSPLIT_DRAG_LEFT_DOWN
  39. };
  40.  
  41. // ---------------------------------------------------------------------------
  42. // wxSplitterWindow maintains one or two panes, with
  43. // an optional vertical or horizontal split which
  44. // can be used with the mouse or programmatically.
  45. // ---------------------------------------------------------------------------
  46.  
  47. // TODO:
  48. // 1) Perhaps make the borders sensitive to dragging in order to create a split.
  49. //    The MFC splitter window manages scrollbars as well so is able to
  50. //    put sash buttons on the scrollbars, but we probably don't want to go down
  51. //    this path.
  52. // 2) for wxWindows 2.0, we must find a way to set the WS_CLIPCHILDREN style
  53. //    to prevent flickering. (WS_CLIPCHILDREN doesn't work in all cases so can't be
  54. //    standard).
  55.  
  56. class WXDLLEXPORT wxSplitterWindow: public wxWindow
  57. {
  58. public:
  59.  
  60. ////////////////////////////////////////////////////////////////////////////
  61. // Public API
  62.  
  63.     // Default constructor
  64.     wxSplitterWindow()
  65.     {
  66.         Init();
  67.     }
  68.  
  69.     // Normal constructor
  70.     wxSplitterWindow(wxWindow *parent, wxWindowID id = -1,
  71.                      const wxPoint& pos = wxDefaultPosition,
  72.                      const wxSize& size = wxDefaultSize,
  73.                      long style = wxSP_3D,
  74.                      const wxString& name = wxT("splitter"))
  75.     {
  76.         Init();
  77.         Create(parent, id, pos, size, style, name);
  78.     }
  79.  
  80.     virtual ~wxSplitterWindow();
  81.  
  82.     bool Create(wxWindow *parent, wxWindowID id = -1,
  83.                      const wxPoint& pos = wxDefaultPosition,
  84.                      const wxSize& size = wxDefaultSize,
  85.                      long style = wxSP_3D,
  86.                      const wxString& name = wxT("splitter"));
  87.  
  88.     // Gets the only or left/top pane
  89.     wxWindow *GetWindow1() const { return m_windowOne; }
  90.  
  91.     // Gets the right/bottom pane
  92.     wxWindow *GetWindow2() const { return m_windowTwo; }
  93.  
  94.     // Sets the split mode
  95.     void SetSplitMode(int mode)
  96.     {
  97.         wxASSERT_MSG( mode == wxSPLIT_VERTICAL || mode == wxSPLIT_HORIZONTAL,
  98.                       _T("invalid split mode") );
  99.  
  100.         m_splitMode = (wxSplitMode)mode;
  101.     }
  102.  
  103.     // Gets the split mode
  104.     wxSplitMode GetSplitMode() const { return m_splitMode; };
  105.  
  106.     // Initialize with one window
  107.     void Initialize(wxWindow *window);
  108.  
  109.     // Associates the given window with window 2, drawing the appropriate sash
  110.     // and changing the split mode.
  111.     // Does nothing and returns FALSE if the window is already split.
  112.     // A sashPosition of 0 means choose a default sash position,
  113.     // negative sashPosition specifies the size of right/lower pane as it's
  114.     // absolute value rather than the size of left/upper pane.
  115.     virtual bool SplitVertically(wxWindow *window1,
  116.                                  wxWindow *window2,
  117.                                  int sashPosition = 0)
  118.         { return DoSplit(wxSPLIT_VERTICAL, window1, window2, sashPosition); }
  119.     virtual bool SplitHorizontally(wxWindow *window1,
  120.                                    wxWindow *window2,
  121.                                    int sashPosition = 0)
  122.         { return DoSplit(wxSPLIT_HORIZONTAL, window1, window2, sashPosition); }
  123.  
  124.     // Removes the specified (or second) window from the view
  125.     // Doesn't actually delete the window.
  126.     bool Unsplit(wxWindow *toRemove = (wxWindow *) NULL);
  127.  
  128.     // Replaces one of the windows with another one (neither old nor new
  129.     // parameter should be NULL)
  130.     bool ReplaceWindow(wxWindow *winOld, wxWindow *winNew);
  131.  
  132.     // Is the window split?
  133.     bool IsSplit() const { return (m_windowTwo != NULL); }
  134.  
  135.     // Sets the sash size
  136.     void SetSashSize(int width) { m_sashSize = width; }
  137.  
  138.     // Sets the border size
  139.     void SetBorderSize(int width) { m_borderSize = width; }
  140.  
  141.     // Gets the sash size
  142.     int GetSashSize() const { return m_sashSize; }
  143.  
  144.     // Gets the border size
  145.     int GetBorderSize() const { return m_borderSize; }
  146.  
  147.     // Set the sash position
  148.     void SetSashPosition(int position, bool redraw = TRUE);
  149.  
  150.     // Gets the sash position
  151.     int GetSashPosition() const { return m_sashPosition; }
  152.  
  153.     // If this is zero, we can remove panes by dragging the sash.
  154.     void SetMinimumPaneSize(int min);
  155.     int GetMinimumPaneSize() const { return m_minimumPaneSize; }
  156.  
  157.     // NB: the OnXXX() functions below are for backwards compatibility only,
  158.     //     don't use them in new code but handle the events instead!
  159.  
  160.     // called when the sash position is about to change, may return a new value
  161.     // for the sash or -1 to prevent the change from happening at all
  162.     virtual int OnSashPositionChanging(int newSashPosition);
  163.  
  164.     // Called when the sash position is about to be changed, return
  165.     // FALSE from here to prevent the change from taking place.
  166.     // Repositions sash to minimum position if pane would be too small.
  167.     // newSashPosition here is always positive or zero.
  168.     virtual bool OnSashPositionChange(int newSashPosition);
  169.  
  170.     // If the sash is moved to an extreme position, a subwindow
  171.     // is removed from the splitter window, and the app is
  172.     // notified. The app should delete or hide the window.
  173.     virtual void OnUnsplit(wxWindow *removed);
  174.  
  175.     // Called when the sash is double-clicked.
  176.     // The default behaviour is to remove the sash if the
  177.     // minimum pane size is zero.
  178.     virtual void OnDoubleClickSash(int x, int y);
  179.  
  180. ////////////////////////////////////////////////////////////////////////////
  181. // Implementation
  182.  
  183.     // Paints the border and sash
  184.     void OnPaint(wxPaintEvent& event);
  185.  
  186.     // Handles mouse events
  187.     void OnMouseEvent(wxMouseEvent& ev);
  188.  
  189.     // Adjusts the panes
  190.     void OnSize(wxSizeEvent& event);
  191.  
  192.     // In live mode, resize child windows in idle time
  193.     void OnIdle(wxIdleEvent& event);
  194.  
  195.     // Draws borders
  196.     virtual void DrawBorders(wxDC& dc);
  197.  
  198.     // Draws the sash
  199.     virtual void DrawSash(wxDC& dc);
  200.  
  201.     // Draws the sash tracker (for whilst moving the sash)
  202.     virtual void DrawSashTracker(int x, int y);
  203.  
  204.     // Tests for x, y over sash
  205.     virtual bool SashHitTest(int x, int y, int tolerance = 2);
  206.  
  207.     // Resizes subwindows
  208.     virtual void SizeWindows();
  209.  
  210.     // Initialize colours
  211.     void InitColours();
  212.  
  213.     void SetNeedUpdating(bool needUpdating) { m_needUpdating = needUpdating; }
  214.     bool GetNeedUpdating() const { return m_needUpdating ; }
  215.  
  216. protected:
  217.     // event handlers
  218. #ifdef __WXMSW__
  219.     void OnSetCursor(wxSetCursorEvent& event);
  220. #endif // wxMSW
  221.  
  222.     // send the given event, return FALSE if the event was processed and vetoed
  223.     // by the user code
  224.     inline bool DoSendEvent(wxSplitterEvent& event);
  225.  
  226. protected:
  227.     // common part of all ctors
  228.     void Init();
  229.  
  230.     // common part of SplitVertically() and SplitHorizontally()
  231.     bool DoSplit(wxSplitMode mode,
  232.                  wxWindow *window1, wxWindow *window2,
  233.                  int sashPosition);
  234.  
  235.     // adjusts sash position with respect to min. pane and window sizes
  236.     int AdjustSashPosition(int sashPos) const;
  237.  
  238.     // get either width or height depending on the split mode
  239.     int GetWindowSize() const;
  240.  
  241.     // convert the user specified sash position which may be > 0 (as is), < 0
  242.     // (specifying the size of the right pane) or 0 (use default) to the real
  243.     // position to be passed to DoSetSashPosition()
  244.     int ConvertSashPosition(int sashPos) const;
  245.  
  246.     // set the real sash position, sashPos here must be positive
  247.     //
  248.     // returns TRUE if the sash position has been changed, FALSE otherwise
  249.     bool DoSetSashPosition(int sashPos);
  250.  
  251.     // set the sash position and send an event about it having been changed
  252.     void SetSashPositionAndNotify(int sashPos);
  253.  
  254.     // set the cursor appropriate for the current split mode
  255.     void SetResizeCursor();
  256.  
  257.     wxSplitMode m_splitMode;
  258.     bool        m_permitUnsplitAlways;
  259.     bool        m_needUpdating; // when in live mode, set this to TRUE to resize children in idle
  260.     wxWindow*   m_windowOne;
  261.     wxWindow*   m_windowTwo;
  262.     int         m_dragMode;
  263.     int         m_oldX;
  264.     int         m_oldY;
  265.     int         m_borderSize;
  266.     int         m_sashSize;     // Sash width or height
  267.     int         m_sashPosition; // Number of pixels from left or top
  268.     int         m_requestedSashPosition;
  269.     int         m_sashPositionCurrent; // while dragging
  270.     int         m_firstX;
  271.     int         m_firstY;
  272.     int         m_minimumPaneSize;
  273.     wxCursor    m_sashCursorWE;
  274.     wxCursor    m_sashCursorNS;
  275.     wxPen*      m_sashTrackerPen;
  276.     wxPen*      m_lightShadowPen;
  277.     wxPen*      m_mediumShadowPen;
  278.     wxPen*      m_darkShadowPen;
  279.     wxPen*      m_hilightPen;
  280.     wxBrush*    m_faceBrush;
  281.     wxPen*      m_facePen;
  282.  
  283. private:
  284.     WX_DECLARE_CONTROL_CONTAINER();
  285.  
  286.     DECLARE_DYNAMIC_CLASS(wxSplitterWindow)
  287.     DECLARE_EVENT_TABLE()
  288. };
  289.  
  290. // ----------------------------------------------------------------------------
  291. // event class and macros
  292. // ----------------------------------------------------------------------------
  293.  
  294. // we reuse the same class for all splitter event types because this is the
  295. // usual wxWin convention, but the three event types have different kind of
  296. // data associated with them, so the accessors can be only used if the real
  297. // event type matches with the one for which the accessors make sense
  298. class WXDLLEXPORT wxSplitterEvent : public wxNotifyEvent
  299. {
  300. public:
  301.     wxSplitterEvent(wxEventType type = wxEVT_NULL,
  302.                     wxSplitterWindow *splitter = (wxSplitterWindow *)NULL)
  303.         : wxNotifyEvent(type)
  304.     {
  305.         SetEventObject(splitter);
  306.         if (splitter) m_id = splitter->GetId();
  307.     }
  308.  
  309.     // SASH_POS_CHANGED methods
  310.  
  311.     // setting the sash position to -1 prevents the change from taking place at
  312.     // all
  313.     void SetSashPosition(int pos)
  314.     {
  315.         wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED
  316.                 || GetEventType() == wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING);
  317.  
  318.         m_data.pos = pos;
  319.     }
  320.  
  321.     int GetSashPosition() const
  322.     {
  323.         wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED
  324.                 || GetEventType() == wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING);
  325.  
  326.         return m_data.pos;
  327.     }
  328.  
  329.     // UNSPLIT event methods
  330.     wxWindow *GetWindowBeingRemoved() const
  331.     {
  332.         wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_UNSPLIT );
  333.  
  334.         return m_data.win;
  335.     }
  336.  
  337.     // DCLICK event methods
  338.     int GetX() const
  339.     {
  340.         wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_DOUBLECLICKED );
  341.  
  342.         return m_data.pt.x;
  343.     }
  344.  
  345.     int GetY() const
  346.     {
  347.         wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_DOUBLECLICKED );
  348.  
  349.         return m_data.pt.y;
  350.     }
  351.  
  352. private:
  353.     friend class WXDLLEXPORT wxSplitterWindow;
  354.  
  355.     // data for the different types of event
  356.     union
  357.     {
  358.         int pos;            // position for SASH_POS_CHANGED event
  359.         wxWindow *win;      // window being removed for UNSPLIT event
  360.         struct
  361.         {
  362.             int x, y;
  363.         } pt;               // position of double click for DCLICK event
  364.     } m_data;
  365.  
  366.     DECLARE_DYNAMIC_CLASS(wxSplitterEvent)
  367. };
  368.  
  369. typedef void (wxEvtHandler::*wxSplitterEventFunction)(wxSplitterEvent&);
  370.  
  371. #define EVT_SPLITTER_SASH_POS_CHANGED(id, fn)                               \
  372.   DECLARE_EVENT_TABLE_ENTRY(                                                \
  373.     wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED,                                \
  374.     id,                                                                     \
  375.     -1,                                                                     \
  376.     (wxObjectEventFunction)(wxEventFunction)(wxSplitterEventFunction) &fn,  \
  377.     NULL                                                                    \
  378.   ),
  379.  
  380. #define EVT_SPLITTER_SASH_POS_CHANGING(id, fn)                              \
  381.   DECLARE_EVENT_TABLE_ENTRY(                                                \
  382.     wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING,                               \
  383.     id,                                                                     \
  384.     -1,                                                                     \
  385.     (wxObjectEventFunction)(wxEventFunction)(wxSplitterEventFunction) &fn,  \
  386.     NULL                                                                    \
  387.   ),
  388.  
  389. #define EVT_SPLITTER_DCLICK(id, fn)                                         \
  390.   DECLARE_EVENT_TABLE_ENTRY(                                                \
  391.     wxEVT_COMMAND_SPLITTER_DOUBLECLICKED,                                   \
  392.     id,                                                                     \
  393.     -1,                                                                     \
  394.     (wxObjectEventFunction)(wxEventFunction)(wxSplitterEventFunction) &fn,  \
  395.     NULL                                                                    \
  396.   ),
  397.  
  398. #define EVT_SPLITTER_UNSPLIT(id, fn)                                        \
  399.   DECLARE_EVENT_TABLE_ENTRY(                                                \
  400.     wxEVT_COMMAND_SPLITTER_UNSPLIT,                                         \
  401.     id,                                                                     \
  402.     -1,                                                                     \
  403.     (wxObjectEventFunction)(wxEventFunction)(wxSplitterEventFunction) &fn,  \
  404.     NULL                                                                    \
  405.   ),
  406.  
  407. #endif // __SPLITTERH_G__
  408.