From ab2b3dd4a28041694104aa782fb0b4f91d410136 Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Sun, 11 Apr 1999 22:43:52 +0000 Subject: [PATCH] Rewrote MDI system git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2090 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/gtk/mdi.h | 50 ++++----- include/wx/gtk/window.h | 5 +- include/wx/gtk1/mdi.h | 50 ++++----- include/wx/gtk1/window.h | 5 +- src/gtk/dialog.cpp | 34 +++---- src/gtk/frame.cpp | 150 +++++++++++++++------------ src/gtk/mdi.cpp | 213 ++++++++++++++++++++------------------- src/gtk1/dialog.cpp | 34 +++---- src/gtk1/frame.cpp | 150 +++++++++++++++------------ src/gtk1/mdi.cpp | 213 ++++++++++++++++++++------------------- 10 files changed, 470 insertions(+), 434 deletions(-) diff --git a/include/wx/gtk/mdi.h b/include/wx/gtk/mdi.h index 8d08ef3afa..5ec157d4ad 100644 --- a/include/wx/gtk/mdi.h +++ b/include/wx/gtk/mdi.h @@ -48,7 +48,7 @@ class wxMDIParentFrame: public wxFrame friend class wxMDIChildFrame; - public: +public: wxMDIParentFrame(void); wxMDIParentFrame( wxWindow *parent, @@ -65,32 +65,28 @@ class wxMDIParentFrame: public wxFrame void GetClientSize(int *width, int *height) const; - wxMDIChildFrame *GetActiveChild(void) const; + wxMDIChildFrame *GetActiveChild() const; - wxMDIClientWindow *GetClientWindow(void) const; - virtual wxMDIClientWindow *OnCreateClient(void); + wxMDIClientWindow *GetClientWindow() const; + virtual wxMDIClientWindow *OnCreateClient(); - virtual void Cascade(void) {}; - virtual void Tile(void) {}; - virtual void ArrangeIcons(void) {}; - virtual void ActivateNext(void); - virtual void ActivatePrevious(void); + virtual void Cascade() {} + virtual void Tile() {} + virtual void ArrangeIcons() {} + virtual void ActivateNext(); + virtual void ActivatePrevious(); void OnActivate( wxActivateEvent& event ); void OnSysColourChanged( wxSysColourChangedEvent& event ); - // implementation - - wxMDIChildFrame *m_currentChild; - - void SetMDIMenuBar( wxMenuBar *menu_bar ); + // implementation + + wxMDIClientWindow *m_clientWindow; + bool m_justInserted; + virtual void GtkOnSize( int x, int y, int width, int height ); + virtual void OnInternalIdle(); - private: - - wxMDIClientWindow *m_clientWindow; - bool m_parentFrameActive; - DECLARE_EVENT_TABLE() }; @@ -104,7 +100,7 @@ class wxMDIChildFrame: public wxFrame public: - wxMDIChildFrame(void); + wxMDIChildFrame(); wxMDIChildFrame( wxMDIParentFrame *parent, wxWindowID id, const wxString& title, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, @@ -121,7 +117,7 @@ class wxMDIChildFrame: public wxFrame virtual void GetClientSize( int *width, int *height ) const; virtual void AddChild( wxWindow *child ); - virtual void Activate(void); + virtual void Activate(); // no status bars virtual wxStatusBar* CreateStatusBar( int WXUNUSED(number)=1, long WXUNUSED(style)=1, @@ -150,18 +146,16 @@ class wxMDIChildFrame: public wxFrame wxString GetTitle() const { return m_title; } // no maximize etc - virtual void Maximize(bool WXUNUSED(maximize)) {} - virtual void Restore(void) {} + virtual void Maximize( bool WXUNUSED(maximize) ) {} + virtual void Restore() {} void OnActivate( wxActivateEvent &event ); - public: + // implementation wxMenuBar *m_menuBar; - -// private: - GtkNotebookPage *m_page; + bool m_justInserted; DECLARE_EVENT_TABLE() }; @@ -174,7 +168,7 @@ class wxMDIClientWindow: public wxWindow { DECLARE_DYNAMIC_CLASS(wxMDIClientWindow) - public: +public: wxMDIClientWindow(void); wxMDIClientWindow( wxMDIParentFrame *parent, long style = 0 ); diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h index 6520054034..2a44e8d335 100644 --- a/include/wx/gtk/window.h +++ b/include/wx/gtk/window.h @@ -405,14 +405,15 @@ public: bool HasVMT(); - /* I don't want users to override what's done in OnIdle */ + /* I don't want users to override what's done in idle so everything that + has to be done in idle time in order for wxGTK to work is done in + OnInternalIdle */ virtual void OnInternalIdle(); /* For compatibility across platforms (not in event table) */ void OnIdle(wxIdleEvent& WXUNUSED(event)) {}; /* used by all classes in the widget creation process */ - void PreCreation( wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name ); void PostCreation(); diff --git a/include/wx/gtk1/mdi.h b/include/wx/gtk1/mdi.h index 8d08ef3afa..5ec157d4ad 100644 --- a/include/wx/gtk1/mdi.h +++ b/include/wx/gtk1/mdi.h @@ -48,7 +48,7 @@ class wxMDIParentFrame: public wxFrame friend class wxMDIChildFrame; - public: +public: wxMDIParentFrame(void); wxMDIParentFrame( wxWindow *parent, @@ -65,32 +65,28 @@ class wxMDIParentFrame: public wxFrame void GetClientSize(int *width, int *height) const; - wxMDIChildFrame *GetActiveChild(void) const; + wxMDIChildFrame *GetActiveChild() const; - wxMDIClientWindow *GetClientWindow(void) const; - virtual wxMDIClientWindow *OnCreateClient(void); + wxMDIClientWindow *GetClientWindow() const; + virtual wxMDIClientWindow *OnCreateClient(); - virtual void Cascade(void) {}; - virtual void Tile(void) {}; - virtual void ArrangeIcons(void) {}; - virtual void ActivateNext(void); - virtual void ActivatePrevious(void); + virtual void Cascade() {} + virtual void Tile() {} + virtual void ArrangeIcons() {} + virtual void ActivateNext(); + virtual void ActivatePrevious(); void OnActivate( wxActivateEvent& event ); void OnSysColourChanged( wxSysColourChangedEvent& event ); - // implementation - - wxMDIChildFrame *m_currentChild; - - void SetMDIMenuBar( wxMenuBar *menu_bar ); + // implementation + + wxMDIClientWindow *m_clientWindow; + bool m_justInserted; + virtual void GtkOnSize( int x, int y, int width, int height ); + virtual void OnInternalIdle(); - private: - - wxMDIClientWindow *m_clientWindow; - bool m_parentFrameActive; - DECLARE_EVENT_TABLE() }; @@ -104,7 +100,7 @@ class wxMDIChildFrame: public wxFrame public: - wxMDIChildFrame(void); + wxMDIChildFrame(); wxMDIChildFrame( wxMDIParentFrame *parent, wxWindowID id, const wxString& title, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, @@ -121,7 +117,7 @@ class wxMDIChildFrame: public wxFrame virtual void GetClientSize( int *width, int *height ) const; virtual void AddChild( wxWindow *child ); - virtual void Activate(void); + virtual void Activate(); // no status bars virtual wxStatusBar* CreateStatusBar( int WXUNUSED(number)=1, long WXUNUSED(style)=1, @@ -150,18 +146,16 @@ class wxMDIChildFrame: public wxFrame wxString GetTitle() const { return m_title; } // no maximize etc - virtual void Maximize(bool WXUNUSED(maximize)) {} - virtual void Restore(void) {} + virtual void Maximize( bool WXUNUSED(maximize) ) {} + virtual void Restore() {} void OnActivate( wxActivateEvent &event ); - public: + // implementation wxMenuBar *m_menuBar; - -// private: - GtkNotebookPage *m_page; + bool m_justInserted; DECLARE_EVENT_TABLE() }; @@ -174,7 +168,7 @@ class wxMDIClientWindow: public wxWindow { DECLARE_DYNAMIC_CLASS(wxMDIClientWindow) - public: +public: wxMDIClientWindow(void); wxMDIClientWindow( wxMDIParentFrame *parent, long style = 0 ); diff --git a/include/wx/gtk1/window.h b/include/wx/gtk1/window.h index 6520054034..2a44e8d335 100644 --- a/include/wx/gtk1/window.h +++ b/include/wx/gtk1/window.h @@ -405,14 +405,15 @@ public: bool HasVMT(); - /* I don't want users to override what's done in OnIdle */ + /* I don't want users to override what's done in idle so everything that + has to be done in idle time in order for wxGTK to work is done in + OnInternalIdle */ virtual void OnInternalIdle(); /* For compatibility across platforms (not in event table) */ void OnIdle(wxIdleEvent& WXUNUSED(event)) {}; /* used by all classes in the widget creation process */ - void PreCreation( wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name ); void PostCreation(); diff --git a/src/gtk/dialog.cpp b/src/gtk/dialog.cpp index 6f8cefcb3c..5aa6f2fb4d 100644 --- a/src/gtk/dialog.cpp +++ b/src/gtk/dialog.cpp @@ -145,26 +145,26 @@ bool wxDialog::Create( wxWindow *parent, gtk_widget_realize( m_widget ); - long decor = (long) GDK_DECOR_ALL; - long func = (long) GDK_FUNC_ALL; - - if ((m_windowStyle & wxCAPTION) == 0) + /* comments see wxFrame */ + + long decor = (long) GDK_DECOR_ALL; + long func = (long) GDK_FUNC_ALL; + if ((m_windowStyle & wxCAPTION) == 0) decor |= GDK_DECOR_TITLE; - if ((m_windowStyle & wxMINIMIZE) == 0) + if ((m_windowStyle & wxMINIMIZE) == 0) func |= GDK_FUNC_MINIMIZE; - if ((m_windowStyle & wxMAXIMIZE) == 0) + if ((m_windowStyle & wxMAXIMIZE) == 0) func |= GDK_FUNC_MAXIMIZE; - if ((m_windowStyle & wxSYSTEM_MENU) == 0) + if ((m_windowStyle & wxSYSTEM_MENU) == 0) decor |= GDK_DECOR_MENU; - if ((m_windowStyle & wxMINIMIZE_BOX) == 0) + if ((m_windowStyle & wxMINIMIZE_BOX) == 0) decor |= GDK_DECOR_MINIMIZE; - if ((m_windowStyle & wxMAXIMIZE_BOX) == 0) + if ((m_windowStyle & wxMAXIMIZE_BOX) == 0) decor |= GDK_DECOR_MAXIMIZE; - if ((m_windowStyle & wxRESIZE_BORDER) == 0) + if ((m_windowStyle & wxRESIZE_BORDER) == 0) func |= GDK_FUNC_RESIZE; - - gdk_window_set_decorations(m_widget->window, (GdkWMDecoration)decor); - gdk_window_set_functions(m_widget->window, (GdkWMFunction)func); + gdk_window_set_decorations(m_widget->window, (GdkWMDecoration)decor); + gdk_window_set_functions(m_widget->window, (GdkWMFunction)func); gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", GTK_SIGNAL_FUNC(gtk_dialog_size_callback), (gpointer)this ); @@ -257,17 +257,17 @@ void wxDialog::OnCloseWindow(wxCloseEvent& event) // sure to destroy the dialog. // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog. - static wxList closing; + static wxList s_closing; - if (closing.Member(this)) + if (s_closing.Member(this)) return; // no loops - closing.Append(this); + s_closing.Append(this); wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL); cancelEvent.SetEventObject( this ); GetEventHandler()->ProcessEvent(cancelEvent); - closing.DeleteObject(this); + s_closing.DeleteObject(this); } bool wxDialog::Destroy() diff --git a/src/gtk/frame.cpp b/src/gtk/frame.cpp index 06351fb9a2..e7b368139f 100644 --- a/src/gtk/frame.cpp +++ b/src/gtk/frame.cpp @@ -162,6 +162,7 @@ wxFrame::wxFrame() m_sizeSet = FALSE; m_miniEdge = 0; m_miniTitle = 0; + m_mainWidget = (GtkWidget*) NULL; } wxFrame::wxFrame( wxWindow *parent, wxWindowID id, const wxString &title, @@ -175,6 +176,7 @@ wxFrame::wxFrame( wxWindow *parent, wxWindowID id, const wxString &title, m_sizeSet = FALSE; m_miniEdge = 0; m_miniTitle = 0; + m_mainWidget = (GtkWidget*) NULL; Create( parent, id, title, pos, size, style, name ); } @@ -200,6 +202,7 @@ bool wxFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title, gtk_window_set_title( GTK_WINDOW(m_widget), title ); GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); + /* needed ? */ gtk_window_set_policy( GTK_WINDOW(m_widget), 1, 1, 0 ); gtk_signal_connect( GTK_OBJECT(m_widget), "delete_event", @@ -224,30 +227,32 @@ bool wxFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title, gtk_widget_realize( m_widget ); - long decor = (long) GDK_DECOR_ALL; - long func = (long) GDK_FUNC_ALL; - - if ((m_windowStyle & wxCAPTION) == 0) + /* all this is for Motif Window Manager "hints" and is supposed to be + recognized by other WM as well. not tested. */ + long decor = (long) GDK_DECOR_ALL; + long func = (long) GDK_FUNC_ALL; + if ((m_windowStyle & wxCAPTION) == 0) decor |= GDK_DECOR_TITLE; - if ((m_windowStyle & wxMINIMIZE) == 0) + if ((m_windowStyle & wxMINIMIZE) == 0) func |= GDK_FUNC_MINIMIZE; - if ((m_windowStyle & wxMAXIMIZE) == 0) + if ((m_windowStyle & wxMAXIMIZE) == 0) func |= GDK_FUNC_MAXIMIZE; - if ((m_windowStyle & wxSYSTEM_MENU) == 0) + if ((m_windowStyle & wxSYSTEM_MENU) == 0) decor |= GDK_DECOR_MENU; - if ((m_windowStyle & wxMINIMIZE_BOX) == 0) + if ((m_windowStyle & wxMINIMIZE_BOX) == 0) decor |= GDK_DECOR_MINIMIZE; - if ((m_windowStyle & wxMAXIMIZE_BOX) == 0) + if ((m_windowStyle & wxMAXIMIZE_BOX) == 0) decor |= GDK_DECOR_MAXIMIZE; - if ((m_windowStyle & wxRESIZE_BORDER) == 0) + if ((m_windowStyle & wxRESIZE_BORDER) == 0) func |= GDK_FUNC_RESIZE; - - gdk_window_set_decorations(m_widget->window, (GdkWMDecoration)decor); - gdk_window_set_functions(m_widget->window, (GdkWMFunction)func); + gdk_window_set_decorations(m_widget->window, (GdkWMDecoration)decor); + gdk_window_set_functions(m_widget->window, (GdkWMFunction)func); + /* the user resized the frame by dragging etc. */ gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", GTK_SIGNAL_FUNC(gtk_frame_size_callback), (gpointer)this ); + /* the only way to get the window size is to connect to this event */ gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event", GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this ); @@ -308,10 +313,11 @@ void wxFrame::DoSetSize( int x, int y, int width, int height, int sizeFlags ) { wxASSERT_MSG( (m_widget != NULL), "invalid frame" ); - /* don't do anything for children of wxMDIChildFrame */ - if (!m_wxwindow) return; - - if (m_resizing) return; // I don't like recursions + /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */ + wxASSERT_MSG( (m_wxwindow != NULL), "invalid frame" ); + + /* avoid recursions */ + if (m_resizing) return; m_resizing = TRUE; int old_x = m_x; @@ -360,7 +366,9 @@ void wxFrame::DoSetSize( int x, int y, int width, int height, int sizeFlags ) if ((m_width != old_width) || (m_height != old_height)) { - /* we set the size in GtkOnSize */ + /* we set the size in GtkOnSize, i.e. mostly the actual resizing is + done either directly before the frame is shown or in idle time + so that different calls to SetSize() don't lead to flicker. */ m_sizeSet = FALSE; } @@ -425,65 +433,79 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height // m_x = x; // m_y = y; + /* avoid recursions */ if (m_resizing) return; m_resizing = TRUE; - if (!m_wxwindow) return; - + /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */ + wxASSERT_MSG( (m_wxwindow != NULL), "invalid frame" ); + m_width = width; m_height = height; - /* check if size is in legal range */ - if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth; - if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight; - if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth; - if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight; - - /* I revert back to wxGTK's original behaviour. m_mainWidget holds the - * menubar, the toolbar and the client area, which is represented by - * m_wxwindow. - * this hurts in the eye, but I don't want to call SetSize() - * because I don't want to call any non-native functions here. */ - + /* space occupied by m_frameToolBar and m_frameMenuBar */ int client_area_y_offset = 0; - if (m_frameMenuBar) + /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses + wxWindow::Create to create it's GTK equivalent. m_mainWidget is only + set in wxFrame::Create so it is used to check what kind of frame we + have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we + skip the part which handles m_frameMenuBar, m_frameToolBar and (most + importantly) m_mainWidget */ + + if (m_mainWidget) { - int xx = m_miniEdge; - int yy = m_miniEdge + m_miniTitle; - int ww = m_width - 2*m_miniEdge; - int hh = wxMENU_HEIGHT; - m_frameMenuBar->m_x = xx; - m_frameMenuBar->m_y = yy; - m_frameMenuBar->m_width = ww; - m_frameMenuBar->m_height = hh; - - gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_frameMenuBar->m_widget, xx, yy ); - gtk_widget_set_usize( m_frameMenuBar->m_widget, ww, hh ); + /* check if size is in legal range */ + if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth; + if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight; + if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth; + if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight; + + /* I revert back to wxGTK's original behaviour. m_mainWidget holds the + * menubar, the toolbar and the client area, which is represented by + * m_wxwindow. + * this hurts in the eye, but I don't want to call SetSize() + * because I don't want to call any non-native functions here. */ + + if (m_frameMenuBar) + { + int xx = m_miniEdge; + int yy = m_miniEdge + m_miniTitle; + int ww = m_width - 2*m_miniEdge; + int hh = wxMENU_HEIGHT; + m_frameMenuBar->m_x = xx; + m_frameMenuBar->m_y = yy; + m_frameMenuBar->m_width = ww; + m_frameMenuBar->m_height = hh; + + gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_frameMenuBar->m_widget, xx, yy ); + gtk_widget_set_usize( m_frameMenuBar->m_widget, ww, hh ); - client_area_y_offset += hh; - } + client_area_y_offset += hh; + } - if (m_frameToolBar) - { - int xx = m_miniEdge; - int yy = m_miniEdge + m_miniTitle; - if ((m_frameMenuBar) || (m_mdiMenuBar)) yy += wxMENU_HEIGHT; - int ww = m_width - 2*m_miniEdge; - int hh = m_frameToolBar->m_height; - - m_frameToolBar->m_x = xx; - m_frameToolBar->m_y = yy; - m_frameToolBar->m_height = hh; - m_frameToolBar->m_width = ww; - - gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_frameToolBar->m_widget, xx, yy ); - gtk_widget_set_usize( m_frameToolBar->m_widget, ww, hh ); + if (m_frameToolBar) + { + int xx = m_miniEdge; + int yy = m_miniEdge + m_miniTitle; + if ((m_frameMenuBar) || (m_mdiMenuBar)) yy += wxMENU_HEIGHT; + int ww = m_width - 2*m_miniEdge; + int hh = m_frameToolBar->m_height; + + m_frameToolBar->m_x = xx; + m_frameToolBar->m_y = yy; + m_frameToolBar->m_height = hh; + m_frameToolBar->m_width = ww; + + gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_frameToolBar->m_widget, xx, yy ); + gtk_widget_set_usize( m_frameToolBar->m_widget, ww, hh ); - client_area_y_offset += hh; + client_area_y_offset += hh; + } + + gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_wxwindow, 0, client_area_y_offset ); } - gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_wxwindow, 0, client_area_y_offset ); gtk_widget_set_usize( m_wxwindow, m_width, m_height-client_area_y_offset ); if (m_frameStatusBar) @@ -533,8 +555,6 @@ void wxFrame::OnInternalIdle() void wxFrame::OnCloseWindow( wxCloseEvent& event ) { - // close the window if it wasn't vetoed by the application -// if ( !event.GetVeto() ) // No, this isn't the interpretation of GetVeto. Destroy(); } diff --git a/src/gtk/mdi.cpp b/src/gtk/mdi.cpp index e0b6d4aeca..82f5e1c260 100644 --- a/src/gtk/mdi.cpp +++ b/src/gtk/mdi.cpp @@ -33,48 +33,6 @@ const int wxMENU_HEIGHT = 27; extern wxList wxPendingDelete; -//----------------------------------------------------------------------------- -// "size_allocate" -//----------------------------------------------------------------------------- - -static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win ) -{ - if ((win->m_x == alloc->x) && - (win->m_y == alloc->y) && - (win->m_width == alloc->width) && - (win->m_height == alloc->height) && - (win->m_sizeSet)) - { - return; - } - - win->SetSize( alloc->x, alloc->y, alloc->width, alloc->height ); -} - -//----------------------------------------------------------------------------- -// "switch_page" -//----------------------------------------------------------------------------- - -static void gtk_page_change_callback( GtkNotebook *WXUNUSED(widget), - GtkNotebookPage *page, - gint WXUNUSED(nPage), - wxMDIClientWindow *client_win ) -{ - wxNode *node = client_win->m_children.First(); - while (node) - { - wxMDIChildFrame *child_frame = (wxMDIChildFrame *)node->Data(); - if (child_frame->m_page == page) - { - wxMDIParentFrame *mdi_frame = (wxMDIParentFrame*)client_win->m_parent; - mdi_frame->m_currentChild = child_frame; - mdi_frame->SetMDIMenuBar( child_frame->m_menuBar ); - return; - } - node = node->Next(); - } -} - //----------------------------------------------------------------------------- // wxMDIParentFrame //----------------------------------------------------------------------------- @@ -84,11 +42,10 @@ IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame,wxFrame) BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame) END_EVENT_TABLE() -wxMDIParentFrame::wxMDIParentFrame(void) +wxMDIParentFrame::wxMDIParentFrame() { + m_justInserted = FALSE; m_clientWindow = (wxMDIClientWindow *) NULL; - m_currentChild = (wxMDIChildFrame *) NULL; - m_parentFrameActive = TRUE; } wxMDIParentFrame::wxMDIParentFrame( wxWindow *parent, @@ -96,13 +53,12 @@ wxMDIParentFrame::wxMDIParentFrame( wxWindow *parent, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) { + m_justInserted = FALSE; m_clientWindow = (wxMDIClientWindow *) NULL; - m_currentChild = (wxMDIChildFrame *) NULL; - m_parentFrameActive = TRUE; Create( parent, id, title, pos, size, style, name ); } -wxMDIParentFrame::~wxMDIParentFrame(void) +wxMDIParentFrame::~wxMDIParentFrame() { } @@ -121,39 +77,58 @@ bool wxMDIParentFrame::Create( wxWindow *parent, void wxMDIParentFrame::GtkOnSize( int x, int y, int width, int height ) { wxFrame::GtkOnSize( x, y, width, height ); - - if (m_mdiMenuBar) + + wxMDIChildFrame *child_frame = GetActiveChild(); + if (!child_frame) return; + + wxMenuBar *menu_bar = child_frame->m_menuBar; + if (!menu_bar) return; + if (!menu_bar->m_widget) return; + + menu_bar->m_x = 0; + menu_bar->m_y = 0; + menu_bar->m_width = m_width; + menu_bar->m_height = wxMENU_HEIGHT; + gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), menu_bar->m_widget, 0, 0 ); + gtk_widget_set_usize( menu_bar->m_widget, m_width, wxMENU_HEIGHT ); +} + +void wxMDIParentFrame::OnInternalIdle() +{ + /* if a an MDI child window has just been inserted + it has to be brought to the top in idle time. we + simply set the last notebook page active as new + pages can only be appended at the end */ + + if (m_justInserted) { - m_mdiMenuBar->m_x = 0; - m_mdiMenuBar->m_y = 0; - m_mdiMenuBar->m_width = m_width; - m_mdiMenuBar->m_height = wxMENU_HEIGHT; - gtk_myfixed_move( GTK_MYFIXED(m_wxwindow), m_mdiMenuBar->m_widget, 0, 0 ); - gtk_widget_set_usize( m_mdiMenuBar->m_widget, m_width, wxMENU_HEIGHT ); + GtkNotebook *notebook = GTK_NOTEBOOK(m_clientWindow->m_widget); + gtk_notebook_set_page( notebook, g_list_length( notebook->children ) - 1 ); + + m_justInserted = FALSE; + return; } -} - -void wxMDIParentFrame::SetMDIMenuBar( wxMenuBar *menu_bar ) -{ - /* hide old child menu bar */ - if (m_mdiMenuBar) m_mdiMenuBar->Show( FALSE ); - - m_mdiMenuBar = menu_bar; + + wxFrame::OnInternalIdle(); - /* show and resize new menu child menu bar */ - if (m_mdiMenuBar) + wxMDIChildFrame *active_child_frame = GetActiveChild(); + + wxNode *node = m_clientWindow->m_children.First(); + while (node) { - m_mdiMenuBar->m_x = 0; - m_mdiMenuBar->m_y = 0; - m_mdiMenuBar->m_width = m_width; - m_mdiMenuBar->m_height = wxMENU_HEIGHT; - gtk_myfixed_move( GTK_MYFIXED(m_wxwindow), m_mdiMenuBar->m_widget, 0, 0 ); - gtk_widget_set_usize( m_mdiMenuBar->m_widget, m_width, wxMENU_HEIGHT ); - m_mdiMenuBar->Show( TRUE ); + wxMDIChildFrame *child_frame = (wxMDIChildFrame *)node->Data(); + if (child_frame->m_menuBar) + { + if (child_frame == active_child_frame) + gtk_widget_show( child_frame->m_menuBar->m_widget ); + else + gtk_widget_hide( child_frame->m_menuBar->m_widget ); + } + node = node->Next(); } - + /* show/hide parent menu bar as required */ - if (m_frameMenuBar) m_frameMenuBar->Show( (m_mdiMenuBar == NULL) ); + if (m_frameMenuBar) m_frameMenuBar->Show( (active_child_frame == NULL) ); } void wxMDIParentFrame::GetClientSize(int *width, int *height ) const @@ -161,29 +136,49 @@ void wxMDIParentFrame::GetClientSize(int *width, int *height ) const wxFrame::GetClientSize( width, height ); } -wxMDIChildFrame *wxMDIParentFrame::GetActiveChild(void) const -{ - return m_currentChild; +wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const +{ + if (!m_clientWindow) return (wxMDIChildFrame*) NULL; + + GtkNotebook *notebook = GTK_NOTEBOOK(m_clientWindow->m_widget); + if (!notebook) return (wxMDIChildFrame*) NULL; + + gint i = gtk_notebook_get_current_page( notebook ); + if (i < 0) return (wxMDIChildFrame*) NULL; + + GtkNotebookPage* page = (GtkNotebookPage*) (g_list_nth(notebook->children,i)->data); + if (!page) return (wxMDIChildFrame*) NULL; + + wxNode *node = m_clientWindow->m_children.First(); + while (node) + { + wxMDIChildFrame *child_frame = (wxMDIChildFrame *)node->Data(); + if (child_frame->m_page == page) + return child_frame; + node = node->Next(); + } + + return (wxMDIChildFrame*) NULL; } -wxMDIClientWindow *wxMDIParentFrame::GetClientWindow(void) const +wxMDIClientWindow *wxMDIParentFrame::GetClientWindow() const { return m_clientWindow; } -wxMDIClientWindow *wxMDIParentFrame::OnCreateClient(void) +wxMDIClientWindow *wxMDIParentFrame::OnCreateClient() { m_clientWindow = new wxMDIClientWindow( this ); return m_clientWindow; } -void wxMDIParentFrame::ActivateNext(void) +void wxMDIParentFrame::ActivateNext() { if (m_clientWindow) gtk_notebook_next_page( GTK_NOTEBOOK(m_clientWindow->m_widget) ); } -void wxMDIParentFrame::ActivatePrevious(void) +void wxMDIParentFrame::ActivatePrevious() { if (m_clientWindow) gtk_notebook_prev_page( GTK_NOTEBOOK(m_clientWindow->m_widget) ); @@ -207,7 +202,7 @@ BEGIN_EVENT_TABLE(wxMDIChildFrame, wxFrame) EVT_ACTIVATE(wxMDIChildFrame::OnActivate) END_EVENT_TABLE() -wxMDIChildFrame::wxMDIChildFrame(void) +wxMDIChildFrame::wxMDIChildFrame() { m_menuBar = (wxMenuBar *) NULL; m_page = (GtkNotebookPage *) NULL; @@ -223,18 +218,10 @@ wxMDIChildFrame::wxMDIChildFrame( wxMDIParentFrame *parent, Create( parent, id, title, wxDefaultPosition, size, style, name ); } -wxMDIChildFrame::~wxMDIChildFrame(void) +wxMDIChildFrame::~wxMDIChildFrame() { if (m_menuBar) - { - wxMDIParentFrame *mdi_frame = (wxMDIParentFrame*)m_parent->m_parent; - if (mdi_frame->m_currentChild == this) - { - mdi_frame->SetMDIMenuBar( (wxMenuBar *) NULL ); - mdi_frame->m_currentChild = (wxMDIChildFrame *) NULL; - } delete m_menuBar; - } } bool wxMDIChildFrame::Create( wxMDIParentFrame *parent, @@ -291,10 +278,12 @@ void wxMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar ) m_menuBar->m_parent = mdi_frame; } - gtk_myfixed_put( GTK_MYFIXED(mdi_frame->m_wxwindow), - m_menuBar->m_widget, m_menuBar->m_x, m_menuBar->m_y ); + /* the menu bar of the child window is shown in idle time as needed */ + gtk_widget_hide( m_menuBar->m_widget ); - mdi_frame->SetMDIMenuBar( m_menuBar ); + /* insert the invisible menu bar into the _parent_ mdi frame */ + gtk_myfixed_put( GTK_MYFIXED(mdi_frame->m_mainWidget), m_menuBar->m_widget, 0, 0 ); + gtk_widget_set_usize( menu_bar->m_widget, mdi_frame->m_width, wxMENU_HEIGHT ); } } @@ -303,7 +292,7 @@ wxMenuBar *wxMDIChildFrame::GetMenuBar() const return m_menuBar; } -void wxMDIChildFrame::Activate(void) +void wxMDIChildFrame::Activate() { } @@ -311,6 +300,24 @@ void wxMDIChildFrame::OnActivate( wxActivateEvent &WXUNUSED(event) ) { } +//----------------------------------------------------------------------------- +// "size_allocate" +//----------------------------------------------------------------------------- + +static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win ) +{ + if ((win->m_x == alloc->x) && + (win->m_y == alloc->y) && + (win->m_width == alloc->width) && + (win->m_height == alloc->height) && + (win->m_sizeSet)) + { + return; + } + + win->SetSize( alloc->x, alloc->y, alloc->width, alloc->height ); +} + //----------------------------------------------------------------------------- // InsertChild callback for wxMDIClientWindow //----------------------------------------------------------------------------- @@ -331,10 +338,9 @@ static void wxInsertChildInMDI( wxMDIClientWindow* parent, wxMDIChildFrame* chil gtk_notebook_append_page( notebook, child->m_widget, label_widget ); child->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data); - - gtk_notebook_set_page( notebook, parent->m_children.Number()-1 ); - - gtk_page_change_callback( (GtkNotebook *) NULL, child->m_page, 0, parent ); + + wxMDIParentFrame *parent_frame = (wxMDIParentFrame*) parent->m_parent; + parent_frame->m_justInserted = TRUE; } //----------------------------------------------------------------------------- @@ -343,7 +349,7 @@ static void wxInsertChildInMDI( wxMDIClientWindow* parent, wxMDIChildFrame* chil IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow,wxWindow) -wxMDIClientWindow::wxMDIClientWindow(void) +wxMDIClientWindow::wxMDIClientWindow() { } @@ -352,7 +358,7 @@ wxMDIClientWindow::wxMDIClientWindow( wxMDIParentFrame *parent, long style ) CreateClient( parent, style ); } -wxMDIClientWindow::~wxMDIClientWindow(void) +wxMDIClientWindow::~wxMDIClientWindow() { } @@ -366,9 +372,6 @@ bool wxMDIClientWindow::CreateClient( wxMDIParentFrame *parent, long style ) m_widget = gtk_notebook_new(); - gtk_signal_connect( GTK_OBJECT(m_widget), "switch_page", - GTK_SIGNAL_FUNC(gtk_page_change_callback), (gpointer)this ); - gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 ); m_parent->AddChild( this ); diff --git a/src/gtk1/dialog.cpp b/src/gtk1/dialog.cpp index 6f8cefcb3c..5aa6f2fb4d 100644 --- a/src/gtk1/dialog.cpp +++ b/src/gtk1/dialog.cpp @@ -145,26 +145,26 @@ bool wxDialog::Create( wxWindow *parent, gtk_widget_realize( m_widget ); - long decor = (long) GDK_DECOR_ALL; - long func = (long) GDK_FUNC_ALL; - - if ((m_windowStyle & wxCAPTION) == 0) + /* comments see wxFrame */ + + long decor = (long) GDK_DECOR_ALL; + long func = (long) GDK_FUNC_ALL; + if ((m_windowStyle & wxCAPTION) == 0) decor |= GDK_DECOR_TITLE; - if ((m_windowStyle & wxMINIMIZE) == 0) + if ((m_windowStyle & wxMINIMIZE) == 0) func |= GDK_FUNC_MINIMIZE; - if ((m_windowStyle & wxMAXIMIZE) == 0) + if ((m_windowStyle & wxMAXIMIZE) == 0) func |= GDK_FUNC_MAXIMIZE; - if ((m_windowStyle & wxSYSTEM_MENU) == 0) + if ((m_windowStyle & wxSYSTEM_MENU) == 0) decor |= GDK_DECOR_MENU; - if ((m_windowStyle & wxMINIMIZE_BOX) == 0) + if ((m_windowStyle & wxMINIMIZE_BOX) == 0) decor |= GDK_DECOR_MINIMIZE; - if ((m_windowStyle & wxMAXIMIZE_BOX) == 0) + if ((m_windowStyle & wxMAXIMIZE_BOX) == 0) decor |= GDK_DECOR_MAXIMIZE; - if ((m_windowStyle & wxRESIZE_BORDER) == 0) + if ((m_windowStyle & wxRESIZE_BORDER) == 0) func |= GDK_FUNC_RESIZE; - - gdk_window_set_decorations(m_widget->window, (GdkWMDecoration)decor); - gdk_window_set_functions(m_widget->window, (GdkWMFunction)func); + gdk_window_set_decorations(m_widget->window, (GdkWMDecoration)decor); + gdk_window_set_functions(m_widget->window, (GdkWMFunction)func); gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", GTK_SIGNAL_FUNC(gtk_dialog_size_callback), (gpointer)this ); @@ -257,17 +257,17 @@ void wxDialog::OnCloseWindow(wxCloseEvent& event) // sure to destroy the dialog. // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog. - static wxList closing; + static wxList s_closing; - if (closing.Member(this)) + if (s_closing.Member(this)) return; // no loops - closing.Append(this); + s_closing.Append(this); wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL); cancelEvent.SetEventObject( this ); GetEventHandler()->ProcessEvent(cancelEvent); - closing.DeleteObject(this); + s_closing.DeleteObject(this); } bool wxDialog::Destroy() diff --git a/src/gtk1/frame.cpp b/src/gtk1/frame.cpp index 06351fb9a2..e7b368139f 100644 --- a/src/gtk1/frame.cpp +++ b/src/gtk1/frame.cpp @@ -162,6 +162,7 @@ wxFrame::wxFrame() m_sizeSet = FALSE; m_miniEdge = 0; m_miniTitle = 0; + m_mainWidget = (GtkWidget*) NULL; } wxFrame::wxFrame( wxWindow *parent, wxWindowID id, const wxString &title, @@ -175,6 +176,7 @@ wxFrame::wxFrame( wxWindow *parent, wxWindowID id, const wxString &title, m_sizeSet = FALSE; m_miniEdge = 0; m_miniTitle = 0; + m_mainWidget = (GtkWidget*) NULL; Create( parent, id, title, pos, size, style, name ); } @@ -200,6 +202,7 @@ bool wxFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title, gtk_window_set_title( GTK_WINDOW(m_widget), title ); GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); + /* needed ? */ gtk_window_set_policy( GTK_WINDOW(m_widget), 1, 1, 0 ); gtk_signal_connect( GTK_OBJECT(m_widget), "delete_event", @@ -224,30 +227,32 @@ bool wxFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title, gtk_widget_realize( m_widget ); - long decor = (long) GDK_DECOR_ALL; - long func = (long) GDK_FUNC_ALL; - - if ((m_windowStyle & wxCAPTION) == 0) + /* all this is for Motif Window Manager "hints" and is supposed to be + recognized by other WM as well. not tested. */ + long decor = (long) GDK_DECOR_ALL; + long func = (long) GDK_FUNC_ALL; + if ((m_windowStyle & wxCAPTION) == 0) decor |= GDK_DECOR_TITLE; - if ((m_windowStyle & wxMINIMIZE) == 0) + if ((m_windowStyle & wxMINIMIZE) == 0) func |= GDK_FUNC_MINIMIZE; - if ((m_windowStyle & wxMAXIMIZE) == 0) + if ((m_windowStyle & wxMAXIMIZE) == 0) func |= GDK_FUNC_MAXIMIZE; - if ((m_windowStyle & wxSYSTEM_MENU) == 0) + if ((m_windowStyle & wxSYSTEM_MENU) == 0) decor |= GDK_DECOR_MENU; - if ((m_windowStyle & wxMINIMIZE_BOX) == 0) + if ((m_windowStyle & wxMINIMIZE_BOX) == 0) decor |= GDK_DECOR_MINIMIZE; - if ((m_windowStyle & wxMAXIMIZE_BOX) == 0) + if ((m_windowStyle & wxMAXIMIZE_BOX) == 0) decor |= GDK_DECOR_MAXIMIZE; - if ((m_windowStyle & wxRESIZE_BORDER) == 0) + if ((m_windowStyle & wxRESIZE_BORDER) == 0) func |= GDK_FUNC_RESIZE; - - gdk_window_set_decorations(m_widget->window, (GdkWMDecoration)decor); - gdk_window_set_functions(m_widget->window, (GdkWMFunction)func); + gdk_window_set_decorations(m_widget->window, (GdkWMDecoration)decor); + gdk_window_set_functions(m_widget->window, (GdkWMFunction)func); + /* the user resized the frame by dragging etc. */ gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", GTK_SIGNAL_FUNC(gtk_frame_size_callback), (gpointer)this ); + /* the only way to get the window size is to connect to this event */ gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event", GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this ); @@ -308,10 +313,11 @@ void wxFrame::DoSetSize( int x, int y, int width, int height, int sizeFlags ) { wxASSERT_MSG( (m_widget != NULL), "invalid frame" ); - /* don't do anything for children of wxMDIChildFrame */ - if (!m_wxwindow) return; - - if (m_resizing) return; // I don't like recursions + /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */ + wxASSERT_MSG( (m_wxwindow != NULL), "invalid frame" ); + + /* avoid recursions */ + if (m_resizing) return; m_resizing = TRUE; int old_x = m_x; @@ -360,7 +366,9 @@ void wxFrame::DoSetSize( int x, int y, int width, int height, int sizeFlags ) if ((m_width != old_width) || (m_height != old_height)) { - /* we set the size in GtkOnSize */ + /* we set the size in GtkOnSize, i.e. mostly the actual resizing is + done either directly before the frame is shown or in idle time + so that different calls to SetSize() don't lead to flicker. */ m_sizeSet = FALSE; } @@ -425,65 +433,79 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height // m_x = x; // m_y = y; + /* avoid recursions */ if (m_resizing) return; m_resizing = TRUE; - if (!m_wxwindow) return; - + /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */ + wxASSERT_MSG( (m_wxwindow != NULL), "invalid frame" ); + m_width = width; m_height = height; - /* check if size is in legal range */ - if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth; - if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight; - if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth; - if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight; - - /* I revert back to wxGTK's original behaviour. m_mainWidget holds the - * menubar, the toolbar and the client area, which is represented by - * m_wxwindow. - * this hurts in the eye, but I don't want to call SetSize() - * because I don't want to call any non-native functions here. */ - + /* space occupied by m_frameToolBar and m_frameMenuBar */ int client_area_y_offset = 0; - if (m_frameMenuBar) + /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses + wxWindow::Create to create it's GTK equivalent. m_mainWidget is only + set in wxFrame::Create so it is used to check what kind of frame we + have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we + skip the part which handles m_frameMenuBar, m_frameToolBar and (most + importantly) m_mainWidget */ + + if (m_mainWidget) { - int xx = m_miniEdge; - int yy = m_miniEdge + m_miniTitle; - int ww = m_width - 2*m_miniEdge; - int hh = wxMENU_HEIGHT; - m_frameMenuBar->m_x = xx; - m_frameMenuBar->m_y = yy; - m_frameMenuBar->m_width = ww; - m_frameMenuBar->m_height = hh; - - gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_frameMenuBar->m_widget, xx, yy ); - gtk_widget_set_usize( m_frameMenuBar->m_widget, ww, hh ); + /* check if size is in legal range */ + if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth; + if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight; + if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth; + if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight; + + /* I revert back to wxGTK's original behaviour. m_mainWidget holds the + * menubar, the toolbar and the client area, which is represented by + * m_wxwindow. + * this hurts in the eye, but I don't want to call SetSize() + * because I don't want to call any non-native functions here. */ + + if (m_frameMenuBar) + { + int xx = m_miniEdge; + int yy = m_miniEdge + m_miniTitle; + int ww = m_width - 2*m_miniEdge; + int hh = wxMENU_HEIGHT; + m_frameMenuBar->m_x = xx; + m_frameMenuBar->m_y = yy; + m_frameMenuBar->m_width = ww; + m_frameMenuBar->m_height = hh; + + gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_frameMenuBar->m_widget, xx, yy ); + gtk_widget_set_usize( m_frameMenuBar->m_widget, ww, hh ); - client_area_y_offset += hh; - } + client_area_y_offset += hh; + } - if (m_frameToolBar) - { - int xx = m_miniEdge; - int yy = m_miniEdge + m_miniTitle; - if ((m_frameMenuBar) || (m_mdiMenuBar)) yy += wxMENU_HEIGHT; - int ww = m_width - 2*m_miniEdge; - int hh = m_frameToolBar->m_height; - - m_frameToolBar->m_x = xx; - m_frameToolBar->m_y = yy; - m_frameToolBar->m_height = hh; - m_frameToolBar->m_width = ww; - - gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_frameToolBar->m_widget, xx, yy ); - gtk_widget_set_usize( m_frameToolBar->m_widget, ww, hh ); + if (m_frameToolBar) + { + int xx = m_miniEdge; + int yy = m_miniEdge + m_miniTitle; + if ((m_frameMenuBar) || (m_mdiMenuBar)) yy += wxMENU_HEIGHT; + int ww = m_width - 2*m_miniEdge; + int hh = m_frameToolBar->m_height; + + m_frameToolBar->m_x = xx; + m_frameToolBar->m_y = yy; + m_frameToolBar->m_height = hh; + m_frameToolBar->m_width = ww; + + gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_frameToolBar->m_widget, xx, yy ); + gtk_widget_set_usize( m_frameToolBar->m_widget, ww, hh ); - client_area_y_offset += hh; + client_area_y_offset += hh; + } + + gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_wxwindow, 0, client_area_y_offset ); } - gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_wxwindow, 0, client_area_y_offset ); gtk_widget_set_usize( m_wxwindow, m_width, m_height-client_area_y_offset ); if (m_frameStatusBar) @@ -533,8 +555,6 @@ void wxFrame::OnInternalIdle() void wxFrame::OnCloseWindow( wxCloseEvent& event ) { - // close the window if it wasn't vetoed by the application -// if ( !event.GetVeto() ) // No, this isn't the interpretation of GetVeto. Destroy(); } diff --git a/src/gtk1/mdi.cpp b/src/gtk1/mdi.cpp index e0b6d4aeca..82f5e1c260 100644 --- a/src/gtk1/mdi.cpp +++ b/src/gtk1/mdi.cpp @@ -33,48 +33,6 @@ const int wxMENU_HEIGHT = 27; extern wxList wxPendingDelete; -//----------------------------------------------------------------------------- -// "size_allocate" -//----------------------------------------------------------------------------- - -static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win ) -{ - if ((win->m_x == alloc->x) && - (win->m_y == alloc->y) && - (win->m_width == alloc->width) && - (win->m_height == alloc->height) && - (win->m_sizeSet)) - { - return; - } - - win->SetSize( alloc->x, alloc->y, alloc->width, alloc->height ); -} - -//----------------------------------------------------------------------------- -// "switch_page" -//----------------------------------------------------------------------------- - -static void gtk_page_change_callback( GtkNotebook *WXUNUSED(widget), - GtkNotebookPage *page, - gint WXUNUSED(nPage), - wxMDIClientWindow *client_win ) -{ - wxNode *node = client_win->m_children.First(); - while (node) - { - wxMDIChildFrame *child_frame = (wxMDIChildFrame *)node->Data(); - if (child_frame->m_page == page) - { - wxMDIParentFrame *mdi_frame = (wxMDIParentFrame*)client_win->m_parent; - mdi_frame->m_currentChild = child_frame; - mdi_frame->SetMDIMenuBar( child_frame->m_menuBar ); - return; - } - node = node->Next(); - } -} - //----------------------------------------------------------------------------- // wxMDIParentFrame //----------------------------------------------------------------------------- @@ -84,11 +42,10 @@ IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame,wxFrame) BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame) END_EVENT_TABLE() -wxMDIParentFrame::wxMDIParentFrame(void) +wxMDIParentFrame::wxMDIParentFrame() { + m_justInserted = FALSE; m_clientWindow = (wxMDIClientWindow *) NULL; - m_currentChild = (wxMDIChildFrame *) NULL; - m_parentFrameActive = TRUE; } wxMDIParentFrame::wxMDIParentFrame( wxWindow *parent, @@ -96,13 +53,12 @@ wxMDIParentFrame::wxMDIParentFrame( wxWindow *parent, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) { + m_justInserted = FALSE; m_clientWindow = (wxMDIClientWindow *) NULL; - m_currentChild = (wxMDIChildFrame *) NULL; - m_parentFrameActive = TRUE; Create( parent, id, title, pos, size, style, name ); } -wxMDIParentFrame::~wxMDIParentFrame(void) +wxMDIParentFrame::~wxMDIParentFrame() { } @@ -121,39 +77,58 @@ bool wxMDIParentFrame::Create( wxWindow *parent, void wxMDIParentFrame::GtkOnSize( int x, int y, int width, int height ) { wxFrame::GtkOnSize( x, y, width, height ); - - if (m_mdiMenuBar) + + wxMDIChildFrame *child_frame = GetActiveChild(); + if (!child_frame) return; + + wxMenuBar *menu_bar = child_frame->m_menuBar; + if (!menu_bar) return; + if (!menu_bar->m_widget) return; + + menu_bar->m_x = 0; + menu_bar->m_y = 0; + menu_bar->m_width = m_width; + menu_bar->m_height = wxMENU_HEIGHT; + gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), menu_bar->m_widget, 0, 0 ); + gtk_widget_set_usize( menu_bar->m_widget, m_width, wxMENU_HEIGHT ); +} + +void wxMDIParentFrame::OnInternalIdle() +{ + /* if a an MDI child window has just been inserted + it has to be brought to the top in idle time. we + simply set the last notebook page active as new + pages can only be appended at the end */ + + if (m_justInserted) { - m_mdiMenuBar->m_x = 0; - m_mdiMenuBar->m_y = 0; - m_mdiMenuBar->m_width = m_width; - m_mdiMenuBar->m_height = wxMENU_HEIGHT; - gtk_myfixed_move( GTK_MYFIXED(m_wxwindow), m_mdiMenuBar->m_widget, 0, 0 ); - gtk_widget_set_usize( m_mdiMenuBar->m_widget, m_width, wxMENU_HEIGHT ); + GtkNotebook *notebook = GTK_NOTEBOOK(m_clientWindow->m_widget); + gtk_notebook_set_page( notebook, g_list_length( notebook->children ) - 1 ); + + m_justInserted = FALSE; + return; } -} - -void wxMDIParentFrame::SetMDIMenuBar( wxMenuBar *menu_bar ) -{ - /* hide old child menu bar */ - if (m_mdiMenuBar) m_mdiMenuBar->Show( FALSE ); - - m_mdiMenuBar = menu_bar; + + wxFrame::OnInternalIdle(); - /* show and resize new menu child menu bar */ - if (m_mdiMenuBar) + wxMDIChildFrame *active_child_frame = GetActiveChild(); + + wxNode *node = m_clientWindow->m_children.First(); + while (node) { - m_mdiMenuBar->m_x = 0; - m_mdiMenuBar->m_y = 0; - m_mdiMenuBar->m_width = m_width; - m_mdiMenuBar->m_height = wxMENU_HEIGHT; - gtk_myfixed_move( GTK_MYFIXED(m_wxwindow), m_mdiMenuBar->m_widget, 0, 0 ); - gtk_widget_set_usize( m_mdiMenuBar->m_widget, m_width, wxMENU_HEIGHT ); - m_mdiMenuBar->Show( TRUE ); + wxMDIChildFrame *child_frame = (wxMDIChildFrame *)node->Data(); + if (child_frame->m_menuBar) + { + if (child_frame == active_child_frame) + gtk_widget_show( child_frame->m_menuBar->m_widget ); + else + gtk_widget_hide( child_frame->m_menuBar->m_widget ); + } + node = node->Next(); } - + /* show/hide parent menu bar as required */ - if (m_frameMenuBar) m_frameMenuBar->Show( (m_mdiMenuBar == NULL) ); + if (m_frameMenuBar) m_frameMenuBar->Show( (active_child_frame == NULL) ); } void wxMDIParentFrame::GetClientSize(int *width, int *height ) const @@ -161,29 +136,49 @@ void wxMDIParentFrame::GetClientSize(int *width, int *height ) const wxFrame::GetClientSize( width, height ); } -wxMDIChildFrame *wxMDIParentFrame::GetActiveChild(void) const -{ - return m_currentChild; +wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const +{ + if (!m_clientWindow) return (wxMDIChildFrame*) NULL; + + GtkNotebook *notebook = GTK_NOTEBOOK(m_clientWindow->m_widget); + if (!notebook) return (wxMDIChildFrame*) NULL; + + gint i = gtk_notebook_get_current_page( notebook ); + if (i < 0) return (wxMDIChildFrame*) NULL; + + GtkNotebookPage* page = (GtkNotebookPage*) (g_list_nth(notebook->children,i)->data); + if (!page) return (wxMDIChildFrame*) NULL; + + wxNode *node = m_clientWindow->m_children.First(); + while (node) + { + wxMDIChildFrame *child_frame = (wxMDIChildFrame *)node->Data(); + if (child_frame->m_page == page) + return child_frame; + node = node->Next(); + } + + return (wxMDIChildFrame*) NULL; } -wxMDIClientWindow *wxMDIParentFrame::GetClientWindow(void) const +wxMDIClientWindow *wxMDIParentFrame::GetClientWindow() const { return m_clientWindow; } -wxMDIClientWindow *wxMDIParentFrame::OnCreateClient(void) +wxMDIClientWindow *wxMDIParentFrame::OnCreateClient() { m_clientWindow = new wxMDIClientWindow( this ); return m_clientWindow; } -void wxMDIParentFrame::ActivateNext(void) +void wxMDIParentFrame::ActivateNext() { if (m_clientWindow) gtk_notebook_next_page( GTK_NOTEBOOK(m_clientWindow->m_widget) ); } -void wxMDIParentFrame::ActivatePrevious(void) +void wxMDIParentFrame::ActivatePrevious() { if (m_clientWindow) gtk_notebook_prev_page( GTK_NOTEBOOK(m_clientWindow->m_widget) ); @@ -207,7 +202,7 @@ BEGIN_EVENT_TABLE(wxMDIChildFrame, wxFrame) EVT_ACTIVATE(wxMDIChildFrame::OnActivate) END_EVENT_TABLE() -wxMDIChildFrame::wxMDIChildFrame(void) +wxMDIChildFrame::wxMDIChildFrame() { m_menuBar = (wxMenuBar *) NULL; m_page = (GtkNotebookPage *) NULL; @@ -223,18 +218,10 @@ wxMDIChildFrame::wxMDIChildFrame( wxMDIParentFrame *parent, Create( parent, id, title, wxDefaultPosition, size, style, name ); } -wxMDIChildFrame::~wxMDIChildFrame(void) +wxMDIChildFrame::~wxMDIChildFrame() { if (m_menuBar) - { - wxMDIParentFrame *mdi_frame = (wxMDIParentFrame*)m_parent->m_parent; - if (mdi_frame->m_currentChild == this) - { - mdi_frame->SetMDIMenuBar( (wxMenuBar *) NULL ); - mdi_frame->m_currentChild = (wxMDIChildFrame *) NULL; - } delete m_menuBar; - } } bool wxMDIChildFrame::Create( wxMDIParentFrame *parent, @@ -291,10 +278,12 @@ void wxMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar ) m_menuBar->m_parent = mdi_frame; } - gtk_myfixed_put( GTK_MYFIXED(mdi_frame->m_wxwindow), - m_menuBar->m_widget, m_menuBar->m_x, m_menuBar->m_y ); + /* the menu bar of the child window is shown in idle time as needed */ + gtk_widget_hide( m_menuBar->m_widget ); - mdi_frame->SetMDIMenuBar( m_menuBar ); + /* insert the invisible menu bar into the _parent_ mdi frame */ + gtk_myfixed_put( GTK_MYFIXED(mdi_frame->m_mainWidget), m_menuBar->m_widget, 0, 0 ); + gtk_widget_set_usize( menu_bar->m_widget, mdi_frame->m_width, wxMENU_HEIGHT ); } } @@ -303,7 +292,7 @@ wxMenuBar *wxMDIChildFrame::GetMenuBar() const return m_menuBar; } -void wxMDIChildFrame::Activate(void) +void wxMDIChildFrame::Activate() { } @@ -311,6 +300,24 @@ void wxMDIChildFrame::OnActivate( wxActivateEvent &WXUNUSED(event) ) { } +//----------------------------------------------------------------------------- +// "size_allocate" +//----------------------------------------------------------------------------- + +static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win ) +{ + if ((win->m_x == alloc->x) && + (win->m_y == alloc->y) && + (win->m_width == alloc->width) && + (win->m_height == alloc->height) && + (win->m_sizeSet)) + { + return; + } + + win->SetSize( alloc->x, alloc->y, alloc->width, alloc->height ); +} + //----------------------------------------------------------------------------- // InsertChild callback for wxMDIClientWindow //----------------------------------------------------------------------------- @@ -331,10 +338,9 @@ static void wxInsertChildInMDI( wxMDIClientWindow* parent, wxMDIChildFrame* chil gtk_notebook_append_page( notebook, child->m_widget, label_widget ); child->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data); - - gtk_notebook_set_page( notebook, parent->m_children.Number()-1 ); - - gtk_page_change_callback( (GtkNotebook *) NULL, child->m_page, 0, parent ); + + wxMDIParentFrame *parent_frame = (wxMDIParentFrame*) parent->m_parent; + parent_frame->m_justInserted = TRUE; } //----------------------------------------------------------------------------- @@ -343,7 +349,7 @@ static void wxInsertChildInMDI( wxMDIClientWindow* parent, wxMDIChildFrame* chil IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow,wxWindow) -wxMDIClientWindow::wxMDIClientWindow(void) +wxMDIClientWindow::wxMDIClientWindow() { } @@ -352,7 +358,7 @@ wxMDIClientWindow::wxMDIClientWindow( wxMDIParentFrame *parent, long style ) CreateClient( parent, style ); } -wxMDIClientWindow::~wxMDIClientWindow(void) +wxMDIClientWindow::~wxMDIClientWindow() { } @@ -366,9 +372,6 @@ bool wxMDIClientWindow::CreateClient( wxMDIParentFrame *parent, long style ) m_widget = gtk_notebook_new(); - gtk_signal_connect( GTK_OBJECT(m_widget), "switch_page", - GTK_SIGNAL_FUNC(gtk_page_change_callback), (gpointer)this ); - gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 ); m_parent->AddChild( this ); -- 2.47.2