1 /*
2  Copyright (C) 2010-2014 Kristian Duske
3 
4  This file is part of TrenchBroom.
5 
6  TrenchBroom is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  TrenchBroom is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef TrenchBroom_SplitterWindow2
21 #define TrenchBroom_SplitterWindow2
22 
23 #include "Macros.h"
24 
25 #include <wx/panel.h>
26 
27 class wxPersistentObject;
28 
29 namespace TrenchBroom {
30     namespace View {
31         class PersistentSplitterWindow2;
32 
33         class SplitterWindow2 : public wxPanel {
34         private:
35             static const size_t NumWindows = 2;
36             static const int HalfMinSashSize = 2;
37 
38             typedef enum {
39                 SplitMode_Unset,
40                 SplitMode_Horizontal,
41                 SplitMode_Vertical
42             } SplitMode;
43 
44             SplitMode m_splitMode;
45             wxWindow* m_sash;
46             wxWindow* m_windows[NumWindows];
47             wxWindow* m_maximizedWindow;
48             wxSize m_minSizes[NumWindows];
49 
50             double m_sashGravity;
51             double m_initialSplitRatio;
52             double m_currentSplitRatio;
53 
54             bool m_sashCursorSet;
55 
56             wxSize m_oldSize;
57 
58             friend class PersistentSplitterWindow2;
59         public:
60             SplitterWindow2(wxWindow* parent);
61 
62             void splitHorizontally(wxWindow* left, wxWindow* right, const wxSize& leftMin = wxDefaultSize, const wxSize& rightMin = wxDefaultSize);
63             void splitVertically(wxWindow* top, wxWindow* bottom, const wxSize& topMin = wxDefaultSize, const wxSize& bottomMin = wxDefaultSize);
64 
65             void setMinSize(wxWindow* window, const wxSize& minSize);
66             void setSashGravity(double sashGravity);
67 
68             bool isMaximized(wxWindow* window) const;
69             void maximize(wxWindow* window);
70             void restore();
71         private:
72             int currentSashPosition() const;
73             int sashPosition(double ratio) const;
74             int sashPosition(double ratio, wxCoord size) const;
75             double splitRatio(int position) const;
76 
77             void split(wxWindow* window1, wxWindow* window2, const wxSize& min1, const wxSize& min2, SplitMode splitMode);
78             void bindMouseEvents(wxWindow* window);
79         public:
80             void OnMouseEnter(wxMouseEvent& event);
81             void OnMouseLeave(wxMouseEvent& event);
82             void OnMouseButton(wxMouseEvent& event);
83             void OnMouseMotion(wxMouseEvent& event);
84             void OnMouseCaptureLost(wxMouseCaptureLostEvent& event);
85         private:
86             bool dragging() const;
87             void setSashCursor();
88             wxCursor sizeCursor() const;
89         public:
90             void OnIdle(wxIdleEvent& event);
91             void OnSize(wxSizeEvent& event);
92         private:
93             void updateSashPosition(const wxSize& oldSize, const wxSize& newSize);
94             void initSashPosition();
95             bool setSashPosition(int newSashPosition);
96             void sizeWindows();
97             int sashSize() const;
98 
99             wxWindow* unmaximizedWindow();
100 
101             template <typename T>
setHV(T & p,const int h,const int v)102             void setHV(T& p, const int h, const int v) const {
103                 setH(p, h);
104                 setV(p, v);
105             }
106 
107             template <typename T>
setH(T & p,const int h)108             void setH(T& p, const int h) const {
109                 switch (m_splitMode) {
110                     case SplitMode_Horizontal:
111                         p.y = h;
112                         break;
113                     case SplitMode_Vertical:
114                         p.x = h;
115                         break;
116                     case SplitMode_Unset:
117                         break;
118                     switchDefault()
119                 }
120             }
121 
122             template <typename T>
setV(T & p,const int v)123             void setV(T& p, const int v) const {
124                 switch (m_splitMode) {
125                     case SplitMode_Horizontal:
126                         p.x = v;
127                         break;
128                     case SplitMode_Vertical:
129                         p.y = v;
130                         break;
131                     case SplitMode_Unset:
132                         break;
133                     switchDefault()
134                 }
135             }
136 
137             template <typename T>
h(const T & p)138             int h(const T& p) const {
139                 switch (m_splitMode) {
140                     case SplitMode_Horizontal:
141                         return p.y;
142                     case SplitMode_Vertical:
143                         return p.x;
144                     case SplitMode_Unset:
145                         return 0;
146                     switchDefault()
147                 }
148             }
149 
150             template <typename T>
v(const T & p)151             int v(const T& p) const {
152                 switch (m_splitMode) {
153                     case SplitMode_Horizontal:
154                         return p.x;
155                     case SplitMode_Vertical:
156                         return p.y;
157                     case SplitMode_Unset:
158                         return 0;
159                     switchDefault()
160                 }
161             }
162         };
163     }
164 }
165 
166 wxPersistentObject* wxCreatePersistentObject(TrenchBroom::View::SplitterWindow2* window);
167 
168 #endif /* defined(TrenchBroom_SplitterWindow2) */
169