]>
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_move( GTK_MYFIXED(m_mainWidget
), menu_bar
->m_widget
, 0, 0 );
100 gtk_widget_set_usize( menu_bar
->m_widget
, m_width
, wxMENU_HEIGHT
);
103 void wxMDIParentFrame::OnInternalIdle()
105 /* if a an MDI child window has just been inserted
106 it has to be brought to the top in idle time. we
107 simply set the last notebook page active as new
108 pages can only be appended at the end */
112 GtkNotebook
*notebook
= GTK_NOTEBOOK(m_clientWindow
->m_widget
);
113 gtk_notebook_set_page( notebook
, g_list_length( notebook
->children
) - 1 );
115 m_justInserted
= FALSE
;
119 wxFrame::OnInternalIdle();
121 wxMDIChildFrame
*active_child_frame
= GetActiveChild();
122 bool visible_child_menu
= FALSE
;
124 wxNode
*node
= m_clientWindow
->m_children
.First();
127 wxMDIChildFrame
*child_frame
= (wxMDIChildFrame
*)node
->Data();
128 if (child_frame
->m_menuBar
)
130 if (child_frame
== active_child_frame
)
132 gtk_widget_show( child_frame
->m_menuBar
->m_widget
);
133 visible_child_menu
= TRUE
;
136 gtk_widget_hide( child_frame
->m_menuBar
->m_widget
);
141 /* show/hide parent menu bar as required */
142 if (m_frameMenuBar
) m_frameMenuBar
->Show( !visible_child_menu
);
145 void wxMDIParentFrame::GetClientSize(int *width
, int *height
) const
147 wxFrame::GetClientSize( width
, height
);
150 wxMDIChildFrame
*wxMDIParentFrame::GetActiveChild() const
152 if (!m_clientWindow
) return (wxMDIChildFrame
*) NULL
;
154 GtkNotebook
*notebook
= GTK_NOTEBOOK(m_clientWindow
->m_widget
);
155 if (!notebook
) return (wxMDIChildFrame
*) NULL
;
157 #if (GTK_MINOR_VERSION > 0)
158 gint i
= gtk_notebook_get_current_page( notebook
);
160 gint i
= gtk_notebook_current_page( notebook
);
162 if (i
< 0) return (wxMDIChildFrame
*) NULL
;
164 GtkNotebookPage
* page
= (GtkNotebookPage
*) (g_list_nth(notebook
->children
,i
)->data
);
165 if (!page
) return (wxMDIChildFrame
*) NULL
;
167 wxNode
*node
= m_clientWindow
->m_children
.First();
170 wxMDIChildFrame
*child_frame
= (wxMDIChildFrame
*)node
->Data();
171 if (child_frame
->m_page
== page
)
176 return (wxMDIChildFrame
*) NULL
;
179 wxMDIClientWindow
*wxMDIParentFrame::GetClientWindow() const
181 return m_clientWindow
;
184 wxMDIClientWindow
*wxMDIParentFrame::OnCreateClient()
186 m_clientWindow
= new wxMDIClientWindow( this );
187 return m_clientWindow
;
190 void wxMDIParentFrame::ActivateNext()
193 gtk_notebook_next_page( GTK_NOTEBOOK(m_clientWindow
->m_widget
) );
196 void wxMDIParentFrame::ActivatePrevious()
199 gtk_notebook_prev_page( GTK_NOTEBOOK(m_clientWindow
->m_widget
) );
202 void wxMDIParentFrame::OnActivate( wxActivateEvent
& WXUNUSED(event
) )
206 void wxMDIParentFrame::OnSysColourChanged( wxSysColourChangedEvent
& WXUNUSED(event
) )
210 //-----------------------------------------------------------------------------
212 //-----------------------------------------------------------------------------
214 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame
,wxFrame
)
216 BEGIN_EVENT_TABLE(wxMDIChildFrame
, wxFrame
)
217 EVT_ACTIVATE(wxMDIChildFrame::OnActivate
)
220 wxMDIChildFrame::wxMDIChildFrame()
222 m_menuBar
= (wxMenuBar
*) NULL
;
223 m_page
= (GtkNotebookPage
*) NULL
;
226 wxMDIChildFrame::wxMDIChildFrame( wxMDIParentFrame
*parent
,
227 wxWindowID id
, const wxString
& title
,
228 const wxPoint
& WXUNUSED(pos
), const wxSize
& size
,
229 long style
, const wxString
& name
)
231 m_menuBar
= (wxMenuBar
*) NULL
;
232 m_page
= (GtkNotebookPage
*) NULL
;
233 Create( parent
, id
, title
, wxDefaultPosition
, size
, style
, name
);
236 wxMDIChildFrame::~wxMDIChildFrame()
242 bool wxMDIChildFrame::Create( wxMDIParentFrame
*parent
,
243 wxWindowID id
, const wxString
& title
,
244 const wxPoint
& WXUNUSED(pos
), const wxSize
& size
,
245 long style
, const wxString
& name
)
249 return wxWindow::Create( parent
->GetClientWindow(), id
, wxDefaultPosition
, size
, style
, name
);
252 void wxMDIChildFrame::GetClientSize( int *width
, int *height
) const
254 wxWindow::GetClientSize( width
, height
);
257 void wxMDIChildFrame::AddChild( wxWindow
*child
)
259 wxWindow::AddChild( child
);
262 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
264 menu
->SetInvokingWindow( win
);
265 wxNode
*node
= menu
->GetItems().First();
268 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
269 if (menuitem
->IsSubMenu())
270 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
275 void wxMDIChildFrame::SetMenuBar( wxMenuBar
*menu_bar
)
277 m_menuBar
= menu_bar
;
281 wxMDIParentFrame
*mdi_frame
= (wxMDIParentFrame
*)m_parent
->m_parent
;
283 if (m_menuBar
->m_parent
!= this)
285 wxNode
*node
= m_menuBar
->GetMenus().First();
288 wxMenu
*menu
= (wxMenu
*)node
->Data();
289 SetInvokingWindow( menu
, this );
293 m_menuBar
->m_parent
= mdi_frame
;
296 /* the menu bar of the child window is shown in idle time as needed */
297 gtk_widget_hide( m_menuBar
->m_widget
);
299 /* insert the invisible menu bar into the _parent_ mdi frame */
300 gtk_myfixed_put( GTK_MYFIXED(mdi_frame
->m_mainWidget
), m_menuBar
->m_widget
, 0, 0 );
301 gtk_widget_set_usize( menu_bar
->m_widget
, mdi_frame
->m_width
, wxMENU_HEIGHT
);
305 wxMenuBar
*wxMDIChildFrame::GetMenuBar() const
310 void wxMDIChildFrame::Activate()
314 void wxMDIChildFrame::OnActivate( wxActivateEvent
&WXUNUSED(event
) )
318 //-----------------------------------------------------------------------------
320 //-----------------------------------------------------------------------------
322 static void gtk_page_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxWindow
*win
)
324 if (g_isIdle
) wxapp_install_idle_handler();
326 if ((win
->m_x
== alloc
->x
) &&
327 (win
->m_y
== alloc
->y
) &&
328 (win
->m_width
== alloc
->width
) &&
329 (win
->m_height
== alloc
->height
) &&
335 win
->SetSize( alloc
->x
, alloc
->y
, alloc
->width
, alloc
->height
);
338 //-----------------------------------------------------------------------------
339 // InsertChild callback for wxMDIClientWindow
340 //-----------------------------------------------------------------------------
342 static void wxInsertChildInMDI( wxMDIClientWindow
* parent
, wxMDIChildFrame
* child
)
344 wxString s
= child
->m_title
;
345 if (s
.IsNull()) s
= _("MDI child");
347 GtkWidget
*label_widget
= gtk_label_new( s
.mbc_str() );
348 gtk_misc_set_alignment( GTK_MISC(label_widget
), 0.0, 0.5 );
350 gtk_signal_connect( GTK_OBJECT(child
->m_widget
), "size_allocate",
351 GTK_SIGNAL_FUNC(gtk_page_size_callback
), (gpointer
)child
);
353 GtkNotebook
*notebook
= GTK_NOTEBOOK(parent
->m_widget
);
355 gtk_notebook_append_page( notebook
, child
->m_widget
, label_widget
);
357 child
->m_page
= (GtkNotebookPage
*) (g_list_last(notebook
->children
)->data
);
359 wxMDIParentFrame
*parent_frame
= (wxMDIParentFrame
*) parent
->m_parent
;
360 parent_frame
->m_justInserted
= TRUE
;
363 //-----------------------------------------------------------------------------
365 //-----------------------------------------------------------------------------
367 IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow
,wxWindow
)
369 wxMDIClientWindow::wxMDIClientWindow()
373 wxMDIClientWindow::wxMDIClientWindow( wxMDIParentFrame
*parent
, long style
)
375 CreateClient( parent
, style
);
378 wxMDIClientWindow::~wxMDIClientWindow()
382 bool wxMDIClientWindow::CreateClient( wxMDIParentFrame
*parent
, long style
)
386 m_insertCallback
= (wxInsertChildFunction
)wxInsertChildInMDI
;
388 PreCreation( parent
, -1, wxPoint(10,10), wxSize(100,100), style
, "wxMDIClientWindow" );
390 m_widget
= gtk_notebook_new();
392 gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget
), 1 );
394 m_parent
->AddChild( this );
396 (m_parent
->m_insertCallback
)( m_parent
, this );