source: filezilla/trunk/fuentes/src/interface/splitter.cpp @ 130

Last change on this file since 130 was 130, checked in by jrpelegrina, 4 years ago

First release to xenial

File size: 6.8 KB
Line 
1#include <filezilla.h>
2#include "splitter.h"
3
4IMPLEMENT_CLASS(CSplitterWindowEx, wxSplitterWindow)
5
6BEGIN_EVENT_TABLE(CSplitterWindowEx, wxSplitterWindow)
7EVT_SIZE(CSplitterWindowEx::OnSize)
8END_EVENT_TABLE()
9
10CSplitterWindowEx::CSplitterWindowEx()
11{
12        m_relative_sash_position = 0.5;
13        m_soft_min_pane_size = -1;
14        m_lastSashPosition = -1;
15}
16
17CSplitterWindowEx::CSplitterWindowEx(wxWindow* parent, wxWindowID id, const wxPoint& point /*=wxDefaultPosition*/, const wxSize& size /*=wxDefaultSize*/, long style /*=wxSP_3D*/, const wxString& name /*=_T("splitterWindow")*/)
18        : wxSplitterWindow(parent, id, point, size, style, name)
19{
20        m_relative_sash_position = 0.5;
21        m_soft_min_pane_size = -1;
22        m_lastSashPosition = -1;
23}
24
25bool CSplitterWindowEx::Create(wxWindow* parent, wxWindowID id, const wxPoint& point /*=wxDefaultPosition*/, const wxSize& size /*=wxDefaultSize*/, long style /*=wxSP_3D*/, const wxString& name /*=_T("splitterWindow")*/)
26{
27        return wxSplitterWindow::Create(parent, id, point, size, style, name);
28}
29
30void CSplitterWindowEx::SetSashGravity(double gravity)
31{
32        // Only support these three for now
33        wxASSERT(gravity == 0.0 || gravity == 0.5 || gravity == 1.0);
34
35        wxSplitterWindow::SetSashGravity(gravity);
36}
37
38void CSplitterWindowEx::OnSize(wxSizeEvent& event)
39{
40        // Code copied from wxWidgets and adjusted for better gravity handling
41
42        // only process this message if we're not iconized - otherwise iconizing
43        // and restoring a window containing the splitter has a funny side effect
44        // of changing the splitter position!
45        wxWindow *parent = wxGetTopLevelParent(this);
46        bool iconized;
47
48        wxTopLevelWindow *winTop = wxDynamicCast(parent, wxTopLevelWindow);
49        if ( winTop )
50        {
51                iconized = winTop->IsIconized();
52        }
53        else
54        {
55                wxFAIL_MSG(wxT("should have a top level parent!"));
56
57                iconized = false;
58        }
59
60        if ( iconized )
61        {
62                m_lastSize = wxSize(0,0);
63
64                event.Skip();
65
66                return;
67        }
68
69        if ( m_windowTwo )
70        {
71                int w, h;
72                GetClientSize(&w, &h);
73
74                int size = m_splitMode == wxSPLIT_VERTICAL ? w : h;
75
76                int newPosition = m_sashPosition;
77
78                int old_size = m_splitMode == wxSPLIT_VERTICAL ? m_lastSize.x : m_lastSize.y;
79                if ( old_size != 0 )
80                {
81                        if (m_sashGravity == 0.5)
82                                newPosition = (int)(size * m_relative_sash_position);
83                        else if (m_sashGravity == 1.0)
84                        {
85                                int delta = (int) ( (size - old_size) );
86                                if ( delta != 0 )
87                                {
88                                        newPosition = m_sashPosition + delta;
89                                        if( newPosition < m_minimumPaneSize )
90                                                newPosition = m_minimumPaneSize;
91                                }
92                        }
93                        else
94                        {
95                                if (newPosition > size - m_minimumPaneSize - GetSashSize())
96                                        newPosition = size - m_minimumPaneSize - GetSashSize();
97                        }
98                }
99
100                if ( newPosition >= size - 5 )
101                        newPosition = wxMax(10, size - 40);
102
103                newPosition = CalcSoftLimit(newPosition);
104
105                if (newPosition != m_sashPosition)
106                        SetSashPositionAndNotify(newPosition);
107
108                m_lastSize = wxSize(w,h);
109        }
110
111        SizeWindows();
112}
113
114void CSplitterWindowEx::SetMinimumPaneSize(int paneSize, int paneSize_soft /*=-1*/)
115{
116        wxASSERT(paneSize_soft >= paneSize || paneSize_soft == -1);
117
118        wxSplitterWindow::SetMinimumPaneSize(paneSize);
119
120        m_soft_min_pane_size = paneSize_soft;
121}
122
123int CSplitterWindowEx::OnSashPositionChanging(int newSashPosition)
124{
125        newSashPosition = AdjustSashPosition(newSashPosition);
126        newSashPosition = CalcSoftLimit(newSashPosition);
127
128        newSashPosition = wxSplitterWindow::OnSashPositionChanging(newSashPosition);
129
130        if (newSashPosition != -1)
131        {
132                int w, h;
133                GetClientSize(&w, &h);
134
135                int size = m_splitMode == wxSPLIT_VERTICAL ? w : h;
136
137                m_relative_sash_position = (double)newSashPosition / size;
138        }
139
140        return newSashPosition;
141}
142
143int CSplitterWindowEx::CalcSoftLimit(int newSashPosition)
144{
145        if (m_soft_min_pane_size != -1)
146        {
147                int w, h;
148                GetClientSize(&w, &h);
149
150                int size = m_splitMode == wxSPLIT_VERTICAL ? w : h;
151
152                int limit = size / 2;
153                if (limit > m_soft_min_pane_size)
154                        limit = m_soft_min_pane_size;
155                if (newSashPosition < limit)
156                        newSashPosition = limit;
157                else if (newSashPosition > size - limit - GetSashSize())
158                        newSashPosition = wxMax(limit, size - limit - GetSashSize());
159        }
160
161        return newSashPosition;
162}
163
164void CSplitterWindowEx::SetRelativeSashPosition(double relative_sash_position)
165{
166        wxASSERT(relative_sash_position >= 0 && relative_sash_position <= 1);
167
168        int w, h;
169        GetClientSize(&w, &h);
170
171        int size = m_splitMode == wxSPLIT_VERTICAL ? w : h;
172
173        wxSplitterWindow::SetSashPosition((int)(size * relative_sash_position));
174
175        m_relative_sash_position = relative_sash_position;
176}
177
178void CSplitterWindowEx::SetSashPosition(int sash_position)
179{
180        if (!m_windowTwo)
181        {
182                m_lastSashPosition = sash_position;
183                return;
184        }
185
186        int w, h;
187        GetClientSize(&w, &h);
188
189        int size = m_splitMode == wxSPLIT_VERTICAL ? w : h;
190
191        if (!sash_position)
192                sash_position = size / 2;
193        if (sash_position < 0 && m_sashGravity == 1.0)
194                sash_position = size + sash_position - GetSashSize();
195
196        wxSplitterWindow::SetSashPosition(sash_position);
197
198        m_relative_sash_position = (double)sash_position / size;
199}
200
201bool CSplitterWindowEx::Unsplit(wxWindow* toRemove /*=NULL*/)
202{
203        if (m_sashGravity == 1)
204        {
205                int w, h;
206                GetClientSize(&w, &h);
207
208                int size = m_splitMode == wxSPLIT_VERTICAL ? w : h;
209
210                m_lastSashPosition = m_sashPosition + GetSashSize() - size;
211        }
212        else
213                m_lastSashPosition = m_sashPosition;
214
215        return wxSplitterWindow::Unsplit(toRemove);
216}
217
218void CSplitterWindowEx::PrepareSplit(wxWindow* window1, wxWindow* window2, int & sashPosition, bool horizontal)
219{
220        int w, h;
221        GetClientSize(&w, &h);
222
223        int size = horizontal ? h : w;
224
225        if (sashPosition == 0) {
226                if (m_sashGravity == 0.5) {
227                        sashPosition = (int)(size * m_relative_sash_position);
228                }
229                else if (m_lastSashPosition != -1) {
230                        if (m_lastSashPosition < 0)
231                                sashPosition = size + m_lastSashPosition - GetSashSize();
232                        else
233                                sashPosition = m_lastSashPosition;
234                }
235        }
236
237        // Needs to be set to avoid resizing oddity:
238        // Maximize window -> Unsplit -> Restore -> Split -> Resize window
239        m_lastSize = wxSize(w, h);
240
241        if (window1 && window2) {
242                window1->MoveBeforeInTabOrder(window2);
243        }
244}
245
246bool CSplitterWindowEx::SplitHorizontally(wxWindow* window1, wxWindow* window2, int sashPosition /*=0*/)
247{
248        PrepareSplit(window1, window2, sashPosition, true);
249        return wxSplitterWindow::SplitHorizontally(window1, window2, sashPosition);
250}
251
252bool CSplitterWindowEx::SplitVertically(wxWindow* window1, wxWindow* window2, int sashPosition /*=0*/)
253{
254        PrepareSplit(window1, window2, sashPosition, false);
255        return wxSplitterWindow::SplitVertically(window1, window2, sashPosition);
256}
257
258int CSplitterWindowEx::GetSashPosition() const
259{
260        if (m_windowTwo || m_lastSashPosition == -1)
261        {
262                int sashPosition = wxSplitterWindow::GetSashPosition();
263
264                if (m_sashGravity == 1.0)
265                {
266                        int w, h;
267                        GetClientSize(&w, &h);
268
269                        int size = m_splitMode == wxSPLIT_VERTICAL ? w : h;
270
271                        sashPosition = sashPosition + GetSashSize() - size;
272                }
273
274                return sashPosition;
275        }
276
277        return m_lastSashPosition;
278}
279
280void CSplitterWindowEx::Initialize(wxWindow *window)
281{
282        wxSplitterWindow::Initialize(window);
283
284        SizeWindows();
285}
Note: See TracBrowser for help on using the repository browser.