]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/mdi.cpp
IRIX compile fixes
[wxWidgets.git] / src / gtk / mdi.cpp
... / ...
CommitLineData
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/intl.h>
18
19#include "glib.h"
20#include "gdk/gdk.h"
21#include "gtk/gtk.h"
22#include "wx/gtk/win_gtk.h"
23
24//-----------------------------------------------------------------------------
25// constants
26//-----------------------------------------------------------------------------
27
28const int wxMENU_HEIGHT = 27;
29
30//-----------------------------------------------------------------------------
31// idle system
32//-----------------------------------------------------------------------------
33
34extern void wxapp_install_idle_handler();
35extern bool g_isIdle;
36
37//-----------------------------------------------------------------------------
38// globals
39//-----------------------------------------------------------------------------
40
41extern wxList wxPendingDelete;
42
43//-----------------------------------------------------------------------------
44// wxMDIParentFrame
45//-----------------------------------------------------------------------------
46
47IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame,wxFrame)
48
49BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame)
50END_EVENT_TABLE()
51
52wxMDIParentFrame::wxMDIParentFrame()
53{
54 m_justInserted = FALSE;
55 m_clientWindow = (wxMDIClientWindow *) NULL;
56}
57
58wxMDIParentFrame::wxMDIParentFrame( wxWindow *parent,
59 wxWindowID id, const wxString& title,
60 const wxPoint& pos, const wxSize& size,
61 long style, const wxString& name )
62{
63 m_justInserted = FALSE;
64 m_clientWindow = (wxMDIClientWindow *) NULL;
65 Create( parent, id, title, pos, size, style, name );
66}
67
68wxMDIParentFrame::~wxMDIParentFrame()
69{
70}
71
72bool wxMDIParentFrame::Create( wxWindow *parent,
73 wxWindowID id, const wxString& title,
74 const wxPoint& pos, const wxSize& size,
75 long style, const wxString& name )
76{
77 wxFrame::Create( parent, id, title, pos, size, style, name );
78
79 OnCreateClient();
80
81 return TRUE;
82}
83
84void wxMDIParentFrame::GtkOnSize( int x, int y, int width, int height )
85{
86 wxFrame::GtkOnSize( x, y, width, height );
87
88 wxMDIChildFrame *child_frame = GetActiveChild();
89 if (!child_frame) return;
90
91 wxMenuBar *menu_bar = child_frame->m_menuBar;
92 if (!menu_bar) return;
93 if (!menu_bar->m_widget) return;
94
95 menu_bar->m_x = 0;
96 menu_bar->m_y = 0;
97 menu_bar->m_width = m_width;
98 menu_bar->m_height = wxMENU_HEIGHT;
99 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget),
100 menu_bar->m_widget,
101 0, 0, m_width, wxMENU_HEIGHT );
102}
103
104void wxMDIParentFrame::OnInternalIdle()
105{
106 /* if a an MDI child window has just been inserted
107 it has to be brought to the top in idle time. we
108 simply set the last notebook page active as new
109 pages can only be appended at the end */
110
111 if (m_justInserted)
112 {
113 GtkNotebook *notebook = GTK_NOTEBOOK(m_clientWindow->m_widget);
114 gtk_notebook_set_page( notebook, g_list_length( notebook->children ) - 1 );
115
116 m_justInserted = FALSE;
117 return;
118 }
119
120 wxFrame::OnInternalIdle();
121
122 wxMDIChildFrame *active_child_frame = GetActiveChild();
123 bool visible_child_menu = FALSE;
124
125 wxNode *node = m_clientWindow->GetChildren().First();
126 while (node)
127 {
128 wxMDIChildFrame *child_frame = (wxMDIChildFrame *)node->Data();
129 wxMenuBar *menu_bar = child_frame->m_menuBar;
130 if (child_frame->m_menuBar)
131 {
132 if (child_frame == active_child_frame)
133 {
134 if (menu_bar->Show(TRUE))
135 {
136 menu_bar->m_width = m_width;
137 menu_bar->m_height = wxMENU_HEIGHT;
138 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget),
139 menu_bar->m_widget,
140 0, 0, m_width, wxMENU_HEIGHT );
141 menu_bar->SetInvokingWindow( child_frame );
142 }
143 visible_child_menu = TRUE;
144 }
145 else
146 {
147 if (menu_bar->Show(FALSE))
148 {
149 menu_bar->UnsetInvokingWindow( child_frame );
150 }
151 }
152 }
153 node = node->Next();
154 }
155
156 /* show/hide parent menu bar as required */
157 if ((m_frameMenuBar) &&
158 (m_frameMenuBar->IsShown() == visible_child_menu))
159 {
160 if (visible_child_menu)
161 {
162 m_frameMenuBar->Show( FALSE );
163 m_frameMenuBar->UnsetInvokingWindow( this );
164 }
165 else
166 {
167 m_frameMenuBar->Show( TRUE );
168 m_frameMenuBar->SetInvokingWindow( this );
169
170 m_frameMenuBar->m_width = m_width;
171 m_frameMenuBar->m_height = wxMENU_HEIGHT;
172 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget),
173 m_frameMenuBar->m_widget,
174 0, 0, m_width, wxMENU_HEIGHT );
175 }
176 }
177}
178
179void wxMDIParentFrame::GetClientSize(int *width, int *height ) const
180{
181 wxFrame::GetClientSize( width, height );
182}
183
184wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const
185{
186 if (!m_clientWindow) return (wxMDIChildFrame*) NULL;
187
188 GtkNotebook *notebook = GTK_NOTEBOOK(m_clientWindow->m_widget);
189 if (!notebook) return (wxMDIChildFrame*) NULL;
190
191#if (GTK_MINOR_VERSION > 0)
192 gint i = gtk_notebook_get_current_page( notebook );
193#else
194 gint i = gtk_notebook_current_page( notebook );
195#endif
196 if (i < 0) return (wxMDIChildFrame*) NULL;
197
198 GtkNotebookPage* page = (GtkNotebookPage*) (g_list_nth(notebook->children,i)->data);
199 if (!page) return (wxMDIChildFrame*) NULL;
200
201 wxNode *node = m_clientWindow->GetChildren().First();
202 while (node)
203 {
204 wxMDIChildFrame *child_frame = (wxMDIChildFrame *)node->Data();
205 if (child_frame->m_page == page)
206 return child_frame;
207 node = node->Next();
208 }
209
210 return (wxMDIChildFrame*) NULL;
211}
212
213wxMDIClientWindow *wxMDIParentFrame::GetClientWindow() const
214{
215 return m_clientWindow;
216}
217
218wxMDIClientWindow *wxMDIParentFrame::OnCreateClient()
219{
220 m_clientWindow = new wxMDIClientWindow( this );
221 return m_clientWindow;
222}
223
224void wxMDIParentFrame::ActivateNext()
225{
226 if (m_clientWindow)
227 gtk_notebook_next_page( GTK_NOTEBOOK(m_clientWindow->m_widget) );
228}
229
230void wxMDIParentFrame::ActivatePrevious()
231{
232 if (m_clientWindow)
233 gtk_notebook_prev_page( GTK_NOTEBOOK(m_clientWindow->m_widget) );
234}
235
236void wxMDIParentFrame::OnActivate( wxActivateEvent& WXUNUSED(event) )
237{
238}
239
240void wxMDIParentFrame::OnSysColourChanged( wxSysColourChangedEvent& WXUNUSED(event) )
241{
242}
243
244//-----------------------------------------------------------------------------
245// wxMDIChildFrame
246//-----------------------------------------------------------------------------
247
248IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame,wxFrame)
249
250BEGIN_EVENT_TABLE(wxMDIChildFrame, wxFrame)
251 EVT_ACTIVATE(wxMDIChildFrame::OnActivate)
252END_EVENT_TABLE()
253
254wxMDIChildFrame::wxMDIChildFrame()
255{
256 m_menuBar = (wxMenuBar *) NULL;
257 m_page = (GtkNotebookPage *) NULL;
258}
259
260wxMDIChildFrame::wxMDIChildFrame( wxMDIParentFrame *parent,
261 wxWindowID id, const wxString& title,
262 const wxPoint& WXUNUSED(pos), const wxSize& size,
263 long style, const wxString& name )
264{
265 m_menuBar = (wxMenuBar *) NULL;
266 m_page = (GtkNotebookPage *) NULL;
267 Create( parent, id, title, wxDefaultPosition, size, style, name );
268}
269
270wxMDIChildFrame::~wxMDIChildFrame()
271{
272 if (m_menuBar)
273 delete m_menuBar;
274}
275
276bool wxMDIChildFrame::Create( wxMDIParentFrame *parent,
277 wxWindowID id, const wxString& title,
278 const wxPoint& WXUNUSED(pos), const wxSize& size,
279 long style, const wxString& name )
280{
281 m_title = title;
282
283 return wxWindow::Create( parent->GetClientWindow(), id, wxDefaultPosition, size, style, name );
284}
285
286void wxMDIChildFrame::GetClientSize( int *width, int *height ) const
287{
288 wxWindow::GetClientSize( width, height );
289}
290
291void wxMDIChildFrame::AddChild( wxWindow *child )
292{
293 wxWindow::AddChild( child );
294}
295
296void wxMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar )
297{
298 wxASSERT_MSG( m_menuBar == NULL, _T("Only one menubar allowed") );
299
300 m_menuBar = menu_bar;
301
302 if (m_menuBar)
303 {
304 wxMDIParentFrame *mdi_frame = (wxMDIParentFrame*)m_parent->GetParent();
305
306 m_menuBar->SetParent( mdi_frame );
307
308 /* insert the invisible menu bar into the _parent_ mdi frame */
309 gtk_myfixed_put( GTK_MYFIXED(mdi_frame->m_mainWidget),
310 m_menuBar->m_widget,
311 0, 0, mdi_frame->m_width, wxMENU_HEIGHT );
312 }
313}
314
315wxMenuBar *wxMDIChildFrame::GetMenuBar() const
316{
317 return m_menuBar;
318}
319
320void wxMDIChildFrame::Activate()
321{
322#if (GTK_MINOR_VERSION > 0)
323 wxMDIParentFrame* parent = (wxMDIParentFrame*) GetParent();
324 GtkNotebook* notebook = GTK_NOTEBOOK(parent->m_widget);
325 gint pageno = gtk_notebook_page_num( notebook, m_page->child );
326 gtk_notebook_set_page( notebook, pageno );
327#else
328 // the only way I can see to do this under gtk+ 1.0.X would
329 // be to keep track of page numbers, start at first and
330 // do "next" enough times to get to this page number - messy
331 // - J. Russell Smyth
332#endif
333}
334
335void wxMDIChildFrame::OnActivate( wxActivateEvent &WXUNUSED(event) )
336{
337}
338
339//-----------------------------------------------------------------------------
340// "size_allocate"
341//-----------------------------------------------------------------------------
342
343static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win )
344{
345 if (g_isIdle) wxapp_install_idle_handler();
346
347 if ((win->m_x == alloc->x) &&
348 (win->m_y == alloc->y) &&
349 (win->m_width == alloc->width) &&
350 (win->m_height == alloc->height) &&
351 (win->m_sizeSet))
352 {
353 return;
354 }
355
356 win->SetSize( alloc->x, alloc->y, alloc->width, alloc->height );
357}
358
359//-----------------------------------------------------------------------------
360// InsertChild callback for wxMDIClientWindow
361//-----------------------------------------------------------------------------
362
363static void wxInsertChildInMDI( wxMDIClientWindow* parent, wxMDIChildFrame* child )
364{
365 wxString s = child->m_title;
366 if (s.IsNull()) s = _("MDI child");
367
368 GtkWidget *label_widget = gtk_label_new( s.mbc_str() );
369 gtk_misc_set_alignment( GTK_MISC(label_widget), 0.0, 0.5 );
370
371 gtk_signal_connect( GTK_OBJECT(child->m_widget), "size_allocate",
372 GTK_SIGNAL_FUNC(gtk_page_size_callback), (gpointer)child );
373
374 GtkNotebook *notebook = GTK_NOTEBOOK(parent->m_widget);
375
376 gtk_notebook_append_page( notebook, child->m_widget, label_widget );
377
378 child->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data);
379
380 wxMDIParentFrame *parent_frame = (wxMDIParentFrame*) parent->GetParent();
381 parent_frame->m_justInserted = TRUE;
382}
383
384//-----------------------------------------------------------------------------
385// wxMDIClientWindow
386//-----------------------------------------------------------------------------
387
388IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow,wxWindow)
389
390wxMDIClientWindow::wxMDIClientWindow()
391{
392}
393
394wxMDIClientWindow::wxMDIClientWindow( wxMDIParentFrame *parent, long style )
395{
396 CreateClient( parent, style );
397}
398
399wxMDIClientWindow::~wxMDIClientWindow()
400{
401}
402
403bool wxMDIClientWindow::CreateClient( wxMDIParentFrame *parent, long style )
404{
405 m_needParent = TRUE;
406
407 m_insertCallback = (wxInsertChildFunction)wxInsertChildInMDI;
408
409 PreCreation( parent, -1, wxPoint(10,10), wxSize(100,100), style, "wxMDIClientWindow" );
410
411 m_widget = gtk_notebook_new();
412
413 gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 );
414
415 m_parent->DoAddChild( this );
416
417 PostCreation();
418
419 Show( TRUE );
420
421 return TRUE;
422}
423