[gtksourceview/wip/new-space-drawing-api] SpaceDrawer: new API with two enums (space types vs locations)
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/new-space-drawing-api] SpaceDrawer: new API with two enums (space types vs locations)
- Date: Sat, 24 Sep 2016 18:08:27 +0000 (UTC)
commit 3c87b1c9162fc260802e32299608dcde64068ac6
Author: Sébastien Wilmet <swilmet gnome org>
Date: Sat Jul 23 17:37:25 2016 +0200
SpaceDrawer: new API with two enums (space types vs locations)
https://bugzilla.gnome.org/show_bug.cgi?id=683678
docs/reference/gtksourceview-3.0-sections.txt | 10 +
gtksourceview/gtksourcespacedrawer.c | 373 +++++++++++++++++++++++++
gtksourceview/gtksourcespacedrawer.h | 64 +++++
3 files changed, 447 insertions(+), 0 deletions(-)
---
diff --git a/docs/reference/gtksourceview-3.0-sections.txt b/docs/reference/gtksourceview-3.0-sections.txt
index 3888e2a..5cca889 100644
--- a/docs/reference/gtksourceview-3.0-sections.txt
+++ b/docs/reference/gtksourceview-3.0-sections.txt
@@ -743,6 +743,12 @@ gtk_source_search_settings_get_type
<FILE>spacedrawer</FILE>
<TITLE>GtkSourceSpaceDrawer</TITLE>
GtkSourceSpaceDrawer
+GtkSourceSpaceTypeFlags
+GtkSourceSpaceLocationFlags
+gtk_source_space_drawer_get_types_for_locations
+gtk_source_space_drawer_set_types_for_locations
+gtk_source_space_drawer_get_matrix
+gtk_source_space_drawer_set_matrix
<SUBSECTION Standard>
GTK_SOURCE_IS_SPACE_DRAWER
GTK_SOURCE_IS_SPACE_DRAWER_CLASS
@@ -753,6 +759,10 @@ GTK_SOURCE_TYPE_SPACE_DRAWER
GtkSourceSpaceDrawerClass
GtkSourceSpaceDrawerPrivate
gtk_source_space_drawer_get_type
+GTK_SOURCE_TYPE_SPACE_LOCATION_FLAGS
+GTK_SOURCE_TYPE_SPACE_TYPE_FLAGS
+gtk_source_space_location_flags_get_type
+gtk_source_space_type_flags_get_type
</SECTION>
<SECTION>
diff --git a/gtksourceview/gtksourcespacedrawer.c b/gtksourceview/gtksourcespacedrawer.c
index fc4416e..89e03f6 100644
--- a/gtksourceview/gtksourcespacedrawer.c
+++ b/gtksourceview/gtksourcespacedrawer.c
@@ -45,17 +45,151 @@
struct _GtkSourceSpaceDrawerPrivate
{
+ GtkSourceSpaceTypeFlags *matrix;
GtkSourceDrawSpacesFlags flags;
GdkRGBA *color;
};
+enum
+{
+ PROP_0,
+ PROP_MATRIX,
+ N_PROPERTIES
+};
+
+static GParamSpec *properties[N_PROPERTIES];
+
G_DEFINE_TYPE_WITH_PRIVATE (GtkSourceSpaceDrawer, gtk_source_space_drawer, G_TYPE_OBJECT)
+#if 0
+static gint
+get_flag_index (gint flag)
+{
+ gint index = 0;
+
+ if (flag <= 0)
+ {
+ return -1;
+ }
+
+ while ((flag & 1) == 0)
+ {
+ flag >>= 1;
+ index++;
+ }
+
+ return flag == 1 ? index : -1;
+}
+#endif
+
+static gint
+get_number_of_locations (void)
+{
+ gint num;
+ gint flags;
+
+ num = 0;
+ flags = GTK_SOURCE_SPACE_LOCATION_ALL;
+
+ while (flags != 0)
+ {
+ flags >>= 1;
+ num++;
+ }
+
+ return num;
+}
+
+static gboolean
+is_zero_matrix (GtkSourceSpaceDrawer *drawer)
+{
+ gint num_locations;
+ gint i;
+
+ num_locations = get_number_of_locations ();
+
+ for (i = 0; i < num_locations; i++)
+ {
+ if (drawer->priv->matrix[i] != 0)
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+set_zero_matrix (GtkSourceSpaceDrawer *drawer)
+{
+ gint num_locations;
+ gint i;
+ gboolean changed = FALSE;
+
+ num_locations = get_number_of_locations ();
+
+ for (i = 0; i < num_locations; i++)
+ {
+ if (drawer->priv->matrix[i] != 0)
+ {
+ drawer->priv->matrix[i] = 0;
+ changed = TRUE;
+ }
+ }
+
+ if (changed)
+ {
+ g_object_notify_by_pspec (G_OBJECT (drawer), properties[PROP_MATRIX]);
+ }
+}
+
+static void
+gtk_source_space_drawer_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkSourceSpaceDrawer *drawer = GTK_SOURCE_SPACE_DRAWER (object);
+
+ switch (prop_id)
+ {
+ case PROP_MATRIX:
+ g_value_set_variant (value, gtk_source_space_drawer_get_matrix (drawer));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_source_space_drawer_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkSourceSpaceDrawer *drawer = GTK_SOURCE_SPACE_DRAWER (object);
+
+ switch (prop_id)
+ {
+ case PROP_MATRIX:
+ gtk_source_space_drawer_set_matrix (drawer, g_value_get_variant (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
static void
gtk_source_space_drawer_finalize (GObject *object)
{
GtkSourceSpaceDrawer *drawer = GTK_SOURCE_SPACE_DRAWER (object);
+ g_free (drawer->priv->matrix);
+
if (drawer->priv->color != NULL)
{
gdk_rgba_free (drawer->priv->color);
@@ -69,13 +203,47 @@ gtk_source_space_drawer_class_init (GtkSourceSpaceDrawerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->get_property = gtk_source_space_drawer_get_property;
+ object_class->set_property = gtk_source_space_drawer_set_property;
object_class->finalize = gtk_source_space_drawer_finalize;
+
+ /**
+ * GtkSourceSpaceDrawer:matrix:
+ *
+ * The :matrix property is a #GVariant property to specify where and
+ * what kind of whitespaces to draw.
+ *
+ * The #GVariant is of type `"ai"`, an array of integers. Each integer
+ * is a combination of #GtkSourceSpaceTypeFlags. There is one integer
+ * for each #GtkSourceSpaceLocationFlags, in the same order as they are
+ * defined in the enum (%GTK_SOURCE_SPACE_LOCATION_NONE and
+ * %GTK_SOURCE_SPACE_LOCATION_ALL are not taken into account).
+ *
+ * If the array is shorter than the number of locations, then the value
+ * for the missing locations will be %GTK_SOURCE_SPACE_TYPE_NONE.
+ *
+ * The default value is the empty array `"[]"`.
+ *
+ * Since: 3.24
+ */
+ properties[PROP_MATRIX] =
+ g_param_spec_variant ("matrix",
+ "Matrix",
+ "",
+ G_VARIANT_TYPE ("ai"),
+ g_variant_new ("ai", NULL),
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, N_PROPERTIES, properties);
}
static void
gtk_source_space_drawer_init (GtkSourceSpaceDrawer *drawer)
{
drawer->priv = gtk_source_space_drawer_get_instance_private (drawer);
+
+ drawer->priv->matrix = g_new0 (GtkSourceSpaceTypeFlags, get_number_of_locations ());
}
GtkSourceSpaceDrawer *
@@ -109,6 +277,211 @@ _gtk_source_space_drawer_set_flags (GtkSourceSpaceDrawer *drawer,
return changed;
}
+/**
+ * gtk_source_space_drawer_get_types_for_locations:
+ * @drawer: a #GtkSourceSpaceDrawer.
+ * @locations: one or several #GtkSourceSpaceLocationFlags.
+ *
+ * If only one location is specified, this function returns what kind of
+ * whitespaces are drawn at that location. The value is retrieved from the
+ * #GtkSourceSpaceDrawer:matrix property.
+ *
+ * If several locations are specified, this function returns the logical AND for
+ * those locations. Which means that if a certain kind of whitespace is present
+ * in the return value, then that kind of whitespace is drawn at all the
+ * specified @locations.
+ *
+ * Returns: a combination of #GtkSourceSpaceTypeFlags.
+ * Since: 3.24
+ */
+GtkSourceSpaceTypeFlags
+gtk_source_space_drawer_get_types_for_locations (GtkSourceSpaceDrawer *drawer,
+ GtkSourceSpaceLocationFlags locations)
+{
+ GtkSourceSpaceTypeFlags ret = GTK_SOURCE_SPACE_TYPE_ALL;
+ gint index;
+ gint num_locations;
+ gboolean found;
+
+ g_return_val_if_fail (GTK_SOURCE_IS_SPACE_DRAWER (drawer), GTK_SOURCE_SPACE_TYPE_NONE);
+
+ index = 0;
+ num_locations = get_number_of_locations ();
+ found = FALSE;
+
+ while (locations != 0 && index < num_locations)
+ {
+ if ((locations & 1) == 1)
+ {
+ ret &= drawer->priv->matrix[index];
+ found = TRUE;
+ }
+
+ locations >>= 1;
+ index++;
+ }
+
+ return found ? ret : GTK_SOURCE_SPACE_TYPE_NONE;
+}
+
+/**
+ * gtk_source_space_drawer_set_types_for_locations:
+ * @drawer: a #GtkSourceSpaceDrawer.
+ * @locations: one or several #GtkSourceSpaceLocationFlags.
+ * @types: a combination of #GtkSourceSpaceTypeFlags.
+ *
+ * Modifies the #GtkSourceSpaceDrawer:matrix property at the specified
+ * @locations.
+ *
+ * Since: 3.24
+ */
+void
+gtk_source_space_drawer_set_types_for_locations (GtkSourceSpaceDrawer *drawer,
+ GtkSourceSpaceLocationFlags locations,
+ GtkSourceSpaceTypeFlags types)
+{
+ gint index;
+ gint num_locations;
+ gboolean changed = FALSE;
+
+ g_return_if_fail (GTK_SOURCE_IS_SPACE_DRAWER (drawer));
+
+ index = 0;
+ num_locations = get_number_of_locations ();
+
+ while (locations != 0 && index < num_locations)
+ {
+ if ((locations & 1) == 1 &&
+ drawer->priv->matrix[index] != types)
+ {
+ drawer->priv->matrix[index] = types;
+ changed = TRUE;
+ }
+
+ locations >>= 1;
+ index++;
+ }
+
+ if (changed)
+ {
+ g_object_notify_by_pspec (G_OBJECT (drawer), properties[PROP_MATRIX]);
+ }
+}
+
+/**
+ * gtk_source_space_drawer_get_matrix:
+ * @drawer: a #GtkSourceSpaceDrawer.
+ *
+ * Gets the value of the #GtkSourceSpaceDrawer:matrix property, as a #GVariant.
+ * An empty array can be returned in case the matrix is a zero matrix.
+ *
+ * The gtk_source_space_drawer_get_types_for_locations() function may be more
+ * convenient to use.
+ *
+ * Returns: the #GtkSourceSpaceDrawer:matrix value as a new floating #GVariant
+ * instance.
+ * Since: 3.24
+ */
+GVariant *
+gtk_source_space_drawer_get_matrix (GtkSourceSpaceDrawer *drawer)
+{
+ GVariantBuilder builder;
+ gint num_locations;
+ gint i;
+
+ g_return_val_if_fail (GTK_SOURCE_IS_SPACE_DRAWER (drawer), NULL);
+
+ if (is_zero_matrix (drawer))
+ {
+ return g_variant_new ("ai", NULL);
+ }
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("ai"));
+
+ num_locations = get_number_of_locations ();
+
+ for (i = 0; i < num_locations; i++)
+ {
+ GVariant *space_types;
+
+ space_types = g_variant_new_int32 ((gint32) drawer->priv->matrix[i]);
+
+ g_variant_builder_add_value (&builder, space_types);
+ }
+
+ return g_variant_builder_end (&builder);
+}
+
+/**
+ * gtk_source_space_drawer_set_matrix:
+ * @drawer: a #GtkSourceSpaceDrawer.
+ * @matrix: (transfer floating) (nullable): the new matrix value, or %NULL.
+ *
+ * Sets a new value to the #GtkSourceSpaceDrawer:matrix property, as a
+ * #GVariant. If @matrix is %NULL, then an empty array is set.
+ *
+ * If @matrix is floating, it is consumed.
+ *
+ * The gtk_source_space_drawer_set_types_for_locations() function may be more
+ * convenient to use.
+ *
+ * Since: 3.24
+ */
+void
+gtk_source_space_drawer_set_matrix (GtkSourceSpaceDrawer *drawer,
+ GVariant *matrix)
+{
+ gint num_locations;
+ gint i;
+ GVariantIter iter;
+ gboolean changed = FALSE;
+
+ g_return_if_fail (GTK_SOURCE_IS_SPACE_DRAWER (drawer));
+
+ if (matrix == NULL)
+ {
+ set_zero_matrix (drawer);
+ return;
+ }
+
+ g_return_if_fail (g_variant_is_of_type (matrix, G_VARIANT_TYPE ("ai")));
+
+ g_variant_iter_init (&iter, matrix);
+
+ num_locations = get_number_of_locations ();
+
+ for (i = 0; i < num_locations; i++)
+ {
+ GVariant *child;
+ gint32 space_types;
+
+ child = g_variant_iter_next_value (&iter);
+ space_types = child != NULL ? g_variant_get_int32 (child) : 0;
+
+ if (drawer->priv->matrix[i] != space_types)
+ {
+ drawer->priv->matrix[i] = space_types;
+ changed = TRUE;
+ }
+
+ if (child != NULL)
+ {
+ g_variant_unref (child);
+ }
+ }
+
+ if (changed)
+ {
+ g_object_notify_by_pspec (G_OBJECT (drawer), properties[PROP_MATRIX]);
+ }
+
+ if (g_variant_is_floating (matrix))
+ {
+ g_variant_ref_sink (matrix);
+ g_variant_unref (matrix);
+ }
+}
+
void
_gtk_source_space_drawer_update_color (GtkSourceSpaceDrawer *drawer,
GtkSourceView *view)
diff --git a/gtksourceview/gtksourcespacedrawer.h b/gtksourceview/gtksourcespacedrawer.h
index 63ca162..a302eea 100644
--- a/gtksourceview/gtksourcespacedrawer.h
+++ b/gtksourceview/gtksourcespacedrawer.h
@@ -51,9 +51,73 @@ struct _GtkSourceSpaceDrawerClass
gpointer padding[20];
};
+/**
+ * GtkSourceSpaceTypeFlags:
+ * @GTK_SOURCE_SPACE_TYPE_NONE: No flags.
+ * @GTK_SOURCE_SPACE_TYPE_SPACE: Space character.
+ * @GTK_SOURCE_SPACE_TYPE_TAB: Tab character.
+ * @GTK_SOURCE_SPACE_TYPE_NEWLINE: Line break character.
+ * @GTK_SOURCE_SPACE_TYPE_NBSP: Non-breaking space character.
+ * @GTK_SOURCE_SPACE_TYPE_ALL: All whitespaces.
+ *
+ * #GtkSourceSpaceTypeFlags contains flags for whitespace types.
+ *
+ * Since: 3.24
+ */
+typedef enum _GtkSourceSpaceTypeFlags
+{
+ GTK_SOURCE_SPACE_TYPE_NONE = 0,
+ GTK_SOURCE_SPACE_TYPE_SPACE = 1 << 0,
+ GTK_SOURCE_SPACE_TYPE_TAB = 1 << 1,
+ GTK_SOURCE_SPACE_TYPE_NEWLINE = 1 << 2,
+ GTK_SOURCE_SPACE_TYPE_NBSP = 1 << 3,
+ GTK_SOURCE_SPACE_TYPE_ALL = 0xf
+} GtkSourceSpaceTypeFlags;
+
+/**
+ * GtkSourceSpaceLocationFlags:
+ * @GTK_SOURCE_SPACE_LOCATION_NONE: No flags.
+ * @GTK_SOURCE_SPACE_LOCATION_LEADING: Leading whitespaces on a line, i.e. the
+ * indentation.
+ * @GTK_SOURCE_SPACE_LOCATION_INSIDE_TEXT: Whitespaces inside a line of text.
+ * @GTK_SOURCE_SPACE_LOCATION_TRAILING: Trailing whitespaces on a line.
+ * @GTK_SOURCE_SPACE_LOCATION_ALL: Whitespaces anywhere.
+ *
+ * #GtkSourceSpaceLocationFlags contains flags for whitespace locations.
+ *
+ * If a line contains only whitespaces (no text), the whitespaces match both
+ * %GTK_SOURCE_SPACE_LOCATION_LEADING and %GTK_SOURCE_SPACE_LOCATION_TRAILING.
+ *
+ * Since: 3.24
+ */
+typedef enum _GtkSourceSpaceLocationFlags
+{
+ GTK_SOURCE_SPACE_LOCATION_NONE = 0,
+ GTK_SOURCE_SPACE_LOCATION_LEADING = 1 << 0,
+ GTK_SOURCE_SPACE_LOCATION_INSIDE_TEXT = 1 << 1,
+ GTK_SOURCE_SPACE_LOCATION_TRAILING = 1 << 2,
+ GTK_SOURCE_SPACE_LOCATION_ALL = 0x7
+} GtkSourceSpaceLocationFlags;
+
GTK_SOURCE_AVAILABLE_IN_3_24
GType gtk_source_space_drawer_get_type (void) G_GNUC_CONST;
+GTK_SOURCE_AVAILABLE_IN_3_24
+GtkSourceSpaceTypeFlags gtk_source_space_drawer_get_types_for_locations (GtkSourceSpaceDrawer
*drawer,
+ GtkSourceSpaceLocationFlags
locations);
+
+GTK_SOURCE_AVAILABLE_IN_3_24
+void gtk_source_space_drawer_set_types_for_locations (GtkSourceSpaceDrawer *drawer,
+ GtkSourceSpaceLocationFlags
locations,
+ GtkSourceSpaceTypeFlags types);
+
+GTK_SOURCE_AVAILABLE_IN_3_24
+GVariant * gtk_source_space_drawer_get_matrix (GtkSourceSpaceDrawer *drawer);
+
+GTK_SOURCE_AVAILABLE_IN_3_24
+void gtk_source_space_drawer_set_matrix (GtkSourceSpaceDrawer *drawer,
+ GVariant *matrix);
+
G_END_DECLS
#endif /* GTK_SOURCE_SPACE_DRAWER_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]