[gtk/prop-list: 4/21] Add GtkNumericSorter
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/prop-list: 4/21] Add GtkNumericSorter
- Date: Mon, 9 Dec 2019 07:28:10 +0000 (UTC)
commit 93e2e5e171d937140a3379d0147333e5becd73af
Author: Matthias Clasen <mclasen redhat com>
Date: Sun Dec 8 14:37:20 2019 -0500
Add GtkNumericSorter
This sorter compares numbers obtained from items
by evaluating an expression.
docs/reference/gtk/gtk4-docs.xml | 1 +
docs/reference/gtk/gtk4-sections.txt | 19 ++
docs/reference/gtk/gtk4.types.in | 1 +
gtk/gtk.h | 1 +
gtk/gtknumericsorter.c | 360 +++++++++++++++++++++++++++++++++++
gtk/gtknumericsorter.h | 53 ++++++
gtk/meson.build | 2 +
7 files changed, 437 insertions(+)
---
diff --git a/docs/reference/gtk/gtk4-docs.xml b/docs/reference/gtk/gtk4-docs.xml
index 5a55fee5d0..98fd5c90fb 100644
--- a/docs/reference/gtk/gtk4-docs.xml
+++ b/docs/reference/gtk/gtk4-docs.xml
@@ -51,6 +51,7 @@
<xi:include href="xml/gtkslicelistmodel.xml" />
<xi:include href="xml/gtksorter.xml" />
<xi:include href="xml/gtkstringsorter.xml" />
+ <xi:include href="xml/gtknumericsorter.xml" />
<xi:include href="xml/gtkcustomsorter.xml" />
<xi:include href="xml/gtkmultisorter.xml" />
<xi:include href="xml/gtksortlistmodel.xml" />
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 714a49d9bd..678399ea82 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -2892,6 +2892,25 @@ GTK_STRING_SORTER_GET_CLASS
gtk_string_sorter_get_type
</SECTION>
+<SECTION>
+<FILE>gtknumericsorter</FILE>
+<TITLE>GtkNumericSorter</TITLE>
+GtkNumericSorter
+gtk_numeric_sorter_new
+gtk_numeric_sorter_get_expression
+gtk_numeric_sorter_set_expression
+gtk_numeric_sorter_get_sort_increasing
+gtk_numeric_sorter_set_sort_increasing
+<SUBSECTION Standard>
+GTK_NUMERIC_SORTER
+GTK_IS_NUMERIC_SORTER
+GTK_TYPE_NUMERIC_SORTER
+GTK_IS_NUMERIC_SORTER_CLASS
+GTK_NUMERIC_SORTER_GET_CLASS
+<SUBSECTION Private>
+gtk_numeric_sorter_get_type
+</SECTION>
+
<SECTION>
<FILE>gtkcustomsorter</FILE>
<TITLE>GtkCustomSorter</TITLE>
diff --git a/docs/reference/gtk/gtk4.types.in b/docs/reference/gtk/gtk4.types.in
index d3a73beb1f..b9f1bde8a9 100644
--- a/docs/reference/gtk/gtk4.types.in
+++ b/docs/reference/gtk/gtk4.types.in
@@ -130,6 +130,7 @@ gtk_native_get_type
gtk_no_selection_get_type
gtk_notebook_get_type
gtk_notebook_page_get_type
+gtk_numeric_sorter_get_type
gtk_orientable_get_type
gtk_overlay_get_type
gtk_pad_controller_get_type
diff --git a/gtk/gtk.h b/gtk/gtk.h
index 7a8d076a53..f74d1a4b0a 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -184,6 +184,7 @@
#include <gtk/gtknativedialog.h>
#include <gtk/gtknoselection.h>
#include <gtk/gtknotebook.h>
+#include <gtk/gtknumericsorter.h>
#include <gtk/gtkorientable.h>
#include <gtk/gtkoverlay.h>
#include <gtk/gtkpadcontroller.h>
diff --git a/gtk/gtknumericsorter.c b/gtk/gtknumericsorter.c
new file mode 100644
index 0000000000..277842f176
--- /dev/null
+++ b/gtk/gtknumericsorter.c
@@ -0,0 +1,360 @@
+/*
+ * Copyright © 2019 Matthias Clasen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Matthias Clasen <mclasen redhat com>
+ */
+
+#include "config.h"
+
+#include "gtknumericsorter.h"
+
+#include "gtkintl.h"
+#include "gtktypebuiltins.h"
+
+/**
+ * SECTION:gtknumericsorter
+ * @Title: GtkNumericSorter
+ * @Short_description: Sort by comparing numbers
+ * @See_also: #GtkExpression
+ *
+ * GtkNumericSorter is a #GtkSorter that compares numbers.
+ *
+ * To obtain the numbers to compare, this sorter evaluates a #GtkExpression.
+ */
+
+struct _GtkNumericSorter
+{
+ GtkSorter parent_instance;
+
+ gboolean sort_increasing;
+
+ GtkExpression *expression;
+ GType target_type;
+};
+
+enum {
+ PROP_0,
+ PROP_EXPRESSION,
+ PROP_SORT_INCREASING,
+ NUM_PROPERTIES
+};
+
+G_DEFINE_TYPE (GtkNumericSorter, gtk_numeric_sorter, GTK_TYPE_SORTER)
+
+static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
+
+static int
+gtk_numeric_sorter_compare (GtkSorter *sorter,
+ gpointer item1,
+ gpointer item2)
+{
+ GtkNumericSorter *self = GTK_NUMERIC_SORTER (sorter);
+ GValue value1 = G_VALUE_INIT;
+ GValue value2 = G_VALUE_INIT;
+ GValue dst = G_VALUE_INIT;
+ int result = 0;
+
+ if (self->expression == NULL ||
+ !gtk_expression_evaluate (self->expression, item1, &value1) ||
+ !gtk_expression_evaluate (self->expression, item2, &value2))
+ goto out;
+
+ switch (self->target_type)
+ {
+ case G_TYPE_INT64:
+ {
+ gint64 v1, v2;
+
+ g_value_init (&dst, G_TYPE_INT64);
+ g_value_transform (&value1, &dst);
+ v1 = g_value_get_int64 (&dst);
+ g_value_transform (&value2, &dst);
+ v2 = g_value_get_int64 (&dst);
+
+ if (v1 > v2)
+ result = 1;
+ else if (v1 < v2)
+ result = -1;
+ else
+ result = 0;
+ }
+ break;
+
+ case G_TYPE_UINT64:
+ {
+ guint64 v1, v2;
+
+ g_value_init (&dst, G_TYPE_UINT64);
+ g_value_transform (&value1, &dst);
+ v1 = g_value_get_uint64 (&dst);
+ g_value_transform (&value2, &dst);
+ v2 = g_value_get_uint64 (&dst);
+
+ if (v1 > v2)
+ result = 1;
+ else if (v1 < v2)
+ result = -1;
+ else
+ result = 0;
+ }
+ break;
+
+ case G_TYPE_DOUBLE:
+ {
+ double v1, v2;
+
+ g_value_init (&dst, G_TYPE_DOUBLE);
+ g_value_transform (&value1, &dst);
+ v1 = g_value_get_double (&dst);
+ g_value_transform (&value2, &dst);
+ v2 = g_value_get_double (&dst);
+
+ if (v1 > v2)
+ result = 1;
+ else if (v1 < v2)
+ result = -1;
+ else
+ result = 0;
+ }
+ break;
+
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+out:
+ g_value_unset (&value1);
+ g_value_unset (&value2);
+
+ if (!self->sort_increasing)
+ result = - result;
+
+ return result;
+}
+
+static void
+gtk_numeric_sorter_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkNumericSorter *self = GTK_NUMERIC_SORTER (object);
+
+ switch (prop_id)
+ {
+ case PROP_EXPRESSION:
+ gtk_numeric_sorter_set_expression (self, g_value_get_boxed (value));
+ break;
+
+ case PROP_SORT_INCREASING:
+ gtk_numeric_sorter_set_sort_increasing (self, g_value_get_boolean (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_numeric_sorter_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkNumericSorter *self = GTK_NUMERIC_SORTER (object);
+
+ switch (prop_id)
+ {
+ case PROP_EXPRESSION:
+ g_value_set_boxed (value, self->expression);
+ break;
+
+ case PROP_SORT_INCREASING:
+ g_value_set_boolean (value, self->sort_increasing);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_numeric_sorter_dispose (GObject *object)
+{
+ GtkNumericSorter *self = GTK_NUMERIC_SORTER (object);
+
+ g_clear_pointer (&self->expression, gtk_expression_unref);
+
+ G_OBJECT_CLASS (gtk_numeric_sorter_parent_class)->dispose (object);
+}
+
+static void
+gtk_numeric_sorter_class_init (GtkNumericSorterClass *class)
+{
+ GtkSorterClass *sorter_class = GTK_SORTER_CLASS (class);
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ sorter_class->compare = gtk_numeric_sorter_compare;
+
+ object_class->get_property = gtk_numeric_sorter_get_property;
+ object_class->set_property = gtk_numeric_sorter_set_property;
+ object_class->dispose = gtk_numeric_sorter_dispose;
+
+ /**
+ * GtkNumericSorter:expression:
+ *
+ * The expression to evalute on item to get a numeric to compare with
+ */
+ properties[PROP_EXPRESSION] =
+ g_param_spec_boxed ("expression",
+ P_("Expression"),
+ P_("Expression to compare with"),
+ GTK_TYPE_EXPRESSION,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
+ /**
+ * GtkNumericSorter:sort-increasing:
+ *
+ * Whether the sorter will sort smaller numbers first
+ */
+ properties[PROP_SORT_INCREASING] =
+ g_param_spec_boolean ("sort-increasing",
+ P_("Sort increasing"),
+ P_("Whether to sort smaller numbers first"),
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
+ g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
+
+}
+
+static void
+gtk_numeric_sorter_init (GtkNumericSorter *self)
+{
+ self->sort_increasing = TRUE;
+}
+
+/**
+ * gtk_numeric_sorter_new:
+ *
+ * Creates a new numeric sorter.
+ *
+ * Until an expression is set on it, this sorter will always
+ * compare items as equal.
+ *
+ * Returns: a new #GtkSorter
+ */
+GtkSorter *
+gtk_numeric_sorter_new (void)
+{
+ return g_object_new (GTK_TYPE_NUMERIC_SORTER, NULL);
+}
+
+/**
+ * gtk_numeric_sorter_get_expression:
+ * @self: a #GtkNumericSorter
+ *
+ * Gets the expression that is evaluated to obtain numbers from items.
+ *
+ * Returns: (nullable): a #GtkExpression, or %NULL
+ */
+GtkExpression *
+gtk_numeric_sorter_get_expression (GtkNumericSorter *self)
+{
+ g_return_val_if_fail (GTK_IS_NUMERIC_SORTER (self), NULL);
+
+ return self->expression;
+}
+
+/**
+ * gtk_numeric_sorter_set_expression:
+ * @self: a #GtkNumericSorter
+ * @expression: (nullable) (transfer none): a #GtkExpression, or %NULL
+ *
+ * Sets the expression that is evaluated to obtain numbers from items.
+ *
+ * The expression must have a type that can be transformed to G_TYPE_INT64,
+ * G_TYPE_UINT64 or G_TYPE_DOUBLE.
+ */
+void
+gtk_numeric_sorter_set_expression (GtkNumericSorter *self,
+ GtkExpression *expression)
+{
+ g_return_if_fail (GTK_IS_NUMERIC_SORTER (self));
+ g_return_if_fail (expression == NULL ||
+ g_value_type_transformable (gtk_expression_get_value_type (expression), G_TYPE_INT64) ||
+ g_value_type_transformable (gtk_expression_get_value_type (expression), G_TYPE_UINT64) ||
+ g_value_type_transformable (gtk_expression_get_value_type (expression), G_TYPE_DOUBLE));
+
+ if (self->expression == expression)
+ return;
+
+ g_clear_pointer (&self->expression, gtk_expression_unref);
+ self->expression = gtk_expression_ref (expression);
+
+ if (g_value_type_transformable (gtk_expression_get_value_type (expression), G_TYPE_INT64))
+ self->target_type = G_TYPE_INT64;
+ else if (g_value_type_transformable (gtk_expression_get_value_type (expression), G_TYPE_UINT64))
+ self->target_type = G_TYPE_UINT64;
+ else
+ self->target_type = G_TYPE_DOUBLE;
+
+ gtk_sorter_changed (GTK_SORTER (self), GTK_SORTER_CHANGE_DIFFERENT);
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_EXPRESSION]);
+}
+
+/**
+ * gtk_numeric_sorter_set_sort_increasing:
+ * @self: a #GtkNumericSorter
+ * @sort_increasing: whether to sort smaller numbers first
+ *
+ * Sets whether to sort smaller numbers before larger ones.
+ */
+void
+gtk_numeric_sorter_set_sort_increasing (GtkNumericSorter *self,
+ gboolean sort_increasing)
+{
+ g_return_if_fail (GTK_IS_NUMERIC_SORTER (self));
+
+ if (self->sort_increasing == sort_increasing)
+ return;
+
+ self->sort_increasing = sort_increasing;
+
+ gtk_sorter_changed (GTK_SORTER (self), GTK_SORTER_CHANGE_INVERTED);
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SORT_INCREASING]);
+}
+
+/**
+ * gtk_numeric_sorter_get_sort_increasing:
+ * @self: a #GtkNumericSorter
+ *
+ * Gets whether this sorter will sort smaller numbers first.
+ *
+ * Returns: %TRUE if smaller numbers are sorted first
+ */
+gboolean
+gtk_numeric_sorter_get_sort_increasing (GtkNumericSorter *self)
+{
+ g_return_val_if_fail (GTK_IS_NUMERIC_SORTER (self), TRUE);
+
+ return self->sort_increasing;
+}
diff --git a/gtk/gtknumericsorter.h b/gtk/gtknumericsorter.h
new file mode 100644
index 0000000000..9668c32ffc
--- /dev/null
+++ b/gtk/gtknumericsorter.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright © 2019 Matthias Clasen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Matthias Clasen <mclasen redhat com>
+ */
+
+#ifndef __GTK_NUMERIC_SORTER_H__
+#define __GTK_NUMERIC_SORTER_H__
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#include <gtk/gtkexpression.h>
+#include <gtk/gtksorter.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_NUMERIC_SORTER (gtk_numeric_sorter_get_type ())
+GDK_AVAILABLE_IN_ALL
+G_DECLARE_FINAL_TYPE (GtkNumericSorter, gtk_numeric_sorter, GTK, NUMERIC_SORTER, GtkSorter)
+
+GDK_AVAILABLE_IN_ALL
+GtkSorter * gtk_numeric_sorter_new (void);
+
+GDK_AVAILABLE_IN_ALL
+GtkExpression * gtk_numeric_sorter_get_expression (GtkNumericSorter *self);
+GDK_AVAILABLE_IN_ALL
+void gtk_numeric_sorter_set_expression (GtkNumericSorter *self,
+ GtkExpression *expression);
+
+GDK_AVAILABLE_IN_ALL
+gboolean gtk_numeric_sorter_get_sort_increasing (GtkNumericSorter *self);
+GDK_AVAILABLE_IN_ALL
+void gtk_numeric_sorter_set_sort_increasing (GtkNumericSorter *self,
+ gboolean sort_increasing);
+
+G_END_DECLS
+
+#endif /* __GTK_NUMERIC_SORTER_H__ */
diff --git a/gtk/meson.build b/gtk/meson.build
index 7235fd4e43..6b26237e4a 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -321,6 +321,7 @@ gtk_public_sources = files([
'gtknomediafile.c',
'gtknoselection.c',
'gtknotebook.c',
+ 'gtknumericsorter.c',
'gtkorientable.c',
'gtkoverlay.c',
'gtkoverlaylayout.c',
@@ -601,6 +602,7 @@ gtk_public_headers = files([
'gtknativedialog.h',
'gtknoselection.h',
'gtknotebook.h',
+ 'gtknumericsorter.h',
'gtkorientable.h',
'gtkoverlay.h',
'gtkpadcontroller.h',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]