summaryrefslogtreecommitdiff
path: root/eel/eel-wrap-table.c
diff options
context:
space:
mode:
Diffstat (limited to 'eel/eel-wrap-table.c')
-rw-r--r--eel/eel-wrap-table.c245
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));
}
/**