static MxFocusable * mx_stack_accept_focus (MxFocusable *focusable, MxFocusHint hint) { GList *c, *children; MxStackPrivate *priv = MX_STACK (focusable)->priv; ClutterContainer *container = CLUTTER_CONTAINER (focusable); focusable = NULL; switch (hint) { default: case MX_FOCUS_HINT_PRIOR: if (priv->current_focus && (!MX_IS_WIDGET (priv->current_focus) || !mx_widget_get_disabled ((MxWidget *)priv->current_focus))) { focusable = mx_focusable_accept_focus (MX_FOCUSABLE (priv->current_focus), hint); if (focusable) break; } /* This purposefully runs into the next case statement */ case MX_FOCUS_HINT_FIRST: case MX_FOCUS_HINT_LAST: children = clutter_container_get_children (container); if (hint == MX_FOCUS_HINT_LAST) children = g_list_reverse (children); if (children) { c = children; while (c && !focusable) { ClutterActor *child = c->data; c = c->next; if (!MX_IS_FOCUSABLE (child)) continue; if (MX_IS_WIDGET (child) && mx_widget_get_disabled ((MxWidget *)child)) continue; priv->current_focus = child; focusable = mx_focusable_accept_focus (MX_FOCUSABLE (child), hint); } g_list_free (children); } break; } return focusable; }
static MxFocusable* mx_bin_accept_focus (MxFocusable *focusable, MxFocusHint hint) { MxBinPrivate *priv = MX_BIN (focusable)->priv; if (MX_IS_FOCUSABLE (priv->child)) return mx_focusable_accept_focus (MX_FOCUSABLE (priv->child), hint); else return NULL; }
static MxFocusable * mx_notebook_accept_focus (MxFocusable *focusable, MxFocusHint hint) { MxNotebookPrivate *priv = MX_NOTEBOOK (focusable)->priv; if (priv->current_page && MX_IS_FOCUSABLE (priv->current_page)) return mx_focusable_accept_focus (MX_FOCUSABLE (priv->current_page), hint); else return NULL; }
static MxFocusable* mx_table_accept_focus (MxFocusable *focusable, MxFocusHint hint) { MxTablePrivate *priv = MX_TABLE (focusable)->priv; MxFocusable *return_focusable; GList* list, *l, *children; return_focusable = NULL; children = clutter_actor_get_children (CLUTTER_ACTOR (focusable)); /* find the first/last focusable widget */ switch (hint) { case MX_FOCUS_HINT_LAST: list = g_list_reverse (g_list_copy (children)); break; case MX_FOCUS_HINT_PRIOR: if (priv->last_focus) { list = g_list_copy (g_list_find (children, priv->last_focus)); if (list) break; } /* This intentionally runs into the next switch case */ default: case MX_FOCUS_HINT_FIRST: list = g_list_copy (children); break; } for (l = list; l; l = g_list_next (l)) { if (MX_IS_FOCUSABLE (l->data)) { return_focusable = mx_focusable_accept_focus (MX_FOCUSABLE (l->data), hint); if (return_focusable) break; } } g_list_free (list); g_list_free (children); return return_focusable; }
static MxFocusable * mx_stack_move_focus (MxFocusable *focusable, MxFocusDirection direction, MxFocusable *from) { GList *c; MxStackPrivate *priv = MX_STACK (focusable)->priv; if (direction == MX_FOCUS_DIRECTION_OUT) return NULL; focusable = NULL; c = g_list_find (priv->children, from); while (c && !focusable) { ClutterActor *child; switch (direction) { case MX_FOCUS_DIRECTION_PREVIOUS : case MX_FOCUS_DIRECTION_LEFT : case MX_FOCUS_DIRECTION_UP : c = c->prev; break; default: c = c->next; break; } if (!c) continue; child = c->data; if (!MX_IS_FOCUSABLE (child)) continue; focusable = mx_focusable_accept_focus (MX_FOCUSABLE (child), MX_FOCUS_HINT_PRIOR); if (focusable) priv->current_focus = child; } return focusable; }
static MxFocusable * mx_toolbar_move_focus (MxFocusable *self, MxFocusDirection direction, MxFocusable *from) { MxFocusable *focusable; MxToolbarPrivate *priv = MX_TOOLBAR (self)->priv; if (priv->child && !MX_IS_FOCUSABLE (priv->child)) priv->child = NULL; focusable = NULL; switch (direction) { case MX_FOCUS_DIRECTION_LEFT: case MX_FOCUS_DIRECTION_PREVIOUS: if (!priv->child_has_focus && priv->child) { priv->child_has_focus = TRUE; focusable = mx_focusable_accept_focus (MX_FOCUSABLE (priv->child), MX_FOCUS_HINT_LAST); } break; case MX_FOCUS_DIRECTION_RIGHT: case MX_FOCUS_DIRECTION_NEXT: if (priv->child_has_focus && priv->has_close_button) { priv->child_has_focus = FALSE; focusable = mx_focusable_accept_focus (MX_FOCUSABLE (priv->close_button), MX_FOCUS_HINT_FIRST); } default: break; } return focusable; }
static MxFocusable * mx_toolbar_accept_focus (MxFocusable *self, MxFocusHint hint) { MxFocusable *focusable; MxToolbarPrivate *priv = MX_TOOLBAR (self)->priv; if (priv->child && !MX_IS_FOCUSABLE (priv->child)) priv->child = NULL; focusable = NULL; switch (hint) { default: case MX_FOCUS_HINT_PRIOR: if (priv->child && priv->child_has_focus) focusable = mx_focusable_accept_focus (MX_FOCUSABLE (priv->child), hint); if (focusable) break; case MX_FOCUS_HINT_LAST: priv->child_has_focus = FALSE; if (priv->has_close_button) focusable = mx_focusable_accept_focus (MX_FOCUSABLE (priv->close_button), hint); if (focusable) break; case MX_FOCUS_HINT_FIRST: priv->child_has_focus = TRUE; if (priv->child) focusable = mx_focusable_accept_focus (MX_FOCUSABLE (priv->child), hint); break; } return focusable; }
void mex_shell_present (MexShell *shell, ClutterActor *actor, MexShellDirection in) { GList *l; ClutterActor *stage; ClutterActorBox box; MexShellPrivate *priv; MexShellChildData *data; gfloat x, y, width, height; g_return_if_fail (MEX_IS_SHELL (shell)); g_return_if_fail (CLUTTER_IS_ACTOR (actor)); priv = shell->priv; l = g_list_find_custom (priv->children, actor, mex_shell_find_child); if (!l) { g_warning (G_STRLOC ": Attempted to present an unknown child."); return; } data = l->data; clutter_actor_get_allocation_box (CLUTTER_ACTOR (shell), &box); width = box.x2 - box.x1; height = box.y2 - box.y1; x = 0; y = 0; if (clutter_actor_get_opacity (data->child) == 0x00) { switch (in) { case MEX_SHELL_DIRECTION_NONE: clutter_actor_set_position (data->child, 0, 0); break; case MEX_SHELL_DIRECTION_TOP: clutter_actor_set_position (data->child, x, -height); break; case MEX_SHELL_DIRECTION_RIGHT: clutter_actor_set_position (data->child, width, y); break; default: case MEX_SHELL_DIRECTION_BOTTOM: clutter_actor_set_position (data->child, x, height); break; case MEX_SHELL_DIRECTION_LEFT: clutter_actor_set_position (data->child, -width, y); break; } data->last_direction = in; } clutter_animator_remove_key (data->animator, (GObject *)data->child, NULL, -1); clutter_animator_set (data->animator, data->child, "x", CLUTTER_LINEAR, 0.0, 0.f, data->child, "x", CLUTTER_EASE_OUT_QUAD, 1.0, x, data->child, "y", CLUTTER_LINEAR, 0.0, 0.f, data->child, "y", CLUTTER_EASE_OUT_QUAD, 1.0, y, data->child, "opacity", CLUTTER_LINEAR, 0.0, 0x00, data->child, "opacity", CLUTTER_EASE_OUT_QUAD, 0.1, 0xff, NULL); clutter_animator_property_set_ease_in (data->animator, (GObject *)data->child, "x", TRUE); clutter_animator_property_set_ease_in (data->animator, (GObject *)data->child, "y", TRUE); clutter_animator_property_set_ease_in (data->animator, (GObject *)data->child, "opacity", TRUE); data->start_animator = TRUE; if (priv->presented && (priv->presented != actor)) { MexShellDirection dir; l = g_list_find_custom (priv->children, priv->presented, mex_shell_find_child); if (!l) { g_warning (G_STRLOC ": Former presented actor is unknown"); return; } data = l->data; x = y = 0; switch (in) { case 0: x = y = 0; dir = 0; break; case MEX_SHELL_DIRECTION_TOP: y = height; dir = MEX_SHELL_DIRECTION_BOTTOM; break; case MEX_SHELL_DIRECTION_RIGHT: x = -width; dir = MEX_SHELL_DIRECTION_LEFT; break; case MEX_SHELL_DIRECTION_BOTTOM: y = -height; dir = MEX_SHELL_DIRECTION_TOP; break; default: case MEX_SHELL_DIRECTION_LEFT: x = width; dir = MEX_SHELL_DIRECTION_RIGHT; break; } data->last_direction = dir; clutter_animator_remove_key (data->animator, (GObject *)data->child, NULL, -1); clutter_animator_set (data->animator, data->child, "x", CLUTTER_LINEAR, 0.0, 0.f, data->child, "x", CLUTTER_EASE_OUT_QUAD, 1.0, x, data->child, "y", CLUTTER_LINEAR, 0.0, 0.f, data->child, "y", CLUTTER_EASE_OUT_QUAD, 1.0, y, data->child, "opacity", CLUTTER_LINEAR, 0.9, 0xff, data->child, "opacity", CLUTTER_EASE_OUT_QUAD, 1.0, 0x00, NULL); clutter_animator_property_set_ease_in (data->animator, (GObject *)data->child, "x", TRUE); clutter_animator_property_set_ease_in (data->animator, (GObject *)data->child, "y", TRUE); clutter_animator_property_set_ease_in (data->animator, (GObject *)data->child, "opacity", TRUE); data->start_animator = TRUE; } priv->presented = actor; stage = clutter_actor_get_stage (actor); if (stage) { MxFocusManager *manager = mx_focus_manager_get_for_stage ((ClutterStage *)stage); if (manager) { if (MX_IS_FOCUSABLE (actor)) mx_focus_manager_push_focus_with_hint (manager, MX_FOCUSABLE (shell), MX_FOCUS_HINT_PRIOR); else mx_focus_manager_move_focus (manager, MX_FOCUS_DIRECTION_OUT); } } clutter_actor_queue_redraw (CLUTTER_ACTOR (shell)); }
static MxFocusable* mx_table_move_focus (MxFocusable *focusable, MxFocusDirection direction, MxFocusable *from) { MxTablePrivate *priv = MX_TABLE (focusable)->priv; MxTable *table = MX_TABLE (focusable); GList *l, *childlink, *children; MxTableChild *child_meta; ClutterActor *child_actor; MxFocusable *focused; gint row, column; ClutterActor *found; /* find the current focus */ child_actor = CLUTTER_ACTOR (from); child_meta = (MxTableChild *) clutter_container_get_child_meta (CLUTTER_CONTAINER (focusable), child_actor); if (!child_meta) return NULL; priv->last_focus = from; /* find the next widget to focus */ switch (direction) { case MX_FOCUS_DIRECTION_NEXT: children = clutter_actor_get_children (CLUTTER_ACTOR (focusable)); childlink = g_list_find (children, from); for (l = childlink->next; l; l = g_list_next (l)) { if (MX_IS_FOCUSABLE (l->data)) { focused = mx_focusable_accept_focus (MX_FOCUSABLE (l->data), MX_FOCUS_HINT_FIRST); if (focused) { g_list_free (children); return focused; } } } /* no next widgets to focus */ g_list_free (children); return NULL; case MX_FOCUS_DIRECTION_PREVIOUS: children = clutter_actor_get_children (CLUTTER_ACTOR (focusable)); childlink = g_list_find (children, from); for (l = g_list_previous (childlink); l; l = g_list_previous (l)) { if (MX_IS_FOCUSABLE (l->data)) { focused = mx_focusable_accept_focus (MX_FOCUSABLE (l->data), MX_FOCUS_HINT_LAST); if (focused) { g_list_free (children); return focused; } } } /* no widget found in the previous position */ g_list_free (children); return NULL; case MX_FOCUS_DIRECTION_UP: /* move focus up */ row = child_meta->row - 1; column = child_meta->col; focused = NULL; while (!focused && row >= 0) { found = mx_table_find_actor_at (table, row, column); if (found) { if (MX_IS_FOCUSABLE (found)) { focused = mx_focusable_accept_focus (MX_FOCUSABLE (found), MX_FOCUS_HINT_FIRST); if (focused) break; } child_meta = (MxTableChild *) clutter_container_get_child_meta (CLUTTER_CONTAINER (focusable), found); /* row might not be the top row if @found is a spanned actor */ row = child_meta->row - 1; } else row --; } return focused; case MX_FOCUS_DIRECTION_DOWN: /* move focus down */ row = child_meta->row + child_meta->row_span; column = child_meta->col; focused = NULL; while (!focused && row < priv->n_rows) { found = mx_table_find_actor_at (table, row, column); if (found) { if (MX_IS_FOCUSABLE (found)) { focused = mx_focusable_accept_focus (MX_FOCUSABLE (found), MX_FOCUS_HINT_FIRST); if (focused) break; } child_meta = (MxTableChild *) clutter_container_get_child_meta (CLUTTER_CONTAINER (focusable), found); row = child_meta->row + child_meta->row_span; } else row ++; } return focused; case MX_FOCUS_DIRECTION_LEFT: /* move focus left */ row = child_meta->row; column = child_meta->col - 1; focused = NULL; while (!focused && column >= 0) { found = mx_table_find_actor_at (table, row, column); if (found) { if (MX_IS_FOCUSABLE (found)) { focused = mx_focusable_accept_focus (MX_FOCUSABLE (found), MX_FOCUS_HINT_FIRST); if (focused) break; } child_meta = (MxTableChild *) clutter_container_get_child_meta (CLUTTER_CONTAINER (focusable), found); /* col might not be the first column if @found is a spanned actor */ column = child_meta->col - 1; } else column --; } return focused; case MX_FOCUS_DIRECTION_RIGHT: /* move focus right */ row = child_meta->row; column = child_meta->col + child_meta->col_span; focused = NULL; while (!focused && column < priv->n_cols) { found = mx_table_find_actor_at (table, row, column); if (found) { if (MX_IS_FOCUSABLE (found)) { focused = mx_focusable_accept_focus (MX_FOCUSABLE (found), MX_FOCUS_HINT_FIRST); if (focused) break; } child_meta = (MxTableChild *) clutter_container_get_child_meta (CLUTTER_CONTAINER (focusable), found); column = child_meta->col + child_meta->col_span; } else column ++; } return focused; default: break; } return NULL; }