]> git.saurik.com Git - wxWidgets.git/blob - src/gtk1/mdi.cpp
* Fixed a memory leak in wxThread
[wxWidgets.git] / src / gtk1 / mdi.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: mdi.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Id: $Id$
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 #ifdef __GNUG__
11 #pragma implementation "mdi.h"
12 #endif
13
14 #include "wx/mdi.h"
15 #include "wx/dialog.h"
16 #include "wx/menu.h"
17 #include "wx/gtk/win_gtk.h"
18 #include <wx/intl.h>
19
20 //-----------------------------------------------------------------------------
21 // constants
22 //-----------------------------------------------------------------------------
23
24 const int wxMENU_HEIGHT = 30;
25
26 //-----------------------------------------------------------------------------
27 // globals
28 //-----------------------------------------------------------------------------
29
30 extern wxList wxPendingDelete;
31
32 //-----------------------------------------------------------------------------
33 // "size_allocate"
34 //-----------------------------------------------------------------------------
35
36 static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win )
37 {
38 if ((win->m_x == alloc->x) &&
39 (win->m_y == alloc->y) &&
40 (win->m_width == alloc->width) &&
41 (win->m_height == alloc->height))
42 {
43 return;
44 }
45
46 win->SetSize( alloc->x, alloc->y, alloc->width, alloc->height );
47 }
48
49 //-----------------------------------------------------------------------------
50 // page change callback
51 //-----------------------------------------------------------------------------
52
53 static void gtk_page_change_callback( GtkNotebook *WXUNUSED(widget),
54 GtkNotebookPage *page,
55 gint WXUNUSED(nPage),
56 wxMDIClientWindow *client_win )
57 {
58 wxNode *node = client_win->m_children.First();
59 while (node)
60 {
61 wxMDIChildFrame *child_frame = (wxMDIChildFrame *)node->Data();
62 if (child_frame->m_page == page)
63 {
64 wxMDIParentFrame *mdi_frame = (wxMDIParentFrame*)client_win->m_parent;
65 mdi_frame->m_currentChild = child_frame;
66 mdi_frame->SetMDIMenuBar( child_frame->m_menuBar );
67 return;
68 }
69 node = node->Next();
70 }
71 }
72
73 //-----------------------------------------------------------------------------
74 // wxMDIParentFrame
75 //-----------------------------------------------------------------------------
76
77 IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame,wxFrame)
78
79 BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame)
80 END_EVENT_TABLE()
81
82 wxMDIParentFrame::wxMDIParentFrame(void)
83 {
84 m_clientWindow = (wxMDIClientWindow *) NULL;
85 m_currentChild = (wxMDIChildFrame *) NULL;
86 m_parentFrameActive = TRUE;
87 }
88
89 wxMDIParentFrame::wxMDIParentFrame( wxWindow *parent,
90 wxWindowID id, const wxString& title,
91 const wxPoint& pos, const wxSize& size,
92 long style, const wxString& name )
93 {
94 m_clientWindow = (wxMDIClientWindow *) NULL;
95 m_currentChild = (wxMDIChildFrame *) NULL;
96 m_parentFrameActive = TRUE;
97 Create( parent, id, title, pos, size, style, name );
98 }
99
100 wxMDIParentFrame::~wxMDIParentFrame(void)
101 {
102 }
103
104 bool wxMDIParentFrame::Create( wxWindow *parent,
105 wxWindowID id, const wxString& title,
106 const wxPoint& pos, const wxSize& size,
107 long style, const wxString& name )
108 {
109 wxFrame::Create( parent, id, title, pos, size, style, name );
110
111 OnCreateClient();
112
113 return TRUE;
114 }
115
116 void wxMDIParentFrame::GtkOnSize( int x, int y, int width, int height )
117 {
118 wxFrame::GtkOnSize( x, y, width, height );
119
120 if (m_mdiMenuBar)
121 {
122 m_mdiMenuBar->m_x = 1;
123 m_mdiMenuBar->m_y = 1;
124 m_mdiMenuBar->m_width = m_width-2;
125 m_mdiMenuBar->m_height = wxMENU_HEIGHT-2;
126 gtk_myfixed_move( GTK_MYFIXED(m_wxwindow), m_mdiMenuBar->m_widget, 1, 1 );
127 gtk_widget_set_usize( m_mdiMenuBar->m_widget, m_width-2, wxMENU_HEIGHT-2 );
128 }
129 }
130
131 void wxMDIParentFrame::SetMDIMenuBar( wxMenuBar *menu_bar )
132 {
133 if (m_mdiMenuBar) m_mdiMenuBar->Show( FALSE );
134 m_mdiMenuBar = menu_bar;
135 if (m_mdiMenuBar)
136 {
137 m_mdiMenuBar->m_x = 1;
138 m_mdiMenuBar->m_y = 1;
139 m_mdiMenuBar->m_width = m_width-2;
140 m_mdiMenuBar->m_height = wxMENU_HEIGHT-2;
141 gtk_myfixed_move( GTK_MYFIXED(m_wxwindow), m_mdiMenuBar->m_widget, 1, 1 );
142 gtk_widget_set_usize( m_mdiMenuBar->m_widget, m_width-2, wxMENU_HEIGHT-2 );
143 m_mdiMenuBar->Show( TRUE );
144 }
145 }
146
147 void wxMDIParentFrame::GetClientSize(int *width, int *height ) const
148 {
149 wxFrame::GetClientSize( width, height );
150 }
151
152 wxMDIChildFrame *wxMDIParentFrame::GetActiveChild(void) const
153 {
154 return m_currentChild;
155 }
156
157 wxMDIClientWindow *wxMDIParentFrame::GetClientWindow(void) const
158 {
159 return m_clientWindow;
160 }
161
162 wxMDIClientWindow *wxMDIParentFrame::OnCreateClient(void)
163 {
164 m_clientWindow = new wxMDIClientWindow( this );
165 return m_clientWindow;
166 }
167
168 void wxMDIParentFrame::ActivateNext(void)
169 {
170 if (m_clientWindow)
171 gtk_notebook_next_page( GTK_NOTEBOOK(m_clientWindow->m_widget) );
172 }
173
174 void wxMDIParentFrame::ActivatePrevious(void)
175 {
176 if (m_clientWindow)
177 gtk_notebook_prev_page( GTK_NOTEBOOK(m_clientWindow->m_widget) );
178 }
179
180 void wxMDIParentFrame::OnActivate( wxActivateEvent& WXUNUSED(event) )
181 {
182 }
183
184 void wxMDIParentFrame::OnSysColourChanged( wxSysColourChangedEvent& WXUNUSED(event) )
185 {
186 }
187
188 //-----------------------------------------------------------------------------
189 // wxMDIChildFrame
190 //-----------------------------------------------------------------------------
191
192 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame,wxFrame)
193
194 BEGIN_EVENT_TABLE(wxMDIChildFrame, wxFrame)
195 EVT_ACTIVATE(wxMDIChildFrame::OnActivate)
196 END_EVENT_TABLE()
197
198 wxMDIChildFrame::wxMDIChildFrame(void)
199 {
200 m_menuBar = (wxMenuBar *) NULL;
201 m_page = (GtkNotebookPage *) NULL;
202 }
203
204 wxMDIChildFrame::wxMDIChildFrame( wxMDIParentFrame *parent,
205 wxWindowID id, const wxString& title,
206 const wxPoint& WXUNUSED(pos), const wxSize& size,
207 long style, const wxString& name )
208 {
209 m_menuBar = (wxMenuBar *) NULL;
210 m_page = (GtkNotebookPage *) NULL;
211 Create( parent, id, title, wxDefaultPosition, size, style, name );
212 }
213
214 wxMDIChildFrame::~wxMDIChildFrame(void)
215 {
216 if (m_menuBar)
217 {
218 wxMDIParentFrame *mdi_frame = (wxMDIParentFrame*)m_parent->m_parent;
219 if (mdi_frame->m_currentChild == this)
220 {
221 mdi_frame->SetMDIMenuBar( (wxMenuBar *) NULL );
222 mdi_frame->m_currentChild = (wxMDIChildFrame *) NULL;
223 }
224 delete m_menuBar;
225 }
226 }
227
228 bool wxMDIChildFrame::Create( wxMDIParentFrame *parent,
229 wxWindowID id, const wxString& title,
230 const wxPoint& WXUNUSED(pos), const wxSize& size,
231 long style, const wxString& name )
232 {
233 m_title = title;
234
235 return wxWindow::Create( parent->GetClientWindow(), id, wxDefaultPosition, size, style, name );
236 }
237
238 void wxMDIChildFrame::GetClientSize( int *width, int *height ) const
239 {
240 wxWindow::GetClientSize( width, height );
241 }
242
243 void wxMDIChildFrame::AddChild( wxWindow *child )
244 {
245 wxWindow::AddChild( child );
246 }
247
248 static void SetInvokingWindow( wxMenu *menu, wxWindow *win )
249 {
250 menu->SetInvokingWindow( win );
251 wxNode *node = menu->m_items.First();
252 while (node)
253 {
254 wxMenuItem *menuitem = (wxMenuItem*)node->Data();
255 if (menuitem->IsSubMenu())
256 SetInvokingWindow( menuitem->GetSubMenu(), win );
257 node = node->Next();
258 }
259 }
260
261 void wxMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar )
262 {
263 m_menuBar = menu_bar;
264
265 if (m_menuBar)
266 {
267 wxMDIParentFrame *mdi_frame = (wxMDIParentFrame*)m_parent->m_parent;
268
269 if (m_menuBar->m_parent != this)
270 {
271 wxNode *node = m_menuBar->m_menus.First();
272 while (node)
273 {
274 wxMenu *menu = (wxMenu*)node->Data();
275 SetInvokingWindow( menu, this );
276 node = node->Next();
277 }
278
279 m_menuBar->m_parent = mdi_frame;
280 }
281 mdi_frame->SetMDIMenuBar( m_menuBar );
282
283 gtk_myfixed_put( GTK_MYFIXED(mdi_frame->m_wxwindow),
284 m_menuBar->m_widget, m_menuBar->m_x, m_menuBar->m_y );
285 }
286 }
287
288 wxMenuBar *wxMDIChildFrame::GetMenuBar()
289 {
290 return m_menuBar;
291 }
292
293 void wxMDIChildFrame::Activate(void)
294 {
295 }
296
297 void wxMDIChildFrame::OnActivate( wxActivateEvent &WXUNUSED(event) )
298 {
299 }
300
301 //-----------------------------------------------------------------------------
302 // InsertChild callback for wxMDIClientWindow
303 //-----------------------------------------------------------------------------
304
305 static void wxInsertChildInMDI( wxMDIClientWindow* parent, wxMDIChildFrame* child )
306 {
307 wxString s = child->m_title;
308 if (s.IsNull()) s = _("MDI child");
309
310 GtkWidget *label_widget = gtk_label_new( s );
311 gtk_misc_set_alignment( GTK_MISC(label_widget), 0.0, 0.5 );
312
313 gtk_signal_connect( GTK_OBJECT(child->m_widget), "size_allocate",
314 GTK_SIGNAL_FUNC(gtk_page_size_callback), (gpointer)child );
315
316 GtkNotebook *notebook = GTK_NOTEBOOK(parent->m_widget);
317
318 gtk_notebook_append_page( notebook, child->m_widget, label_widget );
319
320 child->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data);
321
322 gtk_notebook_set_page( notebook, parent->m_children.Number()-1 );
323
324 gtk_page_change_callback( (GtkNotebook *) NULL, child->m_page, 0, parent );
325 }
326
327 //-----------------------------------------------------------------------------
328 // wxMDIClientWindow
329 //-----------------------------------------------------------------------------
330
331 IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow,wxWindow)
332
333 wxMDIClientWindow::wxMDIClientWindow(void)
334 {
335 }
336
337 wxMDIClientWindow::wxMDIClientWindow( wxMDIParentFrame *parent, long style )
338 {
339 CreateClient( parent, style );
340 }
341
342 wxMDIClientWindow::~wxMDIClientWindow(void)
343 {
344 }
345
346 bool wxMDIClientWindow::CreateClient( wxMDIParentFrame *parent, long style )
347 {
348 m_needParent = TRUE;
349
350 m_insertCallback = (wxInsertChildFunction)wxInsertChildInMDI;
351
352 PreCreation( parent, -1, wxPoint(10,10), wxSize(100,100), style, "wxMDIClientWindow" );
353
354 m_widget = gtk_notebook_new();
355
356 gtk_signal_connect( GTK_OBJECT(m_widget), "switch_page",
357 GTK_SIGNAL_FUNC(gtk_page_change_callback), (gpointer)this );
358
359 gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 );
360
361 m_parent->AddChild( this );
362
363 (m_parent->m_insertCallback)( m_parent, this );
364
365 PostCreation();
366
367 Show( TRUE );
368
369 return TRUE;
370 }
371
372
373