forked from AuroraMiddleware/gtk
Add GtkSorter
This is a helper object for sorting, similar to GtkFilter.
This commit is contained in:
parent
cb15ec0257
commit
b2b847f365
@ -60,6 +60,9 @@
|
||||
<xi:include href="xml/gtkmaplistmodel.xml" />
|
||||
<xi:include href="xml/gtkslicelistmodel.xml" />
|
||||
<xi:include href="xml/gtksortlistmodel.xml" />
|
||||
<section>
|
||||
<xi:include href="xml/gtksorter.xml" />
|
||||
</section>
|
||||
<xi:include href="xml/gtkselectionmodel.xml" />
|
||||
<xi:include href="xml/gtknoselection.xml" />
|
||||
<xi:include href="xml/gtksingleselection.xml" />
|
||||
|
@ -2421,6 +2421,26 @@ GTK_SLICE_LIST_MODEL_GET_CLASS
|
||||
gtk_slice_list_model_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtksorter</FILE>
|
||||
<TITLE>GtkSorter</TITLE>
|
||||
GtkSorter
|
||||
GtkSorterOrder
|
||||
GtkSorterChange
|
||||
gtk_sorter_compare
|
||||
gtk_sorter_get_order
|
||||
gtk_sorter_changed
|
||||
<SUBSECTION Standard>
|
||||
GTK_SORTER
|
||||
GTK_IS_SORTER
|
||||
GTK_TYPE_SORTER
|
||||
GTK_SORTER_CLASS
|
||||
GTK_IS_SORTER_CLASS
|
||||
GTK_SORTER_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
gtk_sorter_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtksortlistmodel</FILE>
|
||||
<TITLE>GtkSortListModel</TITLE>
|
||||
|
@ -185,6 +185,7 @@ gtk_size_group_get_type
|
||||
gtk_slice_list_model_get_type
|
||||
gtk_snapshot_get_type
|
||||
gtk_sort_list_model_get_type
|
||||
gtk_sorter_get_type
|
||||
gtk_spin_button_get_type
|
||||
gtk_spinner_get_type
|
||||
gtk_stack_get_type
|
||||
|
@ -214,6 +214,7 @@
|
||||
#include <gtk/gtksingleselection.h>
|
||||
#include <gtk/gtkslicelistmodel.h>
|
||||
#include <gtk/gtksnapshot.h>
|
||||
#include <gtk/gtksorter.h>
|
||||
#include <gtk/gtksortlistmodel.h>
|
||||
#include <gtk/gtkstacksidebar.h>
|
||||
#include <gtk/gtksizegroup.h>
|
||||
|
207
gtk/gtksorter.c
Normal file
207
gtk/gtksorter.c
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* 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 "gtksorter.h"
|
||||
|
||||
#include "gtkintl.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
|
||||
/**
|
||||
* SECTION:gtksorter
|
||||
* @title: GtkSorter
|
||||
* @Short_description: Sorting items
|
||||
* @See_also: #GtkSortListModel
|
||||
*
|
||||
* #GtkSorter is the way to describe sorting criteria.
|
||||
* Its primary user is #GtkSortListModel.
|
||||
*
|
||||
* The model will use a sorter to determine the order in which its items should appear
|
||||
* by calling gtk_sorter_compare() for pairs of items.
|
||||
*
|
||||
* Sorters may change their sorting behavior through their lifetime. In that case,
|
||||
* they call gtk_sorter_changed(), which will emit the #GtkSorter::changed signal to
|
||||
* notify that the sort order is no longer valid and should be updated by calling
|
||||
* gtk_sorter_compare() again.
|
||||
*
|
||||
* GTK provides various pre-made sorter implementations for common sorting operations.
|
||||
* #GtkColumnView has built-in support for sorting lists via the #GtkColumnViewColumn:sorter
|
||||
* property, where the user can change the sorting by clicking on list headers.
|
||||
*
|
||||
* Of course, in particular for large lists, it is also possible to subclass #GtkSorter
|
||||
* and provide one's own sorter.
|
||||
*/
|
||||
|
||||
enum {
|
||||
CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkSorter, gtk_sorter, G_TYPE_OBJECT)
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static GtkOrdering
|
||||
gtk_sorter_default_compare (GtkSorter *self,
|
||||
gpointer item1,
|
||||
gpointer item2)
|
||||
{
|
||||
g_critical ("Sorter of type '%s' does not implement GtkSorter::compare", G_OBJECT_TYPE_NAME (self));
|
||||
|
||||
return GTK_ORDERING_EQUAL;
|
||||
}
|
||||
|
||||
static GtkSorterOrder
|
||||
gtk_sorter_default_get_order (GtkSorter *self)
|
||||
{
|
||||
return GTK_SORTER_ORDER_PARTIAL;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_sorter_class_init (GtkSorterClass *class)
|
||||
{
|
||||
class->compare = gtk_sorter_default_compare;
|
||||
class->get_order = gtk_sorter_default_get_order;
|
||||
|
||||
/**
|
||||
* GtkSorter::changed:
|
||||
* @self: The #GtkSorter
|
||||
* @change: how the sorter changed
|
||||
*
|
||||
* This signal is emitted whenever the sorter changed. Users of the sorter
|
||||
* should then update the sort order again via gtk_sorter_compare().
|
||||
*
|
||||
* #GtkSortListModel handles this signal automatically.
|
||||
*
|
||||
* Depending on the @change parameter, it may be possible to update
|
||||
* the sort order without a full resorting. Refer to the #GtkSorterChange
|
||||
* documentation for details.
|
||||
*/
|
||||
signals[CHANGED] =
|
||||
g_signal_new (I_("changed"),
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__ENUM,
|
||||
G_TYPE_NONE, 1,
|
||||
GTK_TYPE_SORTER_CHANGE);
|
||||
g_signal_set_va_marshaller (signals[CHANGED],
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
g_cclosure_marshal_VOID__ENUMv);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_sorter_init (GtkSorter *self)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_sorter_compare:
|
||||
* @self: a #GtkSorter
|
||||
* @item1: (type GObject) (transfer none): first item to compare
|
||||
* @item2: (type GObject) (transfer none): second item to compare
|
||||
*
|
||||
* Compares two given items according to the sort order implemented
|
||||
* by the sorter.
|
||||
*
|
||||
* Sorters implement a partial order:
|
||||
* * It is reflexive, ie a = a
|
||||
* * It is antisymmetric, ie if a < b and b < a, then a = b
|
||||
* * It is transitive, ie given any 3 items with a ≤ b and b ≤ c,
|
||||
* then a ≤ c
|
||||
*
|
||||
* The sorter may signal it conforms to additional constraints
|
||||
* via the return value of gtk_sorter_get_order().
|
||||
*
|
||||
* Returns: %GTK_ORDERING_EQUAL if @item1 == @item2,
|
||||
* %GTK_ORDERING_SMALLER if @item1 < @item2,
|
||||
* %GTK_ORDERING_LARGER if @item1 > @item2
|
||||
*/
|
||||
GtkOrdering
|
||||
gtk_sorter_compare (GtkSorter *self,
|
||||
gpointer item1,
|
||||
gpointer item2)
|
||||
{
|
||||
GtkOrdering result;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_SORTER (self), GTK_ORDERING_EQUAL);
|
||||
g_return_val_if_fail (item1 && item2, GTK_ORDERING_EQUAL);
|
||||
|
||||
if (item1 == item2)
|
||||
return GTK_ORDERING_EQUAL;
|
||||
|
||||
result = GTK_SORTER_GET_CLASS (self)->compare (self, item1, item2);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (result < -1 || result > 1)
|
||||
{
|
||||
g_critical ("A sorter of type \"%s\" returned %d, which is not a valid GtkOrdering result.\n"
|
||||
"Did you forget to call gtk_ordering_from_cmpfunc()?",
|
||||
G_OBJECT_TYPE_NAME (self), (int) result);
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_sorter_get_order:
|
||||
* @self: a #GtkSorter
|
||||
*
|
||||
* Gets the order that @self conforms to. See #GtkSorterOrder for details
|
||||
* of the possible return values.
|
||||
*
|
||||
* This function is intended to allow optimizations.
|
||||
*
|
||||
* Returns: The order
|
||||
**/
|
||||
GtkSorterOrder
|
||||
gtk_sorter_get_order (GtkSorter *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_SORTER (self), GTK_SORTER_ORDER_PARTIAL);
|
||||
|
||||
return GTK_SORTER_GET_CLASS (self)->get_order (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_sorter_changed:
|
||||
* @self: a #GtkSorter
|
||||
* @change: How the sorter changed
|
||||
*
|
||||
* Emits the #GtkSorter::changed signal to notify all users of the sorter
|
||||
* that it has changed. Users of the sorter should then update the sort
|
||||
* order via gtk_sorter_compare().
|
||||
*
|
||||
* Depending on the @change parameter, it may be possible to update
|
||||
* the sort order without a full resorting. Refer to the #GtkSorterChange
|
||||
* documentation for details.
|
||||
*
|
||||
* This function is intended for implementors of #GtkSorter subclasses and
|
||||
* should not be called from other functions.
|
||||
*/
|
||||
void
|
||||
gtk_sorter_changed (GtkSorter *self,
|
||||
GtkSorterChange change)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_SORTER (self));
|
||||
|
||||
g_signal_emit (self, signals[CHANGED], 0, change);
|
||||
}
|
124
gtk/gtksorter.h
Normal file
124
gtk/gtksorter.h
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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_SORTER_H__
|
||||
#define __GTK_SORTER_H__
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtkenums.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* GtkSorterOrder:
|
||||
* @GTK_SORTER_ORDER_PARTIAL: A partial order. And #GtkOrdering is possible.
|
||||
* @GTK_SORTER_ORDER_INVALID: An invalid order. gtk_sorter_compare() will
|
||||
* always return %GTK_ORDERING_INVALID if both items are unequal.
|
||||
* @GTK_SORTER_ORDER_NONE: No order, all elements are considered equal.
|
||||
* gtk_sorter_compare() will only return %GTK_ORDERING_EQUAL or
|
||||
* %GTK_ORDERING_INVALID.
|
||||
* @GTK_SORTER_ORDER_TOTAL: A total order. gtk_sorter_compare() will only
|
||||
* return %GTK_ORDERING_EQUAL if an item is compared with itself. Two
|
||||
* different items will never cause this value to be returned.
|
||||
*
|
||||
* Describes the type of order that a #GtkSorter may describe.
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_SORTER_ORDER_PARTIAL,
|
||||
GTK_SORTER_ORDER_NONE,
|
||||
GTK_SORTER_ORDER_TOTAL
|
||||
} GtkSorterOrder;
|
||||
|
||||
/**
|
||||
* GtkSorterChange:
|
||||
* @GTK_SORTER_CHANGE_DIFFERENT: The sorter change cannot be described
|
||||
* by any of the other enumeration values
|
||||
* @GTK_SORTER_CHANGE_INVERTED: The sort order was inverted. Comparisons
|
||||
* that returned %GTK_ORDERING_SMALLER now return %GTK_ORDERING_LARGER
|
||||
* and vice versa. Other comparisons return the same values as before.
|
||||
* @GTK_SORTER_CHANGE_LESS_STRICT: The sorter is less strict: Comparisons
|
||||
* may now return %GTK_ORDERING_EQUAL that did not do so before.
|
||||
* @GTK_SORTER_CHANGE_MORE_STRICT: The sorter is more strict: Comparisons
|
||||
* that did return %GTK_ORDERING_EQUAL may not do so anymore.
|
||||
*
|
||||
* Describes changes in a sorter in more detail and allows users
|
||||
* to optimize resorting.
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_SORTER_CHANGE_DIFFERENT,
|
||||
GTK_SORTER_CHANGE_INVERTED,
|
||||
GTK_SORTER_CHANGE_LESS_STRICT,
|
||||
GTK_SORTER_CHANGE_MORE_STRICT
|
||||
} GtkSorterChange;
|
||||
|
||||
#define GTK_TYPE_SORTER (gtk_sorter_get_type ())
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_DERIVABLE_TYPE (GtkSorter, gtk_sorter, GTK, SORTER, GObject)
|
||||
|
||||
/**
|
||||
* GtkSorterClass
|
||||
* @compare: Compare two items. See gtk_sorter_compare() for details.
|
||||
* @get_order: Get the #GtkSorderOrder that applies to the current sorter.
|
||||
* If unimplemented, it returns %GTK_SORTER_ORDER_PARTIAL.
|
||||
*
|
||||
* The virtual table for #GtkSorter.
|
||||
*/
|
||||
struct _GtkSorterClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
GtkOrdering (* compare) (GtkSorter *self,
|
||||
gpointer item1,
|
||||
gpointer item2);
|
||||
|
||||
/* optional */
|
||||
GtkSorterOrder (* get_order) (GtkSorter *self);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_gtk_reserved1) (void);
|
||||
void (*_gtk_reserved2) (void);
|
||||
void (*_gtk_reserved3) (void);
|
||||
void (*_gtk_reserved4) (void);
|
||||
void (*_gtk_reserved5) (void);
|
||||
void (*_gtk_reserved6) (void);
|
||||
void (*_gtk_reserved7) (void);
|
||||
void (*_gtk_reserved8) (void);
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkOrdering gtk_sorter_compare (GtkSorter *self,
|
||||
gpointer item1,
|
||||
gpointer item2);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkSorterOrder gtk_sorter_get_order (GtkSorter *self);
|
||||
|
||||
/* for sorter implementations */
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_sorter_changed (GtkSorter *self,
|
||||
GtkSorterChange change);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_SORTER_H__ */
|
||||
|
@ -346,6 +346,7 @@ gtk_public_sources = files([
|
||||
'gtksizerequest.c',
|
||||
'gtkslicelistmodel.c',
|
||||
'gtksnapshot.c',
|
||||
'gtksorter.c',
|
||||
'gtksortlistmodel.c',
|
||||
'gtkspinbutton.c',
|
||||
'gtkspinner.c',
|
||||
@ -592,6 +593,7 @@ gtk_public_headers = files([
|
||||
'gtksizerequest.h',
|
||||
'gtkslicelistmodel.h',
|
||||
'gtksnapshot.h',
|
||||
'gtksorter.h',
|
||||
'gtksortlistmodel.h',
|
||||
'gtkspinbutton.h',
|
||||
'gtkspinner.h',
|
||||
|
Loading…
Reference in New Issue
Block a user