コード例 #1
0
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;
}
コード例 #2
0
ファイル: mx-bin.c プロジェクト: GunioRobot/mx
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;
}
コード例 #3
0
ファイル: mx-notebook.c プロジェクト: 3v1n0/mx
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;
}
コード例 #4
0
ファイル: mx-table.c プロジェクト: ManMower/mx
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;
}
コード例 #5
0
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;
}
コード例 #6
0
ファイル: mx-toolbar.c プロジェクト: 3v1n0/mx
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;
}
コード例 #7
0
ファイル: mx-toolbar.c プロジェクト: 3v1n0/mx
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;
}
コード例 #8
0
ファイル: mex-shell.c プロジェクト: dudochkin-victor/mex
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));
}
コード例 #9
0
ファイル: mx-table.c プロジェクト: ManMower/mx
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;
}