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