]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/mdi.cpp
Oh well, I'll just stuff in the rest of the Unicode changes I have made
[wxWidgets.git] / src / gtk / mdi.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: mdi.cpp
3// Purpose:
4// Author: Robert Roebling
a81258be
RR
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
a3622daa 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
10#ifdef __GNUG__
11#pragma implementation "mdi.h"
12#endif
13
14#include "wx/mdi.h"
e3e65dac 15#include "wx/dialog.h"
cf4219e7 16#include "wx/menu.h"
1a5a8367 17#include <wx/intl.h>
716b7364 18
83624f79
RR
19#include "glib.h"
20#include "gdk/gdk.h"
21#include "gtk/gtk.h"
22#include "wx/gtk/win_gtk.h"
23
6ca41e57
RR
24//-----------------------------------------------------------------------------
25// constants
26//-----------------------------------------------------------------------------
27
a0fdacee 28const int wxMENU_HEIGHT = 27;
6ca41e57
RR
29
30//-----------------------------------------------------------------------------
31// globals
716b7364
RR
32//-----------------------------------------------------------------------------
33
34extern wxList wxPendingDelete;
c801d85f 35
6ca41e57
RR
36//-----------------------------------------------------------------------------
37// wxMDIParentFrame
33d0b396
RR
38//-----------------------------------------------------------------------------
39
c801d85f
KB
40IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame,wxFrame)
41
716b7364
RR
42BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame)
43END_EVENT_TABLE()
44
ab2b3dd4 45wxMDIParentFrame::wxMDIParentFrame()
c801d85f 46{
ab2b3dd4 47 m_justInserted = FALSE;
83624f79 48 m_clientWindow = (wxMDIClientWindow *) NULL;
ff7b1510 49}
c801d85f
KB
50
51wxMDIParentFrame::wxMDIParentFrame( wxWindow *parent,
debe6624 52 wxWindowID id, const wxString& title,
c801d85f 53 const wxPoint& pos, const wxSize& size,
debe6624 54 long style, const wxString& name )
c801d85f 55{
ab2b3dd4 56 m_justInserted = FALSE;
83624f79 57 m_clientWindow = (wxMDIClientWindow *) NULL;
83624f79 58 Create( parent, id, title, pos, size, style, name );
ff7b1510 59}
c801d85f 60
ab2b3dd4 61wxMDIParentFrame::~wxMDIParentFrame()
c801d85f 62{
ff7b1510 63}
c801d85f
KB
64
65bool wxMDIParentFrame::Create( wxWindow *parent,
debe6624 66 wxWindowID id, const wxString& title,
c801d85f 67 const wxPoint& pos, const wxSize& size,
debe6624 68 long style, const wxString& name )
c801d85f 69{
83624f79 70 wxFrame::Create( parent, id, title, pos, size, style, name );
a3622daa 71
83624f79 72 OnCreateClient();
a3622daa 73
83624f79 74 return TRUE;
ff7b1510 75}
c801d85f 76
716b7364 77void wxMDIParentFrame::GtkOnSize( int x, int y, int width, int height )
c801d85f 78{
83624f79 79 wxFrame::GtkOnSize( x, y, width, height );
a0fdacee 80
ab2b3dd4
RR
81 wxMDIChildFrame *child_frame = GetActiveChild();
82 if (!child_frame) return;
a0fdacee 83
ab2b3dd4
RR
84 wxMenuBar *menu_bar = child_frame->m_menuBar;
85 if (!menu_bar) return;
86 if (!menu_bar->m_widget) return;
a0fdacee 87
ab2b3dd4
RR
88 menu_bar->m_x = 0;
89 menu_bar->m_y = 0;
90 menu_bar->m_width = m_width;
91 menu_bar->m_height = wxMENU_HEIGHT;
92 gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), menu_bar->m_widget, 0, 0 );
93 gtk_widget_set_usize( menu_bar->m_widget, m_width, wxMENU_HEIGHT );
94}
95
96void wxMDIParentFrame::OnInternalIdle()
97{
98 /* if a an MDI child window has just been inserted
99 it has to be brought to the top in idle time. we
100 simply set the last notebook page active as new
101 pages can only be appended at the end */
102
103 if (m_justInserted)
83624f79 104 {
ab2b3dd4 105 GtkNotebook *notebook = GTK_NOTEBOOK(m_clientWindow->m_widget);
a0fdacee
VZ
106 gtk_notebook_set_page( notebook, g_list_length( notebook->children ) - 1 );
107
108 m_justInserted = FALSE;
109 return;
83624f79 110 }
a0fdacee 111
ab2b3dd4 112 wxFrame::OnInternalIdle();
c626a8b7 113
ab2b3dd4 114 wxMDIChildFrame *active_child_frame = GetActiveChild();
a0fdacee 115
ab2b3dd4
RR
116 wxNode *node = m_clientWindow->m_children.First();
117 while (node)
83624f79 118 {
ab2b3dd4 119 wxMDIChildFrame *child_frame = (wxMDIChildFrame *)node->Data();
a0fdacee
VZ
120 if (child_frame->m_menuBar)
121 {
122 if (child_frame == active_child_frame)
123 gtk_widget_show( child_frame->m_menuBar->m_widget );
124 else
125 gtk_widget_hide( child_frame->m_menuBar->m_widget );
126 }
ab2b3dd4 127 node = node->Next();
83624f79 128 }
a0fdacee 129
e27ce4e9 130 /* show/hide parent menu bar as required */
ab2b3dd4 131 if (m_frameMenuBar) m_frameMenuBar->Show( (active_child_frame == NULL) );
ff7b1510 132}
716b7364
RR
133
134void wxMDIParentFrame::GetClientSize(int *width, int *height ) const
c801d85f 135{
83624f79 136 wxFrame::GetClientSize( width, height );
ff7b1510 137}
c801d85f 138
ab2b3dd4
RR
139wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const
140{
141 if (!m_clientWindow) return (wxMDIChildFrame*) NULL;
a0fdacee 142
ab2b3dd4
RR
143 GtkNotebook *notebook = GTK_NOTEBOOK(m_clientWindow->m_widget);
144 if (!notebook) return (wxMDIChildFrame*) NULL;
a0fdacee
VZ
145
146#if (GTK_MINOR_VERSION > 0)
ab2b3dd4 147 gint i = gtk_notebook_get_current_page( notebook );
a0fdacee
VZ
148#else
149 gint i = gtk_notebook_current_page( notebook );
150#endif
ab2b3dd4 151 if (i < 0) return (wxMDIChildFrame*) NULL;
a0fdacee 152
ab2b3dd4
RR
153 GtkNotebookPage* page = (GtkNotebookPage*) (g_list_nth(notebook->children,i)->data);
154 if (!page) return (wxMDIChildFrame*) NULL;
a0fdacee 155
ab2b3dd4
RR
156 wxNode *node = m_clientWindow->m_children.First();
157 while (node)
158 {
159 wxMDIChildFrame *child_frame = (wxMDIChildFrame *)node->Data();
160 if (child_frame->m_page == page)
161 return child_frame;
162 node = node->Next();
163 }
a0fdacee 164
ab2b3dd4 165 return (wxMDIChildFrame*) NULL;
ff7b1510 166}
c801d85f 167
ab2b3dd4 168wxMDIClientWindow *wxMDIParentFrame::GetClientWindow() const
c801d85f 169{
83624f79 170 return m_clientWindow;
ff7b1510 171}
c801d85f 172
ab2b3dd4 173wxMDIClientWindow *wxMDIParentFrame::OnCreateClient()
c801d85f 174{
83624f79
RR
175 m_clientWindow = new wxMDIClientWindow( this );
176 return m_clientWindow;
ff7b1510 177}
c801d85f 178
ab2b3dd4 179void wxMDIParentFrame::ActivateNext()
c801d85f 180{
83624f79
RR
181 if (m_clientWindow)
182 gtk_notebook_next_page( GTK_NOTEBOOK(m_clientWindow->m_widget) );
ff7b1510 183}
c801d85f 184
ab2b3dd4 185void wxMDIParentFrame::ActivatePrevious()
716b7364 186{
83624f79
RR
187 if (m_clientWindow)
188 gtk_notebook_prev_page( GTK_NOTEBOOK(m_clientWindow->m_widget) );
ff7b1510 189}
716b7364
RR
190
191void wxMDIParentFrame::OnActivate( wxActivateEvent& WXUNUSED(event) )
c801d85f 192{
ff7b1510 193}
c801d85f
KB
194
195void wxMDIParentFrame::OnSysColourChanged( wxSysColourChangedEvent& WXUNUSED(event) )
196{
ff7b1510 197}
c801d85f
KB
198
199//-----------------------------------------------------------------------------
200// wxMDIChildFrame
201//-----------------------------------------------------------------------------
202
cf4219e7 203IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame,wxFrame)
c626a8b7 204
cf4219e7 205BEGIN_EVENT_TABLE(wxMDIChildFrame, wxFrame)
83624f79 206 EVT_ACTIVATE(wxMDIChildFrame::OnActivate)
716b7364
RR
207END_EVENT_TABLE()
208
ab2b3dd4 209wxMDIChildFrame::wxMDIChildFrame()
c801d85f 210{
83624f79
RR
211 m_menuBar = (wxMenuBar *) NULL;
212 m_page = (GtkNotebookPage *) NULL;
ff7b1510 213}
c801d85f
KB
214
215wxMDIChildFrame::wxMDIChildFrame( wxMDIParentFrame *parent,
debe6624 216 wxWindowID id, const wxString& title,
33d0b396 217 const wxPoint& WXUNUSED(pos), const wxSize& size,
debe6624 218 long style, const wxString& name )
c801d85f 219{
83624f79
RR
220 m_menuBar = (wxMenuBar *) NULL;
221 m_page = (GtkNotebookPage *) NULL;
222 Create( parent, id, title, wxDefaultPosition, size, style, name );
ff7b1510 223}
c801d85f 224
ab2b3dd4 225wxMDIChildFrame::~wxMDIChildFrame()
c801d85f 226{
83624f79 227 if (m_menuBar)
83624f79 228 delete m_menuBar;
ff7b1510 229}
c801d85f
KB
230
231bool wxMDIChildFrame::Create( wxMDIParentFrame *parent,
debe6624 232 wxWindowID id, const wxString& title,
33d0b396 233 const wxPoint& WXUNUSED(pos), const wxSize& size,
debe6624 234 long style, const wxString& name )
c801d85f 235{
83624f79 236 m_title = title;
c626a8b7 237
83624f79 238 return wxWindow::Create( parent->GetClientWindow(), id, wxDefaultPosition, size, style, name );
ff7b1510 239}
c801d85f 240
cf4219e7 241void wxMDIChildFrame::GetClientSize( int *width, int *height ) const
c801d85f 242{
83624f79 243 wxWindow::GetClientSize( width, height );
cf4219e7 244}
9746a2ba 245
cf4219e7 246void wxMDIChildFrame::AddChild( wxWindow *child )
716b7364 247{
83624f79 248 wxWindow::AddChild( child );
716b7364 249}
c626a8b7 250
716b7364
RR
251static void SetInvokingWindow( wxMenu *menu, wxWindow *win )
252{
83624f79 253 menu->SetInvokingWindow( win );
c626a8b7 254 wxNode *node = menu->GetItems().First();
83624f79
RR
255 while (node)
256 {
257 wxMenuItem *menuitem = (wxMenuItem*)node->Data();
258 if (menuitem->IsSubMenu())
259 SetInvokingWindow( menuitem->GetSubMenu(), win );
260 node = node->Next();
261 }
ff7b1510 262}
716b7364
RR
263
264void wxMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar )
265{
83624f79 266 m_menuBar = menu_bar;
a3622daa 267
83624f79 268 if (m_menuBar)
716b7364 269 {
83624f79
RR
270 wxMDIParentFrame *mdi_frame = (wxMDIParentFrame*)m_parent->m_parent;
271
272 if (m_menuBar->m_parent != this)
273 {
c626a8b7 274 wxNode *node = m_menuBar->GetMenus().First();
83624f79
RR
275 while (node)
276 {
277 wxMenu *menu = (wxMenu*)node->Data();
278 SetInvokingWindow( menu, this );
279 node = node->Next();
280 }
281
282 m_menuBar->m_parent = mdi_frame;
283 }
c626a8b7 284
ab2b3dd4 285 /* the menu bar of the child window is shown in idle time as needed */
a0fdacee 286 gtk_widget_hide( m_menuBar->m_widget );
c626a8b7 287
ab2b3dd4
RR
288 /* insert the invisible menu bar into the _parent_ mdi frame */
289 gtk_myfixed_put( GTK_MYFIXED(mdi_frame->m_mainWidget), m_menuBar->m_widget, 0, 0 );
290 gtk_widget_set_usize( menu_bar->m_widget, mdi_frame->m_width, wxMENU_HEIGHT );
716b7364 291 }
ff7b1510 292}
cf4219e7 293
33b64e6f 294wxMenuBar *wxMDIChildFrame::GetMenuBar() const
cf4219e7 295{
83624f79 296 return m_menuBar;
ff7b1510 297}
c801d85f 298
ab2b3dd4 299void wxMDIChildFrame::Activate()
c801d85f 300{
ff7b1510 301}
c801d85f 302
9746a2ba
RR
303void wxMDIChildFrame::OnActivate( wxActivateEvent &WXUNUSED(event) )
304{
ff7b1510 305}
9746a2ba 306
ab2b3dd4
RR
307//-----------------------------------------------------------------------------
308// "size_allocate"
309//-----------------------------------------------------------------------------
310
311static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win )
312{
313 if ((win->m_x == alloc->x) &&
314 (win->m_y == alloc->y) &&
315 (win->m_width == alloc->width) &&
316 (win->m_height == alloc->height) &&
317 (win->m_sizeSet))
318 {
319 return;
320 }
321
322 win->SetSize( alloc->x, alloc->y, alloc->width, alloc->height );
323}
324
6ca41e57
RR
325//-----------------------------------------------------------------------------
326// InsertChild callback for wxMDIClientWindow
327//-----------------------------------------------------------------------------
328
329static void wxInsertChildInMDI( wxMDIClientWindow* parent, wxMDIChildFrame* child )
330{
83624f79
RR
331 wxString s = child->m_title;
332 if (s.IsNull()) s = _("MDI child");
6ca41e57 333
83624f79
RR
334 GtkWidget *label_widget = gtk_label_new( s );
335 gtk_misc_set_alignment( GTK_MISC(label_widget), 0.0, 0.5 );
6ca41e57 336
83624f79
RR
337 gtk_signal_connect( GTK_OBJECT(child->m_widget), "size_allocate",
338 GTK_SIGNAL_FUNC(gtk_page_size_callback), (gpointer)child );
c626a8b7 339
83624f79 340 GtkNotebook *notebook = GTK_NOTEBOOK(parent->m_widget);
c626a8b7 341
83624f79 342 gtk_notebook_append_page( notebook, child->m_widget, label_widget );
6ca41e57 343
83624f79 344 child->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data);
a0fdacee 345
ab2b3dd4
RR
346 wxMDIParentFrame *parent_frame = (wxMDIParentFrame*) parent->m_parent;
347 parent_frame->m_justInserted = TRUE;
6ca41e57
RR
348}
349
c801d85f
KB
350//-----------------------------------------------------------------------------
351// wxMDIClientWindow
352//-----------------------------------------------------------------------------
353
354IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow,wxWindow)
355
ab2b3dd4 356wxMDIClientWindow::wxMDIClientWindow()
c801d85f 357{
ff7b1510 358}
c801d85f 359
debe6624 360wxMDIClientWindow::wxMDIClientWindow( wxMDIParentFrame *parent, long style )
c801d85f 361{
83624f79 362 CreateClient( parent, style );
ff7b1510 363}
c801d85f 364
ab2b3dd4 365wxMDIClientWindow::~wxMDIClientWindow()
c801d85f 366{
ff7b1510 367}
c801d85f 368
debe6624 369bool wxMDIClientWindow::CreateClient( wxMDIParentFrame *parent, long style )
c801d85f 370{
83624f79 371 m_needParent = TRUE;
c626a8b7 372
83624f79 373 m_insertCallback = (wxInsertChildFunction)wxInsertChildInMDI;
a3622daa 374
83624f79 375 PreCreation( parent, -1, wxPoint(10,10), wxSize(100,100), style, "wxMDIClientWindow" );
c801d85f 376
83624f79 377 m_widget = gtk_notebook_new();
a3622daa 378
83624f79 379 gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 );
a3622daa 380
83624f79 381 m_parent->AddChild( this );
ee5e8025 382
83624f79 383 (m_parent->m_insertCallback)( m_parent, this );
c626a8b7 384
83624f79 385 PostCreation();
a3622daa 386
83624f79 387 Show( TRUE );
a3622daa 388
83624f79 389 return TRUE;
ff7b1510 390}
c801d85f 391
c801d85f
KB
392
393