]>
Commit | Line | Data |
---|---|---|
cd05bf23 | 1 | ///////////////////////////////////////////////////////////////////////////// |
25f70bc4 | 2 | // Name: src/aui/tabmdi.cpp |
cd05bf23 BW |
3 | // Purpose: Generic MDI (Multiple Document Interface) classes |
4 | // Author: Hans Van Leemputten | |
5 | // Modified by: Benjamin I. Williams / Kirix Corporation | |
6 | // Created: 29/07/2002 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) Hans Van Leemputten | |
9 | // Licence: wxWindows licence | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | // =========================================================================== | |
13 | // declarations | |
14 | // =========================================================================== | |
15 | ||
16 | // --------------------------------------------------------------------------- | |
17 | // headers | |
18 | // --------------------------------------------------------------------------- | |
19 | ||
20 | // For compilers that support precompilation, includes "wx.h". | |
21 | #include "wx/wxprec.h" | |
22 | ||
23 | #ifdef __BORLANDC__ | |
24 | #pragma hdrstop | |
25 | #endif | |
26 | ||
25f70bc4 | 27 | #if wxUSE_AUI |
cd05bf23 BW |
28 | #if wxUSE_MDI |
29 | ||
30 | #include "wx/aui/tabmdi.h" | |
31 | ||
32 | #ifndef WX_PRECOMP | |
33 | #include "wx/panel.h" | |
34 | #include "wx/menu.h" | |
35 | #include "wx/intl.h" | |
36 | #include "wx/log.h" | |
4444d148 | 37 | #include "wx/settings.h" |
cd05bf23 BW |
38 | #endif //WX_PRECOMP |
39 | ||
40 | #include "wx/stockitem.h" | |
445a98c7 | 41 | #include "wx/aui/dockart.h" |
cd05bf23 BW |
42 | |
43 | enum MDI_MENU_ID | |
44 | { | |
45 | wxWINDOWCLOSE = 4001, | |
46 | wxWINDOWCLOSEALL, | |
47 | wxWINDOWNEXT, | |
48 | wxWINDOWPREV | |
49 | }; | |
50 | ||
51 | //----------------------------------------------------------------------------- | |
a3a5df9d | 52 | // wxAuiMDIParentFrame |
cd05bf23 BW |
53 | //----------------------------------------------------------------------------- |
54 | ||
a3a5df9d | 55 | IMPLEMENT_DYNAMIC_CLASS(wxAuiMDIParentFrame, wxFrame) |
cd05bf23 | 56 | |
a3a5df9d | 57 | BEGIN_EVENT_TABLE(wxAuiMDIParentFrame, wxFrame) |
cd05bf23 | 58 | #if wxUSE_MENUS |
a3a5df9d | 59 | EVT_MENU (wxID_ANY, wxAuiMDIParentFrame::DoHandleMenu) |
9827ce92 | 60 | EVT_UPDATE_UI (wxID_ANY, wxAuiMDIParentFrame::DoHandleUpdateUI) |
cd05bf23 BW |
61 | #endif |
62 | END_EVENT_TABLE() | |
63 | ||
a3a5df9d | 64 | wxAuiMDIParentFrame::wxAuiMDIParentFrame() |
cd05bf23 BW |
65 | { |
66 | Init(); | |
67 | } | |
68 | ||
a3a5df9d | 69 | wxAuiMDIParentFrame::wxAuiMDIParentFrame(wxWindow *parent, |
cd05bf23 BW |
70 | wxWindowID id, |
71 | const wxString& title, | |
72 | const wxPoint& pos, | |
73 | const wxSize& size, | |
74 | long style, | |
75 | const wxString& name) | |
76 | { | |
77 | Init(); | |
78 | (void)Create(parent, id, title, pos, size, style, name); | |
79 | } | |
80 | ||
a3a5df9d | 81 | wxAuiMDIParentFrame::~wxAuiMDIParentFrame() |
cd05bf23 | 82 | { |
0d1dd76b VZ |
83 | // Avoid having GetActiveChild() called after m_pClientWindow is destroyed |
84 | SendDestroyEvent(); | |
cd05bf23 BW |
85 | // Make sure the client window is destructed before the menu bars are! |
86 | wxDELETE(m_pClientWindow); | |
87 | ||
88 | #if wxUSE_MENUS | |
b0a54b8a | 89 | wxDELETE(m_pMyMenuBar); |
cd05bf23 | 90 | RemoveWindowMenu(GetMenuBar()); |
b0a54b8a | 91 | wxDELETE(m_pWindowMenu); |
cd05bf23 BW |
92 | #endif // wxUSE_MENUS |
93 | } | |
94 | ||
a3a5df9d | 95 | bool wxAuiMDIParentFrame::Create(wxWindow *parent, |
cd05bf23 BW |
96 | wxWindowID id, |
97 | const wxString& title, | |
98 | const wxPoint& pos, | |
99 | const wxSize& size, | |
100 | long style, | |
101 | const wxString& name) | |
102 | { | |
103 | #if wxUSE_MENUS | |
104 | // this style can be used to prevent a window from having the standard MDI | |
105 | // "Window" menu | |
106 | if (!(style & wxFRAME_NO_WINDOW_MENU)) | |
107 | { | |
108 | m_pWindowMenu = new wxMenu; | |
109 | m_pWindowMenu->Append(wxWINDOWCLOSE, _("Cl&ose")); | |
110 | m_pWindowMenu->Append(wxWINDOWCLOSEALL, _("Close All")); | |
111 | m_pWindowMenu->AppendSeparator(); | |
112 | m_pWindowMenu->Append(wxWINDOWNEXT, _("&Next")); | |
113 | m_pWindowMenu->Append(wxWINDOWPREV, _("&Previous")); | |
114 | } | |
115 | #endif // wxUSE_MENUS | |
116 | ||
6e42617a VZ |
117 | if ( !wxFrame::Create(parent, id, title, pos, size, style, name) ) |
118 | return false; | |
119 | ||
120 | m_pClientWindow = OnCreateClient(); | |
121 | return m_pClientWindow != NULL; | |
cd05bf23 BW |
122 | } |
123 | ||
f39fddcd BW |
124 | |
125 | void wxAuiMDIParentFrame::SetArtProvider(wxAuiTabArt* provider) | |
126 | { | |
127 | if (m_pClientWindow) | |
128 | { | |
129 | m_pClientWindow->SetArtProvider(provider); | |
130 | } | |
131 | } | |
132 | ||
133 | wxAuiTabArt* wxAuiMDIParentFrame::GetArtProvider() | |
134 | { | |
135 | if (!m_pClientWindow) | |
136 | return NULL; | |
ccc8c01a | 137 | |
f39fddcd BW |
138 | return m_pClientWindow->GetArtProvider(); |
139 | } | |
140 | ||
141 | wxAuiNotebook* wxAuiMDIParentFrame::GetNotebook() const | |
142 | { | |
143 | return static_cast<wxAuiNotebook*>(m_pClientWindow); | |
144 | } | |
145 | ||
146 | ||
147 | ||
cd05bf23 | 148 | #if wxUSE_MENUS |
a3a5df9d | 149 | void wxAuiMDIParentFrame::SetWindowMenu(wxMenu* pMenu) |
cd05bf23 BW |
150 | { |
151 | // Replace the window menu from the currently loaded menu bar. | |
152 | wxMenuBar *pMenuBar = GetMenuBar(); | |
153 | ||
154 | if (m_pWindowMenu) | |
155 | { | |
156 | RemoveWindowMenu(pMenuBar); | |
157 | wxDELETE(m_pWindowMenu); | |
158 | } | |
159 | ||
160 | if (pMenu) | |
161 | { | |
162 | m_pWindowMenu = pMenu; | |
163 | AddWindowMenu(pMenuBar); | |
164 | } | |
165 | } | |
166 | ||
a3a5df9d | 167 | void wxAuiMDIParentFrame::SetMenuBar(wxMenuBar* pMenuBar) |
cd05bf23 BW |
168 | { |
169 | // Remove the Window menu from the old menu bar | |
170 | RemoveWindowMenu(GetMenuBar()); | |
4444d148 | 171 | |
cd05bf23 BW |
172 | // Add the Window menu to the new menu bar. |
173 | AddWindowMenu(pMenuBar); | |
4444d148 | 174 | |
cd05bf23 | 175 | wxFrame::SetMenuBar(pMenuBar); |
b0a54b8a | 176 | //m_pMyMenuBar = GetMenuBar(); |
cd05bf23 BW |
177 | } |
178 | #endif // wxUSE_MENUS | |
179 | ||
a3a5df9d | 180 | void wxAuiMDIParentFrame::SetChildMenuBar(wxAuiMDIChildFrame* pChild) |
cd05bf23 BW |
181 | { |
182 | #if wxUSE_MENUS | |
183 | if (!pChild) | |
184 | { | |
185 | // No Child, set Our menu bar back. | |
092d7f88 BW |
186 | if (m_pMyMenuBar) |
187 | SetMenuBar(m_pMyMenuBar); | |
cedd7b22 | 188 | else |
092d7f88 | 189 | SetMenuBar(GetMenuBar()); |
cd05bf23 BW |
190 | |
191 | // Make sure we know our menu bar is in use | |
b0a54b8a | 192 | m_pMyMenuBar = NULL; |
cd05bf23 | 193 | } |
cedd7b22 | 194 | else |
cd05bf23 BW |
195 | { |
196 | if (pChild->GetMenuBar() == NULL) | |
197 | return; | |
ee0a94cf | 198 | |
cd05bf23 BW |
199 | // Do we need to save the current bar? |
200 | if (m_pMyMenuBar == NULL) | |
201 | m_pMyMenuBar = GetMenuBar(); | |
202 | ||
203 | SetMenuBar(pChild->GetMenuBar()); | |
204 | } | |
205 | #endif // wxUSE_MENUS | |
206 | } | |
207 | ||
a3a5df9d | 208 | bool wxAuiMDIParentFrame::ProcessEvent(wxEvent& event) |
cd05bf23 | 209 | { |
7e1f1a13 BW |
210 | // stops the same event being processed repeatedly |
211 | if (m_pLastEvt == &event) | |
cd05bf23 | 212 | return false; |
7e1f1a13 | 213 | m_pLastEvt = &event; |
ccc8c01a | 214 | |
7e1f1a13 | 215 | // let the active child (if any) process the event first. |
cd05bf23 | 216 | bool res = false; |
0d1dd76b VZ |
217 | wxAuiMDIChildFrame* pActiveChild = GetActiveChild(); |
218 | if (pActiveChild && | |
cd05bf23 BW |
219 | event.IsCommandEvent() && |
220 | event.GetEventObject() != m_pClientWindow && | |
221 | !(event.GetEventType() == wxEVT_ACTIVATE || | |
222 | event.GetEventType() == wxEVT_SET_FOCUS || | |
223 | event.GetEventType() == wxEVT_KILL_FOCUS || | |
224 | event.GetEventType() == wxEVT_CHILD_FOCUS || | |
225 | event.GetEventType() == wxEVT_COMMAND_SET_FOCUS || | |
226 | event.GetEventType() == wxEVT_COMMAND_KILL_FOCUS ) | |
227 | ) | |
228 | { | |
0d1dd76b | 229 | res = pActiveChild->GetEventHandler()->ProcessEvent(event); |
cd05bf23 BW |
230 | } |
231 | ||
cd05bf23 BW |
232 | if (!res) |
233 | { | |
7e1f1a13 BW |
234 | // if the event was not handled this frame will handle it, |
235 | // which is why we need the protection code at the beginning | |
236 | // of this method | |
cd05bf23 BW |
237 | res = wxEvtHandler::ProcessEvent(event); |
238 | } | |
239 | ||
7e1f1a13 | 240 | m_pLastEvt = NULL; |
cd05bf23 BW |
241 | |
242 | return res; | |
243 | } | |
244 | ||
a3a5df9d | 245 | wxAuiMDIChildFrame *wxAuiMDIParentFrame::GetActiveChild() const |
cd05bf23 | 246 | { |
91ad3a26 VZ |
247 | // We can be called before the client window is created, so check for its |
248 | // existence. | |
249 | wxAuiMDIClientWindow* const client = GetClientWindow(); | |
250 | return client ? client->GetActiveChild() : NULL; | |
cd05bf23 BW |
251 | } |
252 | ||
a3a5df9d | 253 | void wxAuiMDIParentFrame::SetActiveChild(wxAuiMDIChildFrame* pChildFrame) |
cd05bf23 | 254 | { |
91ad3a26 VZ |
255 | wxAuiMDIClientWindow* const client = GetClientWindow(); |
256 | if (client && client->GetActiveChild() != pChildFrame) | |
0d1dd76b | 257 | { |
91ad3a26 | 258 | client->SetActiveChild(pChildFrame); |
0d1dd76b | 259 | } |
cd05bf23 BW |
260 | } |
261 | ||
8856768e | 262 | wxAuiMDIClientWindow *wxAuiMDIParentFrame::GetClientWindow() const |
cd05bf23 BW |
263 | { |
264 | return m_pClientWindow; | |
265 | } | |
266 | ||
8856768e | 267 | wxAuiMDIClientWindow *wxAuiMDIParentFrame::OnCreateClient() |
cd05bf23 | 268 | { |
6e42617a | 269 | return new wxAuiMDIClientWindow( this ); |
cd05bf23 BW |
270 | } |
271 | ||
a3a5df9d | 272 | void wxAuiMDIParentFrame::ActivateNext() |
cd05bf23 | 273 | { |
4444d148 | 274 | if (m_pClientWindow && m_pClientWindow->GetSelection() != wxNOT_FOUND) |
cd05bf23 BW |
275 | { |
276 | size_t active = m_pClientWindow->GetSelection() + 1; | |
277 | if (active >= m_pClientWindow->GetPageCount()) | |
278 | active = 0; | |
279 | ||
280 | m_pClientWindow->SetSelection(active); | |
281 | } | |
282 | } | |
283 | ||
a3a5df9d | 284 | void wxAuiMDIParentFrame::ActivatePrevious() |
cd05bf23 | 285 | { |
4444d148 | 286 | if (m_pClientWindow && m_pClientWindow->GetSelection() != wxNOT_FOUND) |
cd05bf23 BW |
287 | { |
288 | int active = m_pClientWindow->GetSelection() - 1; | |
289 | if (active < 0) | |
290 | active = m_pClientWindow->GetPageCount() - 1; | |
291 | ||
292 | m_pClientWindow->SetSelection(active); | |
293 | } | |
294 | } | |
295 | ||
a3a5df9d | 296 | void wxAuiMDIParentFrame::Init() |
cd05bf23 | 297 | { |
7e1f1a13 | 298 | m_pLastEvt = NULL; |
cd05bf23 | 299 | m_pClientWindow = NULL; |
cd05bf23 BW |
300 | #if wxUSE_MENUS |
301 | m_pWindowMenu = NULL; | |
302 | m_pMyMenuBar = NULL; | |
303 | #endif // wxUSE_MENUS | |
304 | } | |
305 | ||
306 | #if wxUSE_MENUS | |
a3a5df9d | 307 | void wxAuiMDIParentFrame::RemoveWindowMenu(wxMenuBar* pMenuBar) |
cd05bf23 BW |
308 | { |
309 | if (pMenuBar && m_pWindowMenu) | |
310 | { | |
311 | // Remove old window menu | |
312 | int pos = pMenuBar->FindMenu(_("&Window")); | |
313 | if (pos != wxNOT_FOUND) | |
314 | { | |
315 | // DBG:: We're going to delete the wrong menu!!! | |
316 | wxASSERT(m_pWindowMenu == pMenuBar->GetMenu(pos)); | |
317 | pMenuBar->Remove(pos); | |
318 | } | |
319 | } | |
320 | } | |
321 | ||
a3a5df9d | 322 | void wxAuiMDIParentFrame::AddWindowMenu(wxMenuBar *pMenuBar) |
cd05bf23 BW |
323 | { |
324 | if (pMenuBar && m_pWindowMenu) | |
325 | { | |
ee0a94cf | 326 | int pos = pMenuBar->FindMenu(wxGetStockLabel(wxID_HELP,wxSTOCK_NOFLAGS)); |
cd05bf23 BW |
327 | if (pos == wxNOT_FOUND) |
328 | pMenuBar->Append(m_pWindowMenu, _("&Window")); | |
cedd7b22 | 329 | else |
cd05bf23 BW |
330 | pMenuBar->Insert(pos, m_pWindowMenu, _("&Window")); |
331 | } | |
332 | } | |
333 | ||
a3a5df9d | 334 | void wxAuiMDIParentFrame::DoHandleMenu(wxCommandEvent& event) |
cd05bf23 BW |
335 | { |
336 | switch (event.GetId()) | |
337 | { | |
338 | case wxWINDOWCLOSE: | |
0d1dd76b VZ |
339 | { |
340 | wxAuiMDIChildFrame* pActiveChild = GetActiveChild(); | |
341 | if (pActiveChild) | |
342 | pActiveChild->Close(); | |
cd05bf23 | 343 | break; |
0d1dd76b | 344 | } |
cd05bf23 | 345 | case wxWINDOWCLOSEALL: |
0d1dd76b VZ |
346 | { |
347 | wxAuiMDIChildFrame* pActiveChild; | |
348 | while ((pActiveChild = GetActiveChild()) != NULL) | |
cd05bf23 | 349 | { |
0d1dd76b | 350 | if (!pActiveChild->Close()) |
cd05bf23 BW |
351 | { |
352 | return; // failure | |
353 | } | |
cd05bf23 BW |
354 | } |
355 | break; | |
0d1dd76b | 356 | } |
cd05bf23 BW |
357 | case wxWINDOWNEXT: |
358 | ActivateNext(); | |
359 | break; | |
360 | case wxWINDOWPREV: | |
361 | ActivatePrevious(); | |
362 | break; | |
363 | default: | |
364 | event.Skip(); | |
365 | } | |
366 | } | |
9827ce92 VZ |
367 | |
368 | void wxAuiMDIParentFrame::DoHandleUpdateUI(wxUpdateUIEvent& event) | |
369 | { | |
370 | switch (event.GetId()) | |
371 | { | |
372 | case wxWINDOWCLOSE: | |
373 | case wxWINDOWCLOSEALL: | |
374 | { | |
375 | wxAuiMDIClientWindow* client_window = GetClientWindow(); | |
376 | wxCHECK_RET(client_window, wxS("Missing MDI Client Window")); | |
377 | size_t pages = client_window->GetPageCount(); | |
378 | event.Enable(pages >= 1); | |
379 | break; | |
380 | } | |
381 | ||
382 | case wxWINDOWNEXT: | |
383 | case wxWINDOWPREV: | |
384 | { | |
385 | wxAuiMDIClientWindow* client_window = GetClientWindow(); | |
386 | wxCHECK_RET(client_window, wxS("Missing MDI Client Window")); | |
387 | size_t pages = client_window->GetPageCount(); | |
388 | event.Enable(pages >= 2); | |
389 | break; | |
390 | } | |
391 | ||
392 | default: | |
393 | event.Skip(); | |
394 | } | |
395 | } | |
cd05bf23 BW |
396 | #endif // wxUSE_MENUS |
397 | ||
a3a5df9d | 398 | void wxAuiMDIParentFrame::DoGetClientSize(int* width, int* height) const |
cd05bf23 BW |
399 | { |
400 | wxFrame::DoGetClientSize(width, height); | |
401 | } | |
402 | ||
d606b6e9 BW |
403 | void wxAuiMDIParentFrame::Tile(wxOrientation orient) |
404 | { | |
405 | wxAuiMDIClientWindow* client_window = GetClientWindow(); | |
406 | wxASSERT_MSG(client_window, wxT("Missing MDI Client Window")); | |
ccc8c01a | 407 | |
d606b6e9 BW |
408 | int cur_idx = client_window->GetSelection(); |
409 | if (cur_idx == -1) | |
410 | return; | |
ccc8c01a | 411 | |
d606b6e9 BW |
412 | if (orient == wxVERTICAL) |
413 | { | |
414 | client_window->Split(cur_idx, wxLEFT); | |
415 | } | |
cedd7b22 | 416 | else if (orient == wxHORIZONTAL) |
d606b6e9 BW |
417 | { |
418 | client_window->Split(cur_idx, wxTOP); | |
419 | } | |
420 | } | |
421 | ||
422 | ||
cd05bf23 | 423 | //----------------------------------------------------------------------------- |
a3a5df9d | 424 | // wxAuiMDIChildFrame |
cd05bf23 BW |
425 | //----------------------------------------------------------------------------- |
426 | ||
a3a5df9d | 427 | IMPLEMENT_DYNAMIC_CLASS(wxAuiMDIChildFrame, wxPanel) |
cd05bf23 | 428 | |
a3a5df9d BW |
429 | BEGIN_EVENT_TABLE(wxAuiMDIChildFrame, wxPanel) |
430 | EVT_MENU_HIGHLIGHT_ALL(wxAuiMDIChildFrame::OnMenuHighlight) | |
431 | EVT_ACTIVATE(wxAuiMDIChildFrame::OnActivate) | |
432 | EVT_CLOSE(wxAuiMDIChildFrame::OnCloseWindow) | |
cd05bf23 BW |
433 | END_EVENT_TABLE() |
434 | ||
a3a5df9d | 435 | wxAuiMDIChildFrame::wxAuiMDIChildFrame() |
cd05bf23 BW |
436 | { |
437 | Init(); | |
438 | } | |
439 | ||
a3a5df9d | 440 | wxAuiMDIChildFrame::wxAuiMDIChildFrame(wxAuiMDIParentFrame *parent, |
cd05bf23 BW |
441 | wxWindowID id, |
442 | const wxString& title, | |
443 | const wxPoint& WXUNUSED(pos), | |
444 | const wxSize& size, | |
445 | long style, | |
446 | const wxString& name) | |
447 | { | |
448 | Init(); | |
ccc8c01a | 449 | |
e7e324be BW |
450 | // There are two ways to create an tabbed mdi child fram without |
451 | // making it the active document. Either Show(false) can be called | |
452 | // before Create() (as is customary on some ports with wxFrame-type | |
453 | // windows), or wxMINIMIZE can be passed in the style flags. Note that | |
454 | // wxAuiMDIChildFrame is not really derived from wxFrame, as wxMDIChildFrame | |
455 | // is, but those are the expected symantics. No style flag is passed | |
456 | // onto the panel underneath. | |
457 | if (style & wxMINIMIZE) | |
9a29fe70 | 458 | m_activateOnCreate = false; |
ccc8c01a | 459 | |
e7e324be | 460 | Create(parent, id, title, wxDefaultPosition, size, 0, name); |
cd05bf23 BW |
461 | } |
462 | ||
a3a5df9d | 463 | wxAuiMDIChildFrame::~wxAuiMDIChildFrame() |
cd05bf23 | 464 | { |
b0a54b8a | 465 | wxAuiMDIParentFrame* pParentFrame = GetMDIParentFrame(); |
8691bf11 | 466 | if (pParentFrame) |
b0a54b8a | 467 | { |
8691bf11 BW |
468 | if (pParentFrame->GetActiveChild() == this) |
469 | { | |
470 | pParentFrame->SetActiveChild(NULL); | |
471 | pParentFrame->SetChildMenuBar(NULL); | |
472 | } | |
473 | wxAuiMDIClientWindow* pClientWindow = pParentFrame->GetClientWindow(); | |
474 | wxASSERT(pClientWindow); | |
475 | int idx = pClientWindow->GetPageIndex(this); | |
476 | if (idx != wxNOT_FOUND) | |
477 | { | |
478 | pClientWindow->RemovePage(idx); | |
479 | } | |
b0a54b8a | 480 | } |
ccc8c01a | 481 | |
cd05bf23 BW |
482 | #if wxUSE_MENUS |
483 | wxDELETE(m_pMenuBar); | |
484 | #endif // wxUSE_MENUS | |
485 | } | |
486 | ||
a3a5df9d | 487 | bool wxAuiMDIChildFrame::Create(wxAuiMDIParentFrame* parent, |
cd05bf23 BW |
488 | wxWindowID id, |
489 | const wxString& title, | |
490 | const wxPoint& WXUNUSED(pos), | |
491 | const wxSize& size, | |
492 | long style, | |
493 | const wxString& name) | |
494 | { | |
8856768e | 495 | wxAuiMDIClientWindow* pClientWindow = parent->GetClientWindow(); |
d3b9f782 | 496 | wxASSERT_MSG((pClientWindow != NULL), wxT("Missing MDI client window.")); |
cd05bf23 | 497 | |
e7e324be BW |
498 | // see comment in constructor |
499 | if (style & wxMINIMIZE) | |
9a29fe70 | 500 | m_activateOnCreate = false; |
e7e324be | 501 | |
ea53a601 BW |
502 | wxSize cli_size = pClientWindow->GetClientSize(); |
503 | ||
504 | // create the window off-screen to prevent flicker | |
505 | wxPanel::Create(pClientWindow, | |
cedd7b22 PC |
506 | id, |
507 | wxPoint(cli_size.x+1, cli_size.y+1), | |
508 | size, | |
509 | wxNO_BORDER, name); | |
e7e324be BW |
510 | |
511 | DoShow(false); | |
cd05bf23 BW |
512 | |
513 | SetMDIParentFrame(parent); | |
514 | ||
cd05bf23 BW |
515 | m_title = title; |
516 | ||
9a29fe70 | 517 | pClientWindow->AddPage(this, title, m_activateOnCreate); |
0d1dd76b VZ |
518 | |
519 | // Check that the parent notion of the active child coincides with our one. | |
520 | // This is less obvious that it seems because we must honour | |
521 | // m_activateOnCreate flag but only if it's not the first child because | |
522 | // this one becomes active unconditionally. | |
523 | wxASSERT_MSG | |
524 | ( | |
525 | (m_activateOnCreate || pClientWindow->GetPageCount() == 1) | |
526 | == (parent->GetActiveChild() == this), | |
527 | wxS("Logic error: child [not] activated when it should [not] have been.") | |
528 | ); | |
529 | ||
cd05bf23 | 530 | pClientWindow->Refresh(); |
ccc8c01a | 531 | |
cd05bf23 BW |
532 | return true; |
533 | } | |
534 | ||
a3a5df9d | 535 | bool wxAuiMDIChildFrame::Destroy() |
cd05bf23 | 536 | { |
a3a5df9d | 537 | wxAuiMDIParentFrame* pParentFrame = GetMDIParentFrame(); |
cd05bf23 | 538 | wxASSERT_MSG(pParentFrame, wxT("Missing MDI Parent Frame")); |
4444d148 | 539 | |
8856768e | 540 | wxAuiMDIClientWindow* pClientWindow = pParentFrame->GetClientWindow(); |
cd05bf23 | 541 | wxASSERT_MSG(pClientWindow, wxT("Missing MDI Client Window")); |
4444d148 | 542 | |
cd05bf23 BW |
543 | if (pParentFrame->GetActiveChild() == this) |
544 | { | |
c5e2ca7c BW |
545 | // deactivate ourself |
546 | wxActivateEvent event(wxEVT_ACTIVATE, false, GetId()); | |
547 | event.SetEventObject(this); | |
548 | GetEventHandler()->ProcessEvent(event); | |
ccc8c01a | 549 | |
cd05bf23 | 550 | pParentFrame->SetChildMenuBar(NULL); |
cd05bf23 | 551 | } |
4444d148 | 552 | |
c5e2ca7c | 553 | size_t page_count = pClientWindow->GetPageCount(); |
d3b647c2 | 554 | for (size_t pos = 0; pos < page_count; pos++) |
cd05bf23 BW |
555 | { |
556 | if (pClientWindow->GetPage(pos) == this) | |
557 | return pClientWindow->DeletePage(pos); | |
558 | } | |
4444d148 | 559 | |
cd05bf23 BW |
560 | return false; |
561 | } | |
562 | ||
cd05bf23 | 563 | #if wxUSE_MENUS |
a3a5df9d | 564 | void wxAuiMDIChildFrame::SetMenuBar(wxMenuBar *menu_bar) |
cd05bf23 BW |
565 | { |
566 | wxMenuBar *pOldMenuBar = m_pMenuBar; | |
567 | m_pMenuBar = menu_bar; | |
568 | ||
569 | if (m_pMenuBar) | |
570 | { | |
a3a5df9d | 571 | wxAuiMDIParentFrame* pParentFrame = GetMDIParentFrame(); |
cd05bf23 BW |
572 | wxASSERT_MSG(pParentFrame, wxT("Missing MDI Parent Frame")); |
573 | ||
574 | m_pMenuBar->SetParent(pParentFrame); | |
575 | if (pParentFrame->GetActiveChild() == this) | |
576 | { | |
577 | // replace current menu bars | |
578 | if (pOldMenuBar) | |
579 | pParentFrame->SetChildMenuBar(NULL); | |
580 | pParentFrame->SetChildMenuBar(this); | |
581 | } | |
582 | } | |
583 | } | |
584 | ||
a3a5df9d | 585 | wxMenuBar *wxAuiMDIChildFrame::GetMenuBar() const |
cd05bf23 BW |
586 | { |
587 | return m_pMenuBar; | |
588 | } | |
589 | #endif // wxUSE_MENUS | |
590 | ||
a3a5df9d | 591 | void wxAuiMDIChildFrame::SetTitle(const wxString& title) |
cd05bf23 BW |
592 | { |
593 | m_title = title; | |
594 | ||
a3a5df9d | 595 | wxAuiMDIParentFrame* pParentFrame = GetMDIParentFrame(); |
cd05bf23 BW |
596 | wxASSERT_MSG(pParentFrame, wxT("Missing MDI Parent Frame")); |
597 | ||
8856768e | 598 | wxAuiMDIClientWindow* pClientWindow = pParentFrame->GetClientWindow(); |
cd05bf23 BW |
599 | if (pClientWindow != NULL) |
600 | { | |
601 | size_t pos; | |
602 | for (pos = 0; pos < pClientWindow->GetPageCount(); pos++) | |
603 | { | |
604 | if (pClientWindow->GetPage(pos) == this) | |
605 | { | |
606 | pClientWindow->SetPageText(pos, m_title); | |
607 | break; | |
608 | } | |
609 | } | |
610 | } | |
611 | } | |
612 | ||
a3a5df9d | 613 | wxString wxAuiMDIChildFrame::GetTitle() const |
cd05bf23 BW |
614 | { |
615 | return m_title; | |
616 | } | |
617 | ||
e0dc13d4 BW |
618 | void wxAuiMDIChildFrame::SetIcons(const wxIconBundle& icons) |
619 | { | |
620 | // get icon with the system icon size | |
621 | SetIcon(icons.GetIcon(-1)); | |
9a29fe70 | 622 | m_iconBundle = icons; |
e0dc13d4 BW |
623 | } |
624 | ||
625 | const wxIconBundle& wxAuiMDIChildFrame::GetIcons() const | |
626 | { | |
9a29fe70 | 627 | return m_iconBundle; |
e0dc13d4 BW |
628 | } |
629 | ||
630 | void wxAuiMDIChildFrame::SetIcon(const wxIcon& icon) | |
631 | { | |
632 | wxAuiMDIParentFrame* pParentFrame = GetMDIParentFrame(); | |
633 | wxASSERT_MSG(pParentFrame, wxT("Missing MDI Parent Frame")); | |
634 | ||
635 | m_icon = icon; | |
ccc8c01a | 636 | |
e0dc13d4 BW |
637 | wxBitmap bmp; |
638 | bmp.CopyFromIcon(m_icon); | |
ccc8c01a | 639 | |
e0dc13d4 BW |
640 | wxAuiMDIClientWindow* pClientWindow = pParentFrame->GetClientWindow(); |
641 | if (pClientWindow != NULL) | |
642 | { | |
643 | int idx = pClientWindow->GetPageIndex(this); | |
ccc8c01a | 644 | |
e0dc13d4 BW |
645 | if (idx != -1) |
646 | { | |
647 | pClientWindow->SetPageBitmap((size_t)idx, bmp); | |
648 | } | |
649 | } | |
650 | } | |
651 | ||
652 | const wxIcon& wxAuiMDIChildFrame::GetIcon() const | |
653 | { | |
654 | return m_icon; | |
655 | } | |
ccc8c01a VZ |
656 | |
657 | ||
a3a5df9d | 658 | void wxAuiMDIChildFrame::Activate() |
cd05bf23 | 659 | { |
a3a5df9d | 660 | wxAuiMDIParentFrame* pParentFrame = GetMDIParentFrame(); |
cd05bf23 BW |
661 | wxASSERT_MSG(pParentFrame, wxT("Missing MDI Parent Frame")); |
662 | ||
8856768e | 663 | wxAuiMDIClientWindow* pClientWindow = pParentFrame->GetClientWindow(); |
cd05bf23 BW |
664 | |
665 | if (pClientWindow != NULL) | |
666 | { | |
667 | size_t pos; | |
668 | for (pos = 0; pos < pClientWindow->GetPageCount(); pos++) | |
669 | { | |
670 | if (pClientWindow->GetPage(pos) == this) | |
671 | { | |
672 | pClientWindow->SetSelection(pos); | |
673 | break; | |
674 | } | |
675 | } | |
676 | } | |
677 | } | |
678 | ||
a3a5df9d | 679 | void wxAuiMDIChildFrame::OnMenuHighlight(wxMenuEvent& event) |
cd05bf23 BW |
680 | { |
681 | #if wxUSE_STATUSBAR | |
682 | if (m_pMDIParentFrame) | |
683 | { | |
684 | // we don't have any help text for this item, | |
685 | // but may be the MDI frame does? | |
686 | m_pMDIParentFrame->OnMenuHighlight(event); | |
687 | } | |
688 | #else | |
689 | wxUnusedVar(event); | |
690 | #endif // wxUSE_STATUSBAR | |
691 | } | |
692 | ||
a3a5df9d | 693 | void wxAuiMDIChildFrame::OnActivate(wxActivateEvent& WXUNUSED(event)) |
cd05bf23 BW |
694 | { |
695 | // do nothing | |
696 | } | |
697 | ||
a3a5df9d | 698 | void wxAuiMDIChildFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event)) |
cd05bf23 BW |
699 | { |
700 | Destroy(); | |
701 | } | |
702 | ||
a3a5df9d | 703 | void wxAuiMDIChildFrame::SetMDIParentFrame(wxAuiMDIParentFrame* parentFrame) |
cd05bf23 BW |
704 | { |
705 | m_pMDIParentFrame = parentFrame; | |
706 | } | |
707 | ||
a3a5df9d | 708 | wxAuiMDIParentFrame* wxAuiMDIChildFrame::GetMDIParentFrame() const |
cd05bf23 BW |
709 | { |
710 | return m_pMDIParentFrame; | |
711 | } | |
712 | ||
a3a5df9d | 713 | void wxAuiMDIChildFrame::Init() |
cd05bf23 | 714 | { |
9a29fe70 | 715 | m_activateOnCreate = true; |
cd05bf23 BW |
716 | m_pMDIParentFrame = NULL; |
717 | #if wxUSE_MENUS | |
718 | m_pMenuBar = NULL; | |
719 | #endif // wxUSE_MENUS | |
720 | } | |
721 | ||
e7e324be | 722 | bool wxAuiMDIChildFrame::Show(bool show) |
cd05bf23 | 723 | { |
0d1dd76b VZ |
724 | // wxAuiMDIChildFrame uses m_activateOnCreate only to decide whether to |
725 | // activate the frame when it is created. After Create() is called, | |
726 | // m_activateOnCreate will never be read again. Therefore, calling this | |
727 | // function after Create() is pointless and you probably want to call | |
728 | // Activate() instead. | |
729 | wxCHECK_MSG( !GetHandle(), false, | |
730 | wxS("Show() has no effect after Create(). Do you mean Activate()?") ); | |
731 | ||
9a29fe70 | 732 | m_activateOnCreate = show; |
ccc8c01a | 733 | |
cd05bf23 BW |
734 | // do nothing |
735 | return true; | |
736 | } | |
737 | ||
a3a5df9d | 738 | void wxAuiMDIChildFrame::DoShow(bool show) |
cd05bf23 BW |
739 | { |
740 | wxWindow::Show(show); | |
741 | } | |
742 | ||
a3a5df9d | 743 | void wxAuiMDIChildFrame::DoSetSize(int x, int y, int width, int height, int sizeFlags) |
cd05bf23 | 744 | { |
9a29fe70 | 745 | m_mdiNewRect = wxRect(x, y, width, height); |
a94476de BW |
746 | #ifdef __WXGTK__ |
747 | wxPanel::DoSetSize(x,y,width, height, sizeFlags); | |
f9c240ec BW |
748 | #else |
749 | wxUnusedVar(sizeFlags); | |
a94476de | 750 | #endif |
cd05bf23 BW |
751 | } |
752 | ||
a3a5df9d | 753 | void wxAuiMDIChildFrame::DoMoveWindow(int x, int y, int width, int height) |
cd05bf23 | 754 | { |
9a29fe70 | 755 | m_mdiNewRect = wxRect(x, y, width, height); |
cd05bf23 BW |
756 | } |
757 | ||
a3a5df9d | 758 | void wxAuiMDIChildFrame::ApplyMDIChildFrameRect() |
cd05bf23 | 759 | { |
9a29fe70 | 760 | if (m_mdiCurRect != m_mdiNewRect) |
cd05bf23 | 761 | { |
9a29fe70 VZ |
762 | wxPanel::DoMoveWindow(m_mdiNewRect.x, m_mdiNewRect.y, |
763 | m_mdiNewRect.width, m_mdiNewRect.height); | |
764 | m_mdiCurRect = m_mdiNewRect; | |
cd05bf23 BW |
765 | } |
766 | } | |
767 | ||
768 | ||
769 | //----------------------------------------------------------------------------- | |
8856768e | 770 | // wxAuiMDIClientWindow |
cd05bf23 BW |
771 | //----------------------------------------------------------------------------- |
772 | ||
8856768e | 773 | IMPLEMENT_DYNAMIC_CLASS(wxAuiMDIClientWindow, wxAuiNotebook) |
cd05bf23 | 774 | |
8856768e BW |
775 | BEGIN_EVENT_TABLE(wxAuiMDIClientWindow, wxAuiNotebook) |
776 | EVT_AUINOTEBOOK_PAGE_CHANGED(wxID_ANY, wxAuiMDIClientWindow::OnPageChanged) | |
c5e2ca7c | 777 | EVT_AUINOTEBOOK_PAGE_CLOSE(wxID_ANY, wxAuiMDIClientWindow::OnPageClose) |
8856768e | 778 | EVT_SIZE(wxAuiMDIClientWindow::OnSize) |
cd05bf23 BW |
779 | END_EVENT_TABLE() |
780 | ||
8856768e | 781 | wxAuiMDIClientWindow::wxAuiMDIClientWindow() |
cd05bf23 BW |
782 | { |
783 | } | |
784 | ||
8856768e | 785 | wxAuiMDIClientWindow::wxAuiMDIClientWindow(wxAuiMDIParentFrame* parent, long style) |
cd05bf23 BW |
786 | { |
787 | CreateClient(parent, style); | |
788 | } | |
789 | ||
8856768e | 790 | bool wxAuiMDIClientWindow::CreateClient(wxAuiMDIParentFrame* parent, long style) |
cd05bf23 BW |
791 | { |
792 | SetWindowStyleFlag(style); | |
793 | ||
ccc8c01a | 794 | wxSize caption_icon_size = |
9fbb7d80 BW |
795 | wxSize(wxSystemSettings::GetMetric(wxSYS_SMALLICON_X), |
796 | wxSystemSettings::GetMetric(wxSYS_SMALLICON_Y)); | |
797 | SetUniformBitmapSize(caption_icon_size); | |
ccc8c01a | 798 | |
a3a5df9d | 799 | if (!wxAuiNotebook::Create(parent, |
695c0088 BW |
800 | wxID_ANY, |
801 | wxPoint(0,0), | |
802 | wxSize(100, 100), | |
803 | wxAUI_NB_DEFAULT_STYLE | wxNO_BORDER)) | |
cd05bf23 BW |
804 | { |
805 | return false; | |
806 | } | |
4444d148 | 807 | |
cd05bf23 | 808 | wxColour bkcolour = wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE); |
e7e324be | 809 | SetOwnBackgroundColour(bkcolour); |
4444d148 | 810 | |
254a3429 | 811 | m_mgr.GetArtProvider()->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, bkcolour); |
4444d148 | 812 | |
cd05bf23 BW |
813 | return true; |
814 | } | |
815 | ||
8856768e | 816 | int wxAuiMDIClientWindow::SetSelection(size_t nPage) |
cd05bf23 | 817 | { |
a3a5df9d | 818 | return wxAuiNotebook::SetSelection(nPage); |
cd05bf23 BW |
819 | } |
820 | ||
0d1dd76b VZ |
821 | wxAuiMDIChildFrame* wxAuiMDIClientWindow::GetActiveChild() |
822 | { | |
823 | const int sel = GetSelection(); | |
824 | if ( sel == wxNOT_FOUND ) | |
825 | return NULL; | |
826 | ||
827 | return wxStaticCast(GetPage(sel), wxAuiMDIChildFrame); | |
828 | } | |
829 | ||
8856768e | 830 | void wxAuiMDIClientWindow::PageChanged(int old_selection, int new_selection) |
cd05bf23 BW |
831 | { |
832 | // don't do anything if the page doesn't actually change | |
833 | if (old_selection == new_selection) | |
834 | return; | |
ccc8c01a | 835 | |
c5e2ca7c | 836 | /* |
cd05bf23 BW |
837 | // don't do anything if the new page is already active |
838 | if (new_selection != -1) | |
839 | { | |
a3a5df9d | 840 | wxAuiMDIChildFrame* child = (wxAuiMDIChildFrame*)GetPage(new_selection); |
cd05bf23 BW |
841 | if (child->GetMDIParentFrame()->GetActiveChild() == child) |
842 | return; | |
c5e2ca7c | 843 | }*/ |
ccc8c01a VZ |
844 | |
845 | ||
cd05bf23 | 846 | // notify old active child that it has been deactivated |
8691bf11 | 847 | if ((old_selection != -1) && (old_selection < (int)GetPageCount())) |
cd05bf23 | 848 | { |
a3a5df9d | 849 | wxAuiMDIChildFrame* old_child = (wxAuiMDIChildFrame*)GetPage(old_selection); |
8856768e | 850 | wxASSERT_MSG(old_child, wxT("wxAuiMDIClientWindow::PageChanged - null page pointer")); |
4444d148 | 851 | |
cd05bf23 BW |
852 | wxActivateEvent event(wxEVT_ACTIVATE, false, old_child->GetId()); |
853 | event.SetEventObject(old_child); | |
854 | old_child->GetEventHandler()->ProcessEvent(event); | |
855 | } | |
ccc8c01a | 856 | |
cd05bf23 BW |
857 | // notify new active child that it has been activated |
858 | if (new_selection != -1) | |
859 | { | |
a3a5df9d | 860 | wxAuiMDIChildFrame* active_child = (wxAuiMDIChildFrame*)GetPage(new_selection); |
8856768e | 861 | wxASSERT_MSG(active_child, wxT("wxAuiMDIClientWindow::PageChanged - null page pointer")); |
ccc8c01a | 862 | |
cd05bf23 BW |
863 | wxActivateEvent event(wxEVT_ACTIVATE, true, active_child->GetId()); |
864 | event.SetEventObject(active_child); | |
865 | active_child->GetEventHandler()->ProcessEvent(event); | |
ccc8c01a | 866 | |
cd05bf23 BW |
867 | if (active_child->GetMDIParentFrame()) |
868 | { | |
869 | active_child->GetMDIParentFrame()->SetActiveChild(active_child); | |
870 | active_child->GetMDIParentFrame()->SetChildMenuBar(active_child); | |
871 | } | |
872 | } | |
ccc8c01a | 873 | |
c5e2ca7c BW |
874 | |
875 | } | |
876 | ||
877 | void wxAuiMDIClientWindow::OnPageClose(wxAuiNotebookEvent& evt) | |
878 | { | |
879 | wxAuiMDIChildFrame* wnd; | |
880 | wnd = static_cast<wxAuiMDIChildFrame*>(GetPage(evt.GetSelection())); | |
ccc8c01a | 881 | |
c5e2ca7c | 882 | wnd->Close(); |
ccc8c01a | 883 | |
c5e2ca7c BW |
884 | // regardless of the result of wnd->Close(), we've |
885 | // already taken care of the close operations, so | |
886 | // suppress further processing | |
887 | evt.Veto(); | |
cd05bf23 BW |
888 | } |
889 | ||
8856768e | 890 | void wxAuiMDIClientWindow::OnPageChanged(wxAuiNotebookEvent& evt) |
cd05bf23 BW |
891 | { |
892 | PageChanged(evt.GetOldSelection(), evt.GetSelection()); | |
cd05bf23 BW |
893 | } |
894 | ||
8856768e | 895 | void wxAuiMDIClientWindow::OnSize(wxSizeEvent& evt) |
4444d148 | 896 | { |
a3a5df9d | 897 | wxAuiNotebook::OnSize(evt); |
cd05bf23 BW |
898 | |
899 | for (size_t pos = 0; pos < GetPageCount(); pos++) | |
a3a5df9d | 900 | ((wxAuiMDIChildFrame *)GetPage(pos))->ApplyMDIChildFrameRect(); |
cd05bf23 BW |
901 | } |
902 | ||
25f70bc4 | 903 | #endif //wxUSE_AUI |
cd05bf23 | 904 | #endif // wxUSE_MDI |