Esempio n. 1
0
File: mx-menu.c Progetto: jku/mx
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));

}
Esempio n. 2
0
static gboolean
_enter_event_cb (ClutterActor         *actor,
                 ClutterCrossingEvent *event,
                 gpointer              data)
{
  MxFocusable *focusable;
  MxFocusManager *f_manager;

  f_manager =
    mx_focus_manager_get_for_stage (CLUTTER_STAGE (clutter_actor_get_stage (actor)));

  focusable = mx_focus_manager_get_focused (f_manager);

  /* hide the hover state on a button that has accepted focus via the default
   * focus as we're navigating by mouse and not keys we don't want to move
   * the focus as we may still want it in the place e.g. search bar
   */
  if ((focusable) &&
      (MNB_IS_LAUNCHER_BUTTON (focusable)) &&
      (CLUTTER_ACTOR (focusable) != actor))
    mx_stylable_set_style_pseudo_class (MX_STYLABLE (focusable), NULL);

  mx_stylable_set_style_pseudo_class (MX_STYLABLE (actor), "hover");

  return FALSE;
}
Esempio n. 3
0
static void
ntf_libnotify_update_modal (void)
{
  NtfTray      *tray = ntf_overlay_get_tray (TRUE);
  MetaPlugin *plugin = dawati_netbook_get_plugin_singleton ();

  if (ntf_tray_get_n_notifications (tray) > 0)
    {
      if (!overlay_focused)
        {
          MetaScreen   *screen = meta_plugin_get_screen (plugin);
          ClutterActor *stage = meta_get_stage_for_screen (screen);
          MxFocusManager *manager =
            mx_focus_manager_get_for_stage (CLUTTER_STAGE (stage));

          dawati_netbook_stash_window_focus (plugin, CurrentTime);
          mx_focus_manager_push_focus (manager, MX_FOCUSABLE (tray));
          overlay_focused = TRUE;
        }
    }
  else
    {
      if (overlay_focused)
        {
          dawati_netbook_unstash_window_focus (plugin, CurrentTime);
          overlay_focused = FALSE;
        }
    }
}
Esempio n. 4
0
static gboolean
mex_player_set_controls_visible (MexPlayer *player,
                                 gboolean   visible)
{
  MexPlayerPrivate *priv = player->priv;
  gfloat pos;
  ClutterStage *stage;
  MxFocusManager *fmanager;

  stage = (ClutterStage*) clutter_actor_get_stage (CLUTTER_ACTOR (player));
  fmanager = mx_focus_manager_get_for_stage (stage);

  pos = clutter_actor_get_height (priv->controls);
  if (visible)
    {
      priv->controls_prev_visible = FALSE;
      priv->controls_visible = TRUE;

      mx_widget_set_disabled (MX_WIDGET (priv->controls), FALSE);

      clutter_actor_animate (priv->controls, CLUTTER_EASE_IN_SINE, 250,
                             "opacity", 0xff,
                             "anchor-y", 0.0,
                             NULL);

      mex_player_restart_timer (player);

      if (priv->related_tile)
        {
          mx_focus_manager_push_focus_with_hint (fmanager,
                                                 MX_FOCUSABLE (priv->related_tile),
                                                 MX_FOCUS_HINT_PRIOR);

          g_object_unref (priv->related_tile);
          priv->related_tile = NULL;
        }
      else
        {
          mx_focus_manager_push_focus (fmanager, MX_FOCUSABLE (priv->controls));
        }
    }

  if (!visible)
    {
      priv->controls_visible = FALSE;
      clutter_actor_animate (priv->controls, CLUTTER_EASE_IN_SINE, 250,
                             "opacity", 0x00,
                             "anchor-y", -pos,
                             NULL);

      if (priv->hide_controls_source)
        {
          g_source_remove (priv->hide_controls_source);
          priv->hide_controls_source = 0;
        }
    }

  return TRUE;
}
Esempio n. 5
0
static void
mex_column_unmap (ClutterActor *actor)
{
  MxFocusManager *manager =
    mx_focus_manager_get_for_stage ((ClutterStage *)
      clutter_actor_get_stage (actor));
  g_signal_handlers_disconnect_by_func (manager,
                                        mex_column_notify_focused_cb,
                                        actor);

  CLUTTER_ACTOR_CLASS (mex_column_parent_class)->unmap (actor);
}
Esempio n. 6
0
static void
mex_column_map (ClutterActor *actor)
{
  MxFocusManager *manager;

  MexColumn *self = MEX_COLUMN (actor);

  CLUTTER_ACTOR_CLASS (mex_column_parent_class)->map (actor);

  manager = mx_focus_manager_get_for_stage ((ClutterStage *)
                                            clutter_actor_get_stage (actor));
  g_signal_connect (manager, "notify::focused",
                    G_CALLBACK (mex_column_notify_focused_cb), actor);
  mex_column_notify_focused_cb (manager, NULL, self);
}
Esempio n. 7
0
static void
mex_tile_map (ClutterActor *actor)
{
  MxFocusManager *manager;

  CLUTTER_ACTOR_CLASS (mex_tile_parent_class)->map (actor);

  manager = mx_focus_manager_get_for_stage ((ClutterStage *)
                                            clutter_actor_get_stage (actor));
  if (manager)
    {
      g_signal_connect (manager, "notify::focused",
                        G_CALLBACK (mex_tile_notify_focused_cb), actor);
      mex_tile_notify_focused_cb (manager, NULL, (MexTile *)actor);
    }
}
Esempio n. 8
0
int
main (int argc, char *argv[])
{
  ClutterActor *button, *box, *stage;
  MxApplication *application;
  MxWindow *window;

  application = mx_application_new (&argc, &argv, "Test Mx focus handling",
                                    MX_APPLICATION_SINGLE_INSTANCE);

  window = mx_application_create_window (application);
  stage = (ClutterActor *)mx_window_get_clutter_stage (window);

  box = mx_box_layout_new ();
  mx_box_layout_set_orientation (MX_BOX_LAYOUT (box), MX_ORIENTATION_VERTICAL);
  mx_window_set_child (window, box);

  button = mx_button_new_with_label ("button #1 (activate to remove)");
  g_signal_connect (button, "clicked",
                    G_CALLBACK (button_clicked_cb), NULL);
  mx_box_layout_insert_actor (MX_BOX_LAYOUT (box), button, -1);

  mx_focus_manager_push_focus (mx_focus_manager_get_for_stage (CLUTTER_STAGE (stage)),
                               MX_FOCUSABLE (button));


  button = mx_button_new_with_label ("button #2 (activate to remove)");
  g_signal_connect (button, "clicked",
                    G_CALLBACK (button_clicked_cb), NULL);
  mx_box_layout_insert_actor (MX_BOX_LAYOUT (box), button, -1);

  button = mx_button_new_with_label ("button #3 (activate to remove)");
  g_signal_connect (button, "clicked",
                    G_CALLBACK (button_clicked_cb), NULL);
  mx_box_layout_insert_actor (MX_BOX_LAYOUT (box), button, -1);

  button = mx_button_new_with_label ("button #4 (activate to remove)");
  g_signal_connect (button, "clicked",
                    G_CALLBACK (button_clicked_cb), NULL);
  mx_box_layout_insert_actor (MX_BOX_LAYOUT (box), button, -1);

  clutter_actor_show (stage);

  mx_application_run (application);

  return EXIT_SUCCESS;
}
Esempio n. 9
0
static void
mex_clock_bin_map (ClutterActor *actor)
{
  ClutterActor *stage;
  MxFocusManager *manager;

  MexClockBinPrivate *priv = MEX_CLOCK_BIN (actor)->priv;

  CLUTTER_ACTOR_CLASS (mex_clock_bin_parent_class)->map (actor);

  clutter_actor_map (priv->clock_hbox);

  stage = clutter_actor_get_stage (actor);
  manager = mx_focus_manager_get_for_stage (CLUTTER_STAGE (stage));
  g_signal_connect (manager, "notify::focused",
                    G_CALLBACK (mex_clock_bin_notify_focused_cb), actor);
}
Esempio n. 10
0
static void
mex_menu_map (ClutterActor *actor)
{
  MxFocusManager *manager;
  MexMenu *self = MEX_MENU (actor);

  CLUTTER_ACTOR_CLASS (mex_menu_parent_class)->map (actor);

  manager = mx_focus_manager_get_for_stage ((ClutterStage *)
                                            clutter_actor_get_stage (actor));
  if (manager)
    {
      g_signal_connect (manager, "notify::focused",
                        G_CALLBACK (mex_menu_notify_focused_cb), self);
      mex_menu_notify_focused_cb (manager, NULL, self);
    }
}
Esempio n. 11
0
static void
mex_content_box_notify_open_cb (MexExpanderBox *box,
                                GParamSpec     *pspec)
{
  GList *actions;

  ClutterStage *stage = CLUTTER_STAGE (
                          clutter_actor_get_stage (CLUTTER_ACTOR (box)));
  MxFocusManager *fmanager = mx_focus_manager_get_for_stage (stage);
  MexActionManager *manager = mex_action_manager_get_default ();
  MexContentBoxPrivate *priv = MEX_CONTENT_BOX (box)->priv;
  gboolean open = mex_expander_box_get_open (box);

  if (!open)
    {
      /* If the action list has focus, push it back onto the tile */
      if (mex_actor_has_focus (fmanager, priv->action_list))
        mx_focus_manager_push_focus (fmanager, MX_FOCUSABLE (priv->tile));
      return;
    }

  /* Refresh the info panel and the action list */
  mex_content_view_set_content (MEX_CONTENT_VIEW (priv->panel), priv->content);
  mex_action_list_refresh (MEX_ACTION_LIST (priv->action_list));

  /* See if we have any actions */
  actions = mex_action_manager_get_actions_for_content (manager,
                                                        priv->content);

  /* Push focus onto the action list if we have actions, otherwise onto
   * the tile.
   */
  if (actions)
    {
      clutter_actor_show (priv->action_list);
      mx_focus_manager_push_focus (fmanager,
                                   MX_FOCUSABLE (priv->action_list));
      g_list_free (actions);
    }
  else
    {
      clutter_actor_hide (priv->action_list);
      mx_focus_manager_push_focus (fmanager, MX_FOCUSABLE (priv->tile));
    }
}
Esempio n. 12
0
static void
mex_clock_bin_unmap (ClutterActor *actor)
{
  ClutterActor *stage;
  MxFocusManager *manager;

  MexClockBinPrivate *priv = MEX_CLOCK_BIN (actor)->priv;

  stage = clutter_actor_get_stage (actor);
  manager = mx_focus_manager_get_for_stage (CLUTTER_STAGE (stage));
  g_signal_handlers_disconnect_by_func (manager,
                                        mex_clock_bin_notify_focused_cb,
                                        actor);

  clutter_actor_unmap (priv->clock_hbox);

  CLUTTER_ACTOR_CLASS (mex_clock_bin_parent_class)->unmap (actor);
}
Esempio n. 13
0
static void
mx_menu_show (ClutterActor *actor)
{
    ClutterStage *stage;

    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 void
mex_telepathy_channel_on_video_shown (ClutterActor *actor,
                                      gpointer      user_data)
{
  MexTelepathyChannel *self = MEX_TELEPATHY_CHANNEL (user_data);
  MexTelepathyChannelPrivate *priv = self->priv;

  ClutterStage *stage;
  MxFocusManager *fmanager;

  clutter_actor_hide (CLUTTER_ACTOR (priv->full_frame) );

  stage = CLUTTER_STAGE (clutter_actor_get_stage (CLUTTER_ACTOR (actor)));

  if (stage)
    {
      fmanager = mx_focus_manager_get_for_stage (stage);
      mx_focus_manager_push_focus (fmanager, MX_FOCUSABLE (priv->end_button));
    }
}
Esempio n. 15
0
static gboolean
mx_menu_button_enter_event_cb (ClutterActor *box,
                               ClutterEvent *event,
                               gpointer      user_data)
{
    MxMenuPrivate *priv = MX_MENU (user_data)->priv;
    ClutterStage *stage;

    /* each menu item grabs focus when hovered */

    stage = (ClutterStage *) clutter_actor_get_stage (box);

    /* ensure the menu is not closed when focus is pushed to another actor */
    priv->internal_focus_push = TRUE;

    mx_focus_manager_push_focus (mx_focus_manager_get_for_stage (stage),
                                 MX_FOCUSABLE (box));

    /* prevent the hover pseudo-class from being applied */
    return TRUE;
}
Esempio n. 16
0
void
mex_column_set_collapse_on_focus (MexColumn *column,
                                  gboolean   collapse)
{
  MexColumnPrivate *priv;

  g_return_if_fail (MEX_IS_COLUMN (column));

  priv = column->priv;
  if (priv->collapse != collapse)
    {
      ClutterActor *stage;

      priv->collapse = collapse;
      g_object_notify (G_OBJECT (column), "collapse-on-focus");

      if ((stage = clutter_actor_get_stage (CLUTTER_ACTOR (column))))
        {
          MxFocusManager *manager =
            mx_focus_manager_get_for_stage (CLUTTER_STAGE (stage));
          mex_column_notify_focused_cb (manager, NULL, column);
        }
    }
}
Esempio n. 17
0
void
mex_epg_grid_add_events (MexEpgGrid *grid,
                         MexChannel *channel,
                         GPtrArray  *events)
{
  MexEpgGridPrivate *priv;
  MexChannelManager *channel_manager;
  MxFocusManager *focus_manager;
  GPtrArray *row;
  gint position;
  guint i;

  g_return_if_fail (MEX_IS_EPG_GRID (grid));
  g_return_if_fail (MEX_IS_CHANNEL (channel));
  g_return_if_fail (events);
  priv = grid->priv;

  channel_manager = mex_channel_manager_get_default ();
  position = mex_channel_manager_get_channel_position (channel_manager,
                                                       channel);
  if (G_UNLIKELY (position == -1))
    {
      MEX_WARN (EPG, "Could not find position of channel %s",
                mex_channel_get_name (channel));
      return;
    }

  /* no events for this channel */
  if (G_UNLIKELY (events->len == 0))
    {
      /* signal that we won't have data for that row */
      row_loaded (grid, position);
      return;
    }

  /* we insert tiles in bulk, removing the existing tiles if needed */
  row = g_ptr_array_index (priv->rows, position);

  /* If we already have data for that row, we assume the caller wants to
   * replace the data. If we don't we signal that a new row is loaded */
  if (row)
    remove_row (grid, position);
  else
    row_loaded (grid, position);

  row = g_ptr_array_new ();
  g_ptr_array_set_size (row, events->len);

  /* We are adding events, it's a good time to check if we have a valid
   * current date */
  if (priv->current_date == NULL)
    priv->current_date = g_date_time_new_now_local ();

  for (i = 0; i < events->len; i++)
    {
      MexEpgEvent *event = g_ptr_array_index (events, i);
      ClutterActor *tile;

      tile = mex_epg_tile_new_with_event (event);
      g_signal_connect (tile, "clicked",
                        G_CALLBACK (on_tile_clicked), grid);
      clutter_actor_set_parent (tile, CLUTTER_ACTOR (grid));

      g_ptr_array_index (row, i) = tile;

#if 0
      /* Disabled because we don't need to style differently the events that
       * are occuring now in the current design, might come back though */
      if (mex_epg_event_is_date_in_between (event, priv->current_date))
        mx_stylable_set_style_class (MX_STYLABLE (tile), "EpgTileNow");
#endif
    }

  g_ptr_array_index (priv->rows, position) = row;

  /* If the EpgGrid had the focus before we had a chance to add events,
   * it's a good time to push the focus to one of the EpgTile */
  /* FIXME: default to the channel we are watching, not row 0 */
  if (priv->has_focus_but_no_tile && position == 0 && row->len > 0)
    {
      ClutterActor *focused_tile = g_ptr_array_index (row, 0);
      ClutterActor *stage;

      stage = clutter_actor_get_stage (focused_tile);
      focus_manager = mx_focus_manager_get_for_stage (CLUTTER_STAGE (stage));
      mx_focus_manager_push_focus (focus_manager, MX_FOCUSABLE (focused_tile));

      g_signal_emit (grid, signals[SIGNAL_ROW_SELECTED], 0, 0);

      priv->has_focus_but_no_tile = FALSE;
    }

  /* We have a new row, relayout */
  clutter_actor_queue_relayout (CLUTTER_ACTOR (grid));
}
Esempio n. 18
0
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));
}
Esempio n. 19
0
static gboolean
mex_player_key_press_event (ClutterActor    *actor,
                            ClutterKeyEvent *event)
{
  MexPlayerPrivate *priv = MEX_PLAYER (actor)->priv;
  ClutterStage *stage;
  MxFocusManager *fmanager;

  stage = (ClutterStage*) clutter_actor_get_stage (actor);
  fmanager = mx_focus_manager_get_for_stage (stage);

  switch (event->keyval)
    {
    case CLUTTER_KEY_Down:
        {
          if (!priv->controls_visible && !priv->info_visible)
            return mex_player_set_controls_visible (MEX_PLAYER (actor), TRUE);
          break;
        }

    case MEX_KEY_INFO:
        {
          MexContent *content;

          content = priv->content;

          if (priv->info_visible)
            {
              /* hide the info panel */
              clutter_actor_animate (priv->info_panel, CLUTTER_EASE_IN_SINE,
                                     250, "opacity", 0x00, NULL);

              mx_widget_set_disabled (MX_WIDGET (priv->info_panel), TRUE);
              mx_widget_set_disabled (MX_WIDGET (priv->controls), FALSE);

              priv->info_visible = FALSE;

              if (priv->controls_prev_visible)
                mex_player_set_controls_visible (MEX_PLAYER (actor), TRUE);
            }
          else
            {
              /* if you're pressing info button while the media controls are up
               set them as previously visible */
              if (priv->controls_visible)
                priv->controls_prev_visible = TRUE;

              MxFocusable *focusable;
              focusable = mx_focus_manager_get_focused (fmanager);
              if (MEX_IS_CONTENT_TILE (focusable) &&
                  priv->controls_prev_visible == TRUE)
                {
                  content =
                    mex_content_view_get_content (MEX_CONTENT_VIEW (focusable));

                  /* to avoid any accidental leak */
                  if (priv->related_tile)
                    {
                      g_object_unref (priv->related_tile);
                      priv->related_tile = NULL;
                    }
                  priv->related_tile = g_object_ref (focusable);
                }

              mex_content_view_set_content (MEX_CONTENT_VIEW (priv->info_panel),
                                            content);

              /* show the info panel */
              clutter_actor_animate (priv->info_panel, CLUTTER_EASE_IN_SINE,
                                     250, "opacity", 0xff, NULL);

              mx_widget_set_disabled (MX_WIDGET (priv->info_panel), FALSE);
              mx_widget_set_disabled (MX_WIDGET (priv->controls), TRUE);

              priv->info_visible = TRUE;

              mex_player_set_controls_visible (MEX_PLAYER (actor), FALSE);

              mex_push_focus (MX_FOCUSABLE (priv->info_panel));
            }

          return TRUE;
        }
    }

  return FALSE;
}