diff options
Diffstat (limited to 'eel/eel-wrap-table.c')
-rw-r--r-- | eel/eel-wrap-table.c | 245 |
1 files changed, 119 insertions, 126 deletions
diff --git a/eel/eel-wrap-table.c b/eel/eel-wrap-table.c index f7e8a6ad..42253acd 100644 --- a/eel/eel-wrap-table.c +++ b/eel/eel-wrap-table.c @@ -28,8 +28,6 @@ #include "eel-art-extensions.h" #include "eel-art-gtk-extensions.h" #include "eel-gtk-extensions.h" -#include "eel-gtk-macros.h" -#include "eel-types.h" #include <gtk/gtk.h> /* Arguments */ @@ -57,127 +55,30 @@ struct EelWrapTableDetails guint cols; }; -static void eel_wrap_table_class_init (EelWrapTableClass *wrap_table_class); -static void eel_wrap_table_init (EelWrapTable *wrap); -/* GObjectClass methods */ -static void eel_wrap_table_finalize (GObject *object); -static void eel_wrap_table_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); -static void eel_wrap_table_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); -/* GtkWidgetClass methods */ -static void eel_wrap_table_size_request (GtkWidget *widget, - GtkRequisition *requisition); -static int eel_wrap_table_expose_event (GtkWidget *widget, - GdkEventExpose *event); -static void eel_wrap_table_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static void eel_wrap_table_map (GtkWidget *widget); -static void eel_wrap_table_unmap (GtkWidget *widget); -static void eel_wrap_table_realize (GtkWidget *widget); - -/* GtkContainerClass methods */ -static void eel_wrap_table_add (GtkContainer *container, - GtkWidget *widget); -static void eel_wrap_table_remove (GtkContainer *container, - GtkWidget *widget); -static void eel_wrap_table_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data); -static GType eel_wrap_table_child_type (GtkContainer *container); - - /* Private EelWrapTable methods */ static EelDimensions wrap_table_irect_max_dimensions (const EelDimensions *one, const EelDimensions *two); static EelDimensions wrap_table_get_max_child_dimensions (const EelWrapTable *wrap_table); static EelDimensions wrap_table_get_content_dimensions (const EelWrapTable *wrap_table); static EelIRect wrap_table_get_content_bounds (const EelWrapTable *wrap_table); +static gboolean wrap_table_child_visible_in (GtkWidget *child, + GtkWidget *scrolled); static gboolean wrap_table_child_focus_in (GtkWidget *widget, GdkEventFocus *event, gpointer data); static void wrap_table_layout (EelWrapTable *wrap_table); -EEL_CLASS_BOILERPLATE (EelWrapTable, eel_wrap_table, GTK_TYPE_CONTAINER) - -/* Class init methods */ -static void -eel_wrap_table_class_init (EelWrapTableClass *wrap_table_class) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (wrap_table_class); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (wrap_table_class); - GtkContainerClass *container_class = GTK_CONTAINER_CLASS (wrap_table_class); - - /* GObjectClass */ - gobject_class->finalize = eel_wrap_table_finalize; - gobject_class->set_property = eel_wrap_table_set_property; - gobject_class->get_property = eel_wrap_table_get_property; - - /* GtkWidgetClass */ - widget_class->size_request = eel_wrap_table_size_request; - widget_class->size_allocate = eel_wrap_table_size_allocate; - widget_class->expose_event = eel_wrap_table_expose_event; - widget_class->map = eel_wrap_table_map; - widget_class->unmap = eel_wrap_table_unmap; - widget_class->realize = eel_wrap_table_realize; - - /* GtkContainerClass */ - container_class->add = eel_wrap_table_add; - container_class->remove = eel_wrap_table_remove; - container_class->forall = eel_wrap_table_forall; - container_class->child_type = eel_wrap_table_child_type; - - /* Register some the enum types we need */ - eel_type_init (); - - /* Arguments */ - g_object_class_install_property - (gobject_class, - PROP_X_SPACING, - g_param_spec_uint ("x_spacing", NULL, NULL, - 0, G_MAXINT, 0, G_PARAM_READWRITE)); - - g_object_class_install_property - (gobject_class, - PROP_Y_SPACING, - g_param_spec_uint ("y_spacing", NULL, NULL, - 0, G_MAXINT, 0, G_PARAM_READWRITE)); - - g_object_class_install_property - (gobject_class, - PROP_X_JUSTIFICATION, - g_param_spec_enum ("x_justification", NULL, NULL, - EEL_TYPE_JUSTIFICATION, - EEL_JUSTIFICATION_BEGINNING, - G_PARAM_READWRITE)); - - g_object_class_install_property - (gobject_class, - PROP_Y_JUSTIFICATION, - g_param_spec_enum ("y_justification", NULL, NULL, - EEL_TYPE_JUSTIFICATION, - EEL_JUSTIFICATION_BEGINNING, - G_PARAM_READWRITE)); - - g_object_class_install_property - (gobject_class, - PROP_HOMOGENEOUS, - g_param_spec_boolean ("homogenous", NULL, NULL, - FALSE, G_PARAM_READWRITE)); -} +G_DEFINE_TYPE (EelWrapTable, eel_wrap_table, GTK_TYPE_CONTAINER) static void eel_wrap_table_init (EelWrapTable *wrap_table) { gtk_widget_set_has_window (GTK_WIDGET (wrap_table), FALSE); - wrap_table->details = g_new0 (EelWrapTableDetails, 1); + wrap_table->details = G_TYPE_INSTANCE_GET_PRIVATE (wrap_table, + EEL_TYPE_WRAP_TABLE, + EelWrapTableDetails); wrap_table->details->x_justification = EEL_JUSTIFICATION_BEGINNING; wrap_table->details->y_justification = EEL_JUSTIFICATION_END; wrap_table->details->cols = 1; @@ -191,9 +92,8 @@ eel_wrap_table_finalize (GObject *object) wrap_table = EEL_WRAP_TABLE (object); g_list_free (wrap_table->details->children); - g_free (wrap_table->details); - EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); + G_OBJECT_CLASS (eel_wrap_table_parent_class)->finalize (object); } /* GObjectClass methods */ @@ -391,7 +291,7 @@ eel_wrap_table_realize (GtkWidget *widget) { g_assert (EEL_IS_WRAP_TABLE (widget)); - GTK_WIDGET_CLASS (parent_class)->realize (widget); + GTK_WIDGET_CLASS (eel_wrap_table_parent_class)->realize (widget); gtk_widget_queue_resize (widget); } @@ -497,6 +397,71 @@ eel_wrap_table_child_type (GtkContainer *container) return GTK_TYPE_WIDGET; } +/* Class init methods */ +static void +eel_wrap_table_class_init (EelWrapTableClass *wrap_table_class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (wrap_table_class); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (wrap_table_class); + GtkContainerClass *container_class = GTK_CONTAINER_CLASS (wrap_table_class); + + /* GObjectClass */ + gobject_class->finalize = eel_wrap_table_finalize; + gobject_class->set_property = eel_wrap_table_set_property; + gobject_class->get_property = eel_wrap_table_get_property; + + /* GtkWidgetClass */ + widget_class->size_request = eel_wrap_table_size_request; + widget_class->size_allocate = eel_wrap_table_size_allocate; + widget_class->expose_event = eel_wrap_table_expose_event; + widget_class->map = eel_wrap_table_map; + widget_class->unmap = eel_wrap_table_unmap; + widget_class->realize = eel_wrap_table_realize; + + /* GtkContainerClass */ + container_class->add = eel_wrap_table_add; + container_class->remove = eel_wrap_table_remove; + container_class->forall = eel_wrap_table_forall; + container_class->child_type = eel_wrap_table_child_type; + + /* Arguments */ + g_object_class_install_property + (gobject_class, + PROP_X_SPACING, + g_param_spec_uint ("x_spacing", NULL, NULL, + 0, G_MAXINT, 0, G_PARAM_READWRITE)); + + g_object_class_install_property + (gobject_class, + PROP_Y_SPACING, + g_param_spec_uint ("y_spacing", NULL, NULL, + 0, G_MAXINT, 0, G_PARAM_READWRITE)); + + g_object_class_install_property + (gobject_class, + PROP_X_JUSTIFICATION, + g_param_spec_enum ("x_justification", NULL, NULL, + GTK_TYPE_JUSTIFICATION, + GTK_JUSTIFY_LEFT, + G_PARAM_READWRITE)); + + g_object_class_install_property + (gobject_class, + PROP_Y_JUSTIFICATION, + g_param_spec_enum ("y_justification", NULL, NULL, + GTK_TYPE_JUSTIFICATION, + GTK_JUSTIFY_LEFT, + G_PARAM_READWRITE)); + + g_object_class_install_property + (gobject_class, + PROP_HOMOGENEOUS, + g_param_spec_boolean ("homogenous", NULL, NULL, + FALSE, G_PARAM_READWRITE)); + + g_type_class_add_private (wrap_table_class, sizeof (EelWrapTableDetails)); +} + /* Private EelWrapTable methods */ static int wrap_table_get_num_fitting (int available, @@ -744,23 +709,55 @@ wrap_table_get_content_bounds (const EelWrapTable *wrap_table) return content_bounds; } +/** + * wrap_table_child_visible_in + * + * Get child position relative to parent, then determine whether + * the whole child rectangle is visible in the scrolled window + **/ +static gboolean +wrap_table_child_visible_in (GtkWidget *child, GtkWidget *scrolled) +{ + gint x, y; + GtkAllocation child_alloc, scroll_alloc; + + gtk_widget_translate_coordinates (child, scrolled, 0, 0, &x, &y); + gtk_widget_get_allocation(child, &child_alloc); + gtk_widget_get_allocation(scrolled, &scroll_alloc); + + return (x >= 0 && y >= 0) + && x + child_alloc.width <= scroll_alloc.width + && y + child_alloc.height <= scroll_alloc.height; +} + static gboolean wrap_table_child_focus_in (GtkWidget *widget, GdkEventFocus *event, gpointer data) { - GtkWidget *parent, *pparent; - GtkAllocation allocation; + gint x, y; + GtkWidget *container, *viewport; + GtkAdjustment *hadj, *vadj; + + container = gtk_widget_get_parent (widget); + if (container) + { + viewport = gtk_widget_get_parent (container); + } + g_assert (container && viewport); + g_assert (GTK_IS_VIEWPORT (viewport)); + g_return_val_if_fail (gtk_widget_get_realized (viewport), FALSE); + + if (!wrap_table_child_visible_in (widget, viewport)) + { + hadj = gtk_viewport_get_hadjustment (GTK_VIEWPORT (viewport)); + vadj = gtk_viewport_get_vadjustment (GTK_VIEWPORT (viewport)); - parent = gtk_widget_get_parent (widget); - if (parent) - pparent = gtk_widget_get_parent (parent); - g_assert (parent && pparent); - g_assert (GTK_IS_VIEWPORT (pparent)); + gtk_widget_translate_coordinates (widget, container, 0, 0, &x, &y); - gtk_widget_get_allocation (widget, &allocation); - eel_gtk_viewport_scroll_to_rect (GTK_VIEWPORT (pparent), - &allocation); + gtk_adjustment_set_value (hadj, MIN (x, hadj->upper - hadj->page_size)); + gtk_adjustment_set_value (vadj, MIN (y, vadj->upper - vadj->page_size)); + } return FALSE; } @@ -977,16 +974,12 @@ void eel_wrap_table_set_homogeneous (EelWrapTable *wrap_table, gboolean homogeneous) { - g_return_if_fail (EEL_IS_WRAP_TABLE (wrap_table)); - - if (wrap_table->details->homogeneous == homogeneous) + if (EEL_IS_WRAP_TABLE (wrap_table) && + wrap_table->details->homogeneous != homogeneous) { - return; + wrap_table->details->homogeneous = homogeneous; + gtk_widget_queue_resize (GTK_WIDGET (wrap_table)); } - - wrap_table->details->homogeneous = homogeneous; - - gtk_widget_queue_resize (GTK_WIDGET (wrap_table)); } /** |