X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/94f145095605aa3aafaab289b9d3e1630587f821..6552c7af6c1e252b8b229f972721753ff058fa66:/src/gtk/frame.cpp diff --git a/src/gtk/frame.cpp b/src/gtk/frame.cpp index 48b191aaa0..20b72a5865 100644 --- a/src/gtk/frame.cpp +++ b/src/gtk/frame.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: frame.cpp +// Name: src/gtk/frame.cpp // Purpose: // Author: Robert Roebling // Id: $Id$ @@ -7,55 +7,26 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -// ============================================================================ -// declarations -// ============================================================================ - -// ---------------------------------------------------------------------------- -// headers -// ---------------------------------------------------------------------------- - -#ifdef __GNUG__ - #pragma implementation "frame.h" -#endif +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" -#include "wx/defs.h" +#include "wx/frame.h" -#include "wx/dialog.h" -#include "wx/control.h" -#include "wx/app.h" -#include "wx/menu.h" -#if wxUSE_TOOLBAR +#ifndef WX_PRECOMP + #include "wx/menu.h" #include "wx/toolbar.h" -#endif -#if wxUSE_STATUSBAR #include "wx/statusbr.h" -#endif -#include "wx/dcclient.h" +#endif // WX_PRECOMP -#include #include "wx/gtk/private.h" - -#include -#include - #include "wx/gtk/win_gtk.h" // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- -const int wxMENU_HEIGHT = 27; -const int wxSTATUS_HEIGHT = 25; -const int wxPLACE_HOLDER = 0; - -// ---------------------------------------------------------------------------- -// idle system -// ---------------------------------------------------------------------------- - -extern void wxapp_install_idle_handler(); -extern bool g_isIdle; -extern int g_openDialogs; +static const int wxSTATUS_HEIGHT = 25; +static const int wxPLACE_HOLDER = 0; // ---------------------------------------------------------------------------- // event tables @@ -77,18 +48,21 @@ IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxTopLevelWindow) // "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->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 (g_isIdle) @@ -99,9 +73,10 @@ static void gtk_menu_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidget * // Raise the client area area gdk_window_raise( win->m_wxwindow->window ); - win->m_menuBarDetached = TRUE; + win->m_menuBarDetached = true; win->GtkUpdateSize(); } +} #endif // wxUSE_MENUS_NATIVE @@ -110,18 +85,21 @@ static void gtk_menu_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidget * // "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->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 (g_isIdle) @@ -132,9 +110,10 @@ static void gtk_toolbar_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidge // Raise the client area area gdk_window_raise( win->m_wxwindow->window ); - win->m_toolBarDetached = TRUE; + win->m_toolBarDetached = true; win->GtkUpdateSize(); } +} #endif // wxUSE_TOOLBAR @@ -148,7 +127,7 @@ static void gtk_toolbar_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidge /* Callback for wxFrame. This very strange beast has to be used because * C++ has no virtual methods in a constructor. We have to emulate a - * virtual function here as wxWindows requires different ways to insert + * virtual function here as wxWidgets requires different ways to insert * a child in container classes. */ static void wxInsertChildInFrame( wxFrame* parent, wxWindow* child ) @@ -174,11 +153,12 @@ static void wxInsertChildInFrame( wxFrame* parent, wxWindow* child ) wxToolBar *toolBar = (wxToolBar*) child; if (toolBar->GetWindowStyle() & wxTB_DOCKABLE) { - gtk_signal_connect( GTK_OBJECT(toolBar->m_widget), "child_attached", - GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback), (gpointer)parent ); - - gtk_signal_connect( GTK_OBJECT(toolBar->m_widget), "child_detached", - GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback), (gpointer)parent ); + g_signal_connect (toolBar->m_widget, "child_attached", + G_CALLBACK (gtk_toolbar_attached_callback), + parent); + g_signal_connect (toolBar->m_widget, "child_detached", + G_CALLBACK (gtk_toolbar_detached_callback), + parent); } } #endif // wxUSE_TOOLBAR @@ -193,9 +173,6 @@ static void wxInsertChildInFrame( wxFrame* parent, wxWindow* child ) child->m_width, child->m_height ); } - - // Resize on OnInternalIdle - parent->GtkUpdateSize(); } // ---------------------------------------------------------------------------- @@ -204,8 +181,9 @@ static void wxInsertChildInFrame( wxFrame* parent, wxWindow* child ) void wxFrame::Init() { - m_menuBarDetached = FALSE; - m_toolBarDetached = FALSE; + m_menuBarDetached = false; + m_toolBarDetached = false; + m_menuBarHeight = 2; } bool wxFrame::Create( wxWindow *parent, @@ -216,15 +194,16 @@ bool wxFrame::Create( wxWindow *parent, long style, const wxString &name ) { - bool rt = wxTopLevelWindow::Create(parent, id, title, pos, sizeOrig, + bool rt = wxTopLevelWindow::Create(parent, id, title, pos, sizeOrig, style, name); m_insertCallback = (wxInsertChildFunction) wxInsertChildInFrame; + return rt; } wxFrame::~wxFrame() { - m_isBeingDeleted = TRUE; + m_isBeingDeleted = true; DeleteAllBars(); } @@ -235,17 +214,17 @@ wxFrame::~wxFrame() void wxFrame::DoGetClientSize( int *width, int *height ) const { wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") ); - + wxTopLevelWindow::DoGetClientSize( width, height ); if (height) { #if wxUSE_MENUS_NATIVE // menu bar - if (m_frameMenuBar) + if (m_frameMenuBar && !(m_fsIsShowing && (m_fsSaveFlag & wxFULLSCREEN_NOMENUBAR) != 0)) { if (!m_menuBarDetached) - (*height) -= wxMENU_HEIGHT; + (*height) -= m_menuBarHeight; else (*height) -= wxPLACE_HOLDER; } @@ -253,34 +232,43 @@ void wxFrame::DoGetClientSize( int *width, int *height ) const #if wxUSE_STATUSBAR // status bar - if (m_frameStatusBar && m_frameStatusBar->IsShown()) + if (m_frameStatusBar && m_frameStatusBar->IsShown() && + !(m_fsIsShowing && (m_fsSaveFlag & wxFULLSCREEN_NOSTATUSBAR) != 0)) (*height) -= wxSTATUS_HEIGHT; #endif // wxUSE_STATUSBAR + } #if wxUSE_TOOLBAR - // tool bar - if (m_frameToolBar && m_frameToolBar->IsShown()) + // tool bar + if (m_frameToolBar && m_frameToolBar->IsShown()) + { + if (m_toolBarDetached) { - if (m_toolBarDetached) - { + if (height != NULL) *height -= wxPLACE_HOLDER; + } + else + { + int x, y; + m_frameToolBar->GetSize( &x, &y ); + if ( m_frameToolBar->IsVertical() ) + { + if (width != NULL) + *width -= x; } else { - int x, y; - m_frameToolBar->GetSize( &x, &y ); - if ( m_frameToolBar->GetWindowStyle() & wxTB_VERTICAL ) - { - *width -= x; - } - else - { + if (height != NULL) *height -= y; - } } } -#endif // wxUSE_TOOLBAR } +#endif // wxUSE_TOOLBAR + + if (width != NULL && *width < 0) + *width = 0; + if (height != NULL && *height < 0) + *height = 0; } void wxFrame::DoSetClientSize( int width, int height ) @@ -289,10 +277,10 @@ void wxFrame::DoSetClientSize( int width, int height ) #if wxUSE_MENUS_NATIVE // menu bar - if (m_frameMenuBar) + if (m_frameMenuBar && !(m_fsIsShowing && (m_fsSaveFlag & wxFULLSCREEN_NOMENUBAR) != 0)) { if (!m_menuBarDetached) - height += wxMENU_HEIGHT; + height += m_menuBarHeight; else height += wxPLACE_HOLDER; } @@ -300,7 +288,9 @@ void wxFrame::DoSetClientSize( int width, int height ) #if wxUSE_STATUSBAR // status bar - if (m_frameStatusBar && m_frameStatusBar->IsShown()) height += wxSTATUS_HEIGHT; + if (m_frameStatusBar && m_frameStatusBar->IsShown() && + !(m_fsIsShowing && (m_fsSaveFlag & wxFULLSCREEN_NOSTATUSBAR) != 0)) + height += wxSTATUS_HEIGHT; #endif #if wxUSE_TOOLBAR @@ -315,7 +305,7 @@ void wxFrame::DoSetClientSize( int width, int height ) { int x, y; m_frameToolBar->GetSize( &x, &y ); - if ( m_frameToolBar->GetWindowStyle() & wxTB_VERTICAL ) + if ( m_frameToolBar->IsVertical() ) { width += x; } @@ -330,23 +320,15 @@ void wxFrame::DoSetClientSize( int width, int height ) wxTopLevelWindow::DoSetClientSize( width, height ); } -void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), - int width, int height ) +void wxFrame::GtkOnSize() { - // due to a bug in gtk, x,y are always 0 - // m_x = x; - // m_y = y; - // avoid recursions if (m_resizing) return; - m_resizing = TRUE; + m_resizing = true; // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") ); - m_width = width; - m_height = height; - // space occupied by m_frameToolBar and m_frameMenuBar int client_area_x_offset = 0, client_area_y_offset = 0; @@ -370,33 +352,23 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), if (m_mainWidget) { - // set size hints - gint flag = 0; // GDK_HINT_POS; - if ((minWidth != -1) || (minHeight != -1)) flag |= GDK_HINT_MIN_SIZE; - if ((maxWidth != -1) || (maxHeight != -1)) flag |= GDK_HINT_MAX_SIZE; - GdkGeometry geom; - geom.min_width = minWidth; - geom.min_height = minHeight; - geom.max_width = maxWidth; - geom.max_height = maxHeight; - gtk_window_set_geometry_hints( GTK_WINDOW(m_widget), - (GtkWidget*) NULL, - &geom, - (GdkWindowHints) flag ); - - // I revert back to wxGTK's original behaviour. m_mainWidget holds - // the menubar, the toolbar and the client area, which is represented - // by m_wxwindow. - // This hurts in the eye, but I don't want to call SetSize() - // because I don't want to call any non-native functions here. + // 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 - if (m_frameMenuBar) + if (m_frameMenuBar && !(m_fsIsShowing && (m_fsSaveFlag & wxFULLSCREEN_NOMENUBAR) != 0)) { + if (!GTK_WIDGET_VISIBLE(m_frameMenuBar->m_widget)) + gtk_widget_show( m_frameMenuBar->m_widget ); int xx = m_miniEdge; int yy = m_miniEdge + m_miniTitle; int ww = m_width - 2*m_miniEdge; - int hh = wxMENU_HEIGHT; + if (ww < 0) + ww = 0; + int hh = m_menuBarHeight; if (m_menuBarDetached) hh = wxPLACE_HOLDER; m_frameMenuBar->m_x = xx; m_frameMenuBar->m_y = yy; @@ -407,6 +379,14 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), xx, yy, ww, hh ); client_area_y_offset += hh; } + else + { + if (m_frameMenuBar) + { + if (GTK_WIDGET_VISIBLE(m_frameMenuBar->m_widget)) + gtk_widget_hide( m_frameMenuBar->m_widget ); + } + } #endif // wxUSE_MENUS_NATIVE #if wxUSE_TOOLBAR @@ -419,7 +399,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), if (m_frameMenuBar) { if (!m_menuBarDetached) - yy += wxMENU_HEIGHT; + yy += m_menuBarHeight; else yy += wxPLACE_HOLDER; } @@ -438,15 +418,43 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), 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 = m_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_MENU_NATIVE + m_frameToolBar->m_x = xx; + m_frameToolBar->m_y = yy; + ww = m_width - 2*m_miniEdge; + hh = m_toolBarDetached ? wxPLACE_HOLDER + : m_frameToolBar->m_height; + } else { ww = m_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 ); @@ -457,6 +465,10 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int client_y = client_area_y_offset + m_miniEdge + m_miniTitle; int client_w = m_width - client_area_x_offset - 2*m_miniEdge; int client_h = m_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 ); @@ -468,11 +480,17 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), } #if wxUSE_STATUSBAR - if (m_frameStatusBar && m_frameStatusBar->IsShown()) + if (m_frameStatusBar && m_frameStatusBar->IsShown() && + !(m_fsIsShowing && (m_fsSaveFlag & wxFULLSCREEN_NOSTATUSBAR) != 0)) { + if (!GTK_WIDGET_VISIBLE(m_frameStatusBar->m_widget)) + gtk_widget_show( m_frameStatusBar->m_widget ); + int xx = 0 + m_miniEdge; int yy = m_height - wxSTATUS_HEIGHT - m_miniEdge - client_area_y_offset; int ww = m_width - 2*m_miniEdge; + if (ww < 0) + ww = 0; int hh = wxSTATUS_HEIGHT; m_frameStatusBar->m_x = xx; m_frameStatusBar->m_y = yy; @@ -481,11 +499,18 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), gtk_pizza_set_size( GTK_PIZZA(m_wxwindow), m_frameStatusBar->m_widget, xx, yy, ww, hh ); - gtk_widget_draw( m_frameStatusBar->m_widget, (GdkRectangle*) NULL ); + } + else + { + if (m_frameStatusBar) + { + if (GTK_WIDGET_VISIBLE(m_frameStatusBar->m_widget)) + gtk_widget_hide( m_frameStatusBar->m_widget ); + } } #endif // wxUSE_STATUSBAR - m_sizeSet = TRUE; + m_sizeSet = true; // send size event to frame wxSizeEvent event( wxSize(m_width,m_height), GetId() ); @@ -502,12 +527,12 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), } #endif // wxUSE_STATUSBAR - m_resizing = FALSE; + m_resizing = false; } void wxFrame::OnInternalIdle() { - wxTopLevelWindow::OnInternalIdle(); + wxFrameBase::OnInternalIdle(); #if wxUSE_MENUS_NATIVE if (m_frameMenuBar) m_frameMenuBar->OnInternalIdle(); @@ -516,7 +541,20 @@ void wxFrame::OnInternalIdle() if (m_frameToolBar) m_frameToolBar->OnInternalIdle(); #endif #if wxUSE_STATUSBAR - if (m_frameStatusBar) m_frameStatusBar->OnInternalIdle(); + if (m_frameStatusBar) + { + m_frameStatusBar->OnInternalIdle(); + + // There may be controls in the status bar that + // need to be updated + for ( wxWindowList::compatibility_iterator node = m_frameStatusBar->GetChildren().GetFirst(); + node; + node = node->GetNext() ) + { + wxWindow *child = node->GetData(); + child->OnInternalIdle(); + } + } #endif } @@ -537,11 +575,13 @@ void wxFrame::DetachMenuBar() if (m_frameMenuBar->GetWindowStyle() & wxMB_DOCKABLE) { - gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar->m_widget), - GTK_SIGNAL_FUNC(gtk_menu_attached_callback), (gpointer)this ); + g_signal_handlers_disconnect_by_func (m_frameMenuBar->m_widget, + (gpointer) gtk_menu_attached_callback, + this); - gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar->m_widget), - GTK_SIGNAL_FUNC(gtk_menu_detached_callback), (gpointer)this ); + g_signal_handlers_disconnect_by_func (m_frameMenuBar->m_widget, + (gpointer) gtk_menu_detached_callback, + this); } gtk_widget_ref( m_frameMenuBar->m_widget ); @@ -570,18 +610,44 @@ void wxFrame::AttachMenuBar( wxMenuBar *menuBar ) if (menuBar->GetWindowStyle() & wxMB_DOCKABLE) { - gtk_signal_connect( GTK_OBJECT(menuBar->m_widget), "child_attached", - GTK_SIGNAL_FUNC(gtk_menu_attached_callback), (gpointer)this ); - - gtk_signal_connect( GTK_OBJECT(menuBar->m_widget), "child_detached", - GTK_SIGNAL_FUNC(gtk_menu_detached_callback), (gpointer)this ); + 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); } - m_frameMenuBar->Show( TRUE ); + 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 - m_sizeSet = FALSE; + GtkUpdateSize(); } #endif // wxUSE_MENUS_NATIVE @@ -592,13 +658,13 @@ wxToolBar* wxFrame::CreateToolBar( long style, wxWindowID id, const wxString& na { wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") ); - m_insertInClientArea = FALSE; + m_insertInClientArea = false; m_frameToolBar = wxFrameBase::CreateToolBar( style, id, name ); - m_insertInClientArea = TRUE; + m_insertInClientArea = true; - m_sizeSet = FALSE; + GtkUpdateSize(); return m_frameToolBar; } @@ -643,17 +709,26 @@ wxStatusBar* wxFrame::CreateStatusBar(int number, wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") ); // because it will change when toolbar is added - m_sizeSet = FALSE; + GtkUpdateSize(); return wxFrameBase::CreateStatusBar( number, style, id, name ); } +void wxFrame::SetStatusBar(wxStatusBar *statbar) +{ + bool hadStatBar = m_frameStatusBar != NULL; + + wxFrameBase::SetStatusBar(statbar); + + if (hadStatBar && !m_frameStatusBar) + GtkUpdateSize(); +} + void wxFrame::PositionStatusBar() { if ( !m_frameStatusBar ) return; - m_sizeSet = FALSE; + GtkUpdateSize(); } #endif // wxUSE_STATUSBAR -