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