X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9fa72bd2a637cee761c56e2ce61cec3e43c62765..ac0c512d865e6236fc81882cb84cc38d09f8f0ec:/src/gtk/frame.cpp diff --git a/src/gtk/frame.cpp b/src/gtk/frame.cpp index a2b97cc2e2..48b111dc80 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,53 +7,26 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -// ============================================================================ -// declarations -// ============================================================================ - -// ---------------------------------------------------------------------------- -// headers -// ---------------------------------------------------------------------------- - // 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" - -#include -#include "wx/gtk/private.h" - -#include -#include +#endif // WX_PRECOMP +#include #include "wx/gtk/win_gtk.h" // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- -const int wxSTATUS_HEIGHT = 25; -const int wxPLACE_HOLDER = 0; - -// ---------------------------------------------------------------------------- -// idle system -// ---------------------------------------------------------------------------- - -extern void wxapp_install_idle_handler(); -extern bool g_isIdle; +static const int wxSTATUS_HEIGHT = 25; +static const int wxPLACE_HOLDER = 0; // ---------------------------------------------------------------------------- // event tables @@ -92,9 +65,6 @@ static void gtk_menu_attached_callback( GtkWidget *WXUNUSED(widget), GtkWidget * extern "C" { static void gtk_menu_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win ) { - if (g_isIdle) - wxapp_install_idle_handler(); - if (!win->m_hasVMT) return; // Raise the client area area @@ -129,9 +99,6 @@ static void gtk_toolbar_attached_callback( GtkWidget *WXUNUSED(widget), GtkWidge extern "C" { static void gtk_toolbar_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win ) { - if (g_isIdle) - wxapp_install_idle_handler(); - if (!win->m_hasVMT) return; // Raise the client area area @@ -152,59 +119,46 @@ static void gtk_toolbar_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidge // InsertChild for wxFrame //----------------------------------------------------------------------------- +#if wxUSE_TOOLBAR + /* 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 wxWidgets requires different ways to insert * a child in container classes. */ -static void wxInsertChildInFrame( wxFrame* parent, wxWindow* child ) +static void wxInsertChildInFrame(wxWindow* parent, wxWindow* child) { wxASSERT( GTK_IS_WIDGET(child->m_widget) ); - if (!parent->m_insertInClientArea) - { - // These are outside the client area - wxFrame* frame = (wxFrame*) parent; - gtk_pizza_put( GTK_PIZZA(frame->m_mainWidget), - GTK_WIDGET(child->m_widget), - child->m_x, - child->m_y, - child->m_width, - child->m_height ); + // These are outside the client area + wxFrame* frame = wx_static_cast(wxFrame*, parent); + gtk_pizza_put( GTK_PIZZA(frame->m_mainWidget), + child->m_widget, + child->m_x, + child->m_y, + child->m_width, + child->m_height ); #if wxUSE_TOOLBAR_NATIVE - // We connect to these events for recalculating the client area - // space when the toolbar is floating - if (wxIS_KIND_OF(child,wxToolBar)) + // We connect to these events for recalculating the client area + // space when the toolbar is floating + if (wxIS_KIND_OF(child,wxToolBar)) + { + if (child->HasFlag(wxTB_DOCKABLE)) { - wxToolBar *toolBar = (wxToolBar*) child; - if (toolBar->GetWindowStyle() & wxTB_DOCKABLE) - { - 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); - } + g_signal_connect (child->m_widget, "child_attached", + G_CALLBACK (gtk_toolbar_attached_callback), + parent); + g_signal_connect (child->m_widget, "child_detached", + G_CALLBACK (gtk_toolbar_detached_callback), + parent); } -#endif // wxUSE_TOOLBAR - } - else - { - // These are inside the client area - gtk_pizza_put( GTK_PIZZA(parent->m_wxwindow), - GTK_WIDGET(child->m_widget), - child->m_x, - child->m_y, - child->m_width, - child->m_height ); } - - // Resize on OnInternalIdle - parent->GtkUpdateSize(); +#endif // wxUSE_TOOLBAR_NATIVE } +#endif // wxUSE_TOOLBAR + // ---------------------------------------------------------------------------- // wxFrame creation // ---------------------------------------------------------------------------- @@ -214,6 +168,7 @@ void wxFrame::Init() m_menuBarDetached = false; m_toolBarDetached = false; m_menuBarHeight = 2; + m_fsSaveFlag = 0; } bool wxFrame::Create( wxWindow *parent, @@ -224,11 +179,7 @@ bool wxFrame::Create( wxWindow *parent, long style, const wxString &name ) { - bool rt = wxTopLevelWindow::Create(parent, id, title, pos, sizeOrig, - style, name); - m_insertCallback = (wxInsertChildFunction) wxInsertChildInFrame; - - return rt; + return wxFrameBase::Create(parent, id, title, pos, sizeOrig, style, name); } wxFrame::~wxFrame() @@ -245,107 +196,100 @@ void wxFrame::DoGetClientSize( int *width, int *height ) const { wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") ); - wxTopLevelWindow::DoGetClientSize( width, height ); + wxFrameBase::DoGetClientSize(width, height); if (height) { #if wxUSE_MENUS_NATIVE // menu bar - if (m_frameMenuBar) + if (HasVisibleMenubar() && !m_menuBarDetached) { - if (!m_menuBarDetached) - (*height) -= m_menuBarHeight; - else - (*height) -= wxPLACE_HOLDER; + *height -= m_menuBarHeight; } #endif // wxUSE_MENUS_NATIVE #if wxUSE_STATUSBAR // status bar - if (m_frameStatusBar && m_frameStatusBar->IsShown()) - (*height) -= wxSTATUS_HEIGHT; + if (m_frameStatusBar && GTK_WIDGET_VISIBLE(m_frameStatusBar->m_widget)) + *height -= wxSTATUS_HEIGHT; #endif // wxUSE_STATUSBAR + } #if wxUSE_TOOLBAR - // tool bar - if (m_frameToolBar && m_frameToolBar->IsShown()) + // tool bar + if (m_frameToolBar && + GTK_WIDGET_VISIBLE(m_frameToolBar->m_widget) && !m_toolBarDetached) + { + if (m_frameToolBar->IsVertical()) { - if (m_toolBarDetached) - { - *height -= wxPLACE_HOLDER; - } - else - { - int x, y; - m_frameToolBar->GetSize( &x, &y ); - if ( m_frameToolBar->GetWindowStyle() & wxTB_VERTICAL ) - { - *width -= x; - } - else - { - *height -= y; - } - } + if (width) + *width -= m_frameToolBar->GetSize().x; + } + else + { + if (height) + *height -= m_frameToolBar->GetSize().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 ) +bool wxFrame::ShowFullScreen(bool show, long style) { - wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") ); - -#if wxUSE_MENUS_NATIVE - // menu bar - if (m_frameMenuBar) - { - if (!m_menuBarDetached) - height += m_menuBarHeight; - else - height += wxPLACE_HOLDER; - } -#endif // wxUSE_MENUS_NATIVE - -#if wxUSE_STATUSBAR - // status bar - if (m_frameStatusBar && m_frameStatusBar->IsShown()) height += wxSTATUS_HEIGHT; + if (!wxFrameBase::ShowFullScreen(show, style)) + return false; + + wxWindow* const bar[] = { +#if wxUSE_MENUS + m_frameMenuBar, +#else + NULL, #endif - #if wxUSE_TOOLBAR - // tool bar - if (m_frameToolBar && m_frameToolBar->IsShown()) + m_frameToolBar, +#else + NULL, +#endif +#if wxUSE_STATUSBAR + m_frameStatusBar, +#else + NULL, +#endif + }; + const long fsNoBar[] = { + wxFULLSCREEN_NOMENUBAR, wxFULLSCREEN_NOTOOLBAR, wxFULLSCREEN_NOSTATUSBAR + }; + for (int i = 0; i < 3; i++) + { + if (show) { - if (m_toolBarDetached) - { - height += wxPLACE_HOLDER; - } - else + if (bar[i] && (style & fsNoBar[i])) { - int x, y; - m_frameToolBar->GetSize( &x, &y ); - if ( m_frameToolBar->GetWindowStyle() & wxTB_VERTICAL ) - { - width += x; - } + if (bar[i]->IsShown()) + bar[i]->Show(false); else - { - height += y; - } + style &= ~fsNoBar[i]; } } -#endif + else + { + if (bar[i] && (m_fsSaveFlag & fsNoBar[i])) + bar[i]->Show(true); + } + } + if (show) + m_fsSaveFlag = style; - wxTopLevelWindow::DoSetClientSize( width, height ); + return true; } -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; @@ -353,9 +297,6 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), // 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; @@ -367,54 +308,41 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), skip the part which handles m_frameMenuBar, m_frameToolBar and (most importantly) m_mainWidget */ - int minWidth = GetMinWidth(), - minHeight = GetMinHeight(), - maxWidth = GetMaxWidth(), - maxHeight = GetMaxHeight(); + ConstrainSize(); - if ((minWidth != -1) && (m_width < minWidth)) m_width = minWidth; - if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight; - if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth; - if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight; + int width, height; + GTKDoGetSize(&width, &height); 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 + int menubarHeight = 0; +#endif #if wxUSE_MENUS_NATIVE - if (m_frameMenuBar) + if (HasVisibleMenubar()) { int xx = m_miniEdge; int yy = m_miniEdge + m_miniTitle; - int ww = m_width - 2*m_miniEdge; - int hh = m_menuBarHeight; - if (m_menuBarDetached) hh = wxPLACE_HOLDER; + 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 = hh; + m_frameMenuBar->m_height = menubarHeight; gtk_pizza_set_size( GTK_PIZZA(m_mainWidget), m_frameMenuBar->m_widget, - xx, yy, ww, hh ); - client_area_y_offset += hh; + xx, yy, ww, menubarHeight); + client_area_y_offset += menubarHeight; } #endif // wxUSE_MENUS_NATIVE @@ -423,16 +351,11 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), (m_frameToolBar->m_widget->parent == m_mainWidget)) { int xx = m_miniEdge; - int yy = m_miniEdge + m_miniTitle; + int yy = m_miniEdge + m_miniTitle #if wxUSE_MENUS_NATIVE - if (m_frameMenuBar) - { - if (!m_menuBarDetached) - yy += m_menuBarHeight; - else - yy += wxPLACE_HOLDER; - } -#endif // wxUSE_MENUS_NATIVE + + menubarHeight +#endif + ; m_frameToolBar->m_x = xx; m_frameToolBar->m_y = yy; @@ -443,19 +366,47 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), { ww = m_toolBarDetached ? wxPLACE_HOLDER : m_frameToolBar->m_width; - hh = m_height - 2*m_miniEdge; + 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 = m_width - 2*m_miniEdge; + 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 ); @@ -464,8 +415,12 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int client_x = client_area_x_offset + m_miniEdge; 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; + 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 ); @@ -480,8 +435,10 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), if (m_frameStatusBar && m_frameStatusBar->IsShown()) { int xx = 0 + m_miniEdge; - int yy = m_height - wxSTATUS_HEIGHT - m_miniEdge - client_area_y_offset; - int ww = m_width - 2*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; @@ -490,7 +447,6 @@ 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 ); } #endif // wxUSE_STATUSBAR @@ -615,23 +571,29 @@ void wxFrame::AttachMenuBar( wxMenuBar *menuBar ) void wxFrame::UpdateMenuBarSize() { - GtkRequisition req; - - req.width = 2; - req.height = 2; + m_menuBarHeight = 2; // this is called after Remove with a NULL m_frameMenuBar if ( m_frameMenuBar ) - (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(m_frameMenuBar->m_widget) )->size_request ) - (m_frameMenuBar->m_widget, &req ); - - m_menuBarHeight = req.height; + { + 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 #if wxUSE_TOOLBAR @@ -640,11 +602,10 @@ wxToolBar* wxFrame::CreateToolBar( long style, wxWindowID id, const wxString& na { wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") ); - m_insertInClientArea = false; - + InsertChildFunction save = m_insertCallback; + m_insertCallback = wxInsertChildInFrame; m_frameToolBar = wxFrameBase::CreateToolBar( style, id, name ); - - m_insertInClientArea = true; + m_insertCallback = save; GtkUpdateSize();