X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fc54776e31f04962739980d6cdcc894bb87a9c53..910276d73f05cce48eb3b30062f2b45dde2a6951:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 1e6c3b6b92..2ad8406d0c 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -2,9 +2,8 @@ // Name: window.cpp // Purpose: // Author: Robert Roebling -// Created: 01/02/97 -// Id: -// Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem +// Id: $Id$ +// Copyright: (c) 1998 Robert Roebling, Julian Smart // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -24,12 +23,9 @@ #include "wx/msgdlg.h" #include "wx/dcclient.h" #include "wx/dnd.h" -#include "wx/mdi.h" #include "wx/menu.h" -#include "wx/notebook.h" #include "wx/statusbr.h" #include "wx/intl.h" -#include "wx/gtk/win_gtk.h" #include "gdk/gdkprivate.h" #include "gdk/gdkkeysyms.h" @@ -139,7 +135,7 @@ static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExp if (gdk_event->count > 0) return; /* - printf( "OnExpose from " ); + printf( "OnExpose from " ); if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) printf( win->GetClassInfo()->GetClassName() ); printf( ".\n" ); @@ -842,7 +838,7 @@ static gint gtk_scrollbar_button_release_callback( GtkRange *widget, GdkEventBut // "drop_data_available_event" //----------------------------------------------------------------------------- -static void gtk_window_drop_callback( GtkWidget *widget, GdkEvent *event, wxWindow *win ) +static void gtk_window_drop_callback( GtkWidget *widget, GdkEventDropDataAvailable *event, wxWindow *win ) { if (!win->HasVMT()) return; @@ -851,7 +847,10 @@ static void gtk_window_drop_callback( GtkWidget *widget, GdkEvent *event, wxWind int x = 0; int y = 0; gdk_window_get_pointer( widget->window, &x, &y, (GdkModifierType *) NULL ); - win->GetDropTarget()->Drop( event, x, y ); + + printf( "Drop data is of type %s.\n", event->data_type ); + + win->GetDropTarget()->OnDrop( x, y, (const void*)event->data, (size_t)event->data_numbytes ); } /* @@ -860,6 +859,29 @@ static void gtk_window_drop_callback( GtkWidget *widget, GdkEvent *event, wxWind */ } +//----------------------------------------------------------------------------- +// InsertChild for wxWindow. +//----------------------------------------------------------------------------- + +// Callback for wxWindow. 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 wxNotebook requires a different way to insert +// a child in it. I had opted for creating a wxNotebookPage window class +// which would have made this superflouus (such in the MDI window system), +// but no-one is listening to me... + +static void wxInsertChildInWindow( wxWindow* parent, wxWindow* child ) +{ + gtk_myfixed_put( GTK_MYFIXED(parent->m_wxwindow), + GTK_WIDGET(child->m_widget), + child->m_x, + child->m_y ); + + gtk_widget_set_usize( GTK_WIDGET(child->m_widget), + child->m_width, + child->m_height ); +} + //----------------------------------------------------------------------------- // wxWindow //----------------------------------------------------------------------------- @@ -913,9 +935,19 @@ wxWindow::wxWindow() m_isEnabled = TRUE; m_pDropTarget = (wxDropTarget *) NULL; m_resizing = FALSE; - m_hasOwnStyle = FALSE; + m_scrollGC = (GdkGC*) NULL; + m_widgetStyle = (GtkStyle*) NULL; + m_insertCallback = wxInsertChildInWindow; } +wxWindow::wxWindow( wxWindow *parent, wxWindowID id, + const wxPoint &pos, const wxSize &size, + long style, const wxString &name ) +{ + m_insertCallback = wxInsertChildInWindow; + Create( parent, id, pos, size, style, name ); +} + bool wxWindow::Create( wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name ) @@ -924,8 +956,6 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, m_isEnabled = TRUE; m_needParent = TRUE; - m_cursor = (wxCursor *) NULL; - PreCreation( parent, id, pos, size, style, name ); m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL ); @@ -983,7 +1013,7 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, m_wxwindow = gtk_myfixed_new(); - if (m_wxwindow) GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); + GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); if (m_windowStyle & wxTAB_TRAVERSAL == wxTAB_TRAVERSAL) GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); @@ -1013,9 +1043,13 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" ); gtk_widget_show( m_wxwindow ); + + if (m_parent) m_parent->AddChild( this ); + (m_parent->m_insertCallback)( m_parent, this ); + PostCreation(); - + Show( TRUE ); return TRUE; @@ -1032,6 +1066,10 @@ wxWindow::~wxWindow() DestroyChildren(); + if (m_widgetStyle) gtk_style_unref( m_widgetStyle ); + + if (m_scrollGC) gdk_gc_unref( m_scrollGC ); + if (m_wxwindow) gtk_widget_destroy( m_wxwindow ); if (m_widget) gtk_widget_destroy( m_widget ); @@ -1074,17 +1112,34 @@ void wxWindow::PreCreation( wxWindow *parent, wxWindowID id, { if (m_needParent && (parent == NULL)) wxFatalError( "Need complete parent.", name ); - + m_widget = (GtkWidget *) NULL; m_hasVMT = FALSE; m_parent = parent; m_children.DeleteContents( FALSE ); - m_x = (int)pos.x; - m_y = (int)pos.y; + m_width = size.x; if (m_width == -1) m_width = 20; m_height = size.y; if (m_height == -1) m_height = 20; + + m_x = (int)pos.x; + m_y = (int)pos.y; + + if (!m_needParent) // some reasonable defaults + { + if (m_x == -1) + { + m_x = (gdk_screen_width () - m_width) / 2; + if (m_x < 10) m_x = 10; + } + if (m_y == -1) + { + m_y = (gdk_screen_height () - m_height) / 2; + if (m_y < 10) m_y = 10; + } + } + m_minWidth = -1; m_minHeight = -1; m_maxWidth = -1; @@ -1097,7 +1152,7 @@ void wxWindow::PreCreation( wxWindow *parent, wxWindowID id, m_cursor = new wxCursor( wxCURSOR_ARROW ); m_font = *wxSWISS_FONT; // m_backgroundColour = wxWHITE; - m_foregroundColour = wxBLACK; +// m_foregroundColour = wxBLACK; m_windowStyle = style; m_windowName = name; m_constraints = (wxLayoutConstraints *) NULL; @@ -1110,13 +1165,12 @@ void wxWindow::PreCreation( wxWindow *parent, wxWindowID id, m_pDropTarget = (wxDropTarget *) NULL; m_resizing = FALSE; m_windowValidator = (wxValidator *) NULL; - m_hasOwnStyle = FALSE; + m_scrollGC = (GdkGC*) NULL; + m_widgetStyle = (GtkStyle*) NULL; } void wxWindow::PostCreation() { - if (m_parent) m_parent->AddChild( this ); - if (m_wxwindow) { gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event", @@ -1130,11 +1184,7 @@ void wxWindow::PostCreation() if (m_widget && m_parent) gtk_widget_realize( m_widget ); - if (m_wxwindow) - { - gtk_widget_realize( m_wxwindow ); - gdk_gc_set_exposures( m_wxwindow->style->fg_gc[0], TRUE ); - } + if (m_wxwindow) gtk_widget_realize( m_wxwindow ); SetCursor( *wxSTANDARD_CURSOR ); @@ -1216,6 +1266,21 @@ void wxWindow::PrepareDC( wxDC &WXUNUSED(dc) ) // are we to set fonts here ? } +wxPoint wxWindow::GetClientAreaOrigin() const +{ + return wxPoint(0,0); +} + +void wxWindow::AdjustForParentClientOrigin( int& x, int& y, int sizeFlags ) +{ + if (((sizeFlags & wxSIZE_NO_ADJUSTMENTS) == 0) && GetParent()) + { + wxPoint pt(GetParent()->GetClientAreaOrigin()); + x += pt.x; + y += pt.y; + } +} + void wxWindow::ImplementSetSize() { if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth; @@ -1227,13 +1292,6 @@ void wxWindow::ImplementSetSize() void wxWindow::ImplementSetPosition() { - if (IS_KIND_OF(this,wxFrame) || IS_KIND_OF(this,wxDialog)) - { - if ((m_x != -1) || (m_y != -1)) - gtk_widget_set_uposition( m_widget, m_x, m_y ); - return; - } - if (!m_parent) { wxFAIL_MSG( "wxWindow::SetSize error.\n" ); @@ -1276,12 +1334,15 @@ void wxWindow::SetSize( int x, int y, int width, int height, int sizeFlags ) if (newH == -1) newH = 26; } + AdjustForParentClientOrigin( newX, newY, sizeFlags ); + if ((m_x != newX) || (m_y != newY) || (!m_sizeSet)) { m_x = newX; m_y = newY; ImplementSetPosition(); } + if ((m_width != newW) || (m_height != newH) || (!m_sizeSet)) { m_width = newW; @@ -1441,8 +1502,18 @@ void wxWindow::GetPosition( int *x, int *y ) const { wxASSERT_MSG( (m_widget != NULL), "invalid window" ); - if (x) (*x) = m_x; - if (y) (*y) = m_y; + int xx = m_x; + int yy = m_y; + + if (GetParent()) + { + wxPoint pt(GetParent()->GetClientAreaOrigin()); + xx -= pt.x; + yy -= pt.y; + } + + if (x) (*x) = xx; + if (y) (*y) = yy; } void wxWindow::ClientToScreen( int *x, int *y ) @@ -1468,6 +1539,10 @@ void wxWindow::ClientToScreen( int *x, int *y ) } } + wxPoint pt(GetClientAreaOrigin()); + org_x += pt.x; + org_y += pt.y; + if (x) *x += org_x; if (y) *y += org_y; } @@ -1495,6 +1570,10 @@ void wxWindow::ScreenToClient( int *x, int *y ) } } + wxPoint pt(GetClientAreaOrigin()); + org_x -= pt.x; + org_y -= pt.y; + if (x) *x -= org_x; if (y) *y -= org_y; } @@ -1672,72 +1751,9 @@ bool wxWindow::OnClose() void wxWindow::AddChild( wxWindow *child ) { wxASSERT_MSG( (m_widget != NULL), "invalid window" ); - wxASSERT_MSG( (m_wxwindow != NULL), "window need client area" ); wxASSERT_MSG( (child != NULL), "invalid child" ); - wxASSERT_MSG( (child->m_widget != NULL), "invalid child" ); - - // Addchild is (often) called before the program - // has left the parents constructor so that no - // virtual tables work yet. The approach below - // practically imitates virtual tables, i.e. it - // implements a different AddChild() behaviour - // for wxFrame, wxDialog, wxWindow and - // wxMDIParentFrame. - - // wxFrame and wxDialog as children aren't placed into the parents - - if (( IS_KIND_OF(child,wxFrame) || IS_KIND_OF(child,wxDialog) ) && - (!IS_KIND_OF(child,wxMDIChildFrame))) - { - m_children.Append( child ); - - if ((child->m_x != -1) && (child->m_y != -1)) - gtk_widget_set_uposition( child->m_widget, child->m_x, child->m_y ); - - return; - } - - // In the case of an wxMDIChildFrame descendant, we use the - // client windows's AddChild() - - if (IS_KIND_OF(this,wxMDIParentFrame)) - { - if (IS_KIND_OF(child,wxMDIChildFrame)) - { - wxMDIClientWindow *client = ((wxMDIParentFrame*)this)->GetClientWindow(); - if (client) - { - client->AddChild( child ); - return; - } - } - } - - // wxNotebook is very special, so it has a private AddChild() - - if (IS_KIND_OF(this,wxNotebook)) - { - wxNotebook *tab = (wxNotebook*)this; - tab->AddChild( child ); - return; - } - - // wxFrame has a private AddChild - - if (IS_KIND_OF(this,wxFrame) && !IS_KIND_OF(this,wxMDIChildFrame)) - { - wxFrame *frame = (wxFrame*)this; - frame->AddChild( child ); - return; - } - - // All the rest m_children.Append( child ); - if (m_wxwindow) gtk_myfixed_put( GTK_MYFIXED(m_wxwindow), child->m_widget, - child->m_x, child->m_y ); - - gtk_widget_set_usize( child->m_widget, child->m_width, child->m_height ); } wxList *wxWindow::GetChildren() @@ -1747,8 +1763,7 @@ wxList *wxWindow::GetChildren() void wxWindow::RemoveChild( wxWindow *child ) { - if (GetChildren()) - GetChildren()->DeleteObject( child ); + if (GetChildren()) GetChildren()->DeleteObject( child ); child->m_parent = (wxWindow *) NULL; } @@ -1949,23 +1964,22 @@ wxColour wxWindow::GetBackgroundColour() const return m_backgroundColour; } -void wxWindow::SetBackgroundColourHelper( GdkWindow *window ) -{ - if (!m_backgroundColour.Ok()) return; - - m_backgroundColour.CalcPixel( gdk_window_get_colormap( window ) ); - gdk_window_set_background( window, m_backgroundColour.GetColor() ); - gdk_window_clear( window ); -} - void wxWindow::SetBackgroundColour( const wxColour &colour ) { wxCHECK_RET( m_widget != NULL, "invalid window" ); m_backgroundColour = colour; + if (!m_backgroundColour.Ok()) return; - GtkWidget *widget = m_wxwindow == NULL ? m_widget : m_wxwindow; - SetBackgroundColourHelper( widget->window ); + if (m_wxwindow) + { + GdkWindow *window = m_wxwindow->window; + m_backgroundColour.CalcPixel( gdk_window_get_colormap( window ) ); + gdk_window_set_background( window, m_backgroundColour.GetColor() ); + gdk_window_clear( window ); + } + + ApplyWidgetStyle(); } wxColour wxWindow::GetForegroundColour() const @@ -1975,7 +1989,56 @@ wxColour wxWindow::GetForegroundColour() const void wxWindow::SetForegroundColour( const wxColour &colour ) { + wxCHECK_RET( m_widget != NULL, "invalid window" ); + m_foregroundColour = colour; + if (!m_foregroundColour.Ok()) return; + + ApplyWidgetStyle(); +} + +GtkStyle *wxWindow::GetWidgetStyle() +{ + if (m_widgetStyle) gtk_style_unref( m_widgetStyle ); + + m_widgetStyle = + gtk_style_copy( + gtk_widget_get_style( m_widget ) ); + + return m_widgetStyle; +} + +void wxWindow::SetWidgetStyle() +{ + GtkStyle *style = GetWidgetStyle(); + + gdk_font_unref( style->font ); + style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) ); + + if (m_foregroundColour.Ok()) + { + m_foregroundColour.CalcPixel( gdk_window_get_colormap( m_widget->window ) ); + style->fg[GTK_STATE_NORMAL] = *m_foregroundColour.GetColor(); + style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor(); + style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor(); + } + + if (m_backgroundColour.Ok()) + { + m_backgroundColour.CalcPixel( gdk_window_get_colormap( m_widget->window ) ); + style->bg[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor(); + style->base[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor(); + style->bg[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor(); + style->base[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor(); + style->bg[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor(); + style->base[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor(); + style->bg[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor(); + style->base[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor(); + } +} + +void wxWindow::ApplyWidgetStyle() +{ } bool wxWindow::Validate() @@ -2039,7 +2102,7 @@ void wxWindow::OnInitDialog( wxInitDialogEvent &WXUNUSED(event) ) void wxWindow::InitDialog() { - wxASSERT_MSG( (m_widget != NULL), "invalid window" ); + wxCHECK_RET( m_widget != NULL, "invalid window" ); wxInitDialogEvent event(GetId()); event.SetEventObject( this ); @@ -2061,8 +2124,10 @@ static void SetInvokingWindow( wxMenu *menu, wxWindow *win ) bool wxWindow::PopupMenu( wxMenu *menu, int WXUNUSED(x), int WXUNUSED(y) ) { - wxASSERT_MSG( (m_widget != NULL), "invalid window" ); + wxCHECK_MSG( m_widget != NULL, FALSE, "invalid window" ); + wxCHECK_MSG( menu != NULL, FALSE, "invalid popup-menu" ); + SetInvokingWindow( menu, this ); gtk_menu_popup( GTK_MENU(menu->m_menu), @@ -2078,7 +2143,7 @@ bool wxWindow::PopupMenu( wxMenu *menu, int WXUNUSED(x), int WXUNUSED(y) ) void wxWindow::SetDropTarget( wxDropTarget *dropTarget ) { - wxASSERT_MSG( (m_widget != NULL), "invalid window" ); + wxCHECK_RET( m_widget != NULL, "invalid window" ); GtkWidget *dnd_widget = GetConnectWidget(); @@ -2131,28 +2196,14 @@ bool wxWindow::IsOwnGtkWindow( GdkWindow *window ) void wxWindow::SetFont( const wxFont &font ) { - wxASSERT_MSG( (m_widget != NULL), "invalid window" ); + wxCHECK_RET( m_widget != NULL, "invalid window" ); if (((wxFont*)&font)->Ok()) m_font = font; else m_font = *wxSWISS_FONT; - - GtkStyle *style = (GtkStyle*) NULL; - if (!m_hasOwnStyle) - { - m_hasOwnStyle = TRUE; - style = gtk_style_copy( gtk_widget_get_style( m_widget ) ); - } - else - { - style = gtk_widget_get_style( m_widget ); - } - - gdk_font_unref( style->font ); - style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) ); - - gtk_widget_set_style( m_widget, style ); + + ApplyWidgetStyle(); } wxFont *wxWindow::GetFont() @@ -2172,9 +2223,9 @@ long wxWindow::GetWindowStyleFlag() const void wxWindow::CaptureMouse() { - wxASSERT_MSG( (m_widget != NULL), "invalid window" ); + wxCHECK_RET( m_widget != NULL, "invalid window" ); - wxASSERT_MSG( (g_capturing == FALSE), "CaptureMouse called twice" ); + wxCHECK_RET( g_capturing == FALSE, "CaptureMouse called twice" ); GtkWidget *connect_widget = GetConnectWidget(); gtk_grab_add( connect_widget ); @@ -2189,9 +2240,9 @@ void wxWindow::CaptureMouse() void wxWindow::ReleaseMouse() { - wxASSERT_MSG( (m_widget != NULL), "invalid window" ); + wxCHECK_RET( m_widget != NULL, "invalid window" ); - wxASSERT_MSG( (g_capturing == TRUE), "ReleaseMouse called twice" ); + wxCHECK_RET( g_capturing == TRUE, "ReleaseMouse called twice" ); GtkWidget *connect_widget = GetConnectWidget(); gtk_grab_remove( connect_widget ); @@ -2431,7 +2482,14 @@ void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) int d_y = 0; if (dx > 0) d_x = dx; if (dy > 0) d_y = dy; - gdk_window_copy_area( m_wxwindow->window, m_wxwindow->style->fg_gc[0], d_x, d_y, + + if (!m_scrollGC) + { + m_scrollGC = gdk_gc_new( m_wxwindow->window ); + gdk_gc_set_exposures( m_scrollGC, TRUE ); + } + + gdk_window_copy_area( m_wxwindow->window, m_scrollGC, d_x, d_y, m_wxwindow->window, s_x, s_y, w, h ); wxRect rect;