~ubuntu-branches/ubuntu/maverick/gnome-shell/maverick

« back to all changes in this revision

Viewing changes to src/st/st-widget.c

  • Committer: Bazaar Package Importer
  • Author(s): Laurent Bigonville
  • Date: 2010-08-16 21:24:15 UTC
  • mfrom: (19.1.2 experimental)
  • Revision ID: james.westby@ubuntu.com-20100816212415-xg81p4jiw6quy6gq
Tags: 2.31.5-2ubuntu1
* Merge from debian experimental. Remaining changes:
  - debian/patches/04_workaround_libmozjs_build.patch:
    + workaround build issues due to libmozjs not being installed as a lib
* Drop debian/patches/01_favorite_apps.diff: Keep firefox as default browser

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
 
37
37
#include "st-widget.h"
38
38
 
 
39
#include "st-label.h"
39
40
#include "st-marshal.h"
40
41
#include "st-private.h"
41
42
#include "st-texture-cache.h"
42
43
#include "st-theme-context.h"
43
44
#include "st-tooltip.h"
 
45
#include "st-theme-node-transition.h"
44
46
 
45
47
/*
46
48
 * Forward declaration for sake of StWidgetChild
53
55
  gchar        *style_class;
54
56
  gchar        *inline_style;
55
57
 
56
 
  ClutterActor *border_image;
57
 
  ClutterActor *background_image;
58
 
  ClutterColor  bg_color;
59
 
 
60
 
  guint         border_width;
61
 
  ClutterColor  border_color;
62
 
 
63
 
  StGradientType bg_gradient_type;
64
 
  ClutterColor  bg_gradient_end;
65
 
 
66
 
  ClutterActorBox background_allocation;
67
 
  gdouble       shadow_xoffset;
68
 
  gdouble       shadow_yoffset;
 
58
  StThemeNodeTransition *transition_animation;
69
59
 
70
60
  gboolean      is_stylable : 1;
71
61
  gboolean      has_tooltip : 1;
115
105
 
116
106
static guint signals[LAST_SIGNAL] = { 0, };
117
107
 
 
108
gfloat st_slow_down_factor = 1.0;
 
109
 
118
110
G_DEFINE_ABSTRACT_TYPE (StWidget, st_widget, CLUTTER_TYPE_ACTOR);
119
111
 
120
112
#define ST_WIDGET_GET_PRIVATE(obj)    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ST_TYPE_WIDGET, StWidgetPrivate))
232
224
}
233
225
 
234
226
static void
 
227
st_widget_remove_transition (StWidget *widget)
 
228
{
 
229
  if (widget->priv->transition_animation)
 
230
    {
 
231
      g_object_run_dispose (G_OBJECT (widget->priv->transition_animation));
 
232
      g_object_unref (widget->priv->transition_animation);
 
233
      widget->priv->transition_animation = NULL;
 
234
    }
 
235
}
 
236
 
 
237
static void
235
238
st_widget_dispose (GObject *gobject)
236
239
{
237
240
  StWidget *actor = ST_WIDGET (gobject);
243
246
      priv->theme = NULL;
244
247
    }
245
248
 
246
 
  if (priv->border_image)
247
 
    {
248
 
      clutter_actor_unparent (priv->border_image);
249
 
      priv->border_image = NULL;
250
 
    }
251
 
 
252
249
  if (priv->theme_node)
253
250
    {
254
251
      g_object_run_dispose (G_OBJECT (priv->theme_node));
256
253
      priv->theme_node = NULL;
257
254
    }
258
255
 
 
256
  st_widget_remove_transition (actor);
 
257
 
259
258
  if (priv->tooltip)
260
259
    {
261
260
      ClutterContainer *parent;
369
368
  StWidget *self = ST_WIDGET (actor);
370
369
  StThemeNode *theme_node;
371
370
  ClutterActorBox allocation;
 
371
  guint8 opacity;
372
372
 
373
373
  theme_node = st_widget_get_theme_node (self);
374
374
 
375
375
  clutter_actor_get_allocation_box (actor, &allocation);
376
376
 
377
 
  st_theme_node_paint (theme_node, &allocation, clutter_actor_get_paint_opacity (actor));
 
377
  opacity = clutter_actor_get_paint_opacity (actor);
 
378
 
 
379
  if (self->priv->transition_animation)
 
380
    st_theme_node_transition_paint (self->priv->transition_animation,
 
381
                                    &allocation,
 
382
                                    opacity);
 
383
  else
 
384
    st_theme_node_paint (theme_node, &allocation, opacity);
378
385
}
379
386
 
380
387
static void
404
411
 
405
412
  st_widget_ensure_style ((StWidget*) actor);
406
413
 
407
 
  if (priv->border_image)
408
 
    clutter_actor_map (priv->border_image);
409
 
 
410
 
  if (priv->background_image)
411
 
    clutter_actor_map (priv->background_image);
412
 
 
413
414
  if (priv->tooltip)
414
415
    clutter_actor_map ((ClutterActor *) priv->tooltip);
415
416
}
421
422
 
422
423
  CLUTTER_ACTOR_CLASS (st_widget_parent_class)->unmap (actor);
423
424
 
424
 
  if (priv->border_image)
425
 
    clutter_actor_unmap (priv->border_image);
426
 
 
427
 
  if (priv->background_image)
428
 
    clutter_actor_unmap (priv->background_image);
429
 
 
430
425
  if (priv->tooltip)
431
426
    clutter_actor_unmap ((ClutterActor *) priv->tooltip);
432
427
}
566
561
}
567
562
 
568
563
static gboolean
569
 
actor_contains (ClutterActor *widget,
570
 
                ClutterActor *other)
571
 
{
572
 
  while (other != NULL && other != widget)
573
 
    other = clutter_actor_get_parent (other);
574
 
  return other != NULL;
575
 
}
576
 
 
577
 
static gboolean
578
564
st_widget_enter (ClutterActor         *actor,
579
565
                 ClutterCrossingEvent *event)
580
566
{
582
568
 
583
569
  if (priv->track_hover)
584
570
    {
585
 
      if (actor_contains (actor, event->source))
 
571
      if (_st_actor_contains (actor, event->source))
586
572
        st_widget_set_hover (ST_WIDGET (actor), TRUE);
587
573
      else
588
574
        {
608
594
 
609
595
  if (priv->track_hover)
610
596
    {
611
 
      if (!actor_contains (actor, event->related))
 
597
      if (!_st_actor_contains (actor, event->related))
612
598
        st_widget_set_hover (ST_WIDGET (actor), FALSE);
613
599
    }
614
600
 
1217
1203
 
1218
1204
  actor->priv = priv = ST_WIDGET_GET_PRIVATE (actor);
1219
1205
  priv->is_stylable = TRUE;
 
1206
  priv->transition_animation = NULL;
1220
1207
 
1221
1208
  /* connect style changed */
1222
1209
  g_signal_connect (actor, "notify::name", G_CALLBACK (st_widget_name_notify), NULL);
1223
1210
}
1224
1211
 
1225
1212
static void
 
1213
on_transition_completed (StThemeNodeTransition *transition,
 
1214
                         StWidget              *widget)
 
1215
{
 
1216
  st_widget_remove_transition (widget);
 
1217
}
 
1218
 
 
1219
static void
1226
1220
st_widget_recompute_style (StWidget    *widget,
1227
1221
                           StThemeNode *old_theme_node)
1228
1222
{
1229
1223
  StThemeNode *new_theme_node = st_widget_get_theme_node (widget);
 
1224
  int transition_duration;
1230
1225
 
1231
1226
  if (!old_theme_node ||
1232
1227
      !st_theme_node_geometry_equal (old_theme_node, new_theme_node))
1233
1228
    clutter_actor_queue_relayout ((ClutterActor *) widget);
1234
1229
 
 
1230
  transition_duration = st_theme_node_get_transition_duration (new_theme_node);
 
1231
 
 
1232
  if (transition_duration > 0)
 
1233
    {
 
1234
      if (widget->priv->transition_animation != NULL)
 
1235
        {
 
1236
          st_theme_node_transition_update (widget->priv->transition_animation,
 
1237
                                           new_theme_node);
 
1238
        }
 
1239
      else if (old_theme_node)
 
1240
        {
 
1241
          widget->priv->transition_animation =
 
1242
            st_theme_node_transition_new (old_theme_node,
 
1243
                                          new_theme_node,
 
1244
                                          transition_duration);
 
1245
 
 
1246
          g_signal_connect (widget->priv->transition_animation, "completed",
 
1247
                            G_CALLBACK (on_transition_completed), widget);
 
1248
          g_signal_connect_swapped (widget->priv->transition_animation,
 
1249
                                    "new-frame",
 
1250
                                    G_CALLBACK (clutter_actor_queue_redraw),
 
1251
                                    widget);
 
1252
        }
 
1253
    }
 
1254
  else if (widget->priv->transition_animation)
 
1255
    {
 
1256
      st_widget_remove_transition (widget);
 
1257
    }
 
1258
 
1235
1259
  g_signal_emit (widget, signals[STYLE_CHANGED], 0);
1236
1260
  widget->priv->is_style_dirty = FALSE;
1237
1261
}
1559
1583
{
1560
1584
  ClutterDeviceManager *device_manager;
1561
1585
  ClutterInputDevice *pointer;
1562
 
  ClutterActor *actor;
 
1586
  ClutterActor *pointer_actor;
1563
1587
 
1564
1588
  device_manager = clutter_device_manager_get_default ();
1565
1589
  pointer = clutter_device_manager_get_core_device (device_manager,
1566
1590
                                                    CLUTTER_POINTER_DEVICE);
1567
 
  actor = clutter_input_device_get_pointer_actor (pointer);
1568
 
 
1569
 
  while (actor && actor != (ClutterActor *)widget)
1570
 
    actor = clutter_actor_get_parent (actor);
1571
 
 
1572
 
  st_widget_set_hover (widget, actor == (ClutterActor *)widget);
 
1591
  pointer_actor = clutter_input_device_get_pointer_actor (pointer);
 
1592
  st_widget_set_hover (widget, _st_actor_contains (CLUTTER_ACTOR (widget), pointer_actor));
1573
1593
}
1574
1594
 
1575
1595
/**
1588
1608
 
1589
1609
  return widget->priv->hover;
1590
1610
}
 
1611
 
 
1612
static gboolean
 
1613
append_actor_text (GString      *desc,
 
1614
                   ClutterActor *actor)
 
1615
{
 
1616
  if (CLUTTER_IS_TEXT (actor))
 
1617
    {
 
1618
      g_string_append_printf (desc, " (\"%s\")",
 
1619
                              clutter_text_get_text (CLUTTER_TEXT (actor)));
 
1620
      return TRUE;
 
1621
    }
 
1622
  else if (ST_IS_LABEL (actor))
 
1623
    {
 
1624
      g_string_append_printf (desc, " (\"%s\")",
 
1625
                              st_label_get_text (ST_LABEL (actor)));
 
1626
      return TRUE;
 
1627
    }
 
1628
  else
 
1629
    return FALSE;
 
1630
}
 
1631
 
 
1632
/**
 
1633
 * st_describe_actor:
 
1634
 * @actor: a #ClutterActor
 
1635
 *
 
1636
 * Creates a string describing @actor, for use in debugging. This
 
1637
 * includes the class name and actor name (if any), plus if @actor
 
1638
 * is an #StWidget, its style class and pseudo class names.
 
1639
 *
 
1640
 * Return value: the debug name.
 
1641
 */
 
1642
char *
 
1643
st_describe_actor (ClutterActor *actor)
 
1644
{
 
1645
  GString *desc;
 
1646
  const char *name;
 
1647
  int i;
 
1648
 
 
1649
  if (!actor)
 
1650
    return g_strdup ("[null]");
 
1651
 
 
1652
  desc = g_string_new (NULL);
 
1653
  g_string_append_printf (desc, "[%p %s", actor,
 
1654
                          G_OBJECT_TYPE_NAME (actor));
 
1655
 
 
1656
  if (ST_IS_WIDGET (actor))
 
1657
    {
 
1658
      const char *style_class = st_widget_get_style_class_name (ST_WIDGET (actor));
 
1659
      const char *pseudo_class = st_widget_get_style_pseudo_class (ST_WIDGET (actor));
 
1660
      char **classes;
 
1661
 
 
1662
      if (style_class)
 
1663
        {
 
1664
          classes = g_strsplit (style_class, ",", -1);
 
1665
          for (i = 0; classes[i]; i++)
 
1666
            {
 
1667
              g_strchug (classes[i]);
 
1668
              g_string_append_printf (desc, ".%s", classes[i]);
 
1669
            }
 
1670
          g_strfreev (classes);
 
1671
        }
 
1672
 
 
1673
      if (pseudo_class)
 
1674
        {
 
1675
          classes = g_strsplit (pseudo_class, ",", -1);
 
1676
          for (i = 0; classes[i]; i++)
 
1677
            {
 
1678
              g_strchug (classes[i]);
 
1679
              g_string_append_printf (desc, ":%s", classes[i]);
 
1680
            }
 
1681
          g_strfreev (classes);
 
1682
        }
 
1683
    }
 
1684
 
 
1685
  name = clutter_actor_get_name (actor);
 
1686
  if (name)
 
1687
    g_string_append_printf (desc, " \"%s\"", name);
 
1688
 
 
1689
  if (!append_actor_text (desc, actor) && CLUTTER_IS_CONTAINER (actor))
 
1690
    {
 
1691
      GList *children, *l;
 
1692
 
 
1693
      /* Do a limited search of @actor's children looking for a label */
 
1694
      children = clutter_container_get_children (CLUTTER_CONTAINER (actor));
 
1695
      for (l = children, i = 0; l && i < 20; l = l->next, i++)
 
1696
        {
 
1697
          if (append_actor_text (desc, l->data))
 
1698
            break;
 
1699
          else if (CLUTTER_IS_CONTAINER (l->data))
 
1700
            children = g_list_concat (children, clutter_container_get_children (l->data));
 
1701
        }
 
1702
      g_list_free (children);
 
1703
    }
 
1704
 
 
1705
  g_string_append_c (desc, ']');
 
1706
 
 
1707
  return g_string_free (desc, FALSE);
 
1708
}
 
1709
 
 
1710
/**
 
1711
 * st_set_slow_down_factor:
 
1712
 *
 
1713
 * @factor: new slow-down factor
 
1714
 *
 
1715
 * Set a global factor applied to all animation durations
 
1716
 */
 
1717
void
 
1718
st_set_slow_down_factor (gfloat factor)
 
1719
{
 
1720
  st_slow_down_factor = factor;
 
1721
}
 
1722
 
 
1723
/**
 
1724
 * st_get_slow_down_factor:
 
1725
 *
 
1726
 * Returns: the global factor applied to all animation durations
 
1727
 */
 
1728
gfloat
 
1729
st_get_slow_down_factor ()
 
1730
{
 
1731
  return st_slow_down_factor;
 
1732
}