libegg r889 - in trunk: . libegg/toolpalette
- From: hasselmm svn gnome org
- To: svn-commits-list gnome org
- Subject: libegg r889 - in trunk: . libegg/toolpalette
- Date: Thu, 10 Jul 2008 12:33:07 +0000 (UTC)
Author: hasselmm
Date: Thu Jul 10 12:33:07 2008
New Revision: 889
URL: http://svn.gnome.org/viewvc/libegg?rev=889&view=rev
Log:
Scroll when focusing tool palette item.
* libegg/toolpalette/eggtoolitemgroup.c (EggToolItemGroupPrivate,
egg_tool_item_group_dispose(), egg_tool_item_group_set_focus_cb(),
egg_tool_item_group_realize(), egg_tool_item_group_unrealize(),
egg_tool_item_group_set_toplevel_window()): Hook to parent window's
set-focus signal to track focus changes and actually scroll to the
focused widget when it is one of our items.
* libegg/toolpalette/eggtoolpalette.c
(egg_tool_palette_get_hadjustment(),
egg_tool_palette_get_vadjustment()):
* libegg/toolpalette/eggtoolpalette.h
(egg_tool_palette_get_hadjustment(),
egg_tool_palette_get_vadjustment()):
Provide adjustment accessors. Fix some formatting issues.
Modified:
trunk/ChangeLog
trunk/libegg/toolpalette/eggtoolitemgroup.c
trunk/libegg/toolpalette/eggtoolpalette.c
trunk/libegg/toolpalette/eggtoolpalette.h
trunk/libegg/toolpalette/testtoolpalette.c
Modified: trunk/libegg/toolpalette/eggtoolitemgroup.c
==============================================================================
--- trunk/libegg/toolpalette/eggtoolitemgroup.c (original)
+++ trunk/libegg/toolpalette/eggtoolitemgroup.c Thu Jul 10 12:33:07 2008
@@ -80,8 +80,10 @@
gint header_spacing;
PangoEllipsizeMode ellipsize;
- guint collapsed : 1;
+ gulong focus_set_id;
+ GtkWidget *toplevel;
+ guint collapsed : 1;
};
struct _EggToolItemGroupChild
@@ -444,6 +446,24 @@
}
static void
+egg_tool_item_group_dispose (GObject *object)
+{
+ EggToolItemGroup *group = EGG_TOOL_ITEM_GROUP (object);
+
+ if (group->priv->toplevel)
+ {
+ /* disconnect focus tracking handler */
+ g_signal_handler_disconnect (group->priv->toplevel,
+ group->priv->focus_set_id);
+
+ group->priv->focus_set_id = 0;
+ group->priv->toplevel = NULL;
+ }
+
+ G_OBJECT_CLASS (egg_tool_item_group_parent_class)->dispose (object);
+}
+
+static void
egg_tool_item_group_get_item_size (EggToolItemGroup *group,
GtkRequisition *item_size,
gboolean homogeneous_only,
@@ -800,7 +820,7 @@
child_allocation.width = child_requisition.width;
child_allocation.height = allocation->height;
- if (GTK_TEXT_DIR_RTL == direction)
+ if (GTK_TEXT_DIR_RTL == direction)
child_allocation.x = allocation->width - border_width - child_allocation.width;
}
@@ -958,8 +978,116 @@
}
static void
+egg_tool_item_group_set_focus_cb (GtkWidget *window G_GNUC_UNUSED,
+ GtkWidget *widget,
+ gpointer user_data)
+{
+ GtkAdjustment *adjustment;
+ GtkWidget *p;
+
+ /* Find this group's parent widget in the focused widget's anchestry. */
+ for (p = widget; p; p = gtk_widget_get_parent (p))
+ if (p == user_data)
+ {
+ p = gtk_widget_get_parent (p);
+ break;
+ }
+
+ if (EGG_IS_TOOL_PALETTE (p))
+ {
+ /* Check that the focused widgets is fully visible within
+ * the group's parent widget and make it visible otherwise. */
+
+ adjustment = egg_tool_palette_get_hadjustment (EGG_TOOL_PALETTE (p));
+ adjustment = egg_tool_palette_get_vadjustment (EGG_TOOL_PALETTE (p));
+
+ if (adjustment)
+ {
+ int y;
+
+ /* Handle vertical adjustment. */
+ if (gtk_widget_translate_coordinates
+ (widget, p, 0, 0, NULL, &y) && y < 0)
+ {
+ y += adjustment->value;
+ gtk_adjustment_clamp_page (adjustment, y, y + widget->allocation.height);
+ }
+ else if (gtk_widget_translate_coordinates
+ (widget, p, 0, widget->allocation.height, NULL, &y) &&
+ y > p->allocation.height)
+ {
+ y += adjustment->value;
+ gtk_adjustment_clamp_page (adjustment, y - widget->allocation.height, y);
+ }
+ }
+
+ adjustment = egg_tool_palette_get_hadjustment (EGG_TOOL_PALETTE (p));
+
+ if (adjustment)
+ {
+ int x;
+
+ /* Handle horizontal adjustment. */
+ if (gtk_widget_translate_coordinates
+ (widget, p, 0, 0, &x, NULL) && x < 0)
+ {
+ x += adjustment->value;
+ gtk_adjustment_clamp_page (adjustment, x, x + widget->allocation.width);
+ }
+ else if (gtk_widget_translate_coordinates
+ (widget, p, widget->allocation.width, 0, &x, NULL) &&
+ x > p->allocation.width)
+ {
+ x += adjustment->value;
+ gtk_adjustment_clamp_page (adjustment, x - widget->allocation.width, x);
+ }
+
+ return;
+ }
+ }
+}
+
+static void
+egg_tool_item_group_set_toplevel_window (EggToolItemGroup *group,
+ GtkWidget *toplevel)
+{
+ if (toplevel != group->priv->toplevel)
+ {
+ if (group->priv->toplevel)
+ {
+ /* Disconnect focus tracking handler. */
+ g_signal_handler_disconnect (group->priv->toplevel,
+ group->priv->focus_set_id);
+
+ group->priv->focus_set_id = 0;
+ group->priv->toplevel = NULL;
+ }
+
+ if (toplevel)
+ {
+ /* Install focus tracking handler. We connect to the window's
+ * set-focus signal instead of connecting to the focus signal of
+ * each child to:
+ *
+ * 1) Reduce the number of signal handlers used.
+ * 2) Avoid special handling for group headers.
+ * 3) Catch focus grabs not only for direct children,
+ * but also for nested widgets.
+ */
+ group->priv->focus_set_id =
+ g_signal_connect (toplevel, "set-focus",
+ G_CALLBACK (egg_tool_item_group_set_focus_cb),
+ group);
+
+ group->priv->toplevel = toplevel;
+ }
+ }
+}
+
+static void
egg_tool_item_group_realize (GtkWidget *widget)
{
+ GtkWidget *toplevel_window;
const gint border_width = GTK_CONTAINER (widget)->border_width;
gint attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
GdkWindowAttr attributes;
@@ -995,6 +1123,17 @@
widget->window);
gtk_widget_queue_resize_no_redraw (widget);
+
+ toplevel_window = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
+ egg_tool_item_group_set_toplevel_window (EGG_TOOL_ITEM_GROUP (widget),
+ toplevel_window);
+}
+
+static void
+egg_tool_item_group_unrealize (GtkWidget *widget)
+{
+ egg_tool_item_group_set_toplevel_window (EGG_TOOL_ITEM_GROUP (widget), NULL);
+ GTK_WIDGET_CLASS (egg_tool_item_group_parent_class)->unrealize (widget);
}
static void
@@ -1305,10 +1444,12 @@
oclass->set_property = egg_tool_item_group_set_property;
oclass->get_property = egg_tool_item_group_get_property;
oclass->finalize = egg_tool_item_group_finalize;
+ oclass->dispose = egg_tool_item_group_dispose;
wclass->size_request = egg_tool_item_group_size_request;
wclass->size_allocate = egg_tool_item_group_size_allocate;
wclass->realize = egg_tool_item_group_realize;
+ wclass->unrealize = egg_tool_item_group_unrealize;
wclass->style_set = egg_tool_item_group_style_set;
cclass->add = egg_tool_item_group_add;
@@ -1467,19 +1608,37 @@
EggToolItemGroup *group = EGG_TOOL_ITEM_GROUP (data);
gint64 timestamp = egg_tool_item_group_get_animation_timestamp (group);
- /* enque this early to reduce number of expose events */
+ /* Enque this early to reduce number of expose events. */
gtk_widget_queue_resize_no_redraw (GTK_WIDGET (group));
+ /* Figure out current style of the expander arrow. */
+ if (group->priv->collapsed)
+ {
+ if (group->priv->expander_style == GTK_EXPANDER_EXPANDED)
+ group->priv->expander_style = GTK_EXPANDER_SEMI_COLLAPSED;
+ else
+ group->priv->expander_style = GTK_EXPANDER_COLLAPSED;
+ }
+ else
+ {
+ if (group->priv->expander_style == GTK_EXPANDER_COLLAPSED)
+ group->priv->expander_style = GTK_EXPANDER_SEMI_EXPANDED;
+ else
+ group->priv->expander_style = GTK_EXPANDER_EXPANDED;
+ }
+
if (GTK_WIDGET_REALIZED (group->priv->header))
{
GtkWidget *alignment = egg_tool_item_group_get_alignment (group);
GdkRectangle area;
+ /* Find the header button's arrow area... */
area.x = alignment->allocation.x;
area.y = alignment->allocation.y + (alignment->allocation.height - group->priv->expander_size) / 2;
area.height = group->priv->expander_size;
area.width = group->priv->expander_size;
+ /* ... and invalidated it to get it animated. */
gdk_window_invalidate_rect (group->priv->header->window, &area, TRUE);
}
@@ -1487,10 +1646,11 @@
{
GtkWidget *widget = GTK_WIDGET (group);
GtkWidget *parent = gtk_widget_get_parent (widget);
+ int x, y, width, height;
- gint width = widget->allocation.width;
- gint height = widget->allocation.height;
- gint x, y;
+ /* Find the tool item area button's arrow area... */
+ width = widget->allocation.width;
+ height = widget->allocation.height;
gtk_widget_translate_coordinates (widget, parent, 0, 0, &x, &y);
@@ -1500,24 +1660,11 @@
y += group->priv->header->allocation.height;
}
+ /* ... and invalidated it to get it animated. */
gtk_widget_queue_draw_area (parent, x, y, width, height);
}
- if (group->priv->collapsed)
- {
- if (group->priv->expander_style == GTK_EXPANDER_EXPANDED)
- group->priv->expander_style = GTK_EXPANDER_SEMI_COLLAPSED;
- else
- group->priv->expander_style = GTK_EXPANDER_COLLAPSED;
- }
- else
- {
- if (group->priv->expander_style == GTK_EXPANDER_COLLAPSED)
- group->priv->expander_style = GTK_EXPANDER_SEMI_EXPANDED;
- else
- group->priv->expander_style = GTK_EXPANDER_EXPANDED;
- }
-
+ /* Finish animation when done. */
if (timestamp >= ANIMATION_DURATION)
group->priv->animation_timeout = NULL;
@@ -1560,8 +1707,10 @@
group->priv->animation_timeout = g_timeout_source_new (ANIMATION_TIMEOUT);
parent = gtk_widget_get_parent (GTK_WIDGET (group));
+
if (EGG_IS_TOOL_PALETTE (parent) && !collapsed)
- _egg_tool_palette_set_expanding_child (EGG_TOOL_PALETTE (parent), GTK_WIDGET (group));
+ _egg_tool_palette_set_expanding_child (EGG_TOOL_PALETTE (parent),
+ GTK_WIDGET (group));
g_source_set_callback (group->priv->animation_timeout,
egg_tool_item_group_animation_cb,
Modified: trunk/libegg/toolpalette/eggtoolpalette.c
==============================================================================
--- trunk/libegg/toolpalette/eggtoolpalette.c (original)
+++ trunk/libegg/toolpalette/eggtoolpalette.c Thu Jul 10 12:33:07 2008
@@ -451,21 +451,25 @@
* widget as possible is calculated */
if (widget == palette->priv->expanding_child)
{
- guint j;
+ gint limit =
+ GTK_ORIENTATION_VERTICAL == palette->priv->orientation ?
+ child_allocation.width : child_allocation.height;
+
gint real_size;
- gint limit = GTK_ORIENTATION_VERTICAL == palette->priv->orientation ? child_allocation.width : child_allocation.height;
+ guint j;
min_offset = 0;
+
for (j = 0; j < i; ++j)
- {
- min_offset += group_sizes[j];
- }
+ min_offset += group_sizes[j];
+
max_offset = min_offset + group_sizes[i];
- real_size = _egg_tool_item_group_get_size_for_limit (EGG_TOOL_ITEM_GROUP (widget),
- limit,
- GTK_ORIENTATION_VERTICAL == palette->priv->orientation,
- FALSE);
+ real_size = _egg_tool_item_group_get_size_for_limit
+ (EGG_TOOL_ITEM_GROUP (widget), limit,
+ GTK_ORIENTATION_VERTICAL == palette->priv->orientation,
+ FALSE);
+
if (size == real_size)
palette->priv->expanding_child = NULL;
}
@@ -479,9 +483,11 @@
if (max_offset != -1)
{
- gint limit = GTK_ORIENTATION_VERTICAL == palette->priv->orientation ? allocation->height : allocation->width;
+ gint limit =
+ GTK_ORIENTATION_VERTICAL == palette->priv->orientation ?
+ allocation->height : allocation->width;
- offset = MIN(MAX (offset, max_offset - limit), min_offset);
+ offset = MIN (MAX (offset, max_offset - limit), min_offset);
}
if (remaining_space > 0)
@@ -562,18 +568,9 @@
adjustment->page_increment = page_size * 0.9;
adjustment->step_increment = page_size * 0.1;
adjustment->page_size = page_size;
- if (GTK_ORIENTATION_HORIZONTAL == palette->priv->orientation &&
- GTK_TEXT_DIR_RTL == direction)
- {
- adjustment->lower = page_size - MAX (0, page_start);
- adjustment->upper = page_size;
- offset = -offset;
-
- value = MAX(offset, adjustment->lower);
- gtk_adjustment_clamp_page (adjustment, offset, value + page_size);
- }
- else
+ if (GTK_ORIENTATION_VERTICAL == palette->priv->orientation ||
+ GTK_TEXT_DIR_LTR == direction)
{
adjustment->lower = 0;
adjustment->upper = MAX (0, page_start);
@@ -581,6 +578,16 @@
value = MIN (offset, adjustment->upper - adjustment->page_size);
gtk_adjustment_clamp_page (adjustment, value, offset + page_size);
}
+ else
+ {
+ adjustment->lower = page_size - MAX (0, page_start);
+ adjustment->upper = page_size;
+
+ offset = -offset;
+
+ value = MAX (offset, adjustment->lower);
+ gtk_adjustment_clamp_page (adjustment, offset, value + page_size);
+ }
gtk_adjustment_changed (adjustment);
}
@@ -1597,15 +1604,29 @@
}
void
-_egg_tool_palette_set_expanding_child (EggToolPalette *palette,
- GtkWidget *widget)
+_egg_tool_palette_set_expanding_child (EggToolPalette *palette,
+ GtkWidget *widget)
{
g_return_if_fail (EGG_IS_TOOL_PALETTE (palette));
-
palette->priv->expanding_child = widget;
}
+GtkAdjustment*
+egg_tool_palette_get_hadjustment (EggToolPalette *palette)
+{
+ g_return_val_if_fail (EGG_IS_TOOL_PALETTE (palette), NULL);
+ return palette->priv->hadjustment;
+}
+
+GtkAdjustment*
+egg_tool_palette_get_vadjustment (EggToolPalette *palette)
+{
+ g_return_val_if_fail (EGG_IS_TOOL_PALETTE (palette), NULL);
+ return palette->priv->vadjustment;
+}
+
#ifdef HAVE_EXTENDED_TOOL_SHELL_SUPPORT_BUG_535090
+
GtkSizeGroup *
_egg_tool_palette_get_size_group (EggToolPalette *palette)
{
@@ -1613,4 +1634,5 @@
return palette->priv->text_size_group;
}
+
#endif
Modified: trunk/libegg/toolpalette/eggtoolpalette.h
==============================================================================
--- trunk/libegg/toolpalette/eggtoolpalette.h (original)
+++ trunk/libegg/toolpalette/eggtoolpalette.h Thu Jul 10 12:33:07 2008
@@ -121,6 +121,9 @@
EggToolPaletteDragTargets targets,
GdkDragAction actions);
+GtkAdjustment* egg_tool_palette_get_hadjustment (EggToolPalette *palette);
+GtkAdjustment* egg_tool_palette_get_vadjustment (EggToolPalette *palette);
+
G_CONST_RETURN GtkTargetEntry* egg_tool_palette_get_drag_target_item (void) G_GNUC_CONST;
G_CONST_RETURN GtkTargetEntry* egg_tool_palette_get_drag_target_group (void) G_GNUC_CONST;
Modified: trunk/libegg/toolpalette/testtoolpalette.c
==============================================================================
--- trunk/libegg/toolpalette/testtoolpalette.c (original)
+++ trunk/libegg/toolpalette/testtoolpalette.c Thu Jul 10 12:33:07 2008
@@ -117,7 +117,7 @@
if (EGG_TOOL_ITEM_GROUP (drag_group) != drop_group)
{
gboolean homogeneous, expand, fill, new_row;
-
+
g_object_ref (drag_item);
gtk_container_child_get (GTK_CONTAINER (drag_group), GTK_WIDGET (drag_item),
"homogeneous", &homogeneous,
@@ -433,6 +433,30 @@
}
static void
+load_toggle_items (EggToolPalette *palette)
+{
+ GSList *toggle_group = NULL;
+ GtkToolItem *item;
+ GtkWidget *group;
+ char *label;
+ int i;
+
+ group = egg_tool_item_group_new (_("Radio Item"));
+ gtk_container_add (GTK_CONTAINER (palette), group);
+
+ for (i = 1; i <= 10; ++i)
+ {
+ label = g_strdup_printf ("#%d", i);
+ item = gtk_radio_tool_button_new (toggle_group);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (item), label);
+ g_free (label);
+
+ egg_tool_item_group_insert (EGG_TOOL_ITEM_GROUP (group), item, -1);
+ toggle_group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (item));
+ }
+}
+
+static void
load_special_items (EggToolPalette *palette)
{
GtkToolItem *item;
@@ -720,6 +744,7 @@
/* ===== palette ===== */
load_stock_items (EGG_TOOL_PALETTE (palette));
+ load_toggle_items (EGG_TOOL_PALETTE (palette));
load_special_items (EGG_TOOL_PALETTE (palette));
g_signal_connect (palette, "notify::orientation",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]