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_
#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:

View File

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

View File

@ -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_

View File

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

View File

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

View File

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

View File

@ -25,9 +25,6 @@
#include "wx/panel.h"
#include "wx/gtk/private.h"
#include "wx/gtk/win_gtk.h"
#include <gtk/gtkexpander.h>
// ============================================================================
// 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);
}
}

View File

@ -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 <gdk/gdk.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#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();

View File

@ -19,14 +19,6 @@
#endif // WX_PRECOMP
#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
@ -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);
}
// 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);
// 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);
// 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 );
UpdateMenuBarSize();
}
else
{
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();
// 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 );
// 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
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
// 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);
}
GtkUpdateSize();
// 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

View File

@ -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 <gtk/gtk.h>
#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 );

View File

@ -26,10 +26,6 @@
#include "wx/stockitem.h"
#include "wx/gtk/private.h"
#ifdef __WXGTK20__
#include <gdk/gdktypes.h>
#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;
}

View File

@ -20,8 +20,7 @@
#include "wx/image.h"
#endif
#include "wx/gtk/win_gtk.h"
#include "wx/gtk/private.h"
#include <gtk/gtk.h>
//-----------------------------------------------------------------------------
// 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

View File

@ -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 <gtk/gtk.h>
@ -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 );

View File

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

View File

@ -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)
else
{
*width = w - 2 * m_miniEdge;
if (*width < 0)
*width = 0;
}
if (height)
{
*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) )
{

View File

@ -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 )
int w = alloc->width;
int h = alloc->height;
if (win->m_wxwindow)
{
// the window is currently unmapped, don't generate size events
return;
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;
}
win->m_oldClientWidth = client_width;
win->m_oldClientHeight = client_height;
if (!win->m_nativeSizeEvent)
if (win->m_oldClientWidth != w || win->m_oldClientHeight != h)
{
wxSizeEvent event( win->GetSize(), win->GetId() );
event.SetEventObject( win );
win->GTKProcessEvent( event );
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(&currentX, &currentY);
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 );
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()