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
This commit is contained in:
Paul Cornett
2007-10-24 18:07:24 +00:00
parent a2d3826500
commit cca410b336
16 changed files with 343 additions and 900 deletions

View File

@@ -10,17 +10,6 @@
#ifndef _WX_GTK_FRAME_H_ #ifndef _WX_GTK_FRAME_H_
#define _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 // wxFrame
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -68,13 +57,8 @@ public:
// -------------------------- // --------------------------
// GTK callbacks // GTK callbacks
virtual void GtkOnSize();
virtual void OnInternalIdle(); virtual void OnInternalIdle();
bool m_menuBarDetached;
int m_menuBarHeight;
bool m_toolBarDetached;
protected: protected:
// common part of all ctors // common part of all ctors
void Init(); void Init();
@@ -85,13 +69,6 @@ protected:
#if wxUSE_MENUS_NATIVE #if wxUSE_MENUS_NATIVE
virtual void DetachMenuBar(); virtual void DetachMenuBar();
virtual void AttachMenuBar(wxMenuBar *menubar); 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 #endif // wxUSE_MENUS_NATIVE
private: private:

View File

@@ -12,6 +12,9 @@
#include "wx/frame.h" #include "wx/frame.h"
class WXDLLIMPEXP_FWD_CORE wxMDIChildFrame;
class WXDLLIMPEXP_FWD_CORE wxMDIClientWindow;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// wxMDIParentFrame // wxMDIParentFrame
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -58,12 +61,11 @@ public:
wxMDIClientWindow *m_clientWindow; wxMDIClientWindow *m_clientWindow;
bool m_justInserted; bool m_justInserted;
virtual void GtkOnSize();
virtual void OnInternalIdle(); virtual void OnInternalIdle();
protected: protected:
void Init(); void Init();
virtual bool HasVisibleMenubar() const; virtual void DoGetClientSize(int* width, int* height) const;
private: private:
friend class wxMDIChildFrame; friend class wxMDIChildFrame;

View File

@@ -7,23 +7,12 @@
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#ifndef __GTKMINIFRAMEH__ #ifndef _WX_GTK_MINIFRAME_H_
#define __GTKMINIFRAMEH__ #define _WX_GTK_MINIFRAME_H_
#include "wx/defs.h"
#if wxUSE_MINIFRAME
#include "wx/object.h"
#include "wx/bitmap.h" #include "wx/bitmap.h"
#include "wx/frame.h" #include "wx/frame.h"
//-----------------------------------------------------------------------------
// classes
//-----------------------------------------------------------------------------
class WXDLLIMPEXP_FWD_CORE wxMiniFrame;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// wxMiniFrame // wxMiniFrame
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -54,15 +43,18 @@ public:
const wxString& name = wxFrameNameStr); const wxString& name = wxFrameNameStr);
virtual void SetTitle( const wxString &title ); virtual void SetTitle( const wxString &title );
protected:
virtual void DoGetClientSize(int* width, int* height) const;
// implementation // implementation
public:
bool m_isDragging; bool m_isDragging;
int m_oldX,m_oldY; int m_oldX,m_oldY;
int m_diffX,m_diffY; int m_diffX,m_diffY;
wxBitmap m_closeButton; wxBitmap m_closeButton;
int m_miniEdge;
int m_miniTitle;
}; };
#endif #endif // _WX_GTK_MINIFRAME_H_
#endif
// __GTKMINIFRAMEH__

View File

@@ -25,20 +25,15 @@ public:
{ (void)Create(parent, flags); } { (void)Create(parent, flags); }
bool Create(wxWindow *parent, int flags = wxBORDER_NONE); bool Create(wxWindow *parent, int flags = wxBORDER_NONE);
virtual bool Show( bool show = TRUE ); virtual bool Show(bool show = true);
// implementation // implementation
// -------------- // --------------
virtual void OnInternalIdle();
// GTK time when connecting to button_press signal // GTK time when connecting to button_press signal
wxUint32 m_time; wxUint32 m_time;
protected: protected:
void GtkOnSize();
virtual void DoSetSize(int x, int y, virtual void DoSetSize(int x, int y,
int width, int height, int width, int height,
int sizeFlags = wxSIZE_AUTO); int sizeFlags = wxSIZE_AUTO);
@@ -46,9 +41,9 @@ protected:
virtual void DoMoveWindow(int x, int y, int width, int height); virtual void DoMoveWindow(int x, int y, int width, int height);
private: private:
bool m_sizeSet; #ifdef __WXUNIVERSAL__
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
#endif
DECLARE_DYNAMIC_CLASS(wxPopupWindow) DECLARE_DYNAMIC_CLASS(wxPopupWindow)
}; };

View File

@@ -83,14 +83,11 @@ public:
// -------------------------- // --------------------------
// GTK callbacks // GTK callbacks
virtual void GtkOnSize();
virtual void OnInternalIdle(); virtual void OnInternalIdle();
// do *not* call this to iconize the frame, this is a private function! // do *not* call this to iconize the frame, this is a private function!
void SetIconizeState(bool iconic); void SetIconizeState(bool iconic);
int m_miniEdge,
m_miniTitle;
GtkWidget *m_mainWidget; GtkWidget *m_mainWidget;
bool m_fsIsShowing; /* full screen */ bool m_fsIsShowing; /* full screen */
@@ -101,8 +98,6 @@ public:
int m_gdkFunc, int m_gdkFunc,
m_gdkDecor; m_gdkDecor;
bool m_sizeSet;
// private gtk_timeout_add result for mimicing wxUSER_ATTENTION_INFO and // 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. // wxUSER_ATTENTION_ERROR difference, -2 for no hint, -1 for ERROR hint, rest for GtkTimeout handle.
int m_urgency_hint; int m_urgency_hint;
@@ -116,8 +111,6 @@ public:
// return the size of the window without WM decorations // return the size of the window without WM decorations
void GTKDoGetSize(int *width, int *height) const; void GTKDoGetSize(int *width, int *height) const;
void GtkUpdateSize() { m_sizeSet = false; }
// whether frame extents are accurate // whether frame extents are accurate
virtual bool IsDecorCacheable() const; virtual bool IsDecorCacheable() const;
@@ -139,6 +132,7 @@ protected:
// string shown in the title bar // string shown in the title bar
wxString m_title; wxString m_title;
private:
// is the frame currently iconized? // is the frame currently iconized?
bool m_isIconized; bool m_isIconized;

View File

@@ -60,7 +60,7 @@ public:
virtual bool IsRetained() const; virtual bool IsRetained() const;
virtual void SetFocus(); virtual void SetFocus();
// hint from wx to native GTK+ tab traversal code // hint from wx to native GTK+ tab traversal code
virtual void SetCanFocus(bool canFocus); virtual void SetCanFocus(bool canFocus);
@@ -252,7 +252,7 @@ public:
// return true if the window is of a standard (i.e. not wxWidgets') class // return true if the window is of a standard (i.e. not wxWidgets') class
bool IsOfStandardClass() const { return m_wxwindow == NULL; } bool IsOfStandardClass() const { return m_wxwindow == NULL; }
// this widget will be queried for GTK's focus events // this widget will be queried for GTK's focus events
GtkWidget *m_focusWidget; GtkWidget *m_focusWidget;
@@ -284,13 +284,11 @@ public:
// find the direction of the given scrollbar (must be one of ours) // find the direction of the given scrollbar (must be one of ours)
ScrollDir ScrollDirFromRange(GtkRange *range) const; ScrollDir ScrollDirFromRange(GtkRange *range) const;
// extra (wxGTK-specific) flags // extra (wxGTK-specific) flags
bool m_noExpose:1; // wxGLCanvas has its own redrawing bool m_noExpose:1; // wxGLCanvas has its own redrawing
bool m_nativeSizeEvent:1; // wxGLCanvas sends wxSizeEvent upon "alloc_size" bool m_nativeSizeEvent:1; // wxGLCanvas sends wxSizeEvent upon "alloc_size"
bool m_hasScrolling:1; bool m_hasScrolling:1;
bool m_hasVMT:1; bool m_hasVMT:1;
bool m_resizing:1;
bool m_hasFocus:1; // true if == FindFocus() bool m_hasFocus:1; // true if == FindFocus()
bool m_isScrolling:1; // dragging scrollbar thumb? bool m_isScrolling:1; // dragging scrollbar thumb?
bool m_clipPaintRegion:1; // true after ScrollWindow() bool m_clipPaintRegion:1; // true after ScrollWindow()

View File

@@ -25,9 +25,6 @@
#include "wx/panel.h" #include "wx/panel.h"
#include "wx/gtk/private.h" #include "wx/gtk/private.h"
#include "wx/gtk/win_gtk.h"
#include <gtk/gtkexpander.h>
// ============================================================================ // ============================================================================
// implementation // implementation
@@ -120,39 +117,11 @@ gtk_collapsiblepane_expanded_callback(GObject * WXUNUSED(object),
// when the expander is collapsed!) // when the expander is collapsed!)
gtk_window_set_resizable (GTK_WINDOW (top->m_widget), p->IsExpanded()); gtk_window_set_resizable (GTK_WINDOW (top->m_widget), p->IsExpanded());
// 4) set size hints: note that this code has been taken and adapted // 4) set size hints
// from src/gtk/toplevel.cpp top->SetSizeHints(sz.x, sz.y);
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 );
// 5) set size
top->SetClientSize(sz);
} }
} }

View File

@@ -13,18 +13,12 @@
#include "wx/dialog.h" #include "wx/dialog.h"
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/app.h"
#include "wx/frame.h"
#include "wx/cursor.h" #include "wx/cursor.h"
#endif // WX_PRECOMP #endif // WX_PRECOMP
#include "wx/evtloop.h" #include "wx/evtloop.h"
#include <gdk/gdk.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "wx/gtk/win_gtk.h"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// global data // global data
@@ -42,7 +36,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxDialog,wxTopLevelWindow)
void wxDialog::Init() void wxDialog::Init()
{ {
m_returnCode = 0; m_returnCode = 0;
m_sizeSet = false;
m_modalShowing = false; m_modalShowing = false;
m_themeEnabled = true; m_themeEnabled = true;
} }
@@ -77,16 +70,6 @@ bool wxDialog::Show( bool show )
EndModal( wxID_CANCEL ); 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 ); bool ret = wxWindow::Show( show );
if (show) InitDialog(); if (show) InitDialog();

View File

@@ -19,14 +19,6 @@
#endif // WX_PRECOMP #endif // WX_PRECOMP
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "wx/gtk/win_gtk.h"
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
static const int wxSTATUS_HEIGHT = 25;
static const int wxPLACE_HOLDER = 0;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// event tables // event tables
@@ -38,87 +30,12 @@ IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxTopLevelWindow)
// implementation // 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 // wxFrame creation
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void wxFrame::Init() void wxFrame::Init()
{ {
m_menuBarDetached = false;
m_toolBarDetached = false;
m_menuBarHeight = 2;
m_fsSaveFlag = 0; m_fsSaveFlag = 0;
} }
@@ -153,33 +70,36 @@ void wxFrame::DoGetClientSize( int *width, int *height ) const
{ {
#if wxUSE_MENUS_NATIVE #if wxUSE_MENUS_NATIVE
// menu bar // 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 #endif // wxUSE_MENUS_NATIVE
#if wxUSE_STATUSBAR #if wxUSE_STATUSBAR
// status bar // status bar
if (m_frameStatusBar && GTK_WIDGET_VISIBLE(m_frameStatusBar->m_widget)) if (m_frameStatusBar && m_frameStatusBar->IsShown())
*height -= wxSTATUS_HEIGHT; *height -= m_frameStatusBar->m_height;
#endif // wxUSE_STATUSBAR #endif // wxUSE_STATUSBAR
} }
#if wxUSE_TOOLBAR #if wxUSE_TOOLBAR
// tool bar // tool bar
if (m_frameToolBar && if (m_frameToolBar && m_frameToolBar->IsShown())
GTK_WIDGET_VISIBLE(m_frameToolBar->m_widget) && !m_toolBarDetached)
{ {
GtkRequisition req;
gtk_widget_size_request(m_frameToolBar->m_widget, &req);
if (m_frameToolBar->IsVertical()) if (m_frameToolBar->IsVertical())
{ {
if (width) if (width)
*width -= m_frameToolBar->GetSize().x; *width -= req.width;
} }
else else
{ {
if (height) if (height)
*height -= m_frameToolBar->GetSize().y; *height -= req.height;
} }
} }
#endif // wxUSE_TOOLBAR #endif // wxUSE_TOOLBAR
@@ -239,188 +159,6 @@ bool wxFrame::ShowFullScreen(bool show, long style)
return true; 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() void wxFrame::OnInternalIdle()
{ {
wxFrameBase::OnInternalIdle(); wxFrameBase::OnInternalIdle();
@@ -464,23 +202,15 @@ void wxFrame::DetachMenuBar()
{ {
m_frameMenuBar->UnsetInvokingWindow( this ); 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_widget_ref( m_frameMenuBar->m_widget );
gtk_container_remove( GTK_CONTAINER(m_mainWidget), m_frameMenuBar->m_widget ); gtk_container_remove( GTK_CONTAINER(m_mainWidget), m_frameMenuBar->m_widget );
} }
wxFrameBase::DetachMenuBar(); wxFrameBase::DetachMenuBar();
// make sure next size_allocate causes a wxSizeEvent
m_oldClientWidth = 0;
} }
void wxFrame::AttachMenuBar( wxMenuBar *menuBar ) void wxFrame::AttachMenuBar( wxMenuBar *menuBar )
@@ -492,58 +222,29 @@ void wxFrame::AttachMenuBar( wxMenuBar *menuBar )
m_frameMenuBar->SetInvokingWindow( this ); m_frameMenuBar->SetInvokingWindow( this );
m_frameMenuBar->SetParent(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) // menubar goes into top of vbox (m_mainWidget)
{ gtk_box_pack_start(
g_signal_connect (menuBar->m_widget, "child_attached", GTK_BOX(m_mainWidget), menuBar->m_widget, false, false, 0);
G_CALLBACK (gtk_menu_attached_callback), gtk_box_reorder_child(GTK_BOX(m_mainWidget), menuBar->m_widget, 0);
this);
g_signal_connect (menuBar->m_widget, "child_detached", // disconnect wxWindowGTK "size_request" handler,
G_CALLBACK (gtk_menu_detached_callback), // it interferes with sizing of detached GtkHandleBox
this); 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);
// reset size request to allow native sizing to work
gtk_widget_set_size_request(menuBar->m_widget, -1, -1);
gtk_widget_show( m_frameMenuBar->m_widget ); gtk_widget_show( m_frameMenuBar->m_widget );
UpdateMenuBarSize();
} }
else // make sure next size_allocate causes a wxSizeEvent
{ m_oldClientWidth = 0;
m_menuBarHeight = 2;
GtkUpdateSize(); // resize window in OnInternalIdle
}
}
void wxFrame::UpdateMenuBarSize()
{
m_menuBarHeight = 2;
// 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;
}
// resize window in OnInternalIdle
GtkUpdateSize();
}
bool wxFrame::HasVisibleMenubar() const
{
return m_frameMenuBar && m_frameMenuBar->IsShown();
} }
#endif // wxUSE_MENUS_NATIVE #endif // wxUSE_MENUS_NATIVE
@@ -551,30 +252,61 @@ bool wxFrame::HasVisibleMenubar() const
void wxFrame::SetToolBar(wxToolBar *toolbar) void wxFrame::SetToolBar(wxToolBar *toolbar)
{ {
wxFrameBase::SetToolBar(toolbar); m_frameToolBar = toolbar;
if (toolbar)
if ( m_frameToolBar )
{ {
// insert into toolbar area if not already there if (toolbar->IsVertical())
if ((m_frameToolBar->m_widget->parent) &&
(m_frameToolBar->m_widget->parent != m_mainWidget))
{ {
GetChildren().DeleteObject( m_frameToolBar ); // 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);
gtk_widget_reparent( m_frameToolBar->m_widget, m_mainWidget ); 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 else
if (m_frameToolBar->HasFlag(wxTB_DOCKABLE))
{ {
g_signal_connect(m_frameToolBar->m_widget, "child_attached", // Horizontal toolbar goes into vbox (m_mainWidget)
G_CALLBACK(gtk_toolbar_attached_callback), this); gtk_widget_reparent(toolbar->m_widget, m_mainWidget);
g_signal_connect(m_frameToolBar->m_widget, "child_detached", gtk_box_set_child_packing(GTK_BOX(m_mainWidget),
G_CALLBACK(gtk_toolbar_detached_callback), this); 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
// 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
GtkUpdateSize(); m_oldClientWidth = 0;
} }
#endif // wxUSE_TOOLBAR #endif // wxUSE_TOOLBAR
@@ -583,7 +315,17 @@ void wxFrame::SetToolBar(wxToolBar *toolbar)
void wxFrame::SetStatusBar(wxStatusBar *statbar) void wxFrame::SetStatusBar(wxStatusBar *statbar)
{ {
wxFrameBase::SetStatusBar(statbar); m_frameStatusBar = statbar;
GtkUpdateSize(); 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 #endif // wxUSE_STATUSBAR

View File

@@ -17,25 +17,10 @@
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/intl.h" #include "wx/intl.h"
#include "wx/menu.h" #include "wx/menu.h"
#include "wx/dialog.h"
#endif #endif
#include "wx/notebook.h"
#include "wx/gtk/private.h" #include "wx/gtk/private.h"
#include <gtk/gtk.h>
#include "wx/gtk/win_gtk.h"
//-----------------------------------------------------------------------------
// constants
//-----------------------------------------------------------------------------
const int wxMENU_HEIGHT = 27;
//-----------------------------------------------------------------------------
// globals
//-----------------------------------------------------------------------------
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// "switch_page" // "switch_page"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -121,26 +106,6 @@ bool wxMDIParentFrame::Create(wxWindow *parent,
return true; 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() void wxMDIParentFrame::OnInternalIdle()
{ {
/* if a an MDI child window has just been inserted /* 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; wxMenuBar *menu_bar = active_child_frame->m_menuBar;
if (menu_bar) 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); menu_bar->SetInvokingWindow(active_child_frame);
} }
} }
@@ -191,11 +151,6 @@ void wxMDIParentFrame::OnInternalIdle()
{ {
if (menu_bar->Show(true)) 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 ); menu_bar->SetInvokingWindow( child_frame );
} }
visible_child_menu = true; visible_child_menu = true;
@@ -226,12 +181,27 @@ void wxMDIParentFrame::OnInternalIdle()
{ {
m_frameMenuBar->Show( true ); m_frameMenuBar->Show( true );
m_frameMenuBar->SetInvokingWindow( this ); m_frameMenuBar->SetInvokingWindow( this );
}
}
}
GTKDoGetSize(&m_frameMenuBar->m_width, NULL); void wxMDIParentFrame::DoGetClientSize(int* width, int* height) const
m_frameMenuBar->m_height = wxMENU_HEIGHT; {
gtk_pizza_set_size( GTK_PIZZA(m_mainWidget), wxFrame::DoGetClientSize(width, height);
m_frameMenuBar->m_widget,
0, 0, m_frameMenuBar->m_width, m_frameMenuBar->m_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) ); 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 // wxMDIChildFrame
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -383,11 +341,18 @@ void wxMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar )
m_menuBar->SetParent( mdi_frame ); m_menuBar->SetParent( mdi_frame );
/* insert the invisible menu bar into the _parent_ mdi frame */ /* insert the invisible menu bar into the _parent_ mdi frame */
int w; m_menuBar->Show(false);
mdi_frame->GTKDoGetSize(&w, NULL); gtk_box_pack_start(GTK_BOX(mdi_frame->m_mainWidget), m_menuBar->m_widget, false, false, 0);
gtk_pizza_put( GTK_PIZZA(mdi_frame->m_mainWidget), gtk_box_reorder_child(GTK_BOX(mdi_frame->m_mainWidget), m_menuBar->m_widget, 0);
m_menuBar->m_widget,
0, 0, w, wxMENU_HEIGHT); 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 ) ); 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 // InsertChild callback for wxMDIClientWindow
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -466,9 +411,6 @@ static void wxInsertChildInMDI(wxWindow* parent, wxWindow* child)
GtkWidget *label_widget = gtk_label_new( s.mbc_str() ); GtkWidget *label_widget = gtk_label_new( s.mbc_str() );
gtk_misc_set_alignment( GTK_MISC(label_widget), 0.0, 0.5 ); 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); GtkNotebook *notebook = GTK_NOTEBOOK(parent->m_widget);
gtk_notebook_append_page( notebook, child->m_widget, label_widget ); gtk_notebook_append_page( notebook, child->m_widget, label_widget );

View File

@@ -26,10 +26,6 @@
#include "wx/stockitem.h" #include "wx/stockitem.h"
#include "wx/gtk/private.h" #include "wx/gtk/private.h"
#ifdef __WXGTK20__
#include <gdk/gdktypes.h>
#endif
// FIXME: is this right? somehow I don't think so (VZ) // 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)) #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 // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables
// addings menu later on. // addings menu later on.
if (m_invokingWindow) if (m_invokingWindow)
{
wxMenubarSetInvokingWindow( menu, 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; return true;
} }
@@ -447,16 +430,7 @@ wxMenu *wxMenuBar::Remove(size_t pos)
menu->m_owner = NULL; menu->m_owner = NULL;
if (m_invokingWindow) if (m_invokingWindow)
{
// OPTIMISE ME: see comment in GtkAppend
wxFrame *frame = wxDynamicCast( m_invokingWindow, wxFrame );
if( frame )
frame->UpdateMenuBarSize();
wxMenubarUnsetInvokingWindow( menu, m_invokingWindow ); wxMenubarUnsetInvokingWindow( menu, m_invokingWindow );
}
return menu; return menu;
} }

View File

@@ -20,8 +20,7 @@
#include "wx/image.h" #include "wx/image.h"
#endif #endif
#include "wx/gtk/win_gtk.h" #include <gtk/gtk.h>
#include "wx/gtk/private.h"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// data // data
@@ -29,7 +28,6 @@
extern bool g_blockEventsOnDrag; extern bool g_blockEventsOnDrag;
extern bool g_blockEventsOnScroll; extern bool g_blockEventsOnScroll;
extern GtkWidget *wxGetRootWindow();
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// "expose_event" of m_mainWidget // "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) if (!win->m_hasVMT || gdk_event->count > 0)
return false; return false;
GtkPizza *pizza = GTK_PIZZA(widget);
gtk_paint_shadow (widget->style, gtk_paint_shadow (widget->style,
pizza->bin_window, widget->window,
GTK_STATE_NORMAL, GTK_STATE_NORMAL,
GTK_SHADOW_OUT, GTK_SHADOW_OUT,
NULL, NULL, NULL, // FIXME: No clipping? NULL, NULL, NULL, // FIXME: No clipping?
@@ -76,15 +72,15 @@ static gboolean gtk_window_own_expose_callback(GtkWidget* widget, GdkEventExpose
int style = win->GetWindowStyle(); int style = win->GetWindowStyle();
wxClientDC dc(win); wxClientDC dc(win);
#if wxUSE_NEW_DC #if wxUSE_NEW_DC
wxImplDC *impl = dc.GetImpl(); wxImplDC *impl = dc.GetImpl();
wxGTKClientImplDC *client_impl = wxDynamicCast( impl, wxGTKClientImplDC ); wxGTKClientImplDC *client_impl = wxDynamicCast( impl, wxGTKClientImplDC );
// Hack alert // Hack alert
client_impl->m_window = pizza->bin_window; client_impl->m_window = widget->window;
#else #else
// Hack alert // Hack alert
dc.m_window = pizza->bin_window; dc.m_window = widget->window;
#endif #endif
if (style & wxRESIZE_BORDER) if (style & wxRESIZE_BORDER)
@@ -130,9 +126,6 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton
if (win->m_isDragging) return TRUE; 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 style = win->GetWindowStyle();
int y = (int)gdk_event->y; 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 ); GtkWidget *ancestor = gtk_widget_get_toplevel( widget );
GdkWindow *source = GTK_PIZZA(widget)->bin_window; GdkWindow *source = widget->window;
int org_x = 0; int org_x = 0;
int org_y = 0; int org_y = 0;
@@ -304,11 +297,25 @@ gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event,
win->m_y = y; win->m_y = y;
gtk_window_move( GTK_WINDOW(win->m_widget), x, y ); gtk_window_move( GTK_WINDOW(win->m_widget), x, y );
return TRUE; 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 // wxMiniFrame
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -340,6 +347,27 @@ bool wxMiniFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title
wxFrame::Create( parent, id, title, pos, size, style, name ); 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))) 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) ); 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 */ /* 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 ); G_CALLBACK (gtk_window_own_expose_callback), this );
/* these are required for dragging the mini frame around */ /* 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_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_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_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); G_CALLBACK (gtk_window_leave_callback), this);
return true; 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 ) void wxMiniFrame::SetTitle( const wxString &title )
{ {
wxFrame::SetTitle( title ); wxFrame::SetTitle( title );
if (GTK_PIZZA(m_mainWidget)->bin_window) GtkWidget* fixed = GTK_BIN(m_widget)->child;
gdk_window_invalidate_rect( GTK_PIZZA(m_mainWidget)->bin_window, NULL, true ); if (fixed->window)
gdk_window_invalidate_rect(fixed->window, NULL, false);
} }
#endif // wxUSE_MINIFRAME #endif // wxUSE_MINIFRAME

View File

@@ -15,9 +15,6 @@
#include "wx/popupwin.h" #include "wx/popupwin.h"
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/app.h"
#include "wx/frame.h"
#include "wx/cursor.h"
#endif // WX_PRECOMP #endif // WX_PRECOMP
#include <gtk/gtk.h> #include <gtk/gtk.h>
@@ -131,11 +128,11 @@ static void wxInsertChildInPopupWin(wxWindowGTK* parent, wxWindowGTK* child)
// wxPopupWindow // wxPopupWindow
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxPopupWindow,wxPopupWindowBase)
#ifdef __WXUNIVERSAL__ #ifdef __WXUNIVERSAL__
BEGIN_EVENT_TABLE(wxPopupWindow,wxPopupWindowBase)
EVT_SIZE(wxPopupWindow::OnSize) EVT_SIZE(wxPopupWindow::OnSize)
#endif
END_EVENT_TABLE() END_EVENT_TABLE()
#endif
wxPopupWindow::~wxPopupWindow() wxPopupWindow::~wxPopupWindow()
{ {
@@ -143,8 +140,6 @@ wxPopupWindow::~wxPopupWindow()
bool wxPopupWindow::Create( wxWindow *parent, int style ) bool wxPopupWindow::Create( wxWindow *parent, int style )
{ {
m_sizeSet = false;
if (!PreCreation( parent, wxDefaultPosition, wxDefaultSize ) || if (!PreCreation( parent, wxDefaultPosition, wxDefaultSize ) ||
!CreateBase( parent, -1, wxDefaultPosition, wxDefaultSize, style, wxDefaultValidator, wxT("popup") )) !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_widget != NULL), wxT("invalid dialog") );
wxASSERT_MSG( (m_wxwindow != 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_x = m_x;
int old_y = m_y; int old_y = m_y;
int old_width = m_width; int old_width = m_width;
int old_height = m_height; int old_height = m_height;
if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0) if (x != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
{
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
{
m_x = x; m_x = x;
if (y != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
m_y = y; m_y = y;
if (width != -1)
m_width = width; m_width = width;
if (height != -1)
m_height = height; 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(); 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)) 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 ); gtk_window_move( GTK_WINDOW(m_widget), m_x, m_y );
} }
} }
if ((m_width != old_width) || (m_height != old_height)) 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 ); gtk_widget_set_size_request( m_widget, m_width, m_height );
wxSizeEvent event(GetSize(), GetId());
/* actual resizing is deferred to GtkOnSize in idle time and event.SetEventObject(this);
when showing the dialog */ GetEventHandler()->ProcessEvent(event);
m_sizeSet = false;
} }
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 ) bool wxPopupWindow::Show( bool show )
{ {
if (show && !m_sizeSet) if (show && !IsShown())
{ {
/* by calling GtkOnSize here, we don't have to call wxSizeEvent event(GetSize(), GetId());
either after showing the frame, which would entail event.SetEventObject(this);
much ugly flicker nor from within the size_allocate GetEventHandler()->ProcessEvent(event);
handler, because GTK 1.1.X forbids that. */
GtkOnSize();
} }
bool ret = wxWindow::Show( show ); bool ret = wxWindow::Show( show );

View File

@@ -8,14 +8,6 @@
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// For compilers that support precompilation, includes "wx.h". // For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.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 // InsertChild callback for wxToolBar
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -445,6 +451,9 @@ bool wxToolBar::Create( wxWindow *parent,
PostCreation(size); PostCreation(size);
g_signal_connect_after(m_toolbar, "size_request",
G_CALLBACK(size_request), this);
return true; return true;
} }
@@ -635,11 +644,6 @@ bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
break; 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(); InvalidateBestSize();
return true; return true;

View File

@@ -215,27 +215,30 @@ static wxSize& GetDecorSize(int decor)
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// "size_allocate" // "size_allocate" from m_wxwindow
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
extern "C" { 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) if (win->m_oldClientWidth != alloc->width ||
return; win->m_oldClientHeight != alloc->height)
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)
{ {
win->m_width = w; win->m_oldClientWidth = alloc->width;
win->m_height = h; win->m_oldClientHeight = alloc->height;
wxSize sizeDecor;
win->GtkUpdateSize(); 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 // Update window size and frame extents cache
win->m_width = rect.width; win->m_width = rect.width;
win->m_height = rect.height; win->m_height = rect.height;
win->GtkUpdateSize();
decorSize = size; 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; win->m_height += size.y - decorSize.y;
if (win->m_width < 0) win->m_width = 0; if (win->m_width < 0) win->m_width = 0;
if (win->m_height < 0) win->m_height = 0; if (win->m_height < 0) win->m_height = 0;
win->GtkUpdateSize();
decorSize = size; decorSize = size;
wxSizeEvent event(win->GetSize(), win->GetId());
event.SetEventObject(win);
win->GetEventHandler()->ProcessEvent(event);
} }
} }
if (data) if (data)
@@ -451,9 +458,6 @@ static gboolean property_notify_event(
void wxTopLevelWindowGTK::Init() void wxTopLevelWindowGTK::Init()
{ {
m_sizeSet = false;
m_miniEdge = 0;
m_miniTitle = 0;
m_mainWidget = (GtkWidget*) NULL; m_mainWidget = (GtkWidget*) NULL;
m_isIconized = false; m_isIconized = false;
m_fsIsShowing = false; m_fsIsShowing = false;
@@ -493,9 +497,9 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
// e.g. in wxTaskBarIconAreaGTK // e.g. in wxTaskBarIconAreaGTK
if (m_widget == NULL) if (m_widget == NULL)
{ {
m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) 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 // Tell WM that this is a dialog window and make it center
// on parent by default (this is what GtkDialog ctor does): // on parent by default (this is what GtkDialog ctor does):
gtk_window_set_type_hint(GTK_WINDOW(m_widget), gtk_window_set_type_hint(GTK_WINDOW(m_widget),
@@ -505,7 +509,6 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
} }
else else
{ {
m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
#if GTK_CHECK_VERSION(2,1,0) #if GTK_CHECK_VERSION(2,1,0)
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_signal_connect (m_widget, "delete_event",
G_CALLBACK (gtk_frame_delete_callback), this); G_CALLBACK (gtk_frame_delete_callback), this);
// m_mainWidget holds the toolbar, the menubar and the client area // m_mainWidget is a GtkVBox, holding the bars and client area (m_wxwindow)
m_mainWidget = gtk_pizza_new(); m_mainWidget = gtk_vbox_new(false, 0);
gtk_widget_show( m_mainWidget ); gtk_widget_show( m_mainWidget );
GTK_WIDGET_UNSET_FLAGS( m_mainWidget, GTK_CAN_FOCUS ); GTK_WIDGET_UNSET_FLAGS( m_mainWidget, GTK_CAN_FOCUS );
gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget ); gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget );
// m_wxwindow only represents the client area without toolbar and menubar // m_wxwindow is the client area
m_wxwindow = gtk_pizza_new(); m_wxwindow = gtk_pizza_new_no_scroll();
gtk_widget_show( m_wxwindow ); gtk_widget_show( m_wxwindow );
gtk_container_add( GTK_CONTAINER(m_mainWidget), 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 ); if (m_parent) m_parent->AddChild( this );
// the user resized the frame by dragging etc. g_signal_connect(m_wxwindow, "size_allocate",
g_signal_connect (m_widget, "size_allocate", G_CALLBACK(size_allocate), this);
G_CALLBACK (gtk_frame_size_callback), this);
g_signal_connect (m_widget, "size_request", g_signal_connect (m_widget, "size_request",
G_CALLBACK (wxgtk_tlw_size_request_callback), this); G_CALLBACK (wxgtk_tlw_size_request_callback), this);
@@ -627,15 +629,6 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
m_gdkFunc = 0; m_gdkFunc = 0;
} }
else 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_gdkDecor = GDK_DECOR_BORDER;
m_gdkFunc = GDK_FUNC_MOVE; m_gdkFunc = GDK_FUNC_MOVE;
@@ -812,22 +805,19 @@ bool wxTopLevelWindowGTK::Show( bool show )
{ {
wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") ); wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
if (show == IsShown()) if (show && !IsShown())
return false;
if (show && !m_sizeSet)
{ {
/* by calling GtkOnSize here, we don't have to call // size_allocate signals occur in reverse order (bottom to top).
either after showing the frame, which would entail // Things work better if the initial wxSizeEvents are sent (from the
much ugly flicker or from within the size_allocate // top down), before the initial size_allocate signals occur.
handler, because GTK 1.1.X forbids that. */ wxSizeEvent event(GetSize(), GetId());
event.SetEventObject(this);
GtkOnSize(); 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 // 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 // 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); gtk_window_move((GtkWindow*)m_widget, m_x, m_y);
} }
return true; return change;
} }
void wxTopLevelWindowGTK::Raise() 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 ); gtk_window_move( GTK_WINDOW(m_widget), m_x, m_y );
} }
m_resizing = true;
const wxSize oldSize(m_width, m_height); const wxSize oldSize(m_width, m_height);
if (width >= 0) if (width >= 0)
m_width = width; m_width = width;
@@ -909,13 +897,18 @@ void wxTopLevelWindowGTK::DoSetSize( int x, int y, int width, int height, int si
int w, h; int w, h;
GTKDoGetSize(&w, &h); GTKDoGetSize(&w, &h);
gtk_window_resize(GTK_WINDOW(m_widget), 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 void wxTopLevelWindowGTK::DoGetClientSize( int *width, int *height ) const
{ {
wxASSERT_MSG(m_widget, wxT("invalid frame"));
if ( IsIconized() ) if ( IsIconized() )
{ {
// for consistency with wxMSW, client area is supposed to be empty for // 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; *width = 0;
if ( height ) if ( height )
*height = 0; *height = 0;
return;
} }
else
wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
int w, h;
GTKDoGetSize(&w, &h);
if (width)
{ {
*width = w - 2 * m_miniEdge; GTKDoGetSize(width, height);
if (*width < 0)
*width = 0;
}
if (height)
{
*height = h - 2 * m_miniEdge - m_miniTitle;
if (*height < 0)
*height = 0;
} }
} }
@@ -987,35 +965,6 @@ void wxTopLevelWindowGTK::DoSetSizeHints( int minW, int minH,
(GtkWindow*)m_widget, NULL, &hints, (GdkWindowHints)hints_mask); (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 bool wxTopLevelWindowGTK::IsDecorCacheable() const
{ {
return true; return true;
@@ -1023,14 +972,6 @@ bool wxTopLevelWindowGTK::IsDecorCacheable() const
void wxTopLevelWindowGTK::OnInternalIdle() 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 // set the focus if not done yet and if we can already do it
if ( GTK_WIDGET_REALIZED(m_wxwindow) ) if ( GTK_WIDGET_REALIZED(m_wxwindow) )
{ {

View File

@@ -19,15 +19,11 @@
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/log.h" #include "wx/log.h"
#include "wx/app.h" #include "wx/app.h"
#include "wx/frame.h" #include "wx/toplevel.h"
#include "wx/dcclient.h" #include "wx/dcclient.h"
#include "wx/menu.h" #include "wx/menu.h"
#include "wx/settings.h" #include "wx/settings.h"
#include "wx/msgdlg.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" #include "wx/math.h"
#endif #endif
@@ -429,7 +425,7 @@ extern "C" {
static static
void wxgtk_combo_size_request_callback(GtkWidget * WXUNUSED(widget), void wxgtk_combo_size_request_callback(GtkWidget * WXUNUSED(widget),
GtkRequisition *requisition, GtkRequisition *requisition,
wxComboBox *win) wxWindow* win)
{ {
// This callback is actually hooked into the text entry // This callback is actually hooked into the text entry
// of the combo box, not the GtkHBox. // 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 static void
void gtk_window_size_callback( GtkWidget *WXUNUSED(widget), size_allocate(GtkWidget*, GtkAllocation* alloc, wxWindow* win)
GtkAllocation * WXUNUSED(alloc),
wxWindow *win )
{ {
int client_width = 0; int w = alloc->width;
int client_height = 0; int h = alloc->height;
win->GetClientSize( &client_width, &client_height ); if (win->m_wxwindow)
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 const int border = GTK_CONTAINER(win->m_wxwindow)->border_width;
return; 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 = client_width;
win->m_oldClientHeight = client_height;
if (!win->m_nativeSizeEvent)
{ {
wxSizeEvent event( win->GetSize(), win->GetId() ); win->m_oldClientWidth = w;
event.SetEventObject( win ); win->m_oldClientHeight = h;
win->GTKProcessEvent( event ); // 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_oldClientWidth =
m_oldClientHeight = 0; m_oldClientHeight = 0;
m_resizing = false;
m_insertCallback = wxInsertChildInWindow; m_insertCallback = wxInsertChildInWindow;
m_hasFocus = false; m_hasFocus = false;
@@ -2525,11 +2521,14 @@ void wxWindowGTK::PostCreation()
g_signal_connect (connect_widget, "realize", g_signal_connect (connect_widget, "realize",
G_CALLBACK (gtk_window_realized_callback), this); 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) 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)
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_widget != NULL), wxT("invalid window") );
wxASSERT_MSG( (m_parent != NULL), wxT("wxWindowGTK::SetSize requires parent.\n") ); 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; int currentX, currentY;
GetPosition(&currentX, &currentY); GetPosition(&currentX, &currentY);
if (x == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) 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; height = sizeBest.y;
} }
const wxSize oldSize(m_width, m_height);
if (width != -1) if (width != -1)
m_width = width; m_width = width;
if (height != -1) if (height != -1)
@@ -2683,36 +2680,11 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags
ConstrainSize(); ConstrainSize();
#if wxUSE_TOOLBAR_NATIVE if (m_parent->m_wxwindow)
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
{ {
GtkPizza *pizza = GTK_PIZZA(m_parent->m_wxwindow); GtkPizza *pizza = GTK_PIZZA(m_parent->m_wxwindow);
if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0) m_x = x + gtk_pizza_get_xoffset(pizza);
{ m_y = y + gtk_pizza_get_yoffset(pizza);
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 );
}
int left_border = 0; int left_border = 0;
int right_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 ); 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 // update these variables to keep size_allocate handler
whole windows's size changing, but if the whole // from sending another size event for this change
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. */
GetClientSize( &m_oldClientWidth, &m_oldClientHeight ); GetClientSize( &m_oldClientWidth, &m_oldClientHeight );
gtk_widget_queue_resize(m_widget);
if (!m_nativeSizeEvent)
{
wxSizeEvent event( wxSize(m_width,m_height), GetId() );
event.SetEventObject( this );
GetEventHandler()->ProcessEvent( event );
}
} }
/*
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 );
}
m_resizing = false;
} }
bool wxWindowGTK::GtkShowFromOnIdle() bool wxWindowGTK::GtkShowFromOnIdle()