X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3d2d8da1d89c195cb44f95f267989118e205c7bf..6342bd1ab36c1957684c00d408d09fba65d33db6:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 805201a26c..aa212c4d05 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: window.cpp +// Name: gtk/window.cpp // Purpose: // Author: Robert Roebling // Id: $Id$ @@ -30,6 +30,10 @@ #include "wx/tooltip.h" #endif +#if wxUSE_CARET + #include "wx/caret.h" +#endif // wxUSE_CARET + #include "wx/menu.h" #include "wx/statusbr.h" #include "wx/intl.h" @@ -46,10 +50,13 @@ #include #include #include -#include - #include +#include +#include + +#include "wx/gtk/win_gtk.h" + //----------------------------------------------------------------------------- // documentation on internals //----------------------------------------------------------------------------- @@ -208,6 +215,8 @@ extern bool g_mainThreadLocked; // debug //----------------------------------------------------------------------------- +#define DISABLE_STYLE_IF_BROKEN_THEME 1 + #ifdef __WXDEBUG__ #if wxUSE_THREADS @@ -265,11 +274,23 @@ gdk_window_warp_pointer (GdkWindow *window, gint x, gint y) { +#ifndef __WXGTK20__ GdkWindowPrivate *priv; +#endif if (!window) - window = (GdkWindow*) &gdk_root_parent; + window = GDK_ROOT_PARENT(); +#ifdef __WXGTK20__ + if (!GDK_WINDOW_DESTROYED(window)) + { + XWarpPointer (GDK_WINDOW_XDISPLAY(window), + None, /* not source window -> move from anywhere */ + GDK_WINDOW_XID(window), /* dest window */ + 0, 0, 0, 0, /* not source window -> move from anywhere */ + x, y ); + } +#else priv = (GdkWindowPrivate*) window; if (!priv->destroyed) @@ -280,6 +301,7 @@ gdk_window_warp_pointer (GdkWindow *window, 0, 0, 0, 0, /* not source window -> move from anywhere */ x, y ); } +#endif } //----------------------------------------------------------------------------- @@ -293,6 +315,28 @@ extern bool g_isIdle; // local code (see below) //----------------------------------------------------------------------------- +// returns the child of win which currently has focus or NULL if not found +static wxWindow *FindFocusedChild(wxWindow *win) +{ + wxWindow *winFocus = wxWindow::FindFocus(); + if ( !winFocus ) + return (wxWindow *)NULL; + + if ( winFocus == win ) + return win; + + for ( wxWindowList::Node *node = win->GetChildren().GetFirst(); + node; + node = node->GetNext() ) + { + wxWindow *child = FindFocusedChild(node->GetData()); + if ( child ) + return child; + } + + return (wxWindow *)NULL; +} + static void draw_frame( GtkWidget *widget, wxWindow *win ) { if (!win->m_hasVMT) @@ -308,16 +352,16 @@ static void draw_frame( GtkWidget *widget, wxWindow *win ) GtkRequisition vscroll_req; vscroll_req.width = 2; vscroll_req.height = 2; - (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window->vscrollbar)->klass )->size_request ) + (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window->vscrollbar) )->size_request ) (scroll_window->vscrollbar, &vscroll_req ); GtkRequisition hscroll_req; hscroll_req.width = 2; hscroll_req.height = 2; - (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window->hscrollbar)->klass )->size_request ) + (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window->hscrollbar) )->size_request ) (scroll_window->hscrollbar, &hscroll_req ); - GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget)->klass ); + GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(widget) ); if (scroll_window->vscrollbar_visible) { @@ -379,10 +423,13 @@ static void draw_frame( GtkWidget *widget, wxWindow *win ) // "expose_event" of m_widget //----------------------------------------------------------------------------- -static void gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win ) +gint gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win ) { - if (gdk_event->count > 0) return; + if (gdk_event->count > 0) return FALSE; + draw_frame( widget, win ); + + return TRUE; } //----------------------------------------------------------------------------- @@ -495,7 +542,7 @@ static long map_to_unmodified_wx_keysym( KeySym keysym ) case GDK_F12: key_code = WXK_F12; break; default: { - if (keysym <= 0xFF) + if ((keysym & 0xF000) == 0) { guint upper = gdk_keyval_to_upper( (guint)keysym ); keysym = (upper != 0 ? upper : keysym ); /* to be MSW compatible */ @@ -594,7 +641,7 @@ static long map_to_wx_keysym( KeySym keysym ) case GDK_F12: key_code = WXK_F12; break; default: { - if (keysym <= 0xFF) + if ((keysym & 0xF000) == 0) { key_code = (guint)keysym; } @@ -608,15 +655,15 @@ static long map_to_wx_keysym( KeySym keysym ) // "expose_event" of m_wxwindow //----------------------------------------------------------------------------- -static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxWindow *win ) +static int gtk_window_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win ) { DEBUG_MAIN_THREAD - if (!win->m_hasVMT) - return; - + if (g_isIdle) + wxapp_install_idle_handler(); + /* - if (win->GetName() == wxT("columntitles")) + if (win->GetName() == wxT("panel")) { wxPrintf( wxT("OnExpose from ") ); if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) @@ -628,40 +675,91 @@ static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExp } */ - win->GetUpdateRegion().Union( gdk_event->area.x, - gdk_event->area.y, - gdk_event->area.width, - gdk_event->area.height ); + win->GetUpdateRegion().Union( gdk_event->area.x, + gdk_event->area.y, + gdk_event->area.width, + gdk_event->area.height ); + + if (gdk_event->count == 0) + { + wxEraseEvent eevent( win->GetId() ); + eevent.SetEventObject( win ); + win->GetEventHandler()->ProcessEvent(eevent); + wxPaintEvent event( win->GetId() ); + event.SetEventObject( win ); + win->GetEventHandler()->ProcessEvent( event ); - if (gdk_event->count > 0) - return; + win->GetUpdateRegion().Clear(); + } + + /* The following code will result in all window-less widgets + being redrawn if the wxWindows class is given a chance to + paint *anything* because it will then be allowed to paint + over the window-less widgets */ + + GtkPizza *pizza = GTK_PIZZA (widget); + + GList *children = pizza->children; + while (children) + { + GtkPizzaChild *child = (GtkPizzaChild*) children->data; + children = children->next; - wxEraseEvent eevent( win->GetId() ); - eevent.SetEventObject( win ); - win->GetEventHandler()->ProcessEvent(eevent); + GdkEventExpose child_event = *gdk_event; - wxPaintEvent event( win->GetId() ); - event.SetEventObject( win ); - win->GetEventHandler()->ProcessEvent( event ); + if (GTK_WIDGET_NO_WINDOW (child->widget) && + GTK_WIDGET_DRAWABLE (child->widget) /* && + gtk_widget_intersect (child->widget, &gdk_event->area, &child_event.area)*/ ) + { + child_event.area.x = child->widget->allocation.x; + child_event.area.y = child->widget->allocation.y; + child_event.area.width = child->widget->allocation.width; + child_event.area.height = child->widget->allocation.height; + gtk_widget_event (child->widget, (GdkEvent*) &child_event); + } + } + + return TRUE; +} + +//----------------------------------------------------------------------------- +// "event" of m_wxwindow +//----------------------------------------------------------------------------- + +/* GTK thinks it is clever and filters out a certain amount of "unneeded" + expose events. We need them, of course, so we override the main event + procedure in GtkWidget by giving our own handler for all system events. + There, we look for expose events ourselves whereas all other events are + handled normally. */ - win->GetUpdateRegion().Clear(); +gint gtk_window_event_event_callback( GtkWidget *widget, GdkEventExpose *event, wxWindow *win ) +{ + if (event->type == GDK_EXPOSE) + { + gint ret = gtk_window_expose_callback( widget, event, win ); + return ret; + } + + return FALSE; } //----------------------------------------------------------------------------- // "draw" of m_wxwindow //----------------------------------------------------------------------------- -static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), - GdkRectangle *rect, wxWindow *win ) +/* This callback is a complete replacement of the gtk_pizza_draw() function, + which disabled. */ + +static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxWindow *win ) { DEBUG_MAIN_THREAD if (g_isIdle) wxapp_install_idle_handler(); - + /* - if ((win->GetName() == wxT("columntitles")) && (rect->x == 2)) + if (win->GetName() == wxT("panel")) { wxPrintf( wxT("OnDraw from ") ); if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) @@ -672,19 +770,45 @@ static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), (int)rect->height ); } */ - - win->GetUpdateRegion().Union( rect->x, rect->y, - rect->width, rect->height ); + + GtkPizza *pizza = GTK_PIZZA (widget); + + if (!(GTK_WIDGET_APP_PAINTABLE (widget)) && + (pizza->clear_on_draw)) + { + gdk_window_clear_area( pizza->bin_window, + rect->x, rect->y, rect->width, rect->height); + } + + win->GetUpdateRegion().Union( rect->x, rect->y, rect->width, rect->height ); - wxEraseEvent eevent( win->GetId() ); - eevent.SetEventObject( win ); - win->GetEventHandler()->ProcessEvent(eevent); + win->m_clipPaintRegion = TRUE; + + wxEraseEvent eevent( win->GetId() ); + eevent.SetEventObject( win ); + win->GetEventHandler()->ProcessEvent(eevent); - wxPaintEvent event( win->GetId() ); - event.SetEventObject( win ); - win->GetEventHandler()->ProcessEvent( event ); + wxPaintEvent event( win->GetId() ); + event.SetEventObject( win ); + win->GetEventHandler()->ProcessEvent( event ); + + win->GetUpdateRegion().Clear(); + + win->m_clipPaintRegion = FALSE; + + + GList *children = pizza->children; + while (children) + { + GtkPizzaChild *child = (GtkPizzaChild*) children->data; + children = children->next; - win->GetUpdateRegion().Clear(); + GdkRectangle child_area; + if (gtk_widget_intersect (child->widget, rect, &child_area)) + { + gtk_widget_draw (child->widget, &child_area /* (GdkRectangle*) NULL*/ ); + } + } } //----------------------------------------------------------------------------- @@ -701,6 +825,7 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e if (!win->m_hasVMT) return FALSE; if (g_blockEventsOnDrag) return FALSE; + /* wxString tmp; tmp += (char)gdk_event->keyval; @@ -745,7 +870,7 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e ret = ancestor->GetEventHandler()->ProcessEvent( command_event ); break; } - if (ancestor->m_isFrame) + if (ancestor->IsTopLevel()) break; ancestor = ancestor->GetParent(); } @@ -777,7 +902,12 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e /* win is a control: tab can be propagated up */ if ( (!ret) && ((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab)) && +// VZ: testing for wxTE_PROCESS_TAB shouldn't be done here the control may +// have this style, yet choose not to process this particular TAB in which +// case TAB must still work as a navigational character +#if 0 (!win->HasFlag(wxTE_PROCESS_TAB)) && +#endif // 0 (win->GetParent()) && (win->GetParent()->HasFlag( wxTAB_TRAVERSAL)) ) { @@ -1400,6 +1530,15 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED( gdk_im_begin(win->m_ic, win->m_wxwindow->window); #endif +#ifdef wxUSE_CARET + // caret needs to be informed about focus change + wxCaret *caret = win->GetCaret(); + if ( caret ) + { + caret->OnSetFocus(); + } +#endif // wxUSE_CARET + wxFocusEvent event( wxEVT_SET_FOCUS, win->GetId() ); event.SetEventObject( win ); @@ -1431,6 +1570,10 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED // g_sendActivateEvent to -1 g_sendActivateEvent = 0; + wxWindow *winFocus = FindFocusedChild(win); + if ( winFocus ) + win = winFocus; + g_focusWindow = (wxWindow *)NULL; /* @@ -1445,6 +1588,15 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED gdk_im_end(); #endif +#ifdef wxUSE_CARET + // caret needs to be informed about focus change + wxCaret *caret = win->GetCaret(); + if ( caret ) + { + caret->OnKillFocus(); + } +#endif // wxUSE_CARET + wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() ); event.SetEventObject( win ); @@ -1637,6 +1789,7 @@ static gint gtk_scrollbar_button_press_callback( GtkRange *widget, if (g_isIdle) wxapp_install_idle_handler(); + g_blockEventsOnScroll = TRUE; win->m_isScrolling = (gdk_event->window == widget->slider); @@ -1662,7 +1815,7 @@ static gint gtk_scrollbar_button_release_callback( GtkRange *widget, if (win->m_isScrolling) { - wxEventType command = wxEVT_SCROLL_THUMBRELEASE; + wxEventType command = wxEVT_SCROLLWIN_THUMBRELEASE; int value = -1; int dir = -1; @@ -1833,8 +1986,8 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget), if ((colormap = gtk_widget_get_colormap (widget)) != gtk_widget_get_default_colormap ()) { - attrmask |= GDK_IC_PREEDIT_COLORMAP; - attr->preedit_colormap = colormap; + attrmask |= GDK_IC_PREEDIT_COLORMAP; + attr->preedit_colormap = colormap; } attrmask |= GDK_IC_PREEDIT_FOREGROUND; @@ -1966,8 +2119,13 @@ void wxWindow::Init() m_isFrame = FALSE; m_acceptsFocus = FALSE; + m_clipPaintRegion = FALSE; + m_cursor = *wxSTANDARD_CURSOR; + m_delayedForegroundColour = FALSE; + m_delayedBackgroundColour = FALSE; + #ifdef HAVE_XIM m_ic = (GdkIC*) NULL; m_icattr = (GdkICAttr*) NULL; @@ -2000,22 +2158,13 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, } m_insertCallback = wxInsertChildInWindow; - + m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL ); GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); -#ifdef __WXDEBUG__ - debug_focus_in( m_widget, wxT("wxWindow::m_widget"), name ); -#endif - GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(m_widget); -#ifdef __WXDEBUG__ - debug_focus_in( scrolledWindow->hscrollbar, wxT("wxWindow::hsrcollbar"), name ); - debug_focus_in( scrolledWindow->vscrollbar, wxT("wxWindow::vsrcollbar"), name ); -#endif - - GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass ); + GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(m_widget) ); scroll_class->scrollbar_spacing = 0; gtk_scrolled_window_set_policy( scrolledWindow, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); @@ -2025,10 +2174,6 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, m_wxwindow = gtk_pizza_new(); -#ifdef __WXDEBUG__ - debug_focus_in( m_wxwindow, wxT("wxWindow::m_wxwindow"), name ); -#endif - gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow ); #if (GTK_MINOR_VERSION > 0) @@ -2151,10 +2296,11 @@ wxWindow::~wxWindow() if (m_widgetStyle) { +#if DISABLE_STYLE_IF_BROKEN_THEME // don't delete if it's a pixmap theme style if (!m_widgetStyle->engine_data) gtk_style_unref( m_widgetStyle ); - +#endif m_widgetStyle = (GtkStyle*) NULL; } @@ -2212,6 +2358,12 @@ void wxWindow::PostCreation() if (!m_noExpose) { /* these get reported to wxWindows -> wxPaintEvent */ + + gtk_pizza_set_external( GTK_PIZZA(m_wxwindow), TRUE ); + + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "event", + GTK_SIGNAL_FUNC(gtk_window_event_event_callback), (gpointer)this ); + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event", GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this ); @@ -2321,7 +2473,7 @@ void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags ) if (m_resizing) return; /* I don't like recursions */ m_resizing = TRUE; - + if (m_parent->m_wxwindow == NULL) /* i.e. wxNotebook */ { /* don't set the size for children of wxNotebook, just take the values. */ @@ -2382,6 +2534,12 @@ void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags ) if (m_hasScrolling) { + /* 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. */ GetClientSize( &m_oldClientWidth, &m_oldClientHeight ); } @@ -2495,16 +2653,16 @@ void wxWindow::DoSetClientSize( int width, int height ) GtkRequisition vscroll_req; vscroll_req.width = 2; vscroll_req.height = 2; - (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window->vscrollbar)->klass )->size_request ) + (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window->vscrollbar) )->size_request ) (scroll_window->vscrollbar, &vscroll_req ); GtkRequisition hscroll_req; hscroll_req.width = 2; hscroll_req.height = 2; - (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window->hscrollbar)->klass )->size_request ) + (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window->hscrollbar) )->size_request ) (scroll_window->hscrollbar, &hscroll_req ); - GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass ); + GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(m_widget) ); if (scroll_window->vscrollbar_visible) { @@ -2557,16 +2715,16 @@ void wxWindow::DoGetClientSize( int *width, int *height ) const GtkRequisition vscroll_req; vscroll_req.width = 2; vscroll_req.height = 2; - (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window->vscrollbar)->klass )->size_request ) + (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window->vscrollbar) )->size_request ) (scroll_window->vscrollbar, &vscroll_req ); GtkRequisition hscroll_req; hscroll_req.width = 2; hscroll_req.height = 2; - (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window->hscrollbar)->klass )->size_request ) + (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window->hscrollbar) )->size_request ) (scroll_window->hscrollbar, &hscroll_req ); - GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass ); + GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(m_widget) ); if (scroll_window->vscrollbar_visible) { @@ -2843,7 +3001,16 @@ bool wxWindow::SetCursor( const wxCursor &cursor ) { wxCHECK_MSG( (m_widget != NULL), FALSE, wxT("invalid window") ); - return wxWindowBase::SetCursor( cursor ); + if (cursor == m_cursor) + return FALSE; + + if (g_isIdle) + wxapp_install_idle_handler(); + + if (cursor == wxNullCursor) + return wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ); + else + return wxWindowBase::SetCursor( cursor ); } void wxWindow::WarpPointer( int x, int y ) @@ -2889,37 +3056,69 @@ void wxWindow::Refresh( bool eraseBackground, const wxRect *rect ) { if (m_wxwindow) { + +/* GtkPizza *pizza = GTK_PIZZA(m_wxwindow); gboolean old_clear = pizza->clear_on_draw; gtk_pizza_set_clear( pizza, FALSE ); - gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL ); - gtk_pizza_set_clear( pizza, old_clear ); +*/ + GdkEventExpose gdk_event; + gdk_event.type = GDK_EXPOSE; + gdk_event.window = GTK_PIZZA(m_wxwindow)->bin_window; + gdk_event.count = 0; + gdk_event.area.x = 0; + gdk_event.area.y = 0; + gdk_event.area.width = m_wxwindow->allocation.width; + gdk_event.area.height = m_wxwindow->allocation.height; + gtk_window_expose_callback( m_wxwindow, &gdk_event, this ); + } else + { gtk_widget_draw( m_widget, (GdkRectangle*) NULL ); + } } else { - GdkRectangle gdk_rect; - gdk_rect.x = rect->x; - gdk_rect.y = rect->y; - gdk_rect.width = rect->width; - gdk_rect.height = rect->height; if (m_wxwindow) { +/* GtkPizza *pizza = GTK_PIZZA(m_wxwindow); gboolean old_clear = pizza->clear_on_draw; gtk_pizza_set_clear( pizza, FALSE ); + GdkRectangle gdk_rect; + gdk_rect.x = rect->x; + gdk_rect.y = rect->y; + gdk_rect.width = rect->width; + gdk_rect.height = rect->height; gtk_widget_draw( m_wxwindow, &gdk_rect ); + gtk_window_draw_callback( m_wxwindow, &gdk_rect, this ); gtk_pizza_set_clear( pizza, old_clear ); +*/ + GdkEventExpose gdk_event; + gdk_event.type = GDK_EXPOSE; + gdk_event.window = GTK_PIZZA(m_wxwindow)->bin_window; + gdk_event.count = 0; + gdk_event.area.x = rect->x; + gdk_event.area.y = rect->y; + gdk_event.area.width = rect->width; + gdk_event.area.height = rect->height; + gtk_window_expose_callback( m_wxwindow, &gdk_event, this ); } else + { + GdkRectangle gdk_rect; + gdk_rect.x = rect->x; + gdk_rect.y = rect->y; + gdk_rect.width = rect->width; + gdk_rect.height = rect->height; gtk_widget_draw( m_widget, &gdk_rect ); + } } } @@ -3026,7 +3225,12 @@ GtkStyle *wxWindow::GetWidgetStyle() if (m_widgetStyle) { GtkStyle *remake = gtk_style_copy( m_widgetStyle ); +#ifdef __WXGTK20__ + /* FIXME: is this necessary? */ + _G_TYPE_IGC(remake, GtkObjectClass) = _G_TYPE_IGC(m_widgetStyle, GtkObjectClass); +#else remake->klass = m_widgetStyle->klass; +#endif gtk_style_unref( m_widgetStyle ); m_widgetStyle = remake; @@ -3039,7 +3243,12 @@ GtkStyle *wxWindow::GetWidgetStyle() def = gtk_widget_get_default_style(); m_widgetStyle = gtk_style_copy( def ); +#ifdef __WXGTK20__ + /* FIXME: is this necessary? */ + _G_TYPE_IGC(m_widgetStyle, GtkObjectClass) = _G_TYPE_IGC(def, GtkObjectClass); +#else m_widgetStyle->klass = def->klass; +#endif } return m_widgetStyle; @@ -3047,6 +3256,7 @@ GtkStyle *wxWindow::GetWidgetStyle() void wxWindow::SetWidgetStyle() { +#if DISABLE_STYLE_IF_BROKEN_THEM if (m_widget->style->engine_data) { static bool s_warningPrinted = FALSE; @@ -3058,6 +3268,7 @@ void wxWindow::SetWidgetStyle() m_widgetStyle = m_widget->style; return; } +#endif GtkStyle *style = GetWidgetStyle(); @@ -3076,6 +3287,21 @@ void wxWindow::SetWidgetStyle() style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor(); style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor(); } + else + { + // Try to restore the gtk default style. This is still a little + // oversimplified for what is probably really needed here for controls + // other than buttons, but is better than not being able to (re)set a + // control's foreground colour to *wxBLACK -- RL + GtkStyle *def = gtk_rc_get_style( m_widget ); + + if (!def) + def = gtk_widget_get_default_style(); + + style->fg[GTK_STATE_NORMAL] = def->fg[GTK_STATE_NORMAL]; + style->fg[GTK_STATE_PRELIGHT] = def->fg[GTK_STATE_PRELIGHT]; + style->fg[GTK_STATE_ACTIVE] = def->fg[GTK_STATE_ACTIVE]; + } } if (m_backgroundColour.Ok()) @@ -3091,7 +3317,29 @@ void wxWindow::SetWidgetStyle() style->base[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor(); style->bg[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor(); style->base[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor(); - } + } + else + { + // Try to restore the gtk default style. This is still a little + // oversimplified for what is probably really needed here for controls + // other than buttons, but is better than not being able to (re)set a + // control's background colour to default grey and means resetting a + // button to wxSYS_COLOUR_BTNFACE will restore its usual highlighting + // behavior -- RL + GtkStyle *def = gtk_rc_get_style( m_widget ); + + if (!def) + def = gtk_widget_get_default_style(); + + style->bg[GTK_STATE_NORMAL] = def->bg[GTK_STATE_NORMAL]; + style->base[GTK_STATE_NORMAL] = def->base[GTK_STATE_NORMAL]; + style->bg[GTK_STATE_PRELIGHT] = def->bg[GTK_STATE_PRELIGHT]; + style->base[GTK_STATE_PRELIGHT] = def->base[GTK_STATE_PRELIGHT]; + style->bg[GTK_STATE_ACTIVE] = def->bg[GTK_STATE_ACTIVE]; + style->base[GTK_STATE_ACTIVE] = def->base[GTK_STATE_ACTIVE]; + style->bg[GTK_STATE_INSENSITIVE] = def->bg[GTK_STATE_INSENSITIVE]; + style->base[GTK_STATE_INSENSITIVE] = def->base[GTK_STATE_INSENSITIVE]; + } } } @@ -3245,6 +3493,10 @@ void wxWindow::CaptureMouse() if (!window) return; + wxCursor* cursor = & m_cursor; + if (!cursor->Ok()) + cursor = wxSTANDARD_CURSOR; + gdk_pointer_grab( window, FALSE, (GdkEventMask) (GDK_BUTTON_PRESS_MASK | @@ -3252,7 +3504,7 @@ void wxWindow::CaptureMouse() GDK_POINTER_MOTION_HINT_MASK | GDK_POINTER_MOTION_MASK), (GdkWindow *) NULL, - m_cursor.GetCursor(), + cursor->GetCursor(), (guint32)GDK_CURRENT_TIME ); g_captureWindow = this; } @@ -3438,6 +3690,62 @@ void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") ); + + if ((dx == 0) && (dy == 0)) return; + m_clipPaintRegion = TRUE; gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); + m_clipPaintRegion = FALSE; + +/* + if (m_children.GetCount() > 0) + { + gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); + } + else + { + GtkPizza *pizza = GTK_PIZZA(m_wxwindow); + + pizza->xoffset -= dx; + pizza->yoffset -= dy; + + GdkGC *m_scrollGC = gdk_gc_new( pizza->bin_window ); + gdk_gc_set_exposures( m_scrollGC, TRUE ); + + int cw = 0; + int ch = 0; + GetClientSize( &cw, &ch ); + int w = cw - abs(dx); + int h = ch - abs(dy); + + if ((h < 0) || (w < 0)) + { + Refresh(); + } + else + { + int s_x = 0; + int s_y = 0; + if (dx < 0) s_x = -dx; + if (dy < 0) s_y = -dy; + int d_x = 0; + int d_y = 0; + if (dx > 0) d_x = dx; + if (dy > 0) d_y = dy; + + gdk_window_copy_area( pizza->bin_window, m_scrollGC, d_x, d_y, + pizza->bin_window, s_x, s_y, w, h ); + + wxRect rect; + if (dx < 0) rect.x = cw+dx; else rect.x = 0; + if (dy < 0) rect.y = ch+dy; else rect.y = 0; + if (dy != 0) rect.width = cw; else rect.width = abs(dx); + if (dx != 0) rect.height = ch; else rect.height = abs(dy); + + Refresh( TRUE, &rect ); + } + + gdk_gc_unref( m_scrollGC ); + } +*/ }