1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxSplitterWindow class 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart and Markus Holzem 
   9 // Licence:     wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #ifndef __SPLITTERH_G__ 
  13 #define __SPLITTERH_G__ 
  16     #pragma interface "splitter.h" 
  19 #include "wx/window.h"                      // base class declaration 
  21 class WXDLLEXPORT wxSplitterEvent
; 
  23 // --------------------------------------------------------------------------- 
  25 // --------------------------------------------------------------------------- 
  29     wxSPLIT_HORIZONTAL 
= 1, 
  36     wxSPLIT_DRAG_DRAGGING
, 
  37     wxSPLIT_DRAG_LEFT_DOWN
 
  40 // --------------------------------------------------------------------------- 
  41 // wxSplitterWindow maintains one or two panes, with 
  42 // an optional vertical or horizontal split which 
  43 // can be used with the mouse or programmatically. 
  44 // --------------------------------------------------------------------------- 
  47 // 1) Perhaps make the borders sensitive to dragging in order to create a split. 
  48 //    The MFC splitter window manages scrollbars as well so is able to 
  49 //    put sash buttons on the scrollbars, but we probably don't want to go down 
  51 // 2) for wxWindows 2.0, we must find a way to set the WS_CLIPCHILDREN style 
  52 //    to prevent flickering. (WS_CLIPCHILDREN doesn't work in all cases so can't be 
  55 class WXDLLEXPORT wxSplitterWindow
: public wxWindow
 
  59 //////////////////////////////////////////////////////////////////////////// 
  62     // Default constructor 
  69     wxSplitterWindow(wxWindow 
*parent
, wxWindowID id 
= -1, 
  70                      const wxPoint
& pos 
= wxDefaultPosition
, 
  71                      const wxSize
& size 
= wxDefaultSize
, 
  72                      long style 
= wxSP_3D
|wxCLIP_CHILDREN
, 
  73                      const wxString
& name 
= "splitter") 
  76         Create(parent
, id
, pos
, size
, style
, name
); 
  81     bool Create(wxWindow 
*parent
, wxWindowID id 
= -1, 
  82                      const wxPoint
& pos 
= wxDefaultPosition
, 
  83                      const wxSize
& size 
= wxDefaultSize
, 
  84                      long style 
= wxSP_3D
|wxCLIP_CHILDREN
, 
  85                      const wxString
& name 
= "splitter"); 
  87     // Gets the only or left/top pane 
  88     wxWindow 
*GetWindow1() const { return m_windowOne
; } 
  90     // Gets the right/bottom pane 
  91     wxWindow 
*GetWindow2() const { return m_windowTwo
; } 
  93     // Sets the split mode 
  94     void SetSplitMode(int mode
) { m_splitMode 
= mode
; } 
  96     // Gets the split mode 
  97     int GetSplitMode() const { return m_splitMode
; }; 
  99     // Initialize with one window 
 100     void Initialize(wxWindow 
*window
); 
 102     // Associates the given window with window 2, drawing the appropriate sash 
 103     // and changing the split mode. 
 104     // Does nothing and returns FALSE if the window is already split. 
 105     // A sashPosition of 0 means choose a default sash position, 
 106     // negative sashPosition specifies the size of right/lower pane as it's 
 107     // absolute value rather than the size of left/upper pane. 
 108     virtual bool SplitVertically(wxWindow 
*window1
, 
 110                                  int sashPosition 
= 0); 
 111     virtual bool SplitHorizontally(wxWindow 
*window1
, 
 113                                    int sashPosition 
= 0); 
 115     // Removes the specified (or second) window from the view 
 116     // Doesn't actually delete the window. 
 117     bool Unsplit(wxWindow 
*toRemove 
= (wxWindow 
*) NULL
); 
 119     // Replaces one of the windows with another one (neither old nor new 
 120     // parameter should be NULL) 
 121     bool ReplaceWindow(wxWindow 
*winOld
, wxWindow 
*winNew
); 
 123     // Is the window split? 
 124     bool IsSplit() const { return (m_windowTwo 
!= NULL
); } 
 126     // Sets the sash size 
 127     void SetSashSize(int width
) { m_sashSize 
= width
; } 
 129     // Sets the border size 
 130     void SetBorderSize(int width
) { m_borderSize 
= width
; } 
 132     // Gets the sash size 
 133     int GetSashSize() const { return m_sashSize
; } 
 135     // Gets the border size 
 136     int GetBorderSize() const { return m_borderSize
; } 
 138     // Set the sash position 
 139     void SetSashPosition(int position
, bool redraw 
= TRUE
); 
 141     // Gets the sash position 
 142     int GetSashPosition() const { return m_sashPosition
; } 
 144     // If this is zero, we can remove panes by dragging the sash. 
 145     void SetMinimumPaneSize(int min
) { m_minimumPaneSize 
= min
; } 
 146     int GetMinimumPaneSize() const { return m_minimumPaneSize
; } 
 148     // Called when the sash position is about to be changed, return 
 149     // FALSE from here to prevent the change from taking place. 
 150     // Repositions sash to minimum position if pane would be too small. 
 151     // newSashPosition here is always positive or zero. 
 152     virtual bool OnSashPositionChange(int WXUNUSED(newSashPosition
)) 
 155     // If the sash is moved to an extreme position, a subwindow 
 156     // is removed from the splitter window, and the app is 
 157     // notified. The app should delete or hide the window. 
 158     virtual void OnUnsplit(wxWindow 
*WXUNUSED(removed
)) { } 
 160     // Called when the sash is double-clicked. 
 161     // The default behaviour is to remove the sash if the 
 162     // minimum pane size is zero. 
 163     virtual void OnDoubleClickSash(int WXUNUSED(x
), int WXUNUSED(y
)) { } 
 165 //////////////////////////////////////////////////////////////////////////// 
 168     // Paints the border and sash 
 169     void OnPaint(wxPaintEvent
& event
); 
 171     // Handles mouse events 
 172     void OnMouseEvent(wxMouseEvent
& ev
); 
 175     void OnSize(wxSizeEvent
& event
); 
 177     // In live mode, resize child windows in idle time 
 178     void OnIdle(wxIdleEvent
& event
); 
 181     virtual void DrawBorders(wxDC
& dc
); 
 184     virtual void DrawSash(wxDC
& dc
); 
 186     // Draws the sash tracker (for whilst moving the sash) 
 187     virtual void DrawSashTracker(int x
, int y
); 
 189     // Tests for x, y over sash 
 190     virtual bool SashHitTest(int x
, int y
, int tolerance 
= 2); 
 192     // Resizes subwindows 
 193     virtual void SizeWindows(); 
 195     // Initialize colours 
 198     void SetNeedUpdating(bool needUpdating
) { m_needUpdating 
= needUpdating
; } 
 199     bool GetNeedUpdating() const { return m_needUpdating 
; } 
 202     // our event handlers 
 203     void OnSashPosChanged(wxSplitterEvent
& event
); 
 204     void OnSashPosChanging(wxSplitterEvent
& event
); 
 205     void OnDoubleClick(wxSplitterEvent
& event
); 
 206     void OnUnsplitEvent(wxSplitterEvent
& event
); 
 207     void OnSetCursor(wxSetCursorEvent
& event
); 
 209     void SendUnsplitEvent(wxWindow 
*winRemoved
); 
 216     bool        m_permitUnsplitAlways
; 
 217     bool        m_needUpdating
; // when in live mode, set this to TRUE to resize children in idle 
 218     wxWindow
*   m_windowOne
; 
 219     wxWindow
*   m_windowTwo
; 
 224     int         m_sashSize
;     // Sash width or height 
 225     int         m_sashPosition
; // Number of pixels from left or top 
 228     int         m_minimumPaneSize
; 
 229     wxCursor
*   m_sashCursorWE
; 
 230     wxCursor
*   m_sashCursorNS
; 
 231     wxPen
*      m_sashTrackerPen
; 
 232     wxPen
*      m_lightShadowPen
; 
 233     wxPen
*      m_mediumShadowPen
; 
 234     wxPen
*      m_darkShadowPen
; 
 236     wxBrush
*    m_faceBrush
; 
 240     DECLARE_DYNAMIC_CLASS(wxSplitterWindow
) 
 241     DECLARE_EVENT_TABLE() 
 244 // ---------------------------------------------------------------------------- 
 245 // event class and macros 
 246 // ---------------------------------------------------------------------------- 
 248 // we reuse the same class for all splitter event types because this is the 
 249 // usual wxWin convention, but the three event types have different kind of 
 250 // data associated with them, so the accessors can be only used if the real 
 251 // event type matches with the one for which the accessors make sense 
 252 class WXDLLEXPORT wxSplitterEvent 
: public wxCommandEvent
 
 255     wxSplitterEvent(wxEventType type 
= wxEVT_NULL
, 
 256                     wxSplitterWindow 
*splitter 
= (wxSplitterWindow 
*)NULL
) 
 257         : wxCommandEvent(type
) 
 259         SetEventObject(splitter
); 
 260         if (splitter
) m_id 
= splitter
->GetId(); 
 263     // SASH_POS_CHANGED methods 
 265     // setting the sash position to -1 prevents the change from taking place at 
 267     void SetSashPosition(int pos
) 
 269         wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED
 
 270                 || GetEventType() == wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING
); 
 275     int GetSashPosition() const 
 277         wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED
 
 278                 || GetEventType() == wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING
); 
 283     // UNSPLIT event methods 
 284     wxWindow 
*GetWindowBeingRemoved() const 
 286         wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_UNSPLIT 
); 
 291     // DCLICK event methods 
 294         wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_DOUBLECLICKED 
); 
 301         wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_DOUBLECLICKED 
); 
 307     friend class WXDLLEXPORT wxSplitterWindow
; 
 309     // data for the different types of event 
 312         int pos
;            // position for SASH_POS_CHANGED event 
 313         wxWindow 
*win
;      // window being removed for UNSPLIT event 
 317         } pt
;               // position of double click for DCLICK event 
 320     DECLARE_DYNAMIC_CLASS(wxSplitterEvent
) 
 323 typedef void (wxEvtHandler::*wxSplitterEventFunction
)(wxSplitterEvent
&); 
 325 #define EVT_SPLITTER_SASH_POS_CHANGED(id, fn)                               \ 
 327     wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED,                                \ 
 330     (wxObjectEventFunction)(wxEventFunction)(wxSplitterEventFunction) &fn,  \ 
 334 #define EVT_SPLITTER_SASH_POS_CHANGING(id, fn)                              \ 
 336     wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING,                               \ 
 339     (wxObjectEventFunction)(wxEventFunction)(wxSplitterEventFunction) &fn,  \ 
 343 #define EVT_SPLITTER_DCLICK(id, fn)                                         \ 
 345     wxEVT_COMMAND_SPLITTER_DOUBLECLICKED,                                   \ 
 348     (wxObjectEventFunction)(wxEventFunction)(wxSplitterEventFunction) &fn,  \ 
 352 #define EVT_SPLITTER_UNSPLIT(id, fn)                                        \ 
 354     wxEVT_COMMAND_SPLITTER_UNSPLIT,                                         \ 
 357     (wxObjectEventFunction)(wxEventFunction)(wxSplitterEventFunction) &fn,  \ 
 361 #endif // __SPLITTERH_G__