libegg r836 - in trunk: . libegg/toolpalette
- From: hasselmm svn gnome org
- To: svn-commits-list gnome org
- Subject: libegg r836 - in trunk: . libegg/toolpalette
- Date: Fri, 11 Jan 2008 11:47:38 +0000 (GMT)
Author: hasselmm
Date: Fri Jan 11 11:47:38 2008
New Revision: 836
URL: http://svn.gnome.org/viewvc/libegg?rev=836&view=rev
Log:
Implement composited expand/collapse animation.
* libegg/toolpalette/eggtoolitemgroup.h: Indent fixes.
* libegg/toolpalette/eggtoolitemgroup.c: Implement animation.
* libegg/toolpalette/eggtoolpalette.c: Draw composited
EggToolItemGroup. Delegate item group size calculation
to _egg_tool_item_group_get_height_for_width().
* libegg/toolpalette/eggtoolpaletteprivate.h:
Add _egg_tool_item_group_get_height_for_width() and
_egg_tool_item_group_paint().
Modified:
trunk/ChangeLog
trunk/libegg/toolpalette/eggtoolitemgroup.c
trunk/libegg/toolpalette/eggtoolitemgroup.h
trunk/libegg/toolpalette/eggtoolpalette.c
trunk/libegg/toolpalette/eggtoolpaletteprivate.h
Modified: trunk/libegg/toolpalette/eggtoolitemgroup.c
==============================================================================
--- trunk/libegg/toolpalette/eggtoolitemgroup.c (original)
+++ trunk/libegg/toolpalette/eggtoolitemgroup.c Fri Jan 11 11:47:38 2008
@@ -30,8 +30,10 @@
#include <string.h>
-#define DEFAULT_EXPANDER_SIZE 16
-#define DEFAULT_HEADER_SPACING 2
+#define ANIMATION_TIMEOUT 50
+#define ANIMATION_DURATION (ANIMATION_TIMEOUT * 6)
+#define DEFAULT_EXPANDER_SIZE 16
+#define DEFAULT_HEADER_SPACING 2
#define P_(msgid) _(msgid)
@@ -47,7 +49,8 @@
GtkWidget *header;
GArray *items;
- guint animation_timeout;
+ gint64 animation_start;
+ GSource *animation_timeout;
GtkExpanderStyle expander_style;
gint expander_size;
gint header_spacing;
@@ -230,6 +233,18 @@
}
static void
+egg_tool_item_group_get_item_size (EggToolItemGroup *group,
+ GtkRequisition *item_size)
+{
+ GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (group));
+
+ if (EGG_IS_TOOL_PALETTE (parent))
+ _egg_tool_palette_get_item_size (EGG_TOOL_PALETTE (parent), item_size);
+ else
+ _egg_tool_item_group_item_size_request (group, item_size);
+}
+
+static void
egg_tool_item_group_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
@@ -238,17 +253,10 @@
GtkRequisition child_requistion;
GtkAllocation child_allocation;
GtkRequisition item_size;
- GtkWidget *parent;
guint i;
GTK_WIDGET_CLASS (egg_tool_item_group_parent_class)->size_allocate (widget, allocation);
-
- parent = gtk_widget_get_parent (widget);
-
- if (EGG_IS_TOOL_PALETTE (parent))
- _egg_tool_palette_get_item_size (EGG_TOOL_PALETTE (parent), &item_size);
- else
- _egg_tool_item_group_item_size_request (group, &item_size);
+ egg_tool_item_group_get_item_size (group, &item_size);
child_allocation.x = border_width;
child_allocation.y = border_width;
@@ -265,7 +273,7 @@
child_allocation.y += child_allocation.height;
}
- if (group->priv->expanded)
+ if (group->priv->expanded || group->priv->animation_timeout)
{
for (i = 0; i < group->priv->items->len; ++i)
{
@@ -308,6 +316,7 @@
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;
+ GdkDisplay *display;
attributes.window_type = GDK_WINDOW_CHILD;
attributes.x = widget->allocation.x + border_width;
@@ -324,6 +333,11 @@
widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
&attributes, attributes_mask);
+ display = gdk_drawable_get_display (widget->window);
+
+ if (gdk_display_supports_composite (display))
+ gdk_window_set_composited (widget->window, TRUE);
+
gdk_window_set_user_data (widget->window, widget);
widget->style = gtk_style_attach (widget->style, widget->window);
gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
@@ -506,16 +520,24 @@
}
}
+static gint64
+egg_tool_item_group_get_animation_timestamp (EggToolItemGroup *group)
+{
+ GTimeVal now;
+ g_source_get_current_time (group->priv->animation_timeout, &now);
+ return (now.tv_sec * G_USEC_PER_SEC + now.tv_usec - group->priv->animation_start) / 1000;
+}
+
static gboolean
egg_tool_item_group_animation_cb (gpointer data)
{
EggToolItemGroup *group = EGG_TOOL_ITEM_GROUP (data);
- gboolean finish = TRUE;
- GdkRectangle area;
+ gint64 timestamp = egg_tool_item_group_get_animation_timestamp (group);
if (GTK_WIDGET_REALIZED (group->priv->header))
{
GtkWidget *alignment = egg_tool_item_group_get_alignment (group);
+ GdkRectangle area;
area.x = alignment->allocation.x;
area.y = alignment->allocation.y + (alignment->allocation.height - group->priv->expander_size) / 2;
@@ -525,34 +547,47 @@
gdk_window_invalidate_rect (group->priv->header->window, &area, TRUE);
}
- if (group->priv->expanded)
+ if (GTK_WIDGET_REALIZED (group))
{
- if (group->priv->expander_style == GTK_EXPANDER_COLLAPSED)
+ GtkWidget *widget = GTK_WIDGET (group);
+ GtkWidget *parent = gtk_widget_get_parent (widget);
+
+ gint width = widget->allocation.width;
+ gint height = widget->allocation.height;
+ gint x, y;
+
+ gtk_widget_translate_coordinates (widget, parent, 0, 0, &x, &y);
+
+ if (GTK_WIDGET_VISIBLE (group->priv->header))
{
- group->priv->expander_style = GTK_EXPANDER_SEMI_EXPANDED;
- finish = FALSE;
+ height -= group->priv->header->allocation.height;
+ y += group->priv->header->allocation.height;
}
+
+ gtk_widget_queue_draw_area (parent, x, y, width, height);
+ }
+
+ if (group->priv->expanded)
+ {
+ if (group->priv->expander_style == GTK_EXPANDER_COLLAPSED)
+ group->priv->expander_style = GTK_EXPANDER_SEMI_EXPANDED;
else
group->priv->expander_style = GTK_EXPANDER_EXPANDED;
}
else
{
if (group->priv->expander_style == GTK_EXPANDER_EXPANDED)
- {
- group->priv->expander_style = GTK_EXPANDER_SEMI_COLLAPSED;
- finish = FALSE;
- }
+ group->priv->expander_style = GTK_EXPANDER_SEMI_COLLAPSED;
else
group->priv->expander_style = GTK_EXPANDER_COLLAPSED;
}
- if (finish)
- {
- group->priv->animation_timeout = 0;
- gtk_widget_queue_resize_no_redraw (GTK_WIDGET (group));
- }
+ if (timestamp >= ANIMATION_DURATION)
+ group->priv->animation_timeout = NULL;
+
+ gtk_widget_queue_resize_no_redraw (GTK_WIDGET (group));
- return !finish;
+ return (group->priv->animation_timeout != NULL);
}
void
@@ -563,12 +598,22 @@
if (expanded != group->priv->expanded)
{
+ GTimeVal now;
+
+ g_get_current_time (&now);
+
if (group->priv->animation_timeout)
- g_source_remove (group->priv->animation_timeout);
+ g_source_destroy (group->priv->animation_timeout);
group->priv->expanded = expanded;
- group->priv->animation_timeout = g_timeout_add (50, egg_tool_item_group_animation_cb, group);
+ group->priv->animation_start = (now.tv_sec * G_USEC_PER_SEC + now.tv_usec);
+ group->priv->animation_timeout = g_timeout_source_new (ANIMATION_TIMEOUT);
+ g_source_set_callback (group->priv->animation_timeout,
+ egg_tool_item_group_animation_cb,
+ group, NULL);
+
+ g_source_attach (group->priv->animation_timeout, NULL);
g_object_notify (G_OBJECT (group), "expanded");
}
}
@@ -702,3 +747,84 @@
item_size->height = MAX (item_size->height, child_requisition.height);
}
}
+
+void
+_egg_tool_item_group_paint (EggToolItemGroup *group,
+ cairo_t *cr)
+{
+ GtkWidget *widget = GTK_WIDGET (group);
+
+ gdk_cairo_set_source_pixmap (cr, widget->window,
+ widget->allocation.x,
+ widget->allocation.y);
+
+ if (group->priv->animation_timeout)
+ {
+ cairo_pattern_t *mask;
+ gdouble y0, y1;
+
+ y0 = widget->allocation.height - 256;
+ y1 = widget->allocation.height;
+
+ if (GTK_WIDGET_VISIBLE (group->priv->header))
+ y0 = MAX (y0, group->priv->header->allocation.height);
+ else
+ y0 = MAX (y0, 0);
+
+ y1 = MIN (y0 + 256, y1);
+
+ y0 += widget->allocation.y;
+ y1 += widget->allocation.y;
+
+ mask = cairo_pattern_create_linear (0.0, y0, 0.0, y1);
+
+ cairo_pattern_add_color_stop_rgba (mask, 0.00, 0.0, 0.0, 0.0, 1.00);
+ cairo_pattern_add_color_stop_rgba (mask, 0.25, 0.0, 0.0, 0.0, 0.25);
+ cairo_pattern_add_color_stop_rgba (mask, 0.50, 0.0, 0.0, 0.0, 0.10);
+ cairo_pattern_add_color_stop_rgba (mask, 0.75, 0.0, 0.0, 0.0, 0.01);
+ cairo_pattern_add_color_stop_rgba (mask, 1.00, 0.0, 0.0, 0.0, 0.00);
+
+ cairo_mask (cr, mask);
+ cairo_pattern_destroy (mask);
+ }
+ else
+ cairo_paint (cr);
+}
+
+gint
+_egg_tool_item_group_get_height_for_width (EggToolItemGroup *group,
+ gint width)
+{
+ guint n_items = group->priv->items->len;
+ GtkRequisition child_requisition;
+
+ gtk_widget_size_request (GTK_WIDGET (group), &child_requisition);
+
+ if (n_items && (group->priv->expanded || group->priv->animation_timeout))
+ {
+ gint n_columns, n_rows, height;
+ GtkRequisition item_size;
+
+ egg_tool_item_group_get_item_size (group, &item_size);
+
+ n_columns = width / item_size.width;
+ n_rows = (n_items + n_columns - 1) / n_columns;
+ height = item_size.height * n_rows;
+
+ if (group->priv->animation_timeout)
+ {
+ gint64 timestamp = egg_tool_item_group_get_animation_timestamp (group);
+
+ timestamp = MIN (timestamp, ANIMATION_DURATION);
+
+ if (!group->priv->expanded)
+ timestamp = ANIMATION_DURATION - timestamp;
+
+ height = height * timestamp / ANIMATION_DURATION;
+ }
+
+ child_requisition.height += height;
+ }
+
+ return child_requisition.height;
+}
Modified: trunk/libegg/toolpalette/eggtoolitemgroup.h
==============================================================================
--- trunk/libegg/toolpalette/eggtoolitemgroup.h (original)
+++ trunk/libegg/toolpalette/eggtoolitemgroup.h Fri Jan 11 11:47:38 2008
@@ -50,7 +50,7 @@
};
GType egg_tool_item_group_get_type (void) G_GNUC_CONST;
-GtkWidget* egg_tool_item_group_new (const gchar *name);
+GtkWidget* egg_tool_item_group_new (const gchar *name);
void egg_tool_item_group_set_name (EggToolItemGroup *group,
const gchar *name);
Modified: trunk/libegg/toolpalette/eggtoolpalette.c
==============================================================================
--- trunk/libegg/toolpalette/eggtoolpalette.c (original)
+++ trunk/libegg/toolpalette/eggtoolpalette.c Fri Jan 11 11:47:38 2008
@@ -245,7 +245,6 @@
{
const gint border_width = GTK_CONTAINER (widget)->border_width;
EggToolPalette *palette = EGG_TOOL_PALETTE (widget);
- GtkRequisition child_requisition;
GtkAllocation child_allocation;
gint offset = 0;
guint i;
@@ -262,25 +261,18 @@
for (i = 0; i < palette->priv->groups->len; ++i)
{
EggToolItemGroup *group = egg_tool_palette_get_group (palette, i);
- gint n_items = egg_tool_item_group_get_n_items (group);
- if (!n_items)
- continue;
-
- gtk_widget_size_request (GTK_WIDGET (group), &child_requisition);
- child_allocation.height = child_requisition.height;
-
- if (egg_tool_item_group_get_expanded (group))
+ if (egg_tool_item_group_get_n_items (group))
{
- /* TODO: Use gtk_widget_get_height_for_width */
- gint n_columns = child_allocation.width / palette->priv->item_size.width;
- gint n_rows = (n_items + n_columns - 1) / n_columns;
+ child_allocation.height = _egg_tool_item_group_get_height_for_width (group, child_allocation.width);
- child_allocation.height += palette->priv->item_size.height * n_rows;
- }
+ gtk_widget_size_allocate (GTK_WIDGET (group), &child_allocation);
+ gtk_widget_show (GTK_WIDGET (group));
- gtk_widget_size_allocate (GTK_WIDGET (group), &child_allocation);
- child_allocation.y += child_allocation.height;
+ child_allocation.y += child_allocation.height;
+ }
+ else
+ gtk_widget_hide (GTK_WIDGET (group));
}
child_allocation.y += border_width;
@@ -301,19 +293,31 @@
egg_tool_palette_expose_event (GtkWidget *widget,
GdkEventExpose *event)
{
- EggToolPalette *palette = EGG_TOOL_PALETTE (widget);
+ EggToolPalette *palette = EGG_TOOL_PALETTE (widget);
+ GdkDisplay *display;
+ cairo_t *cr;
guint i;
if (GTK_WIDGET_CLASS (egg_tool_palette_parent_class)->expose_event (widget, event))
return TRUE;
+ display = gdk_drawable_get_display (widget->window);
+ if (!gdk_display_supports_composite (display))
+ return FALSE;
+
+ cr = gdk_cairo_create (widget->window);
+ cairo_push_group (cr);
+
for (i = 0; i < palette->priv->groups->len; ++i)
{
-/* TODO: draw composited window
EggToolItemGroup *group = egg_tool_palette_get_group (palette, i);
-*/
+ _egg_tool_item_group_paint (group, cr);
}
+ cairo_pop_group_to_source (cr);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
return FALSE;
}
Modified: trunk/libegg/toolpalette/eggtoolpaletteprivate.h
==============================================================================
--- trunk/libegg/toolpalette/eggtoolpaletteprivate.h (original)
+++ trunk/libegg/toolpalette/eggtoolpaletteprivate.h Fri Jan 11 11:47:38 2008
@@ -25,12 +25,16 @@
#include "eggtoolpalette.h"
#include "eggtoolitemgroup.h"
-void _egg_tool_palette_get_item_size (EggToolPalette *palette,
- GtkRequisition *item_size);
-void _egg_tool_palette_item_set_drag_source (GtkWidget *widget,
- gpointer data);
+void _egg_tool_palette_get_item_size (EggToolPalette *palette,
+ GtkRequisition *item_size);
+void _egg_tool_palette_item_set_drag_source (GtkWidget *widget,
+ gpointer data);
-void _egg_tool_item_group_item_size_request (EggToolItemGroup *group,
- GtkRequisition *item_size);
+void _egg_tool_item_group_item_size_request (EggToolItemGroup *group,
+ GtkRequisition *item_size);
+gint _egg_tool_item_group_get_height_for_width (EggToolItemGroup *group,
+ gint width);
+void _egg_tool_item_group_paint (EggToolItemGroup *group,
+ cairo_t *cr);
#endif /* __EGG_TOOL_PALETTE_PRIVATE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]