static void mx_menu_show (ClutterActor *actor) { ClutterAnimation *animation = NULL; ClutterStage *stage; /* set reactive and opacity, since these may have been set by the fade-out * animation (e.g. from captured_event_handler or button_release_cb) */ if ((animation = clutter_actor_get_animation (actor))) { clutter_animation_completed (animation); } clutter_actor_set_reactive (actor, TRUE); clutter_actor_set_opacity (actor, 0xff); /* chain up to run show after re-setting properties above */ CLUTTER_ACTOR_CLASS (mx_menu_parent_class)->show (actor); clutter_actor_grab_key_focus (actor); stage = (ClutterStage*) clutter_actor_get_stage (actor); mx_focus_manager_push_focus (mx_focus_manager_get_for_stage (stage), MX_FOCUSABLE (actor)); }
static gboolean mx_menu_captured_event_handler (ClutterActor *actor, ClutterEvent *event, ClutterActor *menu) { int i; ClutterActor *source; MxMenuPrivate *priv = MX_MENU (menu)->priv; /* allow the event to continue if it is applied to the menu or any of its * children */ source = clutter_event_get_source (event); if (source == menu) return FALSE; for (i = 0; i < priv->children->len; i++) { MxMenuChild *child; child = &g_array_index (priv->children, MxMenuChild, i); if (source == (ClutterActor*) child->box) return FALSE; } if (source == priv->up_button || source == priv->down_button) return FALSE; /* hide the menu if the user clicks outside the menu */ if (event->type == CLUTTER_BUTTON_PRESS) { if (clutter_actor_get_animation (menu)) { clutter_animation_completed (clutter_actor_get_animation (menu)); return FALSE; } clutter_actor_set_reactive (menu, FALSE); clutter_actor_animate (menu, CLUTTER_LINEAR, 250, "opacity", (guchar) 0, "signal-swapped::completed", clutter_actor_hide, menu, NULL); } return TRUE; }
static gboolean trough_paging_cb (StScrollBar *self) { gfloat handle_pos, event_pos, tx, ty; gdouble value; gdouble page_increment; gboolean ret; gulong mode; ClutterAnimation *a; GValue v = { 0, }; ClutterTimeline *t; if (self->priv->paging_event_no == 0) { /* Scroll on after initial timeout. */ mode = CLUTTER_EASE_OUT_CUBIC; ret = FALSE; self->priv->paging_event_no = 1; self->priv->paging_source_id = g_timeout_add ( PAGING_INITIAL_REPEAT_TIMEOUT, (GSourceFunc) trough_paging_cb, self); } else if (self->priv->paging_event_no == 1) { /* Scroll on after subsequent timeout. */ ret = FALSE; mode = CLUTTER_EASE_IN_CUBIC; self->priv->paging_event_no = 2; self->priv->paging_source_id = g_timeout_add ( PAGING_SUBSEQUENT_REPEAT_TIMEOUT, (GSourceFunc) trough_paging_cb, self); } else { /* Keep scrolling. */ ret = TRUE; mode = CLUTTER_LINEAR; self->priv->paging_event_no++; } /* Do the scrolling */ st_adjustment_get_values (self->priv->adjustment, &value, NULL, NULL, NULL, &page_increment, NULL); if (self->priv->vertical) handle_pos = clutter_actor_get_y (self->priv->handle); else handle_pos = clutter_actor_get_x (self->priv->handle); clutter_actor_transform_stage_point (CLUTTER_ACTOR (self->priv->trough), self->priv->move_x, self->priv->move_y, &tx, &ty); if (self->priv->vertical) event_pos = ty; else event_pos = tx; if (event_pos > handle_pos) { if (self->priv->paging_direction == NONE) { /* Remember direction. */ self->priv->paging_direction = DOWN; } if (self->priv->paging_direction == UP) { /* Scrolled far enough. */ return FALSE; } value += page_increment; } else { if (self->priv->paging_direction == NONE) { /* Remember direction. */ self->priv->paging_direction = UP; } if (self->priv->paging_direction == DOWN) { /* Scrolled far enough. */ return FALSE; } value -= page_increment; } if (self->priv->paging_animation) { clutter_animation_completed (self->priv->paging_animation); } /* FIXME: Creating a new animation for each scroll is probably not the best * idea, but it's a lot less involved than extenind the current animation */ a = self->priv->paging_animation = g_object_new (CLUTTER_TYPE_ANIMATION, "object", self->priv->adjustment, "duration", (guint)(PAGING_SUBSEQUENT_REPEAT_TIMEOUT * st_slow_down_factor), "mode", mode, NULL); g_value_init (&v, G_TYPE_DOUBLE); g_value_set_double (&v, value); clutter_animation_bind (self->priv->paging_animation, "value", &v); t = clutter_animation_get_timeline (self->priv->paging_animation); g_signal_connect (a, "completed", G_CALLBACK (animation_completed_cb), self->priv); clutter_timeline_start (t); return ret; }