|
| 1 | +/* |
| 2 | + * Copyright (c) 2010, Intel Corporation. |
| 3 | + * |
| 4 | + * This program is free software; you can redistribute it and/or modify it |
| 5 | + * under the terms and conditions of the GNU General Public License, |
| 6 | + * version 2, as published by the Free Software Foundation. |
| 7 | + * |
| 8 | + * This program is distributed in the hope it will be useful, but WITHOUT |
| 9 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 10 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| 11 | + * more details. |
| 12 | + * |
| 13 | + * You should have received a copy of the GNU General Public License along with |
| 14 | + * this program; if not, write to the Free Software Foundation, Inc., |
| 15 | + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
| 16 | + * |
| 17 | + * Author: Rob Staudinger <robsta@linux.intel.com> |
| 18 | + */ |
| 19 | + |
| 20 | +#include <stdbool.h> |
| 21 | +#include <stdlib.h> |
| 22 | +#include <mx/mx.h> |
| 23 | +#include "foo-object-store.h" |
| 24 | +#include "foo-test-object.h" |
| 25 | + |
| 26 | +typedef struct |
| 27 | +{ |
| 28 | + ClutterActor *view; |
| 29 | + MxEntry *entry; |
| 30 | + ClutterModel *store; |
| 31 | +} ObjectStoreTest; |
| 32 | + |
| 33 | +/* |
| 34 | + * Look up item by index. |
| 35 | + * Returned object needs to be g_object_unref'd. |
| 36 | + * May return NULL. |
| 37 | + */ |
| 38 | +FooTestObject * |
| 39 | +store_get_object (ClutterModel *store, |
| 40 | + unsigned index) |
| 41 | +{ |
| 42 | + ClutterModelIter *iter; |
| 43 | + FooTestObject *object = NULL; |
| 44 | + |
| 45 | + iter = clutter_model_get_iter_at_row (store, index); |
| 46 | + if (iter && |
| 47 | + !clutter_model_iter_is_last (iter)) |
| 48 | + { |
| 49 | + /* Column #0 of the model holds the actual object. */ |
| 50 | + clutter_model_iter_get (iter, |
| 51 | + 0, &object, |
| 52 | + -1); |
| 53 | + } |
| 54 | + |
| 55 | + return object; |
| 56 | +} |
| 57 | + |
| 58 | +/* |
| 59 | + * Add object to the store. |
| 60 | + */ |
| 61 | +static void |
| 62 | +store_add_object (ClutterModel *store, |
| 63 | + char const *text) |
| 64 | +{ |
| 65 | + FooTestObject *object; |
| 66 | + |
| 67 | + object = foo_test_object_new (); |
| 68 | + foo_test_object_set_text (object, text); |
| 69 | + |
| 70 | + /* Column #0 holds the actual object, the other cols are mapped to |
| 71 | + * its properties. */ |
| 72 | + clutter_model_append (store, 0, object, -1); |
| 73 | + g_object_unref (object); |
| 74 | +} |
| 75 | + |
| 76 | +static void |
| 77 | +_update_clicked (MxButton *button, |
| 78 | + ObjectStoreTest *app) |
| 79 | +{ |
| 80 | + char const *input; |
| 81 | + |
| 82 | + input = mx_entry_get_text (app->entry); |
| 83 | + if (input == NULL || |
| 84 | + input[0] == '\0') |
| 85 | + { |
| 86 | + g_warning ("Please enter text"); |
| 87 | + return; |
| 88 | + |
| 89 | + } else if (input[0] == '-') { |
| 90 | + |
| 91 | + /* Remove item */ |
| 92 | + int index = g_ascii_isdigit (input[1]) ? |
| 93 | + atoi (&input[1]) : |
| 94 | + -1; |
| 95 | + if (index < 0) |
| 96 | + { |
| 97 | + g_warning ("Invalid number, can not remove"); |
| 98 | + return; |
| 99 | + } |
| 100 | + |
| 101 | + clutter_model_remove (app->store, index); |
| 102 | + |
| 103 | + } else if (g_ascii_isdigit (input[0])) { |
| 104 | + |
| 105 | + /* Update item */ |
| 106 | + unsigned index = atoi (input); |
| 107 | + char **tokens = g_strsplit (input, ":", 2); |
| 108 | + char const *text = tokens[1]; |
| 109 | + FooTestObject *object = store_get_object (app->store, index); |
| 110 | + |
| 111 | + if (object == NULL) |
| 112 | + { |
| 113 | + g_warning ("Failed to find object"); |
| 114 | + return; |
| 115 | + } |
| 116 | + |
| 117 | + foo_test_object_set_text (FOO_TEST_OBJECT (object), text); |
| 118 | + g_object_unref (object); |
| 119 | + |
| 120 | + } else { |
| 121 | + |
| 122 | + /* Add item */ |
| 123 | + store_add_object (app->store, input); |
| 124 | + } |
| 125 | + |
| 126 | + mx_entry_set_text (app->entry, ""); |
| 127 | +} |
| 128 | + |
| 129 | +static void |
| 130 | +_dump_clicked (MxButton *button, |
| 131 | + ObjectStoreTest *app) |
| 132 | +{ |
| 133 | + ClutterModelIter *iter; |
| 134 | + |
| 135 | + for (iter = clutter_model_get_first_iter (app->store); |
| 136 | + !clutter_model_iter_is_last (iter); |
| 137 | + iter = clutter_model_iter_next (iter)) |
| 138 | + { |
| 139 | + FooTestObject *object = NULL; |
| 140 | + char *text = NULL; |
| 141 | + |
| 142 | + clutter_model_iter_get (iter, |
| 143 | + 0, &object, |
| 144 | + 1, &text, |
| 145 | + -1); |
| 146 | + g_debug ("%p %s\n", object, text); |
| 147 | + g_object_unref (object); |
| 148 | + g_free (text); |
| 149 | + } |
| 150 | +} |
| 151 | + |
| 152 | +int |
| 153 | +main (int argc, |
| 154 | + char **argv) |
| 155 | +{ |
| 156 | + ClutterActor *stage; |
| 157 | + MxBoxLayout *vbox; |
| 158 | + MxBoxLayout *hbox; |
| 159 | + ClutterActor *button; |
| 160 | + ClutterActor *label; |
| 161 | + ObjectStoreTest app = { 0, }; |
| 162 | + |
| 163 | + clutter_init (&argc, &argv); |
| 164 | + |
| 165 | + stage = clutter_stage_get_default (); |
| 166 | + clutter_actor_set_size (stage, 320.0, 240.0); |
| 167 | + |
| 168 | + vbox = (MxBoxLayout *) mx_box_layout_new (); |
| 169 | + clutter_actor_set_size (CLUTTER_ACTOR (vbox), 320.0, 240.0); |
| 170 | + mx_box_layout_set_orientation (vbox, MX_ORIENTATION_VERTICAL); |
| 171 | + clutter_container_add_actor (CLUTTER_CONTAINER (stage), CLUTTER_ACTOR (vbox)); |
| 172 | + |
| 173 | + /* Create model */ |
| 174 | + app.store = foo_object_store_new (2, |
| 175 | + FOO_TYPE_TEST_OBJECT, "foo", /* column #0 */ |
| 176 | + G_TYPE_STRING, "text"); /* column #1 */ |
| 177 | + |
| 178 | + /* |
| 179 | + * Create view |
| 180 | + */ |
| 181 | + app.view = mx_list_view_new (); |
| 182 | + |
| 183 | + /* Use MxButton to render the model's items */ |
| 184 | + mx_list_view_set_item_type (MX_LIST_VIEW (app.view), MX_TYPE_BUTTON); |
| 185 | + |
| 186 | + /* Map column #1 to attribute "label" of view's GtkButton */ |
| 187 | + mx_list_view_add_attribute (MX_LIST_VIEW (app.view), "label", 1); |
| 188 | + |
| 189 | + /* Connect to model */ |
| 190 | + mx_list_view_set_model (MX_LIST_VIEW (app.view), app.store); |
| 191 | + |
| 192 | + mx_box_layout_add_actor_with_properties (vbox, app.view, -1, |
| 193 | + "expand", true, |
| 194 | + "x-fill", true, |
| 195 | + "y-fill", true, |
| 196 | + NULL); |
| 197 | + |
| 198 | + hbox = (MxBoxLayout *) mx_box_layout_new (); |
| 199 | + mx_box_layout_set_orientation (hbox, MX_ORIENTATION_HORIZONTAL); |
| 200 | + mx_box_layout_add_actor_with_properties (vbox, CLUTTER_ACTOR (hbox), -1, |
| 201 | + "expand", false, |
| 202 | + "x-fill", true, |
| 203 | + NULL); |
| 204 | + |
| 205 | + app.entry = (MxEntry *) mx_entry_new (); |
| 206 | + mx_box_layout_add_actor_with_properties (hbox, CLUTTER_ACTOR (app.entry), -1, |
| 207 | + "expand", true, |
| 208 | + "x-fill", true, |
| 209 | + NULL); |
| 210 | + |
| 211 | + button = mx_button_new_with_label ("Update"); |
| 212 | + g_signal_connect (button, "clicked", |
| 213 | + G_CALLBACK (_update_clicked), &app); |
| 214 | + clutter_container_add_actor (CLUTTER_CONTAINER (hbox), button); |
| 215 | + |
| 216 | + button = mx_button_new_with_label ("Dump"); |
| 217 | + g_signal_connect (button, "clicked", |
| 218 | + G_CALLBACK (_dump_clicked), &app); |
| 219 | + clutter_container_add_actor (CLUTTER_CONTAINER (hbox), button); |
| 220 | + |
| 221 | + label = mx_label_new_with_text ("Enter text and update to add item\n" |
| 222 | + "Enter <number>:<text> to change item <number>\n" |
| 223 | + "Enter -<number> to delete item <number>"); |
| 224 | + clutter_container_add_actor (CLUTTER_CONTAINER (vbox), label); |
| 225 | + |
| 226 | + clutter_actor_show_all (stage); |
| 227 | + clutter_main (); |
| 228 | + |
| 229 | + return EXIT_SUCCESS; |
| 230 | +} |
0 commit comments