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; friend class wxMDIChildFrame;
public: public:
wxMDIParentFrame(void); wxMDIParentFrame(void);
wxMDIParentFrame( wxWindow *parent, wxMDIParentFrame( wxWindow *parent,
@@ -65,31 +65,27 @@ class wxMDIParentFrame: public wxFrame
void GetClientSize(int *width, int *height) const; void GetClientSize(int *width, int *height) const;
wxMDIChildFrame *GetActiveChild(void) const; wxMDIChildFrame *GetActiveChild() const;
wxMDIClientWindow *GetClientWindow(void) const; wxMDIClientWindow *GetClientWindow() const;
virtual wxMDIClientWindow *OnCreateClient(void); virtual wxMDIClientWindow *OnCreateClient();
virtual void Cascade(void) {}; virtual void Cascade() {}
virtual void Tile(void) {}; virtual void Tile() {}
virtual void ArrangeIcons(void) {}; virtual void ArrangeIcons() {}
virtual void ActivateNext(void); virtual void ActivateNext();
virtual void ActivatePrevious(void); virtual void ActivatePrevious();
void OnActivate( wxActivateEvent& event ); void OnActivate( wxActivateEvent& event );
void OnSysColourChanged( wxSysColourChangedEvent& event ); void OnSysColourChanged( wxSysColourChangedEvent& event );
// implementation // implementation
wxMDIChildFrame *m_currentChild; wxMDIClientWindow *m_clientWindow;
bool m_justInserted;
void SetMDIMenuBar( wxMenuBar *menu_bar );
virtual void GtkOnSize( int x, int y, int width, int height ); virtual void GtkOnSize( int x, int y, int width, int height );
virtual void OnInternalIdle();
private:
wxMDIClientWindow *m_clientWindow;
bool m_parentFrameActive;
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
@@ -104,7 +100,7 @@ class wxMDIChildFrame: public wxFrame
public: public:
wxMDIChildFrame(void); wxMDIChildFrame();
wxMDIChildFrame( wxMDIParentFrame *parent, wxMDIChildFrame( wxMDIParentFrame *parent,
wxWindowID id, const wxString& title, wxWindowID id, const wxString& title,
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, 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 GetClientSize( int *width, int *height ) const;
virtual void AddChild( wxWindow *child ); virtual void AddChild( wxWindow *child );
virtual void Activate(void); virtual void Activate();
// no status bars // no status bars
virtual wxStatusBar* CreateStatusBar( int WXUNUSED(number)=1, long WXUNUSED(style)=1, 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; } wxString GetTitle() const { return m_title; }
// no maximize etc // no maximize etc
virtual void Maximize(bool WXUNUSED(maximize)) {} virtual void Maximize( bool WXUNUSED(maximize) ) {}
virtual void Restore(void) {} virtual void Restore() {}
void OnActivate( wxActivateEvent &event ); void OnActivate( wxActivateEvent &event );
public: // implementation
wxMenuBar *m_menuBar; wxMenuBar *m_menuBar;
// private:
GtkNotebookPage *m_page; GtkNotebookPage *m_page;
bool m_justInserted;
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
@@ -174,7 +168,7 @@ class wxMDIClientWindow: public wxWindow
{ {
DECLARE_DYNAMIC_CLASS(wxMDIClientWindow) DECLARE_DYNAMIC_CLASS(wxMDIClientWindow)
public: public:
wxMDIClientWindow(void); wxMDIClientWindow(void);
wxMDIClientWindow( wxMDIParentFrame *parent, long style = 0 ); wxMDIClientWindow( wxMDIParentFrame *parent, long style = 0 );

View File

@@ -405,14 +405,15 @@ public:
bool HasVMT(); 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(); virtual void OnInternalIdle();
/* For compatibility across platforms (not in event table) */ /* For compatibility across platforms (not in event table) */
void OnIdle(wxIdleEvent& WXUNUSED(event)) {}; void OnIdle(wxIdleEvent& WXUNUSED(event)) {};
/* used by all classes in the widget creation process */ /* used by all classes in the widget creation process */
void PreCreation( wxWindow *parent, wxWindowID id, const wxPoint &pos, void PreCreation( wxWindow *parent, wxWindowID id, const wxPoint &pos,
const wxSize &size, long style, const wxString &name ); const wxSize &size, long style, const wxString &name );
void PostCreation(); void PostCreation();

View File

@@ -48,7 +48,7 @@ class wxMDIParentFrame: public wxFrame
friend class wxMDIChildFrame; friend class wxMDIChildFrame;
public: public:
wxMDIParentFrame(void); wxMDIParentFrame(void);
wxMDIParentFrame( wxWindow *parent, wxMDIParentFrame( wxWindow *parent,
@@ -65,31 +65,27 @@ class wxMDIParentFrame: public wxFrame
void GetClientSize(int *width, int *height) const; void GetClientSize(int *width, int *height) const;
wxMDIChildFrame *GetActiveChild(void) const; wxMDIChildFrame *GetActiveChild() const;
wxMDIClientWindow *GetClientWindow(void) const; wxMDIClientWindow *GetClientWindow() const;
virtual wxMDIClientWindow *OnCreateClient(void); virtual wxMDIClientWindow *OnCreateClient();
virtual void Cascade(void) {}; virtual void Cascade() {}
virtual void Tile(void) {}; virtual void Tile() {}
virtual void ArrangeIcons(void) {}; virtual void ArrangeIcons() {}
virtual void ActivateNext(void); virtual void ActivateNext();
virtual void ActivatePrevious(void); virtual void ActivatePrevious();
void OnActivate( wxActivateEvent& event ); void OnActivate( wxActivateEvent& event );
void OnSysColourChanged( wxSysColourChangedEvent& event ); void OnSysColourChanged( wxSysColourChangedEvent& event );
// implementation // implementation
wxMDIChildFrame *m_currentChild; wxMDIClientWindow *m_clientWindow;
bool m_justInserted;
void SetMDIMenuBar( wxMenuBar *menu_bar );
virtual void GtkOnSize( int x, int y, int width, int height ); virtual void GtkOnSize( int x, int y, int width, int height );
virtual void OnInternalIdle();
private:
wxMDIClientWindow *m_clientWindow;
bool m_parentFrameActive;
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
@@ -104,7 +100,7 @@ class wxMDIChildFrame: public wxFrame
public: public:
wxMDIChildFrame(void); wxMDIChildFrame();
wxMDIChildFrame( wxMDIParentFrame *parent, wxMDIChildFrame( wxMDIParentFrame *parent,
wxWindowID id, const wxString& title, wxWindowID id, const wxString& title,
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, 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 GetClientSize( int *width, int *height ) const;
virtual void AddChild( wxWindow *child ); virtual void AddChild( wxWindow *child );
virtual void Activate(void); virtual void Activate();
// no status bars // no status bars
virtual wxStatusBar* CreateStatusBar( int WXUNUSED(number)=1, long WXUNUSED(style)=1, 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; } wxString GetTitle() const { return m_title; }
// no maximize etc // no maximize etc
virtual void Maximize(bool WXUNUSED(maximize)) {} virtual void Maximize( bool WXUNUSED(maximize) ) {}
virtual void Restore(void) {} virtual void Restore() {}
void OnActivate( wxActivateEvent &event ); void OnActivate( wxActivateEvent &event );
public: // implementation
wxMenuBar *m_menuBar; wxMenuBar *m_menuBar;
// private:
GtkNotebookPage *m_page; GtkNotebookPage *m_page;
bool m_justInserted;
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
@@ -174,7 +168,7 @@ class wxMDIClientWindow: public wxWindow
{ {
DECLARE_DYNAMIC_CLASS(wxMDIClientWindow) DECLARE_DYNAMIC_CLASS(wxMDIClientWindow)
public: public:
wxMDIClientWindow(void); wxMDIClientWindow(void);
wxMDIClientWindow( wxMDIParentFrame *parent, long style = 0 ); wxMDIClientWindow( wxMDIParentFrame *parent, long style = 0 );

View File

@@ -405,14 +405,15 @@ public:
bool HasVMT(); 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(); virtual void OnInternalIdle();
/* For compatibility across platforms (not in event table) */ /* For compatibility across platforms (not in event table) */
void OnIdle(wxIdleEvent& WXUNUSED(event)) {}; void OnIdle(wxIdleEvent& WXUNUSED(event)) {};
/* used by all classes in the widget creation process */ /* used by all classes in the widget creation process */
void PreCreation( wxWindow *parent, wxWindowID id, const wxPoint &pos, void PreCreation( wxWindow *parent, wxWindowID id, const wxPoint &pos,
const wxSize &size, long style, const wxString &name ); const wxSize &size, long style, const wxString &name );
void PostCreation(); void PostCreation();

View File

@@ -145,26 +145,26 @@ bool wxDialog::Create( wxWindow *parent,
gtk_widget_realize( m_widget ); gtk_widget_realize( m_widget );
long decor = (long) GDK_DECOR_ALL; /* comments see wxFrame */
long func = (long) GDK_FUNC_ALL;
if ((m_windowStyle & wxCAPTION) == 0) long decor = (long) GDK_DECOR_ALL;
long func = (long) GDK_FUNC_ALL;
if ((m_windowStyle & wxCAPTION) == 0)
decor |= GDK_DECOR_TITLE; decor |= GDK_DECOR_TITLE;
if ((m_windowStyle & wxMINIMIZE) == 0) if ((m_windowStyle & wxMINIMIZE) == 0)
func |= GDK_FUNC_MINIMIZE; func |= GDK_FUNC_MINIMIZE;
if ((m_windowStyle & wxMAXIMIZE) == 0) if ((m_windowStyle & wxMAXIMIZE) == 0)
func |= GDK_FUNC_MAXIMIZE; func |= GDK_FUNC_MAXIMIZE;
if ((m_windowStyle & wxSYSTEM_MENU) == 0) if ((m_windowStyle & wxSYSTEM_MENU) == 0)
decor |= GDK_DECOR_MENU; decor |= GDK_DECOR_MENU;
if ((m_windowStyle & wxMINIMIZE_BOX) == 0) if ((m_windowStyle & wxMINIMIZE_BOX) == 0)
decor |= GDK_DECOR_MINIMIZE; decor |= GDK_DECOR_MINIMIZE;
if ((m_windowStyle & wxMAXIMIZE_BOX) == 0) if ((m_windowStyle & wxMAXIMIZE_BOX) == 0)
decor |= GDK_DECOR_MAXIMIZE; decor |= GDK_DECOR_MAXIMIZE;
if ((m_windowStyle & wxRESIZE_BORDER) == 0) if ((m_windowStyle & wxRESIZE_BORDER) == 0)
func |= GDK_FUNC_RESIZE; func |= GDK_FUNC_RESIZE;
gdk_window_set_decorations(m_widget->window, (GdkWMDecoration)decor);
gdk_window_set_decorations(m_widget->window, (GdkWMDecoration)decor); gdk_window_set_functions(m_widget->window, (GdkWMFunction)func);
gdk_window_set_functions(m_widget->window, (GdkWMFunction)func);
gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate",
GTK_SIGNAL_FUNC(gtk_dialog_size_callback), (gpointer)this ); GTK_SIGNAL_FUNC(gtk_dialog_size_callback), (gpointer)this );
@@ -257,17 +257,17 @@ void wxDialog::OnCloseWindow(wxCloseEvent& event)
// sure to destroy the dialog. // sure to destroy the dialog.
// The default OnCancel (above) simply ends a modal dialog, and hides a modeless 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 return; // no loops
closing.Append(this); s_closing.Append(this);
wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL); wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
cancelEvent.SetEventObject( this ); cancelEvent.SetEventObject( this );
GetEventHandler()->ProcessEvent(cancelEvent); GetEventHandler()->ProcessEvent(cancelEvent);
closing.DeleteObject(this); s_closing.DeleteObject(this);
} }
bool wxDialog::Destroy() bool wxDialog::Destroy()

View File

@@ -162,6 +162,7 @@ wxFrame::wxFrame()
m_sizeSet = FALSE; m_sizeSet = FALSE;
m_miniEdge = 0; m_miniEdge = 0;
m_miniTitle = 0; m_miniTitle = 0;
m_mainWidget = (GtkWidget*) NULL;
} }
wxFrame::wxFrame( wxWindow *parent, wxWindowID id, const wxString &title, 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_sizeSet = FALSE;
m_miniEdge = 0; m_miniEdge = 0;
m_miniTitle = 0; m_miniTitle = 0;
m_mainWidget = (GtkWidget*) NULL;
Create( parent, id, title, pos, size, style, name ); 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_window_set_title( GTK_WINDOW(m_widget), title );
GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
/* needed ? */
gtk_window_set_policy( GTK_WINDOW(m_widget), 1, 1, 0 ); gtk_window_set_policy( GTK_WINDOW(m_widget), 1, 1, 0 );
gtk_signal_connect( GTK_OBJECT(m_widget), "delete_event", 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 ); gtk_widget_realize( m_widget );
long decor = (long) GDK_DECOR_ALL; /* all this is for Motif Window Manager "hints" and is supposed to be
long func = (long) GDK_FUNC_ALL; recognized by other WM as well. not tested. */
long decor = (long) GDK_DECOR_ALL;
if ((m_windowStyle & wxCAPTION) == 0) long func = (long) GDK_FUNC_ALL;
if ((m_windowStyle & wxCAPTION) == 0)
decor |= GDK_DECOR_TITLE; decor |= GDK_DECOR_TITLE;
if ((m_windowStyle & wxMINIMIZE) == 0) if ((m_windowStyle & wxMINIMIZE) == 0)
func |= GDK_FUNC_MINIMIZE; func |= GDK_FUNC_MINIMIZE;
if ((m_windowStyle & wxMAXIMIZE) == 0) if ((m_windowStyle & wxMAXIMIZE) == 0)
func |= GDK_FUNC_MAXIMIZE; func |= GDK_FUNC_MAXIMIZE;
if ((m_windowStyle & wxSYSTEM_MENU) == 0) if ((m_windowStyle & wxSYSTEM_MENU) == 0)
decor |= GDK_DECOR_MENU; decor |= GDK_DECOR_MENU;
if ((m_windowStyle & wxMINIMIZE_BOX) == 0) if ((m_windowStyle & wxMINIMIZE_BOX) == 0)
decor |= GDK_DECOR_MINIMIZE; decor |= GDK_DECOR_MINIMIZE;
if ((m_windowStyle & wxMAXIMIZE_BOX) == 0) if ((m_windowStyle & wxMAXIMIZE_BOX) == 0)
decor |= GDK_DECOR_MAXIMIZE; decor |= GDK_DECOR_MAXIMIZE;
if ((m_windowStyle & wxRESIZE_BORDER) == 0) if ((m_windowStyle & wxRESIZE_BORDER) == 0)
func |= GDK_FUNC_RESIZE; 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); /* the user resized the frame by dragging etc. */
gdk_window_set_functions(m_widget->window, (GdkWMFunction)func);
gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate",
GTK_SIGNAL_FUNC(gtk_frame_size_callback), (gpointer)this ); 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_connect( GTK_OBJECT(m_widget), "configure_event",
GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this ); 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" ); wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
/* don't do anything for children of wxMDIChildFrame */ /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
if (!m_wxwindow) return; wxASSERT_MSG( (m_wxwindow != NULL), "invalid frame" );
if (m_resizing) return; // I don't like recursions /* avoid recursions */
if (m_resizing) return;
m_resizing = TRUE; m_resizing = TRUE;
int old_x = m_x; 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)) 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; m_sizeSet = FALSE;
} }
@@ -425,65 +433,79 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height
// m_x = x; // m_x = x;
// m_y = y; // m_y = y;
/* avoid recursions */
if (m_resizing) return; if (m_resizing) return;
m_resizing = TRUE; 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_width = width;
m_height = height; m_height = height;
/* check if size is in legal range */ /* space occupied by m_frameToolBar and m_frameMenuBar */
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. */
int client_area_y_offset = 0; 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; /* check if size is in legal range */
int yy = m_miniEdge + m_miniTitle; if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
int ww = m_width - 2*m_miniEdge; if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
int hh = wxMENU_HEIGHT; if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
m_frameMenuBar->m_x = xx; if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
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 ); /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
gtk_widget_set_usize( m_frameMenuBar->m_widget, ww, hh ); * 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. */
client_area_y_offset += hh; 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;
}
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 ); gtk_widget_set_usize( m_wxwindow, m_width, m_height-client_area_y_offset );
if (m_frameStatusBar) if (m_frameStatusBar)
@@ -533,8 +555,6 @@ void wxFrame::OnInternalIdle()
void wxFrame::OnCloseWindow( wxCloseEvent& event ) 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(); Destroy();
} }

View File

@@ -33,48 +33,6 @@ const int wxMENU_HEIGHT = 27;
extern wxList wxPendingDelete; 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 // wxMDIParentFrame
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -84,11 +42,10 @@ IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame,wxFrame)
BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame) BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame)
END_EVENT_TABLE() END_EVENT_TABLE()
wxMDIParentFrame::wxMDIParentFrame(void) wxMDIParentFrame::wxMDIParentFrame()
{ {
m_justInserted = FALSE;
m_clientWindow = (wxMDIClientWindow *) NULL; m_clientWindow = (wxMDIClientWindow *) NULL;
m_currentChild = (wxMDIChildFrame *) NULL;
m_parentFrameActive = TRUE;
} }
wxMDIParentFrame::wxMDIParentFrame( wxWindow *parent, wxMDIParentFrame::wxMDIParentFrame( wxWindow *parent,
@@ -96,13 +53,12 @@ wxMDIParentFrame::wxMDIParentFrame( wxWindow *parent,
const wxPoint& pos, const wxSize& size, const wxPoint& pos, const wxSize& size,
long style, const wxString& name ) long style, const wxString& name )
{ {
m_justInserted = FALSE;
m_clientWindow = (wxMDIClientWindow *) NULL; m_clientWindow = (wxMDIClientWindow *) NULL;
m_currentChild = (wxMDIChildFrame *) NULL;
m_parentFrameActive = TRUE;
Create( parent, id, title, pos, size, style, name ); Create( parent, id, title, pos, size, style, name );
} }
wxMDIParentFrame::~wxMDIParentFrame(void) wxMDIParentFrame::~wxMDIParentFrame()
{ {
} }
@@ -122,38 +78,57 @@ void wxMDIParentFrame::GtkOnSize( int x, int y, int width, int height )
{ {
wxFrame::GtkOnSize( x, y, width, height ); wxFrame::GtkOnSize( x, y, width, height );
if (m_mdiMenuBar) wxMDIChildFrame *child_frame = GetActiveChild();
{ if (!child_frame) return;
m_mdiMenuBar->m_x = 0;
m_mdiMenuBar->m_y = 0; wxMenuBar *menu_bar = child_frame->m_menuBar;
m_mdiMenuBar->m_width = m_width; if (!menu_bar) return;
m_mdiMenuBar->m_height = wxMENU_HEIGHT; if (!menu_bar->m_widget) return;
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 ); 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 a an MDI child window has just been inserted
if (m_mdiMenuBar) m_mdiMenuBar->Show( FALSE ); 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; if (m_justInserted)
/* show and resize new menu child menu bar */
if (m_mdiMenuBar)
{ {
m_mdiMenuBar->m_x = 0; GtkNotebook *notebook = GTK_NOTEBOOK(m_clientWindow->m_widget);
m_mdiMenuBar->m_y = 0; gtk_notebook_set_page( notebook, g_list_length( notebook->children ) - 1 );
m_mdiMenuBar->m_width = m_width;
m_mdiMenuBar->m_height = wxMENU_HEIGHT; m_justInserted = FALSE;
gtk_myfixed_move( GTK_MYFIXED(m_wxwindow), m_mdiMenuBar->m_widget, 0, 0 ); return;
gtk_widget_set_usize( m_mdiMenuBar->m_widget, m_width, wxMENU_HEIGHT ); }
m_mdiMenuBar->Show( TRUE );
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 */ /* 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 void wxMDIParentFrame::GetClientSize(int *width, int *height ) const
@@ -161,29 +136,49 @@ void wxMDIParentFrame::GetClientSize(int *width, int *height ) const
wxFrame::GetClientSize( width, height ); 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; return m_clientWindow;
} }
wxMDIClientWindow *wxMDIParentFrame::OnCreateClient(void) wxMDIClientWindow *wxMDIParentFrame::OnCreateClient()
{ {
m_clientWindow = new wxMDIClientWindow( this ); m_clientWindow = new wxMDIClientWindow( this );
return m_clientWindow; return m_clientWindow;
} }
void wxMDIParentFrame::ActivateNext(void) void wxMDIParentFrame::ActivateNext()
{ {
if (m_clientWindow) if (m_clientWindow)
gtk_notebook_next_page( GTK_NOTEBOOK(m_clientWindow->m_widget) ); gtk_notebook_next_page( GTK_NOTEBOOK(m_clientWindow->m_widget) );
} }
void wxMDIParentFrame::ActivatePrevious(void) void wxMDIParentFrame::ActivatePrevious()
{ {
if (m_clientWindow) if (m_clientWindow)
gtk_notebook_prev_page( GTK_NOTEBOOK(m_clientWindow->m_widget) ); gtk_notebook_prev_page( GTK_NOTEBOOK(m_clientWindow->m_widget) );
@@ -207,7 +202,7 @@ BEGIN_EVENT_TABLE(wxMDIChildFrame, wxFrame)
EVT_ACTIVATE(wxMDIChildFrame::OnActivate) EVT_ACTIVATE(wxMDIChildFrame::OnActivate)
END_EVENT_TABLE() END_EVENT_TABLE()
wxMDIChildFrame::wxMDIChildFrame(void) wxMDIChildFrame::wxMDIChildFrame()
{ {
m_menuBar = (wxMenuBar *) NULL; m_menuBar = (wxMenuBar *) NULL;
m_page = (GtkNotebookPage *) NULL; m_page = (GtkNotebookPage *) NULL;
@@ -223,18 +218,10 @@ wxMDIChildFrame::wxMDIChildFrame( wxMDIParentFrame *parent,
Create( parent, id, title, wxDefaultPosition, size, style, name ); Create( parent, id, title, wxDefaultPosition, size, style, name );
} }
wxMDIChildFrame::~wxMDIChildFrame(void) wxMDIChildFrame::~wxMDIChildFrame()
{ {
if (m_menuBar) 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; delete m_menuBar;
}
} }
bool wxMDIChildFrame::Create( wxMDIParentFrame *parent, bool wxMDIChildFrame::Create( wxMDIParentFrame *parent,
@@ -291,10 +278,12 @@ void wxMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar )
m_menuBar->m_parent = mdi_frame; m_menuBar->m_parent = mdi_frame;
} }
gtk_myfixed_put( GTK_MYFIXED(mdi_frame->m_wxwindow), /* the menu bar of the child window is shown in idle time as needed */
m_menuBar->m_widget, m_menuBar->m_x, m_menuBar->m_y ); 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; 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 // InsertChild callback for wxMDIClientWindow
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -332,9 +339,8 @@ static void wxInsertChildInMDI( wxMDIClientWindow* parent, wxMDIChildFrame* chil
child->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data); child->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data);
gtk_notebook_set_page( notebook, parent->m_children.Number()-1 ); wxMDIParentFrame *parent_frame = (wxMDIParentFrame*) parent->m_parent;
parent_frame->m_justInserted = TRUE;
gtk_page_change_callback( (GtkNotebook *) NULL, child->m_page, 0, parent );
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -343,7 +349,7 @@ static void wxInsertChildInMDI( wxMDIClientWindow* parent, wxMDIChildFrame* chil
IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow,wxWindow) IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow,wxWindow)
wxMDIClientWindow::wxMDIClientWindow(void) wxMDIClientWindow::wxMDIClientWindow()
{ {
} }
@@ -352,7 +358,7 @@ wxMDIClientWindow::wxMDIClientWindow( wxMDIParentFrame *parent, long style )
CreateClient( parent, 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(); 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 ); gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 );
m_parent->AddChild( this ); m_parent->AddChild( this );

View File

@@ -145,26 +145,26 @@ bool wxDialog::Create( wxWindow *parent,
gtk_widget_realize( m_widget ); gtk_widget_realize( m_widget );
long decor = (long) GDK_DECOR_ALL; /* comments see wxFrame */
long func = (long) GDK_FUNC_ALL;
if ((m_windowStyle & wxCAPTION) == 0) long decor = (long) GDK_DECOR_ALL;
long func = (long) GDK_FUNC_ALL;
if ((m_windowStyle & wxCAPTION) == 0)
decor |= GDK_DECOR_TITLE; decor |= GDK_DECOR_TITLE;
if ((m_windowStyle & wxMINIMIZE) == 0) if ((m_windowStyle & wxMINIMIZE) == 0)
func |= GDK_FUNC_MINIMIZE; func |= GDK_FUNC_MINIMIZE;
if ((m_windowStyle & wxMAXIMIZE) == 0) if ((m_windowStyle & wxMAXIMIZE) == 0)
func |= GDK_FUNC_MAXIMIZE; func |= GDK_FUNC_MAXIMIZE;
if ((m_windowStyle & wxSYSTEM_MENU) == 0) if ((m_windowStyle & wxSYSTEM_MENU) == 0)
decor |= GDK_DECOR_MENU; decor |= GDK_DECOR_MENU;
if ((m_windowStyle & wxMINIMIZE_BOX) == 0) if ((m_windowStyle & wxMINIMIZE_BOX) == 0)
decor |= GDK_DECOR_MINIMIZE; decor |= GDK_DECOR_MINIMIZE;
if ((m_windowStyle & wxMAXIMIZE_BOX) == 0) if ((m_windowStyle & wxMAXIMIZE_BOX) == 0)
decor |= GDK_DECOR_MAXIMIZE; decor |= GDK_DECOR_MAXIMIZE;
if ((m_windowStyle & wxRESIZE_BORDER) == 0) if ((m_windowStyle & wxRESIZE_BORDER) == 0)
func |= GDK_FUNC_RESIZE; func |= GDK_FUNC_RESIZE;
gdk_window_set_decorations(m_widget->window, (GdkWMDecoration)decor);
gdk_window_set_decorations(m_widget->window, (GdkWMDecoration)decor); gdk_window_set_functions(m_widget->window, (GdkWMFunction)func);
gdk_window_set_functions(m_widget->window, (GdkWMFunction)func);
gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate",
GTK_SIGNAL_FUNC(gtk_dialog_size_callback), (gpointer)this ); GTK_SIGNAL_FUNC(gtk_dialog_size_callback), (gpointer)this );
@@ -257,17 +257,17 @@ void wxDialog::OnCloseWindow(wxCloseEvent& event)
// sure to destroy the dialog. // sure to destroy the dialog.
// The default OnCancel (above) simply ends a modal dialog, and hides a modeless 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 return; // no loops
closing.Append(this); s_closing.Append(this);
wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL); wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
cancelEvent.SetEventObject( this ); cancelEvent.SetEventObject( this );
GetEventHandler()->ProcessEvent(cancelEvent); GetEventHandler()->ProcessEvent(cancelEvent);
closing.DeleteObject(this); s_closing.DeleteObject(this);
} }
bool wxDialog::Destroy() bool wxDialog::Destroy()

View File

@@ -162,6 +162,7 @@ wxFrame::wxFrame()
m_sizeSet = FALSE; m_sizeSet = FALSE;
m_miniEdge = 0; m_miniEdge = 0;
m_miniTitle = 0; m_miniTitle = 0;
m_mainWidget = (GtkWidget*) NULL;
} }
wxFrame::wxFrame( wxWindow *parent, wxWindowID id, const wxString &title, 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_sizeSet = FALSE;
m_miniEdge = 0; m_miniEdge = 0;
m_miniTitle = 0; m_miniTitle = 0;
m_mainWidget = (GtkWidget*) NULL;
Create( parent, id, title, pos, size, style, name ); 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_window_set_title( GTK_WINDOW(m_widget), title );
GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
/* needed ? */
gtk_window_set_policy( GTK_WINDOW(m_widget), 1, 1, 0 ); gtk_window_set_policy( GTK_WINDOW(m_widget), 1, 1, 0 );
gtk_signal_connect( GTK_OBJECT(m_widget), "delete_event", 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 ); gtk_widget_realize( m_widget );
long decor = (long) GDK_DECOR_ALL; /* all this is for Motif Window Manager "hints" and is supposed to be
long func = (long) GDK_FUNC_ALL; recognized by other WM as well. not tested. */
long decor = (long) GDK_DECOR_ALL;
if ((m_windowStyle & wxCAPTION) == 0) long func = (long) GDK_FUNC_ALL;
if ((m_windowStyle & wxCAPTION) == 0)
decor |= GDK_DECOR_TITLE; decor |= GDK_DECOR_TITLE;
if ((m_windowStyle & wxMINIMIZE) == 0) if ((m_windowStyle & wxMINIMIZE) == 0)
func |= GDK_FUNC_MINIMIZE; func |= GDK_FUNC_MINIMIZE;
if ((m_windowStyle & wxMAXIMIZE) == 0) if ((m_windowStyle & wxMAXIMIZE) == 0)
func |= GDK_FUNC_MAXIMIZE; func |= GDK_FUNC_MAXIMIZE;
if ((m_windowStyle & wxSYSTEM_MENU) == 0) if ((m_windowStyle & wxSYSTEM_MENU) == 0)
decor |= GDK_DECOR_MENU; decor |= GDK_DECOR_MENU;
if ((m_windowStyle & wxMINIMIZE_BOX) == 0) if ((m_windowStyle & wxMINIMIZE_BOX) == 0)
decor |= GDK_DECOR_MINIMIZE; decor |= GDK_DECOR_MINIMIZE;
if ((m_windowStyle & wxMAXIMIZE_BOX) == 0) if ((m_windowStyle & wxMAXIMIZE_BOX) == 0)
decor |= GDK_DECOR_MAXIMIZE; decor |= GDK_DECOR_MAXIMIZE;
if ((m_windowStyle & wxRESIZE_BORDER) == 0) if ((m_windowStyle & wxRESIZE_BORDER) == 0)
func |= GDK_FUNC_RESIZE; 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); /* the user resized the frame by dragging etc. */
gdk_window_set_functions(m_widget->window, (GdkWMFunction)func);
gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate",
GTK_SIGNAL_FUNC(gtk_frame_size_callback), (gpointer)this ); 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_connect( GTK_OBJECT(m_widget), "configure_event",
GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this ); 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" ); wxASSERT_MSG( (m_widget != NULL), "invalid frame" );
/* don't do anything for children of wxMDIChildFrame */ /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
if (!m_wxwindow) return; wxASSERT_MSG( (m_wxwindow != NULL), "invalid frame" );
if (m_resizing) return; // I don't like recursions /* avoid recursions */
if (m_resizing) return;
m_resizing = TRUE; m_resizing = TRUE;
int old_x = m_x; 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)) 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; m_sizeSet = FALSE;
} }
@@ -425,65 +433,79 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height
// m_x = x; // m_x = x;
// m_y = y; // m_y = y;
/* avoid recursions */
if (m_resizing) return; if (m_resizing) return;
m_resizing = TRUE; 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_width = width;
m_height = height; m_height = height;
/* check if size is in legal range */ /* space occupied by m_frameToolBar and m_frameMenuBar */
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. */
int client_area_y_offset = 0; 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; /* check if size is in legal range */
int yy = m_miniEdge + m_miniTitle; if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
int ww = m_width - 2*m_miniEdge; if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
int hh = wxMENU_HEIGHT; if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
m_frameMenuBar->m_x = xx; if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
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 ); /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
gtk_widget_set_usize( m_frameMenuBar->m_widget, ww, hh ); * 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. */
client_area_y_offset += hh; 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;
}
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 ); gtk_widget_set_usize( m_wxwindow, m_width, m_height-client_area_y_offset );
if (m_frameStatusBar) if (m_frameStatusBar)
@@ -533,8 +555,6 @@ void wxFrame::OnInternalIdle()
void wxFrame::OnCloseWindow( wxCloseEvent& event ) 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(); Destroy();
} }

View File

@@ -33,48 +33,6 @@ const int wxMENU_HEIGHT = 27;
extern wxList wxPendingDelete; 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 // wxMDIParentFrame
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -84,11 +42,10 @@ IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame,wxFrame)
BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame) BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame)
END_EVENT_TABLE() END_EVENT_TABLE()
wxMDIParentFrame::wxMDIParentFrame(void) wxMDIParentFrame::wxMDIParentFrame()
{ {
m_justInserted = FALSE;
m_clientWindow = (wxMDIClientWindow *) NULL; m_clientWindow = (wxMDIClientWindow *) NULL;
m_currentChild = (wxMDIChildFrame *) NULL;
m_parentFrameActive = TRUE;
} }
wxMDIParentFrame::wxMDIParentFrame( wxWindow *parent, wxMDIParentFrame::wxMDIParentFrame( wxWindow *parent,
@@ -96,13 +53,12 @@ wxMDIParentFrame::wxMDIParentFrame( wxWindow *parent,
const wxPoint& pos, const wxSize& size, const wxPoint& pos, const wxSize& size,
long style, const wxString& name ) long style, const wxString& name )
{ {
m_justInserted = FALSE;
m_clientWindow = (wxMDIClientWindow *) NULL; m_clientWindow = (wxMDIClientWindow *) NULL;
m_currentChild = (wxMDIChildFrame *) NULL;
m_parentFrameActive = TRUE;
Create( parent, id, title, pos, size, style, name ); Create( parent, id, title, pos, size, style, name );
} }
wxMDIParentFrame::~wxMDIParentFrame(void) wxMDIParentFrame::~wxMDIParentFrame()
{ {
} }
@@ -122,38 +78,57 @@ void wxMDIParentFrame::GtkOnSize( int x, int y, int width, int height )
{ {
wxFrame::GtkOnSize( x, y, width, height ); wxFrame::GtkOnSize( x, y, width, height );
if (m_mdiMenuBar) wxMDIChildFrame *child_frame = GetActiveChild();
{ if (!child_frame) return;
m_mdiMenuBar->m_x = 0;
m_mdiMenuBar->m_y = 0; wxMenuBar *menu_bar = child_frame->m_menuBar;
m_mdiMenuBar->m_width = m_width; if (!menu_bar) return;
m_mdiMenuBar->m_height = wxMENU_HEIGHT; if (!menu_bar->m_widget) return;
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 ); 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 a an MDI child window has just been inserted
if (m_mdiMenuBar) m_mdiMenuBar->Show( FALSE ); 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; if (m_justInserted)
/* show and resize new menu child menu bar */
if (m_mdiMenuBar)
{ {
m_mdiMenuBar->m_x = 0; GtkNotebook *notebook = GTK_NOTEBOOK(m_clientWindow->m_widget);
m_mdiMenuBar->m_y = 0; gtk_notebook_set_page( notebook, g_list_length( notebook->children ) - 1 );
m_mdiMenuBar->m_width = m_width;
m_mdiMenuBar->m_height = wxMENU_HEIGHT; m_justInserted = FALSE;
gtk_myfixed_move( GTK_MYFIXED(m_wxwindow), m_mdiMenuBar->m_widget, 0, 0 ); return;
gtk_widget_set_usize( m_mdiMenuBar->m_widget, m_width, wxMENU_HEIGHT ); }
m_mdiMenuBar->Show( TRUE );
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 */ /* 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 void wxMDIParentFrame::GetClientSize(int *width, int *height ) const
@@ -161,29 +136,49 @@ void wxMDIParentFrame::GetClientSize(int *width, int *height ) const
wxFrame::GetClientSize( width, height ); 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; return m_clientWindow;
} }
wxMDIClientWindow *wxMDIParentFrame::OnCreateClient(void) wxMDIClientWindow *wxMDIParentFrame::OnCreateClient()
{ {
m_clientWindow = new wxMDIClientWindow( this ); m_clientWindow = new wxMDIClientWindow( this );
return m_clientWindow; return m_clientWindow;
} }
void wxMDIParentFrame::ActivateNext(void) void wxMDIParentFrame::ActivateNext()
{ {
if (m_clientWindow) if (m_clientWindow)
gtk_notebook_next_page( GTK_NOTEBOOK(m_clientWindow->m_widget) ); gtk_notebook_next_page( GTK_NOTEBOOK(m_clientWindow->m_widget) );
} }
void wxMDIParentFrame::ActivatePrevious(void) void wxMDIParentFrame::ActivatePrevious()
{ {
if (m_clientWindow) if (m_clientWindow)
gtk_notebook_prev_page( GTK_NOTEBOOK(m_clientWindow->m_widget) ); gtk_notebook_prev_page( GTK_NOTEBOOK(m_clientWindow->m_widget) );
@@ -207,7 +202,7 @@ BEGIN_EVENT_TABLE(wxMDIChildFrame, wxFrame)
EVT_ACTIVATE(wxMDIChildFrame::OnActivate) EVT_ACTIVATE(wxMDIChildFrame::OnActivate)
END_EVENT_TABLE() END_EVENT_TABLE()
wxMDIChildFrame::wxMDIChildFrame(void) wxMDIChildFrame::wxMDIChildFrame()
{ {
m_menuBar = (wxMenuBar *) NULL; m_menuBar = (wxMenuBar *) NULL;
m_page = (GtkNotebookPage *) NULL; m_page = (GtkNotebookPage *) NULL;
@@ -223,18 +218,10 @@ wxMDIChildFrame::wxMDIChildFrame( wxMDIParentFrame *parent,
Create( parent, id, title, wxDefaultPosition, size, style, name ); Create( parent, id, title, wxDefaultPosition, size, style, name );
} }
wxMDIChildFrame::~wxMDIChildFrame(void) wxMDIChildFrame::~wxMDIChildFrame()
{ {
if (m_menuBar) 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; delete m_menuBar;
}
} }
bool wxMDIChildFrame::Create( wxMDIParentFrame *parent, bool wxMDIChildFrame::Create( wxMDIParentFrame *parent,
@@ -291,10 +278,12 @@ void wxMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar )
m_menuBar->m_parent = mdi_frame; m_menuBar->m_parent = mdi_frame;
} }
gtk_myfixed_put( GTK_MYFIXED(mdi_frame->m_wxwindow), /* the menu bar of the child window is shown in idle time as needed */
m_menuBar->m_widget, m_menuBar->m_x, m_menuBar->m_y ); 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; 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 // InsertChild callback for wxMDIClientWindow
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -332,9 +339,8 @@ static void wxInsertChildInMDI( wxMDIClientWindow* parent, wxMDIChildFrame* chil
child->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data); child->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data);
gtk_notebook_set_page( notebook, parent->m_children.Number()-1 ); wxMDIParentFrame *parent_frame = (wxMDIParentFrame*) parent->m_parent;
parent_frame->m_justInserted = TRUE;
gtk_page_change_callback( (GtkNotebook *) NULL, child->m_page, 0, parent );
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -343,7 +349,7 @@ static void wxInsertChildInMDI( wxMDIClientWindow* parent, wxMDIChildFrame* chil
IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow,wxWindow) IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow,wxWindow)
wxMDIClientWindow::wxMDIClientWindow(void) wxMDIClientWindow::wxMDIClientWindow()
{ {
} }
@@ -352,7 +358,7 @@ wxMDIClientWindow::wxMDIClientWindow( wxMDIParentFrame *parent, long style )
CreateClient( parent, 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(); 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 ); gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 );
m_parent->AddChild( this ); m_parent->AddChild( this );