mx/mx/mx-label.c

975 lines
26 KiB
C

/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* mx-label.c: Plain label actor
*
* Copyright 2008,2009 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU Lesser General Public License,
* version 2.1, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*
* Written by: Thomas Wood <thomas@linux.intel.com>
*
*/
/**
* SECTION:mx-label
* @short_description: Widget for displaying text
*
* #MxLabel is a simple widget for displaying one or more lines of text.
* It derives from #MxWidget to add extra style and placement functionality over
* #ClutterText. The internal #ClutterText is publicly accessibly to allow
* applications to set further properties.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <clutter/clutter.h>
#include "mx-label.h"
#include "mx-widget.h"
#include "mx-stylable.h"
#include "mx-private.h"
#include "mx-fade-effect.h"
enum
{
PROP_0,
PROP_CLUTTER_TEXT,
PROP_TEXT,
PROP_USE_MARKUP,
PROP_X_ALIGN,
PROP_Y_ALIGN,
PROP_LINE_WRAP,
PROP_FADE_OUT,
PROP_SHOW_TOOLTIP
};
#define MX_LABEL_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MX_TYPE_LABEL, MxLabelPrivate))
struct _MxLabelPrivate
{
ClutterActor *label;
ClutterEffect *fade_effect;
MxAlign x_align;
MxAlign y_align;
ClutterTimeline *fade_timeline;
ClutterAlpha *fade_alpha;
gint em_width;
guint fade_out : 1;
guint label_should_fade : 1;
guint show_tooltip : 1;
};
G_DEFINE_TYPE (MxLabel, mx_label, MX_TYPE_WIDGET);
static void
mx_label_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MxLabel *label = MX_LABEL (gobject);
switch (prop_id)
{
case PROP_TEXT:
mx_label_set_text (label, g_value_get_string (value));
break;
case PROP_USE_MARKUP:
mx_label_set_use_markup (label, g_value_get_boolean (value));
break;
case PROP_Y_ALIGN:
mx_label_set_y_align (label, g_value_get_enum (value));
break;
case PROP_X_ALIGN:
mx_label_set_x_align (label, g_value_get_enum (value));
break;
case PROP_LINE_WRAP:
mx_label_set_line_wrap (label, g_value_get_boolean (value));
break;
case PROP_FADE_OUT:
mx_label_set_fade_out (label, g_value_get_boolean (value));
break;
case PROP_SHOW_TOOLTIP:
mx_label_set_show_tooltip (label, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
mx_label_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MxLabel *self = MX_LABEL (gobject);
MxLabelPrivate *priv = self->priv;
switch (prop_id)
{
case PROP_CLUTTER_TEXT:
g_value_set_object (value, priv->label);
break;
case PROP_TEXT:
g_value_set_string (value,
clutter_text_get_text (CLUTTER_TEXT (priv->label)));
break;
case PROP_USE_MARKUP:
g_value_set_boolean (value, mx_label_get_use_markup (self));
break;
case PROP_X_ALIGN:
g_value_set_enum (value, priv->x_align);
break;
case PROP_Y_ALIGN:
g_value_set_enum (value, priv->y_align);
break;
case PROP_LINE_WRAP:
g_value_set_boolean (value, mx_label_get_line_wrap (self));
break;
case PROP_FADE_OUT:
g_value_set_boolean (value, priv->fade_out);
break;
case PROP_SHOW_TOOLTIP:
g_value_set_boolean (value, priv->show_tooltip);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
mx_label_style_changed (MxWidget *self,
MxStyleChangedFlags flags)
{
MxLabelPrivate *priv = MX_LABEL (self)->priv;
mx_stylable_apply_clutter_text_attributes (MX_STYLABLE (self),
CLUTTER_TEXT (priv->label));
}
static void
mx_label_get_preferred_width (ClutterActor *actor,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p)
{
MxLabelPrivate *priv = MX_LABEL (actor)->priv;
MxPadding padding = { 0, };
mx_widget_get_padding (MX_WIDGET (actor), &padding);
for_height -= padding.top + padding.bottom;
clutter_actor_get_preferred_width (priv->label, for_height,
min_width_p,
natural_width_p);
/* If we're fading out, make sure our minimum width is zero */
if (priv->fade_out && min_width_p)
*min_width_p = 0;
if (min_width_p)
*min_width_p += padding.left + padding.right;
if (natural_width_p)
*natural_width_p += padding.left + padding.right;
}
static void
mx_label_get_preferred_height (ClutterActor *actor,
gfloat for_width,
gfloat *min_height_p,
gfloat *natural_height_p)
{
MxLabelPrivate *priv = MX_LABEL (actor)->priv;
MxPadding padding = { 0, };
mx_widget_get_padding (MX_WIDGET (actor), &padding);
for_width -= padding.left + padding.right;
clutter_actor_get_preferred_height (priv->label, for_width,
min_height_p,
natural_height_p);
if (min_height_p)
*min_height_p += padding.top + padding.bottom;
if (natural_height_p)
*natural_height_p += padding.top + padding.bottom;
}
static void
mx_label_allocate (ClutterActor *actor,
const ClutterActorBox *box,
ClutterAllocationFlags flags)
{
MxLabelPrivate *priv = MX_LABEL (actor)->priv;
gboolean label_did_fade = priv->label_should_fade;
ClutterActorClass *parent_class;
ClutterActorBox child_box;
gboolean x_fill, y_fill;
gfloat avail_width;
parent_class = CLUTTER_ACTOR_CLASS (mx_label_parent_class);
parent_class->allocate (actor, box, flags);
mx_widget_get_available_area (MX_WIDGET (actor), box, &child_box);
avail_width = child_box.x2 - child_box.x1;
/* The default behaviour of ClutterText is to align to the
* top-left when it gets more space than is needed. Because
* of this behaviour, if we're aligning to the left, we can
* assign all our horizontal space to the label without
* measuring it (i.e. x-fill), and the same applies for
* aligning to the top and vertical space.
*/
x_fill = (priv->x_align == MX_ALIGN_START) ? TRUE : FALSE;
y_fill = (priv->y_align == MX_ALIGN_START) ? TRUE : FALSE;
mx_allocate_align_fill (priv->label, &child_box, priv->x_align,
priv->y_align, x_fill, y_fill);
priv->label_should_fade = FALSE;
if (priv->fade_out)
{
/* If we're fading out, make sure the label has its full width
* allocated. This ensures that the offscreen effect has the full
* label inside its texture.
*/
gfloat label_width;
clutter_actor_get_preferred_width (priv->label, -1, NULL, &label_width);
if (label_width > avail_width)
{
priv->label_should_fade = TRUE;
child_box.x2 = child_box.x1 + label_width;
}
mx_fade_effect_set_bounds (MX_FADE_EFFECT (priv->fade_effect),
0, 0, MIN (label_width, avail_width), 0);
}
/* Allocate the label */
clutter_actor_allocate (priv->label, &child_box, flags);
if (priv->show_tooltip)
{
PangoLayout *layout;
const gchar *text;
layout = clutter_text_get_layout (CLUTTER_TEXT (priv->label));
if (pango_layout_is_ellipsized (layout))
text = clutter_text_get_text (CLUTTER_TEXT (priv->label));
else
text = NULL;
mx_widget_set_tooltip_text (MX_WIDGET (actor), text);
}
/* Animate in/out the faded end of the label */
if (label_did_fade != priv->label_should_fade)
{
/* Begin/reverse the fading timeline when necessary */
if (priv->label_should_fade)
clutter_timeline_set_direction (priv->fade_timeline,
CLUTTER_TIMELINE_FORWARD);
else
clutter_timeline_set_direction (priv->fade_timeline,
CLUTTER_TIMELINE_BACKWARD);
if (!clutter_timeline_is_playing (priv->fade_timeline))
clutter_timeline_rewind (priv->fade_timeline);
clutter_timeline_start (priv->fade_timeline);
}
}
static void
mx_label_paint (ClutterActor *actor)
{
MxLabelPrivate *priv = MX_LABEL (actor)->priv;
ClutterActorClass *parent_class;
parent_class = CLUTTER_ACTOR_CLASS (mx_label_parent_class);
parent_class->paint (actor);
clutter_actor_paint (priv->label);
_mx_fade_effect_set_freeze_update (MX_FADE_EFFECT (priv->fade_effect), TRUE);
}
static void
mx_label_pick (ClutterActor *actor,
const ClutterColor *pick_color)
{
MxLabelPrivate *priv = MX_LABEL (actor)->priv;
ClutterActorClass *parent_class;
parent_class = CLUTTER_ACTOR_CLASS (mx_label_parent_class);
parent_class->pick (actor, pick_color);
clutter_actor_paint (priv->label);
}
static void
mx_label_map (ClutterActor *actor)
{
MxLabelPrivate *priv = MX_LABEL (actor)->priv;
CLUTTER_ACTOR_CLASS (mx_label_parent_class)->map (actor);
clutter_actor_map (priv->label);
}
static void
mx_label_unmap (ClutterActor *actor)
{
MxLabelPrivate *priv = MX_LABEL (actor)->priv;
if (priv->label)
clutter_actor_unmap (priv->label);
CLUTTER_ACTOR_CLASS (mx_label_parent_class)->unmap (actor);
}
static void
mx_label_dispose (GObject *actor)
{
MxLabelPrivate *priv = MX_LABEL (actor)->priv;
if (priv->fade_timeline)
{
clutter_timeline_stop (priv->fade_timeline);
g_object_unref (priv->fade_timeline);
priv->fade_timeline = NULL;
}
if (priv->fade_alpha)
{
g_object_unref (priv->fade_alpha);
priv->fade_alpha = NULL;
}
if (priv->label)
{
clutter_actor_destroy (priv->label);
priv->label = NULL;
}
G_OBJECT_CLASS (mx_label_parent_class)->dispose (actor);
}
static void
mx_label_class_init (MxLabelClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (klass, sizeof (MxLabelPrivate));
gobject_class->set_property = mx_label_set_property;
gobject_class->get_property = mx_label_get_property;
gobject_class->dispose = mx_label_dispose;
actor_class->paint = mx_label_paint;
actor_class->pick = mx_label_pick;
actor_class->allocate = mx_label_allocate;
actor_class->get_preferred_width = mx_label_get_preferred_width;
actor_class->get_preferred_height = mx_label_get_preferred_height;
actor_class->map = mx_label_map;
actor_class->unmap = mx_label_unmap;
pspec = g_param_spec_object ("clutter-text",
"Clutter Text",
"Internal ClutterText actor",
CLUTTER_TYPE_TEXT,
G_PARAM_READABLE);
g_object_class_install_property (gobject_class, PROP_CLUTTER_TEXT, pspec);
pspec = g_param_spec_string ("text",
"Text",
"Text of the label",
NULL,
MX_PARAM_READWRITE | MX_PARAM_TRANSLATEABLE);
g_object_class_install_property (gobject_class, PROP_TEXT, pspec);
pspec = g_param_spec_boolean ("use-markup",
"Use markup",
"Whether the text of the label should be "
"treated as Pango markup",
FALSE,
MX_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_USE_MARKUP, pspec);
pspec = g_param_spec_enum ("x-align",
"X Align",
"Horizontal position of the text layout",
MX_TYPE_ALIGN, MX_ALIGN_START,
MX_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_X_ALIGN, pspec);
pspec = g_param_spec_enum ("y-align",
"Y Align",
"Vertical position of the text layout",
MX_TYPE_ALIGN, MX_ALIGN_START,
MX_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_Y_ALIGN, pspec);
/**
* MxLabel:line-wrap:
*
* Whether to wrap the lines of #MxLabel:text if the contents
* exceed the available allocation.
*
* Since: 1.2
*/
pspec = g_param_spec_boolean ("line-wrap",
"Line wrap",
"If set, wrap the lines if the text becomes too wide",
FALSE,
MX_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_LINE_WRAP, pspec);
pspec = g_param_spec_boolean ("fade-out",
"Fade out",
"Fade out the end of the label, instead "
"of ellipsizing",
FALSE,
MX_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_FADE_OUT, pspec);
/**
* MxLabel:show-tooltip:
*
* Show a tooltip when there is not enough space to display the text. If set
* to %TRUE, this will also cause the #ClutterActor:reactive property to be
* enabled.
*
* Since: 1.4
*/
pspec = g_param_spec_boolean ("show-tooltip",
"Show Tooltip",
"Show a tooltip when there is not enough space"
" to display the text.",
FALSE,
MX_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_SHOW_TOOLTIP, pspec);
}
static void
mx_label_single_line_mode_cb (ClutterText *text,
GParamSpec *pspec,
MxLabel *self)
{
MxLabelPrivate *priv = self->priv;
if (!clutter_text_get_single_line_mode (text) && priv->fade_out)
mx_label_set_fade_out (self, FALSE);
}
static void
mx_label_label_changed_cb (MxLabel *label)
{
MxLabelPrivate *priv = label->priv;
/* Enable updating of the off-screen texture */
_mx_fade_effect_set_freeze_update (MX_FADE_EFFECT (priv->fade_effect), FALSE);
}
static void
mx_label_font_description_cb (ClutterText *text,
GParamSpec *pspec,
MxLabel *self)
{
PangoFontDescription *font;
MxLabelPrivate *priv = self->priv;
/* Find out the em-width - code pretty much copied from Clutter,
* clutter-backend.c, get_units_per_em ()
*/
font = clutter_text_get_font_description (text);
if (font)
{
gint i_dpi;
gdouble dpi;
gdouble font_size = 0;
gint pango_size = pango_font_description_get_size (font);
ClutterSettings *settings = clutter_settings_get_default ();
g_object_get (G_OBJECT (settings), "font-dpi", &i_dpi, NULL);
dpi = i_dpi / 1024.0;
if (pango_font_description_get_size_is_absolute (font))
font_size = pango_size / PANGO_SCALE;
else
font_size = pango_size / PANGO_SCALE * dpi / 96.f;
priv->em_width = (1.2f * font_size) * dpi / 96.f;
mx_fade_effect_set_border (MX_FADE_EFFECT (priv->fade_effect),
0, priv->em_width * 5, 0, 0);
}
}
static void
mx_label_fade_new_frame_cb (ClutterTimeline *timeline,
gint msecs,
MxLabel *self)
{
guint8 a;
ClutterColor color;
MxLabelPrivate *priv = self->priv;
a = (1.0 - clutter_alpha_get_alpha (priv->fade_alpha)) * 255;
color.red = a;
color.green = a;
color.blue = a;
color.alpha = a;
mx_fade_effect_set_color (MX_FADE_EFFECT (priv->fade_effect), &color);
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
}
static void
mx_label_fade_started_cb (ClutterTimeline *timeline,
MxLabel *label)
{
clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (label->priv->fade_effect),
TRUE);
}
static void
mx_label_fade_completed_cb (ClutterTimeline *timeline,
MxLabel *label)
{
MxLabelPrivate *priv = label->priv;
if (!priv->label_should_fade)
clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (priv->fade_effect),
FALSE);
}
static void
mx_label_init (MxLabel *label)
{
MxLabelPrivate *priv;
const ClutterColor opaque = { 0xff, 0xff, 0xff, 0xff };
label->priv = priv = MX_LABEL_GET_PRIVATE (label);
priv->label = g_object_new (CLUTTER_TYPE_TEXT,
"ellipsize", PANGO_ELLIPSIZE_END,
NULL);
clutter_actor_set_parent (priv->label, CLUTTER_ACTOR (label));
priv->fade_effect = mx_fade_effect_new ();
mx_fade_effect_set_color (MX_FADE_EFFECT (priv->fade_effect), &opaque);
clutter_actor_add_effect (priv->label, priv->fade_effect);
clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (priv->fade_effect),
FALSE);
g_signal_connect (label, "style-changed",
G_CALLBACK (mx_label_style_changed), NULL);
g_signal_connect (priv->label, "notify::single-line-mode",
G_CALLBACK (mx_label_single_line_mode_cb), label);
g_signal_connect_swapped (priv->label, "queue-redraw",
G_CALLBACK (mx_label_label_changed_cb), label);
priv->fade_timeline = clutter_timeline_new (250);
priv->fade_alpha = clutter_alpha_new_full (priv->fade_timeline,
CLUTTER_EASE_OUT_QUAD);
g_signal_connect (priv->fade_timeline, "new-frame",
G_CALLBACK (mx_label_fade_new_frame_cb), label);
g_signal_connect (priv->fade_timeline, "started",
G_CALLBACK (mx_label_fade_started_cb), label);
g_signal_connect (priv->fade_timeline, "completed",
G_CALLBACK (mx_label_fade_completed_cb), label);
}
/**
* mx_label_new:
*
* Create a new #MxLabel
*
* Returns: a new #MxLabel
*/
ClutterActor *
mx_label_new (void)
{
return g_object_new (MX_TYPE_LABEL, NULL);
}
/**
* mx_label_new_with_text:
* @text: text to set the label to
*
* Create a new #MxLabel with the specified label
*
* Returns: a new #MxLabel
*/
ClutterActor *
mx_label_new_with_text (const gchar *text)
{
if (text == NULL || *text == '\0')
return g_object_new (MX_TYPE_LABEL, NULL);
else
return g_object_new (MX_TYPE_LABEL,
"text", text,
NULL);
}
/**
* mx_label_get_text:
* @label: a #MxLabel
*
* Get the text displayed on the label
*
* Returns: the text for the label. This must not be freed by the application
*/
const gchar *
mx_label_get_text (MxLabel *label)
{
g_return_val_if_fail (MX_IS_LABEL (label), NULL);
return clutter_text_get_text (CLUTTER_TEXT (label->priv->label));
}
/**
* mx_label_set_text:
* @label: a #MxLabel
* @text: text to set the label to
*
* Sets the text displayed on the label
*/
void
mx_label_set_text (MxLabel *label,
const gchar *text)
{
MxLabelPrivate *priv;
g_return_if_fail (MX_IS_LABEL (label));
g_return_if_fail (text != NULL);
priv = label->priv;
if (clutter_text_get_use_markup (CLUTTER_TEXT (priv->label)))
clutter_text_set_markup (CLUTTER_TEXT (priv->label), text);
else
clutter_text_set_text (CLUTTER_TEXT (priv->label), text);
g_object_notify (G_OBJECT (label), "text");
}
/**
* mx_label_get_use_markup:
* @label: a #MxLabel
*
* Determines whether the text of the label is being treated as Pango markup.
*
* Returns: %TRUE if the text of the label is treated as Pango markup,
* %FALSE otherwise.
*
* Since: 1.2
*/
gboolean
mx_label_get_use_markup (MxLabel *label)
{
g_return_val_if_fail (MX_IS_LABEL (label), FALSE);
return clutter_text_get_use_markup (CLUTTER_TEXT (label->priv->label));
}
/**
* mx_label_set_use_markup:
* @label: a #MxLabel
* @use_markup: %TRUE to use Pango markup, %FALSE otherwise
*
* Sets whether the text of the label should be treated as Pango markup.
*/
void
mx_label_set_use_markup (MxLabel *label,
gboolean use_markup)
{
MxLabelPrivate *priv;
g_return_if_fail (MX_IS_LABEL (label));
priv = label->priv;
clutter_text_set_use_markup (CLUTTER_TEXT (priv->label), use_markup);
g_object_notify (G_OBJECT (label), "use-markup");
}
/**
* mx_label_get_clutter_text:
* @label: a #MxLabel
*
* Retrieve the internal #ClutterText so that extra parameters can be set
*
* Returns: (transfer none): the #ClutterText used by #MxLabel. The label
* is owned by the #MxLabel and should not be unref'ed by the application.
*/
ClutterActor*
mx_label_get_clutter_text (MxLabel *label)
{
g_return_val_if_fail (MX_IS_LABEL (label), NULL);
return label->priv->label;
}
void
mx_label_set_x_align (MxLabel *label,
MxAlign align)
{
g_return_if_fail (MX_IS_LABEL (label));
if (align != label->priv->x_align)
{
label->priv->x_align = align;
clutter_actor_queue_relayout (CLUTTER_ACTOR (label));
g_object_notify (G_OBJECT (label), "x-align");
}
}
MxAlign
mx_label_get_x_align (MxLabel *label)
{
g_return_val_if_fail (MX_IS_LABEL (label), 0);
return label->priv->x_align;
}
void
mx_label_set_y_align (MxLabel *label,
MxAlign align)
{
g_return_if_fail (MX_IS_LABEL (label));
if (align != label->priv->y_align)
{
label->priv->y_align = align;
clutter_actor_queue_relayout (CLUTTER_ACTOR (label));
g_object_notify (G_OBJECT (label), "y-align");
}
}
MxAlign
mx_label_get_y_align (MxLabel *label)
{
g_return_val_if_fail (MX_IS_LABEL (label), 0);
return label->priv->y_align;
}
/**
* mx_label_set_line_wrap:
* @label: An #MxLabel
* @line_wrap: new value of the line-wrap property.
*
* Set the value of the #MxLabel:line-wrap property.
*
* Since: 1.2
*/
void
mx_label_set_line_wrap (MxLabel *label,
gboolean line_wrap)
{
g_return_if_fail (MX_IS_LABEL (label));
clutter_text_set_line_wrap (CLUTTER_TEXT (label->priv->label), line_wrap);
g_object_notify (G_OBJECT (label), "line-wrap");
}
/**
* mx_label_get_line_wrap:
* @label: An #MxLabel
*
* Get the value of the #MxLabel:line-wrap property.
*
* Returns: %TRUE if the "line-wrap" property is set.
*
* Since: 1.2
*/
gboolean
mx_label_get_line_wrap (MxLabel *label)
{
g_return_val_if_fail (MX_IS_LABEL (label), FALSE);
return clutter_text_get_line_wrap (CLUTTER_TEXT (label->priv->label));
}
/**
* mx_label_set_fade_out:
* @label: A #MxLabel
* @fade: %TRUE to fade out, %FALSE otherwise
*
* Set whether to fade out the end of the label, instead of ellipsizing.
* Enabling this mode will also set the #ClutterText:single-line-mode and
* #ClutterText:ellipsize properties.
*
* Since: 1.2
*/
void
mx_label_set_fade_out (MxLabel *label,
gboolean fade)
{
MxLabelPrivate *priv;
g_return_if_fail (MX_IS_LABEL (label));
priv = label->priv;
if (priv->fade_out != fade)
{
priv->fade_out = fade;
g_object_notify (G_OBJECT (label), "fade-out");
/* Enable the fade-effect */
if (fade)
{
priv->label_should_fade = FALSE;
clutter_text_set_single_line_mode (CLUTTER_TEXT (priv->label), TRUE);
clutter_text_set_ellipsize (CLUTTER_TEXT (priv->label),
PANGO_ELLIPSIZE_NONE);
}
/* If we need to fade, listen for the font-description changing so
* we can keep track of the em-width of the label.
*/
if (fade)
{
g_signal_connect (priv->label, "notify::font-description",
G_CALLBACK (mx_label_font_description_cb), label);
mx_label_font_description_cb (CLUTTER_TEXT (priv->label),
NULL, label);
}
else
{
g_signal_handlers_disconnect_by_func (priv->label,
mx_label_font_description_cb,
label);
}
}
}
/**
* mx_label_get_fade_out:
* @label: A #MxLabel
*
* Determines whether the label has been set to fade out when there isn't
* enough space allocated to display the entire label.
*
* Returns: %TRUE if the label is set to fade out, %FALSE otherwise
*
* Since: 1.2
*/
gboolean
mx_label_get_fade_out (MxLabel *label)
{
g_return_val_if_fail (MX_IS_LABEL (label), FALSE);
return label->priv->fade_out;
}
/**
* mx_label_set_show_tooltip:
* @label: A #MxLabel
* @show_tooltip: %TRUE if the tooltip should be shown
*
* Set the value of the #MxLabel:show-tooltip property
*
* Since: 1.4
*/
void
mx_label_set_show_tooltip (MxLabel *label,
gboolean show_tooltip)
{
MxLabelPrivate *priv;
g_return_if_fail (MX_IS_LABEL (label));
priv = label->priv;
if (priv->show_tooltip != show_tooltip)
{
priv->show_tooltip = show_tooltip;
clutter_actor_queue_relayout (CLUTTER_ACTOR (label));
g_object_notify (G_OBJECT (label), "show-tooltip");
}
}
/**
* mx_label_get_show_tooltip:
* @label: A #MxLabel
*
* Returns the current value of the #MxLabel:show-tooltip property.
*
* Returns: %TRUE if the #MxLabel:show-tooltip property is enabled
*
* Since: 1.4
*/
gboolean
mx_label_get_show_tooltip (MxLabel *label)
{
g_return_val_if_fail (MX_IS_LABEL (label), FALSE);
return label->priv->show_tooltip;
}