css: Allow the css editor to take a CSS node

Use that to hilight the selectors that match that node.
This commit is contained in:
Benjamin Otte
2016-03-15 09:23:25 +01:00
parent 9c02a600b2
commit 662065bdb1
5 changed files with 148 additions and 3 deletions

View File

@@ -139,6 +139,31 @@ gtk_css_style_rule_new_parse (GtkCssTokenSource *source,
return GTK_CSS_RULE (rule);
}
gsize
gtk_css_style_rule_get_n_selectors (GtkCssStyleRule *rule)
{
GtkCssStyleRulePrivate *priv;
g_return_val_if_fail (GTK_IS_CSS_STYLE_RULE (rule), 0);
priv = gtk_css_style_rule_get_instance_private (rule);
return priv->selectors->len;
}
GtkCssSelector *
gtk_css_style_rule_get_selector (GtkCssStyleRule *rule,
gsize id)
{
GtkCssStyleRulePrivate *priv;
g_return_val_if_fail (GTK_IS_CSS_STYLE_RULE (rule), 0);
priv = gtk_css_style_rule_get_instance_private (rule);
return g_ptr_array_index (priv->selectors, id);
}
GtkCssStyleDeclaration *
gtk_css_style_rule_get_style (GtkCssStyleRule *rule)
{

View File

@@ -21,6 +21,7 @@
#define __GTK_CSS_STYLE_RULE_PRIVATE_H__
#include "gtk/gtkcssruleprivate.h"
#include "gtk/gtkcssselectorprivate.h"
#include "gtk/gtkcssstyledeclarationprivate.h"
G_BEGIN_DECLS
@@ -51,6 +52,10 @@ GtkCssRule * gtk_css_style_rule_new_parse (GtkCssTokenSour
GtkCssRule *parent_rule,
GtkCssStyleSheet *parent_style_sheet);
gsize gtk_css_style_rule_get_n_selectors (GtkCssStyleRule *rule);
GtkCssSelector * gtk_css_style_rule_get_selector (GtkCssStyleRule *rule,
gsize id);
GtkCssStyleDeclaration *gtk_css_style_rule_get_style (GtkCssStyleRule *rule);

View File

@@ -28,6 +28,7 @@
#include "gtkcssdeclarationprivate.h"
#include "gtkcssprovider.h"
#include "gtkcssrbtreeprivate.h"
#include "gtkcssstyleruleprivate.h"
#include "gtkcssstylesheetprivate.h"
#include "gtkcsstokenizerprivate.h"
#include "gtkcsstokensourceprivate.h"
@@ -79,6 +80,7 @@ struct _GtkInspectorCssEditorPrivate
GtkCssRbTree *tokens;
GtkCssProvider *provider;
GtkCssStyleSheet *style_sheet;
GtkCssNode *node;
GtkToggleButton *disable_button;
guint timeout;
};
@@ -497,6 +499,54 @@ apply_declaration (GtkInspectorCssEditor *ce,
return TRUE;
}
static gboolean
apply_selector (GtkInspectorCssEditor *ce,
GtkCssChunk *chunk)
{
GtkCssChunk *prev;
if (!GTK_IS_CSS_STYLE_RULE (chunk->consumer))
return FALSE;
for (prev = chunk;
prev->consumer == chunk->consumer;
prev = gtk_css_rb_tree_get_previous (ce->priv->tokens, prev))
{
if (gtk_css_token_is (&chunk->token, GTK_CSS_TOKEN_OPEN_CURLY))
return FALSE;
}
return TRUE;
}
static gboolean
apply_selector_matching (GtkInspectorCssEditor *ce,
GtkCssChunk *chunk)
{
GtkCssMatcher matcher;
GtkCssStyleRule *rule;
gsize i;
if (ce->priv->node == NULL)
return FALSE;
if (!apply_selector (ce, chunk))
return FALSE;
rule = GTK_CSS_STYLE_RULE (chunk->consumer);
gtk_css_node_init_matcher (ce->priv->node, &matcher);
for (i = 0; i < gtk_css_style_rule_get_n_selectors (rule); i++)
{
GtkCssSelector *selector = gtk_css_style_rule_get_selector (rule, i);
if (_gtk_css_selector_matches (selector, &matcher))
return TRUE;
}
return FALSE;
}
static gboolean
apply_error (GtkInspectorCssEditor *ce,
GtkCssChunk *chunk)
@@ -521,6 +571,9 @@ static struct {
{ "comment", apply_comment },
{ "string", apply_string },
{ "declaration", apply_declaration },
{ "selector", apply_selector },
{ "selector-matching", apply_selector_matching },
{ "declaration", apply_declaration },
{ "error", apply_error },
{ "warning", apply_warning },
};
@@ -713,9 +766,13 @@ finalize (GObject *object)
if (ce->priv->timeout != 0)
g_source_remove (ce->priv->timeout);
gtk_inspector_css_editor_set_node (ce, NULL);
if (ce->priv->tokens)
gtk_css_rb_tree_unref (ce->priv->tokens);
gtk_inspector_css_editor_set_node (ce, NULL);
g_object_unref (ce->priv->style_sheet);
destroy_provider (ce);
@@ -742,4 +799,47 @@ gtk_inspector_css_editor_class_init (GtkInspectorCssEditorClass *klass)
gtk_widget_class_bind_template_callback (widget_class, query_tooltip_cb);
}
static void
gtk_inspector_css_editor_node_changed_cb (GtkCssNode *node,
GtkCssStyleChange *change,
GtkInspectorCssEditor *ce)
{
clear_all_tags (ce);
update_token_tags (ce, gtk_css_rb_tree_get_first (ce->priv->tokens), NULL);
}
void
gtk_inspector_css_editor_set_node (GtkInspectorCssEditor *ce,
GtkCssNode *node)
{
GtkInspectorCssEditorPrivate *priv;
g_return_if_fail (GTK_INSPECTOR_IS_CSS_EDITOR (ce));
g_return_if_fail (node == NULL || GTK_IS_CSS_NODE (node));
priv = ce->priv;
if (priv->node == node)
return;
if (priv->node)
{
g_signal_handlers_disconnect_by_func (priv->node, gtk_inspector_css_editor_node_changed_cb, ce);
}
priv->node = node;
if (node)
{
g_object_ref (node);
g_signal_connect (priv->node,
"style-changed",
G_CALLBACK (gtk_inspector_css_editor_node_changed_cb),
ce);
}
clear_all_tags (ce);
update_token_tags (ce, gtk_css_rb_tree_get_first (ce->priv->tokens), NULL);
}
// vim: set et sw=2 ts=2:

View File

@@ -25,6 +25,8 @@
#include <gtk/gtkbox.h>
#include "gtkcssnodeprivate.h"
#define GTK_TYPE_INSPECTOR_CSS_EDITOR (gtk_inspector_css_editor_get_type())
#define GTK_INSPECTOR_CSS_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_INSPECTOR_CSS_EDITOR, GtkInspectorCssEditor))
#define GTK_INSPECTOR_CSS_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_INSPECTOR_CSS_EDITOR, GtkInspectorCssEditorClass))
@@ -49,8 +51,9 @@ typedef struct _GtkInspectorCssEditorClass
G_BEGIN_DECLS
GType gtk_inspector_css_editor_get_type (void);
void gtk_inspector_css_editor_set_object (GtkInspectorCssEditor *ce,
GObject *object);
void gtk_inspector_css_editor_set_node (GtkInspectorCssEditor *ce,
GtkCssNode *node);
G_END_DECLS

View File

@@ -10,7 +10,19 @@
<child type="tag">
<object class="GtkTextTag">
<property name="name">string</property>
<property name="foreground">red</property>
<property name="foreground">darkred</property>
</object>
</child>
<child type="tag">
<object class="GtkTextTag">
<property name="name">selector</property>
<property name="foreground">darkgreen</property>
</object>
</child>
<child type="tag">
<object class="GtkTextTag">
<property name="name">selector-matching</property>
<property name="background">yellow</property>
</object>
</child>
<child type="tag">