#ifndef WX_PRECOMP
#include "wx/intl.h"
#include "wx/menu.h"
- #include "wx/dialog.h"
#endif
-#include "wx/notebook.h"
#include "wx/gtk/private.h"
-#include <glib.h>
-#include <gdk/gdk.h>
-#include <gtk/gtk.h>
-#include "wx/gtk/win_gtk.h"
-
-//-----------------------------------------------------------------------------
-// constants
-//-----------------------------------------------------------------------------
-
-const int wxMENU_HEIGHT = 27;
-
-//-----------------------------------------------------------------------------
-// globals
-//-----------------------------------------------------------------------------
-
//-----------------------------------------------------------------------------
// "switch_page"
//-----------------------------------------------------------------------------
gint WXUNUSED(page_num),
wxMDIParentFrame *parent )
{
- if (g_isIdle)
- wxapp_install_idle_handler();
-
// send deactivate event to old child
wxMDIChildFrame *child = parent->GetActiveChild();
{
wxActivateEvent event1( wxEVT_ACTIVATE, false, child->GetId() );
event1.SetEventObject( child);
- child->GetEventHandler()->ProcessEvent( event1 );
+ child->HandleWindowEvent( event1 );
}
// send activate event to new child
- wxMDIClientWindow *client_window = parent->GetClientWindow();
- if (!client_window)
+ wxMDIClientWindowBase *client_window = parent->GetClientWindow();
+ if ( !client_window )
return;
- child = (wxMDIChildFrame*) NULL;
+ child = NULL;
wxWindowList::compatibility_iterator node = client_window->GetChildren().GetFirst();
while ( node )
wxActivateEvent event2( wxEVT_ACTIVATE, true, child->GetId() );
event2.SetEventObject( child);
- child->GetEventHandler()->ProcessEvent( event2 );
+ child->HandleWindowEvent( event2 );
}
}
void wxMDIParentFrame::Init()
{
m_justInserted = false;
- m_clientWindow = (wxMDIClientWindow *) NULL;
-}
-
-wxMDIParentFrame::~wxMDIParentFrame()
-{
}
bool wxMDIParentFrame::Create(wxWindow *parent,
long style,
const wxString& name )
{
- wxFrame::Create( parent, id, title, pos, size, style, name );
+ if ( !wxFrame::Create( parent, id, title, pos, size, style, name ) )
+ return false;
- OnCreateClient();
+ m_clientWindow = OnCreateClient();
+ if ( !m_clientWindow->CreateClient(this, GetWindowStyleFlag()) )
+ return false;
return true;
}
-void wxMDIParentFrame::GtkOnSize()
-{
- wxFrame::GtkOnSize();
-
- 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_pizza_set_size( GTK_PIZZA(m_mainWidget),
- menu_bar->m_widget,
- 0, 0, m_width, wxMENU_HEIGHT );
-}
-
void wxMDIParentFrame::OnInternalIdle()
{
- /* if a an MDI child window has just been inserted
+ /* if a 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 */
wxMenuBar *menu_bar = active_child_frame->m_menuBar;
if (menu_bar)
{
- menu_bar->m_width = m_width;
- menu_bar->m_height = wxMENU_HEIGHT;
- gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
- menu_bar->m_widget,
- 0, 0, m_width, wxMENU_HEIGHT );
menu_bar->SetInvokingWindow(active_child_frame);
}
}
{
if (menu_bar->Show(true))
{
- menu_bar->m_width = m_width;
- menu_bar->m_height = wxMENU_HEIGHT;
- gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
- menu_bar->m_widget,
- 0, 0, m_width, wxMENU_HEIGHT );
menu_bar->SetInvokingWindow( child_frame );
}
visible_child_menu = true;
{
m_frameMenuBar->Show( true );
m_frameMenuBar->SetInvokingWindow( this );
+ }
+ }
+}
+
+void wxMDIParentFrame::DoGetClientSize(int* width, int* height) const
+{
+ wxFrame::DoGetClientSize(width, height);
- m_frameMenuBar->m_width = m_width;
- m_frameMenuBar->m_height = wxMENU_HEIGHT;
- gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
- m_frameMenuBar->m_widget,
- 0, 0, m_width, wxMENU_HEIGHT );
+ if (height)
+ {
+ wxMDIChildFrame* active_child_frame = GetActiveChild();
+ if (active_child_frame)
+ {
+ wxMenuBar* menubar = active_child_frame->m_menuBar;
+ if (menubar && menubar->IsShown())
+ {
+ GtkRequisition req;
+ gtk_widget_size_request(menubar->m_widget, &req);
+ *height -= req.height;
+ if (*height < 0) *height = 0;
+ }
}
}
}
wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const
{
- if (!m_clientWindow) return (wxMDIChildFrame*) NULL;
+ if (!m_clientWindow) return NULL;
GtkNotebook *notebook = GTK_NOTEBOOK(m_clientWindow->m_widget);
- if (!notebook) return (wxMDIChildFrame*) NULL;
+ if (!notebook) return NULL;
gint i = gtk_notebook_get_current_page( notebook );
- if (i < 0) return (wxMDIChildFrame*) NULL;
+ if (i < 0) return NULL;
GtkNotebookPage* page = (GtkNotebookPage*) (g_list_nth(notebook->children,i)->data);
- if (!page) return (wxMDIChildFrame*) NULL;
+ if (!page) return NULL;
wxWindowList::compatibility_iterator node = m_clientWindow->GetChildren().GetFirst();
while (node)
{
+ if ( wxPendingDelete.Member(node->GetData()) )
+ return NULL;
+
wxMDIChildFrame *child_frame = wxDynamicCast( node->GetData(), wxMDIChildFrame );
- wxASSERT_MSG( child_frame, _T("child is not a wxMDIChildFrame") );
+ if (!child_frame)
+ return NULL;
if (child_frame->m_page == page)
return child_frame;
+
node = node->GetNext();
}
- return (wxMDIChildFrame*) NULL;
-}
-
-wxMDIClientWindow *wxMDIParentFrame::GetClientWindow() const
-{
- return m_clientWindow;
-}
-
-wxMDIClientWindow *wxMDIParentFrame::OnCreateClient()
-{
- m_clientWindow = new wxMDIClientWindow( this );
- return m_clientWindow;
+ return NULL;
}
void wxMDIParentFrame::ActivateNext()
EVT_MENU_HIGHLIGHT_ALL(wxMDIChildFrame::OnMenuHighlight)
END_EVENT_TABLE()
-wxMDIChildFrame::wxMDIChildFrame()
-{
- m_menuBar = (wxMenuBar *) NULL;
- m_page = (GtkNotebookPage *) NULL;
-}
-
-wxMDIChildFrame::wxMDIChildFrame( wxMDIParentFrame *parent,
- wxWindowID id, const wxString& title,
- const wxPoint& WXUNUSED(pos), const wxSize& size,
- long style, const wxString& name )
+void wxMDIChildFrame::Init()
{
- m_menuBar = (wxMenuBar *) NULL;
- m_page = (GtkNotebookPage *) NULL;
- Create( parent, id, title, wxDefaultPosition, size, style, name );
-}
-
-wxMDIChildFrame::~wxMDIChildFrame()
-{
- if (m_menuBar)
- delete m_menuBar;
+ m_menuBar = NULL;
+ m_page = NULL;
}
-bool wxMDIChildFrame::Create( wxMDIParentFrame *parent,
- wxWindowID id, const wxString& title,
- const wxPoint& WXUNUSED(pos), const wxSize& size,
- long style, const wxString& name )
+bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
+ wxWindowID id,
+ const wxString& title,
+ const wxPoint& WXUNUSED(pos),
+ const wxSize& size,
+ long style,
+ const wxString& name)
{
+ m_mdiParent = parent;
m_title = title;
- return wxWindow::Create( parent->GetClientWindow(), id, wxDefaultPosition, size, style, name );
+ return wxWindow::Create(parent->GetClientWindow(), id,
+ wxDefaultPosition, size,
+ style, name);
}
-void wxMDIChildFrame::DoSetSize( int x, int y, int width, int height, int sizeFlags )
+wxMDIChildFrame::~wxMDIChildFrame()
{
- wxWindow::DoSetSize( x, y, width, height, sizeFlags );
-}
+ delete m_menuBar;
-void wxMDIChildFrame::DoSetClientSize(int width, int height)
-{
- wxWindow::DoSetClientSize( width, height );
-}
-
-void wxMDIChildFrame::DoGetClientSize( int *width, int *height ) const
-{
- wxWindow::DoGetClientSize( width, height );
-}
-
-void wxMDIChildFrame::AddChild( wxWindowBase *child )
-{
- wxWindow::AddChild(child);
+ // wxMDIClientWindow does not get redrawn properly after last child is removed
+ if (m_parent && m_parent->GetChildren().size() <= 1)
+ gtk_widget_queue_draw(m_parent->m_widget);
}
void wxMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar )
{
- wxASSERT_MSG( m_menuBar == NULL, wxT("Only one menubar allowed") );
+ wxASSERT_MSG( m_menuBar == NULL, "Only one menubar allowed" );
m_menuBar = menu_bar;
m_menuBar->SetParent( mdi_frame );
/* insert the invisible menu bar into the _parent_ mdi frame */
- gtk_pizza_put( GTK_PIZZA(mdi_frame->m_mainWidget),
- m_menuBar->m_widget,
- 0, 0, mdi_frame->m_width, wxMENU_HEIGHT );
+ m_menuBar->Show(false);
+ gtk_box_pack_start(GTK_BOX(mdi_frame->m_mainWidget), m_menuBar->m_widget, false, false, 0);
+ gtk_box_reorder_child(GTK_BOX(mdi_frame->m_mainWidget), m_menuBar->m_widget, 0);
+
+ gulong handler_id = g_signal_handler_find(
+ m_menuBar->m_widget,
+ GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
+ g_signal_lookup("size_request", GTK_TYPE_WIDGET),
+ 0, NULL, NULL, m_menuBar);
+ if (handler_id != 0)
+ g_signal_handler_disconnect(m_menuBar->m_widget, handler_id);
+ gtk_widget_set_size_request(m_menuBar->m_widget, -1, -1);
}
}
return m_menuBar;
}
+GtkNotebook *wxMDIChildFrame::GTKGetNotebook() const
+{
+ wxMDIClientWindow * const
+ client = wxStaticCast(GetParent(), wxMDIClientWindow);
+ wxCHECK( client, NULL );
+
+ return GTK_NOTEBOOK(client->m_widget);
+}
+
void wxMDIChildFrame::Activate()
{
- wxMDIParentFrame* parent = (wxMDIParentFrame*) GetParent();
- GtkNotebook* notebook = GTK_NOTEBOOK(parent->m_widget);
+ GtkNotebook * const notebook = GTKGetNotebook();
+ wxCHECK_RET( notebook, "no parent notebook?" );
+
gint pageno = gtk_notebook_page_num( notebook, m_widget );
gtk_notebook_set_current_page( notebook, pageno );
}
{
#if wxUSE_STATUSBAR
wxMDIParentFrame *mdi_frame = (wxMDIParentFrame*)m_parent->GetParent();
- if ( !ShowMenuHelp(mdi_frame->GetStatusBar(), event.GetMenuId()) )
+ if ( !ShowMenuHelp(event.GetMenuId()) )
{
// we don't have any help text for this item, but may be the MDI frame
// does?
m_title = title;
- wxMDIParentFrame* parent = (wxMDIParentFrame*) GetParent();
- GtkNotebook* notebook = GTK_NOTEBOOK(parent->m_widget);
+ GtkNotebook * const notebook = GTKGetNotebook();
+ wxCHECK_RET( notebook, "no parent notebook?" );
gtk_notebook_set_tab_label_text(notebook, m_widget, wxGTK_CONV( title ) );
}
-//-----------------------------------------------------------------------------
-// "size_allocate"
-//-----------------------------------------------------------------------------
-
-extern "C" {
-static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win )
-{
- if (g_isIdle) wxapp_install_idle_handler();
-
- 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
-//-----------------------------------------------------------------------------
-
-static void wxInsertChildInMDI( wxMDIClientWindow* parent, wxMDIChildFrame* child )
-{
- wxString s = child->GetTitle();
- if (s.IsNull()) s = _("MDI child");
-
- GtkWidget *label_widget = gtk_label_new( s.mbc_str() );
- gtk_misc_set_alignment( GTK_MISC(label_widget), 0.0, 0.5 );
-
- g_signal_connect (child->m_widget, "size_allocate",
- G_CALLBACK (gtk_page_size_callback), child);
-
- GtkNotebook *notebook = GTK_NOTEBOOK(parent->m_widget);
-
- gtk_notebook_append_page( notebook, child->m_widget, label_widget );
-
- child->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data);
-
- wxMDIParentFrame *parent_frame = (wxMDIParentFrame*) parent->GetParent();
- parent_frame->m_justInserted = true;
-}
-
//-----------------------------------------------------------------------------
// wxMDIClientWindow
//-----------------------------------------------------------------------------
-IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow,wxWindow)
-
-wxMDIClientWindow::wxMDIClientWindow()
-{
-}
-
-wxMDIClientWindow::wxMDIClientWindow( wxMDIParentFrame *parent, long style )
-{
- CreateClient( parent, style );
-}
+IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxWindow)
wxMDIClientWindow::~wxMDIClientWindow()
{
-
-}
-
-bool wxMDIClientWindow::CreateClient( wxMDIParentFrame *parent, long style )
+ // disconnect our handler because our ~wxWindow (which is going to be called
+ // after this dtor) will call DestroyChildren(); in turns our children
+ // ~wxWindow dtors will call wxWindow::Show(false) and this will generate
+ // a call to gtk_mdi_page_change_callback with an invalid parent
+ // (because gtk_mdi_page_change_callback expects a wxMDIClientWindow but
+ // at that point of the dtor chain we are a simple wxWindow!)
+ g_signal_handlers_disconnect_by_func(m_widget,
+ (gpointer)gtk_mdi_page_change_callback,
+ GetParent());
+}
+
+bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style)
{
- m_needParent = true;
-
- m_insertCallback = (wxInsertChildFunction)wxInsertChildInMDI;
-
- if (!PreCreation( parent, wxDefaultPosition, wxDefaultSize ) ||
- !CreateBase( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, style, wxDefaultValidator, wxT("wxMDIClientWindow") ))
+ if ( !PreCreation( parent, wxDefaultPosition, wxDefaultSize ) ||
+ !CreateBase( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
+ style, wxDefaultValidator, "wxMDIClientWindow" ))
{
- wxFAIL_MSG( wxT("wxMDIClientWindow creation failed") );
+ wxFAIL_MSG( "wxMDIClientWindow creation failed" );
return false;
}
m_widget = gtk_notebook_new();
+ g_object_ref(m_widget);
g_signal_connect (m_widget, "switch_page",
G_CALLBACK (gtk_mdi_page_change_callback), parent);
return true;
}
-#endif
+void wxMDIClientWindow::AddChildGTK(wxWindowGTK* child)
+{
+ wxMDIChildFrame* child_frame = static_cast<wxMDIChildFrame*>(child);
+ wxString s = child_frame->GetTitle();
+ if ( s.empty() )
+ s = _("MDI child");
+
+ GtkWidget *label_widget = gtk_label_new( s.mbc_str() );
+ gtk_misc_set_alignment( GTK_MISC(label_widget), 0.0, 0.5 );
+
+ GtkNotebook* notebook = GTK_NOTEBOOK(m_widget);
+
+ gtk_notebook_append_page( notebook, child->m_widget, label_widget );
+
+ child_frame->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data);
+
+ wxMDIParentFrame* parent_frame = static_cast<wxMDIParentFrame*>(GetParent());
+ parent_frame->m_justInserted = true;
+}
+
+#endif // wxUSE_MDI