]>
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
->GetChildren().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
->GetChildren().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
->GetParent();
284 if (m_menuBar
->GetParent() != this)
286 wxNode
*node
= m_menuBar
->GetMenus().First();
289 wxMenu
*menu
= (wxMenu
*)node
->Data();
290 SetInvokingWindow( menu
, this );
294 m_menuBar
->SetParent( 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()
314 #if (GTK_MINOR_VERSION > 0)
315 wxMDIParentFrame
* parent
= (wxMDIParentFrame
*) GetParent();
316 GtkNotebook
* notebook
= GTK_NOTEBOOK(parent
->m_widget
);
317 gint pageno
= gtk_notebook_page_num( notebook
, m_page
->child
);
318 gtk_notebook_set_page( notebook
, pageno
);
320 // the only way I can see to do this under gtk+ 1.0.X would
321 // be to keep track of page numbers, start at first and
322 // do "next" enough times to get to this page number - messy
323 // - J. Russell Smyth
327 void wxMDIChildFrame::OnActivate( wxActivateEvent
&WXUNUSED(event
) )
331 //-----------------------------------------------------------------------------
333 //-----------------------------------------------------------------------------
335 static void gtk_page_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxWindow
*win
)
337 if (g_isIdle
) wxapp_install_idle_handler();
339 if ((win
->m_x
== alloc
->x
) &&
340 (win
->m_y
== alloc
->y
) &&
341 (win
->m_width
== alloc
->width
) &&
342 (win
->m_height
== alloc
->height
) &&
348 win
->SetSize( alloc
->x
, alloc
->y
, alloc
->width
, alloc
->height
);
351 //-----------------------------------------------------------------------------
352 // InsertChild callback for wxMDIClientWindow
353 //-----------------------------------------------------------------------------
355 static void wxInsertChildInMDI( wxMDIClientWindow
* parent
, wxMDIChildFrame
* child
)
357 wxString s
= child
->m_title
;
358 if (s
.IsNull()) s
= _("MDI child");
360 GtkWidget
*label_widget
= gtk_label_new( s
.mbc_str() );
361 gtk_misc_set_alignment( GTK_MISC(label_widget
), 0.0, 0.5 );
363 gtk_signal_connect( GTK_OBJECT(child
->m_widget
), "size_allocate",
364 GTK_SIGNAL_FUNC(gtk_page_size_callback
), (gpointer
)child
);
366 GtkNotebook
*notebook
= GTK_NOTEBOOK(parent
->m_widget
);
368 gtk_notebook_append_page( notebook
, child
->m_widget
, label_widget
);
370 child
->m_page
= (GtkNotebookPage
*) (g_list_last(notebook
->children
)->data
);
372 wxMDIParentFrame
*parent_frame
= (wxMDIParentFrame
*) parent
->GetParent();
373 parent_frame
->m_justInserted
= TRUE
;
376 //-----------------------------------------------------------------------------
378 //-----------------------------------------------------------------------------
380 IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow
,wxWindow
)
382 wxMDIClientWindow::wxMDIClientWindow()
386 wxMDIClientWindow::wxMDIClientWindow( wxMDIParentFrame
*parent
, long style
)
388 CreateClient( parent
, style
);
391 wxMDIClientWindow::~wxMDIClientWindow()
395 bool wxMDIClientWindow::CreateClient( wxMDIParentFrame
*parent
, long style
)
399 m_insertCallback
= (wxInsertChildFunction
)wxInsertChildInMDI
;
401 PreCreation( parent
, -1, wxPoint(10,10), wxSize(100,100), style
, "wxMDIClientWindow" );
403 m_widget
= gtk_notebook_new();
405 gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget
), 1 );
407 m_parent
->DoAddChild( this );