]>
git.saurik.com Git - wxWidgets.git/blob - src/gtk/mdi.cpp
1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "mdi.h"
16 #if wxUSE_MDI_ARCHITECTURE
18 #include "wx/dialog.h"
25 #include "wx/gtk/win_gtk.h"
27 //-----------------------------------------------------------------------------
29 //-----------------------------------------------------------------------------
31 const int wxMENU_HEIGHT
= 27;
33 //-----------------------------------------------------------------------------
35 //-----------------------------------------------------------------------------
37 extern void wxapp_install_idle_handler();
40 //-----------------------------------------------------------------------------
42 //-----------------------------------------------------------------------------
44 extern wxList wxPendingDelete
;
46 //-----------------------------------------------------------------------------
48 //-----------------------------------------------------------------------------
50 IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame
,wxFrame
)
52 BEGIN_EVENT_TABLE(wxMDIParentFrame
, wxFrame
)
55 wxMDIParentFrame::wxMDIParentFrame()
57 m_justInserted
= FALSE
;
58 m_clientWindow
= (wxMDIClientWindow
*) NULL
;
61 wxMDIParentFrame::wxMDIParentFrame( wxWindow
*parent
,
62 wxWindowID id
, const wxString
& title
,
63 const wxPoint
& pos
, const wxSize
& size
,
64 long style
, const wxString
& name
)
66 m_justInserted
= FALSE
;
67 m_clientWindow
= (wxMDIClientWindow
*) NULL
;
68 Create( parent
, id
, title
, pos
, size
, style
, name
);
71 wxMDIParentFrame::~wxMDIParentFrame()
75 bool wxMDIParentFrame::Create( wxWindow
*parent
,
76 wxWindowID id
, const wxString
& title
,
77 const wxPoint
& pos
, const wxSize
& size
,
78 long style
, const wxString
& name
)
80 wxFrame::Create( parent
, id
, title
, pos
, size
, style
, name
);
87 void wxMDIParentFrame::GtkOnSize( int x
, int y
, int width
, int height
)
89 wxFrame::GtkOnSize( x
, y
, width
, height
);
91 wxMDIChildFrame
*child_frame
= GetActiveChild();
92 if (!child_frame
) return;
94 wxMenuBar
*menu_bar
= child_frame
->m_menuBar
;
95 if (!menu_bar
) return;
96 if (!menu_bar
->m_widget
) return;
100 menu_bar
->m_width
= m_width
;
101 menu_bar
->m_height
= wxMENU_HEIGHT
;
102 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
104 0, 0, m_width
, wxMENU_HEIGHT
);
107 void wxMDIParentFrame::OnInternalIdle()
109 /* if a an MDI child window has just been inserted
110 it has to be brought to the top in idle time. we
111 simply set the last notebook page active as new
112 pages can only be appended at the end */
116 GtkNotebook
*notebook
= GTK_NOTEBOOK(m_clientWindow
->m_widget
);
117 gtk_notebook_set_page( notebook
, g_list_length( notebook
->children
) - 1 );
119 m_justInserted
= FALSE
;
123 wxFrame::OnInternalIdle();
125 wxMDIChildFrame
*active_child_frame
= GetActiveChild();
126 bool visible_child_menu
= FALSE
;
128 wxNode
*node
= m_clientWindow
->GetChildren().First();
131 wxMDIChildFrame
*child_frame
= (wxMDIChildFrame
*)node
->Data();
132 wxMenuBar
*menu_bar
= child_frame
->m_menuBar
;
133 if (child_frame
->m_menuBar
)
135 if (child_frame
== active_child_frame
)
137 if (menu_bar
->Show(TRUE
))
139 menu_bar
->m_width
= m_width
;
140 menu_bar
->m_height
= wxMENU_HEIGHT
;
141 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
143 0, 0, m_width
, wxMENU_HEIGHT
);
144 menu_bar
->SetInvokingWindow( child_frame
);
146 visible_child_menu
= TRUE
;
150 if (menu_bar
->Show(FALSE
))
152 menu_bar
->UnsetInvokingWindow( child_frame
);
159 /* show/hide parent menu bar as required */
160 if ((m_frameMenuBar
) &&
161 (m_frameMenuBar
->IsShown() == visible_child_menu
))
163 if (visible_child_menu
)
165 m_frameMenuBar
->Show( FALSE
);
166 m_frameMenuBar
->UnsetInvokingWindow( this );
170 m_frameMenuBar
->Show( TRUE
);
171 m_frameMenuBar
->SetInvokingWindow( this );
173 m_frameMenuBar
->m_width
= m_width
;
174 m_frameMenuBar
->m_height
= wxMENU_HEIGHT
;
175 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
176 m_frameMenuBar
->m_widget
,
177 0, 0, m_width
, wxMENU_HEIGHT
);
182 void wxMDIParentFrame::GetClientSize(int *width
, int *height
) const
184 wxFrame::GetClientSize( width
, height
);
187 wxMDIChildFrame
*wxMDIParentFrame::GetActiveChild() const
189 if (!m_clientWindow
) return (wxMDIChildFrame
*) NULL
;
191 GtkNotebook
*notebook
= GTK_NOTEBOOK(m_clientWindow
->m_widget
);
192 if (!notebook
) return (wxMDIChildFrame
*) NULL
;
194 #if (GTK_MINOR_VERSION > 0)
195 gint i
= gtk_notebook_get_current_page( notebook
);
197 gint i
= gtk_notebook_current_page( notebook
);
199 if (i
< 0) return (wxMDIChildFrame
*) NULL
;
201 GtkNotebookPage
* page
= (GtkNotebookPage
*) (g_list_nth(notebook
->children
,i
)->data
);
202 if (!page
) return (wxMDIChildFrame
*) NULL
;
204 wxNode
*node
= m_clientWindow
->GetChildren().First();
207 wxMDIChildFrame
*child_frame
= (wxMDIChildFrame
*)node
->Data();
208 if (child_frame
->m_page
== page
)
213 return (wxMDIChildFrame
*) NULL
;
216 wxMDIClientWindow
*wxMDIParentFrame::GetClientWindow() const
218 return m_clientWindow
;
221 wxMDIClientWindow
*wxMDIParentFrame::OnCreateClient()
223 m_clientWindow
= new wxMDIClientWindow( this );
224 return m_clientWindow
;
227 void wxMDIParentFrame::ActivateNext()
230 gtk_notebook_next_page( GTK_NOTEBOOK(m_clientWindow
->m_widget
) );
233 void wxMDIParentFrame::ActivatePrevious()
236 gtk_notebook_prev_page( GTK_NOTEBOOK(m_clientWindow
->m_widget
) );
239 void wxMDIParentFrame::OnActivate( wxActivateEvent
& WXUNUSED(event
) )
243 void wxMDIParentFrame::OnSysColourChanged( wxSysColourChangedEvent
& WXUNUSED(event
) )
247 //-----------------------------------------------------------------------------
249 //-----------------------------------------------------------------------------
251 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame
,wxFrame
)
253 BEGIN_EVENT_TABLE(wxMDIChildFrame
, wxFrame
)
254 EVT_ACTIVATE(wxMDIChildFrame::OnActivate
)
257 wxMDIChildFrame::wxMDIChildFrame()
259 m_menuBar
= (wxMenuBar
*) NULL
;
260 m_page
= (GtkNotebookPage
*) NULL
;
263 wxMDIChildFrame::wxMDIChildFrame( wxMDIParentFrame
*parent
,
264 wxWindowID id
, const wxString
& title
,
265 const wxPoint
& WXUNUSED(pos
), const wxSize
& size
,
266 long style
, const wxString
& name
)
268 m_menuBar
= (wxMenuBar
*) NULL
;
269 m_page
= (GtkNotebookPage
*) NULL
;
270 Create( parent
, id
, title
, wxDefaultPosition
, size
, style
, name
);
273 wxMDIChildFrame::~wxMDIChildFrame()
279 bool wxMDIChildFrame::Create( wxMDIParentFrame
*parent
,
280 wxWindowID id
, const wxString
& title
,
281 const wxPoint
& WXUNUSED(pos
), const wxSize
& size
,
282 long style
, const wxString
& name
)
286 return wxWindow::Create( parent
->GetClientWindow(), id
, wxDefaultPosition
, size
, style
, name
);
289 void wxMDIChildFrame::GetClientSize( int *width
, int *height
) const
291 wxWindow::GetClientSize( width
, height
);
294 void wxMDIChildFrame::AddChild( wxWindow
*child
)
296 wxWindow::AddChild( child
);
299 void wxMDIChildFrame::SetMenuBar( wxMenuBar
*menu_bar
)
301 wxASSERT_MSG( m_menuBar
== NULL
, _T("Only one menubar allowed") );
303 m_menuBar
= menu_bar
;
307 wxMDIParentFrame
*mdi_frame
= (wxMDIParentFrame
*)m_parent
->GetParent();
309 m_menuBar
->SetParent( mdi_frame
);
311 /* insert the invisible menu bar into the _parent_ mdi frame */
312 gtk_myfixed_put( GTK_MYFIXED(mdi_frame
->m_mainWidget
),
314 0, 0, mdi_frame
->m_width
, wxMENU_HEIGHT
);
318 wxMenuBar
*wxMDIChildFrame::GetMenuBar() const
323 void wxMDIChildFrame::Activate()
325 #if (GTK_MINOR_VERSION > 0)
326 wxMDIParentFrame
* parent
= (wxMDIParentFrame
*) GetParent();
327 GtkNotebook
* notebook
= GTK_NOTEBOOK(parent
->m_widget
);
328 gint pageno
= gtk_notebook_page_num( notebook
, m_page
->child
);
329 gtk_notebook_set_page( notebook
, pageno
);
331 // the only way I can see to do this under gtk+ 1.0.X would
332 // be to keep track of page numbers, start at first and
333 // do "next" enough times to get to this page number - messy
334 // - J. Russell Smyth
338 void wxMDIChildFrame::OnActivate( wxActivateEvent
&WXUNUSED(event
) )
342 //-----------------------------------------------------------------------------
344 //-----------------------------------------------------------------------------
346 static void gtk_page_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxWindow
*win
)
348 if (g_isIdle
) wxapp_install_idle_handler();
350 if ((win
->m_x
== alloc
->x
) &&
351 (win
->m_y
== alloc
->y
) &&
352 (win
->m_width
== alloc
->width
) &&
353 (win
->m_height
== alloc
->height
) &&
359 win
->SetSize( alloc
->x
, alloc
->y
, alloc
->width
, alloc
->height
);
362 //-----------------------------------------------------------------------------
363 // InsertChild callback for wxMDIClientWindow
364 //-----------------------------------------------------------------------------
366 static void wxInsertChildInMDI( wxMDIClientWindow
* parent
, wxMDIChildFrame
* child
)
368 wxString s
= child
->m_title
;
369 if (s
.IsNull()) s
= _("MDI child");
371 GtkWidget
*label_widget
= gtk_label_new( s
.mbc_str() );
372 gtk_misc_set_alignment( GTK_MISC(label_widget
), 0.0, 0.5 );
374 gtk_signal_connect( GTK_OBJECT(child
->m_widget
), "size_allocate",
375 GTK_SIGNAL_FUNC(gtk_page_size_callback
), (gpointer
)child
);
377 GtkNotebook
*notebook
= GTK_NOTEBOOK(parent
->m_widget
);
379 gtk_notebook_append_page( notebook
, child
->m_widget
, label_widget
);
381 child
->m_page
= (GtkNotebookPage
*) (g_list_last(notebook
->children
)->data
);
383 wxMDIParentFrame
*parent_frame
= (wxMDIParentFrame
*) parent
->GetParent();
384 parent_frame
->m_justInserted
= TRUE
;
387 //-----------------------------------------------------------------------------
389 //-----------------------------------------------------------------------------
391 IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow
,wxWindow
)
393 wxMDIClientWindow::wxMDIClientWindow()
397 wxMDIClientWindow::wxMDIClientWindow( wxMDIParentFrame
*parent
, long style
)
399 CreateClient( parent
, style
);
402 wxMDIClientWindow::~wxMDIClientWindow()
406 bool wxMDIClientWindow::CreateClient( wxMDIParentFrame
*parent
, long style
)
410 m_insertCallback
= (wxInsertChildFunction
)wxInsertChildInMDI
;
412 if (!PreCreation( parent
, wxDefaultPosition
, wxDefaultSize
) ||
413 !CreateBase( parent
, -1, wxDefaultPosition
, wxDefaultSize
, style
, wxDefaultValidator
, _T("wxMDIClientWindow") ))
415 wxFAIL_MSG( _T("wxMDIClientWindow creation failed") );
419 m_widget
= gtk_notebook_new();
421 gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget
), 1 );
423 m_parent
->DoAddChild( this );