]>
git.saurik.com Git - wxWidgets.git/blob - src/gtk/mdi.cpp
a6e4317bcf9373f7d3a35c269cc495cb9b2b14fa
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;
95 menu_bar
->InternalSetPosition(0, 0);
96 menu_bar
->InternalSetSize(m_width
, wxMENU_HEIGHT
);
97 gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),
99 0, 0, m_width
, wxMENU_HEIGHT
);
102 void wxMDIParentFrame::OnInternalIdle()
104 /* if a an MDI child window has just been inserted
105 it has to be brought to the top in idle time. we
106 simply set the last notebook page active as new
107 pages can only be appended at the end */
111 GtkNotebook
*notebook
= GTK_NOTEBOOK(m_clientWindow
->m_widget
);
112 gtk_notebook_set_page( notebook
, g_list_length( notebook
->children
) - 1 );
114 m_justInserted
= FALSE
;
118 wxFrame::OnInternalIdle();
120 wxMDIChildFrame
*active_child_frame
= GetActiveChild();
121 bool visible_child_menu
= FALSE
;
123 wxNode
*node
= m_clientWindow
->GetChildren().First();
126 wxMDIChildFrame
*child_frame
= (wxMDIChildFrame
*)node
->Data();
127 if (child_frame
->m_menuBar
)
129 if (child_frame
== active_child_frame
)
131 gtk_widget_show( child_frame
->m_menuBar
->m_widget
);
132 visible_child_menu
= TRUE
;
135 gtk_widget_hide( child_frame
->m_menuBar
->m_widget
);
140 /* show/hide parent menu bar as required */
141 if (m_frameMenuBar
) m_frameMenuBar
->Show( !visible_child_menu
);
144 void wxMDIParentFrame::GetClientSize(int *width
, int *height
) const
146 wxFrame::GetClientSize( width
, height
);
149 wxMDIChildFrame
*wxMDIParentFrame::GetActiveChild() const
151 if (!m_clientWindow
) return (wxMDIChildFrame
*) NULL
;
153 GtkNotebook
*notebook
= GTK_NOTEBOOK(m_clientWindow
->m_widget
);
154 if (!notebook
) return (wxMDIChildFrame
*) NULL
;
156 #if (GTK_MINOR_VERSION > 0)
157 gint i
= gtk_notebook_get_current_page( notebook
);
159 gint i
= gtk_notebook_current_page( notebook
);
161 if (i
< 0) return (wxMDIChildFrame
*) NULL
;
163 GtkNotebookPage
* page
= (GtkNotebookPage
*) (g_list_nth(notebook
->children
,i
)->data
);
164 if (!page
) return (wxMDIChildFrame
*) NULL
;
166 wxNode
*node
= m_clientWindow
->GetChildren().First();
169 wxMDIChildFrame
*child_frame
= (wxMDIChildFrame
*)node
->Data();
170 if (child_frame
->m_page
== page
)
175 return (wxMDIChildFrame
*) NULL
;
178 wxMDIClientWindow
*wxMDIParentFrame::GetClientWindow() const
180 return m_clientWindow
;
183 wxMDIClientWindow
*wxMDIParentFrame::OnCreateClient()
185 m_clientWindow
= new wxMDIClientWindow( this );
186 return m_clientWindow
;
189 void wxMDIParentFrame::ActivateNext()
192 gtk_notebook_next_page( GTK_NOTEBOOK(m_clientWindow
->m_widget
) );
195 void wxMDIParentFrame::ActivatePrevious()
198 gtk_notebook_prev_page( GTK_NOTEBOOK(m_clientWindow
->m_widget
) );
201 void wxMDIParentFrame::OnActivate( wxActivateEvent
& WXUNUSED(event
) )
205 void wxMDIParentFrame::OnSysColourChanged( wxSysColourChangedEvent
& WXUNUSED(event
) )
209 //-----------------------------------------------------------------------------
211 //-----------------------------------------------------------------------------
213 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame
,wxFrame
)
215 BEGIN_EVENT_TABLE(wxMDIChildFrame
, wxFrame
)
216 EVT_ACTIVATE(wxMDIChildFrame::OnActivate
)
219 wxMDIChildFrame::wxMDIChildFrame()
221 m_menuBar
= (wxMenuBar
*) NULL
;
222 m_page
= (GtkNotebookPage
*) NULL
;
225 wxMDIChildFrame::wxMDIChildFrame( wxMDIParentFrame
*parent
,
226 wxWindowID id
, const wxString
& title
,
227 const wxPoint
& WXUNUSED(pos
), const wxSize
& size
,
228 long style
, const wxString
& name
)
230 m_menuBar
= (wxMenuBar
*) NULL
;
231 m_page
= (GtkNotebookPage
*) NULL
;
232 Create( parent
, id
, title
, wxDefaultPosition
, size
, style
, name
);
235 wxMDIChildFrame::~wxMDIChildFrame()
241 bool wxMDIChildFrame::Create( wxMDIParentFrame
*parent
,
242 wxWindowID id
, const wxString
& title
,
243 const wxPoint
& WXUNUSED(pos
), const wxSize
& size
,
244 long style
, const wxString
& name
)
248 return wxWindow::Create( parent
->GetClientWindow(), id
, wxDefaultPosition
, size
, style
, name
);
251 void wxMDIChildFrame::GetClientSize( int *width
, int *height
) const
253 wxWindow::GetClientSize( width
, height
);
256 void wxMDIChildFrame::AddChild( wxWindow
*child
)
258 wxWindow::AddChild( child
);
261 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
263 menu
->SetInvokingWindow( win
);
264 wxNode
*node
= menu
->GetItems().First();
267 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
268 if (menuitem
->IsSubMenu())
269 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
274 void wxMDIChildFrame::SetMenuBar( wxMenuBar
*menu_bar
)
276 m_menuBar
= menu_bar
;
280 wxMDIParentFrame
*mdi_frame
= (wxMDIParentFrame
*)m_parent
->GetParent();
282 if (m_menuBar
->GetParent() != this)
284 wxNode
*node
= m_menuBar
->GetMenus().First();
287 wxMenu
*menu
= (wxMenu
*)node
->Data();
288 SetInvokingWindow( menu
, this );
292 m_menuBar
->SetParent( mdi_frame
);
295 /* the menu bar of the child window is shown in idle time as needed */
296 gtk_widget_hide( m_menuBar
->m_widget
);
298 /* insert the invisible menu bar into the _parent_ mdi frame */
299 gtk_myfixed_put( GTK_MYFIXED(mdi_frame
->m_mainWidget
),
301 0, 0, 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
->GetParent();
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
->DoAddChild( this );