static void mex_content_box_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { MexContentBoxPrivate *priv = MEX_CONTENT_BOX (object)->priv; gint int_value; switch (property_id) { case PROP_OPEN: g_value_set_boolean (value, MEX_CONTENT_BOX (object)->priv->is_open); break; case PROP_IMPORTANT: g_value_set_boolean (value, mex_content_box_get_important (MEX_CONTENT_BOX (object))); break; case PROP_THUMB_WIDTH: g_object_get (priv->tile, "thumb-width", &int_value, NULL); g_value_set_int (value, int_value); break; case PROP_ACTION_LIST_WIDTH: g_value_set_int (value, clutter_actor_get_width (priv->action_list)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } }
static void mex_content_box_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { MexContentBoxPrivate *priv = MEX_CONTENT_BOX (object)->priv; gint int_value; switch (property_id) { case PROP_IMPORTANT: mex_content_box_set_important (MEX_CONTENT_BOX (object), g_value_get_boolean (value)); break; case PROP_THUMB_WIDTH: int_value = g_value_get_int (value); if (int_value > 0) g_object_set (priv->tile, "thumb-width", int_value, "thumb-height", (int) (int_value * DEFAULT_THUMB_RATIO), NULL); break; case PROP_ACTION_LIST_WIDTH: clutter_actor_set_width (priv->action_list, g_value_get_int (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } }
static MxFocusable* mex_content_box_move_focus (MxFocusable *focusable, MxFocusDirection direction, MxFocusable *from) { MexContentBoxPrivate *priv = MEX_CONTENT_BOX (focusable)->priv; MxFocusable *result = NULL; if (priv->is_open) { if (direction == MX_FOCUS_DIRECTION_RIGHT && (ClutterActor *) from != priv->action_list) result = mx_focusable_accept_focus (MX_FOCUSABLE (priv->action_list), 0); else if (direction == MX_FOCUS_DIRECTION_LEFT && (ClutterActor *) from != priv->tile) result = mx_focusable_accept_focus (MX_FOCUSABLE (priv->tile), 0); if (result == NULL) { /* close the content box if it is open */ if (priv->is_open && !priv->is_closing) mex_content_box_toggle_open (MEX_CONTENT_BOX (focusable)); } } return result; }
static void mex_content_box_get_preferred_height (ClutterActor *actor, gfloat for_width, gfloat *min_height, gfloat *pref_height) { MexContentBoxPrivate *priv = MEX_CONTENT_BOX (actor)->priv; gfloat info_h; clutter_actor_get_preferred_height (priv->tile, for_width, min_height, pref_height); if (!priv->extras_visible) return; if (pref_height) { clutter_actor_get_preferred_height (priv->info_panel, for_width, NULL, &info_h); if (clutter_timeline_is_playing (priv->timeline)) *pref_height = *pref_height + (info_h * clutter_alpha_get_alpha (priv->alpha)); else *pref_height = *pref_height + info_h; } }
static void mex_content_box_get_preferred_width (ClutterActor *actor, gfloat for_height, gfloat *min_width, gfloat *pref_width) { MexContentBoxPrivate *priv = MEX_CONTENT_BOX (actor)->priv; gfloat list_w; clutter_actor_get_preferred_width (priv->tile, for_height, min_width, pref_width); if (!priv->extras_visible) return; if (pref_width) { clutter_actor_get_preferred_width (priv->action_list, for_height, NULL, &list_w); if (clutter_timeline_is_playing (priv->timeline)) *pref_width = *pref_width + (list_w * clutter_alpha_get_alpha (priv->alpha)); else *pref_width = *pref_width + list_w; } }
static void mex_content_box_dispose (GObject *object) { MexContentBoxPrivate *priv = MEX_CONTENT_BOX (object)->priv; GList *l; if (priv->bindings) { for (l = priv->bindings; l; l = l->next) g_object_unref (l->data); g_list_free (priv->bindings); priv->bindings = NULL; } if (priv->content) { g_object_unref (priv->content); priv->content = NULL; } if (priv->model) { g_object_unref (priv->model); priv->model = NULL; } G_OBJECT_CLASS (mex_content_box_parent_class)->dispose (object); }
static void mex_content_box_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { MexContentBox *box = MEX_CONTENT_BOX (object); MexContentBoxPrivate *priv = box->priv; switch (property_id) { case PROP_MEDIA_URL: g_value_set_string (value, priv->media_url); break; case PROP_LOGO_URL: g_value_set_string (value, priv->logo_url); break; case PROP_THUMB_WIDTH: g_value_set_int (value, priv->thumb_width); break; case PROP_THUMB_HEIGHT: g_value_set_int (value, priv->thumb_height); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } }
static void mex_content_box_paint (ClutterActor *actor) { MexContentBoxPrivate *priv = MEX_CONTENT_BOX (actor)->priv; gboolean clipped = FALSE; CLUTTER_ACTOR_CLASS (mex_content_box_parent_class)->paint (actor); if (G_UNLIKELY (priv->clip_to_allocation)) { ClutterActorBox box; clutter_actor_get_allocation_box (actor, &box); cogl_clip_push_rectangle (0, 0, box.x2 - box.x1, box.y2 - box.y1); clipped = TRUE; } clutter_actor_paint (priv->tile); if (G_UNLIKELY (priv->extras_visible)) { ClutterActorBox box; clutter_actor_paint (priv->action_list); clutter_actor_paint (priv->info_panel); /* separator */ cogl_set_source_color4ub (255, 255, 255, 51); clutter_actor_get_allocation_box (priv->info_panel, &box); cogl_path_line (box.x1, box.y1, box.x2, box.y1); cogl_path_stroke (); } if (G_UNLIKELY (clipped)) cogl_clip_pop (); }
static MexModel* mex_content_box_get_context (MexContentView *view) { MexContentBox *box = MEX_CONTENT_BOX (view); MexContentBoxPrivate *priv = box->priv; return priv->context; }
static gboolean mex_content_box_key_press_event_cb (ClutterActor *actor, ClutterKeyEvent *event, gpointer user_data) { MexActionManager *manager = mex_action_manager_get_default (); MexContentBoxPrivate *priv = MEX_CONTENT_BOX (actor)->priv; if (MEX_KEY_OK (event->keyval)) { GList *actions; actions = mex_action_manager_get_actions_for_content (manager, priv->content); /* find the first action and "activate" it */ if (actions) { MxAction *action = actions->data; mex_action_set_context (action, priv->context); mex_action_set_content (action, priv->content); g_signal_emit_by_name (action, "activated", 0); g_list_free (actions); return TRUE; } } else if (MEX_KEY_INFO (event->keyval)) { mex_content_box_toggle_open (MEX_CONTENT_BOX (actor)); } else if (MEX_KEY_BACK (event->keyval)) { /* close content box */ if (priv->is_open) mex_content_box_toggle_open (MEX_CONTENT_BOX (actor)); } return FALSE; }
static void mex_content_box_pick (ClutterActor *actor, const ClutterColor *color) { MexContentBoxPrivate *priv = MEX_CONTENT_BOX (actor)->priv; clutter_actor_paint (priv->tile); if (G_UNLIKELY (priv->extras_visible)) clutter_actor_paint (priv->action_list); }
static void mex_content_box_paint (ClutterActor *actor) { MexContentBoxPrivate *priv = MEX_CONTENT_BOX (actor)->priv; if (MEX_IS_PROGRAM (priv->content)) _mex_program_complete (MEX_PROGRAM (priv->content)); CLUTTER_ACTOR_CLASS (mex_content_box_parent_class)->paint (actor); }
/* MxFocusableIface */ static MxFocusable* mex_content_box_accept_focus (MxFocusable *focusable, MxFocusHint hint) { MexContentBoxPrivate *priv = MEX_CONTENT_BOX (focusable)->priv; MxFocusable *focus = MX_FOCUSABLE (priv->tile); clutter_actor_grab_key_focus (CLUTTER_ACTOR (focusable)); return mx_focusable_accept_focus (focus, hint); }
static void mex_content_box_finalize (GObject *object) { MexContentBoxPrivate *priv = MEX_CONTENT_BOX (object)->priv; g_free (priv->thumb_url); g_free (priv->media_url); g_free (priv->logo_url); g_free (priv->description); G_OBJECT_CLASS (mex_content_box_parent_class)->finalize (object); }
static void mex_content_box_allocate (ClutterActor *actor, const ClutterActorBox *box, ClutterAllocationFlags flags) { MexContentBoxPrivate *priv = MEX_CONTENT_BOX (actor)->priv; ClutterActorBox child_box; gfloat pref_w = 0, pref_h = 0, tile_w, tile_h; CLUTTER_ACTOR_CLASS (mex_content_box_parent_class)->allocate (actor, box, flags); tile_w = box->x2 - box->x1; clutter_actor_get_preferred_width (priv->tile, -1, NULL, &tile_w); if (tile_w > box->x2 - box->x1) tile_w = box->x2 - box->x1; clutter_actor_get_preferred_height (priv->tile, tile_w, NULL, &tile_h); child_box.x1 = 0; child_box.x2 = child_box.x1 + tile_w; child_box.y1 = 0; child_box.y2 = child_box.y1 + tile_h; clutter_actor_allocate (priv->tile, &child_box, flags); if (G_UNLIKELY (priv->extras_visible)) { /* action list */ clutter_actor_get_preferred_width (priv->action_list, -1, NULL, &pref_w); clutter_actor_get_preferred_height (priv->info_panel, -1, NULL, &pref_h); child_box.x1 = tile_w; child_box.x2 = tile_w + pref_w; child_box.y1 = 0; child_box.y2 = tile_h; clutter_actor_allocate (priv->action_list, &child_box, flags); child_box.x1 = 0; child_box.x2 = tile_w + pref_w; child_box.y1 = tile_h; child_box.y2 = tile_h + pref_h; clutter_actor_allocate (priv->info_panel, &child_box, flags); } /* enable clip-to-allocation if the children will extend beyond the allocated * box */ if ((tile_w + pref_w) > (box->x2 - box->x1) || (tile_h + pref_h) > (box->y2 - box->y1)) priv->clip_to_allocation = TRUE; else priv->clip_to_allocation = FALSE; }
static gboolean mex_content_box_key_press_event_cb (ClutterActor *actor, ClutterKeyEvent *event, MexExpanderBox *drawer) { gboolean open; MexActionManager *manager = mex_action_manager_get_default (); MexContentBoxPrivate *priv = MEX_CONTENT_BOX (drawer)->priv; if (event->keyval != MEX_KEY_OK && event->keyval != MEX_KEY_INFO) { return FALSE; } if (event->keyval == MEX_KEY_OK) { GList *actions; actions = mex_action_manager_get_actions_for_content (manager, priv->content); if (actions) { MxAction *action = actions->data; mex_action_set_content (action, priv->content); mex_action_set_context (action, priv->model); g_signal_emit_by_name (action, "activated", 0); g_list_free (actions); return TRUE; } } open = !mex_expander_box_get_open (drawer); /* We only want to expand the box if we have either more than one action, * or we have description metadata. We already track this when determining * if the info icon should be visible, so use that to determine whether * we should allow opening here. */ if (open && !mex_tile_get_secondary_icon (MEX_TILE (priv->tile))) return FALSE; mex_expander_box_set_open (drawer, open); mex_expander_box_set_open (MEX_EXPANDER_BOX (priv->box), open); return TRUE; }
static void mex_content_box_dispose (GObject *object) { MexContentBoxPrivate *priv = MEX_CONTENT_BOX (object)->priv; if (priv->content) { g_object_unref (priv->content); priv->content = NULL; } if (priv->context) { g_object_unref (priv->context); priv->context = NULL; } if (priv->tile) { clutter_actor_destroy (priv->tile); priv->tile = NULL; } if (priv->action_list) { clutter_actor_destroy (priv->action_list); priv->action_list = NULL; } if (priv->info_panel) { clutter_actor_destroy (priv->info_panel); priv->info_panel = NULL; } if (priv->timeline) { g_object_unref (priv->timeline); priv->timeline = NULL; } if (priv->alpha) { g_object_unref (priv->alpha); priv->alpha = NULL; } G_OBJECT_CLASS (mex_content_box_parent_class)->dispose (object); }
static gboolean mex_content_box_tile_clicked_cb (ClutterActor *tile, ClutterButtonEvent *event, MexContentBox *self) { /* Because key based interactions moving the focus involve opening/closing the content box, we have to be careful about the order in which we change focus and open/close the box with mouse interactions. */ if (mex_content_box_get_open (self)) { mex_content_box_toggle_open (MEX_CONTENT_BOX (self)); mex_push_focus (MX_FOCUSABLE (tile)); } else { mex_push_focus (MX_FOCUSABLE (tile)); mex_content_box_toggle_open (MEX_CONTENT_BOX (self)); } return TRUE; }
static void mex_content_box_set_context (MexContentView *view, MexModel *model) { MexContentBox *box = MEX_CONTENT_BOX (view); MexContentBoxPrivate *priv = box->priv; if (priv->model == model) return; if (priv->model) g_object_unref (priv->model); priv->model = g_object_ref (model); mex_content_view_set_context (MEX_CONTENT_VIEW (priv->action_list), model); }
static void mex_column_shrink_children (MexColumn *column) { MexColumnPrivate *priv = column->priv; GList *l; if (priv->n_items < 1) return; clutter_timeline_stop (priv->expand_timeline); for (l = priv->children; l; l = g_list_next (l)) { mex_column_shrink_child (l->data); mex_content_box_set_important (MEX_CONTENT_BOX (l->data), FALSE); } }
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)); } }
static void mex_content_box_set_content (MexContentView *view, MexContent *content) { MexContentBox *box = MEX_CONTENT_BOX (view); MexContentBoxPrivate *priv = box->priv; if (priv->content) g_object_unref (priv->content); priv->content = g_object_ref (content); mex_content_view_set_content (MEX_CONTENT_VIEW (priv->tile), content); mex_content_view_set_content (MEX_CONTENT_VIEW (priv->info_panel), content); /* setting the content on action_list is delayed until the box is opened to * ensure any additional actions registered after set_content is called are * available */ }
static void mex_content_box_set_context (MexContentView *view, MexModel *context) { MexContentBox *box = MEX_CONTENT_BOX (view); MexContentBoxPrivate *priv = box->priv; if (priv->context == context) return; if (priv->context) g_object_unref (priv->context); priv->context = g_object_ref (context); mex_content_view_set_context (MEX_CONTENT_VIEW (priv->action_list), context); mex_content_view_set_context (MEX_CONTENT_VIEW (priv->tile), context); mex_content_view_set_context (MEX_CONTENT_VIEW (priv->info_panel), context); }
/** * mex_column_add_content: * * Add an item to the column for the specified content at the specified * position. */ static void mex_column_add_content (MexColumn *column, MexContent *content, guint position) { MexColumnPrivate *priv = column->priv; ClutterActor *box; MexShadow *shadow; ClutterColor shadow_color = { 0, 0, 0, 128 }; GList *sibling; box = mex_content_box_new (); mex_content_view_set_content (MEX_CONTENT_VIEW (box), content); mex_content_view_set_context (MEX_CONTENT_VIEW (box), priv->model); sibling = g_list_nth (priv->children, position); priv->children = g_list_insert_before (priv->children, sibling, box); priv->n_items ++; /* add shadow */ shadow = mex_shadow_new (); mex_shadow_set_paint_flags (shadow, MEX_TEXTURE_FRAME_TOP | MEX_TEXTURE_FRAME_BOTTOM); mex_shadow_set_radius_y (shadow, 25); mex_shadow_set_color (shadow, &shadow_color); clutter_actor_add_effect_with_name (CLUTTER_ACTOR (box), "shadow", CLUTTER_EFFECT (shadow)); clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (shadow), FALSE); g_signal_connect (box, "notify::open", G_CALLBACK (content_box_open_notify), column); /* set important if the column has focus */ mex_content_box_set_important (MEX_CONTENT_BOX (box), priv->has_focus); clutter_actor_set_parent (box, CLUTTER_ACTOR (column)); }
static void mex_column_add (ClutterContainer *container, ClutterActor *actor) { MexColumn *self = MEX_COLUMN (container); MexColumnPrivate *priv = self->priv; if (priv->sort_func) priv->children = g_list_insert_sorted_with_data (priv->children, actor, (GCompareDataFunc)priv->sort_func, priv->sort_data); else priv->children = g_list_append (priv->children, actor); priv->n_items ++; /* Expand/collapse any drawer that gets added as appropriate */ if (MEX_IS_EXPANDER_BOX (actor)) { g_signal_connect (actor, "notify::open", G_CALLBACK (expander_box_open_notify), container); mex_expander_box_set_important (MEX_EXPANDER_BOX (actor), priv->has_focus); if (MEX_IS_CONTENT_BOX (actor)) { ClutterActor *tile = mex_content_box_get_tile (MEX_CONTENT_BOX (actor)); mex_tile_set_important (MEX_TILE (tile), priv->has_focus); } } clutter_actor_set_parent (actor, CLUTTER_ACTOR (self)); g_signal_emit_by_name (self, "actor-added", actor); }
static void mex_column_notify_focused_cb (MxFocusManager *manager, GParamSpec *pspec, MexColumn *self) { GList *c; guint offset, increment; ClutterActor *focused, *focused_cell; gboolean cell_has_focus, has_focus, open, set_tile_important; MexColumnPrivate *priv = self->priv; focused = (ClutterActor *)mx_focus_manager_get_focused (manager); /* Check if we have focus, and what child is focused */ focused_cell = NULL; set_tile_important = FALSE; cell_has_focus = has_focus = FALSE; if (focused) { gboolean contains_column = FALSE; ClutterActor *parent = clutter_actor_get_parent (focused); while (parent) { if (parent == (ClutterActor *)self) { has_focus = TRUE; if (!priv->has_focus) { set_tile_important = TRUE; priv->has_focus = TRUE; } if (focused != priv->header) { cell_has_focus = TRUE; focused_cell = focused; } break; } else if (MEX_IS_COLUMN (parent)) { contains_column = TRUE; } focused = parent; parent = clutter_actor_get_parent (focused); } if (!contains_column) has_focus = TRUE; } if (!has_focus && priv->has_focus) { priv->has_focus = FALSE; set_tile_important = TRUE; } /* Scroll the adjustment to the top */ if (!cell_has_focus && priv->adjustment) mx_adjustment_interpolate (priv->adjustment, 0, 250, CLUTTER_EASE_OUT_CUBIC); /* Open/close boxes as appropriate */ offset = 0; increment = 150; /* If we're changing the tile importance, initialise the state manager */ if (set_tile_important && priv->n_items > 0) { if (priv->expand_timeline) g_object_unref (priv->expand_timeline); priv->expand_timeline = clutter_timeline_new (priv->n_items * increment); clutter_timeline_set_delay (priv->expand_timeline, 350); } /* Loop through children and set the expander box important/unimportant * as necessary, and if necessary, do the same for the tile inside the * expander-box. */ open = has_focus && !cell_has_focus; for (c = priv->children; c; c = c->next) { gchar signal_name[32+16]; ClutterActor *child = c->data; if ((!priv->collapse && priv->has_focus) || (child == focused_cell)) open = TRUE; if (!MEX_IS_EXPANDER_BOX (child)) continue; /* Note, 'marker-reached::' is 16 characters long */ g_snprintf (signal_name, G_N_ELEMENTS (signal_name), "marker-reached::%p", child); if (MEX_IS_CONTENT_BOX (child)) { ClutterActor *tile = mex_content_box_get_tile (MEX_CONTENT_BOX (child)); mex_tile_set_important (MEX_TILE (tile), priv->has_focus); } if (!open) { if (priv->expand_timeline) { if (clutter_timeline_has_marker (priv->expand_timeline, signal_name + 16)) clutter_timeline_remove_marker (priv->expand_timeline, signal_name + 16); g_signal_handlers_disconnect_by_func (priv->expand_timeline, mex_column_expand_drawer_cb, child); } mex_expander_box_set_important (MEX_EXPANDER_BOX (child), FALSE); } else if (set_tile_important) { mex_expander_box_set_important (MEX_EXPANDER_BOX (child), FALSE); clutter_timeline_add_marker_at_time (priv->expand_timeline, signal_name + 16, offset); g_signal_connect_swapped (priv->expand_timeline, signal_name, G_CALLBACK (mex_column_expand_drawer_cb), child); offset += increment; } else mex_expander_box_set_important (MEX_EXPANDER_BOX (child), TRUE); } if (priv->expand_timeline && set_tile_important && (offset >= increment)) clutter_timeline_start (priv->expand_timeline); }
static void mex_column_expand_children (MexColumn *column, ClutterActor *start_at) { MexColumnPrivate *priv = column->priv; guint offset, increment; GList *c; gchar **markers; gint i; gboolean start; if (priv->n_items < 1) return; /* Open/close boxes as appropriate */ offset = 0; increment = 150; clutter_timeline_set_duration (priv->expand_timeline, priv->n_items * increment); clutter_timeline_set_delay (priv->expand_timeline, 350); /* remove the previous markers */ markers = clutter_timeline_list_markers (priv->expand_timeline, -1, NULL); if (markers) { for (i = 0; markers[i]; i++) { clutter_timeline_remove_marker (priv->expand_timeline, markers[i]); } } g_strfreev (markers); /* start is TRUE if start_at is NULL, otherwise it is set to TRUE when the * start_at item is found */ start = (start_at == NULL); for (c = priv->children; c; c = g_list_next (c)) { gchar signal_name[32+16]; ClutterActor *child = c->data; if (!MEX_IS_CONTENT_BOX (child)) continue; mex_content_box_set_important (MEX_CONTENT_BOX (child), TRUE); mex_column_expand_child (child); /* continue until the start item has been found */ if (child == start_at) start = TRUE; if (!start) continue; /* Note, 'marker-reached::' is 16 characters long */ g_snprintf (signal_name, G_N_ELEMENTS (signal_name), "marker-reached::%p", child); /* stagger opening */ clutter_timeline_add_marker_at_time (priv->expand_timeline, signal_name + 16, offset); g_signal_connect_swapped (priv->expand_timeline, signal_name, G_CALLBACK (mex_column_expand_child), child); offset += increment; } clutter_timeline_start (priv->expand_timeline); }
static void mex_content_box_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { MexContentBox *self = MEX_CONTENT_BOX (object); MexContentBoxPrivate *priv = self->priv; switch (property_id) { case PROP_MEDIA_URL: g_free (priv->media_url); priv->media_url = g_value_dup_string (value); break; case PROP_LOGO_URL: /* FIXME: We want the logo URL to be file:// to share the same * underlying texture. This should be handled by a generic "download * queue + texture cache" thingy that caches the same URL to a local * file and hands over a ClutterTexure (or a MagicTexture) with the * same underlying Cogl texture */ { MxTextureCache *cache; ClutterActor *logo, *logo_frame; GFile *file; gchar *path; gint bw, bh; gfloat ratio; g_free (priv->logo_url); priv->logo_url = g_value_dup_string (value); if (priv->logo_url == NULL) break; file = g_file_new_for_uri (priv->logo_url); path = g_file_get_path (file); g_object_unref (file); if (G_UNLIKELY (path == NULL)) { g_warning ("The logo URL provided is not local, refusing to load it"); break; } cache = mx_texture_cache_get_default (); logo = mx_texture_cache_get_actor (cache, path); if (G_UNLIKELY (logo == NULL)) { g_warning ("Could not retrieve texture for %s", path); break; } logo_frame = mex_aspect_frame_new (); /* FIXME, had to set the size (for now?) provides some GObject properties * to tune that? expose it in the CSS */ clutter_actor_set_size (logo_frame, 60, 40); clutter_texture_get_base_size (CLUTTER_TEXTURE (logo), &bw, &bh); ratio = bh / 40.; mex_aspect_frame_set_ratio (MEX_ASPECT_FRAME (logo_frame), ratio); clutter_container_add_actor (CLUTTER_CONTAINER (logo_frame), logo); mex_tile_set_primary_icon (MEX_TILE (priv->tile), logo_frame); } break; case PROP_THUMB_WIDTH: priv->thumb_width = g_value_get_int (value); g_object_set (G_OBJECT (priv->tile), "thumb-width", priv->thumb_width, NULL); break; case PROP_THUMB_HEIGHT: priv->thumb_height = g_value_get_int (value); g_object_set (G_OBJECT (priv->tile), "thumb-height", priv->thumb_height, NULL); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } }
static MexContent * mex_content_box_get_content (MexContentView *view) { return MEX_CONTENT_BOX (view)->priv->content; }