]>
Commit | Line | Data |
---|---|---|
4a4a8111 RN |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: drawer.cpp | |
3 | // Purpose: Generic Drawer child window classes. | |
4 | // Drawer windows appear under their parent window and | |
5 | // behave like a drawer, opening and closing to reveal | |
6 | // content that does not need to be visible at all times. | |
7 | // Author: Ryan Norton | |
8 | // Modified by: | |
9 | // Created: 2004-30-01 | |
10 | // RCS-ID: $Id$ | |
11 | // Copyright: (c) Ryan Norton | |
12 | // Licence: wxWindows licence | |
13 | ///////////////////////////////////////////////////////////////////////////// | |
14 | ||
15 | #ifdef __GNUG__ | |
16 | #pragma implementation "drawerg.h" | |
17 | #endif | |
18 | ||
19 | #include "wx/defs.h" | |
20 | #include "wx/generic/drawerg.h" | |
21 | #include "wx/timer.h" | |
22 | ||
23 | enum wxGenericDrawerConstants | |
24 | { | |
25 | wxGENERICDRAWER_INCREMENT = 1, | |
26 | wxGENERICDRAWER_INTERVAL = 3 | |
27 | }; | |
28 | ||
29 | class wxGenericDrawerTimer : public wxTimer | |
30 | { | |
31 | public: | |
32 | ||
33 | wxGenericDrawerTimer(wxGenericDrawerWindow* pWin, const int& nMult) : | |
34 | m_pWin(pWin), m_nMult(nMult) {} | |
35 | ||
36 | void Notify() | |
37 | { | |
38 | if ((m_nMult < 0 && !m_pWin->m_nOpenOffset) || | |
39 | ( | |
40 | m_nMult >= 0 && | |
41 | (( (m_pWin->m_nCurrentEdge == wxLEFT || | |
42 | m_pWin->m_nCurrentEdge == wxRIGHT) && m_pWin->m_nOpenOffset >= m_pWin->GetSize().GetWidth()) | |
43 | ||
44 | || | |
45 | ||
46 | ( (m_pWin->m_nCurrentEdge == wxTOP || | |
47 | m_pWin->m_nCurrentEdge == wxBOTTOM) && m_pWin->m_nOpenOffset >= m_pWin->GetSize().GetHeight()) | |
48 | )) | |
49 | ) | |
50 | { | |
51 | /* | |
52 | wxFprintf(stderr, "shutdown - mult:%i off:%i tlr:%i ttb:%i\n", m_nMult, m_pWin->m_nOpenOffset, | |
53 | ||
54 | (m_pWin->m_nCurrentEdge == wxLEFT || | |
55 | m_pWin->m_nCurrentEdge == wxRIGHT) && m_pWin->m_nOpenOffset >= m_pWin->GetSize().GetWidth(), | |
56 | ||
57 | (m_pWin->m_nCurrentEdge == wxTOP || | |
58 | m_pWin->m_nCurrentEdge == wxBOTTOM) && m_pWin->m_nOpenOffset >= m_pWin->GetSize().GetHeight() | |
59 | ); | |
60 | */ | |
61 | ||
62 | //clean up & shut down | |
63 | Stop(); | |
64 | m_pWin->m_pTimer = NULL; | |
65 | ||
66 | //reset current edge to preferred edge | |
67 | if (m_nMult < 0) | |
68 | { | |
69 | m_pWin->m_nCurrentEdge = m_pWin->m_nPreferredEdge; | |
70 | m_pWin->DoDrawerPosition(); | |
71 | } | |
72 | ||
73 | //commit seppuku | |
74 | delete this; | |
75 | } | |
76 | else | |
77 | { | |
78 | // wxFprintf(stderr, "continue\n"); | |
79 | wxPoint pos = m_pWin->GetPosition(); | |
80 | switch (m_pWin->m_nCurrentEdge) | |
81 | { | |
82 | case wxLEFT: | |
83 | pos.x -= wxGENERICDRAWER_INCREMENT * m_nMult; | |
84 | break; | |
85 | ||
86 | case wxRIGHT: | |
87 | pos.x += wxGENERICDRAWER_INCREMENT * m_nMult; | |
88 | break; | |
89 | ||
90 | case wxTOP: | |
91 | pos.y -= wxGENERICDRAWER_INCREMENT * m_nMult; | |
92 | break; | |
93 | ||
94 | case wxBOTTOM: | |
95 | default: | |
96 | pos.y += wxGENERICDRAWER_INCREMENT * m_nMult; | |
97 | break; | |
98 | } | |
99 | m_pWin->SetPosition(pos); | |
100 | //wxFprintf(stderr, "tpos:%i,%i\n", pos.x, pos.y); | |
101 | m_pWin->m_nOpenOffset += wxGENERICDRAWER_INCREMENT * m_nMult; | |
102 | } | |
103 | } | |
104 | ||
105 | wxGenericDrawerWindow* m_pWin; | |
106 | int m_nMult; | |
107 | }; | |
108 | ||
109 | enum wxGenericDrawerOffsets | |
110 | { | |
111 | wxGENERICDRAWER_TOPOFFSET = 20, | |
112 | wxGENERICDRAWER_BOTTOMOFFSET = 20 | |
113 | }; | |
114 | ||
115 | IMPLEMENT_DYNAMIC_CLASS(wxGenericDrawerWindow, wxWindow) | |
116 | ||
117 | wxGenericDrawerWindow::wxGenericDrawerWindow() : | |
118 | m_bOpen(false), m_nCurrentEdge(wxLEFT), m_nPreferredEdge(wxLEFT), m_nOpenOffset(0), | |
119 | m_pTimer(NULL) | |
120 | { | |
121 | } | |
122 | ||
123 | wxGenericDrawerWindow::~wxGenericDrawerWindow() | |
124 | { | |
125 | m_isBeingDeleted = true; | |
126 | this->Show(false); | |
127 | if (m_pTimer) | |
128 | { | |
129 | m_pTimer->Stop(); | |
130 | delete m_pTimer; | |
131 | } | |
132 | } | |
133 | ||
134 | bool wxGenericDrawerWindow::Create(wxWindow *parent, | |
135 | wxWindowID id, const wxString& title, | |
136 | wxSize size, wxDirection edge, const wxString& name) | |
137 | { | |
138 | wxASSERT_MSG(NULL != parent, wxT("wxDrawerWindows must be attached to a parent window.")); | |
139 | ||
140 | wxASSERT_MSG(m_pTimer == NULL, wxT("Currently opening!!")); | |
141 | ||
142 | wxASSERT_MSG(edge == wxLEFT || | |
143 | edge == wxRIGHT || | |
144 | edge == wxTOP || | |
145 | edge == wxBOTTOM, wxT("Invalid edge") ); | |
146 | ||
147 | // Create the drawer window. | |
148 | const wxPoint pos(0, 0); | |
149 | const long style = wxNO_BORDER || wxVSCROLL | wxHSCROLL;//wxFRAME_DRAWER; | |
150 | ||
151 | bool success = wxTopLevelWindow::Create(parent, id, wxT(""), pos, size, style, name); | |
152 | ||
153 | if (success) | |
154 | { | |
155 | // Set the drawers parent. | |
156 | ||
157 | ||
158 | if (parent->IsTopLevel()) | |
159 | { | |
160 | wxTopLevelWindow* tlwParent = (wxTopLevelWindow*) parent; | |
161 | ||
162 | //connect to parent's events | |
163 | tlwParent->Connect(tlwParent->GetId(), wxEVT_MOVE, | |
164 | (wxObjectEventFunction) (wxEventFunction) (wxMoveEventFunction) &wxGenericDrawerWindow::OnDrawerMove, | |
165 | NULL, //user data | |
166 | this); | |
167 | ||
168 | tlwParent->Connect(tlwParent->GetId(), wxEVT_SIZE, | |
169 | (wxObjectEventFunction) (wxEventFunction) (wxSizeEventFunction) &wxGenericDrawerWindow::OnDrawerSize, | |
170 | NULL, //user data | |
171 | this); | |
172 | ||
173 | tlwParent->Connect(tlwParent->GetId(), wxEVT_KILL_FOCUS, | |
174 | (wxObjectEventFunction) (wxEventFunction) (wxFocusEventFunction) &wxGenericDrawerWindow::OnDrawerFocus, | |
175 | NULL, //user data | |
176 | this); | |
177 | ||
178 | m_LastParentSize = parent->GetSize(); | |
179 | DoDrawerPosition(); | |
180 | DoDrawerSize(); | |
181 | } | |
182 | else | |
183 | success = false; | |
184 | } | |
185 | ||
186 | m_nCurrentEdge = m_nPreferredEdge = edge; | |
187 | Show(success); | |
188 | if (success && parent->IsShown()) //bring parent on top | |
189 | { | |
190 | parent->Show(false); | |
191 | parent->Show(true); | |
192 | } | |
193 | //wxFprintf(stderr,wxT("success==%i\n"), success); | |
194 | return success; | |
195 | } | |
196 | ||
197 | wxDirection wxGenericDrawerWindow::GetCurrentEdge() const | |
198 | { | |
199 | return m_nCurrentEdge; | |
200 | } | |
201 | ||
202 | wxDirection wxGenericDrawerWindow::GetPreferredEdge() const | |
203 | { | |
204 | return m_nPreferredEdge; | |
205 | } | |
206 | ||
207 | bool wxGenericDrawerWindow::IsOpen() const | |
208 | { | |
209 | return m_bOpen; | |
210 | } | |
211 | ||
212 | bool wxGenericDrawerWindow::Open(const bool& show) | |
213 | { | |
214 | if(show) | |
215 | { | |
216 | if (m_pTimer) | |
217 | delete m_pTimer; | |
218 | ||
219 | m_pTimer = new wxGenericDrawerTimer(this, 1); | |
220 | m_pTimer->Start(wxGENERICDRAWER_INTERVAL); | |
221 | } | |
222 | else | |
223 | { | |
224 | if (m_pTimer) | |
225 | delete m_pTimer; | |
226 | ||
227 | m_pTimer = new wxGenericDrawerTimer(this, -1); | |
228 | m_pTimer->Start(wxGENERICDRAWER_INTERVAL); | |
229 | } | |
230 | ||
231 | return true; | |
232 | } | |
233 | ||
234 | bool wxGenericDrawerWindow::SetPreferredEdge(const wxDirection& edge) | |
235 | { | |
236 | wxASSERT(edge == wxLEFT || | |
237 | edge == wxRIGHT || | |
238 | edge == wxTOP || | |
239 | edge == wxBOTTOM ); | |
240 | ||
241 | if (!m_nOpenOffset) | |
242 | { | |
243 | m_nCurrentEdge = edge; | |
244 | DoDrawerPosition(); | |
245 | } | |
246 | ||
247 | m_nPreferredEdge = edge; | |
248 | return true; | |
249 | } | |
250 | ||
251 | void wxGenericDrawerWindow::DoDrawerPosition() | |
252 | { | |
253 | const wxPoint parentPosition(GetParent()->GetPosition()); | |
254 | SetPosition(wxPoint( | |
255 | parentPosition.x + | |
256 | (m_nCurrentEdge == wxLEFT ? | |
257 | -m_nOpenOffset : m_nCurrentEdge == wxRIGHT ? GetParent()->GetSize().GetWidth() + m_nOpenOffset - GetSize().GetWidth(): wxGENERICDRAWER_TOPOFFSET), | |
258 | parentPosition.y + | |
259 | (m_nCurrentEdge == wxTOP ? | |
260 | -m_nOpenOffset : m_nCurrentEdge == wxBOTTOM ? GetParent()->GetSize().GetHeight() + m_nOpenOffset - GetSize().GetHeight() : wxGENERICDRAWER_TOPOFFSET) | |
261 | )); | |
262 | //wxFprintf(stderr,wxT("parentposition:%i,%i\n"), parentPosition.x, parentPosition.y); | |
263 | //wxFprintf(stderr,wxT("offset:%i\nposition:%i,%i\n"), m_nOpenOffset, GetPosition().x, GetPosition().y); | |
264 | } | |
265 | ||
266 | void wxGenericDrawerWindow::DoDrawerSize() | |
267 | { | |
268 | // Constrain the drawer size to the parent window. | |
269 | const wxSize parentSize(GetParent()->GetClientSize()); | |
270 | wxSize size = GetSize(); | |
271 | ||
272 | if (wxLEFT == m_nCurrentEdge || wxRIGHT == m_nCurrentEdge) | |
273 | { | |
274 | if (size.GetHeight() > parentSize.GetHeight()) | |
275 | size.SetHeight(parentSize.GetHeight() - (wxGENERICDRAWER_TOPOFFSET + wxGENERICDRAWER_BOTTOMOFFSET)); | |
276 | ||
277 | size.SetHeight(size.GetHeight() + (parentSize.GetHeight() - m_LastParentSize.GetHeight())); | |
278 | } | |
279 | else | |
280 | { | |
281 | if (size.GetWidth() > parentSize.GetWidth()) | |
282 | size.SetWidth(parentSize.GetWidth() - (wxGENERICDRAWER_TOPOFFSET + wxGENERICDRAWER_BOTTOMOFFSET)); | |
283 | ||
284 | size.SetWidth(size.GetWidth() + (parentSize.GetWidth() - m_LastParentSize.GetWidth())); | |
285 | } | |
286 | ||
287 | SetSize(size); | |
288 | m_LastParentSize = parentSize; | |
289 | ||
290 | //wxFprintf(stderr,wxT("size:%i,%i\n"), size.GetWidth(), size.GetHeight()); | |
291 | } | |
292 | ||
293 | void wxGenericDrawerWindow::OnDrawerFocus(wxFocusEvent& evt) | |
294 | { | |
295 | // wxFprintf(stderr, wxT("focus\n")); | |
296 | ||
297 | if (wxWindow::FindFocus() == this) | |
298 | GetParent()->SetFocus(); | |
299 | } | |
300 | ||
301 | void wxGenericDrawerWindow::OnDrawerMove(wxMoveEvent& evt) | |
302 | { | |
303 | DoDrawerPosition(); | |
304 | } | |
305 | ||
306 | void wxGenericDrawerWindow::OnDrawerSize(wxSizeEvent& evt) | |
307 | { | |
308 | DoDrawerSize(); | |
309 | } | |
310 |