diff options
author | Danielle Madeley <danielle.madeley@collabora.co.uk> | 2009-08-25 13:01:28 +1000 |
---|---|---|
committer | Danielle Madeley <danielle.madeley@collabora.co.uk> | 2009-11-18 12:17:16 +1100 |
commit | 016bee66ba2a247bff7fd907e796b673ddb5a149 (patch) | |
tree | 1b266bff96b7903adb95ed1366b5ec16aec028fe /examples | |
parent | 33f486548e9aa1b22df8c23d1cc451525c7d9988 (diff) | |
download | clutter-gtk-016bee66ba2a247bff7fd907e796b673ddb5a149.tar.gz |
Animated Notebook example
Diffstat (limited to 'examples')
-rw-r--r-- | examples/Makefile.am | 9 | ||||
-rw-r--r-- | examples/animated-notebook.c | 195 | ||||
-rw-r--r-- | examples/animated-notebook.ui | 293 |
3 files changed, 496 insertions, 1 deletions
diff --git a/examples/Makefile.am b/examples/Makefile.am index a463e6a..bf56a46 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -3,6 +3,7 @@ include $(top_srcdir)/build/autotools/Makefile.am.silent NULL = noinst_PROGRAMS = \ + animated-notebook \ gtk-clutter-events \ gtk-clutter-multistage \ gtk-clutter-standin-test \ @@ -26,6 +27,10 @@ common_ldadd = \ $(CLUTTER_LIBS) \ $(GTK_LIBS) +animated_notebook_SOURCES = animated-notebook.c +animated_notebook_DEPENDENCIES = $(common_deps) +animated_notebook_LDADD = $(common_ldadd) + gtk_clutter_test_SOURCES = gtk-clutter-test.c gtk_clutter_test_DEPENDENCIES = $(common_deps) gtk_clutter_test_LDADD = $(common_ldadd) @@ -66,4 +71,6 @@ reparenting_test_SOURCES = reparenting-test.c reparenting_test_DEPENDENCIES = $(common_deps) reparenting_test_LDADD = $(common_ldadd) -EXTRA_DIST = redhand.png +EXTRA_DIST = \ + animated-notebook.ui \ + redhand.png diff --git a/examples/animated-notebook.c b/examples/animated-notebook.c new file mode 100644 index 0000000..ae32013 --- /dev/null +++ b/examples/animated-notebook.c @@ -0,0 +1,195 @@ +/* Animated Notebook Demonstration + * + * (c) 2009, Collabora Ltd. + * + * Written by Davyd Madeley <davyd.madeley@collabora.co.uk> + */ + +#include <gtk/gtk.h> +#include <clutter/clutter.h> +#include <clutter-gtk/clutter-gtk.h> + +static void +animation_complete (ClutterTimeline *timeline, ClutterActor *actor) +{ + /* reparent the page into the gtkalignment, because we don't need + * 1 million actors lying around */ + GtkWidget *bin = gtk_clutter_actor_get_widget (GTK_CLUTTER_ACTOR (actor)); + GtkWidget *page = gtk_bin_get_child (GTK_BIN (bin)); + GtkWidget *parent = GTK_WIDGET (g_object_get_data (G_OBJECT (page), + "future-parent")); + + // gtk_clutter_actor_set_ignore_damage (GTK_CLUTTER_ACTOR (actor), FALSE); + gtk_widget_reparent (page, parent); + clutter_actor_destroy (actor); +} + +static void +page_removed (ClutterTimeline *timeline, ClutterActor *actor) +{ + GtkWidget *bin = gtk_clutter_actor_get_widget (GTK_CLUTTER_ACTOR (actor)); + GtkWidget *page = gtk_bin_get_child (GTK_BIN (bin)); + + /* remove this page from the bin so it doesn't get disposed */ + gtk_container_remove (GTK_CONTAINER (bin), page); + clutter_actor_destroy (actor); +} + +static void +page_changed (GtkTreeSelection *selection, GtkBuilder *ui) +{ + /* the page has probably been changed */ + + GtkTreeModel *model; + GtkTreeIter iter; + gtk_tree_selection_get_selected (selection, &model, &iter); + + GtkWidget *page; + gtk_tree_model_get (model, &iter, + 2, &page, + -1); + + g_return_if_fail (GTK_IS_WIDGET (page)); + + /* get the event box */ + GtkWidget *bin = GTK_WIDGET (gtk_builder_get_object (ui, "page-box")); + + if (gtk_bin_get_child (GTK_BIN (bin)) == page) + { + g_object_unref (page); + return; + } + + /* get the ClutterStage */ + GtkWidget *treeview = GTK_WIDGET (gtk_tree_selection_get_tree_view (selection)); + GtkWidget *toplevel = gtk_widget_get_toplevel (treeview); + + g_return_if_fail (GTK_CLUTTER_IS_WINDOW (toplevel)); + + ClutterActor *stage = gtk_clutter_window_get_stage ( + GTK_CLUTTER_WINDOW (toplevel)); + + /* unparent the old child into an actor */ + ClutterActor *actor = gtk_clutter_actor_new (); + gtk_widget_reparent (gtk_bin_get_child (GTK_BIN (bin)), + gtk_clutter_actor_get_widget (GTK_CLUTTER_ACTOR (actor))); + + clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor); + ClutterAnimation *animation = clutter_actor_animate (actor, + CLUTTER_EASE_OUT_SINE, 500, + "fixed::x", (float) bin->allocation.x, + "fixed::y", (float) bin->allocation.y, + "fixed::scale-gravity", CLUTTER_GRAVITY_CENTER, + "scale-x", 0., + "scale-y", 0., + "opacity", 0x0, + NULL); + + g_signal_connect_after (clutter_animation_get_timeline (animation), + "completed", + G_CALLBACK (page_removed), + actor); + + /* put the page onto a GtkClutterActor */ + actor = gtk_clutter_actor_new (); + gtk_container_add (GTK_CONTAINER (gtk_clutter_actor_get_widget ( + GTK_CLUTTER_ACTOR (actor))), page); + g_object_unref (page); + + clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor); + + /* get the initial position */ + GdkRectangle rect; + GtkTreeViewColumn *column = gtk_tree_view_get_column ( + GTK_TREE_VIEW (treeview), 0); + GtkTreePath *path = gtk_tree_model_get_path (model, &iter); + gtk_tree_view_get_cell_area (GTK_TREE_VIEW (treeview), path, column, + &rect); + gtk_tree_path_free (path); + + gtk_tree_view_convert_tree_to_widget_coords (GTK_TREE_VIEW (treeview), + rect.x + rect.width, + rect.y, + &rect.x, + &rect.y); + + g_object_set_data (G_OBJECT (page), "future-parent", bin); + + /* animate the actor to expand from the initial position to the final + * position (the allocation of the GtkEventBox) */ + animation = clutter_actor_animate (actor, + CLUTTER_EASE_IN_SINE, 700, + "fixed::x", (float) rect.x, + "fixed::y", (float) rect.y, + "fixed::scale-x", 0., + "fixed::scale-y", (float) rect.height / (float) bin->allocation.height, + "fixed::scale-gravity", CLUTTER_GRAVITY_NORTH_WEST, + "x", (float) bin->allocation.x, + "y", (float) bin->allocation.y, + "scale-x", 1., + "scale-y", 1., + NULL); + + g_signal_connect_after (clutter_animation_get_timeline (animation), + "completed", + G_CALLBACK (animation_complete), + actor); +} + +int +main (int argc, char **argv) +{ + GError *error = NULL; + + gtk_clutter_init (&argc, &argv); + + GtkBuilder *ui = gtk_builder_new (); + gtk_builder_add_from_file (ui, "animated-notebook.ui", &error); + if (error) g_error ("%s", error->message); + + /* iterate the model, load each of the pages */ + GtkTreeModel *model = GTK_TREE_MODEL (gtk_builder_get_object (ui, + "pages-store")); + GtkTreeIter iter; + gboolean valid; + for (valid = gtk_tree_model_get_iter_first (model, &iter); + valid; + valid = gtk_tree_model_iter_next (model, &iter)) + { + char *ui_name; + gtk_tree_model_get (model, &iter, + 1, &ui_name, + -1); + + g_print ("Looking up %s\n", ui_name); + + GtkWidget *page = GTK_WIDGET (gtk_builder_get_object (ui, ui_name)); + gtk_list_store_set (GTK_LIST_STORE (model), &iter, + 2, page, + -1); + + g_object_weak_ref (G_OBJECT (page), (GWeakNotify) g_print, + g_strdup_printf ("Finalised %s (%%p)\n", ui_name)); + + g_free (ui_name); + } + + /* construct the toplevel UI */ + GtkWidget *window = gtk_clutter_window_new (); + GtkWidget *hbox = GTK_WIDGET (gtk_builder_get_object (ui, + "main-window-toplevel")); + gtk_container_add (GTK_CONTAINER (window), hbox); + + /* Glade doesn't expose GtkTreeSelection */ + GtkWidget *treeview = GTK_WIDGET (gtk_builder_get_object (ui, + "page-treeview")); + g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)), + "changed", + G_CALLBACK (page_changed), + ui); + + gtk_widget_show_all (window); + gtk_main (); + + return 0; +} diff --git a/examples/animated-notebook.ui b/examples/animated-notebook.ui new file mode 100644 index 0000000..d408a8e --- /dev/null +++ b/examples/animated-notebook.ui @@ -0,0 +1,293 @@ +<?xml version="1.0"?> +<interface> + <requires lib="gtk+" version="2.16"/> + <!-- interface-naming-policy project-wide --> + <object class="GtkListStore" id="pages-store"> + <columns> + <!-- column-name page-name --> + <column type="gchararray"/> + <!-- column-name ui-name --> + <column type="gchararray"/> + <!-- column-name widget --> + <column type="GObject"/> + </columns> + <data> + <row> + <col id="0" translatable="yes">Page 1</col> + <col id="1" translatable="yes">page-1</col> + <col id="2"/> + </row> + <row> + <col id="0" translatable="yes">Page 2</col> + <col id="1" translatable="yes">page-2</col> + <col id="2"/> + </row> + <row> + <col id="0" translatable="yes">Page 3</col> + <col id="1" translatable="yes">page-3</col> + <col id="2"/> + </row> + </data> + </object> + <object class="GtkHBox" id="main-window-toplevel"> + <property name="visible">True</property> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">never</property> + <property name="vscrollbar_policy">automatic</property> + <child> + <object class="GtkTreeView" id="page-treeview"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="model">pages-store</property> + <child> + <object class="GtkTreeViewColumn" id="treeviewcolumn1"> + <property name="title">Page Name</property> + <child> + <object class="GtkCellRendererText" id="cellrenderertext1"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="page-box"> + <property name="visible">True</property> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> + </object> + <object class="GtkTable" id="page-1"> + <property name="visible">True</property> + <property name="n_rows">4</property> + <property name="n_columns">2</property> + <property name="column_spacing">6</property> + <property name="row_spacing">3</property> + <child> + <object class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Property 1:</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label2"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Property 2:</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label3"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Property 3:</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label4"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Property 4:</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combobox1"> + <property name="visible">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + </packing> + </child> + <child> + <object class="GtkHScale" id="hscale1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combobox2"> + <property name="visible">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="spinbutton1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">●</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + </packing> + </child> + </object> + <object class="GtkVBox" id="page-2"> + <property name="visible">True</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkFrame" id="frame1"> + <property name="visible">True</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkAlignment" id="alignment1"> + <property name="visible">True</property> + <property name="left_padding">12</property> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">automatic</property> + <property name="shadow_type">etched-in</property> + <child> + <object class="GtkTreeView" id="treeview2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + </child> + </object> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="label1a"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Page 2</b></property> + <property name="use_markup">True</property> + </object> + </child> + </object> + <packing> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkHButtonBox" id="hbuttonbox1"> + <property name="visible">True</property> + <property name="layout_style">end</property> + <child> + <object class="GtkButton" id="button1"> + <property name="label" translatable="yes">gtk-add</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="button2"> + <property name="label" translatable="yes">gtk-remove</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="button3"> + <property name="label" translatable="yes">gtk-clear</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> + </packing> + </child> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> + <child> + <placeholder/> + </child> + </object> + <object class="GtkImage" id="page-3"> + <property name="visible">True</property> + <property name="pixbuf">redhand.png</property> + </object> + <object class="GtkSizeGroup" id="sizegroup1"> + <property name="mode">both</property> + <widgets> + <widget name="page-box"/> + <widget name="page-1"/> + <widget name="page-2"/> + <widget name="page-3"/> + </widgets> + </object> +</interface> |