diff --git a/examples/Makefile.am b/examples/Makefile.am index d637ebecf..c1da143de 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -2,6 +2,7 @@ include $(top_srcdir)/build/autotools/Makefile.am.silent all_examples = \ basic-actor \ + box-layout \ canvas \ constraints \ drag-action \ diff --git a/examples/box-layout.c b/examples/box-layout.c new file mode 100644 index 000000000..5f71fb4ba --- /dev/null +++ b/examples/box-layout.c @@ -0,0 +1,301 @@ +/* + * Copyright 2009 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * Boston, MA 02111-1307, USA. + * + */ +#include +#include + +#define INSTRUCTIONS \ + "Press v\t\342\236\236\tSwitch horizontal/vertical\n" \ + "Press h\t\342\236\236\tSwitch homogeneous\n" \ + "Press p\t\342\236\236\tSwitch pack start/end\n" \ + "Press s\t\342\236\236\tIncrement spacing (up to 12px)\n" \ + "Press a\t\342\236\236\tSwitch animations on/off\n" \ + "Press +\t\342\236\236\tAdd a new actor\n" \ + "Press q\t\342\236\236\tQuit" + + +static const gchar * +get_align_name (ClutterActorAlign align) +{ + switch (align) + { + case CLUTTER_ACTOR_ALIGN_FILL: + return "fill"; + + case CLUTTER_ACTOR_ALIGN_START: + return "start"; + + case CLUTTER_ACTOR_ALIGN_CENTER: + return "center"; + + case CLUTTER_ACTOR_ALIGN_END: + return "end"; + + default: + g_assert_not_reached (); + } +} + +static gboolean +button_release_cb (ClutterActor *rect, + ClutterEvent *event, + gpointer user_data) +{ + ClutterActorAlign x_align, y_align; + gboolean x_expand, y_expand; + + g_object_get (rect, + "x-align", &x_align, + "y-align", &y_align, + "x-expand", &x_expand, + "y-expand", &y_expand, + NULL); + + switch (clutter_event_get_button (event)) + { + case CLUTTER_BUTTON_PRIMARY: + if (clutter_event_has_shift_modifier (event)) + { + if (y_align < 3) + y_align += 1; + else + y_align = 0; + break; + } + else + { + if (x_align < 3) + x_align += 1; + else + x_align = 0; + } + break; + + case CLUTTER_BUTTON_SECONDARY: + if (clutter_event_has_shift_modifier (event)) + y_expand = !y_expand; + else + x_expand = !x_expand; + break; + + default: + break; + } + + g_object_set (rect, + "x-align", x_align, + "y-align", y_align, + "x-expand", x_expand, + "y-expand", y_expand, + NULL); + return TRUE; +} + +static void +changed_cb (ClutterActor *actor, + GParamSpec *pspec, + ClutterActor *text) +{ + ClutterActorAlign x_align, y_align; + gboolean x_expand, y_expand; + gchar *label; + + g_object_get (actor, + "x-align", &x_align, + "y-align", &y_align, + "x-expand", &x_expand, + "y-expand", &y_expand, + NULL); + + label = g_strdup_printf ("%d,%d\n" + "%s\n%s", + x_expand, y_expand, + get_align_name (x_align), + get_align_name (y_align)); + clutter_text_set_text (CLUTTER_TEXT (text), label); + g_free (label); +} + +static void +add_actor (ClutterActor *box, + gint position) +{ + ClutterActor *rect, *text; + ClutterColor color; + ClutterLayoutManager *layout; + + clutter_color_from_hls (&color, + g_random_double_range (0.0, 360.0), + 0.5, + 0.5); + color.alpha = 255; + + layout = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER, + CLUTTER_BIN_ALIGNMENT_CENTER); + rect = clutter_actor_new (); + clutter_actor_set_layout_manager (rect, layout); + clutter_actor_set_background_color (rect, &color); + clutter_actor_set_reactive (rect, TRUE); + clutter_actor_set_size (rect, 32, 64); + clutter_actor_set_x_expand (rect, TRUE); + clutter_actor_set_y_expand (rect, TRUE); + clutter_actor_set_x_align (rect, CLUTTER_ACTOR_ALIGN_CENTER); + clutter_actor_set_y_align (rect, CLUTTER_ACTOR_ALIGN_CENTER); + + text = clutter_text_new_with_text ("Sans 8px", NULL); + clutter_text_set_line_alignment (CLUTTER_TEXT (text), + PANGO_ALIGN_CENTER); + clutter_actor_add_child (rect, text); + + g_signal_connect (rect, "button-release-event", + G_CALLBACK (button_release_cb), NULL); + g_signal_connect (rect, "notify::x-expand", + G_CALLBACK (changed_cb), text); + g_signal_connect (rect, "notify::y-expand", + G_CALLBACK (changed_cb), text); + g_signal_connect (rect, "notify::x-align", + G_CALLBACK (changed_cb), text); + g_signal_connect (rect, "notify::y-align", + G_CALLBACK (changed_cb), text); + changed_cb (rect, NULL, text); + + clutter_actor_insert_child_at_index (box, rect, position); +} + +static gboolean +key_release_cb (ClutterActor *stage, + ClutterEvent *event, + ClutterActor *box) +{ + ClutterBoxLayout *layout; + gboolean toggle; + guint spacing; + + layout = CLUTTER_BOX_LAYOUT (clutter_actor_get_layout_manager (box)); + + switch (clutter_event_get_key_symbol (event)) + { + case CLUTTER_KEY_a: + toggle = clutter_layout_manager_get_use_animations + (CLUTTER_LAYOUT_MANAGER (layout)); + clutter_layout_manager_set_use_animations + (CLUTTER_LAYOUT_MANAGER (layout), !toggle); + break; + + case CLUTTER_KEY_v: + { + ClutterOrientation orientation; + + orientation = clutter_box_layout_get_orientation (layout); + + if (orientation == CLUTTER_ORIENTATION_HORIZONTAL) + orientation = CLUTTER_ORIENTATION_VERTICAL; + else + orientation = CLUTTER_ORIENTATION_HORIZONTAL; + + clutter_box_layout_set_orientation (layout, orientation); + } + break; + + case CLUTTER_KEY_h: + toggle = clutter_box_layout_get_homogeneous (layout); + clutter_box_layout_set_homogeneous (layout, !toggle); + break; + + case CLUTTER_KEY_p: + toggle = clutter_box_layout_get_pack_start (layout); + clutter_box_layout_set_pack_start (layout, !toggle); + break; + + case CLUTTER_KEY_s: + spacing = clutter_box_layout_get_spacing (layout); + + if (spacing > 12) + spacing = 0; + else + spacing++; + + clutter_box_layout_set_spacing (layout, spacing); + break; + + case CLUTTER_KEY_plus: + add_actor (box, g_random_int_range (0, clutter_actor_get_n_children (box))); + break; + + case CLUTTER_KEY_q: + clutter_main_quit (); + break; + + default: + return FALSE; + } + + return TRUE; +} + +int +main (int argc, char *argv[]) +{ + ClutterActor *stage, *box, *instructions; + ClutterLayoutManager *layout; + gint i; + + if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) + return EXIT_FAILURE; + + stage = clutter_stage_new (); + clutter_stage_set_title (CLUTTER_STAGE (stage), "Box Layout"); + clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); + + /* make the stage a vbox */ + layout = clutter_box_layout_new (); + clutter_box_layout_set_orientation (CLUTTER_BOX_LAYOUT (layout), + CLUTTER_ORIENTATION_VERTICAL); + clutter_actor_set_layout_manager (stage, layout); + + box = clutter_actor_new (); + clutter_actor_set_background_color (box, CLUTTER_COLOR_LightGray); + clutter_actor_set_x_expand (box, TRUE); + clutter_actor_set_y_expand (box, TRUE); + layout = clutter_box_layout_new (); + clutter_layout_manager_set_use_animations (layout, TRUE); + clutter_actor_set_layout_manager (box, layout); + clutter_actor_add_child (stage, box); + + instructions = clutter_text_new_with_text ("Sans 12px", INSTRUCTIONS); + clutter_actor_set_x_expand (instructions, TRUE); + clutter_actor_set_y_expand (instructions, FALSE); + clutter_actor_set_x_align (instructions, CLUTTER_ACTOR_ALIGN_START); + clutter_actor_set_margin_top (instructions, 4); + clutter_actor_set_margin_left (instructions, 4); + clutter_actor_set_margin_bottom (instructions, 4); + clutter_actor_add_child (stage, instructions); + + for (i = 0; i < 5; i++) + add_actor (box, i); + + g_signal_connect (stage, "destroy", + G_CALLBACK (clutter_main_quit), NULL); + g_signal_connect (stage, "key-release-event", + G_CALLBACK (key_release_cb), box); + + clutter_actor_show (stage); + clutter_main (); + + return EXIT_SUCCESS; +} diff --git a/tests/interactive/Makefile.am b/tests/interactive/Makefile.am index 57737083e..3def7e167 100644 --- a/tests/interactive/Makefile.am +++ b/tests/interactive/Makefile.am @@ -38,7 +38,6 @@ UNIT_TESTS = \ test-cairo-clock.c \ test-cairo-flowers.c \ test-cogl-vertex-buffer.c \ - test-box-layout.c \ test-stage-sizing.c \ test-scrolling.c \ test-swipe-action.c \ diff --git a/tests/interactive/test-box-layout.c b/tests/interactive/test-box-layout.c deleted file mode 100644 index 210969be2..000000000 --- a/tests/interactive/test-box-layout.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright 2009 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU Lesser General Public License, - * version 2.1, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * Boston, MA 02111-1307, USA. - * - */ -#include -#include - -#include - -#include -#include -#include - -#define INSTRUCTIONS \ - "Press v\t\342\236\236\tSwitch horizontal/vertical\n" \ - "Press h\t\342\236\236\tSwitch homogeneous\n" \ - "Press p\t\342\236\236\tSwitch pack start/end\n" \ - "Press s\t\342\236\236\tIncrement spacing (up to 12px)\n" \ - "Press a\t\342\236\236\tSwitch animations on/off\n" \ - "Press q\t\342\236\236\tQuit" - -static ClutterActor *hover_actor = NULL; -static ClutterActor *box = NULL; -static ClutterActor *label = NULL; -static guint last_index = 0; - -static void -on_paint (ClutterActor *actor, - gpointer user_data) -{ - guint index_ = GPOINTER_TO_UINT (user_data); - gchar *text = g_strdup_printf ("%u", index_); - ClutterActorBox alloc = { 0, }; - CoglColor color; - gint layout_width, layout_height; - gfloat width, height; - PangoLayout *layout; - - clutter_actor_get_allocation_box (actor, &alloc); - clutter_actor_box_get_size (&alloc, &width, &height); - - layout = clutter_actor_create_pango_layout (actor, text); - pango_layout_get_size (layout, &layout_width, &layout_height); - - cogl_color_init_from_4ub (&color, 0, 0, 0, 255); - cogl_pango_render_layout (layout, - (width - (layout_width / 1024)) / 2, - (height - (layout_height / 1024)) / 2, - &color, 0); - - g_object_unref (layout); - g_free (text); -} - -static void -enter_event (ClutterActor *actor, - ClutterEvent *event, - gpointer data) -{ - clutter_rectangle_set_border_width (CLUTTER_RECTANGLE (actor), 2); - clutter_rectangle_set_border_color (CLUTTER_RECTANGLE (actor), - CLUTTER_COLOR_Black); - - hover_actor = actor; -} - -static void -leave_event (ClutterActor *actor, - ClutterEvent *event, - gpointer data) -{ - clutter_rectangle_set_border_width (CLUTTER_RECTANGLE (actor), 0); - - hover_actor = NULL; -} - -static gboolean -button_release_event (ClutterActor *actor, - ClutterEvent *event, - ClutterBoxLayout *layout) -{ - gboolean xfill, yfill; - ClutterBoxAlignment xalign, yalign; - gint button; - - button = clutter_event_get_button (event); - - if (button == CLUTTER_BUTTON_PRIMARY) - { - clutter_box_layout_get_fill (layout, actor, &xfill, &yfill); - clutter_box_layout_set_fill (layout, actor, - xfill ? FALSE : TRUE, - yfill ? FALSE : TRUE); - } - else - { - clutter_box_layout_get_alignment (layout, actor, &xalign, &yalign); - - if (xalign < 2) - xalign += 1; - else - xalign = 0; - - if (yalign < 2) - yalign += 1; - else - yalign = 0; - - clutter_box_layout_set_alignment (layout, actor, xalign, yalign); - } - - return TRUE; -} - -static void -add_actor (ClutterBoxLayout *layout, - guint index_) -{ - ClutterActor *rect; - static gboolean expand = TRUE; - ClutterColor color; - - clutter_color_from_hls (&color, - g_random_double_range (0.0, 360.0), - 0.5, - 0.5); - color.alpha = 255; - - rect = clutter_rectangle_new_with_color (&color); - clutter_actor_set_size (rect, 32, 64); - clutter_box_layout_pack (layout, rect, expand, - FALSE, /* x-fill */ - FALSE, /* y-fill */ - CLUTTER_BOX_ALIGNMENT_CENTER, - CLUTTER_BOX_ALIGNMENT_CENTER); - - clutter_actor_set_reactive (rect, TRUE); - g_signal_connect_after (rect, "paint", - G_CALLBACK (on_paint), - GUINT_TO_POINTER (index_)); - g_signal_connect (rect, "enter-event", G_CALLBACK (enter_event), NULL); - g_signal_connect (rect, "leave-event", G_CALLBACK (leave_event), NULL); - g_signal_connect (rect, "button-release-event", - G_CALLBACK (button_release_event), - layout); - - expand = !expand; -} - -static gboolean -key_release_cb (ClutterActor *actor, - ClutterEvent *event, - ClutterBoxLayout *layout) -{ - gboolean toggle; - guint spacing; - - switch (clutter_event_get_key_symbol (event)) - { - case CLUTTER_KEY_a: - toggle = clutter_box_layout_get_use_animations (layout); - clutter_box_layout_set_use_animations (layout, !toggle); - break; - - case CLUTTER_KEY_v: - { - ClutterOrientation orientation; - - orientation = clutter_box_layout_get_orientation (layout); - - if (orientation == CLUTTER_ORIENTATION_HORIZONTAL) - orientation = CLUTTER_ORIENTATION_VERTICAL; - else - orientation = CLUTTER_ORIENTATION_HORIZONTAL; - - clutter_box_layout_set_orientation (layout, orientation); - } - break; - - case CLUTTER_KEY_h: - toggle = clutter_box_layout_get_homogeneous (layout); - clutter_box_layout_set_homogeneous (layout, !toggle); - break; - - case CLUTTER_KEY_p: - toggle = clutter_box_layout_get_pack_start (layout); - clutter_box_layout_set_pack_start (layout, !toggle); - break; - - case CLUTTER_KEY_s: - spacing = clutter_box_layout_get_spacing (layout); - - if (spacing > 12) - spacing = 0; - else - spacing++; - - clutter_box_layout_set_spacing (layout, spacing); - break; - - case CLUTTER_KEY_plus: - add_actor (layout, last_index++); - break; - - case CLUTTER_KEY_q: - clutter_main_quit (); - break; - - default: - return FALSE; - } - - return TRUE; -} - -static void -stage_size_changed_cb (ClutterActor *stage, - const ClutterActorBox *allocation, - ClutterAllocationFlags flags, - gpointer dummy G_GNUC_UNUSED) -{ - gfloat width, height; - - clutter_actor_box_get_size (allocation, &width, &height); - clutter_actor_set_size (box, width - 100, height - 100); - - clutter_actor_set_y (label, - height - clutter_actor_get_height (label) - 8); -} - -G_MODULE_EXPORT int -test_box_layout_main (int argc, char *argv[]) -{ - ClutterActor *stage; - ClutterLayoutManager *layout; - gint i; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Box Layout"); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); - clutter_actor_set_size (stage, 640, 480); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - layout = clutter_box_layout_new (); - - box = clutter_box_new (layout); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), box); - - for (i = 0; i < 5; i++) - add_actor (CLUTTER_BOX_LAYOUT (layout), last_index++); - - g_signal_connect (stage, "key-release-event", - G_CALLBACK (key_release_cb), - layout); - g_signal_connect (stage, "allocation-changed", - G_CALLBACK (stage_size_changed_cb), - NULL); - - label = clutter_text_new_with_text ("Sans 12px", INSTRUCTIONS); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), label); - clutter_actor_set_y (label, - 480 - clutter_actor_get_height (label) - 8); - - clutter_actor_show (stage); - - clutter_main (); - - return EXIT_SUCCESS; -} - -G_MODULE_EXPORT const char * -test_box_layout_describe (void) -{ - return "BoxLayout layout manager example"; -}