Rewrote MDI system

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2090 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling 1999-04-11 22:43:52 +00:00
parent 53b7ce7ef8
commit ab2b3dd4a2
10 changed files with 468 additions and 432 deletions

View File

@ -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 );
virtual void GtkOnSize( int x, int y, int width, int height );
private:
wxMDIClientWindow *m_clientWindow;
bool m_parentFrameActive;
// implementation
wxMDIClientWindow *m_clientWindow;
bool m_justInserted;
virtual void GtkOnSize( int x, int y, int width, int height );
virtual void OnInternalIdle();
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 );

View File

@ -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();

View File

@ -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 );
virtual void GtkOnSize( int x, int y, int width, int height );
private:
wxMDIClientWindow *m_clientWindow;
bool m_parentFrameActive;
// implementation
wxMDIClientWindow *m_clientWindow;
bool m_justInserted;
virtual void GtkOnSize( int x, int y, int width, int height );
virtual void OnInternalIdle();
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 );

View File

@ -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();

View File

@ -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()

View File

@ -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;
/* 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;
gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_frameMenuBar->m_widget, xx, yy );
gtk_widget_set_usize( m_frameMenuBar->m_widget, ww, hh );
/* 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 );
client_area_y_offset += hh;
}
gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_wxwindow, 0, client_area_y_offset );
}
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;
}
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();
}

View File

@ -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)
{
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 );
}
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::SetMDIMenuBar( wxMenuBar *menu_bar )
void wxMDIParentFrame::OnInternalIdle()
{
/* hide old child menu bar */
if (m_mdiMenuBar) m_mdiMenuBar->Show( FALSE );
/* 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 */
m_mdiMenuBar = menu_bar;
/* show and resize new menu child menu bar */
if (m_mdiMenuBar)
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 );
m_mdiMenuBar->Show( TRUE );
GtkNotebook *notebook = GTK_NOTEBOOK(m_clientWindow->m_widget);
gtk_notebook_set_page( notebook, g_list_length( notebook->children ) - 1 );
m_justInserted = FALSE;
return;
}
wxFrame::OnInternalIdle();
wxMDIChildFrame *active_child_frame = GetActiveChild();
wxNode *node = m_clientWindow->m_children.First();
while (node)
{
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
wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const
{
return m_currentChild;
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 );

View File

@ -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()

View File

@ -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;
/* 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;
gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_frameMenuBar->m_widget, xx, yy );
gtk_widget_set_usize( m_frameMenuBar->m_widget, ww, hh );
/* 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 );
client_area_y_offset += hh;
}
gtk_myfixed_move( GTK_MYFIXED(m_mainWidget), m_wxwindow, 0, client_area_y_offset );
}
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;
}
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();
}

View File

@ -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)
{
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 );
}
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::SetMDIMenuBar( wxMenuBar *menu_bar )
void wxMDIParentFrame::OnInternalIdle()
{
/* hide old child menu bar */
if (m_mdiMenuBar) m_mdiMenuBar->Show( FALSE );
/* 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 */
m_mdiMenuBar = menu_bar;
/* show and resize new menu child menu bar */
if (m_mdiMenuBar)
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 );
m_mdiMenuBar->Show( TRUE );
GtkNotebook *notebook = GTK_NOTEBOOK(m_clientWindow->m_widget);
gtk_notebook_set_page( notebook, g_list_length( notebook->children ) - 1 );
m_justInserted = FALSE;
return;
}
wxFrame::OnInternalIdle();
wxMDIChildFrame *active_child_frame = GetActiveChild();
wxNode *node = m_clientWindow->m_children.First();
while (node)
{
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
wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const
{
return m_currentChild;
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 );