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

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

First release to xenial

File size: 5.3 KB
Line 
1#include <filezilla.h>
2#include "window_state_manager.h"
3#include "Options.h"
4#if wxUSE_DISPLAY
5#include <wx/display.h>
6#endif
7#include <wx/tokenzr.h>
8
9CWindowStateManager::CWindowStateManager(wxTopLevelWindow* pWindow)
10{
11        m_pWindow = pWindow;
12
13        m_lastMaximized = false;
14
15        m_pWindow->Connect(wxID_ANY, wxEVT_SIZE, wxSizeEventHandler(CWindowStateManager::OnSize), 0, this);
16        m_pWindow->Connect(wxID_ANY, wxEVT_MOVE, wxMoveEventHandler(CWindowStateManager::OnMove), 0, this);
17
18#ifdef __WXGTK__
19        m_maximize_requested = 0;
20#endif
21}
22
23CWindowStateManager::~CWindowStateManager()
24{
25        m_pWindow->Disconnect(wxID_ANY, wxEVT_SIZE, wxSizeEventHandler(CWindowStateManager::OnSize), 0, this);
26        m_pWindow->Disconnect(wxID_ANY, wxEVT_MOVE, wxMoveEventHandler(CWindowStateManager::OnMove), 0, this);
27}
28
29void CWindowStateManager::Remember(unsigned int optionId)
30{
31        if (!m_lastWindowSize.IsFullySpecified())
32                return;
33
34        wxString posString;
35
36        // is_maximized
37        posString += wxString::Format(_T("%d "), m_lastMaximized ? 1 : 0);
38
39        // pos_x pos_y
40        posString += wxString::Format(_T("%d %d "), m_lastWindowPosition.x, m_lastWindowPosition.y);
41
42        // pos_width pos_height
43        posString += wxString::Format(_T("%d %d "), m_lastWindowSize.x, m_lastWindowSize.y);
44
45        COptions::Get()->SetOption(optionId, posString);
46}
47
48bool CWindowStateManager::ReadDefaults(const unsigned int optionId, bool& maximized, wxPoint& position, wxSize& size)
49{
50        if (wxGetKeyState(WXK_SHIFT) && wxGetKeyState(WXK_ALT) && wxGetKeyState(WXK_CONTROL))
51                return false;
52
53        // Fields:
54        // - maximized (1 or 0)
55        // - x position
56        // - y position
57        // - width
58        // - height
59        const wxString layout = COptions::Get()->GetOption(optionId);
60        wxStringTokenizer tokens(layout, _T(" "));
61        int count = tokens.CountTokens();
62        if (count != 5)
63                return false;
64
65        long values[5];
66        for (int i = 0; i < count; i++)
67        {
68                wxString token = tokens.GetNextToken();
69                if (!token.ToLong(values + i))
70                        return false;
71        }
72        if (values[3] <= 0 || values[4] <= 0)
73                return false;
74
75        const wxRect screen_size = GetScreenDimensions();
76
77        size.x = values[3];
78        size.y = values[4];
79
80        // Make sure position is (somewhat) sane.
81        // We allow the window to be partially out of sight, as long as the title bar is at least partially visible.
82
83        // Deal with the horizontal
84        position.x = wxMin(screen_size.GetRight() - 30, values[1]);
85        if (position.x + size.x - 30 < screen_size.GetLeft())
86                position.x = screen_size.GetLeft() + 30 - size.x;
87
88        // Deal with the vertical
89        position.y = wxMin(screen_size.GetBottom() - 30, values[2]);
90        if (position.y < screen_size.GetTop())
91                position.y = screen_size.GetTop();
92
93        maximized = values[0] != 0;
94
95        return true;
96}
97
98bool CWindowStateManager::Restore(const unsigned int optionId, const wxSize& default_size /*=wxSize(-1, -1)*/)
99{
100        wxPoint position(-1, -1);
101        wxSize size = default_size;
102        bool maximized = false;
103
104        bool read = ReadDefaults(optionId, maximized, position, size);
105
106        if (maximized)
107        {
108                // We need to move so it appears on the proper display on multi-monitor systems
109                m_pWindow->Move(position.x, position.y);
110
111                // We need to call SetClientSize here too. Since window isn't yet shown here, Maximize
112                // doesn't actually resize the window till it is shown
113
114                // The slight off-size is needed to ensure the client sizes gets changed at least once.
115                // Otherwise all the splitters would have default size still.
116                m_pWindow->SetClientSize(size.x + 1, size.y);
117
118                // A 2nd call is neccessary, for some reason the first call
119                // doesn't fully set the height properly at least under wxMSW
120                m_pWindow->SetClientSize(size.x, size.y);
121
122#ifdef __WXMSW__
123                m_pWindow->Show();
124#endif
125                m_pWindow->Maximize();
126#ifdef __WXGTK__
127                if (!m_pWindow->IsMaximized())
128                        m_maximize_requested = 4;
129#endif //__WXGTK__
130        }
131        else
132        {
133                if (read)
134                        m_pWindow->Move(position.x, position.y);
135
136                if (size.IsFullySpecified())
137                {
138                        // The slight off-size is needed to ensure the client sizes gets changed at least once.
139                        // Otherwise all the splitters would have default size still.
140                        m_pWindow->SetClientSize(size.x + 1, size.x);
141
142                        // A 2nd call is neccessary, for some reason the first call
143                        // doesn't fully set the height properly at least under wxMSW
144                        m_pWindow->SetClientSize(size.x, size.y);
145                }
146
147                if (!read)
148                        m_pWindow->CentreOnScreen();
149        }
150
151        return true;
152}
153
154void CWindowStateManager::OnSize(wxSizeEvent& event)
155{
156#ifdef __WXGTK__
157        if (m_maximize_requested)
158                m_maximize_requested--;
159#endif
160        if (!m_pWindow->IsIconized())
161        {
162                m_lastMaximized = m_pWindow->IsMaximized();
163                if (!m_lastMaximized)
164                {
165                        m_lastWindowPosition = m_pWindow->GetPosition();
166                        m_lastWindowSize = m_pWindow->GetClientSize();
167                }
168        }
169        event.Skip();
170}
171
172void CWindowStateManager::OnMove(wxMoveEvent& event)
173{
174        if (!m_pWindow->IsIconized() && !m_pWindow->IsMaximized())
175        {
176                m_lastWindowPosition = m_pWindow->GetPosition();
177                m_lastWindowSize = m_pWindow->GetClientSize();
178        }
179        event.Skip();
180}
181
182wxRect CWindowStateManager::GetScreenDimensions()
183{
184#if wxUSE_DISPLAY
185        wxRect screen_size(0, 0, 0, 0);
186
187        // Get bounding rectangle of virtual screen
188        for (unsigned int i = 0; i < wxDisplay::GetCount(); i++)
189        {
190                wxDisplay display(i);
191                wxRect rect = display.GetGeometry();
192                screen_size.Union(rect);
193        }
194        if (screen_size.GetWidth() <= 0 || screen_size.GetHeight() <= 0)
195                screen_size = wxRect(0, 0, 1000000000, 1000000000);
196#else
197        wxRect screen_size(0, 0, 1000000000, 1000000000);
198#endif
199
200        return screen_size;
201}
Note: See TracBrowser for help on using the repository browser.