wxTopLevelWindow (only for wxGTK for now)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11612 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2001-09-15 22:13:08 +00:00
parent 280df08533
commit 7d9f12f3b9
21 changed files with 2588 additions and 2529 deletions

View File

@@ -19,10 +19,6 @@
#pragma implementation "frame.h"
#endif
#ifdef __VMS
#define XIconifyWindow XICONIFYWINDOW
#endif
#include "wx/defs.h"
#include "wx/dialog.h"
@@ -66,23 +62,7 @@ extern int g_openDialogs;
// ----------------------------------------------------------------------------
#ifndef __WXUNIVERSAL__
IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
#endif
// ----------------------------------------------------------------------------
// data
// ----------------------------------------------------------------------------
extern wxList wxPendingDelete;
// ----------------------------------------------------------------------------
// debug
// ----------------------------------------------------------------------------
#ifdef __WXDEBUG__
extern void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window );
IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxTopLevelWindow)
#endif
// ============================================================================
@@ -93,66 +73,6 @@ extern void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar
// GTK callbacks
// ----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// "focus" from m_window
//-----------------------------------------------------------------------------
static gint gtk_frame_focus_callback( GtkWidget *widget, GtkDirectionType WXUNUSED(d), wxWindow *WXUNUSED(win) )
{
if (g_isIdle)
wxapp_install_idle_handler();
// This disables GTK's tab traversal
gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus" );
return TRUE;
}
//-----------------------------------------------------------------------------
// "size_allocate"
//-----------------------------------------------------------------------------
static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxFrameGTK *win )
{
if (g_isIdle)
wxapp_install_idle_handler();
if (!win->m_hasVMT)
return;
if ((win->m_width != alloc->width) || (win->m_height != alloc->height))
{
/*
wxPrintf( "OnSize from " );
if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
wxPrintf( win->GetClassInfo()->GetClassName() );
wxPrintf( " %d %d %d %d\n", (int)alloc->x,
(int)alloc->y,
(int)alloc->width,
(int)alloc->height );
*/
win->m_width = alloc->width;
win->m_height = alloc->height;
win->m_queuedFullRedraw = TRUE;
win->GtkUpdateSize();
}
}
//-----------------------------------------------------------------------------
// "delete_event"
//-----------------------------------------------------------------------------
static gint gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxFrameGTK *win )
{
if (g_isIdle)
wxapp_install_idle_handler();
if ((g_openDialogs == 0) && (win->IsEnabled()))
win->Close();
return TRUE;
}
#if wxUSE_MENUS_NATIVE
//-----------------------------------------------------------------------------
@@ -211,175 +131,6 @@ static void gtk_toolbar_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidge
}
#endif // wxUSE_TOOLBAR
//-----------------------------------------------------------------------------
// "configure_event"
//-----------------------------------------------------------------------------
static gint
#if (GTK_MINOR_VERSION > 0)
gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxFrameGTK *win )
#else
gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *event, wxFrameGTK *win )
#endif
{
if (g_isIdle)
wxapp_install_idle_handler();
if (!win->m_hasVMT)
return FALSE;
#if (GTK_MINOR_VERSION > 0)
int x = 0;
int y = 0;
gdk_window_get_root_origin( win->m_widget->window, &x, &y );
win->m_x = x;
win->m_y = y;
#else
win->m_x = event->x;
win->m_y = event->y;
#endif
wxMoveEvent mevent( wxPoint(win->m_x,win->m_y), win->GetId() );
mevent.SetEventObject( win );
win->GetEventHandler()->ProcessEvent( mevent );
return FALSE;
}
//-----------------------------------------------------------------------------
// "realize" from m_widget
//-----------------------------------------------------------------------------
/* we cannot MWM hints and icons before the widget has been realized,
so we do this directly after realization */
static void
gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget), wxFrameGTK *win )
{
if (g_isIdle)
wxapp_install_idle_handler();
if ((win->m_miniEdge > 0) || (win->HasFlag(wxSIMPLE_BORDER)) || (win->HasFlag(wxNO_BORDER)))
{
/* This is a mini-frame or a borderless frame. */
gdk_window_set_decorations( win->m_widget->window, (GdkWMDecoration)0 );
gdk_window_set_functions( win->m_widget->window, (GdkWMFunction)0 );
}
else
{
/* All this is for Motif Window Manager "hints" and is supposed to be
recognized by other WM as well. Not tested. */
long decor = (long) GDK_DECOR_BORDER;
long func = (long) GDK_FUNC_MOVE;
if ((win->GetWindowStyle() & wxCAPTION) != 0)
decor |= GDK_DECOR_TITLE;
if ((win->GetWindowStyle() & wxSYSTEM_MENU) != 0)
{
decor |= GDK_DECOR_MENU;
func |= GDK_FUNC_CLOSE;
}
if ((win->GetWindowStyle() & wxMINIMIZE_BOX) != 0)
{
func |= GDK_FUNC_MINIMIZE;
decor |= GDK_DECOR_MINIMIZE;
}
if ((win->GetWindowStyle() & wxMAXIMIZE_BOX) != 0)
{
func |= GDK_FUNC_MAXIMIZE;
decor |= GDK_DECOR_MAXIMIZE;
}
if ((win->GetWindowStyle() & wxRESIZE_BORDER) != 0)
{
func |= GDK_FUNC_RESIZE;
decor |= GDK_DECOR_RESIZEH;
}
gdk_window_set_decorations( win->m_widget->window, (GdkWMDecoration)decor);
gdk_window_set_functions( win->m_widget->window, (GdkWMFunction)func);
}
/* GTK's shrinking/growing policy */
if ((win->GetWindowStyle() & wxRESIZE_BORDER) == 0)
gtk_window_set_policy(GTK_WINDOW(win->m_widget), 0, 0, 1);
else
gtk_window_set_policy(GTK_WINDOW(win->m_widget), 1, 1, 1);
/* reset the icon */
wxIcon iconOld = win->GetIcon();
if ( iconOld != wxNullIcon )
{
wxIcon icon( iconOld );
win->SetIcon( wxNullIcon );
win->SetIcon( icon );
}
/* we set the focus to the child that accepts the focus. this
doesn't really have to be done in "realize" but why not? */
wxWindowList::Node *node = win->GetChildren().GetFirst();
while (node)
{
wxWindow *child = node->GetData();
if (child->AcceptsFocus())
{
child->SetFocus();
break;
}
node = node->GetNext();
}
}
//-----------------------------------------------------------------------------
// "map_event" from m_widget
//-----------------------------------------------------------------------------
static void
gtk_frame_map_callback( GtkWidget * WXUNUSED(widget),
GdkEvent * WXUNUSED(event),
wxFrame *win )
{
win->SetIconizeState(FALSE);
}
//-----------------------------------------------------------------------------
// "unmap_event" from m_widget
//-----------------------------------------------------------------------------
static void
gtk_frame_unmap_callback( GtkWidget * WXUNUSED(widget),
GdkEvent * WXUNUSED(event),
wxFrame *win )
{
win->SetIconizeState(TRUE);
}
//-----------------------------------------------------------------------------
// "expose_event" of m_client
//-----------------------------------------------------------------------------
static int gtk_window_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win )
{
GtkPizza *pizza = GTK_PIZZA(widget);
gtk_paint_flat_box (win->m_widget->style, pizza->bin_window, GTK_STATE_NORMAL,
GTK_SHADOW_NONE, &gdk_event->area, win->m_widget, "base", 0, 0, -1, -1);
return TRUE;
}
//-----------------------------------------------------------------------------
// "draw" of m_client
//-----------------------------------------------------------------------------
static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxWindow *win )
{
GtkPizza *pizza = GTK_PIZZA(widget);
gtk_paint_flat_box (win->m_widget->style, pizza->bin_window, GTK_STATE_NORMAL,
GTK_SHADOW_NONE, rect, win->m_widget, "base", 0, 0, -1, -1);
}
// ----------------------------------------------------------------------------
// wxFrameGTK itself
@@ -447,17 +198,8 @@ static void wxInsertChildInFrame( wxFrameGTK* parent, wxWindow* child )
void wxFrameGTK::Init()
{
m_sizeSet = FALSE;
m_miniEdge = 0;
m_miniTitle = 0;
m_mainWidget = (GtkWidget*) NULL;
m_menuBarDetached = FALSE;
m_toolBarDetached = FALSE;
m_insertInClientArea = TRUE;
m_isFrame = TRUE;
m_isIconized = FALSE;
m_fsIsShowing = FALSE;
m_themeEnabled = TRUE;
}
bool wxFrameGTK::Create( wxWindow *parent,
@@ -468,285 +210,28 @@ bool wxFrameGTK::Create( wxWindow *parent,
long style,
const wxString &name )
{
// always create a frame of some reasonable, even if arbitrary, size (at
// least for MSW compatibility)
wxSize size = sizeOrig;
if ( size.x == -1 || size.y == -1 )
{
wxSize sizeDpy = wxGetDisplaySize();
if ( size.x == -1 )
size.x = sizeDpy.x / 3;
if ( size.y == -1 )
size.y = sizeDpy.y / 5;
}
wxTopLevelWindows.Append( this );
m_needParent = FALSE;
if (!PreCreation( parent, pos, size ) ||
!CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
{
wxFAIL_MSG( wxT("wxFrameGTK creation failed") );
return FALSE;
}
m_title = title;
bool rt = wxTopLevelWindow::Create(parent, id, title, pos, sizeOrig,
style, name);
m_insertCallback = (wxInsertChildFunction) wxInsertChildInFrame;
GtkWindowType win_type = GTK_WINDOW_TOPLEVEL;
if (style & wxFRAME_TOOL_WINDOW)
win_type = GTK_WINDOW_POPUP;
m_widget = gtk_window_new( win_type );
if ((m_parent) && (HasFlag(wxFRAME_FLOAT_ON_PARENT)) && (GTK_IS_WINDOW(m_parent->m_widget)))
gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(m_parent->m_widget) );
if (!name.IsEmpty())
gtk_window_set_wmclass( GTK_WINDOW(m_widget), name.mb_str(), name.mb_str() );
#ifdef __WXDEBUG__
debug_focus_in( m_widget, wxT("wxFrameGTK::m_widget"), name );
#endif
gtk_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() );
GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
gtk_signal_connect( GTK_OBJECT(m_widget), "delete_event",
GTK_SIGNAL_FUNC(gtk_frame_delete_callback), (gpointer)this );
/* m_mainWidget holds the toolbar, the menubar and the client area */
m_mainWidget = gtk_pizza_new();
gtk_widget_show( m_mainWidget );
GTK_WIDGET_UNSET_FLAGS( m_mainWidget, GTK_CAN_FOCUS );
gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget );
/* for m_mainWidget themes */
gtk_signal_connect( GTK_OBJECT(m_mainWidget), "expose_event",
GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
gtk_signal_connect( GTK_OBJECT(m_mainWidget), "draw",
GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
#ifdef __WXDEBUG__
debug_focus_in( m_mainWidget, wxT("wxFrameGTK::m_mainWidget"), name );
#endif
/* m_wxwindow only represents the client area without toolbar and menubar */
m_wxwindow = gtk_pizza_new();
gtk_widget_show( m_wxwindow );
gtk_container_add( GTK_CONTAINER(m_mainWidget), m_wxwindow );
#ifdef __WXDEBUG__
debug_focus_in( m_wxwindow, wxT("wxFrameGTK::m_wxwindow"), name );
#endif
/* we donm't allow the frame to get the focus as otherwise
the frame will grab it at arbitrary focus changes. */
GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
if (m_parent) m_parent->AddChild( this );
/* the user resized the frame by dragging etc. */
gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate",
GTK_SIGNAL_FUNC(gtk_frame_size_callback), (gpointer)this );
PostCreation();
if ((m_x != -1) || (m_y != -1))
gtk_widget_set_uposition( m_widget, m_x, m_y );
gtk_widget_set_usize( m_widget, m_width, m_height );
/* we cannot set MWM hints and icons before the widget has
been realized, so we do this directly after realization */
gtk_signal_connect( GTK_OBJECT(m_widget), "realize",
GTK_SIGNAL_FUNC(gtk_frame_realized_callback), (gpointer) this );
/* the only way to get the window size is to connect to this event */
gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event",
GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this );
/* map and unmap for iconized state */
gtk_signal_connect( GTK_OBJECT(m_widget), "map_event",
GTK_SIGNAL_FUNC(gtk_frame_map_callback), (gpointer)this );
gtk_signal_connect( GTK_OBJECT(m_widget), "unmap_event",
GTK_SIGNAL_FUNC(gtk_frame_unmap_callback), (gpointer)this );
/* the only way to get the window size is to connect to this event */
gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event",
GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this );
/* disable native tab traversal */
gtk_signal_connect( GTK_OBJECT(m_widget), "focus",
GTK_SIGNAL_FUNC(gtk_frame_focus_callback), (gpointer)this );
return TRUE;
return rt;
}
wxFrameGTK::~wxFrameGTK()
{
m_isBeingDeleted = TRUE;
DeleteAllBars();
wxTopLevelWindows.DeleteObject( this );
if (wxTheApp->GetTopWindow() == this)
wxTheApp->SetTopWindow( (wxWindow*) NULL );
if ((wxTopLevelWindows.Number() == 0) &&
(wxTheApp->GetExitOnFrameDelete()))
{
wxTheApp->ExitMainLoop();
}
}
bool wxFrameGTK::ShowFullScreen(bool show, long style )
{
if (show == m_fsIsShowing) return FALSE; // return what?
m_fsIsShowing = show;
if (show)
{
m_fsSaveStyle = m_windowStyle;
m_fsSaveFlag = style;
GetPosition( &m_fsSaveFrame.x, &m_fsSaveFrame.y );
GetSize( &m_fsSaveFrame.width, &m_fsSaveFrame.height );
gtk_widget_hide( m_widget );
gtk_widget_unrealize( m_widget );
m_windowStyle = wxSIMPLE_BORDER;
int x;
int y;
wxDisplaySize( &x, &y );
SetSize( 0, 0, x, y );
gtk_widget_realize( m_widget );
gtk_widget_show( m_widget );
}
else
{
gtk_widget_hide( m_widget );
gtk_widget_unrealize( m_widget );
m_windowStyle = m_fsSaveStyle;
SetSize( m_fsSaveFrame.x, m_fsSaveFrame.y, m_fsSaveFrame.width, m_fsSaveFrame.height );
gtk_widget_realize( m_widget );
gtk_widget_show( m_widget );
}
return TRUE;
}
// ----------------------------------------------------------------------------
// overridden wxWindow methods
// ----------------------------------------------------------------------------
bool wxFrameGTK::Show( bool show )
{
wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
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 or from within the size_allocate
handler, because GTK 1.1.X forbids that. */
GtkOnSize( m_x, m_y, m_width, m_height );
}
return wxWindow::Show( show );
}
void wxFrameGTK::DoMoveWindow(int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(width), int WXUNUSED(height) )
{
wxFAIL_MSG( wxT("DoMoveWindow called for wxFrameGTK") );
}
void wxFrameGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags )
{
wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
/* this shouldn't happen: wxFrameGTK, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
/* avoid recursions */
if (m_resizing)
return;
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
{
m_x = x;
m_y = y;
m_width = width;
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;
}
*/
if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
if ((m_x != -1) || (m_y != -1))
{
if ((m_x != old_x) || (m_y != old_y))
{
gtk_widget_set_uposition( m_widget, m_x, m_y );
}
}
if ((m_width != old_width) || (m_height != old_height))
{
gtk_widget_set_usize( m_widget, m_width, m_height );
/* we set the size in GtkOnSize, i.e. mostly the actual resizing is
done either directly before the frame is shown or in idle time
so that different calls to SetSize() don't lead to flicker. */
m_sizeSet = FALSE;
}
m_resizing = FALSE;
}
void wxFrameGTK::DoGetClientSize( int *width, int *height ) const
{
wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
wxTopLevelWindow::DoGetClientSize( width, height );
wxWindow::DoGetClientSize( width, height );
if (height)
{
#if wxUSE_MENUS_NATIVE
@@ -762,7 +247,8 @@ void wxFrameGTK::DoGetClientSize( int *width, int *height ) const
#if wxUSE_STATUSBAR
/* status bar */
if (m_frameStatusBar && m_frameStatusBar->IsShown()) (*height) -= wxSTATUS_HEIGHT;
if (m_frameStatusBar && m_frameStatusBar->IsShown())
(*height) -= wxSTATUS_HEIGHT;
#endif // wxUSE_STATUSBAR
#if wxUSE_TOOLBAR
@@ -788,13 +274,6 @@ void wxFrameGTK::DoGetClientSize( int *width, int *height ) const
}
}
#endif // wxUSE_TOOLBAR
/* mini edge */
*height -= m_miniEdge*2 + m_miniTitle;
}
if (width)
{
*width -= m_miniEdge*2;
}
}
@@ -842,7 +321,7 @@ void wxFrameGTK::DoSetClientSize( int width, int height )
}
#endif
DoSetSize( -1, -1, width + m_miniEdge*2, height + m_miniEdge*2 + m_miniTitle, 0 );
wxTopLevelWindow::DoSetClientSize( width, height );
}
void wxFrameGTK::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
@@ -1015,25 +494,9 @@ void wxFrameGTK::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
m_resizing = FALSE;
}
void wxFrameGTK::MakeModal( bool modal )
{
if (modal)
gtk_grab_add( m_widget );
else
gtk_grab_remove( m_widget );
}
void wxFrameGTK::OnInternalIdle()
{
if (!m_sizeSet && GTK_WIDGET_REALIZED(m_wxwindow))
{
GtkOnSize( m_x, m_y, m_width, m_height );
// we'll come back later
if (g_isIdle)
wxapp_install_idle_handler();
return;
}
wxTopLevelWindow::OnInternalIdle();
#if wxUSE_MENUS_NATIVE
if (m_frameMenuBar) m_frameMenuBar->OnInternalIdle();
@@ -1044,8 +507,6 @@ void wxFrameGTK::OnInternalIdle()
#if wxUSE_STATUSBAR
if (m_frameStatusBar) m_frameStatusBar->OnInternalIdle();
#endif
wxWindow::OnInternalIdle();
}
// ----------------------------------------------------------------------------
@@ -1175,85 +636,3 @@ void wxFrameGTK::PositionStatusBar()
}
#endif // wxUSE_STATUSBAR
// ----------------------------------------------------------------------------
// frame title/icon
// ----------------------------------------------------------------------------
void wxFrameGTK::SetTitle( const wxString &title )
{
wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
m_title = title;
gtk_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() );
}
void wxFrameGTK::SetIcon( const wxIcon &icon )
{
wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
wxFrameBase::SetIcon(icon);
if ( !m_icon.Ok() )
return;
if (!m_widget->window)
return;
wxMask *mask = icon.GetMask();
GdkBitmap *bm = (GdkBitmap *) NULL;
if (mask) bm = mask->GetBitmap();
gdk_window_set_icon( m_widget->window, (GdkWindow *) NULL, icon.GetPixmap(), bm );
}
// ----------------------------------------------------------------------------
// frame state: maximized/iconized/normal
// ----------------------------------------------------------------------------
void wxFrameGTK::Maximize(bool WXUNUSED(maximize))
{
wxFAIL_MSG( _T("not implemented") );
}
bool wxFrameGTK::IsMaximized() const
{
// wxFAIL_MSG( _T("not implemented") );
// This is an approximation
return FALSE;
}
void wxFrameGTK::Restore()
{
wxFAIL_MSG( _T("not implemented") );
}
void wxFrameGTK::Iconize( bool iconize )
{
if (iconize)
{
GdkWindow *window = m_widget->window;
// you should do it later, for example from OnCreate() handler
wxCHECK_RET( window, _T("frame not created yet - can't iconize") );
XIconifyWindow( GDK_WINDOW_XDISPLAY( window ),
GDK_WINDOW_XWINDOW( window ),
DefaultScreen( GDK_DISPLAY() ) );
}
}
bool wxFrameGTK::IsIconized() const
{
return m_isIconized;
}
void wxFrameGTK::SetIconizeState(bool iconize)
{
if ( iconize != m_isIconized )
{
m_isIconized = iconize;
(void)SendIconizeEvent(iconize);
}
}