[egg-list-box/flow-box-enhancements: 1/3] Introduce EggFlowBoxChild
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [egg-list-box/flow-box-enhancements: 1/3] Introduce EggFlowBoxChild
- Date: Sun, 22 Sep 2013 17:31:35 +0000 (UTC)
commit aa130a1b9763c1b261b860284d09255a716aa745
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Sep 21 18:32:55 2013 -0400
Introduce EggFlowBoxChild
This is EggFlowBoxChildInfo turned into a widget.
We are following the same approach taken by GtkListBox here,
in having a public child type.
egg-flow-box-accessible.c | 20 +-
egg-flow-box-accessible.h | 3 +-
egg-flow-box.c | 1116 +++++++++++++++++++++++++++++----------------
egg-flow-box.h | 74 +++-
test-flow-box.c | 9 +-
5 files changed, 808 insertions(+), 414 deletions(-)
---
diff --git a/egg-flow-box-accessible.c b/egg-flow-box-accessible.c
index 7b244c3..e799db0 100644
--- a/egg-flow-box-accessible.c
+++ b/egg-flow-box-accessible.c
@@ -78,7 +78,7 @@ egg_flow_box_accessible_add_selection (AtkSelection *selection,
g_list_free (children);
if (child)
{
- egg_flow_box_select_child (EGG_FLOW_BOX (box), child);
+ egg_flow_box_select_child (EGG_FLOW_BOX (box), EGG_FLOW_BOX_CHILD (child));
return TRUE;
}
return FALSE;
@@ -101,7 +101,7 @@ egg_flow_box_accessible_remove_selection (AtkSelection *selection,
g_list_free (children);
if (child)
{
- egg_flow_box_unselect_child (EGG_FLOW_BOX (box), child);
+ egg_flow_box_unselect_child (EGG_FLOW_BOX (box), EGG_FLOW_BOX_CHILD (child));
return TRUE;
}
return FALSE;
@@ -140,16 +140,16 @@ typedef struct
} FindSelectedData;
static void
-find_selected_child (EggFlowBox *box,
- GtkWidget *child,
- gpointer data)
+find_selected_child (EggFlowBox *box,
+ EggFlowBoxChild *child,
+ gpointer data)
{
FindSelectedData *d = data;
if (d->idx == 0)
{
if (d->child == NULL)
- d->child = child;
+ d->child = GTK_WIDGET (child);
}
else
d->idx -= 1;
@@ -181,9 +181,9 @@ egg_flow_box_accessible_ref_selection (AtkSelection *selection,
}
static void
-count_selected (EggFlowBox *box,
- GtkWidget *child,
- gpointer data)
+count_selected (EggFlowBox *box,
+ EggFlowBoxChild *child,
+ gpointer data)
{
gint *count = data;
*count += 1;
@@ -212,7 +212,7 @@ egg_flow_box_accessible_is_child_selected (AtkSelection *selection,
GtkWidget *box;
GtkWidget *widget;
GList *children;
- GtkWidget *child;
+ EggFlowBoxChild *child;
box = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
if (box == NULL)
diff --git a/egg-flow-box-accessible.h b/egg-flow-box-accessible.h
index 779aee4..fac44f5 100644
--- a/egg-flow-box-accessible.h
+++ b/egg-flow-box-accessible.h
@@ -48,7 +48,8 @@ struct _EggFlowBoxAccessibleClass
GType egg_flow_box_accessible_get_type (void);
void _egg_flow_box_accessible_selection_changed (GtkWidget *box);
-void _egg_flow_box_accessible_update_cursor (GtkWidget *box, GtkWidget *child);
+void _egg_flow_box_accessible_update_cursor (GtkWidget *box,
+ GtkWidget *child);
G_END_DECLS
diff --git a/egg-flow-box.c b/egg-flow-box.c
index d8ef538..fa295e8 100644
--- a/egg-flow-box.c
+++ b/egg-flow-box.c
@@ -77,6 +77,7 @@ _egg_marshal_VOID__ENUM_INT (GClosure * closure,
callback (data1, g_value_get_enum (param_values + 1), g_value_get_int (param_values + 2), data2);
}
+#define I_(msgid) (msgid)
#define P_(msgid) (msgid)
#define DEFAULT_MAX_CHILDREN_PER_LINE 7
@@ -93,6 +94,11 @@ enum {
};
enum {
+ CHILD_ACTIVATE,
+ CHILD_LAST_SIGNAL
+};
+
+enum {
PROP_0,
PROP_ORIENTATION,
PROP_HOMOGENEOUS,
@@ -106,46 +112,49 @@ enum {
PROP_ACTIVATE_ON_SINGLE_CLICK
};
-typedef struct _EggFlowBoxChildInfo EggFlowBoxChildInfo;
-
struct _EggFlowBoxPrivate {
- GtkOrientation orientation;
- GtkAlign halign_policy;
- GtkAlign valign_policy;
- guint homogeneous : 1;
- guint activate_on_single_click : 1;
- GtkSelectionMode selection_mode;
- GtkAdjustment *adjustment;
-
- guint row_spacing;
- guint column_spacing;
-
- gboolean active_child_active;
- EggFlowBoxChildInfo *active_child;
- EggFlowBoxChildInfo *prelight_child;
- EggFlowBoxChildInfo *cursor_child;
- EggFlowBoxChildInfo *selected_child;
-
- guint16 min_children_per_line;
- guint16 max_children_per_line;
- guint16 cur_children_per_line;
-
- GSequence *children;
- GHashTable *child_hash;
+ GtkOrientation orientation;
+ GtkAlign halign_policy;
+ GtkAlign valign_policy;
+ gboolean homogeneous;
+
+ guint row_spacing;
+ guint column_spacing;
+
+ EggFlowBoxChild *prelight_child;
+ EggFlowBoxChild *cursor_child;
+ EggFlowBoxChild *selected_child;
+
+ gboolean active_child_active;
+ EggFlowBoxChild *active_child;
+
+ GtkSelectionMode selection_mode;
+
+ GtkAdjustment *adjustment;
+ gboolean activate_on_single_click;
+
+ guint16 min_children_per_line;
+ guint16 max_children_per_line;
+ guint16 cur_children_per_line;
+
+ GSequence *children;
};
-struct _EggFlowBoxChildInfo
+typedef struct _EggFlowBoxChildPrivate EggFlowBoxChildPrivate;
+struct _EggFlowBoxChildPrivate
{
GSequenceIter *iter;
- GtkWidget *widget;
- guint selected : 1;
- GdkRectangle area;
+ GtkWidget *widget;
+ guint selected : 1;
+ GdkRectangle area;
};
static guint signals[LAST_SIGNAL] = { 0 };
+static guint child_signals[CHILD_LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE_WITH_CODE (EggFlowBox, egg_flow_box, GTK_TYPE_CONTAINER,
G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL))
+G_DEFINE_TYPE_WITH_PRIVATE (EggFlowBoxChild, egg_flow_box_child, GTK_TYPE_BIN)
#define ORIENTATION_ALIGN_POLICY(box) \
@@ -158,29 +167,345 @@ G_DEFINE_TYPE_WITH_CODE (EggFlowBox, egg_flow_box, GTK_TYPE_CONTAINER,
((EggFlowBox *)(box))->priv->valign_policy : \
((EggFlowBox *)(box))->priv->halign_policy)
-static EggFlowBoxChildInfo*
-egg_flow_box_child_info_new (GtkWidget *widget)
+static void egg_flow_box_update_cursor (EggFlowBox *box,
+ EggFlowBoxChild *child);
+static void egg_flow_box_select_and_activate (EggFlowBox *box,
+ EggFlowBoxChild *child);
+static void egg_flow_box_update_selection (EggFlowBox *box,
+ EggFlowBoxChild *child,
+ gboolean modify,
+ gboolean extend);
+
+GtkWidget *
+egg_flow_box_child_new (void)
+{
+ return g_object_new (EGG_TYPE_FLOW_BOX_CHILD, NULL);
+}
+
+static void
+egg_flow_box_child_init (EggFlowBoxChild *child)
+{
+ GtkStyleContext *context;
+
+ gtk_widget_set_can_focus (GTK_WIDGET (child), TRUE);
+ gtk_widget_set_redraw_on_allocate (GTK_WIDGET (child), TRUE);
+
+ context = gtk_widget_get_style_context (GTK_WIDGET (child));
+ gtk_style_context_add_class (context, "grid-child");
+}
+
+static EggFlowBox *
+egg_flow_box_child_get_box (EggFlowBoxChild *child)
{
- EggFlowBoxChildInfo *info;
+ GtkWidget *parent;
+
+ parent = gtk_widget_get_parent (GTK_WIDGET (child));
+ if (parent && EGG_IS_FLOW_BOX (parent))
+ return EGG_FLOW_BOX (parent);
- info = g_new0 (EggFlowBoxChildInfo, 1);
- info->widget = g_object_ref (widget);
- return info;
+ return NULL;
}
static void
-egg_flow_box_child_info_free (EggFlowBoxChildInfo *info)
+egg_flow_box_child_set_focus (EggFlowBoxChild *child)
{
- g_clear_object (&info->widget);
- g_free (info);
+ EggFlowBox *box = egg_flow_box_child_get_box (child);
+ GdkModifierType state = 0;
+ gboolean modify_selection_pressed;
+
+ modify_selection_pressed = FALSE;
+ if (gtk_get_current_event_state (&state))
+ {
+ GdkModifierType modify_mod_mask;
+ modify_mod_mask =
+ gtk_widget_get_modifier_mask (GTK_WIDGET (box),
+ GDK_MODIFIER_INTENT_MODIFY_SELECTION);
+ if ((state & modify_mod_mask) == modify_mod_mask)
+ modify_selection_pressed = TRUE;
+ }
+
+ if (modify_selection_pressed)
+ egg_flow_box_update_cursor (box, child);
+ else
+ egg_flow_box_update_selection (box, child, FALSE, FALSE);
}
-static EggFlowBoxChildInfo*
-egg_flow_box_lookup_info (EggFlowBox *flow_box, GtkWidget* child)
+static gboolean
+egg_flow_box_child_focus (GtkWidget *widget,
+ GtkDirectionType direction)
{
- EggFlowBoxPrivate *priv = flow_box->priv;
+ gboolean had_focus = FALSE;
+ GtkWidget *child;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+
+ g_object_get (widget, "has-focus", &had_focus, NULL);
+ if (had_focus)
+ {
+ /* If on row, going right, enter into possible container */
+ if (child &&
+ (direction == GTK_DIR_RIGHT || direction == GTK_DIR_TAB_FORWARD))
+ {
+ if (gtk_widget_child_focus (GTK_WIDGET (child), direction))
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+ else if (gtk_container_get_focus_child (GTK_CONTAINER (widget)) != NULL)
+ {
+ /* Child has focus, always navigate inside it first */
+
+ if (gtk_widget_child_focus (child, direction))
+ return TRUE;
+ /* If exiting child container to the left, select child */
+ if (direction == GTK_DIR_LEFT || direction == GTK_DIR_TAB_BACKWARD)
+ {
+ egg_flow_box_child_set_focus (EGG_FLOW_BOX_CHILD (widget));
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+ else
+ {
+ /* If coming from the left, enter into possible container */
+ if (child &&
+ (direction == GTK_DIR_LEFT || direction == GTK_DIR_TAB_BACKWARD))
+ {
+ if (gtk_widget_child_focus (child, direction))
+ return TRUE;
+ }
+
+ egg_flow_box_child_set_focus (EGG_FLOW_BOX_CHILD (widget));
+ return TRUE;
+ }
+}
+
+static void
+egg_flow_box_child_activate (EggFlowBoxChild *child)
+{
+ EggFlowBox *box;
+
+ box = egg_flow_box_child_get_box (child);
+ if (box)
+ egg_flow_box_select_and_activate (box, child);
+}
+
+static void
+egg_flow_box_child_visibility_changed (EggFlowBox *box,
+ EggFlowBoxChild *child)
+{
+}
+
+static void
+egg_flow_box_child_show (GtkWidget *widget)
+{
+ EggFlowBoxChild *child = EGG_FLOW_BOX_CHILD (widget);
+ EggFlowBox *box;
+
+ GTK_WIDGET_CLASS (egg_flow_box_child_parent_class)->show (widget);
+
+ box = egg_flow_box_child_get_box (child);
+ if (box)
+ egg_flow_box_child_visibility_changed (box, child);
+}
+
+static void
+egg_flow_box_child_hide (GtkWidget *widget)
+{
+ EggFlowBoxChild *child = EGG_FLOW_BOX_CHILD (widget);
+ EggFlowBox *box;
+
+ GTK_WIDGET_CLASS (egg_flow_box_child_parent_class)->hide (widget);
+
+ box = egg_flow_box_child_get_box (child);
+ if (box)
+ egg_flow_box_child_visibility_changed (box, child);
+}
+
+static gboolean
+egg_flow_box_child_draw (GtkWidget *widget,
+ cairo_t *cr)
+{
+ GtkAllocation allocation = {0};
+ GtkStyleContext* context;
+ GtkStateFlags state;
+ GtkBorder border;
+ gint focus_pad;
+
+ gtk_widget_get_allocation (widget, &allocation);
+ context = gtk_widget_get_style_context (widget);
+ state = gtk_widget_get_state_flags (widget);
+
+ gtk_render_background (context, cr, 0, 0, allocation.width, allocation.height);
+ gtk_render_frame (context, cr, 0, 0, allocation.width, allocation.height);
+
+ if (gtk_widget_has_visible_focus (widget))
+ {
+ gtk_style_context_get_border (context, state, &border);
+
+ gtk_style_context_get_style (context,
+ "focus-padding", &focus_pad,
+ NULL);
+ gtk_render_focus (context, cr, border.left + focus_pad, border.top + focus_pad,
+ allocation.width - 2 * focus_pad - border.left - border.right,
+ allocation.height - 2 * focus_pad - border.top - border.bottom);
+ }
+
+ GTK_WIDGET_CLASS (egg_flow_box_child_parent_class)->draw (widget, cr);
+
+ return TRUE;
+}
+
+static void
+egg_flow_box_child_get_full_border (EggFlowBoxChild *child,
+ GtkBorder *full_border)
+{
+ GtkWidget *widget = GTK_WIDGET (child);
+ GtkStyleContext *context;
+ GtkStateFlags state;
+ GtkBorder padding, border;
+ int focus_width, focus_pad;
+
+ context = gtk_widget_get_style_context (widget);
+ state = gtk_style_context_get_state (context);
+
+ gtk_style_context_get_padding (context, state, &padding);
+ gtk_style_context_get_border (context, state, &border);
+ gtk_style_context_get_style (context,
+ "focus-line-width", &focus_width,
+ "focus-padding", &focus_pad,
+ NULL);
+
+ full_border->left = padding.left + border.left + focus_width + focus_pad;
+ full_border->right = padding.right + border.right + focus_width + focus_pad;
+ full_border->top = padding.top + border.top + focus_width + focus_pad;
+ full_border->bottom = padding.bottom + border.bottom + focus_width + focus_pad;
+}
+
+static void
+egg_flow_box_child_get_preferred_height_for_width (GtkWidget *widget,
+ gint width,
+ gint *minimum_height_out,
+ gint *natural_height_out)
+{
+ GtkWidget *child;
+ gint child_min = 0, child_natural = 0;
+ GtkBorder full_border = { 0, };
+
+ egg_flow_box_child_get_full_border (EGG_FLOW_BOX_CHILD (widget), &full_border);
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (child && gtk_widget_get_visible (child))
+ gtk_widget_get_preferred_height_for_width (child, width - full_border.left - full_border.right,
+ &child_min, &child_natural);
+
+ if (minimum_height_out)
+ *minimum_height_out = full_border.top + child_min + full_border.bottom;
+ if (natural_height_out)
+ *natural_height_out = full_border.top + child_natural + full_border.bottom;
+}
+
+static void
+egg_flow_box_child_get_preferred_width (GtkWidget *widget,
+ gint *minimum_width_out,
+ gint *natural_width_out)
+{
+ GtkWidget *child;
+ gint child_min = 0, child_natural = 0;
+ GtkBorder full_border = { 0, };
+
+ egg_flow_box_child_get_full_border (EGG_FLOW_BOX_CHILD (widget), &full_border);
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (child && gtk_widget_get_visible (child))
+ gtk_widget_get_preferred_width (child,
+ &child_min, &child_natural);
- return g_hash_table_lookup (priv->child_hash, child);
+ if (minimum_width_out)
+ *minimum_width_out = full_border.left + child_min + full_border.right;
+ if (natural_width_out)
+ *natural_width_out = full_border.left + child_natural + full_border.bottom;
+}
+
+static void
+egg_flow_box_child_get_preferred_width_for_height (GtkWidget *widget,
+ gint height,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ egg_flow_box_child_get_preferred_width (widget, minimum_width, natural_width);
+}
+
+static void
+egg_flow_box_child_get_preferred_height (GtkWidget *widget,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ gint natural_width;
+ egg_flow_box_child_get_preferred_width (widget, NULL, &natural_width);
+ egg_flow_box_child_get_preferred_height_for_width (widget, natural_width,
+ minimum_height, natural_height);
+}
+
+static void
+egg_flow_box_child_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GtkWidget *child;
+
+ gtk_widget_set_allocation (widget, allocation);
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (child && gtk_widget_get_visible (child))
+ {
+ GtkAllocation child_allocation;
+ GtkBorder border = { 0, };
+
+ egg_flow_box_child_get_full_border (EGG_FLOW_BOX_CHILD (widget), &border);
+
+ child_allocation.x = allocation->x + border.left;
+ child_allocation.y = allocation->y + border.top;
+ child_allocation.width = allocation->width - border.left - border.right;
+ child_allocation.height = allocation->height - border.top - border.bottom;
+
+ child_allocation.width = MAX (1, child_allocation.width);
+ child_allocation.height = MAX (1, child_allocation.height);
+
+ gtk_widget_size_allocate (child, &child_allocation);
+ }
+}
+
+static void
+egg_flow_box_child_class_init (EggFlowBoxChildClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+ widget_class->show = egg_flow_box_child_show;
+ widget_class->hide = egg_flow_box_child_hide;
+ widget_class->draw = egg_flow_box_child_draw;
+ widget_class->get_preferred_height = egg_flow_box_child_get_preferred_height;
+ widget_class->get_preferred_height_for_width = egg_flow_box_child_get_preferred_height_for_width;
+ widget_class->get_preferred_width = egg_flow_box_child_get_preferred_width;
+ widget_class->get_preferred_width_for_height = egg_flow_box_child_get_preferred_width_for_height;
+ widget_class->size_allocate = egg_flow_box_child_size_allocate;
+ widget_class->focus = egg_flow_box_child_focus;
+
+ class->activate = egg_flow_box_child_activate;
+
+ child_signals[CHILD_ACTIVATE] =
+ g_signal_new (I_("activate"),
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EggFlowBoxChildClass, activate),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ widget_class->activate_signal = child_signals[CHILD_ACTIVATE];
+
+ gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_LIST_ITEM);
}
void
@@ -244,11 +569,13 @@ egg_flow_box_set_homogeneous (EggFlowBox *box,
}
/* Children are visible if they are shown by the app (visible)
- and not filtered out (child_visible) by the box */
+ * and not filtered out (child_visible) by the box
+ */
static gboolean
child_is_visible (GtkWidget *child)
{
- return gtk_widget_get_visible (child) && gtk_widget_get_child_visible (child);
+ return gtk_widget_get_visible (child) &&
+ gtk_widget_get_child_visible (child);
}
static gint
@@ -262,12 +589,9 @@ get_visible_children (EggFlowBox *box)
!g_sequence_iter_is_end (iter);
iter = g_sequence_iter_next (iter))
{
- EggFlowBoxChildInfo *child_info;
GtkWidget *child;
- child_info = g_sequence_get (iter);
- child = child_info->widget;
-
+ child = g_sequence_get (iter);
if (!child_is_visible (child))
continue;
@@ -281,10 +605,10 @@ get_visible_children (EggFlowBox *box)
* equal widths or heights
*/
static void
-get_average_item_size (EggFlowBox *box,
- GtkOrientation orientation,
- gint *min_size,
- gint *nat_size)
+get_average_item_size (EggFlowBox *box,
+ GtkOrientation orientation,
+ gint *min_size,
+ gint *nat_size)
{
EggFlowBoxPrivate *priv = box->priv;
GSequenceIter *iter;
@@ -295,12 +619,10 @@ get_average_item_size (EggFlowBox *box,
!g_sequence_iter_is_end (iter);
iter = g_sequence_iter_next (iter))
{
- EggFlowBoxChildInfo *child_info;
GtkWidget *child;
gint child_min, child_nat;
- child_info = g_sequence_get (iter);
- child = child_info->widget;
+ child = g_sequence_get (iter);
if (!child_is_visible (child))
continue;
@@ -325,11 +647,11 @@ get_average_item_size (EggFlowBox *box,
/* Gets the largest minimum/natural size for a given size
* (used to get the largest item heights for a fixed item width and the opposite) */
static void
-get_largest_size_for_opposing_orientation (EggFlowBox *box,
- GtkOrientation orientation,
- gint item_size,
- gint *min_item_size,
- gint *nat_item_size)
+get_largest_size_for_opposing_orientation (EggFlowBox *box,
+ GtkOrientation orientation,
+ gint item_size,
+ gint *min_item_size,
+ gint *nat_item_size)
{
EggFlowBoxPrivate *priv = box->priv;
GSequenceIter *iter;
@@ -340,12 +662,10 @@ get_largest_size_for_opposing_orientation (EggFlowBox *box,
!g_sequence_iter_is_end (iter);
iter = g_sequence_iter_next (iter))
{
- EggFlowBoxChildInfo *child_info;
GtkWidget *child;
gint child_min, child_nat;
- child_info = g_sequence_get (iter);
- child = child_info->widget;
+ child = g_sequence_get (iter);
if (!child_is_visible (child))
continue;
@@ -395,13 +715,11 @@ get_largest_size_for_line_in_opposing_orientation (EggFlowBox *box,
iter = g_sequence_iter_next (iter))
{
GtkWidget *child;
- EggFlowBoxChildInfo *child_info;
gint child_min, child_nat, this_item_size;
- child_info = g_sequence_get (iter);
- child = child_info->widget;
+ child = g_sequence_get (iter);
- if (!child_is_visible (child))
+ if (!gtk_widget_is_visible (child))
continue;
/* Distribute the extra pixels to the first children in the line
@@ -459,14 +777,12 @@ gather_aligned_item_requests (EggFlowBox *box,
!g_sequence_iter_is_end (iter);
iter = g_sequence_iter_next (iter), i++)
{
- EggFlowBoxChildInfo *child_info;
GtkWidget *child;
GtkAlign item_align;
gint child_min, child_nat;
gint position;
- child_info = g_sequence_get (iter);
- child = child_info->widget;
+ child = g_sequence_get (iter);
if (!child_is_visible (child))
continue;
@@ -582,8 +898,8 @@ get_offset_pixels (GtkAlign align,
}
static void
-egg_flow_box_real_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
+egg_flow_box_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
{
EggFlowBox *box = EGG_FLOW_BOX (widget);
EggFlowBoxPrivate *priv = box->priv;
@@ -603,7 +919,6 @@ egg_flow_box_real_size_allocate (GtkWidget *widget,
gint extra_line_pixels = 0, extra_per_line = 0, extra_line_extra = 0;
gint i, this_line_size;
GSequenceIter *iter;
- GtkStyleContext *context;
gint focus_width;
gint focus_pad;
@@ -619,14 +934,9 @@ egg_flow_box_real_size_allocate (GtkWidget *widget,
allocation->x, allocation->y,
allocation->width, allocation->height);
- context = gtk_widget_get_style_context (GTK_WIDGET (box));
- gtk_style_context_get_style (context,
- "focus-line-width", &focus_width,
- "focus-padding", &focus_pad,
- NULL);
- child_allocation.x = 0 + focus_width + focus_pad;
+ child_allocation.x = 0;
child_allocation.y = 0;
- child_allocation.width = allocation->width - 2 * (focus_width + focus_pad);
+ child_allocation.width = allocation->width;
min_items = MAX (1, priv->min_children_per_line);
@@ -837,20 +1147,20 @@ egg_flow_box_real_size_allocate (GtkWidget *widget,
!g_sequence_iter_is_end (iter);
iter = g_sequence_iter_next (iter))
{
- EggFlowBoxChildInfo *child_info;
GtkWidget *child;
+ EggFlowBoxChildPrivate *child_priv;
gint position;
gint this_item_size;
- child_info = g_sequence_get (iter);
- child = child_info->widget;
+ child = g_sequence_get (iter);
+ child_priv = egg_flow_box_child_get_instance_private (EGG_FLOW_BOX_CHILD (child));
if (!child_is_visible (child))
{
- child_info->area.x = child_allocation.x;
- child_info->area.y = child_allocation.y;
- child_info->area.width = 0;
- child_info->area.height = 0;
+ child_priv->area.x = child_allocation.x;
+ child_priv->area.y = child_allocation.y;
+ child_priv->area.width = 0;
+ child_priv->area.height = 0;
continue;
}
@@ -955,10 +1265,10 @@ egg_flow_box_real_size_allocate (GtkWidget *widget,
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
child_allocation.x = allocation->x + allocation->width - (child_allocation.x - allocation->x) -
child_allocation.width;
- child_info->area.x = child_allocation.x;
- child_info->area.y = child_allocation.y;
- child_info->area.width = child_allocation.width;
- child_info->area.height = child_allocation.height;
+ child_priv->area.x = child_allocation.x;
+ child_priv->area.y = child_allocation.y;
+ child_priv->area.width = child_allocation.width;
+ child_priv->area.height = child_allocation.height;
gtk_widget_size_allocate (child, &child_allocation);
item_offset += this_item_size;
@@ -972,47 +1282,64 @@ egg_flow_box_real_size_allocate (GtkWidget *widget,
}
static void
-egg_flow_box_real_add (GtkContainer *container,
- GtkWidget *child)
+egg_flow_box_add (GtkContainer *container,
+ GtkWidget *child)
{
EggFlowBox *box = EGG_FLOW_BOX (container);
EggFlowBoxPrivate *priv = box->priv;
- EggFlowBoxChildInfo *info;
+ EggFlowBoxChild *info;
+ EggFlowBoxChildPrivate *child_priv;
GSequenceIter *iter = NULL;
g_return_if_fail (EGG_IS_FLOW_BOX (box));
g_return_if_fail (GTK_IS_WIDGET (child));
- info = egg_flow_box_child_info_new (child);
- g_hash_table_insert (priv->child_hash, child, info);
+ if (EGG_IS_FLOW_BOX_CHILD (child))
+ info = EGG_FLOW_BOX_CHILD (child);
+ else
+ {
+ info = EGG_FLOW_BOX_CHILD (egg_flow_box_child_new ());
+ gtk_widget_show (GTK_WIDGET (info));
+ gtk_container_add (GTK_CONTAINER (info), child);
+ }
+
iter = g_sequence_append (priv->children, info);
- info->iter = iter;
- gtk_widget_set_parent (child, GTK_WIDGET (box));
+ child_priv = egg_flow_box_child_get_instance_private (info);
+ child_priv->iter = iter;
+ gtk_widget_set_parent (GTK_WIDGET (info), GTK_WIDGET (box));
+ gtk_widget_set_child_visible (GTK_WIDGET (info), TRUE);
}
static void
-egg_flow_box_real_remove (GtkContainer *container,
- GtkWidget *child)
+egg_flow_box_remove (GtkContainer *container,
+ GtkWidget *child)
{
EggFlowBox *box = EGG_FLOW_BOX (container);
EggFlowBoxPrivate *priv = box->priv;
gboolean was_visible;
gboolean was_selected;
- EggFlowBoxChildInfo *child_info;
+ EggFlowBoxChild *child_info;
+ EggFlowBoxChildPrivate *child_priv;
g_return_if_fail (child != NULL);
- was_visible = child_is_visible (child);
-
- child_info = egg_flow_box_lookup_info (box, child);
- if (child_info == NULL)
+ if (EGG_IS_FLOW_BOX_CHILD (child))
+ child_info = EGG_FLOW_BOX_CHILD (child);
+ else
{
- g_warning ("Tried to remove non-child %p\n", child);
- return;
+ child_info = (EggFlowBoxChild*)gtk_widget_get_parent (child);
+ if (!EGG_IS_FLOW_BOX_CHILD (child_info))
+ {
+ g_warning ("Tried to remove non-child %p\n", child);
+ return;
+ }
}
- was_selected = child_info->selected;
+ child_priv = egg_flow_box_child_get_instance_private (child_info);
+
+ was_visible = child_is_visible (GTK_WIDGET (child_info));
+ was_selected = child_priv->selected;
if (child_info == priv->prelight_child)
priv->prelight_child = NULL;
@@ -1021,9 +1348,8 @@ egg_flow_box_real_remove (GtkContainer *container,
if (child_info == priv->selected_child)
priv->selected_child = NULL;
- gtk_widget_unparent (child);
- g_hash_table_remove (priv->child_hash, child);
- g_sequence_remove (child_info->iter);
+ gtk_widget_unparent (GTK_WIDGET (child_info));
+ g_sequence_remove (child_priv->iter);
if (was_visible && gtk_widget_get_visible (GTK_WIDGET (box)))
gtk_widget_queue_resize (GTK_WIDGET (box));
@@ -1033,33 +1359,33 @@ egg_flow_box_real_remove (GtkContainer *container,
}
static void
-egg_flow_box_real_forall (GtkContainer *container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_target)
+egg_flow_box_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_target)
{
EggFlowBox *box = EGG_FLOW_BOX (container);
- EggFlowBoxPrivate *priv = box->priv;
+ EggFlowBoxPrivate *priv = box->priv;
GSequenceIter *iter;
- EggFlowBoxChildInfo *child_info;
+ GtkWidget *child;
iter = g_sequence_get_begin_iter (priv->children);
while (!g_sequence_iter_is_end (iter))
{
- child_info = g_sequence_get (iter);
+ child = g_sequence_get (iter);
iter = g_sequence_iter_next (iter);
- callback (child_info->widget, callback_target);
+ callback (child, callback_target);
}
}
static GType
-egg_flow_box_real_child_type (GtkContainer *container)
+egg_flow_box_child_type (GtkContainer *container)
{
- return GTK_TYPE_WIDGET;
+ return EGG_TYPE_FLOW_BOX_CHILD;
}
static GtkSizeRequestMode
-egg_flow_box_real_get_request_mode (GtkWidget *widget)
+egg_flow_box_get_request_mode (GtkWidget *widget)
{
EggFlowBox *box = EGG_FLOW_BOX (widget);
EggFlowBoxPrivate *priv = box->priv;
@@ -1098,13 +1424,10 @@ get_largest_aligned_line_length (EggFlowBox *box,
!g_sequence_iter_is_end (iter);
iter = g_sequence_iter_next (iter))
{
- EggFlowBoxChildInfo *child_info;
GtkWidget *child;
gint child_min, child_nat;
- child_info = g_sequence_get (iter);
- child = child_info->widget;
-
+ child = g_sequence_get (iter);
if (!child_is_visible (child))
continue;
@@ -1145,9 +1468,9 @@ get_largest_aligned_line_length (EggFlowBox *box,
static void
-egg_flow_box_real_get_preferred_width (GtkWidget *widget,
- gint *minimum_size,
- gint *natural_size)
+egg_flow_box_get_preferred_width (GtkWidget *widget,
+ gint *minimum_size,
+ gint *natural_size)
{
EggFlowBox *box = EGG_FLOW_BOX (widget);
EggFlowBoxPrivate *priv = box->priv;
@@ -1162,7 +1485,7 @@ egg_flow_box_real_get_preferred_width (GtkWidget *widget,
{
min_width = nat_width = 0;
- if (! priv->homogeneous)
+ if (!priv->homogeneous)
{
/* When not homogeneous; horizontally oriented boxes
* need enough width for the widest row */
@@ -1231,9 +1554,9 @@ egg_flow_box_real_get_preferred_width (GtkWidget *widget,
}
static void
-egg_flow_box_real_get_preferred_height (GtkWidget *widget,
- gint *minimum_size,
- gint *natural_size)
+egg_flow_box_get_preferred_height (GtkWidget *widget,
+ gint *minimum_size,
+ gint *natural_size)
{
EggFlowBox *box = EGG_FLOW_BOX (widget);
EggFlowBoxPrivate *priv = box->priv;
@@ -1317,10 +1640,10 @@ egg_flow_box_real_get_preferred_height (GtkWidget *widget,
}
static void
-egg_flow_box_real_get_preferred_height_for_width (GtkWidget *widget,
- gint width,
- gint *minimum_height,
- gint *natural_height)
+egg_flow_box_get_preferred_height_for_width (GtkWidget *widget,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height)
{
EggFlowBox *box = EGG_FLOW_BOX (widget);
EggFlowBoxPrivate *priv = box->priv;
@@ -1475,10 +1798,10 @@ egg_flow_box_real_get_preferred_height_for_width (GtkWidget *widget,
}
static void
-egg_flow_box_real_get_preferred_width_for_height (GtkWidget *widget,
- gint height,
- gint *minimum_width,
- gint *natural_width)
+egg_flow_box_get_preferred_width_for_height (GtkWidget *widget,
+ gint height,
+ gint *minimum_width,
+ gint *natural_width)
{
EggFlowBox *box = EGG_FLOW_BOX (widget);
EggFlowBoxPrivate *priv = box->priv;
@@ -2033,24 +2356,26 @@ egg_flow_box_set_property (GObject *object,
}
}
-static EggFlowBoxChildInfo *
+static EggFlowBoxChild *
egg_flow_box_find_child_at_pos (EggFlowBox *box,
gint x,
gint y)
{
EggFlowBoxPrivate *priv = box->priv;
- EggFlowBoxChildInfo *child_info;
+ EggFlowBoxChild *child_info;
GSequenceIter *iter;
- EggFlowBoxChildInfo *info;
+ EggFlowBoxChild *info;
+ EggFlowBoxChildPrivate *child_priv;
child_info = NULL;
for (iter = g_sequence_get_begin_iter (priv->children);
!g_sequence_iter_is_end (iter);
iter = g_sequence_iter_next (iter))
{
- info = (EggFlowBoxChildInfo *) g_sequence_get (iter);
- if (x >= info->area.x && x < (info->area.x + info->area.width)
- && y >= info->area.y && y < (info->area.y + info->area.height))
+ info = (EggFlowBoxChild *) g_sequence_get (iter);
+ child_priv = egg_flow_box_child_get_instance_private (info);
+ if (x >= child_priv->area.x && x < (child_priv->area.x + child_priv->area.width)
+ && y >= child_priv->area.y && y < (child_priv->area.y + child_priv->area.height))
{
child_info = info;
break;
@@ -2062,7 +2387,7 @@ egg_flow_box_find_child_at_pos (EggFlowBox *box,
static void
egg_flow_box_update_prelight (EggFlowBox *box,
- EggFlowBoxChildInfo *child)
+ EggFlowBoxChild *child)
{
EggFlowBoxPrivate *priv = box->priv;
@@ -2075,7 +2400,7 @@ egg_flow_box_update_prelight (EggFlowBox *box,
static void
egg_flow_box_update_active (EggFlowBox *box,
- EggFlowBoxChildInfo *child)
+ EggFlowBoxChild *child)
{
EggFlowBoxPrivate *priv = box->priv;
gboolean val;
@@ -2090,11 +2415,11 @@ egg_flow_box_update_active (EggFlowBox *box,
}
static gboolean
-egg_flow_box_real_enter_notify_event (GtkWidget *widget,
- GdkEventCrossing *event)
+egg_flow_box_enter_notify_event (GtkWidget *widget,
+ GdkEventCrossing *event)
{
EggFlowBox *box = EGG_FLOW_BOX (widget);
- EggFlowBoxChildInfo *child_info;
+ EggFlowBoxChild *child_info;
if (event->window != gtk_widget_get_window (GTK_WIDGET (box)))
@@ -2108,11 +2433,11 @@ egg_flow_box_real_enter_notify_event (GtkWidget *widget,
}
static gboolean
-egg_flow_box_real_leave_notify_event (GtkWidget *widget,
- GdkEventCrossing *event)
+egg_flow_box_leave_notify_event (GtkWidget *widget,
+ GdkEventCrossing *event)
{
EggFlowBox *box = EGG_FLOW_BOX (widget);
- EggFlowBoxChildInfo *child_info = NULL;
+ EggFlowBoxChild *child_info = NULL;
if (event->window != gtk_widget_get_window (GTK_WIDGET (box)))
return FALSE;
@@ -2129,11 +2454,11 @@ egg_flow_box_real_leave_notify_event (GtkWidget *widget,
}
static gboolean
-egg_flow_box_real_motion_notify_event (GtkWidget *widget,
- GdkEventMotion *event)
+egg_flow_box_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event)
{
EggFlowBox *box = EGG_FLOW_BOX (widget);
- EggFlowBoxChildInfo *child_info;
+ EggFlowBoxChild *child_info;
GdkWindow *window;
GdkWindow *event_window;
gint relative_x;
@@ -2164,15 +2489,15 @@ egg_flow_box_real_motion_notify_event (GtkWidget *widget,
}
static gboolean
-egg_flow_box_real_button_press_event (GtkWidget *widget,
- GdkEventButton *event)
+egg_flow_box_button_press_event (GtkWidget *widget,
+ GdkEventButton *event)
{
EggFlowBox *box = EGG_FLOW_BOX (widget);
EggFlowBoxPrivate *priv = box->priv;
if (event->button == GDK_BUTTON_PRIMARY)
{
- EggFlowBoxChildInfo *child_info;
+ EggFlowBoxChild *child_info;
child_info = egg_flow_box_find_child_at_pos (box, event->x, event->y);
if (child_info != NULL)
{
@@ -2183,7 +2508,7 @@ egg_flow_box_real_button_press_event (GtkWidget *widget,
!priv->activate_on_single_click)
g_signal_emit (box,
signals[CHILD_ACTIVATED], 0,
- child_info->widget);
+ child_info);
}
}
@@ -2192,21 +2517,48 @@ egg_flow_box_real_button_press_event (GtkWidget *widget,
static void
egg_flow_box_queue_draw_child (EggFlowBox *box,
- EggFlowBoxChildInfo *child_info)
+ EggFlowBoxChild *child_info)
{
+ EggFlowBoxChildPrivate *priv;
GdkRectangle rect;
GdkWindow *window;
- rect = child_info->area;
+ priv = egg_flow_box_child_get_instance_private (child_info);
+ rect = priv->area;
window = gtk_widget_get_window (GTK_WIDGET (box));
gdk_window_invalidate_rect (window, &rect, TRUE);
}
static gboolean
+egg_flow_box_child_set_selected (EggFlowBoxChild *child,
+ gboolean selected)
+{
+ EggFlowBoxChildPrivate *priv;
+
+ priv = egg_flow_box_child_get_instance_private (child);
+ if (priv->selected != selected)
+ {
+ priv->selected = selected;
+ if (selected)
+ gtk_widget_set_state_flags (GTK_WIDGET (child),
+ GTK_STATE_FLAG_SELECTED, FALSE);
+ else
+ gtk_widget_unset_state_flags (GTK_WIDGET (child),
+ GTK_STATE_FLAG_SELECTED);
+ gtk_widget_queue_draw (GTK_WIDGET (child));
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
egg_flow_box_unselect_all_internal (EggFlowBox *box)
{
- EggFlowBoxChildInfo *child_info;
+ EggFlowBoxChild *child_info;
+ EggFlowBoxChildPrivate *priv;
GSequenceIter *iter;
gboolean dirty = FALSE;
@@ -2218,22 +2570,20 @@ egg_flow_box_unselect_all_internal (EggFlowBox *box)
iter = g_sequence_iter_next (iter))
{
child_info = g_sequence_get (iter);
- if (child_info->selected)
- {
- child_info->selected = FALSE;
- egg_flow_box_queue_draw_child (box, child_info);
- dirty = TRUE;
- }
+ dirty != egg_flow_box_child_set_selected (child_info, FALSE);
}
return dirty;
}
static void
-egg_flow_box_unselect_child_info (EggFlowBox *box,
- EggFlowBoxChildInfo *child_info)
+egg_flow_box_unselect_child_info (EggFlowBox *box,
+ EggFlowBoxChild *child_info)
{
- if (!child_info->selected)
+ EggFlowBoxChildPrivate *priv;
+
+ priv = egg_flow_box_child_get_instance_private (child_info);
+ if (!priv->selected)
return;
if (box->priv->selection_mode == GTK_SELECTION_NONE)
@@ -2241,65 +2591,69 @@ egg_flow_box_unselect_child_info (EggFlowBox *box,
else if (box->priv->selection_mode != GTK_SELECTION_MULTIPLE)
egg_flow_box_unselect_all_internal (box);
else
- child_info->selected = FALSE;
+ egg_flow_box_child_set_selected (child_info, FALSE);
g_signal_emit (box, signals[SELECTED_CHILDREN_CHANGED], 0);
-
- egg_flow_box_queue_draw_child (box, child_info);
}
static void
-egg_flow_box_update_cursor (EggFlowBox *box,
- EggFlowBoxChildInfo *child_info)
+egg_flow_box_update_cursor (EggFlowBox *box,
+ EggFlowBoxChild *child)
{
EggFlowBoxPrivate *priv = box->priv;
- priv->cursor_child = child_info;
- gtk_widget_grab_focus (GTK_WIDGET (box));
- gtk_widget_queue_draw (GTK_WIDGET (box));
-
- if (child_info != NULL && priv->adjustment != NULL)
- {
- GtkAllocation allocation;
-
- gtk_widget_get_allocation (GTK_WIDGET (box), &allocation);
- gtk_adjustment_clamp_page (priv->adjustment,
- priv->cursor_child->area.y + allocation.y,
- priv->cursor_child->area.y + allocation.y +
priv->cursor_child->area.height);
- }
-
- _egg_flow_box_accessible_update_cursor (GTK_WIDGET (box), child_info ? child_info->widget : NULL);
+ priv->cursor_child = child;
+ gtk_widget_grab_focus (GTK_WIDGET (child));
+ gtk_widget_queue_draw (GTK_WIDGET (child));
+ _egg_flow_box_accessible_update_cursor (GTK_WIDGET (box), GTK_WIDGET (child));
}
static void
-egg_flow_box_select_child_info (EggFlowBox *box,
- EggFlowBoxChildInfo *child_info)
+egg_flow_box_select_child_info (EggFlowBox *box,
+ EggFlowBoxChild *child_info)
{
- if (child_info->selected)
+ EggFlowBoxChildPrivate *child_priv;
+
+ child_priv = egg_flow_box_child_get_instance_private (child_info);
+ if (child_priv->selected)
return;
if (box->priv->selection_mode == GTK_SELECTION_NONE)
return;
- else if (box->priv->selection_mode != GTK_SELECTION_MULTIPLE)
+ if (box->priv->selection_mode != GTK_SELECTION_MULTIPLE)
egg_flow_box_unselect_all_internal (box);
- child_info->selected = TRUE;
+ egg_flow_box_child_set_selected (child_info, TRUE);
box->priv->selected_child = child_info;
g_signal_emit (box, signals[SELECTED_CHILDREN_CHANGED], 0);
- egg_flow_box_queue_draw_child (box, child_info);
egg_flow_box_update_cursor (box, child_info);
}
static void
-egg_flow_box_select_all_between (EggFlowBox *box,
- EggFlowBoxChildInfo *child1,
- EggFlowBoxChildInfo *child2)
+egg_flow_box_select_all_between (EggFlowBox *box,
+ EggFlowBoxChild *child1,
+ EggFlowBoxChild *child2)
{
GSequenceIter *iter, *iter1, *iter2;
+ EggFlowBoxChildPrivate *priv;
+
+ if (child1)
+ {
+ priv = egg_flow_box_child_get_instance_private (child1);
+ iter1 = priv->iter;
+ }
+ else
+ iter1 = g_sequence_get_begin_iter (box->priv->children);
+
+ if (child2)
+ {
+ priv = egg_flow_box_child_get_instance_private (child2);
+ iter2 = priv->iter;
+ }
+ else
+ iter2 = g_sequence_get_end_iter (box->priv->children);
- iter1 = child1 ? child1->iter : g_sequence_get_begin_iter (box->priv->children);
- iter2 = child2 ? child2->iter : g_sequence_get_end_iter (box->priv->children);
if (g_sequence_iter_compare (iter2, iter1) < 0)
{
iter = iter1;
@@ -2309,14 +2663,11 @@ egg_flow_box_select_all_between (EggFlowBox *box,
for (iter = iter1; ; iter = g_sequence_iter_next (iter))
{
- EggFlowBoxChildInfo *child_info;
+ GtkWidget *child;
- child_info = g_sequence_get (iter);
- if (child_info && child_is_visible (child_info->widget))
- {
- child_info->selected = TRUE;
- egg_flow_box_queue_draw_child (box, child_info);
- }
+ child = g_sequence_get (iter);
+ if (child_is_visible (child))
+ egg_flow_box_child_set_selected (EGG_FLOW_BOX_CHILD (child), TRUE);
if (g_sequence_iter_compare (iter, iter2) == 0)
break;
@@ -2324,12 +2675,15 @@ egg_flow_box_select_all_between (EggFlowBox *box,
}
static void
-egg_flow_box_update_selection (EggFlowBox *box,
- EggFlowBoxChildInfo *child_info,
- gboolean modify,
- gboolean extend)
+egg_flow_box_update_selection (EggFlowBox *box,
+ EggFlowBoxChild *child_info,
+ gboolean modify,
+ gboolean extend)
{
EggFlowBoxPrivate *priv = box->priv;
+ EggFlowBoxChildPrivate *child_priv;
+
+ child_priv = egg_flow_box_child_get_instance_private (child_info);
if (priv->selection_mode == GTK_SELECTION_NONE)
return;
@@ -2337,17 +2691,17 @@ egg_flow_box_update_selection (EggFlowBox *box,
if (priv->selection_mode == GTK_SELECTION_BROWSE)
{
egg_flow_box_unselect_all_internal (box);
- child_info->selected = TRUE;
+ egg_flow_box_child_set_selected (child_info, TRUE);
priv->selected_child = child_info;
}
else if (priv->selection_mode == GTK_SELECTION_SINGLE)
{
gboolean was_selected;
- was_selected = child_info->selected;
+ was_selected = child_priv->selected;
egg_flow_box_unselect_all_internal (box);
- child_info->selected = modify ? !was_selected : TRUE;
- priv->selected_child = child_info->selected ? child_info : NULL;
+ egg_flow_box_child_set_selected (child_info, modify ? !was_selected : TRUE);
+ priv->selected_child = child_priv->selected ? child_info : NULL;
}
else /* GTK_SELECTION_MULTIPLE */
{
@@ -2356,7 +2710,7 @@ egg_flow_box_update_selection (EggFlowBox *box,
egg_flow_box_unselect_all_internal (box);
if (priv->selected_child == NULL)
{
- child_info->selected = TRUE;
+ egg_flow_box_child_set_selected (child_info, TRUE);
priv->selected_child = child_info;
}
else
@@ -2364,26 +2718,25 @@ egg_flow_box_update_selection (EggFlowBox *box,
}
else
{
- child_info->selected = modify ? !child_info->selected : TRUE;
+ egg_flow_box_child_set_selected (child_info, modify ? !child_priv->selected : TRUE);
priv->selected_child = child_info;
}
}
g_signal_emit (box, signals[SELECTED_CHILDREN_CHANGED], 0);
- egg_flow_box_queue_draw_child (box, child_info);
egg_flow_box_update_cursor (box, child_info);
}
static void
-egg_flow_box_select_and_activate (EggFlowBox *box,
- EggFlowBoxChildInfo *child_info)
+egg_flow_box_select_and_activate (EggFlowBox *box,
+ EggFlowBoxChild *child_info)
{
GtkWidget *w = NULL;
if (child_info != NULL)
{
- w = child_info->widget;
+ w = gtk_bin_get_child (GTK_BIN (child_info));
egg_flow_box_select_child_info (box, child_info);
}
@@ -2392,8 +2745,8 @@ egg_flow_box_select_and_activate (EggFlowBox *box,
}
static gboolean
-egg_flow_box_real_button_release_event (GtkWidget *widget,
- GdkEventButton *event)
+egg_flow_box_button_release_event (GtkWidget *widget,
+ GdkEventButton *event)
{
EggFlowBox *box = EGG_FLOW_BOX (widget);
EggFlowBoxPrivate *priv = box->priv;
@@ -2438,39 +2791,39 @@ egg_flow_box_real_button_release_event (GtkWidget *widget,
return FALSE;
}
-static EggFlowBoxChildInfo *
+static EggFlowBoxChild *
egg_flow_box_get_first_visible (EggFlowBox *box)
{
EggFlowBoxPrivate *priv = box->priv;
- EggFlowBoxChildInfo *child_info;
+ EggFlowBoxChild *child;
GSequenceIter *iter;
for (iter = g_sequence_get_begin_iter (priv->children);
!g_sequence_iter_is_end (iter);
iter = g_sequence_iter_next (iter))
{
- child_info = g_sequence_get (iter);
- if (child_is_visible (child_info->widget))
- return child_info;
+ child = g_sequence_get (iter);
+ if (child_is_visible (GTK_WIDGET (child)))
+ return child;
}
return NULL;
}
-static EggFlowBoxChildInfo *
+static EggFlowBoxChild *
egg_flow_box_get_last_visible (EggFlowBox *box)
{
EggFlowBoxPrivate *priv = box->priv;
- EggFlowBoxChildInfo *child_info;
+ EggFlowBoxChild *child;
GSequenceIter *iter;
iter = g_sequence_get_end_iter (priv->children);
while (!g_sequence_iter_is_begin (iter))
{
iter = g_sequence_iter_prev (iter);
- child_info = g_sequence_get (iter);
- if (child_is_visible (child_info->widget))
- return child_info;
+ child = g_sequence_get (iter);
+ if (child_is_visible (GTK_WIDGET (child)))
+ return child;
}
return NULL;
@@ -2480,7 +2833,7 @@ static GSequenceIter *
egg_flow_box_get_previous_visible (EggFlowBox *box,
GSequenceIter *iter)
{
- EggFlowBoxChildInfo *child_info;
+ EggFlowBoxChild *child;
if (g_sequence_iter_is_begin (iter))
return NULL;
@@ -2488,8 +2841,8 @@ egg_flow_box_get_previous_visible (EggFlowBox *box,
do
{
iter = g_sequence_iter_prev (iter);
- child_info = g_sequence_get (iter);
- if (child_is_visible (child_info->widget))
+ child = g_sequence_get (iter);
+ if (child_is_visible (GTK_WIDGET (child)))
return iter;
}
while (!g_sequence_iter_is_begin (iter));
@@ -2501,7 +2854,7 @@ static GSequenceIter *
egg_flow_box_get_next_visible (EggFlowBox *box,
GSequenceIter *iter)
{
- EggFlowBoxChildInfo *child_info;
+ EggFlowBoxChild *child;
if (g_sequence_iter_is_end (iter))
return iter;
@@ -2511,8 +2864,8 @@ egg_flow_box_get_next_visible (EggFlowBox *box,
iter = g_sequence_iter_next (iter);
if (!g_sequence_iter_is_end (iter))
{
- child_info = g_sequence_get (iter);
- if (child_is_visible (child_info->widget))
+ child = g_sequence_get (iter);
+ if (child_is_visible (GTK_WIDGET (child)))
return iter;
}
}
@@ -2525,7 +2878,7 @@ static GSequenceIter *
egg_flow_box_get_above_visible (EggFlowBox *box,
GSequenceIter *iter)
{
- EggFlowBoxChildInfo *child_info;
+ EggFlowBoxChild *child;
GSequenceIter *ret = NULL;
gint i;
@@ -2536,8 +2889,8 @@ egg_flow_box_get_above_visible (EggFlowBox *box,
do
{
iter = g_sequence_iter_prev (iter);
- child_info = g_sequence_get (iter);
- if (child_is_visible (child_info->widget))
+ child = g_sequence_get (iter);
+ if (child_is_visible (GTK_WIDGET (child)))
i++;
}
while (!g_sequence_iter_is_begin (iter)
@@ -2553,7 +2906,7 @@ static GSequenceIter *
egg_flow_box_get_below_visible (EggFlowBox *box,
GSequenceIter *iter)
{
- EggFlowBoxChildInfo *child_info;
+ EggFlowBoxChild *child;
GSequenceIter *ret = NULL;
gint i;
@@ -2566,8 +2919,8 @@ egg_flow_box_get_below_visible (EggFlowBox *box,
iter = g_sequence_iter_next (iter);
if (!g_sequence_iter_is_end (iter))
{
- child_info = g_sequence_get (iter);
- if (child_is_visible (child_info->widget))
+ child = g_sequence_get (iter);
+ if (child_is_visible (GTK_WIDGET (child)))
i++;
}
}
@@ -2581,40 +2934,29 @@ egg_flow_box_get_below_visible (EggFlowBox *box,
}
static gboolean
-egg_flow_box_real_focus (GtkWidget *widget,
- GtkDirectionType direction)
+egg_flow_box_focus (GtkWidget *widget,
+ GtkDirectionType direction)
{
EggFlowBox *box = EGG_FLOW_BOX (widget);
EggFlowBoxPrivate *priv = box->priv;
gboolean had_focus = FALSE;
GtkWidget *recurse_into;
- EggFlowBoxChildInfo *current_focus_child;
- EggFlowBoxChildInfo *next_focus_child;
+ EggFlowBoxChild *current_focus_child;
+ EggFlowBoxChild *next_focus_child;
gboolean modify_selection_pressed;
gboolean extend_selection_pressed;
GdkModifierType state = 0;
+ EggFlowBoxChildPrivate *child_priv;
recurse_into = NULL;
-
- g_object_get (GTK_WIDGET (box), "has-focus", &had_focus, NULL);
current_focus_child = NULL;
next_focus_child = NULL;
- if (had_focus)
- {
- /* If on row, going right, enter into possible container */
- if (direction == GTK_DIR_RIGHT || direction == GTK_DIR_TAB_FORWARD)
- {
- if (priv->cursor_child != NULL)
- recurse_into = priv->cursor_child->widget;
- }
- current_focus_child = priv->cursor_child;
- }
- else if (gtk_container_get_focus_child ((GtkContainer *) box) != NULL)
+ if (gtk_container_get_focus_child ((GtkContainer *) box) != NULL)
{
/* There is a focus child, always navigate inside it first */
recurse_into = gtk_container_get_focus_child ((GtkContainer *) box);
- current_focus_child = egg_flow_box_lookup_info (box, recurse_into);
+ current_focus_child = EGG_FLOW_BOX_CHILD (recurse_into);
/* If exiting child container to the left, select row or out */
if (direction == GTK_DIR_LEFT || direction == GTK_DIR_TAB_BACKWARD)
@@ -2626,7 +2968,7 @@ egg_flow_box_real_focus (GtkWidget *widget,
if (direction == GTK_DIR_LEFT || direction == GTK_DIR_TAB_BACKWARD)
{
if (priv->selected_child != NULL)
- recurse_into = priv->selected_child->widget;
+ recurse_into = gtk_bin_get_child (GTK_BIN (priv->selected_child));
}
}
@@ -2640,31 +2982,33 @@ egg_flow_box_real_focus (GtkWidget *widget,
{
if (current_focus_child != NULL)
{
- GSequenceIter *i;
+ GSequenceIter *iter;
+
+ child_priv = egg_flow_box_child_get_instance_private (current_focus_child);
if (direction == GTK_DIR_LEFT)
{
- i = egg_flow_box_get_previous_visible (box, current_focus_child->iter);
- if (i != NULL)
- next_focus_child = g_sequence_get (i);
+ iter = egg_flow_box_get_previous_visible (box, child_priv->iter);
+ if (iter != NULL)
+ next_focus_child = g_sequence_get (iter);
}
else if (direction == GTK_DIR_RIGHT)
{
- i = egg_flow_box_get_next_visible (box, current_focus_child->iter);
- if (i != NULL && !g_sequence_iter_is_end (i))
- next_focus_child = g_sequence_get (i);
+ iter = egg_flow_box_get_next_visible (box, child_priv->iter);
+ if (iter != NULL && !g_sequence_iter_is_end (iter))
+ next_focus_child = g_sequence_get (iter);
}
else if (direction == GTK_DIR_UP)
{
- i = egg_flow_box_get_above_visible (box, current_focus_child->iter);
- if (i != NULL && !g_sequence_iter_is_end (i))
- next_focus_child = g_sequence_get (i);
+ iter = egg_flow_box_get_above_visible (box, child_priv->iter);
+ if (iter != NULL && !g_sequence_iter_is_end (iter))
+ next_focus_child = g_sequence_get (iter);
}
else if (direction == GTK_DIR_DOWN)
{
- i = egg_flow_box_get_below_visible (box, current_focus_child->iter);
- if (i != NULL && !g_sequence_iter_is_end (i))
- next_focus_child = g_sequence_get (i);
+ iter = egg_flow_box_get_below_visible (box, child_priv->iter);
+ if (iter != NULL && !g_sequence_iter_is_end (iter))
+ next_focus_child = g_sequence_get (iter);
}
}
else
@@ -2725,14 +3069,14 @@ egg_flow_box_real_focus (GtkWidget *widget,
}
typedef struct {
- EggFlowBoxChildInfo *child;
+ EggFlowBoxChild *child;
GtkStateFlags state;
} ChildFlags;
static ChildFlags *
child_flags_find_or_add (ChildFlags *array,
int *array_length,
- EggFlowBoxChildInfo *to_find)
+ EggFlowBoxChild *to_find)
{
gint i;
@@ -2782,7 +3126,7 @@ egg_flow_box_add_move_binding (GtkBindingSet *binding_set,
}
static void
-egg_flow_box_real_activate_cursor_child (EggFlowBox *box)
+egg_flow_box_activate_cursor_child (EggFlowBox *box)
{
EggFlowBoxPrivate *priv = box->priv;
@@ -2790,35 +3134,39 @@ egg_flow_box_real_activate_cursor_child (EggFlowBox *box)
}
static void
-egg_flow_box_real_toggle_cursor_child (EggFlowBox *box)
+egg_flow_box_toggle_cursor_child (EggFlowBox *box)
{
EggFlowBoxPrivate *priv = box->priv;
+ EggFlowBoxChildPrivate *child_priv;
if (priv->cursor_child == NULL)
return;
+ child_priv = egg_flow_box_child_get_instance_private (priv->cursor_child);
+
if ((priv->selection_mode == GTK_SELECTION_SINGLE ||
priv->selection_mode == GTK_SELECTION_MULTIPLE) &&
- priv->cursor_child->selected)
+ child_priv->selected)
egg_flow_box_unselect_child_info (box, priv->cursor_child);
else
egg_flow_box_select_and_activate (box, priv->cursor_child);
}
static void
-egg_flow_box_real_move_cursor (EggFlowBox *box,
- GtkMovementStep step,
- gint count)
+egg_flow_box_move_cursor (EggFlowBox *box,
+ GtkMovementStep step,
+ gint count)
{
EggFlowBoxPrivate *priv = box->priv;
GdkModifierType state;
gboolean extend_selection_pressed;
gboolean modify_selection_pressed;
- EggFlowBoxChildInfo *child;
+ EggFlowBoxChild *child;
GdkModifierType extend_mod_mask;
GdkModifierType modify_mod_mask;
- EggFlowBoxChildInfo *prev;
- EggFlowBoxChildInfo *next;
+ EggFlowBoxChild *prev;
+ EggFlowBoxChild *next;
+ EggFlowBoxChildPrivate *child_priv;
gint page_size;
GSequenceIter *iter;
gint start_y;
@@ -2846,7 +3194,8 @@ egg_flow_box_real_move_cursor (EggFlowBox *box,
case GTK_MOVEMENT_VISUAL_POSITIONS:
if (priv->cursor_child != NULL)
{
- iter = priv->cursor_child->iter;
+ child_priv = egg_flow_box_child_get_instance_private (priv->cursor_child);
+ iter = child_priv->iter;
if (gtk_widget_get_direction (GTK_WIDGET (box)) == GTK_TEXT_DIR_RTL)
count = - count;
@@ -2874,7 +3223,8 @@ egg_flow_box_real_move_cursor (EggFlowBox *box,
case GTK_MOVEMENT_DISPLAY_LINES:
if (priv->cursor_child != NULL)
{
- iter = priv->cursor_child->iter;
+ child_priv = egg_flow_box_child_get_instance_private (priv->cursor_child);
+ iter = child_priv->iter;
while (count < 0 && iter != NULL)
{
@@ -2898,9 +3248,10 @@ egg_flow_box_real_move_cursor (EggFlowBox *box,
if (priv->cursor_child != NULL)
{
- start_y = priv->cursor_child->area.y;
+ child_priv = egg_flow_box_child_get_instance_private (priv->cursor_child);
+ start_y = child_priv->area.y;
end_y = start_y;
- iter = priv->cursor_child->iter;
+ iter = child_priv->iter;
child = priv->cursor_child;
if (count < 0)
@@ -2915,10 +3266,11 @@ egg_flow_box_real_move_cursor (EggFlowBox *box,
break;
prev = g_sequence_get (iter);
+ child_priv = egg_flow_box_child_get_instance_private (prev);
/* go up an even number of rows */
if (i % priv->cur_children_per_line == 0
- && prev->area.y < start_y - page_size)
+ && child_priv->area.y < start_y - page_size)
break;
child = prev;
@@ -2937,16 +3289,18 @@ egg_flow_box_real_move_cursor (EggFlowBox *box,
break;
next = g_sequence_get (iter);
+ child_priv = egg_flow_box_child_get_instance_private (next);
if (i % priv->cur_children_per_line == 0
- && next->area.y > start_y + page_size)
+ && child_priv->area.y > start_y + page_size)
break;
child = next;
i++;
}
}
- end_y = child->area.y;
+ child_priv = egg_flow_box_child_get_instance_private (child);
+ end_y = child_priv->area.y;
}
break;
default:
@@ -3009,8 +3363,8 @@ egg_flow_box_unselect_all (EggFlowBox *box)
}
static gboolean
-egg_flow_box_real_draw (GtkWidget *widget,
- cairo_t *cr)
+egg_flow_box_draw (GtkWidget *widget,
+ cairo_t *cr)
{
EggFlowBox *box = EGG_FLOW_BOX (widget);
EggFlowBoxPrivate *priv = box->priv;
@@ -3020,25 +3374,31 @@ egg_flow_box_real_draw (GtkWidget *widget,
gint focus_pad;
int i;
GSequenceIter *iter;
+ EggFlowBoxChildPrivate *child_priv;
gtk_widget_get_allocation (GTK_WIDGET (box), &allocation);
context = gtk_widget_get_style_context (GTK_WIDGET (box));
- state = gtk_widget_get_state_flags (widget);
- gtk_render_background (context, cr, (gdouble) 0, (gdouble) 0, (gdouble) allocation.width, (gdouble)
allocation.height);
+ gtk_render_background (context, cr, 0, 0, allocation.width, allocation.height);
+
+ GTK_WIDGET_CLASS (egg_flow_box_parent_class)->draw (widget, cr);
+ return TRUE;
+
+ state = gtk_widget_get_state_flags (widget);
for (iter = g_sequence_get_begin_iter (priv->children);
!g_sequence_iter_is_end (iter);
iter = g_sequence_iter_next (iter))
{
- EggFlowBoxChildInfo *child_info;
+ EggFlowBoxChild *child_info;
ChildFlags flags[3], *found;
gint flags_length;
child_info = g_sequence_get (iter);
+ child_priv = egg_flow_box_child_get_instance_private (child_info);
flags_length = 0;
- if (child_info->selected)
+ if (child_priv->selected)
{
found = child_flags_find_or_add (flags, &flags_length, child_info);
found->state |= (state | GTK_STATE_FLAG_SELECTED);
@@ -3059,11 +3419,12 @@ egg_flow_box_real_draw (GtkWidget *widget,
for (i = 0; i < flags_length; i++)
{
ChildFlags *flag = &flags[i];
+ child_priv = egg_flow_box_child_get_instance_private (flag->child);
gtk_style_context_save (context);
gtk_style_context_set_state (context, flag->state);
gtk_render_background (context, cr,
- flag->child->area.x, flag->child->area.y,
- flag->child->area.width, flag->child->area.height);
+ child_priv->area.x, child_priv->area.y,
+ child_priv->area.width, child_priv->area.height);
gtk_style_context_restore (context);
}
}
@@ -3073,11 +3434,12 @@ egg_flow_box_real_draw (GtkWidget *widget,
gtk_style_context_get_style (context,
"focus-padding", &focus_pad,
NULL);
+ child_priv = egg_flow_box_child_get_instance_private (priv->cursor_child);
gtk_render_focus (context, cr,
- priv->cursor_child->area.x + focus_pad,
- priv->cursor_child->area.y + focus_pad,
- priv->cursor_child->area.width - 2 * focus_pad,
- priv->cursor_child->area.height - 2 * focus_pad);
+ child_priv->area.x + focus_pad,
+ child_priv->area.y + focus_pad,
+ child_priv->area.width - 2 * focus_pad,
+ child_priv->area.height - 2 * focus_pad);
}
@@ -3087,7 +3449,7 @@ egg_flow_box_real_draw (GtkWidget *widget,
}
static void
-egg_flow_box_real_realize (GtkWidget *widget)
+egg_flow_box_realize (GtkWidget *widget)
{
EggFlowBox *box = EGG_FLOW_BOX (widget);
GtkAllocation allocation;
@@ -3121,14 +3483,13 @@ egg_flow_box_finalize (GObject *obj)
EggFlowBoxPrivate *priv = flow_box->priv;
g_sequence_free (priv->children);
- g_hash_table_unref (priv->child_hash);
g_clear_object (&priv->adjustment);
G_OBJECT_CLASS (egg_flow_box_parent_class)->finalize (obj);
}
static void
-egg_flow_box_real_selected_children_changed (EggFlowBox *box)
+egg_flow_box_selected_children_changed (EggFlowBox *box)
{
_egg_flow_box_accessible_selection_changed (GTK_WIDGET (box));
}
@@ -3145,33 +3506,33 @@ egg_flow_box_class_init (EggFlowBoxClass *class)
object_class->get_property = egg_flow_box_get_property;
object_class->set_property = egg_flow_box_set_property;
- widget_class->enter_notify_event = egg_flow_box_real_enter_notify_event;
- widget_class->leave_notify_event = egg_flow_box_real_leave_notify_event;
- widget_class->motion_notify_event = egg_flow_box_real_motion_notify_event;
- widget_class->size_allocate = egg_flow_box_real_size_allocate;
- widget_class->realize = egg_flow_box_real_realize;
- widget_class->focus = egg_flow_box_real_focus;
- widget_class->draw = egg_flow_box_real_draw;
- widget_class->button_press_event = egg_flow_box_real_button_press_event;
- widget_class->button_release_event = egg_flow_box_real_button_release_event;
- widget_class->get_request_mode = egg_flow_box_real_get_request_mode;
- widget_class->get_preferred_width = egg_flow_box_real_get_preferred_width;
- widget_class->get_preferred_height = egg_flow_box_real_get_preferred_height;
- widget_class->get_preferred_height_for_width = egg_flow_box_real_get_preferred_height_for_width;
- widget_class->get_preferred_width_for_height = egg_flow_box_real_get_preferred_width_for_height;
-
- container_class->add = egg_flow_box_real_add;
- container_class->remove = egg_flow_box_real_remove;
- container_class->forall = egg_flow_box_real_forall;
- container_class->child_type = egg_flow_box_real_child_type;
+ widget_class->enter_notify_event = egg_flow_box_enter_notify_event;
+ widget_class->leave_notify_event = egg_flow_box_leave_notify_event;
+ widget_class->motion_notify_event = egg_flow_box_motion_notify_event;
+ widget_class->size_allocate = egg_flow_box_size_allocate;
+ widget_class->realize = egg_flow_box_realize;
+ widget_class->focus = egg_flow_box_focus;
+ widget_class->draw = egg_flow_box_draw;
+ widget_class->button_press_event = egg_flow_box_button_press_event;
+ widget_class->button_release_event = egg_flow_box_button_release_event;
+ widget_class->get_request_mode = egg_flow_box_get_request_mode;
+ widget_class->get_preferred_width = egg_flow_box_get_preferred_width;
+ widget_class->get_preferred_height = egg_flow_box_get_preferred_height;
+ widget_class->get_preferred_height_for_width = egg_flow_box_get_preferred_height_for_width;
+ widget_class->get_preferred_width_for_height = egg_flow_box_get_preferred_width_for_height;
+
+ container_class->add = egg_flow_box_add;
+ container_class->remove = egg_flow_box_remove;
+ container_class->forall = egg_flow_box_forall;
+ container_class->child_type = egg_flow_box_child_type;
gtk_container_class_handle_border_width (container_class);
- class->activate_cursor_child = egg_flow_box_real_activate_cursor_child;
- class->toggle_cursor_child = egg_flow_box_real_toggle_cursor_child;
- class->move_cursor = egg_flow_box_real_move_cursor;
+ class->activate_cursor_child = egg_flow_box_activate_cursor_child;
+ class->toggle_cursor_child = egg_flow_box_toggle_cursor_child;
+ class->move_cursor = egg_flow_box_move_cursor;
class->select_all = egg_flow_box_select_all;
class->unselect_all = egg_flow_box_unselect_all;
- class->selected_children_changed = egg_flow_box_real_selected_children_changed;
+ class->selected_children_changed = egg_flow_box_selected_children_changed;
g_object_class_override_property (object_class, PROP_ORIENTATION, "orientation");
@@ -3412,6 +3773,9 @@ egg_flow_box_init (EggFlowBox *box)
box->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (box, EGG_TYPE_FLOW_BOX, EggFlowBoxPrivate);
+ gtk_widget_set_has_window (GTK_WIDGET (box), TRUE);
+ gtk_widget_set_redraw_on_allocate (GTK_WIDGET (box), TRUE);
+
priv->orientation = GTK_ORIENTATION_HORIZONTAL;
priv->selection_mode = GTK_SELECTION_SINGLE;
priv->halign_policy = GTK_ALIGN_FILL;
@@ -3419,12 +3783,9 @@ egg_flow_box_init (EggFlowBox *box)
priv->max_children_per_line = DEFAULT_MAX_CHILDREN_PER_LINE;
priv->column_spacing = 0;
priv->row_spacing = 0;
- priv->children = g_sequence_new ((GDestroyNotify)egg_flow_box_child_info_free);
- priv->child_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
priv->activate_on_single_click = TRUE;
- gtk_widget_set_can_focus (GTK_WIDGET (box), TRUE);
- gtk_widget_set_has_window (GTK_WIDGET (box), TRUE);
+ priv->children = g_sequence_new (NULL);
}
/**
@@ -3451,7 +3812,8 @@ egg_flow_box_new (void)
GList *
egg_flow_box_get_selected_children (EggFlowBox *box)
{
- EggFlowBoxChildInfo *child_info;
+ EggFlowBoxChild *child_info;
+ EggFlowBoxChildPrivate *child_priv;
GSequenceIter *iter;
GList *selected = NULL;
@@ -3462,65 +3824,47 @@ egg_flow_box_get_selected_children (EggFlowBox *box)
iter = g_sequence_iter_next (iter))
{
child_info = g_sequence_get (iter);
- if (child_info->selected)
- selected = g_list_prepend (selected, child_info->widget);
+ child_priv = egg_flow_box_child_get_instance_private (child_info);
+ if (child_priv->selected)
+ selected = g_list_prepend (selected, child_info);
}
return g_list_reverse (selected);
}
void
-egg_flow_box_select_child (EggFlowBox *box,
- GtkWidget *child)
+egg_flow_box_select_child (EggFlowBox *box,
+ EggFlowBoxChild *child)
{
- EggFlowBoxChildInfo *child_info;
-
g_return_if_fail (EGG_IS_FLOW_BOX (box));
- g_return_if_fail (child != NULL);
+ g_return_if_fail (EGG_IS_FLOW_BOX_CHILD (child));
- child_info = egg_flow_box_lookup_info (box, child);
- if (child_info == NULL)
- {
- g_warning ("Tried to select non-child %p\n", child);
- return;
- }
-
- egg_flow_box_select_child_info (box, child_info);
+ egg_flow_box_select_child_info (box, child);
}
void
-egg_flow_box_unselect_child (EggFlowBox *box,
- GtkWidget *child)
+egg_flow_box_unselect_child (EggFlowBox *box,
+ EggFlowBoxChild *child)
{
- EggFlowBoxChildInfo *child_info;
+ EggFlowBoxChild *child_info;
g_return_if_fail (EGG_IS_FLOW_BOX (box));
- g_return_if_fail (child != NULL);
+ g_return_if_fail (EGG_IS_FLOW_BOX_CHILD (child));
- child_info = egg_flow_box_lookup_info (box, child);
- if (child_info == NULL)
- {
- g_warning ("Tried to unselect non-child %p\n", child);
- return;
- }
-
- egg_flow_box_unselect_child_info (box, child_info);
+ egg_flow_box_unselect_child_info (box, child);
}
gboolean
-egg_flow_box_is_child_selected (EggFlowBox *box,
- GtkWidget *child)
+egg_flow_box_is_child_selected (EggFlowBox *box,
+ EggFlowBoxChild *child)
{
- EggFlowBoxChildInfo *child_info;
+ EggFlowBoxChildPrivate *priv;
- child_info = egg_flow_box_lookup_info (box, child);
- if (child_info == NULL)
- {
- g_warning ("Tried to obtain selection status of non-child %p\n", child);
- return FALSE;
- }
+ g_return_if_fail (EGG_IS_FLOW_BOX (box));
+ g_return_if_fail (EGG_IS_FLOW_BOX_CHILD (child));
- return child_info->selected;
+ priv = egg_flow_box_child_get_instance_private (child);
+ return priv->selected;
}
/**
@@ -3537,7 +3881,8 @@ egg_flow_box_selected_foreach (EggFlowBox *box,
EggFlowBoxForeachFunc func,
gpointer data)
{
- EggFlowBoxChildInfo *child_info;
+ EggFlowBoxChild *child_info;
+ EggFlowBoxChildPrivate *priv;
GSequenceIter *iter;
g_return_if_fail (EGG_IS_FLOW_BOX (box));
@@ -3547,14 +3892,15 @@ egg_flow_box_selected_foreach (EggFlowBox *box,
iter = g_sequence_iter_next (iter))
{
child_info = g_sequence_get (iter);
- if (child_info->selected)
- (* func) (box, child_info->widget, data);
+ priv = egg_flow_box_child_get_instance_private (child_info);
+ if (priv->selected)
+ (* func) (box, child_info, data);
}
}
void
-egg_flow_box_set_selection_mode (EggFlowBox *box,
- GtkSelectionMode mode)
+egg_flow_box_set_selection_mode (EggFlowBox *box,
+ GtkSelectionMode mode)
{
gboolean dirty = FALSE;
g_return_if_fail (EGG_IS_FLOW_BOX (box));
diff --git a/egg-flow-box.h b/egg-flow-box.h
index 3154a9f..d85b147 100644
--- a/egg-flow-box.h
+++ b/egg-flow-box.h
@@ -42,17 +42,21 @@ typedef struct _EggFlowBox EggFlowBox;
typedef struct _EggFlowBoxPrivate EggFlowBoxPrivate;
typedef struct _EggFlowBoxClass EggFlowBoxClass;
+typedef struct _EggFlowBoxChild EggFlowBoxChild;
+typedef struct _EggFlowBoxChildClass EggFlowBoxChildClass;
+
/**
* EggFlowBoxForeachFunc:
- * @flow_box: an #EggFlowBox
- * @child: The child #GtkWidget
+ * @box: an #EggFlowBox
+ * @child: The child #EggFlowBoxChild
* @data: user data
*
* A function used by egg_flow_box_selected_foreach() to map all
- * selected children. It will be called on every selected child in the box.
+ * selected children. It will be called on every selected child
+ * in the box.
*/
-typedef void (* EggFlowBoxForeachFunc) (EggFlowBox *flow_box,
- GtkWidget *child,
+typedef void (* EggFlowBoxForeachFunc) (EggFlowBox *box,
+ EggFlowBoxChild *child,
gpointer data);
struct _EggFlowBox
@@ -67,15 +71,55 @@ struct _EggFlowBoxClass
{
GtkContainerClass parent_class;
- void (* child_activated) (EggFlowBox *self, GtkWidget *child);
- void (* selected_children_changed) (EggFlowBox *self);
- void (*activate_cursor_child) (EggFlowBox *self);
- void (*toggle_cursor_child) (EggFlowBox *self);
- void (*move_cursor) (EggFlowBox *self, GtkMovementStep step, gint count);
- void (*select_all) (EggFlowBox *self);
- void (*unselect_all) (EggFlowBox *self);
+ void (*child_activated) (EggFlowBox *box,
+ EggFlowBoxChild *child);
+ void (*selected_children_changed) (EggFlowBox *box);
+ void (*activate_cursor_child) (EggFlowBox *box);
+ void (*toggle_cursor_child) (EggFlowBox *box);
+ void (*move_cursor) (EggFlowBox *box,
+ GtkMovementStep step,
+ gint count);
+ void (*select_all) (EggFlowBox *box);
+ void (*unselect_all) (EggFlowBox *box);
+
+ /* Padding for future expansion */
+ void (*_gtk_reserved1) (void);
+ void (*_gtk_reserved2) (void);
+ void (*_gtk_reserved3) (void);
+ void (*_gtk_reserved4) (void);
+ void (*_gtk_reserved5) (void);
+ void (*_gtk_reserved6) (void);
+};
+
+#define EGG_TYPE_FLOW_BOX_CHILD (egg_flow_box_child_get_type ())
+#define EGG_FLOW_BOX_CHILD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_FLOW_BOX_CHILD,
EggFlowBoxChild))
+#define EGG_FLOW_BOX_CHILD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_FLOW_BOX_CHILD,
EggFlowBoxChildClass))
+#define EGG_IS_FLOW_BOX_CHILD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_FLOW_BOX_CHILD))
+#define EGG_IS_FLOW_BOX_CHILD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_FLOW_BOX_CHILD))
+#define EGG_FLOW_BOX_CHILD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EG_TYPE_FLOW_BOX_CHILD,
EggFlowBoxChildClass))
+
+struct _EggFlowBoxChild
+{
+ GtkBin parent_instance;
+};
+
+struct _EggFlowBoxChildClass
+{
+ GtkBinClass parent_class;
+
+ void (* activate) (EggFlowBoxChild *child);
+
+ /* Padding for future expansion */
+ void (*_gtk_reserved1) (void);
+ void (*_gtk_reserved2) (void);
};
+GType egg_flow_box_child_get_type (void) G_GNUC_CONST;
+GtkWidget* egg_flow_box_child_new (void);
+gint egg_flow_box_child_get_index (EggFlowBoxChild *child);
+void egg_flow_box_child_changed (EggFlowBoxChild *child);
+
+
GType egg_flow_box_get_type (void) G_GNUC_CONST;
GtkWidget *egg_flow_box_new (void);
@@ -114,13 +158,13 @@ void egg_flow_box_selected_foreach (EggFlowBox
EggFlowBoxForeachFunc func,
gpointer data);
void egg_flow_box_select_child (EggFlowBox *box,
- GtkWidget *child);
+ EggFlowBoxChild *child);
void egg_flow_box_unselect_child (EggFlowBox *box,
- GtkWidget *child);
+ EggFlowBoxChild *child);
void egg_flow_box_select_all (EggFlowBox *box);
void egg_flow_box_unselect_all (EggFlowBox *box);
gboolean egg_flow_box_is_child_selected (EggFlowBox *box,
- GtkWidget *child);
+ EggFlowBoxChild *child);
GtkSelectionMode egg_flow_box_get_selection_mode (EggFlowBox *box);
void egg_flow_box_set_selection_mode (EggFlowBox *box,
GtkSelectionMode mode);
diff --git a/test-flow-box.c b/test-flow-box.c
index 3d2612e..42f714c 100644
--- a/test-flow-box.c
+++ b/test-flow-box.c
@@ -287,11 +287,14 @@ on_child_activated (EggFlowBox *self,
}
static void
-selection_foreach (EggFlowBox *self,
- GtkWidget *child,
- gpointer data)
+selection_foreach (EggFlowBox *self,
+ EggFlowBoxChild *child_info,
+ gpointer data)
{
const char *id;
+ GtkWidget *child;
+
+ child = gtk_bin_get_child (GTK_BIN (child_info));
id = g_object_get_data (G_OBJECT (child), "id");
g_message ("Child selected %p: %s", child, id);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]