예제 #1
0
파일: gtkcssnode.c 프로젝트: GYGit/gtk
static void
gtk_css_node_set_invalid (GtkCssNode *node,
                          gboolean    invalid)
{
  if (node->invalid == invalid)
    return;

  node->invalid = invalid;

  if (node->visible)
    {
      if (node->parent)
        {
          if (invalid)
            gtk_css_node_set_invalid (node->parent, TRUE);
        }
      else
        {
          if (invalid)
            GTK_CSS_NODE_GET_CLASS (node)->queue_validate (node);
          else
            GTK_CSS_NODE_GET_CLASS (node)->dequeue_validate (node);
        }
    }
}
예제 #2
0
파일: gtkcssnode.c 프로젝트: GYGit/gtk
void
gtk_css_node_set_visible (GtkCssNode *cssnode,
                          gboolean    visible)
{
  GtkCssNode *iter;

  if (cssnode->visible == visible)
    return;

  cssnode->visible = visible;
  g_object_notify_by_pspec (G_OBJECT (cssnode), cssnode_properties[PROP_VISIBLE]);

  if (cssnode->invalid)
    {
      if (cssnode->visible)
        {
          if (cssnode->parent)
            gtk_css_node_set_invalid (cssnode->parent, TRUE);
          else
            GTK_CSS_NODE_GET_CLASS (cssnode)->queue_validate (cssnode);
        }
      else
        {
          if (cssnode->parent == NULL)
            GTK_CSS_NODE_GET_CLASS (cssnode)->dequeue_validate (cssnode);
        }
    }

  if (cssnode->next_sibling)
    {
      gtk_css_node_invalidate (cssnode->next_sibling, GTK_CSS_CHANGE_ANY_SIBLING | GTK_CSS_CHANGE_NTH_CHILD);
      if (gtk_css_node_is_first_child (cssnode))
        {
          for (iter = cssnode->next_sibling;
               iter != NULL;
               iter = iter->next_sibling)
            {
              gtk_css_node_invalidate (iter, GTK_CSS_CHANGE_FIRST_CHILD);
              if (iter->visible)
                break;
            }
        }
    }
               
  if (cssnode->previous_sibling)
    {
      if (gtk_css_node_is_last_child (cssnode))
        {
          for (iter = cssnode->previous_sibling;
               iter != NULL;
               iter = iter->previous_sibling)
            {
              gtk_css_node_invalidate (iter, GTK_CSS_CHANGE_LAST_CHILD);
              if (iter->visible)
                break;
            }
        }
      gtk_css_node_invalidate (cssnode->parent->first_child, GTK_CSS_CHANGE_NTH_LAST_CHILD);
    }
}
예제 #3
0
void
gtk_css_node_set_visible (GtkCssNode *cssnode,
                          gboolean    visible)
{
  if (cssnode->visible == visible)
    return;

  cssnode->visible = visible;
  g_object_notify_by_pspec (G_OBJECT (cssnode), cssnode_properties[PROP_VISIBLE]);

  if (cssnode->invalid)
    {
      if (cssnode->visible)
        {
          if (cssnode->parent)
            gtk_css_node_set_invalid (cssnode->parent, TRUE);
          else
            GTK_CSS_NODE_GET_CLASS (cssnode)->queue_validate (cssnode);
        }
      else
        {
          if (cssnode->parent == NULL)
            GTK_CSS_NODE_GET_CLASS (cssnode)->dequeue_validate (cssnode);
        }
    }

  if (cssnode->next_sibling)
    gtk_css_node_invalidate (cssnode->next_sibling, GTK_CSS_CHANGE_ANY_SIBLING
                                                    | GTK_CSS_CHANGE_NTH_CHILD
                                                    | (cssnode->previous_sibling ? 0 : GTK_CSS_CHANGE_FIRST_CHILD));

  if (cssnode->previous_sibling)
    gtk_css_node_invalidate (cssnode->previous_sibling, GTK_CSS_CHANGE_NTH_LAST_CHILD
                                                        | (cssnode->next_sibling ? 0 : GTK_CSS_CHANGE_LAST_CHILD));
}
예제 #4
0
파일: gtkcssnode.c 프로젝트: GYGit/gtk
void
gtk_css_node_validate_internal (GtkCssNode *cssnode,
                                gint64      timestamp)
{
  GtkCssNode *child;

  if (!cssnode->invalid)
    return;

  gtk_css_node_ensure_style (cssnode, timestamp);

  /* need to set to FALSE then to TRUE here to make it chain up */
  gtk_css_node_set_invalid (cssnode, FALSE);
  if (!gtk_css_style_is_static (cssnode->style))
    gtk_css_node_set_invalid (cssnode, TRUE);

  GTK_CSS_NODE_GET_CLASS (cssnode)->validate (cssnode);

  for (child = gtk_css_node_get_first_child (cssnode);
       child;
       child = gtk_css_node_get_next_sibling (child))
    {
      if (child->visible)
        gtk_css_node_validate_internal (child, timestamp);
    }
}
예제 #5
0
파일: gtkcssnode.c 프로젝트: GYGit/gtk
static GdkFrameClock *
gtk_css_node_get_frame_clock_or_null (GtkCssNode *cssnode)
{
  while (cssnode->parent)
    cssnode = cssnode->parent;

  return GTK_CSS_NODE_GET_CLASS (cssnode)->get_frame_clock (cssnode);
}
예제 #6
0
파일: gtkcssnode.c 프로젝트: GYGit/gtk
void
gtk_css_node_invalidate (GtkCssNode   *cssnode,
                         GtkCssChange  change)
{
  if (!cssnode->invalid)
    change &= ~GTK_CSS_CHANGE_TIMESTAMP;

  if (change == 0)
    return;

  cssnode->pending_changes |= change;

  GTK_CSS_NODE_GET_CLASS (cssnode)->invalidate (cssnode);

  if (cssnode->parent)
    cssnode->parent->needs_propagation = TRUE;
  gtk_css_node_invalidate_style (cssnode);
}
예제 #7
0
void
gtk_css_node_validate_internal (GtkCssNode *cssnode,
                                gint64      timestamp)
{
    GtkCssNode *child;

    /* If you run your application with
     *   GTK_DEBUG=no-css-cache
     * every invalidation will purge the cache and completely query
     * everything anew form the cache. This is slow (in particular
     * when animating), but useful for figuring out bugs.
     *
     * We achieve that by pretending that everything that could have
     * changed has and so we of course totally need to redo everything.
     *
     * Note that this also completely revalidates child widgets all
     * the time.
     */
#ifdef G_ENABLE_DEBUG
    if (GTK_DEBUG_CHECK (NO_CSS_CACHE))
        cssnode->pending_changes |= GTK_CSS_CHANGE_ANY;
#endif

    if (!cssnode->invalid)
        return;

    gtk_css_node_ensure_style (cssnode, timestamp);

    /* need to set to FALSE then to TRUE here to make it chain up */
    gtk_css_node_set_invalid (cssnode, FALSE);
    if (!gtk_css_style_is_static (cssnode->style))
        gtk_css_node_set_invalid (cssnode, TRUE);

    GTK_CSS_NODE_GET_CLASS (cssnode)->validate (cssnode);

    for (child = gtk_css_node_get_first_child (cssnode);
            child;
            child = gtk_css_node_get_next_sibling (child))
    {
        if (child->visible)
            gtk_css_node_validate_internal (child, timestamp);
    }
}
예제 #8
0
static void
gtk_css_node_ensure_style (GtkCssNode *cssnode,
                           gint64      current_time)
{
    gboolean style_changed;

    if (!gtk_css_node_needs_new_style (cssnode))
        return;

    if (cssnode->parent)
        gtk_css_node_ensure_style (cssnode->parent, current_time);

    if (cssnode->style_is_invalid)
    {
        GtkCssStyle *new_style;

        if (cssnode->previous_sibling)
            gtk_css_node_ensure_style (cssnode->previous_sibling, current_time);

        new_style = GTK_CSS_NODE_GET_CLASS (cssnode)->update_style (cssnode,
                    cssnode->pending_changes,
                    current_time,
                    cssnode->style);

        style_changed = gtk_css_node_set_style (cssnode, new_style);
        g_object_unref (new_style);

        if (!style_changed && (cssnode->pending_changes & GTK_CSS_CHANGE_SOURCE))
        {
            /* clear the global cache if we reuse the same style after the CSS changed */
            g_object_set_qdata (G_OBJECT (cssnode->style), quark_global_cache, NULL);
        }
    }
    else
    {
        style_changed = FALSE;
    }

    gtk_css_node_propagate_pending_changes (cssnode, style_changed);

    cssnode->pending_changes = 0;
    cssnode->style_is_invalid = FALSE;
}
예제 #9
0
파일: gtkcssnode.c 프로젝트: GYGit/gtk
static void
gtk_css_node_ensure_style (GtkCssNode *cssnode,
                           gint64      current_time)
{
  gboolean style_changed;

  if (!gtk_css_node_needs_new_style (cssnode))
    return;

  if (cssnode->parent)
    gtk_css_node_ensure_style (cssnode->parent, current_time);

  if (cssnode->style_is_invalid)
    {
      GtkCssStyle *new_style;

      if (cssnode->previous_sibling)
        gtk_css_node_ensure_style (cssnode->previous_sibling, current_time);

      g_clear_pointer (&cssnode->cache, gtk_css_node_style_cache_unref);

      new_style = GTK_CSS_NODE_GET_CLASS (cssnode)->update_style (cssnode,
                                                                  cssnode->pending_changes,
                                                                  current_time,
                                                                  cssnode->style);

      style_changed = gtk_css_node_set_style (cssnode, new_style);
      g_object_unref (new_style);
    }
  else
    {
      style_changed = FALSE;
    }

  gtk_css_node_propagate_pending_changes (cssnode, style_changed);

  cssnode->pending_changes = 0;
  cssnode->style_is_invalid = FALSE;
}
예제 #10
0
파일: gtkcssnode.c 프로젝트: GYGit/gtk
static void
gtk_css_node_parent_will_be_set (GtkCssNode *node)
{
  if (node->invalid)
    GTK_CSS_NODE_GET_CLASS (node)->dequeue_validate (node);
}
예제 #11
0
파일: gtkcssnode.c 프로젝트: GYGit/gtk
const GtkWidgetPath *
gtk_css_node_get_widget_path (GtkCssNode *cssnode)
{
  return GTK_CSS_NODE_GET_CLASS (cssnode)->get_widget_path (cssnode);
}
예제 #12
0
파일: gtkcssnode.c 프로젝트: GYGit/gtk
gboolean
gtk_css_node_init_matcher (GtkCssNode     *cssnode,
                           GtkCssMatcher  *matcher)
{
  return GTK_CSS_NODE_GET_CLASS (cssnode)->init_matcher (cssnode, matcher);
}
예제 #13
0
파일: gtkcssnode.c 프로젝트: GYGit/gtk
static GtkStyleProviderPrivate *
gtk_css_node_get_style_provider_or_null (GtkCssNode *cssnode)
{
  return GTK_CSS_NODE_GET_CLASS (cssnode)->get_style_provider (cssnode);
}