X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/68567a967bc8afd37a40cb9a7ee5021b9ee6cd96..2121eb69fa8d49f4484f7170159e61f2e8885de4:/src/gtk/win_gtk.c diff --git a/src/gtk/win_gtk.c b/src/gtk/win_gtk.c index cd3e794936..6115bc3a33 100644 --- a/src/gtk/win_gtk.c +++ b/src/gtk/win_gtk.c @@ -1,5 +1,5 @@ /* /////////////////////////////////////////////////////////////////////////// -// Name: win_gtk.c +// Name: src/gtk/win_gtk.c // Purpose: Native GTK+ widget for wxWidgets, based on GtkLayout and // GtkFixed. It makes use of the gravity window property and // therefore does not work with GTK 1.0. @@ -13,11 +13,8 @@ #define XCheckIfEvent XCHECKIFEVENT #endif -#include "wx/setup.h" +#include "wx/platform.h" #include "wx/gtk/win_gtk.h" -#include "gtk/gtksignal.h" -#include "gtk/gtkprivate.h" -#include "gdk/gdkx.h" #ifdef __cplusplus extern "C" { @@ -67,8 +64,7 @@ static void gtk_pizza_scroll_set_adjustments (GtkPizza *pizza, GtkAdjustment *hadj, GtkAdjustment *vadj); -/* static */ -GtkContainerClass *pizza_parent_class = NULL; +static GtkWidgetClass* pizza_parent_class; GtkType gtk_pizza_get_type () @@ -192,22 +188,12 @@ gtk_pizza_init (GtkPizza *pizza) pizza->children = NULL; - pizza->width = 20; - pizza->height = 20; - pizza->bin_window = NULL; - pizza->xoffset = 0; - pizza->yoffset = 0; - - pizza->configure_serial = 0; - pizza->scroll_x = 0; - pizza->scroll_y = 0; - pizza->visibility = GDK_VISIBILITY_PARTIAL; - - pizza->clear_on_draw = TRUE; - pizza->use_filter = TRUE; - pizza->external_expose = FALSE; + pizza->m_xoffset = 0; + pizza->m_yoffset = 0; + + pizza->m_width = -1; } GtkWidget* @@ -215,66 +201,85 @@ gtk_pizza_new () { GtkPizza *pizza; - pizza = gtk_type_new (gtk_pizza_get_type ()); + pizza = g_object_new (gtk_pizza_get_type (), NULL); return GTK_WIDGET (pizza); } -static void -gtk_pizza_scroll_set_adjustments (GtkPizza *pizza, - GtkAdjustment *hadj, - GtkAdjustment *vadj) +gint gtk_pizza_get_xoffset (GtkPizza *pizza) { - /* We handle scrolling in the wxScrolledWindow, not here. */ + g_return_val_if_fail ( (pizza != NULL), -1 ); + g_return_val_if_fail ( (GTK_IS_PIZZA (pizza)), -1 ); + + return pizza->m_xoffset; } -void -gtk_pizza_set_shadow_type (GtkPizza *pizza, - GtkMyShadowType type) +gint gtk_pizza_get_yoffset (GtkPizza *pizza) { - g_return_if_fail (pizza != NULL); - g_return_if_fail (GTK_IS_PIZZA (pizza)); - - if ((GtkMyShadowType) pizza->shadow_type != type) - { - pizza->shadow_type = type; + g_return_val_if_fail ( (pizza != NULL), -1 ); + g_return_val_if_fail ( (GTK_IS_PIZZA (pizza)), -1 ); - if (GTK_WIDGET_VISIBLE (pizza)) - { - gtk_widget_size_allocate (GTK_WIDGET (pizza), &(GTK_WIDGET (pizza)->allocation)); - gtk_widget_queue_draw (GTK_WIDGET (pizza)); - } - } + return pizza->m_yoffset; } -void -gtk_pizza_set_clear (GtkPizza *pizza, - gboolean clear) +void gtk_pizza_set_xoffset (GtkPizza *pizza, gint xoffset) { g_return_if_fail (pizza != NULL); g_return_if_fail (GTK_IS_PIZZA (pizza)); - pizza->clear_on_draw = clear; + pizza->m_xoffset = xoffset; + // do something } -void -gtk_pizza_set_filter (GtkPizza *pizza, - gboolean use) +void gtk_pizza_set_yoffset (GtkPizza *pizza, gint yoffset) { g_return_if_fail (pizza != NULL); g_return_if_fail (GTK_IS_PIZZA (pizza)); - pizza->use_filter = use; + pizza->m_xoffset = yoffset; + // do something +} + +gint gtk_pizza_get_rtl_offset (GtkPizza *pizza) +{ + gint width; + + g_return_val_if_fail ( (pizza != NULL), 0 ); + g_return_val_if_fail ( (GTK_IS_PIZZA (pizza)), 0 ); + + if (!pizza->bin_window) return 0; + + gdk_window_get_geometry( pizza->bin_window, NULL, NULL, &width, NULL, NULL ); + + return width; +} + + +static void +gtk_pizza_scroll_set_adjustments (GtkPizza *pizza, + GtkAdjustment *hadj, + GtkAdjustment *vadj) +{ + /* We handle scrolling in the wxScrolledWindow, not here. */ } void -gtk_pizza_set_external (GtkPizza *pizza, - gboolean expose) +gtk_pizza_set_shadow_type (GtkPizza *pizza, + GtkMyShadowType type) { g_return_if_fail (pizza != NULL); g_return_if_fail (GTK_IS_PIZZA (pizza)); - pizza->external_expose = expose; + if (pizza->shadow_type != type) + { + pizza->shadow_type = type; + + if (GTK_WIDGET_VISIBLE (pizza)) + { + gtk_widget_size_allocate (GTK_WIDGET (pizza), &(GTK_WIDGET (pizza)->allocation)); + gtk_widget_queue_draw (GTK_WIDGET (pizza)); + } + } } void @@ -291,6 +296,12 @@ gtk_pizza_put (GtkPizza *pizza, g_return_if_fail (GTK_IS_PIZZA (pizza)); g_return_if_fail (widget != NULL); + if (gtk_widget_get_direction( GTK_WIDGET(pizza) ) == GTK_TEXT_DIR_RTL) + { + // reverse horizontal placement + x = pizza->m_width - x - width; + } + child_info = g_new (GtkPizzaChild, 1); child_info->widget = widget; @@ -299,6 +310,9 @@ gtk_pizza_put (GtkPizza *pizza, child_info->width = width; child_info->height = height; + if (GTK_IS_PIZZA(widget)) + GTK_PIZZA(widget)->m_width = width; + pizza->children = g_list_append (pizza->children, child_info); if (GTK_WIDGET_REALIZED (pizza)) @@ -306,77 +320,7 @@ gtk_pizza_put (GtkPizza *pizza, gtk_widget_set_parent (widget, GTK_WIDGET (pizza)); - gtk_widget_set_usize (widget, width, height); -} - -void -gtk_pizza_move (GtkPizza *pizza, - GtkWidget *widget, - gint x, - gint y) -{ - GtkPizzaChild *child; - GList *children; - - g_return_if_fail (pizza != NULL); - g_return_if_fail (GTK_IS_PIZZA (pizza)); - g_return_if_fail (widget != NULL); - - children = pizza->children; - while (children) - { - child = children->data; - children = children->next; - - if (child->widget == widget) - { - if ((child->x == x) && (child->y == y)) - break; - - child->x = x; - child->y = y; - - if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (pizza)) - gtk_widget_queue_resize (widget); - break; - } - } -} - -void -gtk_pizza_resize (GtkPizza *pizza, - GtkWidget *widget, - gint width, - gint height) -{ - GtkPizzaChild *child; - GList *children; - - g_return_if_fail (pizza != NULL); - g_return_if_fail (GTK_IS_PIZZA (pizza)); - g_return_if_fail (widget != NULL); - - children = pizza->children; - while (children) - { - child = children->data; - children = children->next; - - if (child->widget == widget) - { - if ((child->width == width) && (child->height == height)) - break; - - child->width = width; - child->height = height; - - gtk_widget_set_usize (widget, width, height); - - if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (pizza)) - gtk_widget_queue_resize (widget); - break; - } - } + gtk_widget_set_size_request (widget, width, height); } void @@ -394,6 +338,16 @@ gtk_pizza_set_size (GtkPizza *pizza, g_return_if_fail (GTK_IS_PIZZA (pizza)); g_return_if_fail (widget != NULL); +#ifndef WX_WARN_ILLEGAL_SETSIZE + /* this really shouldn't happen -- but it does, a lot, right now and we + can't pass negative values to gtk_widget_set_size_request() without getting + a warning printed out, so filter them out here */ + if ( width < 0 ) + width = 0; + if ( height < 0 ) + height = 0; +#endif + children = pizza->children; while (children) { @@ -402,53 +356,33 @@ gtk_pizza_set_size (GtkPizza *pizza, if (child->widget == widget) { - if ((child->x == x) && + gint new_x = x; + if (gtk_widget_get_direction( GTK_WIDGET(pizza) ) == GTK_TEXT_DIR_RTL) + { + // reverse horizontal placement + new_x = pizza->m_width - new_x - width; + } + + if ((child->x == new_x) && (child->y == y) && (child->width == width) && (child->height == height)) return; - child->x = x; + child->x = new_x; child->y = y; child->width = width; child->height = height; + + if (GTK_IS_PIZZA(widget)) + GTK_PIZZA(widget)->m_width = width; - gtk_widget_set_usize (widget, width, height); - - if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (pizza)) - gtk_widget_queue_resize (widget); + gtk_widget_set_size_request (widget, width, height); return; } } } -gint -gtk_pizza_child_resized (GtkPizza *pizza, - GtkWidget *widget) -{ - GtkPizzaChild *child; - GList *children; - - g_return_val_if_fail (pizza != NULL, FALSE); - g_return_val_if_fail (GTK_IS_PIZZA (pizza), FALSE); - g_return_val_if_fail (widget != NULL, FALSE); - - children = pizza->children; - while (children) - { - child = children->data; - children = children->next; - - if (child->widget == widget) - { - return ((child->width == widget->allocation.width) && - (child->height == widget->allocation.height)); - } - } - - return FALSE; -} - static void gtk_pizza_map (GtkWidget *widget) { @@ -469,8 +403,7 @@ gtk_pizza_map (GtkWidget *widget) children = children->next; if ( GTK_WIDGET_VISIBLE (child->widget) && - !GTK_WIDGET_MAPPED (child->widget) && - TRUE) + !GTK_WIDGET_MAPPED (child->widget) ) { gtk_widget_map (child->widget); } @@ -598,8 +531,8 @@ gtk_pizza_unrealize (GtkWidget *widget) gdk_window_destroy (pizza->bin_window); pizza->bin_window = NULL; - if (GTK_WIDGET_CLASS (pizza_parent_class)->unrealize) - (* GTK_WIDGET_CLASS (pizza_parent_class)->unrealize) (widget); + if (pizza_parent_class->unrealize) + pizza_parent_class->unrealize(widget); } static void @@ -665,6 +598,10 @@ gtk_pizza_size_allocate (GtkWidget *widget, y = allocation->y + border; w = allocation->width - border*2; h = allocation->height - border*2; + if (w < 0) + w = 0; + if (h < 0) + h = 0; if (GTK_WIDGET_REALIZED (widget)) { @@ -692,16 +629,12 @@ gtk_pizza_expose (GtkWidget *widget, g_return_val_if_fail (GTK_IS_PIZZA (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); - pizza = GTK_PIZZA (widget); + pizza = (GtkPizza*)widget; if (event->window != pizza->bin_window) return FALSE; - /* We handle all expose events in window.cpp now. */ - if (pizza->external_expose) - return FALSE; - - (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, event); + pizza_parent_class->expose_event(widget, event); return FALSE; } @@ -715,7 +648,7 @@ gtk_pizza_style_set(GtkWidget *widget, GtkStyle *previous_style) gtk_style_set_background(widget->style, GTK_PIZZA(widget)->bin_window, GTK_STATE_NORMAL ); } - (* GTK_WIDGET_CLASS (pizza_parent_class)->style_set) (widget, previous_style); + pizza_parent_class->style_set(widget, previous_style); } static void @@ -802,8 +735,8 @@ gtk_pizza_allocate_child (GtkPizza *pizza, GtkAllocation allocation; GtkRequisition requisition; - allocation.x = child->x - pizza->xoffset; - allocation.y = child->y - pizza->yoffset; + allocation.x = child->x - pizza->m_xoffset; + allocation.y = child->y - pizza->m_yoffset; gtk_widget_get_child_requisition (child->widget, &requisition); allocation.width = requisition.width; allocation.height = requisition.height; @@ -858,24 +791,11 @@ gtk_pizza_adjust_allocations (GtkPizza *pizza, } } - -/* This is the main routine to do the scrolling. Scrolling is - * done by "Guffaw" scrolling, as in the Mozilla XFE, with - * a few modifications. - * - * The main improvement is that we keep track of whether we - * are obscured or not. If not, we ignore the generated expose - * events and instead do the exposes ourself, without having - * to wait for a roundtrip to the server. This also provides - * a limited form of expose-event compression, since we do - * the affected area as one big chunk. - */ - void gtk_pizza_scroll (GtkPizza *pizza, gint dx, gint dy) { - pizza->xoffset += dx; - pizza->yoffset += dy; + pizza->m_xoffset += dx; + pizza->m_yoffset += dy; gtk_pizza_adjust_allocations (pizza, -dx, -dy); @@ -886,4 +806,3 @@ gtk_pizza_scroll (GtkPizza *pizza, gint dx, gint dy) #ifdef __cplusplus } #endif /* __cplusplus */ -