From cca410b336cd5628a944ede9e9944fdbb04552d4 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Wed, 24 Oct 2007 18:07:24 +0000 Subject: [PATCH] Use a GtkVBox to do TLW layout. Rework some of the remaining sizing code. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@49406 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/gtk/frame.h | 23 -- include/wx/gtk/mdi.h | 6 +- include/wx/gtk/minifram.h | 28 +-- include/wx/gtk/popupwin.h | 11 +- include/wx/gtk/toplevel.h | 8 +- include/wx/gtk/window.h | 6 +- src/gtk/collpane.cpp | 39 +--- src/gtk/dialog.cpp | 17 -- src/gtk/frame.cpp | 444 ++++++++------------------------------ src/gtk/mdi.cpp | 122 +++-------- src/gtk/menu.cpp | 26 --- src/gtk/minifram.cpp | 86 ++++++-- src/gtk/popupwin.cpp | 102 ++------- src/gtk/tbargtk.cpp | 30 +-- src/gtk/toplevel.cpp | 161 +++++--------- src/gtk/window.cpp | 136 +++++------- 16 files changed, 344 insertions(+), 901 deletions(-) diff --git a/include/wx/gtk/frame.h b/include/wx/gtk/frame.h index b93964dd5f..98addeee04 100644 --- a/include/wx/gtk/frame.h +++ b/include/wx/gtk/frame.h @@ -10,17 +10,6 @@ #ifndef _WX_GTK_FRAME_H_ #define _WX_GTK_FRAME_H_ -//----------------------------------------------------------------------------- -// classes -//----------------------------------------------------------------------------- - -class WXDLLIMPEXP_FWD_CORE wxMDIChildFrame; -class WXDLLIMPEXP_FWD_CORE wxMDIClientWindow; -class WXDLLIMPEXP_FWD_CORE wxMenu; -class WXDLLIMPEXP_FWD_CORE wxMenuBar; -class WXDLLIMPEXP_FWD_CORE wxToolBar; -class WXDLLIMPEXP_FWD_CORE wxStatusBar; - //----------------------------------------------------------------------------- // wxFrame //----------------------------------------------------------------------------- @@ -68,13 +57,8 @@ public: // -------------------------- // GTK callbacks - virtual void GtkOnSize(); virtual void OnInternalIdle(); - bool m_menuBarDetached; - int m_menuBarHeight; - bool m_toolBarDetached; - protected: // common part of all ctors void Init(); @@ -85,13 +69,6 @@ protected: #if wxUSE_MENUS_NATIVE virtual void DetachMenuBar(); virtual void AttachMenuBar(wxMenuBar *menubar); - // Whether frame has a menubar showing - // (needed to deal with perverted MDI menubar handling) - virtual bool HasVisibleMenubar() const; - -public: - // Menu size is dynamic now, call this whenever it might change. - void UpdateMenuBarSize(); #endif // wxUSE_MENUS_NATIVE private: diff --git a/include/wx/gtk/mdi.h b/include/wx/gtk/mdi.h index 978b1abe86..fb3521fa05 100644 --- a/include/wx/gtk/mdi.h +++ b/include/wx/gtk/mdi.h @@ -12,6 +12,9 @@ #include "wx/frame.h" +class WXDLLIMPEXP_FWD_CORE wxMDIChildFrame; +class WXDLLIMPEXP_FWD_CORE wxMDIClientWindow; + //----------------------------------------------------------------------------- // wxMDIParentFrame //----------------------------------------------------------------------------- @@ -58,12 +61,11 @@ public: wxMDIClientWindow *m_clientWindow; bool m_justInserted; - virtual void GtkOnSize(); virtual void OnInternalIdle(); protected: void Init(); - virtual bool HasVisibleMenubar() const; + virtual void DoGetClientSize(int* width, int* height) const; private: friend class wxMDIChildFrame; diff --git a/include/wx/gtk/minifram.h b/include/wx/gtk/minifram.h index 7d925b40a3..0a5d6107b6 100644 --- a/include/wx/gtk/minifram.h +++ b/include/wx/gtk/minifram.h @@ -7,23 +7,12 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifndef __GTKMINIFRAMEH__ -#define __GTKMINIFRAMEH__ +#ifndef _WX_GTK_MINIFRAME_H_ +#define _WX_GTK_MINIFRAME_H_ -#include "wx/defs.h" - -#if wxUSE_MINIFRAME - -#include "wx/object.h" #include "wx/bitmap.h" #include "wx/frame.h" -//----------------------------------------------------------------------------- -// classes -//----------------------------------------------------------------------------- - -class WXDLLIMPEXP_FWD_CORE wxMiniFrame; - //----------------------------------------------------------------------------- // wxMiniFrame //----------------------------------------------------------------------------- @@ -54,15 +43,18 @@ public: const wxString& name = wxFrameNameStr); virtual void SetTitle( const wxString &title ); + +protected: + virtual void DoGetClientSize(int* width, int* height) const; + // implementation - +public: bool m_isDragging; int m_oldX,m_oldY; int m_diffX,m_diffY; wxBitmap m_closeButton; + int m_miniEdge; + int m_miniTitle; }; -#endif - -#endif - // __GTKMINIFRAMEH__ +#endif // _WX_GTK_MINIFRAME_H_ diff --git a/include/wx/gtk/popupwin.h b/include/wx/gtk/popupwin.h index e150b2d3e7..cb0f7f18dd 100644 --- a/include/wx/gtk/popupwin.h +++ b/include/wx/gtk/popupwin.h @@ -25,20 +25,15 @@ public: { (void)Create(parent, flags); } bool Create(wxWindow *parent, int flags = wxBORDER_NONE); - virtual bool Show( bool show = TRUE ); + virtual bool Show(bool show = true); // implementation // -------------- - virtual void OnInternalIdle(); - // GTK time when connecting to button_press signal wxUint32 m_time; - protected: - void GtkOnSize(); - virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO); @@ -46,9 +41,9 @@ protected: virtual void DoMoveWindow(int x, int y, int width, int height); private: - bool m_sizeSet; - +#ifdef __WXUNIVERSAL__ DECLARE_EVENT_TABLE() +#endif DECLARE_DYNAMIC_CLASS(wxPopupWindow) }; diff --git a/include/wx/gtk/toplevel.h b/include/wx/gtk/toplevel.h index 9b1965b1b2..f3d8c858fe 100644 --- a/include/wx/gtk/toplevel.h +++ b/include/wx/gtk/toplevel.h @@ -83,14 +83,11 @@ public: // -------------------------- // GTK callbacks - virtual void GtkOnSize(); virtual void OnInternalIdle(); // do *not* call this to iconize the frame, this is a private function! void SetIconizeState(bool iconic); - int m_miniEdge, - m_miniTitle; GtkWidget *m_mainWidget; bool m_fsIsShowing; /* full screen */ @@ -101,8 +98,6 @@ public: int m_gdkFunc, m_gdkDecor; - bool m_sizeSet; - // private gtk_timeout_add result for mimicing wxUSER_ATTENTION_INFO and // wxUSER_ATTENTION_ERROR difference, -2 for no hint, -1 for ERROR hint, rest for GtkTimeout handle. int m_urgency_hint; @@ -116,8 +111,6 @@ public: // return the size of the window without WM decorations void GTKDoGetSize(int *width, int *height) const; - void GtkUpdateSize() { m_sizeSet = false; } - // whether frame extents are accurate virtual bool IsDecorCacheable() const; @@ -139,6 +132,7 @@ protected: // string shown in the title bar wxString m_title; +private: // is the frame currently iconized? bool m_isIconized; diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h index f2126cf432..6ed61b72cc 100644 --- a/include/wx/gtk/window.h +++ b/include/wx/gtk/window.h @@ -60,7 +60,7 @@ public: virtual bool IsRetained() const; virtual void SetFocus(); - + // hint from wx to native GTK+ tab traversal code virtual void SetCanFocus(bool canFocus); @@ -252,7 +252,7 @@ public: // return true if the window is of a standard (i.e. not wxWidgets') class bool IsOfStandardClass() const { return m_wxwindow == NULL; } - + // this widget will be queried for GTK's focus events GtkWidget *m_focusWidget; @@ -284,13 +284,11 @@ public: // find the direction of the given scrollbar (must be one of ours) ScrollDir ScrollDirFromRange(GtkRange *range) const; - // extra (wxGTK-specific) flags bool m_noExpose:1; // wxGLCanvas has its own redrawing bool m_nativeSizeEvent:1; // wxGLCanvas sends wxSizeEvent upon "alloc_size" bool m_hasScrolling:1; bool m_hasVMT:1; - bool m_resizing:1; bool m_hasFocus:1; // true if == FindFocus() bool m_isScrolling:1; // dragging scrollbar thumb? bool m_clipPaintRegion:1; // true after ScrollWindow() diff --git a/src/gtk/collpane.cpp b/src/gtk/collpane.cpp index b6b81b3042..1239855006 100644 --- a/src/gtk/collpane.cpp +++ b/src/gtk/collpane.cpp @@ -25,9 +25,6 @@ #include "wx/panel.h" #include "wx/gtk/private.h" -#include "wx/gtk/win_gtk.h" - -#include // ============================================================================ // implementation @@ -120,39 +117,11 @@ gtk_collapsiblepane_expanded_callback(GObject * WXUNUSED(object), // when the expander is collapsed!) gtk_window_set_resizable (GTK_WINDOW (top->m_widget), p->IsExpanded()); - // 4) set size hints: note that this code has been taken and adapted - // from src/gtk/toplevel.cpp - GdkGeometry geom; - - geom.min_width = sz.x; - geom.min_height = sz.y; - - gtk_window_set_geometry_hints( GTK_WINDOW(top->m_widget), - (GtkWidget*) NULL, - &geom, - GDK_HINT_MIN_SIZE ); - - // 5) set size: also this code has been adapted from src/gtk/toplevel.cpp - // to do the size changes immediately and not delaying them in the idle - // time - top->m_width = sz.x; - top->m_height = sz.y; - - int client_x = top->m_miniEdge; - int client_y = top->m_miniEdge + top->m_miniTitle; - int client_w = top->m_width - 2*top->m_miniEdge; - int client_h = top->m_height - 2*top->m_miniEdge - top->m_miniTitle; - if (client_w < 0) - client_w = 0; - if (client_h < 0) - client_h = 0; - - gtk_pizza_set_size( GTK_PIZZA(top->m_mainWidget), - top->m_wxwindow, - client_x, client_y, client_w, client_h ); - - gtk_widget_set_size_request( top->m_wxwindow, sz.x, sz.y ); + // 4) set size hints + top->SetSizeHints(sz.x, sz.y); + // 5) set size + top->SetClientSize(sz); } } diff --git a/src/gtk/dialog.cpp b/src/gtk/dialog.cpp index 056a469fea..dc66c23778 100644 --- a/src/gtk/dialog.cpp +++ b/src/gtk/dialog.cpp @@ -13,18 +13,12 @@ #include "wx/dialog.h" #ifndef WX_PRECOMP - #include "wx/app.h" - #include "wx/frame.h" #include "wx/cursor.h" #endif // WX_PRECOMP #include "wx/evtloop.h" -#include #include -#include - -#include "wx/gtk/win_gtk.h" //----------------------------------------------------------------------------- // global data @@ -42,7 +36,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxDialog,wxTopLevelWindow) void wxDialog::Init() { m_returnCode = 0; - m_sizeSet = false; m_modalShowing = false; m_themeEnabled = true; } @@ -77,16 +70,6 @@ bool wxDialog::Show( bool show ) EndModal( wxID_CANCEL ); } - if (show && !m_sizeSet) - { - /* by calling GtkOnSize here, we don't have to call - either after showing the frame, which would entail - much ugly flicker nor from within the size_allocate - handler, because GTK 1.1.X forbids that. */ - - GtkOnSize(); - } - bool ret = wxWindow::Show( show ); if (show) InitDialog(); diff --git a/src/gtk/frame.cpp b/src/gtk/frame.cpp index 910ff36947..6f9dcbb5b3 100644 --- a/src/gtk/frame.cpp +++ b/src/gtk/frame.cpp @@ -19,14 +19,6 @@ #endif // WX_PRECOMP #include -#include "wx/gtk/win_gtk.h" - -// ---------------------------------------------------------------------------- -// constants -// ---------------------------------------------------------------------------- - -static const int wxSTATUS_HEIGHT = 25; -static const int wxPLACE_HOLDER = 0; // ---------------------------------------------------------------------------- // event tables @@ -38,87 +30,12 @@ IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxTopLevelWindow) // implementation // ============================================================================ -// ---------------------------------------------------------------------------- -// GTK callbacks -// ---------------------------------------------------------------------------- - -#if wxUSE_MENUS_NATIVE - -//----------------------------------------------------------------------------- -// "child_attached" of menu bar -//----------------------------------------------------------------------------- - -extern "C" { -static void gtk_menu_attached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win ) -{ - if (!win->m_hasVMT) return; - - win->m_menuBarDetached = false; - win->GtkUpdateSize(); -} -} - -//----------------------------------------------------------------------------- -// "child_detached" of menu bar -//----------------------------------------------------------------------------- - -extern "C" { -static void gtk_menu_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win ) -{ - if (!win->m_hasVMT) return; - - // Raise the client area area - gdk_window_raise( win->m_wxwindow->window ); - - win->m_menuBarDetached = true; - win->GtkUpdateSize(); -} -} - -#endif // wxUSE_MENUS_NATIVE - -#if wxUSE_TOOLBAR -//----------------------------------------------------------------------------- -// "child_attached" of tool bar -//----------------------------------------------------------------------------- - -extern "C" { -static void gtk_toolbar_attached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win ) -{ - if (!win->m_hasVMT) return; - - win->m_toolBarDetached = false; - win->GtkUpdateSize(); -} -} - -//----------------------------------------------------------------------------- -// "child_detached" of tool bar -//----------------------------------------------------------------------------- - -extern "C" { -static void gtk_toolbar_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win ) -{ - if (!win->m_hasVMT) return; - - // Raise the client area area - gdk_window_raise( win->m_wxwindow->window ); - - win->m_toolBarDetached = true; - win->GtkUpdateSize(); -} -} -#endif // wxUSE_TOOLBAR - // ---------------------------------------------------------------------------- // wxFrame creation // ---------------------------------------------------------------------------- void wxFrame::Init() { - m_menuBarDetached = false; - m_toolBarDetached = false; - m_menuBarHeight = 2; m_fsSaveFlag = 0; } @@ -153,33 +70,36 @@ void wxFrame::DoGetClientSize( int *width, int *height ) const { #if wxUSE_MENUS_NATIVE // menu bar - if (HasVisibleMenubar() && !m_menuBarDetached) + if (m_frameMenuBar && m_frameMenuBar->IsShown()) { - *height -= m_menuBarHeight; + GtkRequisition req; + gtk_widget_size_request(m_frameMenuBar->m_widget, &req); + *height -= req.height; } #endif // wxUSE_MENUS_NATIVE #if wxUSE_STATUSBAR // status bar - if (m_frameStatusBar && GTK_WIDGET_VISIBLE(m_frameStatusBar->m_widget)) - *height -= wxSTATUS_HEIGHT; + if (m_frameStatusBar && m_frameStatusBar->IsShown()) + *height -= m_frameStatusBar->m_height; #endif // wxUSE_STATUSBAR } #if wxUSE_TOOLBAR // tool bar - if (m_frameToolBar && - GTK_WIDGET_VISIBLE(m_frameToolBar->m_widget) && !m_toolBarDetached) + if (m_frameToolBar && m_frameToolBar->IsShown()) { + GtkRequisition req; + gtk_widget_size_request(m_frameToolBar->m_widget, &req); if (m_frameToolBar->IsVertical()) { if (width) - *width -= m_frameToolBar->GetSize().x; + *width -= req.width; } else { if (height) - *height -= m_frameToolBar->GetSize().y; + *height -= req.height; } } #endif // wxUSE_TOOLBAR @@ -239,188 +159,6 @@ bool wxFrame::ShowFullScreen(bool show, long style) return true; } -void wxFrame::GtkOnSize() -{ - // avoid recursions - if (m_resizing) return; - m_resizing = true; - - // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow - wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") ); - - // space occupied by m_frameToolBar and m_frameMenuBar - int client_area_x_offset = 0, - client_area_y_offset = 0; - - /* 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 */ - - ConstrainSize(); - - int width, height; - GTKDoGetSize(&width, &height); - - if (m_mainWidget) - { - // TODO - // Rewrite this terrible code to using GtkVBox - - // m_mainWidget holds the menubar, the toolbar and the client - // area, which is represented by m_wxwindow. - -#if wxUSE_MENUS_NATIVE - int menubarHeight = 0; -#endif - -#if wxUSE_MENUS_NATIVE - if (HasVisibleMenubar()) - { - int xx = m_miniEdge; - int yy = m_miniEdge + m_miniTitle; - int ww = width - 2*m_miniEdge; - if (ww < 0) - ww = 0; - menubarHeight = m_menuBarHeight; - if (m_menuBarDetached) menubarHeight = wxPLACE_HOLDER; - m_frameMenuBar->m_x = xx; - m_frameMenuBar->m_y = yy; - m_frameMenuBar->m_width = ww; - m_frameMenuBar->m_height = menubarHeight; - gtk_pizza_set_size( GTK_PIZZA(m_mainWidget), - m_frameMenuBar->m_widget, - xx, yy, ww, menubarHeight); - client_area_y_offset += menubarHeight; - } -#endif // wxUSE_MENUS_NATIVE - -#if wxUSE_TOOLBAR - if ((m_frameToolBar) && m_frameToolBar->IsShown() && - (m_frameToolBar->m_widget->parent == m_mainWidget)) - { - int xx = m_miniEdge; - int yy = m_miniEdge + m_miniTitle -#if wxUSE_MENUS_NATIVE - + menubarHeight -#endif - ; - - m_frameToolBar->m_x = xx; - m_frameToolBar->m_y = yy; - - // don't change the toolbar's reported height/width - int ww, hh; - if ( m_frameToolBar->GetWindowStyle() & wxTB_VERTICAL ) - { - ww = m_toolBarDetached ? wxPLACE_HOLDER - : m_frameToolBar->m_width; - hh = height - 2*m_miniEdge; - - client_area_x_offset += ww; - } - else if( m_frameToolBar->HasFlag(wxTB_RIGHT) ) - { - yy += 2; - ww = m_toolBarDetached ? wxPLACE_HOLDER - : m_frameToolBar->m_width; - xx = GetClientSize().x - 1; - hh = height - 2*m_miniEdge; - if( hh < 0 ) - hh = 0; - - } - else if( m_frameToolBar->GetWindowStyle() & wxTB_BOTTOM ) - { - xx = m_miniEdge; - yy = GetClientSize().y; -#if wxUSE_MENUS_NATIVE - yy += m_menuBarHeight; -#endif // wxUSE_MENUS_NATIVE - m_frameToolBar->m_x = xx; - m_frameToolBar->m_y = yy; - ww = width - 2*m_miniEdge; - hh = m_toolBarDetached ? wxPLACE_HOLDER - : m_frameToolBar->m_height; - } - else - { - ww = width - 2*m_miniEdge; - hh = m_toolBarDetached ? wxPLACE_HOLDER - : m_frameToolBar->m_height; - - client_area_y_offset += hh; - } - - if (ww < 0) - ww = 0; - if (hh < 0) - hh = 0; - gtk_pizza_set_size( GTK_PIZZA(m_mainWidget), - m_frameToolBar->m_widget, - xx, yy, ww, hh ); - } -#endif // wxUSE_TOOLBAR - - int client_x = client_area_x_offset + m_miniEdge; - int client_y = client_area_y_offset + m_miniEdge + m_miniTitle; - int client_w = width - client_area_x_offset - 2*m_miniEdge; - int client_h = height - client_area_y_offset- 2*m_miniEdge - m_miniTitle; - if (client_w < 0) - client_w = 0; - if (client_h < 0) - client_h = 0; - gtk_pizza_set_size( GTK_PIZZA(m_mainWidget), - m_wxwindow, - client_x, client_y, client_w, client_h ); - } - else - { - // If there is no m_mainWidget between m_widget and m_wxwindow there - // is no need to set the size or position of m_wxwindow. - } - -#if wxUSE_STATUSBAR - if (m_frameStatusBar && m_frameStatusBar->IsShown()) - { - int xx = 0 + m_miniEdge; - int yy = height - wxSTATUS_HEIGHT - m_miniEdge - client_area_y_offset; - int ww = width - 2*m_miniEdge; - if (ww < 0) - ww = 0; - int hh = wxSTATUS_HEIGHT; - m_frameStatusBar->m_x = xx; - m_frameStatusBar->m_y = yy; - m_frameStatusBar->m_width = ww; - m_frameStatusBar->m_height = hh; - gtk_pizza_set_size( GTK_PIZZA(m_wxwindow), - m_frameStatusBar->m_widget, - xx, yy, ww, hh ); - } -#endif // wxUSE_STATUSBAR - - m_sizeSet = true; - - // send size event to frame - wxSizeEvent event( wxSize(m_width,m_height), GetId() ); - event.SetEventObject( this ); - GetEventHandler()->ProcessEvent( event ); - -#if wxUSE_STATUSBAR - // send size event to status bar - if (m_frameStatusBar) - { - wxSizeEvent event2( wxSize(m_frameStatusBar->m_width,m_frameStatusBar->m_height), m_frameStatusBar->GetId() ); - event2.SetEventObject( m_frameStatusBar ); - m_frameStatusBar->GetEventHandler()->ProcessEvent( event2 ); - } -#endif // wxUSE_STATUSBAR - - m_resizing = false; -} - void wxFrame::OnInternalIdle() { wxFrameBase::OnInternalIdle(); @@ -464,23 +202,15 @@ void wxFrame::DetachMenuBar() { m_frameMenuBar->UnsetInvokingWindow( this ); - if (m_frameMenuBar->GetWindowStyle() & wxMB_DOCKABLE) - { - g_signal_handlers_disconnect_by_func (m_frameMenuBar->m_widget, - (gpointer) gtk_menu_attached_callback, - this); - - g_signal_handlers_disconnect_by_func (m_frameMenuBar->m_widget, - (gpointer) gtk_menu_detached_callback, - this); - } - gtk_widget_ref( m_frameMenuBar->m_widget ); gtk_container_remove( GTK_CONTAINER(m_mainWidget), m_frameMenuBar->m_widget ); } wxFrameBase::DetachMenuBar(); + + // make sure next size_allocate causes a wxSizeEvent + m_oldClientWidth = 0; } void wxFrame::AttachMenuBar( wxMenuBar *menuBar ) @@ -492,58 +222,29 @@ void wxFrame::AttachMenuBar( wxMenuBar *menuBar ) m_frameMenuBar->SetInvokingWindow( this ); m_frameMenuBar->SetParent(this); - gtk_pizza_put( GTK_PIZZA(m_mainWidget), - m_frameMenuBar->m_widget, - m_frameMenuBar->m_x, - m_frameMenuBar->m_y, - m_frameMenuBar->m_width, - m_frameMenuBar->m_height ); - - if (menuBar->GetWindowStyle() & wxMB_DOCKABLE) - { - g_signal_connect (menuBar->m_widget, "child_attached", - G_CALLBACK (gtk_menu_attached_callback), - this); - g_signal_connect (menuBar->m_widget, "child_detached", - G_CALLBACK (gtk_menu_detached_callback), - this); - } - gtk_widget_show( m_frameMenuBar->m_widget ); + // menubar goes into top of vbox (m_mainWidget) + gtk_box_pack_start( + GTK_BOX(m_mainWidget), menuBar->m_widget, false, false, 0); + gtk_box_reorder_child(GTK_BOX(m_mainWidget), menuBar->m_widget, 0); - UpdateMenuBarSize(); - } - else - { - m_menuBarHeight = 2; - GtkUpdateSize(); // resize window in OnInternalIdle - } -} + // disconnect wxWindowGTK "size_request" handler, + // it interferes with sizing of detached GtkHandleBox + gulong handler_id = g_signal_handler_find( + menuBar->m_widget, + GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA), + g_signal_lookup("size_request", GTK_TYPE_WIDGET), + 0, NULL, NULL, menuBar); + if (handler_id != 0) + g_signal_handler_disconnect(menuBar->m_widget, handler_id); -void wxFrame::UpdateMenuBarSize() -{ - m_menuBarHeight = 2; + // reset size request to allow native sizing to work + gtk_widget_set_size_request(menuBar->m_widget, -1, -1); - // this is called after Remove with a NULL m_frameMenuBar - if ( m_frameMenuBar ) - { - GtkRequisition req; - gtk_widget_ensure_style(m_frameMenuBar->m_widget); - // have to call class method directly because - // "size_request" signal is overridden by wx - GTK_WIDGET_GET_CLASS(m_frameMenuBar->m_widget)->size_request( - m_frameMenuBar->m_widget, &req); - - m_menuBarHeight = req.height; + gtk_widget_show( m_frameMenuBar->m_widget ); } - - // resize window in OnInternalIdle - GtkUpdateSize(); -} - -bool wxFrame::HasVisibleMenubar() const -{ - return m_frameMenuBar && m_frameMenuBar->IsShown(); + // make sure next size_allocate causes a wxSizeEvent + m_oldClientWidth = 0; } #endif // wxUSE_MENUS_NATIVE @@ -551,30 +252,61 @@ bool wxFrame::HasVisibleMenubar() const void wxFrame::SetToolBar(wxToolBar *toolbar) { - wxFrameBase::SetToolBar(toolbar); - - if ( m_frameToolBar ) + m_frameToolBar = toolbar; + if (toolbar) { - // insert into toolbar area if not already there - if ((m_frameToolBar->m_widget->parent) && - (m_frameToolBar->m_widget->parent != m_mainWidget)) + if (toolbar->IsVertical()) { - GetChildren().DeleteObject( m_frameToolBar ); - - gtk_widget_reparent( m_frameToolBar->m_widget, m_mainWidget ); + // Vertical toolbar and m_wxwindow go into an hbox, inside the + // vbox (m_mainWidget). hbox is created on demand. + GtkWidget* hbox = m_wxwindow->parent; + if (!GTK_IS_HBOX(hbox)) + { + hbox = gtk_hbox_new(false, 0); + gtk_widget_show(hbox); + gtk_container_add(GTK_CONTAINER(m_mainWidget), hbox); + gtk_widget_reparent(m_wxwindow, hbox); + } + gtk_widget_reparent(toolbar->m_widget, hbox); + gtk_box_set_child_packing(GTK_BOX(hbox), + toolbar->m_widget, false, false, 0, GTK_PACK_START); + + int pos = 0; // left + if (toolbar->HasFlag(wxTB_RIGHT)) + pos = 1; // right + gtk_box_reorder_child(GTK_BOX(hbox), toolbar->m_widget, pos); } -#if wxUSE_TOOLBAR_NATIVE - if (m_frameToolBar->HasFlag(wxTB_DOCKABLE)) + else { - g_signal_connect(m_frameToolBar->m_widget, "child_attached", - G_CALLBACK(gtk_toolbar_attached_callback), this); - g_signal_connect(m_frameToolBar->m_widget, "child_detached", - G_CALLBACK(gtk_toolbar_detached_callback), this); + // Horizontal toolbar goes into vbox (m_mainWidget) + gtk_widget_reparent(toolbar->m_widget, m_mainWidget); + gtk_box_set_child_packing(GTK_BOX(m_mainWidget), + toolbar->m_widget, false, false, 0, GTK_PACK_START); + + int pos = 0; // top + if (m_frameMenuBar) + pos = 1; // below menubar + if (toolbar->HasFlag(wxTB_BOTTOM)) + pos += 2; // below client area (m_wxwindow) + gtk_box_reorder_child( + GTK_BOX(m_mainWidget), toolbar->m_widget, pos); } -#endif // wxUSE_TOOLBAR_NATIVE - } - GtkUpdateSize(); + // disconnect wxWindowGTK "size_request" handler, + // it interferes with sizing of detached GtkHandleBox + gulong handler_id = g_signal_handler_find( + toolbar->m_widget, + GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA), + g_signal_lookup("size_request", GTK_TYPE_WIDGET), + 0, NULL, NULL, toolbar); + if (handler_id != 0) + g_signal_handler_disconnect(toolbar->m_widget, handler_id); + + // reset size request to allow native sizing to work + gtk_widget_set_size_request(toolbar->m_widget, -1, -1); + } + // make sure next size_allocate causes a wxSizeEvent + m_oldClientWidth = 0; } #endif // wxUSE_TOOLBAR @@ -583,7 +315,17 @@ void wxFrame::SetToolBar(wxToolBar *toolbar) void wxFrame::SetStatusBar(wxStatusBar *statbar) { - wxFrameBase::SetStatusBar(statbar); - GtkUpdateSize(); + m_frameStatusBar = statbar; + if (statbar) + { + // statusbar goes into bottom of vbox (m_mainWidget) + gtk_widget_reparent(statbar->m_widget, m_mainWidget); + gtk_box_set_child_packing(GTK_BOX(m_mainWidget), + statbar->m_widget, false, false, 0, GTK_PACK_END); + // make sure next size_allocate on statusbar causes a size event + statbar->m_oldClientWidth = 0; + } + // make sure next size_allocate causes a wxSizeEvent + m_oldClientWidth = 0; } #endif // wxUSE_STATUSBAR diff --git a/src/gtk/mdi.cpp b/src/gtk/mdi.cpp index fb0e1b7079..5d3a4efbee 100644 --- a/src/gtk/mdi.cpp +++ b/src/gtk/mdi.cpp @@ -17,25 +17,10 @@ #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 -#include "wx/gtk/win_gtk.h" - -//----------------------------------------------------------------------------- -// constants -//----------------------------------------------------------------------------- - -const int wxMENU_HEIGHT = 27; - -//----------------------------------------------------------------------------- -// globals -//----------------------------------------------------------------------------- - //----------------------------------------------------------------------------- // "switch_page" //----------------------------------------------------------------------------- @@ -121,26 +106,6 @@ bool wxMDIParentFrame::Create(wxWindow *parent, 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; - GTKDoGetSize(&menu_bar->m_width, NULL); - menu_bar->m_height = wxMENU_HEIGHT; - gtk_pizza_set_size( GTK_PIZZA(m_mainWidget), - menu_bar->m_widget, - 0, 0, menu_bar->m_width, menu_bar->m_height); -} - void wxMDIParentFrame::OnInternalIdle() { /* if a an MDI child window has just been inserted @@ -160,11 +125,6 @@ void wxMDIParentFrame::OnInternalIdle() wxMenuBar *menu_bar = active_child_frame->m_menuBar; if (menu_bar) { - GTKDoGetSize(&menu_bar->m_width, NULL); - menu_bar->m_height = wxMENU_HEIGHT; - gtk_pizza_set_size( GTK_PIZZA(m_mainWidget), - menu_bar->m_widget, - 0, 0, menu_bar->m_width, menu_bar->m_height); menu_bar->SetInvokingWindow(active_child_frame); } } @@ -191,11 +151,6 @@ void wxMDIParentFrame::OnInternalIdle() { if (menu_bar->Show(true)) { - GTKDoGetSize(&menu_bar->m_width, NULL); - menu_bar->m_height = wxMENU_HEIGHT; - gtk_pizza_set_size( GTK_PIZZA(m_mainWidget), - menu_bar->m_widget, - 0, 0, menu_bar->m_width, menu_bar->m_height); menu_bar->SetInvokingWindow( child_frame ); } visible_child_menu = true; @@ -226,12 +181,27 @@ void wxMDIParentFrame::OnInternalIdle() { m_frameMenuBar->Show( true ); m_frameMenuBar->SetInvokingWindow( this ); + } + } +} - GTKDoGetSize(&m_frameMenuBar->m_width, NULL); - m_frameMenuBar->m_height = wxMENU_HEIGHT; - gtk_pizza_set_size( GTK_PIZZA(m_mainWidget), - m_frameMenuBar->m_widget, - 0, 0, m_frameMenuBar->m_width, m_frameMenuBar->m_height); +void wxMDIParentFrame::DoGetClientSize(int* width, int* height) const +{ + wxFrame::DoGetClientSize(width, 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; + } } } } @@ -292,18 +262,6 @@ void wxMDIParentFrame::ActivatePrevious() gtk_notebook_prev_page( GTK_NOTEBOOK(m_clientWindow->m_widget) ); } -bool wxMDIParentFrame::HasVisibleMenubar() const -{ - if (wxFrame::HasVisibleMenubar()) - return true; - - wxMDIChildFrame* active_child_frame = GetActiveChild(); - wxMenuBar* menubar = NULL; - if (active_child_frame) - menubar = active_child_frame->m_menuBar; - return menubar && menubar->IsShown(); -} - //----------------------------------------------------------------------------- // wxMDIChildFrame //----------------------------------------------------------------------------- @@ -383,11 +341,18 @@ void wxMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar ) m_menuBar->SetParent( mdi_frame ); /* insert the invisible menu bar into the _parent_ mdi frame */ - int w; - mdi_frame->GTKDoGetSize(&w, NULL); - gtk_pizza_put( GTK_PIZZA(mdi_frame->m_mainWidget), - m_menuBar->m_widget, - 0, 0, w, 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); } } @@ -433,26 +398,6 @@ void wxMDIChildFrame::SetTitle( const wxString &title ) 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, wxMDIChildFrame *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 //----------------------------------------------------------------------------- @@ -466,9 +411,6 @@ static void wxInsertChildInMDI(wxWindow* parent, wxWindow* 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 ); diff --git a/src/gtk/menu.cpp b/src/gtk/menu.cpp index 98a7ea30de..718e3c801b 100644 --- a/src/gtk/menu.cpp +++ b/src/gtk/menu.cpp @@ -26,10 +26,6 @@ #include "wx/stockitem.h" #include "wx/gtk/private.h" -#ifdef __WXGTK20__ -#include -#endif - // FIXME: is this right? somehow I don't think so (VZ) #define gtk_accel_group_attach(g, o) gtk_window_add_accel_group((o), (g)) @@ -390,21 +386,8 @@ bool wxMenuBar::GtkAppend(wxMenu *menu, const wxString& title, int pos) // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables // addings menu later on. if (m_invokingWindow) - { wxMenubarSetInvokingWindow( menu, m_invokingWindow ); - // OPTIMISE ME: we should probably cache this, or pass it - // directly, but for now this is a minimal - // change to validate the new dynamic sizing. - // see (and refactor :) similar code in Remove - // below. - - wxFrame *frame = wxDynamicCast( m_invokingWindow, wxFrame ); - - if( frame ) - frame->UpdateMenuBarSize(); - } - return true; } @@ -447,16 +430,7 @@ wxMenu *wxMenuBar::Remove(size_t pos) menu->m_owner = NULL; if (m_invokingWindow) - { - // OPTIMISE ME: see comment in GtkAppend - wxFrame *frame = wxDynamicCast( m_invokingWindow, wxFrame ); - - if( frame ) - frame->UpdateMenuBarSize(); - wxMenubarUnsetInvokingWindow( menu, m_invokingWindow ); - } - return menu; } diff --git a/src/gtk/minifram.cpp b/src/gtk/minifram.cpp index 98fff86c66..ae4a543418 100644 --- a/src/gtk/minifram.cpp +++ b/src/gtk/minifram.cpp @@ -20,8 +20,7 @@ #include "wx/image.h" #endif -#include "wx/gtk/win_gtk.h" -#include "wx/gtk/private.h" +#include //----------------------------------------------------------------------------- // data @@ -29,7 +28,6 @@ extern bool g_blockEventsOnDrag; extern bool g_blockEventsOnScroll; -extern GtkWidget *wxGetRootWindow(); //----------------------------------------------------------------------------- // "expose_event" of m_mainWidget @@ -63,10 +61,8 @@ static gboolean gtk_window_own_expose_callback(GtkWidget* widget, GdkEventExpose if (!win->m_hasVMT || gdk_event->count > 0) return false; - GtkPizza *pizza = GTK_PIZZA(widget); - gtk_paint_shadow (widget->style, - pizza->bin_window, + widget->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, NULL, NULL, // FIXME: No clipping? @@ -76,15 +72,15 @@ static gboolean gtk_window_own_expose_callback(GtkWidget* widget, GdkEventExpose int style = win->GetWindowStyle(); wxClientDC dc(win); - + #if wxUSE_NEW_DC wxImplDC *impl = dc.GetImpl(); wxGTKClientImplDC *client_impl = wxDynamicCast( impl, wxGTKClientImplDC ); // Hack alert - client_impl->m_window = pizza->bin_window; + client_impl->m_window = widget->window; #else // Hack alert - dc.m_window = pizza->bin_window; + dc.m_window = widget->window; #endif if (style & wxRESIZE_BORDER) @@ -130,9 +126,6 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton if (win->m_isDragging) return TRUE; - GtkPizza *pizza = GTK_PIZZA(widget); - if (gdk_event->window != pizza->bin_window) return TRUE; - int style = win->GetWindowStyle(); int y = (int)gdk_event->y; @@ -143,7 +136,7 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton { GtkWidget *ancestor = gtk_widget_get_toplevel( widget ); - GdkWindow *source = GTK_PIZZA(widget)->bin_window; + GdkWindow *source = widget->window; int org_x = 0; int org_y = 0; @@ -304,11 +297,25 @@ gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, win->m_y = y; gtk_window_move( GTK_WINDOW(win->m_widget), x, y ); - return TRUE; } } +//----------------------------------------------------------------------------- +// "size_allocate" from GtkFixed, parent of m_mainWidget +//----------------------------------------------------------------------------- + +extern "C" { +static void size_allocate(GtkWidget*, GtkAllocation* alloc, wxMiniFrame* win) +{ + // place m_mainWidget inside of decorations drawn on the GtkFixed + GtkAllocation alloc2 = win->m_mainWidget->allocation; + alloc2.width = alloc->width - 2 * win->m_miniEdge; + alloc2.height = alloc->height - win->m_miniTitle - 2 * win->m_miniEdge; + gtk_widget_size_allocate(win->m_mainWidget, &alloc2); +} +} + //----------------------------------------------------------------------------- // wxMiniFrame //----------------------------------------------------------------------------- @@ -340,6 +347,27 @@ bool wxMiniFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title wxFrame::Create( parent, id, title, pos, size, style, name ); + // borders and title are on a GtkFixed between m_widget and m_mainWidget + GtkWidget* fixed = gtk_fixed_new(); + gtk_fixed_set_has_window((GtkFixed*)fixed, true); + gtk_widget_add_events(fixed, + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK | + GDK_BUTTON_MOTION_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_LEAVE_NOTIFY_MASK); + gtk_widget_show(fixed); + gtk_widget_reparent(m_mainWidget, fixed); + gtk_container_add((GtkContainer*)m_widget, fixed); + gtk_fixed_move((GtkFixed*)fixed, m_mainWidget, m_miniEdge, m_miniTitle + m_miniEdge); + g_signal_connect(fixed, "size_allocate", G_CALLBACK(size_allocate), this); + + m_gdkDecor = 0; + m_gdkFunc = 0; + if (style & wxRESIZE_BORDER) + m_gdkFunc = GDK_FUNC_RESIZE; + if (m_parent && (GTK_IS_WINDOW(m_parent->m_widget))) { gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(m_parent->m_widget) ); @@ -355,27 +383,43 @@ bool wxMiniFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title } /* these are called when the borders are drawn */ - g_signal_connect (m_mainWidget, "expose_event", + g_signal_connect_after(fixed, "expose_event", G_CALLBACK (gtk_window_own_expose_callback), this ); /* these are required for dragging the mini frame around */ - g_signal_connect (m_mainWidget, "button_press_event", + g_signal_connect (fixed, "button_press_event", G_CALLBACK (gtk_window_button_press_callback), this); - g_signal_connect (m_mainWidget, "button_release_event", + g_signal_connect (fixed, "button_release_event", G_CALLBACK (gtk_window_button_release_callback), this); - g_signal_connect (m_mainWidget, "motion_notify_event", + g_signal_connect (fixed, "motion_notify_event", G_CALLBACK (gtk_window_motion_notify_callback), this); - g_signal_connect (m_mainWidget, "leave_notify_event", + g_signal_connect (fixed, "leave_notify_event", G_CALLBACK (gtk_window_leave_callback), this); return true; } +void wxMiniFrame::DoGetClientSize(int* width, int* height) const +{ + wxFrame::DoGetClientSize(width, height); + if (width) + { + *width -= 2 * m_miniEdge; + if (*width < 0) *width = 0; + } + if (height) + { + *height -= m_miniTitle + 2 * m_miniEdge; + if (*height < 0) *height = 0; + } +} + void wxMiniFrame::SetTitle( const wxString &title ) { wxFrame::SetTitle( title ); - if (GTK_PIZZA(m_mainWidget)->bin_window) - gdk_window_invalidate_rect( GTK_PIZZA(m_mainWidget)->bin_window, NULL, true ); + GtkWidget* fixed = GTK_BIN(m_widget)->child; + if (fixed->window) + gdk_window_invalidate_rect(fixed->window, NULL, false); } #endif // wxUSE_MINIFRAME diff --git a/src/gtk/popupwin.cpp b/src/gtk/popupwin.cpp index 6e1048917c..2dafe977bb 100644 --- a/src/gtk/popupwin.cpp +++ b/src/gtk/popupwin.cpp @@ -15,9 +15,6 @@ #include "wx/popupwin.h" #ifndef WX_PRECOMP - #include "wx/app.h" - #include "wx/frame.h" - #include "wx/cursor.h" #endif // WX_PRECOMP #include @@ -131,11 +128,11 @@ static void wxInsertChildInPopupWin(wxWindowGTK* parent, wxWindowGTK* child) // wxPopupWindow //----------------------------------------------------------------------------- -BEGIN_EVENT_TABLE(wxPopupWindow,wxPopupWindowBase) #ifdef __WXUNIVERSAL__ +BEGIN_EVENT_TABLE(wxPopupWindow,wxPopupWindowBase) EVT_SIZE(wxPopupWindow::OnSize) -#endif END_EVENT_TABLE() +#endif wxPopupWindow::~wxPopupWindow() { @@ -143,8 +140,6 @@ wxPopupWindow::~wxPopupWindow() bool wxPopupWindow::Create( wxWindow *parent, int style ) { - m_sizeSet = false; - if (!PreCreation( parent, wxDefaultPosition, wxDefaultSize ) || !CreateBase( parent, -1, wxDefaultPosition, wxDefaultSize, style, wxDefaultValidator, wxT("popup") )) { @@ -203,41 +198,20 @@ void wxPopupWindow::DoSetSize( int x, int y, int width, int height, int sizeFlag wxASSERT_MSG( (m_widget != NULL), wxT("invalid dialog") ); wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid dialog") ); - if (m_resizing) return; /* I don't like recursions */ - m_resizing = true; - int old_x = m_x; int old_y = m_y; int old_width = m_width; int old_height = m_height; - if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0) - { - if (x != -1) m_x = x; - if (y != -1) m_y = y; - if (width != -1) m_width = width; - if (height != -1) m_height = height; - } - else - { + if (x != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) m_x = x; + if (y != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) m_y = y; + if (width != -1) m_width = width; + if (height != -1) m_height = height; - } - -/* - if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH) - { - if (width == -1) m_width = 80; - } - - if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT) - { - if (height == -1) m_height = 26; - } -*/ ConstrainSize(); @@ -245,75 +219,27 @@ void wxPopupWindow::DoSetSize( int x, int y, int width, int height, int sizeFlag { if ((m_x != old_x) || (m_y != old_y)) { - /* we set the position here and when showing the dialog - for the first time in idle time */ - // Where does that happen in idle time? I do not see it anywhere - MR gtk_window_move( GTK_WINDOW(m_widget), m_x, m_y ); } } if ((m_width != old_width) || (m_height != old_height)) { + // gtk_window_resize does not work for GTK_WINDOW_POPUP gtk_widget_set_size_request( m_widget, m_width, m_height ); - - /* actual resizing is deferred to GtkOnSize in idle time and - when showing the dialog */ - m_sizeSet = false; - + wxSizeEvent event(GetSize(), GetId()); + event.SetEventObject(this); + GetEventHandler()->ProcessEvent(event); } - - m_resizing = false; -} - -void wxPopupWindow::GtkOnSize() -{ - if (m_sizeSet) return; - if (!m_wxwindow) return; - - /* FIXME: is this a hack? */ - /* Since for some reason GTK will revert to using maximum size ever set - for this window, we have to set geometry hints maxsize to match size - given. Also set the to that minsize since resizing isn't possible - anyway. */ - - /* set size hints */ - gint flag = GDK_HINT_MAX_SIZE | GDK_HINT_MIN_SIZE; // GDK_HINT_POS; - GdkGeometry geom; - geom.min_width = m_width; - geom.min_height = m_height; - geom.max_width = m_width; - geom.max_height = m_height; - gtk_window_set_geometry_hints( GTK_WINDOW(m_widget), - (GtkWidget*) NULL, - &geom, - (GdkWindowHints) flag ); - - - m_sizeSet = true; - - wxSizeEvent event( wxSize(m_width,m_height), GetId() ); - event.SetEventObject( this ); - GetEventHandler()->ProcessEvent( event ); -} - -void wxPopupWindow::OnInternalIdle() -{ - if (!m_sizeSet && GTK_WIDGET_REALIZED(m_wxwindow)) - GtkOnSize(); - - wxWindow::OnInternalIdle(); } bool wxPopupWindow::Show( bool show ) { - if (show && !m_sizeSet) + if (show && !IsShown()) { - /* by calling GtkOnSize here, we don't have to call - either after showing the frame, which would entail - much ugly flicker nor from within the size_allocate - handler, because GTK 1.1.X forbids that. */ - - GtkOnSize(); + wxSizeEvent event(GetSize(), GetId()); + event.SetEventObject(this); + GetEventHandler()->ProcessEvent(event); } bool ret = wxWindow::Show( show ); diff --git a/src/gtk/tbargtk.cpp b/src/gtk/tbargtk.cpp index d81c1fb2a6..b403ca69d6 100644 --- a/src/gtk/tbargtk.cpp +++ b/src/gtk/tbargtk.cpp @@ -8,14 +8,6 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -// ============================================================================ -// declarations -// ============================================================================ - -// ---------------------------------------------------------------------------- -// headers -// ---------------------------------------------------------------------------- - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -333,6 +325,20 @@ static gint gtk_toolbar_tool_callback( GtkWidget *WXUNUSED(widget), } } +//----------------------------------------------------------------------------- +// "size_request" from m_toolbar +//----------------------------------------------------------------------------- + +extern "C" { +static void +size_request(GtkWidget*, GtkRequisition* req, wxToolBar* win) +{ + const wxSize margins = win->GetMargins(); + req->width += margins.x; + req->height += 2 * margins.y; +} +} + //----------------------------------------------------------------------------- // InsertChild callback for wxToolBar //----------------------------------------------------------------------------- @@ -445,6 +451,9 @@ bool wxToolBar::Create( wxWindow *parent, PostCreation(size); + g_signal_connect_after(m_toolbar, "size_request", + G_CALLBACK(size_request), this); + return true; } @@ -635,11 +644,6 @@ bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase) break; } - GtkRequisition req; - (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(m_widget) )->size_request ) - (m_widget, &req ); - m_width = req.width + m_xMargin; - m_height = req.height + 2*m_yMargin; InvalidateBestSize(); return true; diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp index 51ac28e480..28503b6538 100644 --- a/src/gtk/toplevel.cpp +++ b/src/gtk/toplevel.cpp @@ -215,27 +215,30 @@ static wxSize& GetDecorSize(int decor) } //----------------------------------------------------------------------------- -// "size_allocate" +// "size_allocate" from m_wxwindow //----------------------------------------------------------------------------- extern "C" { -static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxTopLevelWindowGTK *win ) +static void +size_allocate(GtkWidget*, GtkAllocation* alloc, wxTopLevelWindowGTK* win) { - if (!win->m_hasVMT) - return; - - wxSize sizeDecor; - if (!win->IsFullScreen()) - sizeDecor = GetDecorSize(win->m_gdkDecor); - const int w = alloc->width + sizeDecor.x; - const int h = alloc->height + sizeDecor.y; - - if (win->m_width != w || win->m_height != h) + if (win->m_oldClientWidth != alloc->width || + win->m_oldClientHeight != alloc->height) { - win->m_width = w; - win->m_height = h; - - win->GtkUpdateSize(); + win->m_oldClientWidth = alloc->width; + win->m_oldClientHeight = alloc->height; + wxSize sizeDecor; + if (!win->IsFullScreen()) + sizeDecor = GetDecorSize(win->m_gdkDecor); + win->m_width = win->m_widget->allocation.width + sizeDecor.x; + win->m_height = win->m_widget->allocation.height + sizeDecor.y; + if (!win->IsIconized()) + { + wxSizeEvent event(win->GetSize(), win->GetId()); + event.SetEventObject(win); + win->GetEventHandler()->ProcessEvent(event); + } + // else the window is currently unmapped, don't generate size events } } } @@ -362,8 +365,10 @@ gtk_frame_map_callback( GtkWidget* widget, // Update window size and frame extents cache win->m_width = rect.width; win->m_height = rect.height; - win->GtkUpdateSize(); decorSize = size; + wxSizeEvent event(win->GetSize(), win->GetId()); + event.SetEventObject(win); + win->GetEventHandler()->ProcessEvent(event); } } @@ -434,8 +439,10 @@ static gboolean property_notify_event( win->m_height += size.y - decorSize.y; if (win->m_width < 0) win->m_width = 0; if (win->m_height < 0) win->m_height = 0; - win->GtkUpdateSize(); decorSize = size; + wxSizeEvent event(win->GetSize(), win->GetId()); + event.SetEventObject(win); + win->GetEventHandler()->ProcessEvent(event); } } if (data) @@ -451,9 +458,6 @@ static gboolean property_notify_event( void wxTopLevelWindowGTK::Init() { - m_sizeSet = false; - m_miniEdge = 0; - m_miniTitle = 0; m_mainWidget = (GtkWidget*) NULL; m_isIconized = false; m_fsIsShowing = false; @@ -493,9 +497,9 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, // e.g. in wxTaskBarIconAreaGTK if (m_widget == NULL) { + m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL); if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) { - m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL); // Tell WM that this is a dialog window and make it center // on parent by default (this is what GtkDialog ctor does): gtk_window_set_type_hint(GTK_WINDOW(m_widget), @@ -505,7 +509,6 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, } else { - m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL); #if GTK_CHECK_VERSION(2,1,0) if (!gtk_check_version(2,1,0)) { @@ -567,14 +570,14 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, g_signal_connect (m_widget, "delete_event", G_CALLBACK (gtk_frame_delete_callback), this); - // m_mainWidget holds the toolbar, the menubar and the client area - m_mainWidget = gtk_pizza_new(); + // m_mainWidget is a GtkVBox, holding the bars and client area (m_wxwindow) + m_mainWidget = gtk_vbox_new(false, 0); gtk_widget_show( m_mainWidget ); GTK_WIDGET_UNSET_FLAGS( m_mainWidget, GTK_CAN_FOCUS ); gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget ); - // m_wxwindow only represents the client area without toolbar and menubar - m_wxwindow = gtk_pizza_new(); + // m_wxwindow is the client area + m_wxwindow = gtk_pizza_new_no_scroll(); gtk_widget_show( m_wxwindow ); gtk_container_add( GTK_CONTAINER(m_mainWidget), m_wxwindow ); @@ -584,9 +587,8 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, if (m_parent) m_parent->AddChild( this ); - // the user resized the frame by dragging etc. - g_signal_connect (m_widget, "size_allocate", - G_CALLBACK (gtk_frame_size_callback), this); + g_signal_connect(m_wxwindow, "size_allocate", + G_CALLBACK(size_allocate), this); g_signal_connect (m_widget, "size_request", G_CALLBACK (wxgtk_tlw_size_request_callback), this); @@ -627,15 +629,6 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, m_gdkFunc = 0; } else - if (m_miniEdge > 0) - { - m_gdkDecor = 0; - m_gdkFunc = 0; - - if ((style & wxRESIZE_BORDER) != 0) - m_gdkFunc |= GDK_FUNC_RESIZE; - } - else { m_gdkDecor = GDK_DECOR_BORDER; m_gdkFunc = GDK_FUNC_MOVE; @@ -812,22 +805,19 @@ bool wxTopLevelWindowGTK::Show( bool show ) { wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") ); - if (show == IsShown()) - return false; - - if (show && !m_sizeSet) + if (show && !IsShown()) { - /* by calling GtkOnSize here, we don't have to call - either after showing the frame, which would entail - much ugly flicker or from within the size_allocate - handler, because GTK 1.1.X forbids that. */ - - GtkOnSize(); + // size_allocate signals occur in reverse order (bottom to top). + // Things work better if the initial wxSizeEvents are sent (from the + // top down), before the initial size_allocate signals occur. + wxSizeEvent event(GetSize(), GetId()); + event.SetEventObject(this); + GetEventHandler()->ProcessEvent(event); } - wxTopLevelWindowBase::Show(show); + bool change = wxTopLevelWindowBase::Show(show); - if (!show) + if (change && !show) { // make sure window has a non-default position, so when it is shown // again, it won't be repositioned by WM as if it were a new window @@ -835,7 +825,7 @@ bool wxTopLevelWindowGTK::Show( bool show ) gtk_window_move((GtkWindow*)m_widget, m_x, m_y); } - return true; + return change; } void wxTopLevelWindowGTK::Raise() @@ -896,8 +886,6 @@ void wxTopLevelWindowGTK::DoSetSize( int x, int y, int width, int height, int si gtk_window_move( GTK_WINDOW(m_widget), m_x, m_y ); } - m_resizing = true; - const wxSize oldSize(m_width, m_height); if (width >= 0) m_width = width; @@ -909,13 +897,18 @@ void wxTopLevelWindowGTK::DoSetSize( int x, int y, int width, int height, int si int w, h; GTKDoGetSize(&w, &h); gtk_window_resize(GTK_WINDOW(m_widget), w, h); - GtkUpdateSize(); + + GetClientSize(&m_oldClientWidth, &m_oldClientHeight); + wxSizeEvent event(GetSize(), GetId()); + event.SetEventObject(this); + GetEventHandler()->ProcessEvent(event); } - m_resizing = false; } void wxTopLevelWindowGTK::DoGetClientSize( int *width, int *height ) const { + wxASSERT_MSG(m_widget, wxT("invalid frame")); + if ( IsIconized() ) { // for consistency with wxMSW, client area is supposed to be empty for @@ -924,25 +917,10 @@ void wxTopLevelWindowGTK::DoGetClientSize( int *width, int *height ) const *width = 0; if ( height ) *height = 0; - - return; } - - wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") ); - - int w, h; - GTKDoGetSize(&w, &h); - if (width) - { - *width = w - 2 * m_miniEdge; - if (*width < 0) - *width = 0; - } - if (height) + else { - *height = h - 2 * m_miniEdge - m_miniTitle; - if (*height < 0) - *height = 0; + GTKDoGetSize(width, height); } } @@ -987,35 +965,6 @@ void wxTopLevelWindowGTK::DoSetSizeHints( int minW, int minH, (GtkWindow*)m_widget, NULL, &hints, (GdkWindowHints)hints_mask); } -void wxTopLevelWindowGTK::GtkOnSize() -{ - // avoid recursions - if (m_resizing) return; - m_resizing = true; - - if ( m_wxwindow == NULL ) return; - - ConstrainSize(); - - if (m_mainWidget) - { - int w, h; - GTKDoGetSize(&w, &h); - gtk_pizza_set_size( GTK_PIZZA(m_mainWidget), - m_wxwindow, - 0, 0, w, h); - } - - m_sizeSet = true; - - // send size event to frame - wxSizeEvent event( wxSize(m_width,m_height), GetId() ); - event.SetEventObject( this ); - GetEventHandler()->ProcessEvent( event ); - - m_resizing = false; -} - bool wxTopLevelWindowGTK::IsDecorCacheable() const { return true; @@ -1023,14 +972,6 @@ bool wxTopLevelWindowGTK::IsDecorCacheable() const void wxTopLevelWindowGTK::OnInternalIdle() { - if (!m_sizeSet && GTK_WIDGET_REALIZED(m_wxwindow)) - { - GtkOnSize(); - - // we'll come back later - return; - } - // set the focus if not done yet and if we can already do it if ( GTK_WIDGET_REALIZED(m_wxwindow) ) { diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 115e27d54f..18a1c409d5 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -19,15 +19,11 @@ #ifndef WX_PRECOMP #include "wx/log.h" #include "wx/app.h" - #include "wx/frame.h" + #include "wx/toplevel.h" #include "wx/dcclient.h" #include "wx/menu.h" #include "wx/settings.h" #include "wx/msgdlg.h" - #include "wx/textctrl.h" - #include "wx/toolbar.h" - #include "wx/combobox.h" - #include "wx/layout.h" #include "wx/math.h" #endif @@ -429,7 +425,7 @@ extern "C" { static void wxgtk_combo_size_request_callback(GtkWidget * WXUNUSED(widget), GtkRequisition *requisition, - wxComboBox *win) + wxWindow* win) { // This callback is actually hooked into the text entry // of the combo box, not the GtkHBox. @@ -2065,34 +2061,36 @@ gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win ) } //----------------------------------------------------------------------------- -// "size_allocate" +// "size_allocate" from m_wxwindow or m_widget //----------------------------------------------------------------------------- -static -void gtk_window_size_callback( GtkWidget *WXUNUSED(widget), - GtkAllocation * WXUNUSED(alloc), - wxWindow *win ) +static void +size_allocate(GtkWidget*, GtkAllocation* alloc, wxWindow* win) { - int client_width = 0; - int client_height = 0; - win->GetClientSize( &client_width, &client_height ); - if ((client_width == win->m_oldClientWidth) && (client_height == win->m_oldClientHeight)) - return; - - if ( !client_width && !client_height ) - { - // the window is currently unmapped, don't generate size events - return; - } - - win->m_oldClientWidth = client_width; - win->m_oldClientHeight = client_height; - - if (!win->m_nativeSizeEvent) + int w = alloc->width; + int h = alloc->height; + if (win->m_wxwindow) { - wxSizeEvent event( win->GetSize(), win->GetId() ); - event.SetEventObject( win ); - win->GTKProcessEvent( event ); + const int border = GTK_CONTAINER(win->m_wxwindow)->border_width; + w -= 2 * border; + h -= 2 * border; + if (w < 0) w = 0; + if (h < 0) h = 0; + } + if (win->m_oldClientWidth != w || win->m_oldClientHeight != h) + { + win->m_oldClientWidth = w; + win->m_oldClientHeight = h; + // this callback can be connected to m_wxwindow, + // so always get size from m_widget->allocation + win->m_width = win->m_widget->allocation.width; + win->m_height = win->m_widget->allocation.height; + if (!win->m_nativeSizeEvent) + { + wxSizeEvent event(win->GetSize(), win->GetId()); + event.SetEventObject(win); + win->GTKProcessEvent(event); + } } } @@ -2240,8 +2238,6 @@ void wxWindowGTK::Init() m_oldClientWidth = m_oldClientHeight = 0; - m_resizing = false; - m_insertCallback = wxInsertChildInWindow; m_hasFocus = false; @@ -2525,11 +2521,14 @@ void wxWindowGTK::PostCreation() g_signal_connect (connect_widget, "realize", G_CALLBACK (gtk_window_realized_callback), this); + if (!IsTopLevel()) + { + g_signal_connect(m_wxwindow ? m_wxwindow : m_widget, "size_allocate", + G_CALLBACK(size_allocate), this); + } + if (m_wxwindow) { - // Catch native resize events - g_signal_connect (m_wxwindow, "size_allocate", - G_CALLBACK (gtk_window_size_callback), this); #if GTK_CHECK_VERSION(2, 8, 0) if (!gtk_check_version(2,8,0)) { @@ -2654,9 +2653,6 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") ); wxASSERT_MSG( (m_parent != NULL), wxT("wxWindowGTK::SetSize requires parent.\n") ); - if (m_resizing) return; /* I don't like recursions */ - m_resizing = true; - int currentX, currentY; GetPosition(¤tX, ¤tY); if (x == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) @@ -2676,6 +2672,7 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags height = sizeBest.y; } + const wxSize oldSize(m_width, m_height); if (width != -1) m_width = width; if (height != -1) @@ -2683,36 +2680,11 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags ConstrainSize(); -#if wxUSE_TOOLBAR_NATIVE - if (wxDynamicCast(GetParent(), wxToolBar)) - { - // don't take the x,y values, they're wrong because toolbar sets them - GtkWidget *widget = m_widget; - gtk_widget_set_size_request (widget, m_width, m_height); - } - else -#endif - if (m_parent->m_wxwindow == NULL) // i.e. wxNotebook - { - // don't set the size for children of wxNotebook, just take the values. - m_x = x; - m_y = y; - m_width = width; - m_height = height; - } - else + if (m_parent->m_wxwindow) { GtkPizza *pizza = GTK_PIZZA(m_parent->m_wxwindow); - if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0) - { - if (x != -1) m_x = x + gtk_pizza_get_xoffset( pizza ); - if (y != -1) m_y = y + gtk_pizza_get_yoffset( pizza ); - } - else - { - m_x = x + gtk_pizza_get_xoffset( pizza ); - m_y = y + gtk_pizza_get_yoffset( pizza ); - } + m_x = x + gtk_pizza_get_xoffset(pizza); + m_y = y + gtk_pizza_get_yoffset(pizza); int left_border = 0; int right_border = 0; @@ -2740,32 +2712,20 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags m_height+top_border+bottom_border ); } - if (m_hasScrolling) + if (m_width != oldSize.x || m_height != oldSize.y) { - /* Sometimes the client area changes size without the - whole windows's size changing, but if the whole - windows's size doesn't change, no wxSizeEvent will - normally be sent. Here we add an extra test if - the client test has been changed and this will - be used then. */ + // update these variables to keep size_allocate handler + // from sending another size event for this change GetClientSize( &m_oldClientWidth, &m_oldClientHeight ); - } - -/* - wxPrintf( "OnSize sent from " ); - if (GetClassInfo() && GetClassInfo()->GetClassName()) - wxPrintf( GetClassInfo()->GetClassName() ); - wxPrintf( " %d %d %d %d\n", (int)m_x, (int)m_y, (int)m_width, (int)m_height ); -*/ - if (!m_nativeSizeEvent) - { - wxSizeEvent event( wxSize(m_width,m_height), GetId() ); - event.SetEventObject( this ); - GetEventHandler()->ProcessEvent( event ); + gtk_widget_queue_resize(m_widget); + if (!m_nativeSizeEvent) + { + wxSizeEvent event( wxSize(m_width,m_height), GetId() ); + event.SetEventObject( this ); + GetEventHandler()->ProcessEvent( event ); + } } - - m_resizing = false; } bool wxWindowGTK::GtkShowFromOnIdle() -- 2.45.2