Add GtkFilter
This commit is contained in:
@@ -44,6 +44,7 @@
|
||||
|
||||
<chapter id="Lists">
|
||||
<title>GListModel support</title>
|
||||
<xi:include href="xml/gtkfilter.xml" />
|
||||
<xi:include href="xml/gtkfilterlistmodel.xml" />
|
||||
<xi:include href="xml/gtkflattenlistmodel.xml" />
|
||||
<xi:include href="xml/gtkmaplistmodel.xml" />
|
||||
|
||||
@@ -1369,6 +1369,25 @@ GTK_DIRECTORY_LIST_GET_CLASS
|
||||
gtk_directory_list_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkfilter</FILE>
|
||||
<TITLE>GtkFilter</TITLE>
|
||||
GtkFilter
|
||||
gtk_filter_match
|
||||
gtk_filter_get_strictness
|
||||
<SUBSECTION>
|
||||
gtk_filter_changed
|
||||
<SUBSECTION Standard>
|
||||
GTK_FILTER
|
||||
GTK_IS_FILTER
|
||||
GTK_TYPE_FILTER
|
||||
GTK_FILTER_CLASS
|
||||
GTK_IS_FILTER_CLASS
|
||||
GTK_FILTER_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
gtk_filter_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkfilterlistmodel</FILE>
|
||||
<TITLE>GtkFilterListModel</TITLE>
|
||||
|
||||
@@ -115,6 +115,7 @@
|
||||
#include <gtk/gtkfilechoosernative.h>
|
||||
#include <gtk/gtkfilechooserwidget.h>
|
||||
#include <gtk/gtkfilefilter.h>
|
||||
#include <gtk/gtkfilter.h>
|
||||
#include <gtk/gtkfilterlistmodel.h>
|
||||
#include <gtk/gtkflattenlistmodel.h>
|
||||
#include <gtk/gtkflowbox.h>
|
||||
|
||||
179
gtk/gtkfilter.c
Normal file
179
gtk/gtkfilter.c
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
* 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: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkfilter.h"
|
||||
|
||||
#include "gtkintl.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
|
||||
/**
|
||||
* SECTION:gtkfilter
|
||||
* @Short_description: Filtering items in GTK
|
||||
* @Title: GtkFilter
|
||||
* @See_also: #GtkFilerListModel
|
||||
*
|
||||
* #GtkFilter is the way to describe filters to be used in #GtkFilterListModel.
|
||||
*
|
||||
* The model will use a filter to determine if it should filter items or not
|
||||
* by calling gtk_filter_match() for each item and only keeping the ones
|
||||
* visible that the function returns %TRUE for.
|
||||
*
|
||||
* Filters may change what items they match through their lifetime. In that
|
||||
* case they can call gtk_filter_changed() which will emit the GtkFilter:changed
|
||||
* signal to notify that previous filter results are no longer valid and that
|
||||
* items should be checked via gtk_filter_match() again.
|
||||
*
|
||||
* GTK provides various premade filter implementations for common filtering
|
||||
* operations. These filters often include properties that can be linked to
|
||||
* various widgets to easily allow searches.
|
||||
*
|
||||
* However, in particular for large lists or complex search methods, it is
|
||||
* also possible to subclass #GtkFilter and provide one's own filter.
|
||||
*/
|
||||
|
||||
enum {
|
||||
CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkFilter, gtk_filter, G_TYPE_OBJECT)
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static gboolean
|
||||
gtk_filter_default_match (GtkFilter *self,
|
||||
gpointer item)
|
||||
{
|
||||
g_critical ("Filter of type '%s' does not implement GtkFilter::match", G_OBJECT_TYPE_NAME (self));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GtkFilterMatch
|
||||
gtk_filter_default_get_strictness (GtkFilter *self)
|
||||
{
|
||||
return GTK_FILTER_MATCH_SOME;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_filter_class_init (GtkFilterClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||||
|
||||
class->match = gtk_filter_default_match;
|
||||
class->get_strictness = gtk_filter_default_get_strictness;
|
||||
|
||||
/**
|
||||
* GtkFilter:changed:
|
||||
* @self: The #GtkFilter
|
||||
* @change: how the filter changed
|
||||
*
|
||||
* This signal is emitted whenever the filter changed. Users of the filter
|
||||
* should then check items again via gtk_filter_match().
|
||||
*
|
||||
* Depending on the @change variable, not all items need to be changed, but
|
||||
* only some. Refer to the #GtkFilterChange documentation for details on that.
|
||||
*/
|
||||
signals[CHANGED] =
|
||||
g_signal_new (I_("changed"),
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__ENUM,
|
||||
G_TYPE_NONE, 1,
|
||||
GTK_TYPE_FILTER_CHANGE);
|
||||
g_signal_set_va_marshaller (signals[CHANGED],
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
g_cclosure_marshal_VOID__ENUMv);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_filter_init (GtkFilter *self)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_filter_match:
|
||||
* @self: a #GtkFilter
|
||||
* @item: (type GObject) (transfer none): The item to check
|
||||
*
|
||||
* Checks if the given @item is matched by the filter or not.
|
||||
*
|
||||
* Returns: %TRUE if the filter matches the item and a filter model should
|
||||
* keep it, %FALSE if not.
|
||||
*/
|
||||
gboolean
|
||||
gtk_filter_match (GtkFilter *self,
|
||||
gpointer item)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_FILTER (self), FALSE);
|
||||
g_return_val_if_fail (item != NULL, FALSE);
|
||||
|
||||
return GTK_FILTER_GET_CLASS (self)->match (self, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_filter_get_strictness:
|
||||
* @self: a #GtkFilter
|
||||
*
|
||||
* Gets the known strictness of @filters. If the strictness is not known,
|
||||
* %GTK_FILTER_MATCH_SOME is returned.
|
||||
*
|
||||
* This value may change after emission of the GtkFilter:changed signal.
|
||||
*
|
||||
* This function is meant purely for optimization purposes, filters can
|
||||
* choose to omit implementing it, but #GtkFilterListModel uses it.
|
||||
*
|
||||
* Returns: the strictness of @self
|
||||
**/
|
||||
GtkFilterMatch
|
||||
gtk_filter_get_strictness (GtkFilter *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_FILTER (self), GTK_FILTER_MATCH_SOME);
|
||||
|
||||
return GTK_FILTER_GET_CLASS (self)->get_strictness (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_filter_changed:
|
||||
* @self: a #GtkFilter
|
||||
* @change: How the filter changed
|
||||
*
|
||||
* Emits the GtkFilter:changed signal to notify all users of the filter that
|
||||
* the filter changed. Users of the filter should then check items again via
|
||||
* gtk_filter_match().
|
||||
*
|
||||
* Depending on the @change variable, not all items need to be changed, but
|
||||
* only some. Refer to the #GtkFilterChange documentation for details on that.
|
||||
*
|
||||
* This function is intended for implementors of #GtkFilter subclasses and
|
||||
* should not be called from other functions.
|
||||
*/
|
||||
void
|
||||
gtk_filter_changed (GtkFilter *self,
|
||||
GtkFilterChange change)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_FILTER (self));
|
||||
|
||||
g_signal_emit (self, signals[CHANGED], 0, change);
|
||||
}
|
||||
|
||||
129
gtk/gtkfilter.h
Normal file
129
gtk/gtkfilter.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
* 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: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __GTK_FILTER_H__
|
||||
#define __GTK_FILTER_H__
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* GtkFilterMatch:
|
||||
* @GTK_FILTER_MATCH_SOME: The filter matches some items,
|
||||
* gtk_filter_match() may return %TRUE or %FALSE
|
||||
* @GTK_FILTER_MATCH_NONE: The filter does not match any item,
|
||||
* gtk_filter_match() will always return %FALSE.
|
||||
* @GTK_FILTER_MATCH_ALL: The filter matches all items,
|
||||
* gtk_filter_match() will alays return %TRUE.
|
||||
*
|
||||
* Describes the known strictness of a filter.
|
||||
*
|
||||
* Note that for filters where the strictness is not known,
|
||||
* %@GTK_FILTER_MATCH_SOME is always an acceptable value,
|
||||
* even if a filter does match all or no items.
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_FILTER_MATCH_SOME = 0,
|
||||
GTK_FILTER_MATCH_NONE,
|
||||
GTK_FILTER_MATCH_ALL
|
||||
} GtkFilterMatch;
|
||||
|
||||
/**
|
||||
* GtkFilterChange:
|
||||
* @GTK_FILTER_CHANGE_DIFFERENT: The filter change cannot be
|
||||
* described with any of the other enumeration values.
|
||||
* @GTK_FILTER_CHANGE_MATCH_ALL: The filter now matches every
|
||||
* item: gtk_filter_get_strictness() will now return
|
||||
* %GTK_FILTER_MATCH_ALL
|
||||
* @GTK_FILTER_CHANGE_LESS_STRICT: The filter is less strict than
|
||||
* it was before: All items that it used to return %TRUE for
|
||||
* still return %TRUE, others now may, too.
|
||||
* @GTK_FILTER_CHANGE_MORE_STRICT: The filter is more strict than
|
||||
* it was before: All items that it used to return %FALSE for
|
||||
* still return %FALSE, others now may, too.
|
||||
* @GTK_FILTER_CHANGE_MATCH_NONE: The filter now matches no item:
|
||||
* gtk_filter_get_strictness() will now return
|
||||
* %GTK_FILTER_MATCH_NONE
|
||||
*
|
||||
* Describes changes in a filter in more detail and allows objects
|
||||
* using the filter to optimize refiltering items.
|
||||
*
|
||||
* If you are writing an implementation and are not sure which
|
||||
* value to pass, @GTK_FILTER_CHANGE_DIFFERENT is always a correct
|
||||
* choice.
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_FILTER_CHANGE_DIFFERENT = 0,
|
||||
GTK_FILTER_CHANGE_MATCH_ALL,
|
||||
GTK_FILTER_CHANGE_LESS_STRICT,
|
||||
GTK_FILTER_CHANGE_MORE_STRICT,
|
||||
GTK_FILTER_CHANGE_MATCH_NONE
|
||||
} GtkFilterChange;
|
||||
|
||||
#define GTK_TYPE_FILTER (gtk_filter_get_type ())
|
||||
|
||||
/**
|
||||
* GtkFilter:
|
||||
*
|
||||
* The object describing a filter.
|
||||
*/
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_DERIVABLE_TYPE (GtkFilter, gtk_filter, GTK, FILTER, GObject)
|
||||
|
||||
struct _GtkFilterClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
gboolean (* match) (GtkFilter *self,
|
||||
gpointer item);
|
||||
|
||||
/* optional */
|
||||
GtkFilterMatch (* get_strictness) (GtkFilter *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
|
||||
gboolean gtk_filter_match (GtkFilter *filter,
|
||||
gpointer item);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkFilterMatch gtk_filter_get_strictness (GtkFilter *filter);
|
||||
|
||||
/* for filter implementations */
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_filter_changed (GtkFilter *filter,
|
||||
GtkFilterChange change);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_FILTER_H__ */
|
||||
@@ -237,6 +237,7 @@ gtk_public_sources = files([
|
||||
'gtkfilechoosernative.c',
|
||||
'gtkfilechooserwidget.c',
|
||||
'gtkfilefilter.c',
|
||||
'gtkfilter.c',
|
||||
'gtkfilterlistmodel.c',
|
||||
'gtkfixed.c',
|
||||
'gtkfixedlayout.c',
|
||||
@@ -504,6 +505,7 @@ gtk_public_headers = files([
|
||||
'gtkfilechoosernative.h',
|
||||
'gtkfilechooserwidget.h',
|
||||
'gtkfilefilter.h',
|
||||
'gtkfilter.h',
|
||||
'gtkfilterlistmodel.h',
|
||||
'gtkfixed.h',
|
||||
'gtkfixedlayout.h',
|
||||
|
||||
Reference in New Issue
Block a user