1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        sashwin.h
3 // Purpose:     wxSashWindow implementation. A sash window has an optional
4 //              sash on each edge, allowing it to be dragged. An event
5 //              is generated when the sash is released.
6 // Author:      Julian Smart
7 // Modified by:
8 // Created:     01/02/97
9 // RCS-ID:      $Id: sashwin.h 41020 2006-09-05 20:47:48Z VZ $
10 // Copyright:   (c) Julian Smart
11 // Licence:     wxWindows licence
12 /////////////////////////////////////////////////////////////////////////////
13 
14 #ifndef _WX_SASHWIN_H_G_
15 #define _WX_SASHWIN_H_G_
16 
17 #if wxUSE_SASH
18 
19 #include "wx/defs.h"
20 #include "wx/window.h"
21 #include "wx/string.h"
22 
23 #define wxSASH_DRAG_NONE       0
24 #define wxSASH_DRAG_DRAGGING   1
25 #define wxSASH_DRAG_LEFT_DOWN  2
26 
27 enum wxSashEdgePosition {
28     wxSASH_TOP = 0,
29     wxSASH_RIGHT,
30     wxSASH_BOTTOM,
31     wxSASH_LEFT,
32     wxSASH_NONE = 100
33 };
34 
35 /*
36  * wxSashEdge represents one of the four edges of a window.
37  */
38 
39 class WXDLLIMPEXP_ADV wxSashEdge
40 {
41 public:
wxSashEdge()42     wxSashEdge()
43     { m_show = false;
44 #if WXWIN_COMPATIBILITY_2_6
45       m_border = false;
46 #endif
47       m_margin = 0; }
48 
49     bool    m_show;     // Is the sash showing?
50 #if WXWIN_COMPATIBILITY_2_6
51     bool    m_border;   // Do we draw a border?
52 #endif
53     int     m_margin;   // The margin size
54 };
55 
56 /*
57  * wxSashWindow flags
58  */
59 
60 #define wxSW_NOBORDER         0x0000
61 //#define wxSW_3D               0x0010
62 #define wxSW_BORDER           0x0020
63 #define wxSW_3DSASH           0x0040
64 #define wxSW_3DBORDER         0x0080
65 #define wxSW_3D (wxSW_3DSASH | wxSW_3DBORDER)
66 
67 /*
68  * wxSashWindow allows any of its edges to have a sash which can be dragged
69  * to resize the window. The actual content window will be created as a child
70  * of wxSashWindow.
71  */
72 
73 class WXDLLIMPEXP_ADV wxSashWindow: public wxWindow
74 {
75 public:
76     // Default constructor
wxSashWindow()77     wxSashWindow()
78     {
79         Init();
80     }
81 
82     // Normal constructor
83     wxSashWindow(wxWindow *parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
84         const wxSize& size = wxDefaultSize, long style = wxSW_3D|wxCLIP_CHILDREN, const wxString& name = wxT("sashWindow"))
85     {
86         Init();
87         Create(parent, id, pos, size, style, name);
88     }
89 
90     virtual ~wxSashWindow();
91 
92     bool Create(wxWindow *parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
93         const wxSize& size = wxDefaultSize, long style = wxSW_3D|wxCLIP_CHILDREN, const wxString& name = wxT("sashWindow"));
94 
95     // Set whether there's a sash in this position
96     void SetSashVisible(wxSashEdgePosition edge, bool sash);
97 
98     // Get whether there's a sash in this position
GetSashVisible(wxSashEdgePosition edge)99     bool GetSashVisible(wxSashEdgePosition edge) const { return m_sashes[edge].m_show; }
100 
101 #if WXWIN_COMPATIBILITY_2_6
102     // Set whether there's a border in this position
103     // This value is unused in wxSashWindow.
SetSashBorder(wxSashEdgePosition edge,bool border)104     void SetSashBorder(wxSashEdgePosition edge, bool border) { m_sashes[edge].m_border = border; }
105 
106     // Get whether there's a border in this position
107     // This value is unused in wxSashWindow.
HasBorder(wxSashEdgePosition edge)108     bool HasBorder(wxSashEdgePosition edge) const { return m_sashes[edge].m_border; }
109 #endif
110 
111     // Get border size
GetEdgeMargin(wxSashEdgePosition edge)112     int GetEdgeMargin(wxSashEdgePosition edge) const { return m_sashes[edge].m_margin; }
113 
114     // Sets the default sash border size
SetDefaultBorderSize(int width)115     void SetDefaultBorderSize(int width) { m_borderSize = width; }
116 
117     // Gets the default sash border size
GetDefaultBorderSize()118     int GetDefaultBorderSize() const { return m_borderSize; }
119 
120     // Sets the addition border size between child and sash window
SetExtraBorderSize(int width)121     void SetExtraBorderSize(int width) { m_extraBorderSize = width; }
122 
123     // Gets the addition border size between child and sash window
GetExtraBorderSize()124     int GetExtraBorderSize() const { return m_extraBorderSize; }
125 
SetMinimumSizeX(int min)126     virtual void SetMinimumSizeX(int min) { m_minimumPaneSizeX = min; }
SetMinimumSizeY(int min)127     virtual void SetMinimumSizeY(int min) { m_minimumPaneSizeY = min; }
GetMinimumSizeX()128     virtual int GetMinimumSizeX() const { return m_minimumPaneSizeX; }
GetMinimumSizeY()129     virtual int GetMinimumSizeY() const { return m_minimumPaneSizeY; }
130 
SetMaximumSizeX(int max)131     virtual void SetMaximumSizeX(int max) { m_maximumPaneSizeX = max; }
SetMaximumSizeY(int max)132     virtual void SetMaximumSizeY(int max) { m_maximumPaneSizeY = max; }
GetMaximumSizeX()133     virtual int GetMaximumSizeX() const { return m_maximumPaneSizeX; }
GetMaximumSizeY()134     virtual int GetMaximumSizeY() const { return m_maximumPaneSizeY; }
135 
136 ////////////////////////////////////////////////////////////////////////////
137 // Implementation
138 
139     // Paints the border and sash
140     void OnPaint(wxPaintEvent& event);
141 
142     // Handles mouse events
143     void OnMouseEvent(wxMouseEvent& ev);
144 
145     // Adjusts the panes
146     void OnSize(wxSizeEvent& event);
147 
148 #if defined(__WXMSW__) || defined(__WXMAC__)
149     // Handle cursor correctly
150     void OnSetCursor(wxSetCursorEvent& event);
151 #endif // wxMSW
152 
153     // Draws borders
154     void DrawBorders(wxDC& dc);
155 
156     // Draws the sashes
157     void DrawSash(wxSashEdgePosition edge, wxDC& dc);
158 
159     // Draws the sashes
160     void DrawSashes(wxDC& dc);
161 
162     // Draws the sash tracker (for whilst moving the sash)
163     void DrawSashTracker(wxSashEdgePosition edge, int x, int y);
164 
165     // Tests for x, y over sash
166     wxSashEdgePosition SashHitTest(int x, int y, int tolerance = 2);
167 
168     // Resizes subwindows
169     void SizeWindows();
170 
171     // Initialize colours
172     void InitColours();
173 
174 private:
175     void Init();
176 
177     wxSashEdge  m_sashes[4];
178     int         m_dragMode;
179     wxSashEdgePosition m_draggingEdge;
180     int         m_oldX;
181     int         m_oldY;
182     int         m_borderSize;
183     int         m_extraBorderSize;
184     int         m_firstX;
185     int         m_firstY;
186     int         m_minimumPaneSizeX;
187     int         m_minimumPaneSizeY;
188     int         m_maximumPaneSizeX;
189     int         m_maximumPaneSizeY;
190     wxCursor*   m_sashCursorWE;
191     wxCursor*   m_sashCursorNS;
192     wxColour    m_lightShadowColour;
193     wxColour    m_mediumShadowColour;
194     wxColour    m_darkShadowColour;
195     wxColour    m_hilightColour;
196     wxColour    m_faceColour;
197     bool        m_mouseCaptured;
198     wxCursor*   m_currentCursor;
199 
200 private:
201     DECLARE_DYNAMIC_CLASS(wxSashWindow)
202     DECLARE_EVENT_TABLE()
203     DECLARE_NO_COPY_CLASS(wxSashWindow)
204 };
205 
206 BEGIN_DECLARE_EVENT_TYPES()
207     DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV,
208                                 wxEVT_SASH_DRAGGED, wxEVT_FIRST + 1200)
209 END_DECLARE_EVENT_TYPES()
210 
211 enum wxSashDragStatus
212 {
213     wxSASH_STATUS_OK,
214     wxSASH_STATUS_OUT_OF_RANGE
215 };
216 
217 class WXDLLIMPEXP_ADV wxSashEvent: public wxCommandEvent
218 {
219 public:
220     wxSashEvent(int id = 0, wxSashEdgePosition edge = wxSASH_NONE)
221     {
222         m_eventType = (wxEventType) wxEVT_SASH_DRAGGED;
223         m_id = id;
224         m_edge = edge;
225     }
226 
SetEdge(wxSashEdgePosition edge)227     void SetEdge(wxSashEdgePosition edge) { m_edge = edge; }
GetEdge()228     wxSashEdgePosition GetEdge() const { return m_edge; }
229 
230     //// The rectangle formed by the drag operation
SetDragRect(const wxRect & rect)231     void SetDragRect(const wxRect& rect) { m_dragRect = rect; }
GetDragRect()232     wxRect GetDragRect() const { return m_dragRect; }
233 
234     //// Whether the drag caused the rectangle to be reversed (e.g.
235     //// dragging the top below the bottom)
SetDragStatus(wxSashDragStatus status)236     void SetDragStatus(wxSashDragStatus status) { m_dragStatus = status; }
GetDragStatus()237     wxSashDragStatus GetDragStatus() const { return m_dragStatus; }
238 
239 private:
240     wxSashEdgePosition  m_edge;
241     wxRect              m_dragRect;
242     wxSashDragStatus    m_dragStatus;
243 
244 private:
245     DECLARE_DYNAMIC_CLASS_NO_COPY(wxSashEvent)
246 };
247 
248 typedef void (wxEvtHandler::*wxSashEventFunction)(wxSashEvent&);
249 
250 #define wxSashEventHandler(func) \
251     (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxSashEventFunction, &func)
252 
253 #define EVT_SASH_DRAGGED(id, fn) \
254     wx__DECLARE_EVT1(wxEVT_SASH_DRAGGED, id, wxSashEventHandler(fn))
255 #define EVT_SASH_DRAGGED_RANGE(id1, id2, fn) \
256     wx__DECLARE_EVT2(wxEVT_SASH_DRAGGED, id1, id2, wxSashEventHandler(fn))
257 
258 #endif // wxUSE_SASH
259 
260 #endif
261   // _WX_SASHWIN_H_G_
262