mirror of
https://github.com/brl/mutter.git
synced 2025-03-03 11:58:09 +00:00
[units] Rework Units into logical distance value
Units as they have been implemented since Clutter 0.4 have always been misdefined as "logical distance unit", while they were just pixels with fractionary bits. Units should be reworked to be opaque structures to hold a value and its unit type, that can be then converted into pixels when Clutter needs to paint or compute size requisitions and perform allocations. The previous API should be completely removed to avoid collisions, and a new type: ClutterUnits should be added; the ability to install GObject properties using ClutterUnits should be maintained.
This commit is contained in:
parent
1580ffb884
commit
0d5e17ecd1
2
.gitignore
vendored
2
.gitignore
vendored
@ -202,6 +202,8 @@ stamp-h1
|
||||
/tests/conform/test-blend-strings
|
||||
/tests/conform/test-color-from-string
|
||||
/tests/conform/test-color-to-string
|
||||
/tests/conform/test-units-constructors
|
||||
/tests/conform/test-units-string
|
||||
/tests/conform/test-conformance-result.xml
|
||||
/tests/micro-bench/test-text-perf
|
||||
/tests/micro-bench/test-text
|
||||
|
@ -2903,7 +2903,7 @@ clutter_actor_dispose (GObject *object)
|
||||
object->ref_count);
|
||||
|
||||
/* avoid recursing when called from clutter_actor_destroy() */
|
||||
if (priv->parent_actor)
|
||||
if (priv->parent_actor != NULL)
|
||||
{
|
||||
ClutterActor *parent = priv->parent_actor;
|
||||
|
||||
@ -7147,91 +7147,29 @@ parse_units (ClutterActor *self,
|
||||
|
||||
if (G_VALUE_HOLDS (&value, G_TYPE_INT))
|
||||
{
|
||||
retval = g_value_get_int (&value);
|
||||
retval = (gfloat) g_value_get_int (&value);
|
||||
}
|
||||
else if (G_VALUE_HOLDS (&value, G_TYPE_FLOAT))
|
||||
{
|
||||
retval = g_value_get_float (&value);
|
||||
}
|
||||
else if (G_VALUE_HOLDS (&value, G_TYPE_STRING))
|
||||
{
|
||||
gint64 val;
|
||||
gchar *end;
|
||||
ClutterUnits units;
|
||||
gboolean res;
|
||||
|
||||
val = g_ascii_strtoll (g_value_get_string (&value), &end, 10);
|
||||
|
||||
/* skip whitespace */
|
||||
while (g_ascii_isspace (*end))
|
||||
end++;
|
||||
|
||||
/* assume pixels */
|
||||
if (*end == '\0')
|
||||
res = clutter_units_from_string (&units, g_value_get_string (&value));
|
||||
if (res)
|
||||
retval = clutter_units_to_pixels (&units);
|
||||
else
|
||||
{
|
||||
retval = val;
|
||||
goto out;
|
||||
g_warning ("Invalid value '%s': integers, strings or floating point "
|
||||
"values can be used for the x, y, width and height "
|
||||
"properties. Valid modifiers for strings are 'px', 'mm', "
|
||||
"'pt' and 'em'.",
|
||||
g_value_get_string (&value));
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
if (strcmp (end, "px") == 0)
|
||||
{
|
||||
retval = val;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strcmp (end, "em") == 0)
|
||||
{
|
||||
retval = CLUTTER_UNITS_FROM_EM (val);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strcmp (end, "mm") == 0)
|
||||
{
|
||||
retval = CLUTTER_UNITS_FROM_MM (val);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strcmp (end, "pt") == 0)
|
||||
{
|
||||
retval = CLUTTER_UNITS_FROM_POINTS (val);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (end[0] == '%' && end[1] == '\0')
|
||||
{
|
||||
ClutterActor *stage;
|
||||
|
||||
if (CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IS_TOPLEVEL)
|
||||
{
|
||||
g_warning ("Unable to set percentage of %s on a top-level "
|
||||
"actor of type '%s'",
|
||||
(dimension == PARSE_X ||
|
||||
dimension == PARSE_WIDTH ||
|
||||
dimension == PARSE_ANCHOR_X) ? "width" : "height",
|
||||
g_type_name (G_OBJECT_TYPE (self)));
|
||||
retval = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
stage = clutter_actor_get_stage (self);
|
||||
if (stage == NULL)
|
||||
stage = clutter_stage_get_default ();
|
||||
|
||||
if (dimension == PARSE_X ||
|
||||
dimension == PARSE_WIDTH ||
|
||||
dimension == PARSE_ANCHOR_X)
|
||||
{
|
||||
retval = clutter_actor_get_width (stage) * val;
|
||||
}
|
||||
else
|
||||
{
|
||||
retval = clutter_actor_get_height (stage) * val;
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
g_warning ("Invalid value '%s': integers, strings or floating point "
|
||||
"values can be used for the x, y, width and height "
|
||||
"properties. Valid modifiers for strings are 'px', 'mm' "
|
||||
"and '%%'.",
|
||||
g_value_get_string (&value));
|
||||
|
||||
retval = 0;
|
||||
}
|
||||
else if (G_VALUE_HOLDS (&value, G_TYPE_DOUBLE))
|
||||
{
|
||||
@ -7505,7 +7443,18 @@ clutter_actor_set_custom_property (ClutterScriptable *scriptable,
|
||||
const gchar *name,
|
||||
const GValue *value)
|
||||
{
|
||||
CLUTTER_NOTE (SCRIPT, "in ClutterActor::set_custom_property('%s')", name);
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
{
|
||||
gchar *tmp = g_strdup_value_contents (value);
|
||||
|
||||
CLUTTER_NOTE (SCRIPT,
|
||||
"in ClutterActor::set_custom_property('%s') = %s",
|
||||
name,
|
||||
tmp);
|
||||
|
||||
g_free (tmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (strcmp (name, "rotation") == 0)
|
||||
{
|
||||
|
@ -27,68 +27,39 @@
|
||||
|
||||
/**
|
||||
* SECTION:clutter-units
|
||||
* @short_description: A logical distance unit.
|
||||
* @short_description: A logical distance unit
|
||||
*
|
||||
* Clutter units are logical units with granularity greater than that of the
|
||||
* device units; they are used by #ClutterActorBox and the units-based family
|
||||
* of #ClutterActor functions. To convert between Clutter units and device
|
||||
* units, use %CLUTTER_UNITS_FROM_DEVICE and %CLUTTER_UNITS_TO_DEVICE macros.
|
||||
* #ClutterUnits is a structure holding a logical distance value along with
|
||||
* its type, expressed as a value of the #ClutterUnitType enumeration. It is
|
||||
* possible to use #ClutterUnits to store a position or a size in units
|
||||
* different than pixels, and convert them whenever needed (for instance
|
||||
* inside the #ClutterActor::allocate() virtual function, or inside the
|
||||
* #ClutterActor::get_preferred_width() and #ClutterActor::get_preferred_height()
|
||||
* virtual functions.
|
||||
*
|
||||
* #ClutterUnit<!-- -->s can be converted from other units like millimeters,
|
||||
* typographic points (at the current resolution) and percentages. It is
|
||||
* also possible to convert fixed point values to and from #ClutterUnit
|
||||
* values.
|
||||
*
|
||||
* In order to register a #ClutterUnit property, the #ClutterParamSpecUnit
|
||||
* In order to register a #ClutterUnits property, the #ClutterParamSpecUnits
|
||||
* #GParamSpec sub-class should be used:
|
||||
*
|
||||
* |[
|
||||
* GParamSpec *pspec;
|
||||
*
|
||||
* pspec = clutter_param_spec_unit ("width",
|
||||
* "Width",
|
||||
* "Width of the actor, in units",
|
||||
* 0, CLUTTER_MAXUNIT,
|
||||
* 0,
|
||||
* G_PARAM_READWRITE);
|
||||
* pspec = clutter_param_spec_units ("active-width",
|
||||
* "Width",
|
||||
* "Width of the active area, in millimeters",
|
||||
* CLUTTER_UNIT_MM,
|
||||
* 0.0, 12.0,
|
||||
* 12.0,
|
||||
* G_PARAM_READWRITE);
|
||||
* g_object_class_install_property (gobject_class, PROP_WIDTH, pspec);
|
||||
* ]|
|
||||
*
|
||||
* A #GValue holding units can be manipulated using clutter_value_set_unit()
|
||||
* and clutter_value_get_unit(). #GValue<!-- -->s containing a #ClutterUnit
|
||||
* value can also be transformed to #GValue<!-- -->s containing integer
|
||||
* values - with a loss of precision:
|
||||
* A #GValue holding units can be manipulated using clutter_value_set_units()
|
||||
* and clutter_value_get_units(). #GValue<!-- -->s containing a #ClutterUnits
|
||||
* value can also be transformed to #GValue<!-- -->s initialized with
|
||||
* %G_TYPE_INT, %G_TYPE_FLOAT and %G_TYPE_STRING through implicit conversion
|
||||
* and using g_value_transform().
|
||||
*
|
||||
* |[
|
||||
* static gboolean
|
||||
* units_to_int (const GValue *src,
|
||||
* GValue *dest)
|
||||
* {
|
||||
* g_return_val_if_fail (CLUTTER_VALUE_HOLDS_UNIT (src), FALSE);
|
||||
*
|
||||
* g_value_init (dest, G_TYPE_INT);
|
||||
* return g_value_transform (src, &dest);
|
||||
* }
|
||||
* ]|
|
||||
*
|
||||
* The code above is equivalent to:
|
||||
*
|
||||
* |[
|
||||
* static gboolean
|
||||
* units_to_int (const GValue *src,
|
||||
* GValue *dest)
|
||||
* {
|
||||
* g_return_val_if_fail (CLUTTER_VALUE_HOLDS_UNIT (src), FALSE);
|
||||
*
|
||||
* g_value_init (dest, G_TYPE_INT);
|
||||
* g_value_set_int (dest,
|
||||
* CLUTTER_UNITS_TO_INT (clutter_value_get_unit (src)));
|
||||
*
|
||||
* return TRUE;
|
||||
* }
|
||||
* ]|
|
||||
*
|
||||
* #ClutterUnit is available since Clutter 0.4
|
||||
* #ClutterUnits is available since Clutter 1.0
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -105,19 +76,8 @@
|
||||
|
||||
#define FLOAT_EPSILON (1e-30)
|
||||
|
||||
/**
|
||||
* clutter_units_mm:
|
||||
* @mm: millimeters to convert
|
||||
*
|
||||
* Converts a value in millimeters to #ClutterUnit<!-- -->s at
|
||||
* the current DPI.
|
||||
*
|
||||
* Return value: the value in units
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
ClutterUnit
|
||||
clutter_units_mm (gdouble mm)
|
||||
static gfloat
|
||||
units_mm_to_pixels (gfloat mm)
|
||||
{
|
||||
ClutterBackend *backend;
|
||||
gdouble dpi;
|
||||
@ -130,19 +90,8 @@ clutter_units_mm (gdouble mm)
|
||||
return mm * dpi / 25.4;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_units_pt:
|
||||
* @pt: typographic points to convert
|
||||
*
|
||||
* Converts a value in typographic points to #ClutterUnit<!-- -->s
|
||||
* at the current DPI.
|
||||
*
|
||||
* Return value: the value in units
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
ClutterUnit
|
||||
clutter_units_pt (gdouble pt)
|
||||
static gfloat
|
||||
units_pt_to_pixels (gfloat pt)
|
||||
{
|
||||
ClutterBackend *backend;
|
||||
gdouble dpi;
|
||||
@ -155,44 +104,9 @@ clutter_units_pt (gdouble pt)
|
||||
return pt * dpi / 72.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_units_em:
|
||||
* @em: em to convert
|
||||
*
|
||||
* Converts a value in em to #ClutterUnit<!-- -->s at the
|
||||
* current DPI
|
||||
*
|
||||
* Return value: the value in units
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
ClutterUnit
|
||||
clutter_units_em (gdouble em)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
|
||||
return em * _clutter_backend_get_units_per_em (backend, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_units_em_for_font:
|
||||
* @font_name: the font name and size
|
||||
* @em: em to convert
|
||||
*
|
||||
* Converts a value in em to #ClutterUnit<!-- -->s at the
|
||||
* current DPI for the given font name.
|
||||
*
|
||||
* The @font_name string must be in a format that
|
||||
* pango_font_description_from_string() can parse, like
|
||||
* for clutter_text_set_font_name() or clutter_backend_set_font_name().
|
||||
*
|
||||
* Return value: the value in units
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
ClutterUnit
|
||||
clutter_units_em_for_font (const gchar *font_name,
|
||||
gdouble em)
|
||||
static gfloat
|
||||
units_em_to_pixels (const gchar *font_name,
|
||||
gfloat em)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
|
||||
@ -218,19 +132,185 @@ clutter_units_em_for_font (const gchar *font_name,
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_units_pixels:
|
||||
* @px: pixels to convert
|
||||
* clutter_units_mm:
|
||||
* @units: a #ClutterUnits
|
||||
* @mm: millimeters
|
||||
*
|
||||
* Converts a value in pixels to #ClutterUnit<!-- -->s
|
||||
*
|
||||
* Return value: the value in units
|
||||
* Stores a value in millimiters inside @units
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
ClutterUnit
|
||||
clutter_units_pixels (gint px)
|
||||
void
|
||||
clutter_units_mm (ClutterUnits *units,
|
||||
gfloat mm)
|
||||
{
|
||||
return CLUTTER_UNITS_FROM_INT (px);
|
||||
g_return_if_fail (units != NULL);
|
||||
|
||||
units->unit_type = CLUTTER_UNIT_MM;
|
||||
units->value = mm;
|
||||
units->pixels = units_mm_to_pixels (mm);
|
||||
units->pixels_set = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_units_pt:
|
||||
* @units: a #ClutterUnits
|
||||
* @pt: typographic points
|
||||
*
|
||||
* Stores a value in typographic points inside @units
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_units_pt (ClutterUnits *units,
|
||||
gfloat pt)
|
||||
{
|
||||
g_return_if_fail (units != NULL);
|
||||
|
||||
units->unit_type = CLUTTER_UNIT_POINT;
|
||||
units->value = pt;
|
||||
units->pixels = units_pt_to_pixels (pt);
|
||||
units->pixels_set = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_units_em:
|
||||
* @units: a #ClutterUnits
|
||||
* @em: em
|
||||
*
|
||||
* Stores a value in em inside @units, using the default font
|
||||
* name as returned by clutter_backend_get_font_name()
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_units_em (ClutterUnits *units,
|
||||
gfloat em)
|
||||
{
|
||||
g_return_if_fail (units != NULL);
|
||||
|
||||
units->unit_type = CLUTTER_UNIT_EM;
|
||||
units->value = em;
|
||||
units->pixels = units_em_to_pixels (NULL, em);
|
||||
units->pixels_set = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_units_em_for_font:
|
||||
* @units: a #ClutterUnits
|
||||
* @font_name: the font name and size
|
||||
* @em: em
|
||||
*
|
||||
* Stores a value in em inside @units using @font_name
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_units_em_for_font (ClutterUnits *units,
|
||||
const gchar *font_name,
|
||||
gfloat em)
|
||||
{
|
||||
g_return_if_fail (units != NULL);
|
||||
|
||||
units->unit_type = CLUTTER_UNIT_EM;
|
||||
units->value = em;
|
||||
units->pixels = units_em_to_pixels (font_name, em);
|
||||
units->pixels_set = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_units_pixels:
|
||||
* @units: a #ClutterUnits
|
||||
* @px: pixels
|
||||
*
|
||||
* Stores a value in pixels inside @units
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_units_pixels (ClutterUnits *units,
|
||||
gint px)
|
||||
{
|
||||
g_return_if_fail (units != NULL);
|
||||
|
||||
units->unit_type = CLUTTER_UNIT_PIXEL;
|
||||
units->value = px;
|
||||
units->pixels = px;
|
||||
units->pixels_set = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_units_get_unit_type:
|
||||
* @units: a #ClutterUnits
|
||||
*
|
||||
* Retrieves the unit type of the value stored inside @units
|
||||
*
|
||||
* Return value: a unit type
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
ClutterUnitType
|
||||
clutter_units_get_unit_type (const ClutterUnits *units)
|
||||
{
|
||||
g_return_val_if_fail (units != NULL, CLUTTER_UNIT_PIXEL);
|
||||
|
||||
return units->unit_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_units_get_unit_value:
|
||||
* @units: a #ClutterUnits
|
||||
*
|
||||
* Retrieves the value stored inside @units
|
||||
*
|
||||
* Return value: the value stored inside a #ClutterUnits
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
gfloat
|
||||
clutter_units_get_unit_value (const ClutterUnits *units)
|
||||
{
|
||||
g_return_val_if_fail (units != NULL, 0.0);
|
||||
|
||||
return units->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_units_copy:
|
||||
* @units: the #ClutterUnits to copy
|
||||
*
|
||||
* Copies @units
|
||||
*
|
||||
* Return value: the newly created copy of a #ClutterUnits structure.
|
||||
* Use clutter_units_free() to free the allocated resources
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
ClutterUnits *
|
||||
clutter_units_copy (const ClutterUnits *units)
|
||||
{
|
||||
if (units != NULL)
|
||||
return g_slice_dup (ClutterUnits, units);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_units_free:
|
||||
* @units: the #ClutterUnits to free
|
||||
*
|
||||
* Frees the resources allocated by @units
|
||||
*
|
||||
* You should only call this function on a #ClutterUnits
|
||||
* created using clutter_units_copy()
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_units_free (ClutterUnits *units)
|
||||
{
|
||||
if (units != NULL)
|
||||
g_slice_free (ClutterUnits, units);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -243,156 +323,271 @@ clutter_units_pixels (gint px)
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
gint
|
||||
clutter_units_to_pixels (ClutterUnit units)
|
||||
gfloat
|
||||
clutter_units_to_pixels (ClutterUnits *units)
|
||||
{
|
||||
return CLUTTER_UNITS_TO_INT (units);
|
||||
g_return_val_if_fail (units != NULL, 0.0);
|
||||
|
||||
if (units->pixels_set)
|
||||
return units->pixels;
|
||||
|
||||
switch (units->unit_type)
|
||||
{
|
||||
case CLUTTER_UNIT_MM:
|
||||
units->pixels = units_mm_to_pixels (units->value);
|
||||
break;
|
||||
|
||||
case CLUTTER_UNIT_POINT:
|
||||
units->pixels = units_pt_to_pixels (units->value);
|
||||
break;
|
||||
|
||||
case CLUTTER_UNIT_EM:
|
||||
units->pixels = units_em_to_pixels (NULL, units->value);
|
||||
break;
|
||||
|
||||
case CLUTTER_UNIT_PIXEL:
|
||||
units->pixels = units->value;
|
||||
break;
|
||||
}
|
||||
|
||||
units->pixels_set = TRUE;
|
||||
|
||||
return units->pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_units_from_string:
|
||||
* @units: a #ClutterUnits
|
||||
* @str: the string to convert
|
||||
*
|
||||
* Parses a value and updates @units with it
|
||||
*
|
||||
* A #ClutterUnits expressed in string should match:
|
||||
*
|
||||
* |[
|
||||
* number: [0-9]
|
||||
* unit_value: <numbers>+
|
||||
* unit_name: px|pt|mm|em
|
||||
* units: <unit_value> <unit_name>
|
||||
* ]|
|
||||
*
|
||||
* For instance, these are valid strings:
|
||||
*
|
||||
* |[
|
||||
* 10 px
|
||||
* 5 em
|
||||
* 24 pt
|
||||
* 12.6 mm
|
||||
* ]|
|
||||
*
|
||||
* Return value: %TRUE if the string was successfully parsed
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
gboolean
|
||||
clutter_units_from_string (ClutterUnits *units,
|
||||
const gchar *str)
|
||||
{
|
||||
ClutterUnitType unit_type;
|
||||
gfloat value;
|
||||
|
||||
g_return_val_if_fail (units != NULL, FALSE);
|
||||
g_return_val_if_fail (str != NULL, FALSE);
|
||||
|
||||
/* Ensure that the first character is a digit */
|
||||
while (g_ascii_isspace (*str))
|
||||
str++;
|
||||
|
||||
if (*str == '\0')
|
||||
return FALSE;
|
||||
|
||||
if (!g_ascii_isdigit (*str))
|
||||
return FALSE;
|
||||
|
||||
/* integer part */
|
||||
value = (gfloat) strtoul (str, (char **) &str, 10);
|
||||
|
||||
if (*str == '.' || *str == ',')
|
||||
{
|
||||
glong frac = 100000;
|
||||
|
||||
while (g_ascii_isdigit (*++str))
|
||||
{
|
||||
frac += (*str - '0') * frac;
|
||||
frac /= 10;
|
||||
}
|
||||
|
||||
value += (1.0f / (gfloat) frac);
|
||||
}
|
||||
|
||||
/* assume pixels by default, if no unit is specified */
|
||||
if (str == '\0')
|
||||
unit_type = CLUTTER_UNIT_PIXEL;
|
||||
else
|
||||
{
|
||||
while (g_ascii_isspace (*str))
|
||||
str++;
|
||||
|
||||
if (strncmp (str, "em", 2) == 0)
|
||||
unit_type = CLUTTER_UNIT_EM;
|
||||
else if (strncmp (str, "mm", 2) == 0)
|
||||
unit_type = CLUTTER_UNIT_MM;
|
||||
else if (strncmp (str, "pt", 2) == 0)
|
||||
unit_type = CLUTTER_UNIT_POINT;
|
||||
else if (strncmp (str, "px", 2) == 0)
|
||||
unit_type = CLUTTER_UNIT_PIXEL;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
units->unit_type = unit_type;
|
||||
units->value = value;
|
||||
units->pixels_set = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_units_to_string:
|
||||
* @units: a #ClutterUnits
|
||||
*
|
||||
* Converts @units into a string
|
||||
*
|
||||
* See clutter_units_from_string() for the units syntax and for
|
||||
* examples of outputs
|
||||
*
|
||||
* Return value: a newly allocated string containing the encoded
|
||||
* #ClutterUnits value. Use g_free() to free the string
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
gchar *
|
||||
clutter_units_to_string (const ClutterUnits *units)
|
||||
{
|
||||
const gchar *unit_name;
|
||||
gchar *fmt;
|
||||
|
||||
g_return_val_if_fail (units != NULL, NULL);
|
||||
|
||||
switch (units->unit_type)
|
||||
{
|
||||
case CLUTTER_UNIT_MM:
|
||||
unit_name = "mm";
|
||||
fmt = g_strdup_printf ("%.2f", units->value);
|
||||
break;
|
||||
|
||||
case CLUTTER_UNIT_POINT:
|
||||
unit_name = "pt";
|
||||
fmt = g_strdup_printf ("%.1f", units->value);
|
||||
break;
|
||||
|
||||
case CLUTTER_UNIT_EM:
|
||||
unit_name = "em";
|
||||
fmt = g_strdup_printf ("%.2f", units->value);
|
||||
break;
|
||||
|
||||
case CLUTTER_UNIT_PIXEL:
|
||||
unit_name = "px";
|
||||
fmt = g_strdup_printf ("%d", (int) units->value);
|
||||
break;
|
||||
}
|
||||
|
||||
return g_strconcat (fmt, " ", unit_name, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* GValue and GParamSpec integration
|
||||
*/
|
||||
|
||||
static GTypeInfo _info = {
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static GTypeFundamentalInfo _finfo = { 0, };
|
||||
|
||||
/* units to integer */
|
||||
static void
|
||||
clutter_value_init_unit (GValue *value)
|
||||
clutter_value_transform_units_int (const GValue *src,
|
||||
GValue *dest)
|
||||
{
|
||||
value->data[0].v_float = 0.0;
|
||||
dest->data[0].v_int = clutter_units_to_pixels (src->data[0].v_pointer);
|
||||
}
|
||||
|
||||
/* integer to units */
|
||||
static void
|
||||
clutter_value_copy_unit (const GValue *src,
|
||||
GValue *dest)
|
||||
clutter_value_transform_int_units (const GValue *src,
|
||||
GValue *dest)
|
||||
{
|
||||
dest->data[0].v_float = src->data[0].v_float;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
clutter_value_collect_unit (GValue *value,
|
||||
guint n_collect_values,
|
||||
GTypeCValue *collect_values,
|
||||
guint collect_flags)
|
||||
{
|
||||
value->data[0].v_float = collect_values[0].v_double;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
clutter_value_lcopy_unit (const GValue *value,
|
||||
guint n_collect_values,
|
||||
GTypeCValue *collect_values,
|
||||
guint collect_flags)
|
||||
{
|
||||
gfloat *units_p = collect_values[0].v_pointer;
|
||||
|
||||
if (!units_p)
|
||||
return g_strdup_printf ("value location for '%s' passed as NULL",
|
||||
G_VALUE_TYPE_NAME (value));
|
||||
|
||||
*units_p = value->data[0].v_float;
|
||||
|
||||
return NULL;
|
||||
clutter_units_pixels (dest->data[0].v_pointer, src->data[0].v_int);
|
||||
}
|
||||
|
||||
/* units to float */
|
||||
static void
|
||||
clutter_value_transform_unit_int (const GValue *src,
|
||||
GValue *dest)
|
||||
clutter_value_transform_units_float (const GValue *src,
|
||||
GValue *dest)
|
||||
{
|
||||
dest->data[0].v_int = CLUTTER_UNITS_TO_INT (src->data[0].v_float);
|
||||
dest->data[0].v_float = clutter_units_to_pixels (src->data[0].v_pointer);
|
||||
}
|
||||
|
||||
/* float to units */
|
||||
static void
|
||||
clutter_value_transform_int_unit (const GValue *src,
|
||||
GValue *dest)
|
||||
clutter_value_transform_float_units (const GValue *src,
|
||||
GValue *dest)
|
||||
{
|
||||
dest->data[0].v_float = CLUTTER_UNITS_FROM_INT (src->data[0].v_int);
|
||||
clutter_units_pixels (dest->data[0].v_pointer, src->data[0].v_float);
|
||||
}
|
||||
|
||||
/* units to string */
|
||||
static void
|
||||
clutter_value_transform_unit_float (const GValue *src,
|
||||
GValue *dest)
|
||||
clutter_value_transform_units_string (const GValue *src,
|
||||
GValue *dest)
|
||||
{
|
||||
dest->data[0].v_float = CLUTTER_UNITS_TO_FLOAT (src->data[0].v_float);
|
||||
gchar *string = clutter_units_to_string (src->data[0].v_pointer);
|
||||
|
||||
g_value_take_string (dest, string);
|
||||
}
|
||||
|
||||
/* string to units */
|
||||
static void
|
||||
clutter_value_transform_float_unit (const GValue *src,
|
||||
GValue *dest)
|
||||
clutter_value_transform_string_units (const GValue *src,
|
||||
GValue *dest)
|
||||
{
|
||||
dest->data[0].v_float = CLUTTER_UNITS_FROM_FLOAT (src->data[0].v_float);
|
||||
}
|
||||
ClutterUnits units = { CLUTTER_UNIT_PIXEL, 0.0f };
|
||||
|
||||
#if 0
|
||||
static void
|
||||
clutter_value_transform_unit_fixed (const GValue *src,
|
||||
GValue *dest)
|
||||
{
|
||||
dest->data[0].v_int = CLUTTER_UNITS_TO_FIXED (src->data[0].v_float);
|
||||
}
|
||||
clutter_units_from_string (&units, g_value_get_string (src));
|
||||
|
||||
static void
|
||||
clutter_value_transform_fixed_unit (const GValue *src,
|
||||
GValue *dest)
|
||||
{
|
||||
dest->data[0].v_float = CLUTTER_UNITS_FROM_FIXED (src->data[0].v_int);
|
||||
clutter_value_set_units (dest, &units);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const GTypeValueTable _clutter_unit_value_table = {
|
||||
clutter_value_init_unit,
|
||||
NULL,
|
||||
clutter_value_copy_unit,
|
||||
NULL,
|
||||
"d",
|
||||
clutter_value_collect_unit,
|
||||
"p",
|
||||
clutter_value_lcopy_unit
|
||||
};
|
||||
|
||||
GType
|
||||
clutter_unit_get_type (void)
|
||||
clutter_units_get_type (void)
|
||||
{
|
||||
static GType _clutter_unit_type = 0;
|
||||
static volatile gsize clutter_units_type__volatile = 0;
|
||||
|
||||
if (G_UNLIKELY (_clutter_unit_type == 0))
|
||||
if (g_once_init_enter (&clutter_units_type__volatile))
|
||||
{
|
||||
_info.value_table = & _clutter_unit_value_table;
|
||||
_clutter_unit_type =
|
||||
g_type_register_fundamental (g_type_fundamental_next (),
|
||||
I_("ClutterUnit"),
|
||||
&_info, &_finfo, 0);
|
||||
GType clutter_units_type =
|
||||
g_boxed_type_register_static (I_("ClutterUnits"),
|
||||
(GBoxedCopyFunc) clutter_units_copy,
|
||||
(GBoxedFreeFunc) clutter_units_free);
|
||||
|
||||
g_value_register_transform_func (_clutter_unit_type, G_TYPE_INT,
|
||||
clutter_value_transform_unit_int);
|
||||
g_value_register_transform_func (G_TYPE_INT, _clutter_unit_type,
|
||||
clutter_value_transform_int_unit);
|
||||
g_value_register_transform_func (clutter_units_type, G_TYPE_INT,
|
||||
clutter_value_transform_units_int);
|
||||
g_value_register_transform_func (G_TYPE_INT, clutter_units_type,
|
||||
clutter_value_transform_int_units);
|
||||
|
||||
g_value_register_transform_func (_clutter_unit_type, G_TYPE_FLOAT,
|
||||
clutter_value_transform_unit_float);
|
||||
g_value_register_transform_func (G_TYPE_FLOAT, _clutter_unit_type,
|
||||
clutter_value_transform_float_unit);
|
||||
g_value_register_transform_func (clutter_units_type, G_TYPE_FLOAT,
|
||||
clutter_value_transform_units_float);
|
||||
g_value_register_transform_func (G_TYPE_FLOAT, clutter_units_type,
|
||||
clutter_value_transform_float_units);
|
||||
|
||||
g_value_register_transform_func (clutter_units_type, G_TYPE_STRING,
|
||||
clutter_value_transform_units_string);
|
||||
g_value_register_transform_func (G_TYPE_STRING, clutter_units_type,
|
||||
clutter_value_transform_string_units);
|
||||
|
||||
g_once_init_leave (&clutter_units_type__volatile, clutter_units_type);
|
||||
}
|
||||
|
||||
return _clutter_unit_type;
|
||||
return clutter_units_type__volatile;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_value_set_unit:
|
||||
* clutter_value_set_units:
|
||||
* @value: a #GValue initialized to #CLUTTER_TYPE_UNIT
|
||||
* @units: the units to set
|
||||
*
|
||||
@ -401,16 +596,16 @@ clutter_unit_get_type (void)
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
clutter_value_set_unit (GValue *value,
|
||||
ClutterUnit units)
|
||||
clutter_value_set_units (GValue *value,
|
||||
const ClutterUnits *units)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_VALUE_HOLDS_UNIT (value));
|
||||
g_return_if_fail (CLUTTER_VALUE_HOLDS_UNITS (value));
|
||||
|
||||
value->data[0].v_float = units;
|
||||
value->data[0].v_pointer = clutter_units_copy (units);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_value_get_unit:
|
||||
* clutter_value_get_units:
|
||||
* @value: a #GValue initialized to #CLUTTER_TYPE_UNIT
|
||||
*
|
||||
* Gets the #ClutterUnit<!-- -->s contained in @value.
|
||||
@ -419,76 +614,98 @@ clutter_value_set_unit (GValue *value,
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
ClutterUnit
|
||||
G_CONST_RETURN ClutterUnits *
|
||||
clutter_value_get_unit (const GValue *value)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_VALUE_HOLDS_UNIT (value), 0);
|
||||
g_return_val_if_fail (CLUTTER_VALUE_HOLDS_UNITS (value), NULL);
|
||||
|
||||
return value->data[0].v_float;
|
||||
return value->data[0].v_pointer;
|
||||
}
|
||||
|
||||
static void
|
||||
param_unit_init (GParamSpec *pspec)
|
||||
param_units_init (GParamSpec *pspec)
|
||||
{
|
||||
ClutterParamSpecUnit *uspec = CLUTTER_PARAM_SPEC_UNIT (pspec);
|
||||
ClutterParamSpecUnits *uspec = CLUTTER_PARAM_SPEC_UNITS (pspec);
|
||||
|
||||
uspec->minimum = CLUTTER_MINUNIT;
|
||||
uspec->maximum = CLUTTER_MAXUNIT;
|
||||
uspec->default_value = 0;
|
||||
uspec->minimum = -G_MAXFLOAT;
|
||||
uspec->maximum = G_MAXFLOAT;
|
||||
uspec->default_value = 0.0f;
|
||||
uspec->default_type = CLUTTER_UNIT_PIXEL;
|
||||
}
|
||||
|
||||
static void
|
||||
param_unit_set_default (GParamSpec *pspec,
|
||||
GValue *value)
|
||||
param_units_set_default (GParamSpec *pspec,
|
||||
GValue *value)
|
||||
{
|
||||
value->data[0].v_float = CLUTTER_PARAM_SPEC_UNIT (pspec)->default_value;
|
||||
ClutterParamSpecUnits *uspec = CLUTTER_PARAM_SPEC_UNITS (pspec);
|
||||
ClutterUnits units;
|
||||
|
||||
units.unit_type = uspec->default_type;
|
||||
units.value = uspec->default_value;
|
||||
units.pixels_set = FALSE;
|
||||
|
||||
clutter_value_set_units (value, &units);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
param_unit_validate (GParamSpec *pspec,
|
||||
GValue *value)
|
||||
param_units_validate (GParamSpec *pspec,
|
||||
GValue *value)
|
||||
{
|
||||
ClutterParamSpecUnit *uspec = CLUTTER_PARAM_SPEC_UNIT (pspec);
|
||||
gfloat oval = value->data[0].v_float;
|
||||
ClutterParamSpecUnits *uspec = CLUTTER_PARAM_SPEC_UNITS (pspec);
|
||||
ClutterUnits *units = value->data[0].v_pointer;
|
||||
gfloat oval = units->value;
|
||||
|
||||
g_assert (CLUTTER_IS_PARAM_SPEC_UNIT (pspec));
|
||||
g_assert (CLUTTER_IS_PARAM_SPEC_UNITS (pspec));
|
||||
|
||||
value->data[0].v_float = CLAMP (value->data[0].v_float,
|
||||
uspec->minimum,
|
||||
uspec->maximum);
|
||||
units->value = CLAMP (units->value,
|
||||
uspec->minimum,
|
||||
uspec->maximum);
|
||||
|
||||
return value->data[0].v_float != oval;
|
||||
return units->value != oval;
|
||||
}
|
||||
|
||||
static gint
|
||||
param_unit_values_cmp (GParamSpec *pspec,
|
||||
const GValue *value1,
|
||||
const GValue *value2)
|
||||
param_units_values_cmp (GParamSpec *pspec,
|
||||
const GValue *value1,
|
||||
const GValue *value2)
|
||||
{
|
||||
gfloat epsilon = FLOAT_EPSILON;
|
||||
ClutterUnits *units1 = value1->data[0].v_pointer;
|
||||
ClutterUnits *units2 = value2->data[0].v_pointer;
|
||||
gfloat v1, v2;
|
||||
|
||||
if (value1->data[0].v_float < value2->data[0].v_float)
|
||||
return - (value2->data[0].v_float - value1->data[0].v_float > epsilon);
|
||||
if (units1->unit_type == units2->unit_type)
|
||||
{
|
||||
v1 = units1->value;
|
||||
v2 = units2->value;
|
||||
}
|
||||
else
|
||||
return value1->data[0].v_float - value2->data[0].v_float > epsilon;
|
||||
{
|
||||
v1 = clutter_units_to_pixels (units1);
|
||||
v2 = clutter_units_to_pixels (units2);
|
||||
}
|
||||
|
||||
if (v1 < v2)
|
||||
return - (v2 - v1 > FLOAT_EPSILON);
|
||||
else
|
||||
return v1 - v2 > FLOAT_EPSILON;
|
||||
}
|
||||
|
||||
GType
|
||||
clutter_param_unit_get_type (void)
|
||||
clutter_param_units_get_type (void)
|
||||
{
|
||||
static GType pspec_type = 0;
|
||||
|
||||
if (G_UNLIKELY (pspec_type == 0))
|
||||
{
|
||||
const GParamSpecTypeInfo pspec_info = {
|
||||
sizeof (ClutterParamSpecUnit),
|
||||
sizeof (ClutterParamSpecUnits),
|
||||
16,
|
||||
param_unit_init,
|
||||
CLUTTER_TYPE_UNIT,
|
||||
param_units_init,
|
||||
CLUTTER_TYPE_UNITS,
|
||||
NULL,
|
||||
param_unit_set_default,
|
||||
param_unit_validate,
|
||||
param_unit_values_cmp,
|
||||
param_units_set_default,
|
||||
param_units_validate,
|
||||
param_units_values_cmp,
|
||||
};
|
||||
|
||||
pspec_type = g_param_type_register_static (I_("ClutterParamSpecUnit"),
|
||||
@ -499,38 +716,42 @@ clutter_param_unit_get_type (void)
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_param_spec_unit:
|
||||
* clutter_param_spec_units:
|
||||
* @name: name of the property
|
||||
* @nick: short name
|
||||
* @blurb: description (can be translatable)
|
||||
* @default_type: the default type for the #ClutterUnits
|
||||
* @minimum: lower boundary
|
||||
* @maximum: higher boundary
|
||||
* @default_value: default value
|
||||
* @flags: flags for the param spec
|
||||
*
|
||||
* Creates a #GParamSpec for properties using #ClutterUnit<!-- -->s.
|
||||
* Creates a #GParamSpec for properties using #ClutterUnits.
|
||||
*
|
||||
* Return value: the newly created #GParamSpec
|
||||
*
|
||||
* Since: 0.8
|
||||
* Since: 1.0
|
||||
*/
|
||||
GParamSpec *
|
||||
clutter_param_spec_unit (const gchar *name,
|
||||
const gchar *nick,
|
||||
const gchar *blurb,
|
||||
ClutterUnit minimum,
|
||||
ClutterUnit maximum,
|
||||
ClutterUnit default_value,
|
||||
GParamFlags flags)
|
||||
clutter_param_spec_units (const gchar *name,
|
||||
const gchar *nick,
|
||||
const gchar *blurb,
|
||||
ClutterUnitType default_type,
|
||||
gfloat minimum,
|
||||
gfloat maximum,
|
||||
gfloat default_value,
|
||||
GParamFlags flags)
|
||||
{
|
||||
ClutterParamSpecUnit *uspec;
|
||||
ClutterParamSpecUnits *uspec;
|
||||
|
||||
g_return_val_if_fail (default_value >= minimum && default_value <= maximum,
|
||||
NULL);
|
||||
|
||||
uspec = g_param_spec_internal (CLUTTER_TYPE_PARAM_UNIT,
|
||||
uspec = g_param_spec_internal (CLUTTER_TYPE_PARAM_UNITS,
|
||||
name, nick, blurb,
|
||||
flags);
|
||||
|
||||
uspec->default_type = default_type;
|
||||
uspec->minimum = minimum;
|
||||
uspec->maximum = maximum;
|
||||
uspec->default_value = default_value;
|
||||
|
@ -25,7 +25,7 @@
|
||||
*/
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly.h"
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __CLUTTER_UNITS_H__
|
||||
@ -38,240 +38,131 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* ClutterUnit:
|
||||
* ClutterUnitType:
|
||||
* @CLUTTER_UNIT_PIXEL: Unit expressed in pixels (with subpixel precision)
|
||||
* @CLUTTER_UNIT_EM: Unit expressed in em
|
||||
* @CLUTTER_UNIT_MM: Unit expressed in millimeters
|
||||
* @CLUTTER_UNIT_POINT: Unit expressed in points
|
||||
*
|
||||
* Device independent unit used by Clutter. The value held can be
|
||||
* transformed into other units, likes pixels
|
||||
* The type of unit in which a value is expressed
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
typedef float ClutterUnit;
|
||||
|
||||
/**
|
||||
* CLUTTER_UNITS_FROM_INT:
|
||||
* @x: integer value
|
||||
*
|
||||
* Converts @x from an integer value to #ClutterUnit<!-- -->s
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
#define CLUTTER_UNITS_FROM_INT(x) ((float)(x))
|
||||
|
||||
/**
|
||||
* CLUTTER_UNITS_TO_INT:
|
||||
* @x: value in #ClutterUnit<!-- -->s
|
||||
*
|
||||
* Converts @x from a #ClutterUnit value into an integer
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
#define CLUTTER_UNITS_TO_INT(x) ((int)(x))
|
||||
|
||||
/**
|
||||
* CLUTTER_UNITS_FROM_FLOAT:
|
||||
* @x: float value
|
||||
*
|
||||
* Converts @x from a floating point value to #ClutterUnit<!-- -->s
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
#define CLUTTER_UNITS_FROM_FLOAT(x) (x)
|
||||
|
||||
/**
|
||||
* CLUTTER_UNITS_TO_FLOAT:
|
||||
* @x: value in #ClutterUnit<!-- -->s
|
||||
*
|
||||
* Converts @x from a #ClutterUnit value into a float
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
#define CLUTTER_UNITS_TO_FLOAT(x) (x)
|
||||
|
||||
/**
|
||||
* CLUTTER_UNITS_FROM_FIXED:
|
||||
* @x: #CoglFixed value
|
||||
*
|
||||
* Converts @x from a fixed point value to #ClutterUnit<!-- -->s
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
#define CLUTTER_UNITS_FROM_FIXED(x) (COGL_FIXED_TO_FLOAT (x))
|
||||
|
||||
/**
|
||||
* CLUTTER_UNITS_TO_FIXED:
|
||||
* @x: value in #ClutterUnit<!-- -->s
|
||||
*
|
||||
* Converts @x from a #ClutterUnit value into a #CoglFixed
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
#define CLUTTER_UNITS_TO_FIXED(x) (COGL_FIXED_FROM_FLOAT (x))
|
||||
|
||||
/**
|
||||
* CLUTTER_UNITS_FORMAT:
|
||||
*
|
||||
* Format string that should be used for scanning and printing units.
|
||||
* It is a string literal, but it does not include the percent sign to
|
||||
* allow precision and length modifiers between the percent sign and
|
||||
* the format:
|
||||
*
|
||||
* |[
|
||||
* g_print ("%" CLUTTER_UNITS_FORMAT, units);
|
||||
* ]|
|
||||
* This enumeration might be expanded at later date
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
#define CLUTTER_UNITS_FORMAT "f"
|
||||
typedef enum {
|
||||
CLUTTER_UNIT_PIXEL,
|
||||
CLUTTER_UNIT_EM,
|
||||
CLUTTER_UNIT_MM,
|
||||
CLUTTER_UNIT_POINT
|
||||
} ClutterUnitType;
|
||||
|
||||
/**
|
||||
* CLUTTER_UNITS_FROM_DEVICE:
|
||||
* @x: value in pixels
|
||||
* ClutterUnits:
|
||||
*
|
||||
* Converts @x from pixels to #ClutterUnit<!-- -->s
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
#define CLUTTER_UNITS_FROM_DEVICE(x) (clutter_units_pixels ((x)))
|
||||
|
||||
/**
|
||||
* CLUTTER_UNITS_TO_DEVICE:
|
||||
* @x: value in #ClutterUnit<!-- -->s
|
||||
*
|
||||
* Converts @x from #ClutterUnit<!-- -->s to pixels
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
#define CLUTTER_UNITS_TO_DEVICE(x) (clutter_units_to_pixels ((x)))
|
||||
|
||||
/**
|
||||
* CLUTTER_UNITS_FROM_PANGO_UNIT:
|
||||
* @x: value in Pango units
|
||||
*
|
||||
* Converts a value in Pango units to #ClutterUnit<!-- -->s
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
#define CLUTTER_UNITS_FROM_PANGO_UNIT(x) ((float)((x) / 1024.0))
|
||||
|
||||
/**
|
||||
* CLUTTER_UNITS_TO_PANGO_UNIT:
|
||||
* @x: value in #ClutterUnit<!-- -->s
|
||||
*
|
||||
* Converts a value in #ClutterUnit<!-- -->s to Pango units
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
#define CLUTTER_UNITS_TO_PANGO_UNIT(x) ((int)((x) * 1024))
|
||||
|
||||
/**
|
||||
* CLUTTER_UNITS_FROM_MM:
|
||||
* @x: a value in millimeters
|
||||
*
|
||||
* Converts a value in millimeters into #ClutterUnit<!-- -->s
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
#define CLUTTER_UNITS_FROM_MM(x) (clutter_units_mm (x))
|
||||
|
||||
/**
|
||||
* CLUTTER_UNITS_FROM_POINTS:
|
||||
* @x: a value in typographic points
|
||||
*
|
||||
* Converts a value in typographic points into #ClutterUnit<!-- -->s
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
#define CLUTTER_UNITS_FROM_POINTS(x) (clutter_units_pt (x))
|
||||
|
||||
/**
|
||||
* CLUTTER_UNITS_FROM_EM:
|
||||
* @x: a value in em
|
||||
*
|
||||
* Converts a value in em into #ClutterUnit<!-- -->s
|
||||
* An opaque structure, to be used to store sizing and positioning
|
||||
* values along with their unit.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
#define CLUTTER_UNITS_FROM_EM(x) (clutter_units_em (x))
|
||||
typedef struct _ClutterUnits ClutterUnits;
|
||||
|
||||
ClutterUnit clutter_units_mm (gdouble mm);
|
||||
ClutterUnit clutter_units_pt (gdouble pt);
|
||||
ClutterUnit clutter_units_em (gdouble em);
|
||||
ClutterUnit clutter_units_em_for_font (const gchar *font_name,
|
||||
gdouble em);
|
||||
ClutterUnit clutter_units_pixels (gint px);
|
||||
struct _ClutterUnits
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterUnitType unit_type;
|
||||
|
||||
gint clutter_units_to_pixels (ClutterUnit units);
|
||||
gfloat value;
|
||||
|
||||
#define CLUTTER_TYPE_UNIT (clutter_unit_get_type ())
|
||||
#define CLUTTER_TYPE_PARAM_UNIT (clutter_param_unit_get_type ())
|
||||
#define CLUTTER_PARAM_SPEC_UNIT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), CLUTTER_TYPE_PARAM_UNIT, ClutterParamSpecUnit))
|
||||
#define CLUTTER_IS_PARAM_SPEC_UNIT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), CLUTTER_TYPE_PARAM_UNIT))
|
||||
/* pre-filled by the provided constructors */
|
||||
gfloat pixels;
|
||||
guint pixels_set;
|
||||
|
||||
/**
|
||||
* CLUTTER_MAXUNIT:
|
||||
*
|
||||
* Higher boundary for a #ClutterUnit
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
#define CLUTTER_MAXUNIT (G_MAXFLOAT)
|
||||
/* padding for eventual expansion */
|
||||
gint64 __padding_1;
|
||||
gint64 __padding_2;
|
||||
};
|
||||
|
||||
/**
|
||||
* CLUTTER_MINUNIT:
|
||||
*
|
||||
* Lower boundary for a #ClutterUnit
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
#define CLUTTER_MINUNIT (-G_MAXFLOAT)
|
||||
GType clutter_units_get_type (void) G_GNUC_CONST;
|
||||
ClutterUnitType clutter_units_get_unit_type (const ClutterUnits *units);
|
||||
gfloat clutter_units_get_unit_value (const ClutterUnits *units);
|
||||
|
||||
ClutterUnits * clutter_units_copy (const ClutterUnits *units);
|
||||
void clutter_units_free (ClutterUnits *units);
|
||||
|
||||
void clutter_units_pixels (ClutterUnits *units,
|
||||
gint px);
|
||||
void clutter_units_em (ClutterUnits *units,
|
||||
gfloat em);
|
||||
void clutter_units_em_for_font (ClutterUnits *units,
|
||||
const gchar *font_name,
|
||||
gfloat em);
|
||||
void clutter_units_mm (ClutterUnits *units,
|
||||
gfloat mm);
|
||||
void clutter_units_pt (ClutterUnits *units,
|
||||
gfloat pt);
|
||||
|
||||
gfloat clutter_units_to_pixels (ClutterUnits *units);
|
||||
|
||||
gchar * clutter_units_to_string (const ClutterUnits *units);
|
||||
gboolean clutter_units_from_string (ClutterUnits *units,
|
||||
const gchar *str);
|
||||
|
||||
#define CLUTTER_TYPE_UNITS (clutter_units_get_type ())
|
||||
#define CLUTTER_TYPE_PARAM_UNITS (clutter_param_units_get_type ())
|
||||
#define CLUTTER_PARAM_SPEC_UNITS(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), CLUTTER_TYPE_PARAM_UNITS, ClutterParamSpecUnits))
|
||||
#define CLUTTER_IS_PARAM_SPEC_UNITS(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), CLUTTER_TYPE_PARAM_UNITS))
|
||||
|
||||
/**
|
||||
* CLUTTER_VALUE_HOLDS_UNIT:
|
||||
* @x: a #GValue
|
||||
*
|
||||
* Evaluates to %TRUE if @x holds #ClutterUnit<!-- -->s.
|
||||
* Evaluates to %TRUE if @x holds a #ClutterUnits value
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
#define CLUTTER_VALUE_HOLDS_UNIT(x) (G_VALUE_HOLDS ((x), CLUTTER_TYPE_UNIT))
|
||||
#define CLUTTER_VALUE_HOLDS_UNITS(x) (G_VALUE_HOLDS ((x), CLUTTER_TYPE_UNITS))
|
||||
|
||||
typedef struct _ClutterParamSpecUnit ClutterParamSpecUnit;
|
||||
typedef struct _ClutterParamSpecUnits ClutterParamSpecUnits;
|
||||
|
||||
/**
|
||||
* ClutterParamSpecUnit:
|
||||
* ClutterParamSpecUnits:
|
||||
* @default_type: default type
|
||||
* @default_value: default value
|
||||
* @minimum: lower boundary
|
||||
* @maximum: higher boundary
|
||||
* @default_value: default value
|
||||
*
|
||||
* #GParamSpec subclass for unit based properties.
|
||||
*
|
||||
* Since: 0.8
|
||||
* Since: 1.0
|
||||
*/
|
||||
struct _ClutterParamSpecUnit
|
||||
struct _ClutterParamSpecUnits
|
||||
{
|
||||
/*< private >*/
|
||||
GParamSpec parent_instance;
|
||||
GParamSpec parent_instance;
|
||||
|
||||
/*< public >*/
|
||||
ClutterUnit minimum;
|
||||
ClutterUnit maximum;
|
||||
ClutterUnit default_value;
|
||||
ClutterUnitType default_type;
|
||||
|
||||
gfloat default_value;
|
||||
gfloat minimum;
|
||||
gfloat maximum;
|
||||
};
|
||||
|
||||
GType clutter_unit_get_type (void) G_GNUC_CONST;
|
||||
GType clutter_param_unit_get_type (void) G_GNUC_CONST;
|
||||
GType clutter_param_units_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void clutter_value_set_unit (GValue *value,
|
||||
ClutterUnit units);
|
||||
ClutterUnit clutter_value_get_unit (const GValue *value);
|
||||
GParamSpec * clutter_param_spec_units (const gchar *name,
|
||||
const gchar *nick,
|
||||
const gchar *blurb,
|
||||
ClutterUnitType default_type,
|
||||
gfloat minimum,
|
||||
gfloat maximum,
|
||||
gfloat default_value,
|
||||
GParamFlags flags);
|
||||
|
||||
GParamSpec *clutter_param_spec_unit (const gchar *name,
|
||||
const gchar *nick,
|
||||
const gchar *blurb,
|
||||
ClutterUnit minimum,
|
||||
ClutterUnit maximum,
|
||||
ClutterUnit default_value,
|
||||
GParamFlags flags);
|
||||
void clutter_value_set_units (GValue *value,
|
||||
const ClutterUnits *units);
|
||||
G_CONST_RETURN ClutterUnits *clutter_value_get_units (const GValue *value);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -27,45 +27,35 @@ clutter_media_get_type
|
||||
<SECTION>
|
||||
<FILE>clutter-units</FILE>
|
||||
<TITLE>Unit conversion</TITLE>
|
||||
ClutterUnit
|
||||
CLUTTER_UNITS_FORMAT
|
||||
CLUTTER_UNITS_FROM_FLOAT
|
||||
CLUTTER_UNITS_TO_FLOAT
|
||||
CLUTTER_UNITS_FROM_INT
|
||||
CLUTTER_UNITS_TO_INT
|
||||
|
||||
<SUBSECTION>
|
||||
CLUTTER_UNITS_FROM_DEVICE
|
||||
CLUTTER_UNITS_TO_DEVICE
|
||||
CLUTTER_UNITS_FROM_FIXED
|
||||
CLUTTER_UNITS_TO_FIXED
|
||||
CLUTTER_UNITS_FROM_PANGO_UNIT
|
||||
CLUTTER_UNITS_TO_PANGO_UNIT
|
||||
CLUTTER_UNITS_FROM_MM
|
||||
CLUTTER_UNITS_FROM_POINTS
|
||||
CLUTTER_UNITS_FROM_EM
|
||||
ClutterUnitType
|
||||
ClutterUnits
|
||||
clutter_units_mm
|
||||
clutter_units_pt
|
||||
clutter_units_em
|
||||
clutter_units_em_for_font
|
||||
clutter_units_pixels
|
||||
clutter_units_to_pixels
|
||||
clutter_units_copy
|
||||
clutter_units_free
|
||||
clutter_units_get_unit_type
|
||||
clutter_units_get_unit_value
|
||||
clutter_units_from_string
|
||||
clutter_units_to_string
|
||||
|
||||
<SUBSECTION>
|
||||
CLUTTER_MAXUNIT
|
||||
CLUTTER_MINUNIT
|
||||
ClutterParamSpecUnit
|
||||
clutter_param_spec_unit
|
||||
CLUTTER_VALUE_HOLDS_UNIT
|
||||
clutter_value_set_unit
|
||||
clutter_value_get_unit
|
||||
ClutterParamSpecUnits
|
||||
clutter_param_spec_units
|
||||
CLUTTER_VALUE_HOLDS_UNITS
|
||||
clutter_value_set_units
|
||||
clutter_value_get_units
|
||||
|
||||
<SUBSECTION Private>
|
||||
CLUTTER_TYPE_UNIT
|
||||
CLUTTER_TYPE_PARAM_UNIT
|
||||
CLUTTER_PARAM_SPEC_UNIT
|
||||
CLUTTER_IS_PARAM_SPEC_UNIT
|
||||
clutter_unit_get_type
|
||||
clutter_param_unit_get_type
|
||||
CLUTTER_TYPE_UNITS
|
||||
CLUTTER_TYPE_PARAM_UNITS
|
||||
CLUTTER_PARAM_SPEC_UNITS
|
||||
CLUTTER_IS_PARAM_SPEC_UNITS
|
||||
clutter_units_get_type
|
||||
clutter_param_units_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
@ -30,6 +30,7 @@ test_conformance_SOURCES = \
|
||||
test-model.c \
|
||||
test-blend-strings.c \
|
||||
test-color.c \
|
||||
test-clutter-units.c \
|
||||
$(NULL)
|
||||
|
||||
# For convenience, this provides a way to easily run individual unit tests:
|
||||
|
58
tests/conform/test-clutter-units.c
Normal file
58
tests/conform/test-clutter-units.c
Normal file
@ -0,0 +1,58 @@
|
||||
#include <stdio.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
void
|
||||
test_units_constructors (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
ClutterUnits units;
|
||||
|
||||
clutter_units_pixels (&units, 100);
|
||||
g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_PIXEL);
|
||||
g_assert_cmpfloat (clutter_units_get_unit_value (&units), ==, 100.0);
|
||||
g_assert_cmpfloat (clutter_units_to_pixels (&units), ==, 100.0);
|
||||
|
||||
clutter_units_em (&units, 5.0);
|
||||
g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_EM);
|
||||
g_assert_cmpfloat (clutter_units_get_unit_value (&units), ==, 5.0);
|
||||
g_assert_cmpfloat (clutter_units_to_pixels (&units), !=, 5.0);
|
||||
}
|
||||
|
||||
void
|
||||
test_units_string (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
ClutterUnits units;
|
||||
gchar *string;
|
||||
|
||||
g_assert (clutter_units_from_string (&units, "5 em") == TRUE);
|
||||
g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_EM);
|
||||
g_assert_cmpfloat (clutter_units_get_unit_value (&units), ==, 5);
|
||||
|
||||
g_assert (clutter_units_from_string (&units, " 16 mm") == TRUE);
|
||||
g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_MM);
|
||||
g_assert_cmpfloat (clutter_units_get_unit_value (&units), ==, 16);
|
||||
|
||||
g_assert (clutter_units_from_string (&units, "1 pony") == FALSE);
|
||||
|
||||
clutter_units_pt (&units, 24.0);
|
||||
string = clutter_units_to_string (&units);
|
||||
g_assert_cmpstr (string, ==, "24.0 pt");
|
||||
g_free (string);
|
||||
|
||||
clutter_units_em (&units, 3.0);
|
||||
string = clutter_units_to_string (&units);
|
||||
g_assert_cmpstr (string, ==, "3.00 em");
|
||||
|
||||
units.unit_type = CLUTTER_UNIT_PIXEL;
|
||||
units.value = 0;
|
||||
|
||||
g_assert (clutter_units_from_string (&units, string) == TRUE);
|
||||
g_assert (clutter_units_get_unit_type (&units) != CLUTTER_UNIT_PIXEL);
|
||||
g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_EM);
|
||||
g_assert_cmpint ((int) clutter_units_get_unit_value (&units), ==, 3);
|
||||
|
||||
g_free (string);
|
||||
}
|
@ -148,5 +148,8 @@ main (int argc, char **argv)
|
||||
TEST_CONFORM_SIMPLE ("/color", test_color_from_string);
|
||||
TEST_CONFORM_SIMPLE ("/color", test_color_to_string);
|
||||
|
||||
TEST_CONFORM_SIMPLE ("/units", test_units_constructors);
|
||||
TEST_CONFORM_SIMPLE ("/units", test_units_string);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
@ -90,18 +90,20 @@ test_text_field_main (gint argc,
|
||||
ClutterColor entry_color = {0x33, 0xff, 0x33, 0xff};
|
||||
ClutterColor label_color = {0xff, 0xff, 0xff, 0xff};
|
||||
ClutterColor background_color = {0x00, 0x00, 0x00, 0xff};
|
||||
ClutterUnits h_padding, v_padding;
|
||||
gfloat width, height;
|
||||
gfloat h_padding, v_padding;
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &background_color);
|
||||
|
||||
h_padding = clutter_units_em_for_font (FONT, 2.0); /* 2em */
|
||||
v_padding = clutter_units_em_for_font (FONT, 3.0); /* 3em */
|
||||
clutter_units_em_for_font (&h_padding, FONT, 2.0); /* 2em */
|
||||
clutter_units_em_for_font (&v_padding, FONT, 3.0); /* 3em */
|
||||
|
||||
g_print ("padding: h:%.2f px, v:%.2f px\n", h_padding, v_padding);
|
||||
g_print ("padding: h:%.2f px, v:%.2f px\n",
|
||||
clutter_units_to_pixels (&h_padding),
|
||||
clutter_units_to_pixels (&v_padding));
|
||||
|
||||
text = create_label (&label_color, "<b>Input field:</b> ");
|
||||
clutter_actor_set_position (text, 10, 10);
|
||||
@ -111,17 +113,21 @@ test_text_field_main (gint argc,
|
||||
height = clutter_actor_get_height (text);
|
||||
|
||||
text = create_entry (&entry_color, "<i>some</i> text", 0, 0);
|
||||
clutter_actor_set_position (text, 10 + width + h_padding, 10);
|
||||
clutter_actor_set_position (text,
|
||||
width + 10 + clutter_units_to_pixels (&h_padding),
|
||||
10);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), text);
|
||||
|
||||
text = create_label (&label_color, "<i>A very long password field</i>: ");
|
||||
clutter_actor_set_position (text, 10, height + v_padding);
|
||||
clutter_actor_set_position (text,
|
||||
10,
|
||||
height + 10 + clutter_units_to_pixels (&v_padding));
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), text);
|
||||
|
||||
text = create_entry (&entry_color, "password", '*', 8);
|
||||
clutter_actor_set_position (text,
|
||||
width + 10 + h_padding,
|
||||
height + 10 + v_padding);
|
||||
width + 10 + clutter_units_to_pixels (&h_padding),
|
||||
height + 10 + clutter_units_to_pixels (&v_padding));
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), text);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
Loading…
x
Reference in New Issue
Block a user