Example #1
0
static void
st_container_update_pseudo_classes (StContainer *container)
{
  GList *first_item, *last_item;
  ClutterActor *first_child, *last_child;
  StContainerPrivate *priv = container->priv;

  if (priv->block_update_pseudo_classes)
    return;

  first_item = priv->children;
  first_child = first_item ? first_item->data : NULL;
  if (first_child != priv->first_child)
    {
      if (priv->first_child && ST_IS_WIDGET (priv->first_child))
        st_widget_remove_style_pseudo_class (ST_WIDGET (priv->first_child),
                                             "first-child");
      if (priv->first_child)
        {
          g_object_unref (priv->first_child);
          priv->first_child = NULL;
        }

      if (first_child && ST_IS_WIDGET (first_child))
        st_widget_add_style_pseudo_class (ST_WIDGET (first_child),
                                          "first-child");
      if (first_child)
        priv->first_child = g_object_ref (first_child);
    }

  last_item = g_list_last (priv->children);
  last_child = last_item ? last_item->data : NULL;
  if (last_child != priv->last_child)
    {
      if (priv->last_child && ST_IS_WIDGET (priv->last_child))
        st_widget_remove_style_pseudo_class (ST_WIDGET (priv->last_child),
                                             "last-child");
      if (priv->last_child)
        {
          g_object_unref (priv->last_child);
          priv->last_child = NULL;
        }

      if (last_child && ST_IS_WIDGET (last_child))
        st_widget_add_style_pseudo_class (ST_WIDGET (last_child),
                                          "last-child");
      if (last_child)
        priv->last_child = g_object_ref (last_child);
    }
}
Example #2
0
/**
 * st_widget_get_theme:
 * @actor: a #StWidget
 *
 * Gets the overriding theme set on the actor. See st_widget_set_theme()
 *
 * Return value: (transfer none): the overriding theme, or %NULL
 */
StTheme *
st_widget_get_theme (StWidget *actor)
{
  g_return_val_if_fail (ST_IS_WIDGET (actor), NULL);

  return actor->priv->theme;
}
Example #3
0
/**
 * st_widget_get_style_pseudo_class:
 * @actor: a #StWidget
 *
 * Get the current style pseudo class list.
 *
 * Note that an actor can have multiple pseudo classes; if you just
 * want to test for the presence of a specific pseudo class, use
 * st_widget_has_style_pseudo_class().
 *
 * Returns: the pseudo class list string. The string is owned by the
 * #StWidget and should not be modified or freed.
 */
const gchar*
st_widget_get_style_pseudo_class (StWidget *actor)
{
  g_return_val_if_fail (ST_IS_WIDGET (actor), NULL);

  return actor->priv->pseudo_class;
}
Example #4
0
static gboolean
shell_stack_navigate_focus (StWidget         *widget,
                            ClutterActor     *from,
                            GtkDirectionType  direction)
{
  ClutterActor *top_actor;

  /* If the stack is itself focusable, then focus into or out of
   * it, as appropriate.
   */
  if (st_widget_get_can_focus (widget))
    {
      if (from && clutter_actor_contains (CLUTTER_ACTOR (widget), from))
        return FALSE;

      if (CLUTTER_ACTOR_IS_MAPPED (CLUTTER_ACTOR (widget)))
        {
          clutter_actor_grab_key_focus (CLUTTER_ACTOR (widget));
          return TRUE;
        }
      else
        {
          return FALSE;
        }
    }

  top_actor = clutter_actor_get_last_child (CLUTTER_ACTOR (widget));
  if (ST_IS_WIDGET (top_actor))
    return st_widget_navigate_focus (ST_WIDGET (top_actor), from, direction, FALSE);
  else
    return FALSE;
}
Example #5
0
/**
 * st_widget_get_hover:
 * @widget: A #StWidget
 *
 * If #StWidget:track-hover is set, this returns whether the pointer
 * is currently over the widget.
 *
 * Returns: current value of hover on @widget
 */
gboolean
st_widget_get_hover (StWidget *widget)
{
  g_return_val_if_fail (ST_IS_WIDGET (widget), FALSE);

  return widget->priv->hover;
}
Example #6
0
/**
 * st_widget_get_style:
 * @actor: a #StWidget
 *
 * Get the current inline style string. See st_widget_set_style().
 *
 * Returns: The inline style string, or %NULL. The string is owned by the
 * #StWidget and should not be modified or freed.
 */
const gchar*
st_widget_get_style (StWidget *actor)
{
  g_return_val_if_fail (ST_IS_WIDGET (actor), NULL);

  return actor->priv->inline_style;
}
Example #7
0
/**
 * st_widget_set_hover:
 * @widget: A #StWidget
 * @hover: whether the pointer is hovering over the widget
 *
 * Sets @widget's hover property and adds or removes "hover" from its
 * pseudo class accordingly. If #StWidget:has-tooltip is %TRUE, this
 * will also show or hide the tooltip, as appropriate.
 *
 * If you have set #StWidget:track-hover, you should not need to call
 * this directly. You can call st_widget_sync_hover() if the hover
 * state might be out of sync due to another actor's pointer grab.
 */
void
st_widget_set_hover (StWidget *widget,
                     gboolean  hover)
{
  StWidgetPrivate *priv;

  g_return_if_fail (ST_IS_WIDGET (widget));

  priv = widget->priv;

  if (priv->hover != hover)
    {
      priv->hover = hover;
      if (priv->hover)
        {
          st_widget_add_style_pseudo_class (widget, "hover");
          if (priv->has_tooltip)
            st_widget_show_tooltip (widget);
        }
      else
        {
          st_widget_remove_style_pseudo_class (widget, "hover");
          if (priv->has_tooltip)
            st_widget_hide_tooltip (widget);
        }
      g_object_notify (G_OBJECT (widget), "hover");
    }
}
Example #8
0
/**
 * st_widget_set_has_tooltip:
 * @widget: A #StWidget
 * @has_tooltip: %TRUE if the widget should display a tooltip
 *
 * Enables tooltip support on the #StWidget.
 *
 * Note that setting has-tooltip to %TRUE will cause
 * #ClutterActor:reactive and #StWidget:track-hover to be set %TRUE as
 * well, but you must clear these flags yourself (if appropriate) when
 * setting it %FALSE.
 */
void
st_widget_set_has_tooltip (StWidget *widget,
                           gboolean  has_tooltip)
{
  StWidgetPrivate *priv;

  g_return_if_fail (ST_IS_WIDGET (widget));

  priv = widget->priv;

  priv->has_tooltip = has_tooltip;

  if (has_tooltip)
    {
      clutter_actor_set_reactive ((ClutterActor*) widget, TRUE);
      st_widget_set_track_hover (widget, TRUE);

      if (!priv->tooltip)
        {
          priv->tooltip = g_object_new (ST_TYPE_TOOLTIP, NULL);
          clutter_actor_set_parent ((ClutterActor *) priv->tooltip,
                                    (ClutterActor *) widget);
        }
    }
  else
    {
      if (priv->tooltip)
        {
          clutter_actor_unparent (CLUTTER_ACTOR (priv->tooltip));
          priv->tooltip = NULL;
        }
    }
}
Example #9
0
/**
 * st_widget_get_has_tooltip:
 * @widget: A #StWidget
 *
 * Returns the current value of the has-tooltip property. See
 * st_tooltip_set_has_tooltip() for more information.
 *
 * Returns: current value of has-tooltip on @widget
 */
gboolean
st_widget_get_has_tooltip (StWidget *widget)
{
  g_return_val_if_fail (ST_IS_WIDGET (widget), FALSE);

  return widget->priv->has_tooltip;
}
Example #10
0
static gboolean
sagarmatha_stack_navigate_focus (StWidget         *widget,
                            ClutterActor     *from,
                            GtkDirectionType  direction)
{
  ClutterActor *top_actor;
  GList *children;

  /* If the stack is itself focusable, then focus into or out of
   * it, as appropriate.
   */
  if (st_widget_get_can_focus (widget))
    {
      if (from && clutter_actor_contains (CLUTTER_ACTOR (widget), from))
        return FALSE;

      clutter_actor_grab_key_focus (CLUTTER_ACTOR (widget));
      return TRUE;
    }

  /* Otherwise, navigate into its top-most child only */
  children = st_container_get_children_list (ST_CONTAINER (widget));
  if (!children)
    return FALSE;

  top_actor = g_list_last (children)->data;
  if (ST_IS_WIDGET (top_actor))
    return st_widget_navigate_focus (ST_WIDGET (top_actor), from, direction, FALSE);
  else
    return FALSE;
}
Example #11
0
/**
 * st_widget_show_tooltip:
 * @widget: A #StWidget
 *
 * Show the tooltip for @widget
 *
 */
void
st_widget_show_tooltip (StWidget *widget)
{
  gfloat x, y, width, height;
  ClutterGeometry area;

  g_return_if_fail (ST_IS_WIDGET (widget));

  /* XXX not necceary, but first allocate transform is wrong */

  clutter_actor_get_transformed_position ((ClutterActor*) widget,
                                          &x, &y);

  clutter_actor_get_size ((ClutterActor*) widget, &width, &height);

  area.x = x;
  area.y = y;
  area.width = width;
  area.height = height;


  if (widget->priv->tooltip)
    {
      st_tooltip_set_tip_area (widget->priv->tooltip, &area);
      st_tooltip_show (widget->priv->tooltip);
    }
}
Example #12
0
/**
 * st_widget_has_style_pseudo_class:
 * @actor: a #StWidget
 * @pseudo_class: a pseudo class string
 *
 * Tests if @actor's pseudo class list includes @pseudo_class.
 *
 * Returns: whether or not @actor's pseudo class list includes
 * @pseudo_class.
 */
gboolean
st_widget_has_style_pseudo_class (StWidget    *actor,
                                  const gchar *pseudo_class)
{
  g_return_val_if_fail (ST_IS_WIDGET (actor), FALSE);

  return find_class_name (actor->priv->pseudo_class, pseudo_class) != NULL;
}
Example #13
0
/**
 * st_widget_hide_tooltip:
 * @widget: A #StWidget
 *
 * Hide the tooltip for @widget
 *
 */
void
st_widget_hide_tooltip (StWidget *widget)
{
  g_return_if_fail (ST_IS_WIDGET (widget));

  if (widget->priv->tooltip)
    st_tooltip_hide (widget->priv->tooltip);
}
Example #14
0
/**
 * st_widget_ensure_style:
 * @widget: A #StWidget
 *
 * Ensures that @widget has read its style information.
 *
 */
void
st_widget_ensure_style (StWidget *widget)
{
  g_return_if_fail (ST_IS_WIDGET (widget));

  if (widget->priv->is_style_dirty)
    st_widget_recompute_style (widget, NULL);
}
Example #15
0
static void
st_bin_popup_menu (StWidget *widget)
{
  StBinPrivate *priv = ST_BIN (widget)->priv;

  if (priv->child && ST_IS_WIDGET (priv->child))
    st_widget_popup_menu (ST_WIDGET (priv->child));
}
Example #16
0
static void
notify_children_of_style_change_foreach (ClutterActor *actor,
                                         gpointer      user_data)
{
  if (ST_IS_WIDGET (actor))
    st_widget_style_changed (ST_WIDGET (actor));
  else if (CLUTTER_IS_CONTAINER (actor))
    notify_children_of_style_change ((ClutterContainer *)actor);
}
Example #17
0
StTextDirection
st_widget_get_direction (StWidget *self)
{
  g_return_val_if_fail (ST_IS_WIDGET (self), ST_TEXT_DIRECTION_LTR);

  if (self->priv->direction != ST_TEXT_DIRECTION_NONE)
    return self->priv->direction;
  else
    return default_direction;
}
Example #18
0
/**
 * st_widget_set_style_class_name:
 * @actor: a #StWidget
 * @style_class_list: (allow-none): a new style class list string
 *
 * Set the style class name list. @style_class_list can either be
 * %NULL, for no classes, or a space-separated list of style class
 * names. See also st_widget_add_style_class_name() and
 * st_widget_remove_style_class_name().
 */
void
st_widget_set_style_class_name (StWidget    *actor,
                                const gchar *style_class_list)
{
  g_return_if_fail (ST_IS_WIDGET (actor));

  if (set_class_list (&actor->priv->style_class, style_class_list))
    {
      st_widget_style_changed (actor);
      g_object_notify (G_OBJECT (actor), "style-class");
    }
}
Example #19
0
/**
 * st_widget_get_tooltip_text:
 * @widget: A #StWidget
 *
 * Get the current tooltip string
 *
 * Returns: The current tooltip string, owned by the #StWidget
 */
const gchar*
st_widget_get_tooltip_text (StWidget *widget)
{
  StWidgetPrivate *priv;

  g_return_val_if_fail (ST_IS_WIDGET (widget), NULL);
  priv = widget->priv;

  if (!priv->has_tooltip)
    return NULL;

  return st_tooltip_get_label (widget->priv->tooltip);
}
Example #20
0
/**
 * st_widget_remove_style_pseudo_class:
 * @actor: a #StWidget
 * @pseudo_class: a pseudo class string
 *
 * Removes @pseudo_class from @actor's pseudo class, if it is present.
 */
void
st_widget_remove_style_pseudo_class (StWidget    *actor,
                                     const gchar *pseudo_class)
{
  g_return_if_fail (ST_IS_WIDGET (actor));
  g_return_if_fail (pseudo_class != NULL);

  if (remove_class_name (&actor->priv->pseudo_class, pseudo_class))
    {
      st_widget_style_changed (actor);
      g_object_notify (G_OBJECT (actor), "pseudo-class");
    }
}
Example #21
0
/**
 * st_widget_set_tooltip_text:
 * @widget: A #StWidget
 * @text: text to set as the tooltip
 *
 * Set the tooltip text of the widget. This will set StWidget::has-tooltip to
 * %TRUE. A value of %NULL will unset the tooltip and set has-tooltip to %FALSE.
 *
 */
void
st_widget_set_tooltip_text (StWidget    *widget,
                            const gchar *text)
{
  StWidgetPrivate *priv;

  g_return_if_fail (ST_IS_WIDGET (widget));

  priv = widget->priv;

  if (text == NULL)
    st_widget_set_has_tooltip (widget, FALSE);
  else
    st_widget_set_has_tooltip (widget, TRUE);

  st_tooltip_set_label (priv->tooltip, text);
}
Example #22
0
/**
 * st_widget_set_track_hover:
 * @widget: A #StWidget
 * @track_hover: %TRUE if the widget should track the pointer hover state
 *
 * Enables hover tracking on the #StWidget.
 *
 * If hover tracking is enabled, and the widget is visible and
 * reactive, then @widget's #StWidget:hover property will be updated
 * automatically to reflect whether the pointer is in @widget (or one
 * of its children), and @widget's #StWidget:pseudo-class will have
 * the "hover" class added and removed from it accordingly.
 *
 * Note that currently it is not possible to correctly track the hover
 * state when another actor has a pointer grab. You can use
 * st_widget_sync_hover() to update the property manually in this
 * case.
 */
void
st_widget_set_track_hover (StWidget *widget,
                           gboolean  track_hover)
{
  StWidgetPrivate *priv;

  g_return_if_fail (ST_IS_WIDGET (widget));

  priv = widget->priv;

  if (priv->track_hover != track_hover)
    {
      priv->track_hover = track_hover;
      g_object_notify (G_OBJECT (widget), "track-hover");

      if (priv->track_hover)
        st_widget_sync_hover (widget);
    }
}
Example #23
0
/**
 * st_widget_set_style:
 * @actor: a #StWidget
 * @style_class: (allow-none): a inline style string, or %NULL
 *
 * Set the inline style string for this widget. The inline style string is an
 * optional ';'-separated list of CSS properties that override the style as
 * determined from the stylesheets of the current theme.
 */
void
st_widget_set_style (StWidget  *actor,
                       const gchar *style)
{
  StWidgetPrivate *priv = actor->priv;

  g_return_if_fail (ST_IS_WIDGET (actor));

  priv = actor->priv;

  if (g_strcmp0 (style, priv->inline_style))
    {
      g_free (priv->inline_style);
      priv->inline_style = g_strdup (style);

      st_widget_style_changed (actor);

      g_object_notify (G_OBJECT (actor), "style");
    }
}
Example #24
0
/**
 * st_widget_get_theme_node:
 * @widget: a #StWidget
 *
 * Gets the theme node holding style information for the widget.
 * The theme node is used to access standard and custom CSS
 * properties of the widget.
 *
 * Return value: (transfer none): the theme node for the widget.
 *   This is owned by the widget. When attributes of the widget
 *   or the environment that affect the styling change (for example
 *   the style_class property of the widget), it will be recreated,
 *   and the ::style-changed signal will be emitted on the widget.
 */
StThemeNode *
st_widget_get_theme_node (StWidget *widget)
{
  StWidgetPrivate *priv = widget->priv;

  if (priv->theme_node == NULL)
    {
      StThemeNode *parent_node = NULL;
      ClutterStage *stage = NULL;
      ClutterActor *parent;

      parent = clutter_actor_get_parent (CLUTTER_ACTOR (widget));
      while (parent != NULL)
        {
          if (parent_node == NULL && ST_IS_WIDGET (parent))
            parent_node = st_widget_get_theme_node (ST_WIDGET (parent));
          else if (CLUTTER_IS_STAGE (parent))
            stage = CLUTTER_STAGE (parent);

          parent = clutter_actor_get_parent (parent);
        }

      if (stage == NULL)
        {
          g_error ("st_widget_get_theme_node called on a widget not in a stage");
        }

      if (parent_node == NULL)
        parent_node = get_root_theme_node (CLUTTER_STAGE (stage));

      priv->theme_node = st_theme_node_new (st_theme_context_get_for_stage (stage),
                                            parent_node, priv->theme,
                                            G_OBJECT_TYPE (widget),
                                            clutter_actor_get_name (CLUTTER_ACTOR (widget)),
                                            priv->style_class,
                                            priv->pseudo_class,
                                            priv->inline_style);
    }

  return priv->theme_node;
}
Example #25
0
static gboolean
st_bin_navigate_focus (StWidget         *widget,
                       ClutterActor     *from,
                       GtkDirectionType  direction)
{
  StBinPrivate *priv = ST_BIN (widget)->priv;
  ClutterActor *bin_actor = CLUTTER_ACTOR (widget);

  if (st_widget_get_can_focus (widget))
    {
      if (from && clutter_actor_contains (bin_actor, from))
        return FALSE;

      clutter_actor_grab_key_focus (bin_actor);
      return TRUE;
    }
  else if (priv->child && ST_IS_WIDGET (priv->child))
    return st_widget_navigate_focus (ST_WIDGET (priv->child), from, direction, FALSE);
  else
    return FALSE;
}
Example #26
0
/**
 * st_widget_set_theme:
 * @actor: a #StWidget
 * @theme: a new style class string
 *
 * Overrides the theme that would be inherited from the actor's parent
 * or the stage with an entirely new theme (set of stylesheets).
 */
void
st_widget_set_theme (StWidget  *actor,
                      StTheme  *theme)
{
  StWidgetPrivate *priv = actor->priv;

  g_return_if_fail (ST_IS_WIDGET (actor));

  priv = actor->priv;

  if (theme !=priv->theme)
    {
      if (priv->theme)
        g_object_unref (priv->theme);
      priv->theme = g_object_ref (priv->theme);

      st_widget_style_changed (actor);

      g_object_notify (G_OBJECT (actor), "theme");
    }
}
Example #27
0
static gboolean
st_container_navigate_focus (StWidget         *widget,
                             ClutterActor     *from,
                             GtkDirectionType  direction)
{
  StContainer *container = ST_CONTAINER (widget);
  ClutterActor *container_actor, *focus_child;
  GList *children, *l;

  container_actor = CLUTTER_ACTOR (widget);
  if (from == container_actor)
    return FALSE;

  /* Figure out if @from is a descendant of @container, and if so,
   * set @focus_child to the immediate child of @container that
   * contains (or *is*) @from.
   */
  focus_child = from;
  while (focus_child && clutter_actor_get_parent (focus_child) != container_actor)
    focus_child = clutter_actor_get_parent (focus_child);

  if (st_widget_get_can_focus (widget))
    {
      if (!focus_child)
        {
          /* Accept focus from outside */
          clutter_actor_grab_key_focus (container_actor);
          return TRUE;
        }
      else
        {
          /* Yield focus from within: since @container itself is
           * focusable we don't allow the focus to be navigated
           * within @container.
           */
          return FALSE;
        }
    }

  /* See if we can navigate within @focus_child */
  if (focus_child && ST_IS_WIDGET (focus_child))
    {
      if (st_widget_navigate_focus (ST_WIDGET (focus_child), from, direction, FALSE))
        return TRUE;
    }

  /* At this point we know that we want to navigate focus to one of
   * @container's immediate children; the next one after @focus_child,
   * or the first one if @focus_child is %NULL. (With "next" and
   * "first" being determined by @direction.)
   */

  children = st_container_get_focus_chain (container);
  if (direction == GTK_DIR_TAB_FORWARD ||
      direction == GTK_DIR_TAB_BACKWARD)
    {
      if (direction == GTK_DIR_TAB_BACKWARD)
        children = g_list_reverse (children);

      if (focus_child)
        {
          /* Remove focus_child and any earlier children */
          while (children && children->data != focus_child)
            children = g_list_delete_link (children, children);
          if (children)
            children = g_list_delete_link (children, children);
        }
    }
  else /* direction is an arrow key, not tab */
    {
      StContainerChildSortData sort_data;

      /* Compute the allocation box of the previous focused actor, in
       * @container's coordinate space. If there was no previous focus,
       * use the coordinates of the appropriate edge of @container.
       *
       * Note that all of this code assumes the actors are not
       * transformed (or at most, they are all scaled by the same
       * amount). If @container or any of its children is rotated, or
       * any child is inconsistently scaled, then the focus chain will
       * probably be unpredictable.
       */
      if (focus_child)
        {
          clutter_actor_get_allocation_box (focus_child, &sort_data.box);
        }
      else
        {
          clutter_actor_get_allocation_box (CLUTTER_ACTOR (container), &sort_data.box);
          switch (direction)
            {
            case GTK_DIR_UP:
              sort_data.box.y1 = sort_data.box.y2;
              break;
            case GTK_DIR_DOWN:
              sort_data.box.y2 = sort_data.box.y1;
              break;
            case GTK_DIR_LEFT:
              sort_data.box.x1 = sort_data.box.x2;
              break;
            case GTK_DIR_RIGHT:
              sort_data.box.x2 = sort_data.box.x1;
              break;
            default:
              g_warn_if_reached ();
            }
        }
      sort_data.direction = direction;

      if (focus_child)
        children = filter_by_position (children, &sort_data.box, direction);
      if (children)
        children = g_list_sort_with_data (children, sort_by_position, &sort_data);
    }

  /* Now try each child in turn */
  for (l = children; l; l = l->next)
    {
      if (ST_IS_WIDGET (l->data))
        {
          if (st_widget_navigate_focus (l->data, from, direction, FALSE))
            {
              g_list_free (children);
              return TRUE;
            }
        }
    }

  g_list_free (children);
  return FALSE;
}
Example #28
0
void
st_widget_set_direction (StWidget *self, StTextDirection dir)
{
  g_return_if_fail (ST_IS_WIDGET (self));
  self->priv->direction = dir;
}