Fix for TextCtrl problem as reported by Vegh
[wxWidgets.git] / src / gtk / 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 int x = 0;
123 int y = 0;
124 GetClientSize( &x, &y );
125 m_mdiMenuBar->SetSize( 1, 1, x-2, wxMENU_HEIGHT-2, wxSIZE_NO_ADJUSTMENTS );
126 }
127 }
128
129 void wxMDIParentFrame::SetMDIMenuBar( wxMenuBar *menu_bar )
130 {
131 if (m_mdiMenuBar) m_mdiMenuBar->Show( FALSE );
132 m_mdiMenuBar = menu_bar;
133 if (m_mdiMenuBar)
134 {
135 int x = 0;
136 int y = 0;
137 GetClientSize( &x, &y );
138 m_mdiMenuBar->SetSize( 1, 1, x-2, wxMENU_HEIGHT-2, wxSIZE_NO_ADJUSTMENTS );
139 m_mdiMenuBar->Show( TRUE );
140 }
141 }
142
143 void wxMDIParentFrame::GetClientSize(int *width, int *height ) const
144 {
145 wxFrame::GetClientSize( width, height );
146 }
147
148 wxMDIChildFrame *wxMDIParentFrame::GetActiveChild(void) const
149 {
150 return m_currentChild;
151 }
152
153 wxMDIClientWindow *wxMDIParentFrame::GetClientWindow(void) const
154 {
155 return m_clientWindow;
156 }
157
158 wxMDIClientWindow *wxMDIParentFrame::OnCreateClient(void)
159 {
160 m_clientWindow = new wxMDIClientWindow( this );
161 return m_clientWindow;
162 }
163
164 void wxMDIParentFrame::ActivateNext(void)
165 {
166 if (m_clientWindow)
167 gtk_notebook_next_page( GTK_NOTEBOOK(m_clientWindow->m_widget) );
168 }
169
170 void wxMDIParentFrame::ActivatePrevious(void)
171 {
172 if (m_clientWindow)
173 gtk_notebook_prev_page( GTK_NOTEBOOK(m_clientWindow->m_widget) );
174 }
175
176 void wxMDIParentFrame::OnActivate( wxActivateEvent& WXUNUSED(event) )
177 {
178 }
179
180 void wxMDIParentFrame::OnSysColourChanged( wxSysColourChangedEvent& WXUNUSED(event) )
181 {
182 }
183
184 //-----------------------------------------------------------------------------
185 // wxMDIChildFrame
186 //-----------------------------------------------------------------------------
187
188 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame,wxFrame)
189
190 BEGIN_EVENT_TABLE(wxMDIChildFrame, wxFrame)
191 EVT_ACTIVATE(wxMDIChildFrame::OnActivate)
192 END_EVENT_TABLE()
193
194 wxMDIChildFrame::wxMDIChildFrame(void)
195 {
196 m_menuBar = (wxMenuBar *) NULL;
197 m_page = (GtkNotebookPage *) NULL;
198 }
199
200 wxMDIChildFrame::wxMDIChildFrame( wxMDIParentFrame *parent,
201 wxWindowID id, const wxString& title,
202 const wxPoint& WXUNUSED(pos), const wxSize& size,
203 long style, const wxString& name )
204 {
205 m_menuBar = (wxMenuBar *) NULL;
206 m_page = (GtkNotebookPage *) NULL;
207 Create( parent, id, title, wxDefaultPosition, size, style, name );
208 }
209
210 wxMDIChildFrame::~wxMDIChildFrame(void)
211 {
212 if (m_menuBar)
213 {
214 wxMDIParentFrame *mdi_frame = (wxMDIParentFrame*)m_parent->m_parent;
215 if (mdi_frame->m_currentChild == this)
216 {
217 mdi_frame->SetMDIMenuBar( (wxMenuBar *) NULL );
218 mdi_frame->m_currentChild = (wxMDIChildFrame *) NULL;
219 }
220 delete m_menuBar;
221 }
222 }
223
224 bool wxMDIChildFrame::Create( wxMDIParentFrame *parent,
225 wxWindowID id, const wxString& title,
226 const wxPoint& WXUNUSED(pos), const wxSize& size,
227 long style, const wxString& name )
228 {
229 m_title = title;
230
231 return wxWindow::Create( parent->GetClientWindow(), id, wxDefaultPosition, size, style, name );
232 }
233
234 void wxMDIChildFrame::GetClientSize( int *width, int *height ) const
235 {
236 wxWindow::GetClientSize( width, height );
237 }
238
239 void wxMDIChildFrame::AddChild( wxWindow *child )
240 {
241 wxWindow::AddChild( child );
242 }
243
244 static void SetInvokingWindow( wxMenu *menu, wxWindow *win )
245 {
246 menu->SetInvokingWindow( win );
247 wxNode *node = menu->m_items.First();
248 while (node)
249 {
250 wxMenuItem *menuitem = (wxMenuItem*)node->Data();
251 if (menuitem->IsSubMenu())
252 SetInvokingWindow( menuitem->GetSubMenu(), win );
253 node = node->Next();
254 }
255 }
256
257 void wxMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar )
258 {
259 m_menuBar = menu_bar;
260
261 if (m_menuBar)
262 {
263 wxMDIParentFrame *mdi_frame = (wxMDIParentFrame*)m_parent->m_parent;
264
265 if (m_menuBar->m_parent != this)
266 {
267 wxNode *node = m_menuBar->m_menus.First();
268 while (node)
269 {
270 wxMenu *menu = (wxMenu*)node->Data();
271 SetInvokingWindow( menu, this );
272 node = node->Next();
273 }
274
275 m_menuBar->m_parent = mdi_frame;
276 }
277 mdi_frame->SetMDIMenuBar( m_menuBar );
278
279 gtk_myfixed_put( GTK_MYFIXED(mdi_frame->m_wxwindow),
280 m_menuBar->m_widget, m_menuBar->m_x, m_menuBar->m_y );
281 }
282 }
283
284 wxMenuBar *wxMDIChildFrame::GetMenuBar()
285 {
286 return m_menuBar;
287 }
288
289 void wxMDIChildFrame::Activate(void)
290 {
291 }
292
293 void wxMDIChildFrame::OnActivate( wxActivateEvent &WXUNUSED(event) )
294 {
295 }
296
297 //-----------------------------------------------------------------------------
298 // InsertChild callback for wxMDIClientWindow
299 //-----------------------------------------------------------------------------
300
301 static void wxInsertChildInMDI( wxMDIClientWindow* parent, wxMDIChildFrame* child )
302 {
303 wxString s = child->m_title;
304 if (s.IsNull()) s = _("MDI child");
305
306 GtkWidget *label_widget = gtk_label_new( s );
307 gtk_misc_set_alignment( GTK_MISC(label_widget), 0.0, 0.5 );
308
309 gtk_signal_connect( GTK_OBJECT(child->m_widget), "size_allocate",
310 GTK_SIGNAL_FUNC(gtk_page_size_callback), (gpointer)child );
311
312 GtkNotebook *notebook = GTK_NOTEBOOK(parent->m_widget);
313
314 gtk_notebook_append_page( notebook, child->m_widget, label_widget );
315
316 child->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data);
317
318 gtk_notebook_set_page( notebook, parent->m_children.Number()-1 );
319
320 gtk_page_change_callback( (GtkNotebook *) NULL, child->m_page, 0, parent );
321 }
322
323 //-----------------------------------------------------------------------------
324 // wxMDIClientWindow
325 //-----------------------------------------------------------------------------
326
327 IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow,wxWindow)
328
329 wxMDIClientWindow::wxMDIClientWindow(void)
330 {
331 }
332
333 wxMDIClientWindow::wxMDIClientWindow( wxMDIParentFrame *parent, long style )
334 {
335 CreateClient( parent, style );
336 }
337
338 wxMDIClientWindow::~wxMDIClientWindow(void)
339 {
340 }
341
342 bool wxMDIClientWindow::CreateClient( wxMDIParentFrame *parent, long style )
343 {
344 m_needParent = TRUE;
345
346 m_insertCallback = (wxInsertChildFunction)wxInsertChildInMDI;
347
348 PreCreation( parent, -1, wxPoint(10,10), wxSize(100,100), style, "wxMDIClientWindow" );
349
350 m_widget = gtk_notebook_new();
351
352 gtk_signal_connect( GTK_OBJECT(m_widget), "switch_page",
353 GTK_SIGNAL_FUNC(gtk_page_change_callback), (gpointer)this );
354
355 gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 );
356
357 gtk_myfixed_put( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x, m_y );
358
359 PostCreation();
360
361 Show( TRUE );
362
363 return TRUE;
364 }
365
366
367