2 #include "wh-slider-menu.h"
4 #define CSW() CLUTTER_STAGE_WIDTH()
5 #define CSH() CLUTTER_STAGE_HEIGHT()
7 #define SELECTED_OFFSET (CLUTTER_STAGE_WIDTH()/5)
9 typedef struct WoohaaSliderMenuEntry
12 WoohaaSliderMenuSelectedFunc selected_func;
16 WoohaaSliderMenuEntry;
18 #define WOOHAA_TYPE_BEHAVIOUR_SLIDER (clutter_behaviour_slider_get_type ())
20 #define WOOHAA_BEHAVIOUR_SLIDER(obj) \
21 (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
22 WOOHAA_TYPE_BEHAVIOUR_SLIDER, WoohaaBehaviourSlider))
24 #define WOOHAA_BEHAVIOUR_SLIDER_CLASS(klass) \
25 (G_TYPE_CHECK_CLASS_CAST ((klass), \
26 WOOHAA_TYPE_BEHAVIOUR_SLIDER, WoohaaBehaviourSliderClass))
28 #define CLUTTER_IS_BEHAVIOUR_SLIDER(obj) \
29 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
30 WOOHAA_TYPE_BEHAVIOUR_SLIDER))
32 #define CLUTTER_IS_BEHAVIOUR_SLIDER_CLASS(klass) \
33 (G_TYPE_CHECK_CLASS_TYPE ((klass), \
34 WOOHAA_TYPE_BEHAVIOUR_SLIDER))
36 #define WOOHAA_BEHAVIOUR_SLIDER_GET_CLASS(obj) \
37 (G_TYPE_INSTANCE_GET_CLASS ((obj), \
38 WOOHAA_TYPE_BEHAVIOUR_SLIDER, WoohaaBehaviourSliderClass))
40 typedef struct _WoohaaBehaviourSlider WoohaaBehaviourSlider;
41 typedef struct _WoohaaBehaviourSliderClass WoohaaBehaviourSliderClass;
43 struct _WoohaaBehaviourSlider
45 ClutterBehaviour parent;
46 WoohaaSliderMenuEntry *old;
47 WoohaaSliderMenuEntry *new;
48 WoohaaSliderMenu *menu;
51 struct _WoohaaBehaviourSliderClass
53 ClutterBehaviourClass parent_class;
56 GType clutter_behaviour_slider_get_type (void) G_GNUC_CONST;
58 G_DEFINE_TYPE (WoohaaBehaviourSlider, clutter_behaviour_slider, CLUTTER_TYPE_BEHAVIOUR);
60 static ClutterBehaviour*
61 clutter_behaviour_slider_new (WoohaaSliderMenu *menu,
62 WoohaaSliderMenuEntry *start,
63 WoohaaSliderMenuEntry *end);
65 struct _WoohaaSliderMenuPrivate
71 gint active_entry_num;
72 gint offset; /* current offset */
75 ClutterActor *entry_group;
79 ClutterTimeline *timeline;
81 ClutterBehaviour *behave;
82 ClutterEffectTemplate *effect_template;
85 ClutterColor *font_color;
86 ClutterActor *next, *prev;
89 G_DEFINE_TYPE (WoohaaSliderMenu, woohaa_slider_menu, CLUTTER_TYPE_ACTOR);
91 #define WOOHAA_SLIDER_MENU_GET_PRIVATE(obj) \
92 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), WOOHAA_TYPE_SLIDER_MENU, WoohaaSliderMenuPrivate))
95 woohaa_slider_menu_dispose (GObject *object)
97 WoohaaSliderMenu *self;
98 WoohaaSliderMenuPrivate *priv;
100 self = WOOHAA_SLIDER_MENU(object);
103 G_OBJECT_CLASS (woohaa_slider_menu_parent_class)->dispose (object);
107 woohaa_slider_menu_finalize (GObject *object)
109 WoohaaSliderMenu *self;
110 WoohaaSliderMenuPrivate *priv;
112 self = WOOHAA_SLIDER_MENU(object);
115 G_OBJECT_CLASS (woohaa_slider_menu_parent_class)->finalize (object);
119 woohaa_slider_menu_paint (ClutterActor *actor)
121 WoohaaSliderMenuPrivate *priv = (WOOHAA_SLIDER_MENU (actor))->priv;
123 clutter_actor_paint (priv->bg);
124 clutter_actor_paint (priv->next);
125 clutter_actor_paint (priv->prev);
126 clutter_actor_paint (priv->entry_group);
130 woohaa_slider_menu_get_preferred_width (ClutterActor *actor,
131 ClutterUnit for_height,
132 ClutterUnit *min_width_p,
133 ClutterUnit *natural_width_p)
135 *min_width_p = CLUTTER_UNITS_FROM_INT (100);
136 *natural_width_p = CLUTTER_UNITS_FROM_INT (CSW());
140 woohaa_slider_menu_get_preferred_height (ClutterActor *actor,
141 ClutterUnit for_width,
142 ClutterUnit *min_height_p,
143 ClutterUnit *natural_height_p)
145 WoohaaSliderMenuPrivate *priv = (WOOHAA_SLIDER_MENU (actor))->priv;
147 *min_height_p = CLUTTER_UNITS_FROM_INT (1);
148 if (priv->entry_height)
149 *natural_height_p = CLUTTER_UNITS_FROM_INT (priv->entry_height * 2);
151 *natural_height_p = CLUTTER_UNITS_FROM_INT (200);
155 woohaa_slider_menu_allocate (ClutterActor *actor,
156 const ClutterActorBox *box,
157 gboolean absolute_origin_changed)
159 WoohaaSliderMenuPrivate *priv = (WOOHAA_SLIDER_MENU (actor))->priv;
160 ClutterUnit natural_width, natural_height;
161 ClutterActorBox child_box;
162 ClutterUnit focal_x, focal_y;
163 ClutterUnit entry_offset = 0, entry_width = 0;
164 WoohaaSliderMenuEntry *current, *old;
166 clutter_actor_get_preferred_size (priv->bg, NULL, NULL,
167 &natural_width, &natural_height);
170 child_box.x2 = natural_width;
171 child_box.y2 = natural_height;
172 clutter_actor_allocate (priv->bg, &child_box, absolute_origin_changed);
174 focal_x = CLUTTER_UNITS_FROM_INT(CSW()/4);
179 current = (WOOHAA_BEHAVIOUR_SLIDER (priv->behave))->new;
180 old = (WOOHAA_BEHAVIOUR_SLIDER (priv->behave))->old;
184 entry_offset = (clutter_actor_get_xu (current->actor) - clutter_actor_get_xu (old->actor)) *
185 ((gdouble)(priv->alpha_value) / (gdouble)CLUTTER_ALPHA_MAX_ALPHA) +
186 clutter_actor_get_xu (old->actor);
188 entry_width = (clutter_actor_get_widthu (current->actor) - clutter_actor_get_widthu (old->actor)) *
189 ((gdouble)(priv->alpha_value) / (gdouble)CLUTTER_ALPHA_MAX_ALPHA) +
190 clutter_actor_get_widthu (old->actor);
195 child_box.x1 = focal_x - entry_offset;
196 child_box.y1 = focal_y;
197 child_box.x2 = natural_height/2 + child_box.x1 - entry_offset;
198 child_box.y2 = natural_height/2 + child_box.y1;
199 clutter_actor_allocate (priv->entry_group,
201 absolute_origin_changed);
203 if (priv->active_entry_num > 0)
205 clutter_actor_set_opacity (priv->prev, 0xAA);
207 child_box.x1 = focal_x - natural_height/2;
208 child_box.y1 = focal_y + natural_height/10;
209 child_box.x2 = natural_height/2 + child_box.x1;
210 child_box.y2 = natural_height/2 + child_box.y1;
211 clutter_actor_allocate (priv->prev, &child_box, absolute_origin_changed);
215 clutter_actor_set_opacity (priv->prev,
216 0xff + (priv->alpha_value * (-0xff)
217 / CLUTTER_ALPHA_MAX_ALPHA));
220 if (priv->active_entry_num < priv->n_entrys - 1)
222 clutter_actor_set_opacity (priv->next, 0xAA);
224 child_box.x1 = focal_x + entry_width;
225 child_box.y1 = focal_y + natural_height/10;
226 child_box.x2 = natural_height/2 + child_box.x1;
227 child_box.y2 = natural_height/2 + child_box.y1;
228 clutter_actor_allocate (priv->next, &child_box, absolute_origin_changed);
232 clutter_actor_set_opacity (priv->next,
233 0xff + (priv->alpha_value * (-0xff)
234 / CLUTTER_ALPHA_MAX_ALPHA));
237 CLUTTER_ACTOR_CLASS (woohaa_slider_menu_parent_class)->
238 allocate (actor, box, absolute_origin_changed);
242 woohaa_slider_menu_class_init (WoohaaSliderMenuClass *klass)
244 GObjectClass *object_class = G_OBJECT_CLASS (klass);
245 ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
247 g_type_class_add_private (klass, sizeof (WoohaaSliderMenuPrivate));
249 object_class->dispose = woohaa_slider_menu_dispose;
250 object_class->finalize = woohaa_slider_menu_finalize;
252 actor_class->get_preferred_width = woohaa_slider_menu_get_preferred_width;
253 actor_class->get_preferred_height = woohaa_slider_menu_get_preferred_height;
254 actor_class->allocate = woohaa_slider_menu_allocate;
255 actor_class->paint = woohaa_slider_menu_paint;
259 woohaa_slider_menu_init (WoohaaSliderMenu *woohaa_slider_menu)
261 WoohaaSliderMenuPrivate *priv;
263 woohaa_slider_menu->priv = priv =
264 G_TYPE_INSTANCE_GET_PRIVATE (woohaa_slider_menu,
265 WOOHAA_TYPE_SLIDER_MENU,
266 WoohaaSliderMenuPrivate);
268 priv->menu_width = CSW();
270 priv->timeline = clutter_timeline_new (30, 60);
272 priv->alpha = clutter_alpha_new_full (priv->timeline,
273 CLUTTER_ALPHA_SINE_INC,
276 priv->behave = clutter_behaviour_slider_new (woohaa_slider_menu, 0, 0);
278 priv->effect_template
279 = clutter_effect_template_new (clutter_timeline_new (20, 60),
280 CLUTTER_ALPHA_SINE_INC);
282 priv->font_color = g_new0(ClutterColor, 1);
283 clutter_color_parse ("#ccccccff", priv->font_color);
285 priv->bg = clutter_texture_new_from_file (PKGDATADIR "/header.svg", NULL);
286 if (!priv->bg) g_warning ("Unable to load heaer.svg");
288 clutter_actor_set_parent (priv->bg, CLUTTER_ACTOR (woohaa_slider_menu));
290 clutter_actor_set_width (priv->bg, CSW());
292 clutter_actor_show (priv->bg);
294 priv->next = clutter_texture_new_from_file (PKGDATADIR "/arrow-next.svg",
296 if (!priv->next) g_warning ("Unable to load arror-next.svg");
298 clutter_actor_hide (priv->next);
299 clutter_actor_set_parent (priv->next, CLUTTER_ACTOR (woohaa_slider_menu));
301 priv->prev = clutter_texture_new_from_file (PKGDATADIR "/arrow-prev.svg",
303 if (!priv->prev) g_warning ("Unable to load arror-prev.svg");
305 clutter_actor_hide (priv->prev);
306 clutter_actor_set_parent (priv->prev, CLUTTER_ACTOR (woohaa_slider_menu));
308 priv->entry_group = clutter_group_new ();
309 clutter_actor_set_parent (priv->entry_group,
310 CLUTTER_ACTOR (woohaa_slider_menu));
311 clutter_actor_show (priv->entry_group);
315 woohaa_slider_menu_new (const gchar *font)
318 WoohaaSliderMenuPrivate *priv;
320 menu = g_object_new (WOOHAA_TYPE_SLIDER_MENU, NULL);
321 priv = WOOHAA_SLIDER_MENU_GET_PRIVATE (menu);
322 priv->font = g_strdup(font);
328 woohaa_slider_menu_add_option (WoohaaSliderMenu *menu,
330 WoohaaSliderMenuSelectedFunc selected,
333 WoohaaSliderMenuPrivate *priv = WOOHAA_SLIDER_MENU_GET_PRIVATE (menu);
334 WoohaaSliderMenuEntry *entry;
338 actor = clutter_label_new_with_text (priv->font, text);
339 clutter_label_set_color (CLUTTER_LABEL(actor), priv->font_color);
340 clutter_label_set_line_wrap (CLUTTER_LABEL(actor), FALSE);
342 entry = g_new0(WoohaaSliderMenuEntry, 1);
343 entry->actor = actor;
344 entry->selected_func = selected;
345 entry->userdata = userdata;
347 if (clutter_actor_get_height(actor) > priv->entry_height)
349 priv->entry_height = clutter_actor_get_height(actor);
351 clutter_actor_set_width (priv->bg, CSW());
352 clutter_actor_set_height (priv->bg, priv->entry_height
353 + (priv->entry_height/2));
356 if (clutter_actor_get_height(priv->next) > priv->entry_height)
360 w = priv->entry_height/8;
361 h = priv->entry_height/4;
363 clutter_actor_set_size (priv->next, w, h);
364 clutter_actor_set_size (priv->prev, w, h);
367 pad = clutter_actor_get_width (priv->next) * 2;
369 entry->offset = priv->unclipped_width + pad;
371 if (priv->entrys == NULL)
372 priv->unclipped_width += pad;
374 priv->unclipped_width += clutter_actor_get_width(actor) + pad;
376 if (priv->entrys == 0)
379 clutter_actor_set_opacity (actor, 0xff);
383 clutter_actor_set_opacity (actor, 0x33);
384 clutter_actor_set_scale (actor, 0.7, 0.7);
387 clutter_group_add (CLUTTER_GROUP (priv->entry_group), actor);
389 priv->entrys = g_list_append (priv->entrys, entry);
391 clutter_actor_set_position (actor,
393 priv->entry_height/12);
399 woohaa_slider_menu_activate (WoohaaSliderMenu *menu,
402 WoohaaSliderMenuPrivate *priv = WOOHAA_SLIDER_MENU_GET_PRIVATE (menu);
403 WoohaaSliderMenuEntry *selected, *current;
405 if (entry_num < 0 || entry_num >= priv->n_entrys)
408 if (clutter_timeline_is_playing(priv->timeline))
412 = (WoohaaSliderMenuEntry *)g_list_nth_data(priv->entrys,
413 priv->active_entry_num);
415 selected = (WoohaaSliderMenuEntry *)g_list_nth_data(priv->entrys,
418 priv->active_entry_num = entry_num;
420 WOOHAA_BEHAVIOUR_SLIDER(priv->behave)->old = current;
421 WOOHAA_BEHAVIOUR_SLIDER(priv->behave)->new = selected;
423 clutter_actor_queue_relayout (CLUTTER_ACTOR (menu));
425 /* FIXME: Should be a signal */
426 if (selected->selected_func)
427 selected->selected_func(menu, selected->actor, selected->userdata);
429 clutter_timeline_start (priv->timeline);
433 woohaa_slider_menu_advance (WoohaaSliderMenu *menu, gint n)
435 WoohaaSliderMenuPrivate *priv = WOOHAA_SLIDER_MENU_GET_PRIVATE (menu);
436 woohaa_slider_menu_activate (menu, priv->active_entry_num + n);
439 /* Custom behaviour */
442 clutter_behaviour_alpha_notify (ClutterBehaviour *behave,
445 WoohaaBehaviourSlider *slide = WOOHAA_BEHAVIOUR_SLIDER(behave);
446 WoohaaSliderMenu *menu;
448 WoohaaSliderMenuPrivate *priv;
450 if (!(slide->old) || !(slide->new))
454 priv = WOOHAA_SLIDER_MENU_GET_PRIVATE (menu);
456 priv->offset = slide->old->offset +
457 (((gint)alpha_value *
458 (slide->new->offset - slide->old->offset))
459 / CLUTTER_ALPHA_MAX_ALPHA);
461 clutter_actor_set_opacity (slide->old->actor,
464 / CLUTTER_ALPHA_MAX_ALPHA));
466 clutter_actor_set_opacity (slide->new->actor,
469 / CLUTTER_ALPHA_MAX_ALPHA));
471 scale = (0.3 * alpha_value) / (gdouble)CLUTTER_ALPHA_MAX_ALPHA;
473 clutter_actor_set_scale (slide->new->actor,
477 if (slide->new->actor != slide->old->actor)
478 clutter_actor_set_scale (slide->old->actor,
482 priv->alpha_value = alpha_value;
484 if (CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR(menu)))
485 clutter_actor_queue_relayout (CLUTTER_ACTOR (menu));
489 clutter_behaviour_slider_class_init (WoohaaBehaviourSliderClass *klass)
491 ClutterBehaviourClass *behave_class = CLUTTER_BEHAVIOUR_CLASS (klass);
493 behave_class->alpha_notify = clutter_behaviour_alpha_notify;
497 clutter_behaviour_slider_init (WoohaaBehaviourSlider *self)
501 static ClutterBehaviour*
502 clutter_behaviour_slider_new (WoohaaSliderMenu *menu,
503 WoohaaSliderMenuEntry *old,
504 WoohaaSliderMenuEntry *new)
506 WoohaaSliderMenuPrivate *priv = WOOHAA_SLIDER_MENU_GET_PRIVATE (menu);
507 WoohaaBehaviourSlider *slide_behave;
509 slide_behave = g_object_new (WOOHAA_TYPE_BEHAVIOUR_SLIDER,
510 "alpha", priv->alpha,
513 slide_behave->old = old;
514 slide_behave->new = new;
515 slide_behave->menu = menu;
517 return CLUTTER_BEHAVIOUR(slide_behave);