]>
git.saurik.com Git - wxWidgets.git/blob - src/gtk1/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 wxMenuBar
*menu_bar
= child_frame
->m_menuBar
;
130 if (child_frame
->m_menuBar
)
132 if (child_frame
== active_child_frame
)
134 if (menu_bar
->Show(TRUE
))
136 menu_bar
->m_width
= m_width
;
137 menu_bar
->m_height
= wxMENU_HEIGHT
;
138 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
140 0, 0, m_width
, wxMENU_HEIGHT
);
141 menu_bar
->SetInvokingWindow( child_frame
);
143 visible_child_menu
= TRUE
;
147 if (menu_bar
->Show(FALSE
))
149 menu_bar
->UnsetInvokingWindow( child_frame
);
156 /* show/hide parent menu bar as required */
157 if ((m_frameMenuBar
) &&
158 (m_frameMenuBar
->IsShown() == visible_child_menu
))
160 if (visible_child_menu
)
162 m_frameMenuBar
->Show( FALSE
);
163 m_frameMenuBar
->UnsetInvokingWindow( this );
167 m_frameMenuBar
->Show( TRUE
);
168 m_frameMenuBar
->SetInvokingWindow( this );
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
);
179 void wxMDIParentFrame::GetClientSize(int *width
, int *height
) const
181 wxFrame::GetClientSize( width
, height
);
184 wxMDIChildFrame
*wxMDIParentFrame::GetActiveChild() const
186 if (!m_clientWindow
) return (wxMDIChildFrame
*) NULL
;
188 GtkNotebook
*notebook
= GTK_NOTEBOOK(m_clientWindow
->m_widget
);
189 if (!notebook
) return (wxMDIChildFrame
*) NULL
;
191 #if (GTK_MINOR_VERSION > 0)
192 gint i
= gtk_notebook_get_current_page( notebook
);
194 gint i
= gtk_notebook_current_page( notebook
);
196 if (i
< 0) return (wxMDIChildFrame
*) NULL
;
198 GtkNotebookPage
* page
= (GtkNotebookPage
*) (g_list_nth(notebook
->children
,i
)->data
);
199 if (!page
) return (wxMDIChildFrame
*) NULL
;
201 wxNode
*node
= m_clientWindow
->GetChildren().First();
204 wxMDIChildFrame
*child_frame
= (wxMDIChildFrame
*)node
->Data();
205 if (child_frame
->m_page
== page
)
210 return (wxMDIChildFrame
*) NULL
;
213 wxMDIClientWindow
*wxMDIParentFrame::GetClientWindow() const
215 return m_clientWindow
;
218 wxMDIClientWindow
*wxMDIParentFrame::OnCreateClient()
220 m_clientWindow
= new wxMDIClientWindow( this );
221 return m_clientWindow
;
224 void wxMDIParentFrame::ActivateNext()
227 gtk_notebook_next_page( GTK_NOTEBOOK(m_clientWindow
->m_widget
) );
230 void wxMDIParentFrame::ActivatePrevious()
233 gtk_notebook_prev_page( GTK_NOTEBOOK(m_clientWindow
->m_widget
) );
236 void wxMDIParentFrame::OnActivate( wxActivateEvent
& WXUNUSED(event
) )
240 void wxMDIParentFrame::OnSysColourChanged( wxSysColourChangedEvent
& WXUNUSED(event
) )
244 //-----------------------------------------------------------------------------
246 //-----------------------------------------------------------------------------
248 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame
,wxFrame
)
250 BEGIN_EVENT_TABLE(wxMDIChildFrame
, wxFrame
)
251 EVT_ACTIVATE(wxMDIChildFrame::OnActivate
)
254 wxMDIChildFrame::wxMDIChildFrame()
256 m_menuBar
= (wxMenuBar
*) NULL
;
257 m_page
= (GtkNotebookPage
*) NULL
;
260 wxMDIChildFrame::wxMDIChildFrame( wxMDIParentFrame
*parent
,
261 wxWindowID id
, const wxString
& title
,
262 const wxPoint
& WXUNUSED(pos
), const wxSize
& size
,
263 long style
, const wxString
& name
)
265 m_menuBar
= (wxMenuBar
*) NULL
;
266 m_page
= (GtkNotebookPage
*) NULL
;
267 Create( parent
, id
, title
, wxDefaultPosition
, size
, style
, name
);
270 wxMDIChildFrame::~wxMDIChildFrame()
276 bool wxMDIChildFrame::Create( wxMDIParentFrame
*parent
,
277 wxWindowID id
, const wxString
& title
,
278 const wxPoint
& WXUNUSED(pos
), const wxSize
& size
,
279 long style
, const wxString
& name
)
283 return wxWindow::Create( parent
->GetClientWindow(), id
, wxDefaultPosition
, size
, style
, name
);
286 void wxMDIChildFrame::GetClientSize( int *width
, int *height
) const
288 wxWindow::GetClientSize( width
, height
);
291 void wxMDIChildFrame::AddChild( wxWindow
*child
)
293 wxWindow::AddChild( child
);
296 void wxMDIChildFrame::SetMenuBar( wxMenuBar
*menu_bar
)
298 wxASSERT_MSG( m_menuBar
== NULL
, _T("Only one menubar allowed") );
300 m_menuBar
= menu_bar
;
304 wxMDIParentFrame
*mdi_frame
= (wxMDIParentFrame
*)m_parent
->GetParent();
306 m_menuBar
->SetParent( mdi_frame
);
308 /* insert the invisible menu bar into the _parent_ mdi frame */
309 gtk_myfixed_put( GTK_MYFIXED(mdi_frame
->m_mainWidget
),
311 0, 0, mdi_frame
->m_width
, wxMENU_HEIGHT
);
315 wxMenuBar
*wxMDIChildFrame::GetMenuBar() const
320 void wxMDIChildFrame::Activate()
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
);
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
335 void wxMDIChildFrame::OnActivate( wxActivateEvent
&WXUNUSED(event
) )
339 //-----------------------------------------------------------------------------
341 //-----------------------------------------------------------------------------
343 static void gtk_page_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxWindow
*win
)
345 if (g_isIdle
) wxapp_install_idle_handler();
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
) &&
356 win
->SetSize( alloc
->x
, alloc
->y
, alloc
->width
, alloc
->height
);
359 //-----------------------------------------------------------------------------
360 // InsertChild callback for wxMDIClientWindow
361 //-----------------------------------------------------------------------------
363 static void wxInsertChildInMDI( wxMDIClientWindow
* parent
, wxMDIChildFrame
* child
)
365 wxString s
= child
->m_title
;
366 if (s
.IsNull()) s
= _("MDI child");
368 GtkWidget
*label_widget
= gtk_label_new( s
.mbc_str() );
369 gtk_misc_set_alignment( GTK_MISC(label_widget
), 0.0, 0.5 );
371 gtk_signal_connect( GTK_OBJECT(child
->m_widget
), "size_allocate",
372 GTK_SIGNAL_FUNC(gtk_page_size_callback
), (gpointer
)child
);
374 GtkNotebook
*notebook
= GTK_NOTEBOOK(parent
->m_widget
);
376 gtk_notebook_append_page( notebook
, child
->m_widget
, label_widget
);
378 child
->m_page
= (GtkNotebookPage
*) (g_list_last(notebook
->children
)->data
);
380 wxMDIParentFrame
*parent_frame
= (wxMDIParentFrame
*) parent
->GetParent();
381 parent_frame
->m_justInserted
= TRUE
;
384 //-----------------------------------------------------------------------------
386 //-----------------------------------------------------------------------------
388 IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow
,wxWindow
)
390 wxMDIClientWindow::wxMDIClientWindow()
394 wxMDIClientWindow::wxMDIClientWindow( wxMDIParentFrame
*parent
, long style
)
396 CreateClient( parent
, style
);
399 wxMDIClientWindow::~wxMDIClientWindow()
403 bool wxMDIClientWindow::CreateClient( wxMDIParentFrame
*parent
, long style
)
407 m_insertCallback
= (wxInsertChildFunction
)wxInsertChildInMDI
;
409 PreCreation( parent
, -1, wxPoint(10,10), wxSize(100,100), style
, "wxMDIClientWindow" );
411 m_widget
= gtk_notebook_new();
413 gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget
), 1 );
415 m_parent
->DoAddChild( this );