]>
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"
15 #include "wx/dialog.h"
22 #include "wx/gtk/win_gtk.h"
24 //-----------------------------------------------------------------------------
26 //-----------------------------------------------------------------------------
28 const int wxMENU_HEIGHT
= 27;
30 //-----------------------------------------------------------------------------
32 //-----------------------------------------------------------------------------
34 extern void wxapp_install_idle_handler();
37 //-----------------------------------------------------------------------------
39 //-----------------------------------------------------------------------------
41 extern wxList wxPendingDelete
;
43 //-----------------------------------------------------------------------------
45 //-----------------------------------------------------------------------------
47 IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame
,wxFrame
)
49 BEGIN_EVENT_TABLE(wxMDIParentFrame
, wxFrame
)
52 wxMDIParentFrame::wxMDIParentFrame()
54 m_justInserted
= FALSE
;
55 m_clientWindow
= (wxMDIClientWindow
*) NULL
;
58 wxMDIParentFrame::wxMDIParentFrame( wxWindow
*parent
,
59 wxWindowID id
, const wxString
& title
,
60 const wxPoint
& pos
, const wxSize
& size
,
61 long style
, const wxString
& name
)
63 m_justInserted
= FALSE
;
64 m_clientWindow
= (wxMDIClientWindow
*) NULL
;
65 Create( parent
, id
, title
, pos
, size
, style
, name
);
68 wxMDIParentFrame::~wxMDIParentFrame()
72 bool wxMDIParentFrame::Create( wxWindow
*parent
,
73 wxWindowID id
, const wxString
& title
,
74 const wxPoint
& pos
, const wxSize
& size
,
75 long style
, const wxString
& name
)
77 wxFrame::Create( parent
, id
, title
, pos
, size
, style
, name
);
84 void wxMDIParentFrame::GtkOnSize( int x
, int y
, int width
, int height
)
86 wxFrame::GtkOnSize( x
, y
, width
, height
);
88 wxMDIChildFrame
*child_frame
= GetActiveChild();
89 if (!child_frame
) return;
91 wxMenuBar
*menu_bar
= child_frame
->m_menuBar
;
92 if (!menu_bar
) return;
93 if (!menu_bar
->m_widget
) return;
97 menu_bar
->m_width
= m_width
;
98 menu_bar
->m_height
= wxMENU_HEIGHT
;
99 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
101 0, 0, m_width
, wxMENU_HEIGHT
);
104 void wxMDIParentFrame::OnInternalIdle()
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 */
113 GtkNotebook
*notebook
= GTK_NOTEBOOK(m_clientWindow
->m_widget
);
114 gtk_notebook_set_page( notebook
, g_list_length( notebook
->children
) - 1 );
116 m_justInserted
= FALSE
;
120 wxFrame::OnInternalIdle();
122 wxMDIChildFrame
*active_child_frame
= GetActiveChild();
123 bool visible_child_menu
= FALSE
;
125 wxNode
*node
= m_clientWindow
->m_children
.First();
128 wxMDIChildFrame
*child_frame
= (wxMDIChildFrame
*)node
->Data();
129 if (child_frame
->m_menuBar
)
131 if (child_frame
== active_child_frame
)
133 gtk_widget_show( child_frame
->m_menuBar
->m_widget
);
134 visible_child_menu
= TRUE
;
137 gtk_widget_hide( child_frame
->m_menuBar
->m_widget
);
142 /* show/hide parent menu bar as required */
143 if (m_frameMenuBar
) m_frameMenuBar
->Show( !visible_child_menu
);
146 void wxMDIParentFrame::GetClientSize(int *width
, int *height
) const
148 wxFrame::GetClientSize( width
, height
);
151 wxMDIChildFrame
*wxMDIParentFrame::GetActiveChild() const
153 if (!m_clientWindow
) return (wxMDIChildFrame
*) NULL
;
155 GtkNotebook
*notebook
= GTK_NOTEBOOK(m_clientWindow
->m_widget
);
156 if (!notebook
) return (wxMDIChildFrame
*) NULL
;
158 #if (GTK_MINOR_VERSION > 0)
159 gint i
= gtk_notebook_get_current_page( notebook
);
161 gint i
= gtk_notebook_current_page( notebook
);
163 if (i
< 0) return (wxMDIChildFrame
*) NULL
;
165 GtkNotebookPage
* page
= (GtkNotebookPage
*) (g_list_nth(notebook
->children
,i
)->data
);
166 if (!page
) return (wxMDIChildFrame
*) NULL
;
168 wxNode
*node
= m_clientWindow
->m_children
.First();
171 wxMDIChildFrame
*child_frame
= (wxMDIChildFrame
*)node
->Data();
172 if (child_frame
->m_page
== page
)
177 return (wxMDIChildFrame
*) NULL
;
180 wxMDIClientWindow
*wxMDIParentFrame::GetClientWindow() const
182 return m_clientWindow
;
185 wxMDIClientWindow
*wxMDIParentFrame::OnCreateClient()
187 m_clientWindow
= new wxMDIClientWindow( this );
188 return m_clientWindow
;
191 void wxMDIParentFrame::ActivateNext()
194 gtk_notebook_next_page( GTK_NOTEBOOK(m_clientWindow
->m_widget
) );
197 void wxMDIParentFrame::ActivatePrevious()
200 gtk_notebook_prev_page( GTK_NOTEBOOK(m_clientWindow
->m_widget
) );
203 void wxMDIParentFrame::OnActivate( wxActivateEvent
& WXUNUSED(event
) )
207 void wxMDIParentFrame::OnSysColourChanged( wxSysColourChangedEvent
& WXUNUSED(event
) )
211 //-----------------------------------------------------------------------------
213 //-----------------------------------------------------------------------------
215 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame
,wxFrame
)
217 BEGIN_EVENT_TABLE(wxMDIChildFrame
, wxFrame
)
218 EVT_ACTIVATE(wxMDIChildFrame::OnActivate
)
221 wxMDIChildFrame::wxMDIChildFrame()
223 m_menuBar
= (wxMenuBar
*) NULL
;
224 m_page
= (GtkNotebookPage
*) NULL
;
227 wxMDIChildFrame::wxMDIChildFrame( wxMDIParentFrame
*parent
,
228 wxWindowID id
, const wxString
& title
,
229 const wxPoint
& WXUNUSED(pos
), const wxSize
& size
,
230 long style
, const wxString
& name
)
232 m_menuBar
= (wxMenuBar
*) NULL
;
233 m_page
= (GtkNotebookPage
*) NULL
;
234 Create( parent
, id
, title
, wxDefaultPosition
, size
, style
, name
);
237 wxMDIChildFrame::~wxMDIChildFrame()
243 bool wxMDIChildFrame::Create( wxMDIParentFrame
*parent
,
244 wxWindowID id
, const wxString
& title
,
245 const wxPoint
& WXUNUSED(pos
), const wxSize
& size
,
246 long style
, const wxString
& name
)
250 return wxWindow::Create( parent
->GetClientWindow(), id
, wxDefaultPosition
, size
, style
, name
);
253 void wxMDIChildFrame::GetClientSize( int *width
, int *height
) const
255 wxWindow::GetClientSize( width
, height
);
258 void wxMDIChildFrame::AddChild( wxWindow
*child
)
260 wxWindow::AddChild( child
);
263 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
265 menu
->SetInvokingWindow( win
);
266 wxNode
*node
= menu
->GetItems().First();
269 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
270 if (menuitem
->IsSubMenu())
271 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
276 void wxMDIChildFrame::SetMenuBar( wxMenuBar
*menu_bar
)
278 m_menuBar
= menu_bar
;
282 wxMDIParentFrame
*mdi_frame
= (wxMDIParentFrame
*)m_parent
->m_parent
;
284 if (m_menuBar
->m_parent
!= this)
286 wxNode
*node
= m_menuBar
->GetMenus().First();
289 wxMenu
*menu
= (wxMenu
*)node
->Data();
290 SetInvokingWindow( menu
, this );
294 m_menuBar
->m_parent
= mdi_frame
;
297 /* the menu bar of the child window is shown in idle time as needed */
298 gtk_widget_hide( m_menuBar
->m_widget
);
300 /* insert the invisible menu bar into the _parent_ mdi frame */
301 gtk_myfixed_put( GTK_MYFIXED(mdi_frame
->m_mainWidget
),
303 0, 0, mdi_frame
->m_width
, wxMENU_HEIGHT
);
307 wxMenuBar
*wxMDIChildFrame::GetMenuBar() const
312 void wxMDIChildFrame::Activate()
316 void wxMDIChildFrame::OnActivate( wxActivateEvent
&WXUNUSED(event
) )
320 //-----------------------------------------------------------------------------
322 //-----------------------------------------------------------------------------
324 static void gtk_page_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxWindow
*win
)
326 if (g_isIdle
) wxapp_install_idle_handler();
328 if ((win
->m_x
== alloc
->x
) &&
329 (win
->m_y
== alloc
->y
) &&
330 (win
->m_width
== alloc
->width
) &&
331 (win
->m_height
== alloc
->height
) &&
337 win
->SetSize( alloc
->x
, alloc
->y
, alloc
->width
, alloc
->height
);
340 //-----------------------------------------------------------------------------
341 // InsertChild callback for wxMDIClientWindow
342 //-----------------------------------------------------------------------------
344 static void wxInsertChildInMDI( wxMDIClientWindow
* parent
, wxMDIChildFrame
* child
)
346 wxString s
= child
->m_title
;
347 if (s
.IsNull()) s
= _("MDI child");
349 GtkWidget
*label_widget
= gtk_label_new( s
.mbc_str() );
350 gtk_misc_set_alignment( GTK_MISC(label_widget
), 0.0, 0.5 );
352 gtk_signal_connect( GTK_OBJECT(child
->m_widget
), "size_allocate",
353 GTK_SIGNAL_FUNC(gtk_page_size_callback
), (gpointer
)child
);
355 GtkNotebook
*notebook
= GTK_NOTEBOOK(parent
->m_widget
);
357 gtk_notebook_append_page( notebook
, child
->m_widget
, label_widget
);
359 child
->m_page
= (GtkNotebookPage
*) (g_list_last(notebook
->children
)->data
);
361 wxMDIParentFrame
*parent_frame
= (wxMDIParentFrame
*) parent
->m_parent
;
362 parent_frame
->m_justInserted
= TRUE
;
365 //-----------------------------------------------------------------------------
367 //-----------------------------------------------------------------------------
369 IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow
,wxWindow
)
371 wxMDIClientWindow::wxMDIClientWindow()
375 wxMDIClientWindow::wxMDIClientWindow( wxMDIParentFrame
*parent
, long style
)
377 CreateClient( parent
, style
);
380 wxMDIClientWindow::~wxMDIClientWindow()
384 bool wxMDIClientWindow::CreateClient( wxMDIParentFrame
*parent
, long style
)
388 m_insertCallback
= (wxInsertChildFunction
)wxInsertChildInMDI
;
390 PreCreation( parent
, -1, wxPoint(10,10), wxSize(100,100), style
, "wxMDIClientWindow" );
392 m_widget
= gtk_notebook_new();
394 gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget
), 1 );
396 m_parent
->AddChild( this );
398 (m_parent
->m_insertCallback
)( m_parent
, this );