X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/afbe906abdf9aa69a56571b8b20b095351dd8f34..b78d046d82b43135f3ab0c8fd5edbd9e68ad712b:/src/gtk/window.cpp?ds=sidebyside diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 4294a2a249..c68761947b 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -25,6 +25,7 @@ #include "wx/utils.h" #include "wx/dialog.h" #include "wx/msgdlg.h" +#include "wx/module.h" #if wxUSE_DRAG_AND_DROP #include "wx/dnd.h" @@ -39,7 +40,7 @@ #endif // wxUSE_CARET #if wxUSE_TEXTCTRL -#include "wx/textctrl.h" + #include "wx/textctrl.h" #endif #include "wx/menu.h" @@ -54,8 +55,7 @@ #include -#include -#include +#include "wx/gtk/private.h" #include #include #include @@ -65,6 +65,22 @@ #include "wx/gtk/win_gtk.h" +#ifdef __WXGTK20__ + #define SET_CONTAINER_FOCUS(w, d) gtk_widget_child_focus((w), (d)) +#else + #define SET_CONTAINER_FOCUS(w, d) gtk_container_focus(GTK_CONTAINER(w), (d)) +#endif + +#ifdef __WXGTK20__ + #ifdef HAVE_XIM + #undef HAVE_XIM + #endif +#endif + +#ifdef __WXGTK20__ +extern GtkContainerClass *pizza_parent_class; +#endif + //----------------------------------------------------------------------------- // documentation on internals //----------------------------------------------------------------------------- @@ -204,6 +220,8 @@ extern bool g_blockEventsOnDrag; extern bool g_blockEventsOnScroll; extern wxCursor g_globalCursor; +static GdkGC *g_eraseGC = NULL; + // mouse capture state: the window which has it and if the mouse is currently // inside it static wxWindowGTK *g_captureWindow = (wxWindowGTK*) NULL; @@ -372,7 +390,6 @@ static wxWindowGTK* wxGetTopLevelParent(wxWindowGTK *win) return p; } - static void draw_frame( GtkWidget *widget, wxWindowGTK *win ) { // wxUniversal widgets draw the borders and scrollbars themselves @@ -468,6 +485,11 @@ gint gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_even draw_frame( widget, win ); +#ifdef __WXGTK20__ + + (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, gdk_event); + +#endif return TRUE; } @@ -475,11 +497,15 @@ gint gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_even // "draw" of m_widget //----------------------------------------------------------------------------- +#ifndef __WXGTK20__ + static void gtk_window_own_draw_callback( GtkWidget *widget, GdkRectangle *WXUNUSED(rect), wxWindowGTK *win ) { draw_frame( widget, win ); } +#endif + //----------------------------------------------------------------------------- // key code mapping routines //----------------------------------------------------------------------------- @@ -805,6 +831,12 @@ static int gtk_window_expose_callback( GtkWidget *widget, // Actual redrawing takes place in idle time. win->Update(); +#ifdef __WXGTK20__ + + (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, gdk_event); + +#endif + return TRUE; } @@ -835,8 +867,10 @@ gint gtk_window_event_event_callback( GtkWidget *widget, // "draw" of m_wxwindow //----------------------------------------------------------------------------- +#ifndef __WXGTK20__ + // This callback is a complete replacement of the gtk_pizza_draw() function, -// which disabled. +// which is disabled. static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, @@ -901,7 +935,7 @@ static void gtk_window_draw_callback( GtkWidget *widget, win->GetUpdateRegion().Union( rect->x, rect->y, rect->width, rect->height ); // Actual redrawing takes place in idle time. - + win->Update(); #ifndef __WXUNIVERSAL__ @@ -921,6 +955,8 @@ static void gtk_window_draw_callback( GtkWidget *widget, #endif } +#endif + //----------------------------------------------------------------------------- // "key_press_event" from any window //----------------------------------------------------------------------------- @@ -1857,7 +1893,9 @@ static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_ // "value_changed" from m_vAdjust //----------------------------------------------------------------------------- -static void gtk_window_vscroll_callback( GtkAdjustment *adjust, wxWindowGTK *win ) +static void gtk_window_vscroll_callback( GtkAdjustment *adjust, + SCROLLBAR_CBACK_ARG + wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -1873,14 +1911,7 @@ static void gtk_window_vscroll_callback( GtkAdjustment *adjust, wxWindowGTK *win win->m_oldVerticalPos = adjust->value; - GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(win->m_widget); - GtkRange *range = GTK_RANGE( scrolledWindow->vscrollbar ); - - wxEventType command = wxEVT_SCROLLWIN_THUMBTRACK; - if (range->scroll_type == GTK_SCROLL_STEP_BACKWARD) command = wxEVT_SCROLLWIN_LINEUP; - else if (range->scroll_type == GTK_SCROLL_STEP_FORWARD) command = wxEVT_SCROLLWIN_LINEDOWN; - else if (range->scroll_type == GTK_SCROLL_PAGE_BACKWARD) command = wxEVT_SCROLLWIN_PAGEUP; - else if (range->scroll_type == GTK_SCROLL_PAGE_FORWARD) command = wxEVT_SCROLLWIN_PAGEDOWN; + wxEventType command = GtkScrollWinTypeToWx(GET_SCROLL_TYPE(win->m_widget)); int value = (int)(adjust->value+0.5); @@ -1893,7 +1924,9 @@ static void gtk_window_vscroll_callback( GtkAdjustment *adjust, wxWindowGTK *win // "value_changed" from m_hAdjust //----------------------------------------------------------------------------- -static void gtk_window_hscroll_callback( GtkAdjustment *adjust, wxWindowGTK *win ) +static void gtk_window_hscroll_callback( GtkAdjustment *adjust, + SCROLLBAR_CBACK_ARG + wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -1906,16 +1939,9 @@ static void gtk_window_hscroll_callback( GtkAdjustment *adjust, wxWindowGTK *win float diff = adjust->value - win->m_oldHorizontalPos; if (fabs(diff) < 0.2) return; - win->m_oldHorizontalPos = adjust->value; + wxEventType command = GtkScrollWinTypeToWx(GET_SCROLL_TYPE(win->m_widget)); - GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(win->m_widget); - GtkRange *range = GTK_RANGE( scrolledWindow->hscrollbar ); - - wxEventType command = wxEVT_SCROLLWIN_THUMBTRACK; - if (range->scroll_type == GTK_SCROLL_STEP_BACKWARD) command = wxEVT_SCROLLWIN_LINEUP; - else if (range->scroll_type == GTK_SCROLL_STEP_FORWARD) command = wxEVT_SCROLLWIN_LINEDOWN; - else if (range->scroll_type == GTK_SCROLL_PAGE_BACKWARD) command = wxEVT_SCROLLWIN_PAGEUP; - else if (range->scroll_type == GTK_SCROLL_PAGE_FORWARD) command = wxEVT_SCROLLWIN_PAGEDOWN; + win->m_oldHorizontalPos = adjust->value; int value = (int)(adjust->value+0.5); @@ -1939,7 +1965,11 @@ static gint gtk_scrollbar_button_press_callback( GtkRange *widget, g_blockEventsOnScroll = TRUE; + + // FIXME: there is no 'slider' field in GTK+ 2.0 any more +#ifndef __WXGTK20__ win->m_isScrolling = (gdk_event->window == widget->slider); +#endif return FALSE; } @@ -2338,10 +2368,7 @@ bool wxWindowGTK::Create( wxWindow *parent, m_wxwindow = gtk_pizza_new(); - gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow ); - #ifndef __WXUNIVERSAL__ -#if (GTK_MINOR_VERSION > 0) GtkPizza *pizza = GTK_PIZZA(m_wxwindow); if (HasFlag(wxRAISED_BORDER)) @@ -2360,33 +2387,13 @@ bool wxWindowGTK::Create( wxWindow *parent, { gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_NONE ); } -#else // GTK_MINOR_VERSION == 0 - GtkViewport *viewport = GTK_VIEWPORT(scrolledWindow->viewport); - - if (HasFlag(wxRAISED_BORDER)) - { - gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_OUT ); - } - else if (HasFlag(wxSUNKEN_BORDER)) - { - gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_IN ); - } - else - { - gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_NONE ); - } -#endif // GTK_MINOR_VERSION #endif // __WXUNIVERSAL__ + gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow ); + GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); m_acceptsFocus = TRUE; -#if (GTK_MINOR_VERSION == 0) - // shut the viewport up - gtk_viewport_set_hadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); - gtk_viewport_set_vadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); -#endif // GTK_MINOR_VERSION == 0 - // I _really_ don't want scrollbars in the beginning m_vAdjust->lower = 0.0; m_vAdjust->upper = 1.0; @@ -2538,6 +2545,7 @@ void wxWindowGTK::PostCreation() gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event", GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this ); +#ifndef __WXGTK20__ gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw", GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this ); @@ -2546,14 +2554,19 @@ void wxWindowGTK::PostCreation() gtk_signal_connect( GTK_OBJECT(m_wxwindow), "event", GTK_SIGNAL_FUNC(gtk_window_event_event_callback), (gpointer)this ); } +#else + gtk_widget_set_redraw_on_allocate( GTK_WIDGET(m_wxwindow), HasFlag( wxNO_FULL_REPAINT_ON_RESIZE ) ); +#endif } - // these are called when the "sunken" or "raised" borders are drawn */ + // these are called when the "sunken" or "raised" borders are drawn gtk_signal_connect( GTK_OBJECT(m_widget), "expose_event", GTK_SIGNAL_FUNC(gtk_window_own_expose_callback), (gpointer)this ); +#ifndef __WXGTK20__ gtk_signal_connect( GTK_OBJECT(m_widget), "draw", GTK_SIGNAL_FUNC(gtk_window_own_draw_callback), (gpointer)this ); +#endif } // focus handling @@ -2561,12 +2574,6 @@ void wxWindowGTK::PostCreation() if (m_focusWidget == NULL) m_focusWidget = m_widget; -#if 0 - if (GetClassInfo() && GetClassInfo()->GetClassName()) - wxPrintf( GetClassInfo()->GetClassName() ); - wxPrintf( ".\n" ); -#endif - gtk_signal_connect( GTK_OBJECT(m_focusWidget), "focus_in_event", GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this ); @@ -2682,7 +2689,6 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags else { GtkPizza *pizza = GTK_PIZZA(m_parent->m_wxwindow); - if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0) { if (x != -1) m_x = x + pizza->xoffset; @@ -2721,12 +2727,14 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags int border = 0; int bottom_border = 0; +#ifndef __WXGTK20__ if (GTK_WIDGET_CAN_DEFAULT(m_widget)) { /* the default button has a border around it */ border = 6; bottom_border = 5; } +#endif DoMoveWindow( m_x-border, m_y-border, @@ -2766,7 +2774,7 @@ void wxWindowGTK::OnInternalIdle() { // Update invalidated regions. Update(); - + // Synthetize activate events. if ( g_sendActivateEvent != -1 ) { @@ -3167,7 +3175,7 @@ void wxWindowGTK::SetFocus() } else if (GTK_IS_CONTAINER(m_widget)) { - gtk_container_focus( GTK_CONTAINER(m_widget), GTK_DIR_TAB_FORWARD ); + SET_CONTAINER_FOCUS( m_widget, GTK_DIR_TAB_FORWARD ); } else { @@ -3288,12 +3296,7 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect ) if (!m_widget) return; if (!m_widget->window) return; - // temporarily hide the caret to avoid nasty interactions between caret - // drawing and the window contents redraw -#if 0 // def wxUSE_CARET -- doesn't seem to help :-( - wxCaretSuspend cs((wxWindow *)this); -#endif // wxUSE_CARET - +#ifndef __WXGTK20__ if (eraseBackground && m_wxwindow && m_wxwindow->window) { if (rect) @@ -3339,14 +3342,35 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect ) gtk_widget_draw( m_widget, (GdkRectangle*) NULL ); } } +#else + if (m_wxwindow) + { + if (rect) + { + GdkRectangle gdk_rect; + gdk_rect.x = rect->x; + gdk_rect.y = rect->y; + gdk_rect.width = rect->width; + gdk_rect.height = rect->height; + gdk_window_invalidate_rect( GTK_PIZZA(m_wxwindow)->bin_window, &gdk_rect, TRUE ); + } + else + { + gdk_window_invalidate_rect( GTK_PIZZA(m_wxwindow)->bin_window, NULL, TRUE ); + } + } +#endif } void wxWindowGTK::Update() { +#ifdef __WXGTK20__ + if (m_wxwindow && GTK_PIZZA(m_wxwindow)->bin_window) + gdk_window_process_updates( GTK_PIZZA(m_wxwindow)->bin_window, FALSE ); +#endif + if (!m_updateRegion.IsEmpty()) - { GtkSendPaintEvents(); - } } void wxWindowGTK::GtkSendPaintEvents() @@ -3364,16 +3388,18 @@ void wxWindowGTK::GtkSendPaintEvents() { wxWindowDC dc( (wxWindow*)this ); dc.SetClippingRegion( m_clearRegion ); - + wxEraseEvent erase_event( GetId(), &dc ); erase_event.SetEventObject( this ); - + if (!GetEventHandler()->ProcessEvent(erase_event)) { + gdk_gc_set_foreground( g_eraseGC, m_backgroundColour.GetColor() ); + wxRegionIterator upd( m_clearRegion ); while (upd) { - gdk_window_clear_area( GTK_PIZZA(m_wxwindow)->bin_window, + gdk_draw_rectangle( GTK_PIZZA(m_wxwindow)->bin_window, g_eraseGC, 0, upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() ); upd ++; } @@ -3392,12 +3418,13 @@ void wxWindowGTK::GtkSendPaintEvents() m_clipPaintRegion = FALSE; #ifndef __WXUNIVERSAL__ +#ifndef __WXGTK20__ // The following code will result in all window-less widgets // being redrawn because the wxWindows class is allowed to // paint over the window-less widgets. - + GtkPizza *pizza = GTK_PIZZA(m_wxwindow); - + GList *children = pizza->children; while (children) { @@ -3409,12 +3436,12 @@ void wxWindowGTK::GtkSendPaintEvents() { // Get intersection of widget area and update region wxRegion region( m_updateRegion ); - + GdkEventExpose gdk_event; gdk_event.type = GDK_EXPOSE; gdk_event.window = pizza->bin_window; gdk_event.count = 0; - + wxRegionIterator upd( m_updateRegion ); while (upd) { @@ -3423,16 +3450,17 @@ void wxWindowGTK::GtkSendPaintEvents() rect.y = upd.GetY(); rect.width = upd.GetWidth(); rect.height = upd.GetHeight(); - + if (gtk_widget_intersect (child->widget, &rect, &gdk_event.area)) { gtk_widget_event (child->widget, (GdkEvent*) &gdk_event); } - + upd ++; } } } +#endif #endif m_updateRegion.Clear(); @@ -3541,10 +3569,9 @@ GtkStyle *wxWindowGTK::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 + + // FIXME: no more klass in 2.0 +#ifndef __WXGTK20__ remake->klass = m_widgetStyle->klass; #endif @@ -3559,10 +3586,9 @@ GtkStyle *wxWindowGTK::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 + + // FIXME: no more klass in 2.0 +#ifndef __WXGTK20__ m_widgetStyle->klass = def->klass; #endif } @@ -3590,8 +3616,7 @@ void wxWindowGTK::SetWidgetStyle() if (m_font != wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT )) { - gdk_font_unref( style->font ); - style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) ); + SET_STYLE_FONT(style, m_font.GetInternalFont( 1.0 )); } if (m_foregroundColour.Ok()) @@ -3701,6 +3726,9 @@ static gint gs_pop_y = 0; extern "C" void wxPopupMenuPositionCallback( GtkMenu *menu, gint *x, gint *y, +#ifdef __WXGTK20__ + gboolean * WXUNUSED(whatever), +#endif gpointer WXUNUSED(user_data) ) { // ensure that the menu appears entirely on screen @@ -4036,89 +4064,45 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) // No scrolling requested. if ((dx == 0) && (dy == 0)) return; - + +#ifndef __WXGTK20__ if (!m_updateRegion.IsEmpty()) { m_updateRegion.Offset( dx, dy ); - + int cw = 0; int ch = 0; GetClientSize( &cw, &ch ); m_updateRegion.Intersect( 0, 0, cw, ch ); } - + if (!m_clearRegion.IsEmpty()) { m_clearRegion.Offset( dx, dy ); - + int cw = 0; int ch = 0; GetClientSize( &cw, &ch ); m_clearRegion.Intersect( 0, 0, cw, ch ); } - -#if 1 m_clipPaintRegion = TRUE; - + gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); - - m_clipPaintRegion = FALSE; + m_clipPaintRegion = FALSE; #else - 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; + gdk_window_scroll( GTK_PIZZA(m_wxwindow)->bin_window, dx, 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 ); - } + GTK_PIZZA(m_wxwindow)->xoffset += dx; + GTK_PIZZA(m_wxwindow)->yoffset += dy; - gdk_gc_unref( m_scrollGC ); - } #endif + } + // Find the wxWindow at the current mouse position, also returning the mouse // position. wxWindow* wxFindWindowAtPointer(wxPoint& pt) @@ -4160,3 +4144,32 @@ wxPoint wxGetMousePosition() } +// ---------------------------------------------------------------------------- +// wxDCModule +// ---------------------------------------------------------------------------- + +class wxWinModule : public wxModule +{ +public: + bool OnInit(); + void OnExit(); + +private: + DECLARE_DYNAMIC_CLASS(wxWinModule) +}; + +IMPLEMENT_DYNAMIC_CLASS(wxWinModule, wxModule) + +bool wxWinModule::OnInit() +{ + g_eraseGC = gdk_gc_new( GDK_ROOT_PARENT() ); + gdk_gc_set_fill( g_eraseGC, GDK_SOLID ); + + return TRUE; +} + +void wxWinModule::OnExit() +{ + gdk_gc_unref( g_eraseGC ); +} +