[gtk] node editor: Do some simple syntax highlighting
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk] node editor: Do some simple syntax highlighting
- Date: Tue, 7 May 2019 16:24:41 +0000 (UTC)
commit b3c4320bc2d9941a72f3fecf139eccab419a8ddd
Author: Timm Bäder <mail baedert org>
Date: Tue May 7 17:19:58 2019 +0200
node editor: Do some simple syntax highlighting
demos/node-editor/node-editor-application.c | 18 ++++
demos/node-editor/node-editor-window.c | 135 +++++++++++++++++++++++++++-
demos/node-editor/node-editor-window.ui | 16 +---
3 files changed, 154 insertions(+), 15 deletions(-)
---
diff --git a/demos/node-editor/node-editor-application.c b/demos/node-editor/node-editor-application.c
index a2c9dcfb19..d4d65f964f 100644
--- a/demos/node-editor/node-editor-application.c
+++ b/demos/node-editor/node-editor-application.c
@@ -23,6 +23,16 @@
#include "node-editor-window.h"
+static const char *css =
+"textview.editor {"
+" color: rgb(192, 197, 206);"
+" caret-color: white;"
+"}"
+"textview.editor text {"
+" background-color: rgb(43, 48, 59);"
+"}"
+;
+
struct _NodeEditorApplication
{
GtkApplication parent;
@@ -58,6 +68,7 @@ node_editor_application_startup (GApplication *app)
{
const char *quit_accels[2] = { "<Ctrl>Q", NULL };
const char *open_accels[2] = { "<Ctrl>O", NULL };
+ GtkCssProvider *provider;
G_APPLICATION_CLASS (node_editor_application_parent_class)->startup (app);
@@ -66,6 +77,13 @@ node_editor_application_startup (GApplication *app)
app);
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.quit", quit_accels);
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "win.open", open_accels);
+
+
+ provider = gtk_css_provider_new ();
+ gtk_css_provider_load_from_data (provider, css, -1);
+ gtk_style_context_add_provider_for_display (gdk_display_get_default (),
+ GTK_STYLE_PROVIDER (provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
static void
diff --git a/demos/node-editor/node-editor-window.c b/demos/node-editor/node-editor-window.c
index ef61e9f20d..cb9f78c349 100644
--- a/demos/node-editor/node-editor-window.c
+++ b/demos/node-editor/node-editor-window.c
@@ -39,6 +39,7 @@ struct _NodeEditorWindow
GtkWidget *picture;
GtkWidget *text_view;
GtkTextBuffer *text_buffer;
+ GtkTextTagTable *tag_table;
GtkWidget *renderer_listbox;
GListStore *renderers;
@@ -99,6 +100,42 @@ deserialize_error_func (const GtkCssSection *section,
g_array_append_val (self->errors, text_view_error);
}
+static void
+text_iter_skip_alpha_backward (GtkTextIter *iter)
+{
+ /* Just skip to the previous non-whitespace char */
+
+ while (!gtk_text_iter_is_start (iter))
+ {
+ gunichar c = gtk_text_iter_get_char (iter);
+
+ if (g_unichar_isspace (c))
+ {
+ gtk_text_iter_forward_char (iter);
+ break;
+ }
+
+ gtk_text_iter_backward_char (iter);
+ }
+}
+
+static void
+text_iter_skip_whitespace_backward (GtkTextIter *iter)
+{
+ while (!gtk_text_iter_is_start (iter))
+ {
+ gunichar c = gtk_text_iter_get_char (iter);
+
+ if (g_unichar_isalpha (c))
+ {
+ gtk_text_iter_forward_char (iter);
+ break;
+ }
+
+ gtk_text_iter_backward_char (iter);
+ }
+}
+
static void
text_changed (GtkTextBuffer *buffer,
NodeEditorWindow *self)
@@ -141,6 +178,71 @@ text_changed (GtkTextBuffer *buffer,
{
gtk_picture_set_paintable (GTK_PICTURE (self->picture), NULL);
}
+
+ GtkTextIter iter;
+
+ gtk_text_buffer_get_start_iter (self->text_buffer, &iter);
+
+ while (!gtk_text_iter_is_end (&iter))
+ {
+ gunichar c = gtk_text_iter_get_char (&iter);
+
+ if (c == '{')
+ {
+ GtkTextIter word_end = iter;
+ GtkTextIter word_start;
+
+ gtk_text_iter_backward_char (&word_end);
+ text_iter_skip_whitespace_backward (&word_end);
+
+ word_start = word_end;
+ gtk_text_iter_backward_word_start (&word_start);
+ text_iter_skip_alpha_backward (&word_start);
+
+ gtk_text_buffer_apply_tag_by_name (self->text_buffer, "nodename",
+ &word_start, &word_end);
+ }
+ else if (c == ':')
+ {
+ GtkTextIter word_end = iter;
+ GtkTextIter word_start;
+
+ gtk_text_iter_backward_char (&word_end);
+ text_iter_skip_whitespace_backward (&word_end);
+
+ word_start = word_end;
+ gtk_text_iter_backward_word_start (&word_start);
+ text_iter_skip_alpha_backward (&word_start);
+
+ gtk_text_buffer_apply_tag_by_name (self->text_buffer, "propname",
+ &word_start, &word_end);
+ }
+ else if (c == '"')
+ {
+ GtkTextIter string_start = iter;
+ GtkTextIter string_end = iter;
+
+ gtk_text_iter_forward_char (&iter);
+ while (!gtk_text_iter_is_end (&iter))
+ {
+ c = gtk_text_iter_get_char (&iter);
+
+ if (c == '"')
+ {
+ gtk_text_iter_forward_char (&iter);
+ string_end = iter;
+ break;
+ }
+
+ gtk_text_iter_forward_char (&iter);
+ }
+
+ gtk_text_buffer_apply_tag_by_name (self->text_buffer, "string",
+ &string_start, &string_end);
+ }
+
+ gtk_text_iter_forward_char (&iter);
+ }
}
static gboolean
@@ -493,12 +595,10 @@ node_editor_window_class_init (NodeEditorWindowClass *class)
widget_class->realize = node_editor_window_realize;
widget_class->unrealize = node_editor_window_unrealize;
- gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, text_buffer);
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, text_view);
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, picture);
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, renderer_listbox);
- gtk_widget_class_bind_template_callback (widget_class, text_changed);
gtk_widget_class_bind_template_callback (widget_class, text_view_query_tooltip_cb);
gtk_widget_class_bind_template_callback (widget_class, open_cb);
gtk_widget_class_bind_template_callback (widget_class, save_cb);
@@ -559,6 +659,37 @@ node_editor_window_init (NodeEditorWindow *self)
g_array_set_clear_func (self->errors, (GDestroyNotify)text_view_error_free);
g_action_map_add_action_entries (G_ACTION_MAP (self), win_entries, G_N_ELEMENTS (win_entries), self);
+
+ self->tag_table = gtk_text_tag_table_new ();
+ gtk_text_tag_table_add (self->tag_table,
+ g_object_new (GTK_TYPE_TEXT_TAG,
+ "name", "error",
+ "underline", PANGO_UNDERLINE_ERROR,
+ NULL));
+ gtk_text_tag_table_add (self->tag_table,
+ g_object_new (GTK_TYPE_TEXT_TAG,
+ "name", "nodename",
+ "foreground-rgba", &(GdkRGBA) { 0.9, 0.78, 0.53, 1},
+ NULL));
+ gtk_text_tag_table_add (self->tag_table,
+ g_object_new (GTK_TYPE_TEXT_TAG,
+ "name", "propname",
+ "foreground-rgba", &(GdkRGBA) { 0.7, 0.55, 0.67, 1},
+ NULL));
+ gtk_text_tag_table_add (self->tag_table,
+ g_object_new (GTK_TYPE_TEXT_TAG,
+ "name", "string",
+ "foreground-rgba", &(GdkRGBA) { 0.63, 0.73, 0.54, 1},
+ NULL));
+ gtk_text_tag_table_add (self->tag_table,
+ g_object_new (GTK_TYPE_TEXT_TAG,
+ "name", "number",
+ "foreground-rgba", &(GdkRGBA) { 0.8, 0.52, 0.43, 1},
+ NULL));
+
+ self->text_buffer = gtk_text_buffer_new (self->tag_table);
+ g_signal_connect (self->text_buffer, "changed", G_CALLBACK (text_changed), self);
+ gtk_text_view_set_buffer (GTK_TEXT_VIEW (self->text_view), self->text_buffer);
}
NodeEditorWindow *
diff --git a/demos/node-editor/node-editor-window.ui b/demos/node-editor/node-editor-window.ui
index 0ce06be89e..d254d992b3 100644
--- a/demos/node-editor/node-editor-window.ui
+++ b/demos/node-editor/node-editor-window.ui
@@ -1,17 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <object class="GtkTextTagTable" id="tags">
- <child type="tag">
- <object class="GtkTextTag">
- <property name="name">error</property>
- <property name="underline">error</property>
- </object>
- </child>
- </object>
- <object class="GtkTextBuffer" id="text_buffer">
- <property name="tag-table">tags</property>
- <signal name="changed" handler="text_changed"/>
- </object>
<template class="NodeEditorWindow" parent="GtkApplicationWindow">
<style>
<class name="devel"/>
@@ -61,7 +49,6 @@
<property name="expand">1</property>
<child>
<object class="GtkTextView" id="text_view">
- <property name="buffer">text_buffer</property>
<property name="wrap-mode">word</property>
<property name="monospace">1</property>
<property name="has-focus">1</property>
@@ -71,6 +58,9 @@
<property name="bottom-margin">6</property>
<property name="has-tooltip">1</property>
<signal name="query-tooltip" handler="text_view_query_tooltip_cb"/>
+ <style>
+ <class name="editor" />
+ </style>
</object>
</child>
</object>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]