Drop GtkCoverFlow for now

There is no agreement that a coverflow widget is
appropriate for GTK 4.

It would be ok as a demo if it could live in gtk-demo,
but that requires us to make GtkListBase public first.
The demo is also somewhat rough and needs more work
to look plausible.

Drop GtkCoverFlow and the related demo for now.
This commit is contained in:
Matthias Clasen 2020-05-31 13:11:35 -04:00
parent 93353888ca
commit 73fdb8f7b0
7 changed files with 0 additions and 976 deletions

View File

@ -218,7 +218,6 @@
<file>infobar.c</file>
<file>links.c</file>
<file>listbox.c</file>
<file>listview_applauncher.c</file>
<file>listview_colors.c</file>
<file>listview_clocks.c</file>
<file>listview_filebrowser.c</file>

View File

@ -1,199 +0,0 @@
/* Lists/Application launcher
*
* This demo uses the GtkCoverFlow widget as a fancy application launcher.
*
* It is also a very small introduction to listviews.
*/
#include <gtk/gtk.h>
/* This is the function that creates the #GListModel that we need.
* GTK list widgets need a #GListModel to display, as models support change
* notifications.
* Unfortunately various older APIs do not provide list models, so we create
* our own.
*/
static GListModel *
create_application_list (void)
{
GListStore *store;
GList *apps, *l;
/* We use a #GListStore here, which is a simple array-like list implementation
* for manual management.
* List models need to know what type of data they provide, so we need to
* provide the type here. As we want to do a list of applications, #GAppInfo
* is the object we provide.
*/
store = g_list_store_new (G_TYPE_APP_INFO);
apps = g_app_info_get_all ();
for (l = apps; l; l = l->next)
{
g_list_store_append (store, l->data);
}
g_list_free_full (apps, g_object_unref);
return G_LIST_MODEL (store);
}
/* This is the function we use for setting up new listitems to display.
* We add just a #GtkImage here to display the application's icon as this is just
* a simple demo.
*/
static void
setup_listitem_cb (GtkListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *image;
image = gtk_image_new ();
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
gtk_list_item_set_child (list_item, image);
}
/* Here we need to prepare the listitem for displaying its item. We get the
* listitem already set up from the previous function, so we can reuse the
* #GtkImage widget we set up above.
* We get the item - which we know is a #GAppInfo because it comes out of
* the model we set up above, grab its icon and display it.
*/
static void
bind_listitem_cb (GtkListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *image;
GAppInfo *app_info;
image = gtk_list_item_get_child (list_item);
app_info = gtk_list_item_get_item (list_item);
gtk_image_set_from_gicon (GTK_IMAGE (image), g_app_info_get_icon (app_info));
}
/* In more complex code, we would also need functions to unbind and teardown
* the listitem, but this is simple code, so the default implementations are
* enough. If we had connected signals, this step would have been necessary.
*
* The #GtkSignalListItemFactory documentation contains more information about
* this step.
*/
/* This function is called whenever an item in the list is activated. This is
* the simple way to allow reacting to the Enter key or double-clicking on a
* listitem.
* Of course, it is possible to use far more complex interactions by turning
* off activation and adding buttons or other widgets in the setup function
* above, but this is a simple demo, so we'll use the simple way.
*/
static void
activate_cb (GtkCoverFlow *coverflow,
guint position,
gpointer unused)
{
GAppInfo *app_info;
GdkAppLaunchContext *context;
GError *error = NULL;
app_info = g_list_model_get_item (gtk_cover_flow_get_model (coverflow), position);
/* Prepare the context for launching the application and launch it. This
* code is explained in detail in the documentation for #GdkAppLaunchContext
* and #GAppInfo.
*/
context = gdk_display_get_app_launch_context (gtk_widget_get_display (GTK_WIDGET (coverflow)));
if (!g_app_info_launch (app_info,
NULL,
G_APP_LAUNCH_CONTEXT (context),
&error))
{
GtkWidget *dialog;
/* And because error handling is important, even a simple demo has it:
* We display an error dialog that something went wrong.
*/
dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (coverflow))),
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Could not launch %s", g_app_info_get_display_name (app_info));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error->message);
g_clear_error (&error);
gtk_widget_show (dialog);
}
g_object_unref (context);
g_object_unref (app_info);
}
static GtkWidget *window = NULL;
GtkWidget *
do_listview_applauncher (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkWidget *coverflow, *sw;;
GListModel *model;
GtkListItemFactory *factory;
/* Create a window and set a few defaults */
window = gtk_window_new ();
gtk_window_set_default_size (GTK_WINDOW (window), 640, 320);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Application Launcher");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
/* The #GtkListitemFactory is what is used to create #GtkListItems
* to display the data from the model. So it is absolutely necessary
* to create one.
* We will use a #GtkSignalListItemFactory because it is the simplest
* one to use. Different ones are available for different use cases.
* The most powerful one is #GtkBuilderListItemFactory which uses
* #GtkBuilder .ui files, so it requires little code.
*/
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_listitem_cb), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_listitem_cb), NULL);
/* Create the list widget here: We use a coverflow widget because it's
* the coolest one. We could just as well use other list widgets such
* as a #GtkListView or a #GtkGridView and the code would look very
* similar.
*/
coverflow = gtk_cover_flow_new_with_factory (factory);
/* We connect the activate signal here. It's the function we defined
* above for launching the selected application.
*/
g_signal_connect (coverflow, "activate", G_CALLBACK (activate_cb), NULL);
/* And of course we need to set the data model. Here we call the function
* we wrote above that gives us the list of applications. Then we set
* it on the coverflow list widget.
* The coverflow will now take items from the model and use the factory
* to create as many listitems as it needs to show itself to the user.
*/
model = create_application_list ();
gtk_cover_flow_set_model (GTK_COVER_FLOW (coverflow), model);
g_object_unref (model);
/* List widgets should always be contained in a #GtkScrolledWindow,
* because otherwise they might get too large or they might not
* be scrollable.
*/
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_window_set_child (GTK_WINDOW (window), sw);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), coverflow);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@ -42,7 +42,6 @@ demos = files([
'listbox.c',
'flowbox.c',
'list_store.c',
'listview_applauncher.c',
'listview_clocks.c',
'listview_colors.c',
'listview_filebrowser.c',

View File

@ -85,7 +85,6 @@
#include <gtk/gtkcomboboxtext.h>
#include <gtk/gtkconstraintlayout.h>
#include <gtk/gtkconstraint.h>
#include <gtk/gtkcoverflow.h>
#include <gtk/gtkcssprovider.h>
#include <gtk/gtkcustomlayout.h>
#include <gtk/gtkcustomsorter.h>

View File

@ -1,704 +0,0 @@
/*
* Copyright © 2018 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 "gtkcoverflow.h"
#include "gtkintl.h"
#include "gtklistbaseprivate.h"
#include "gtkmain.h"
#include "gtkorientable.h"
#include "gtkprivate.h"
#include "gtkrbtreeprivate.h"
#include "gtkwidgetprivate.h"
/* Extra items to display at most above + below the central item */
#define GTK_COVER_FLOW_DISPLAY_ITEMS 5
/* Number of extra space we leave around the covers */
#define GTK_COVER_FLOW_SCALE_ALONG 3
#define GTK_COVER_FLOW_SCALE_ACROSS 2
/**
* SECTION:gtkcoverflow
* @title: GtkCoverFlow
* @short_description: A coverflow list widget
* @see_also: #GListModel
*
* GtkCoverFlow is a widget to present a coverflow list
*/
struct _GtkCoverFlow
{
GtkListBase parent_instance;
int size_across;
int size_along;
};
struct _GtkCoverFlowClass
{
GtkListBaseClass parent_class;
};
enum
{
PROP_0,
PROP_FACTORY,
PROP_MODEL,
N_PROPS
};
enum {
ACTIVATE,
LAST_SIGNAL
};
G_DEFINE_TYPE (GtkCoverFlow, gtk_cover_flow, GTK_TYPE_LIST_BASE)
static GParamSpec *properties[N_PROPS] = { NULL, };
static guint signals[LAST_SIGNAL] = { 0 };
static gboolean
gtk_cover_flow_get_allocation_along (GtkListBase *base,
guint pos,
int *offset,
int *size)
{
GtkCoverFlow *self = GTK_COVER_FLOW (base);
if (offset)
*offset = pos * self->size_along;
if (size)
*size = self->size_along;
return TRUE;
}
static gboolean
gtk_cover_flow_get_allocation_across (GtkListBase *base,
guint pos,
int *offset,
int *size)
{
GtkCoverFlow *self = GTK_COVER_FLOW (base);
if (offset)
*offset = pos * self->size_across;
if (size)
*size = self->size_across;
return TRUE;
}
static guint
gtk_cover_flow_move_focus_along (GtkListBase *base,
guint pos,
int steps)
{
if (steps < 0)
return pos - MIN (pos, -steps);
else
{
pos += MIN (gtk_list_base_get_n_items (base) - pos - 1, steps);
}
return pos;
}
static guint
gtk_cover_flow_move_focus_across (GtkListBase *base,
guint pos,
int steps)
{
return pos;
}
static gboolean
gtk_cover_flow_get_position_from_allocation (GtkListBase *base,
int across,
int along,
guint *pos,
cairo_rectangle_int_t *area)
{
GtkCoverFlow *self = GTK_COVER_FLOW (base);
if (across >= self->size_across ||
along >= self->size_along * gtk_list_base_get_n_items (base))
return FALSE;
*pos = along / self->size_along;
if (area)
{
area->x = 0;
area->width = self->size_across;
area->y = *pos * self->size_along;
area->height = self->size_along;
}
return TRUE;
}
static void
gtk_cover_flow_measure_children (GtkCoverFlow *self,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural)
{
GtkListItemManagerItem *item;
int min, nat, child_min, child_nat;
min = 0;
nat = 0;
for (item = gtk_list_item_manager_get_first (gtk_list_base_get_manager (GTK_LIST_BASE (self)));
item != NULL;
item = gtk_rb_tree_node_get_next (item))
{
/* ignore unavailable items */
if (item->widget == NULL)
continue;
gtk_widget_measure (item->widget,
orientation, for_size,
&child_min, &child_nat, NULL, NULL);
min = MAX (min, child_min);
nat = MAX (nat, child_nat);
}
*minimum = min;
*natural = nat;
}
static void
gtk_cover_flow_measure_across (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural)
{
GtkCoverFlow *self = GTK_COVER_FLOW (widget);
if (for_size > 0)
for_size /= GTK_COVER_FLOW_SCALE_ALONG;
gtk_cover_flow_measure_children (self, orientation, for_size, minimum, natural);
*minimum *= GTK_COVER_FLOW_SCALE_ACROSS;
*natural *= GTK_COVER_FLOW_SCALE_ACROSS;
}
static void
gtk_cover_flow_measure_along (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural)
{
GtkCoverFlow *self = GTK_COVER_FLOW (widget);
if (for_size > 0)
for_size /= GTK_COVER_FLOW_SCALE_ACROSS;
gtk_cover_flow_measure_children (self, orientation, for_size, minimum, natural);
*minimum *= GTK_COVER_FLOW_SCALE_ALONG;
*natural *= GTK_COVER_FLOW_SCALE_ALONG;
}
static void
gtk_cover_flow_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkCoverFlow *self = GTK_COVER_FLOW (widget);
if (orientation == gtk_list_base_get_orientation (GTK_LIST_BASE (self)))
gtk_cover_flow_measure_along (widget, orientation, for_size, minimum, natural);
else
gtk_cover_flow_measure_across (widget, orientation, for_size, minimum, natural);
}
static GskTransform *
transform_translate_oriented (GskTransform *transform,
GtkOrientation orientation,
GtkTextDirection dir,
float across,
float along)
{
if (orientation == GTK_ORIENTATION_VERTICAL)
return gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (across, along));
else if (dir == GTK_TEXT_DIR_LTR)
return gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (along, across));
else
return gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (-along, across));
}
static void
gtk_cover_flow_size_allocate_child (GtkWidget *child,
GtkOrientation orientation,
GtkTextDirection dir,
GskTransform *transform,
int width,
int height)
{
if (orientation == GTK_ORIENTATION_VERTICAL)
{
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (-width / 2, -height / 2));
gtk_widget_allocate (child, width, height, -1, transform);
}
else
{
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (-height / 2, -width / 2));
gtk_widget_allocate (child, height, width, -1, transform);
}
}
static void
gtk_cover_flow_size_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkCoverFlow *self = GTK_COVER_FLOW (widget);
GtkOrientation orientation, opposite_orientation;
GtkTextDirection dir;
GtkListItemManagerItem *item;
GtkListItemManager *manager;
guint i, pos;
int x, y, along, across;
manager = gtk_list_base_get_manager (GTK_LIST_BASE (self));
orientation = gtk_list_base_get_orientation (GTK_LIST_BASE (self));
opposite_orientation = OPPOSITE_ORIENTATION (orientation);
/* step 0: exit early if list is empty */
if (gtk_list_item_manager_get_root (manager) == NULL)
return;
/* step 1: determine size of children */
along = orientation == GTK_ORIENTATION_HORIZONTAL ? width : height;
across = opposite_orientation == GTK_ORIENTATION_HORIZONTAL ? width : height;
self->size_along = along / GTK_COVER_FLOW_SCALE_ALONG;
self->size_across = across / GTK_COVER_FLOW_SCALE_ACROSS;
/* step 2: update the adjustments */
gtk_list_base_update_adjustments (GTK_LIST_BASE (self),
self->size_across,
self->size_along * gtk_list_base_get_n_items (GTK_LIST_BASE (self)),
self->size_across,
self->size_along,
&x, &y);
pos = gtk_list_base_get_anchor (GTK_LIST_BASE (self));
/* step 4: actually allocate the widgets */
dir = _gtk_widget_get_direction (widget);
i = 0;
for (item = gtk_list_item_manager_get_first (manager);
item != NULL;
item = gtk_rb_tree_node_get_next (item))
{
if (item->widget)
{
/* start at the center */
GskTransform *transform = transform_translate_oriented (NULL, orientation, dir, across / 2, along / 2);
if (i == pos)
{
/* nothing to do, we're already centered */
}
else if (MAX (pos, i) - MIN (pos, i) < GTK_COVER_FLOW_DISPLAY_ITEMS) /* ABS() doesn't work with guint */
{
int diff = i - pos;
transform = gsk_transform_perspective (transform, MAX (width, height) * 2);
transform = transform_translate_oriented (transform,
orientation, dir,
0,
diff * self->size_along / 4);
transform = transform_translate_oriented (transform,
orientation, dir,
0,
(diff < 0 ? -1 : 1) * self->size_along / 2);
if (orientation == GTK_ORIENTATION_VERTICAL)
transform = gsk_transform_rotate_3d (transform,
diff > 0 ? 60 : -60,
graphene_vec3_x_axis ());
else
transform = gsk_transform_rotate_3d (transform,
diff < 0 ? 60 : -60,
graphene_vec3_y_axis ());
transform = transform_translate_oriented (transform,
orientation, dir,
0,
(diff < 0 ? 1 : -1) * self->size_along / 4);
}
else
{
transform = transform_translate_oriented (transform,
orientation, dir,
- 2 * self->size_across,
- 2 * self->size_along);
}
gtk_cover_flow_size_allocate_child (item->widget,
orientation, dir,
transform,
self->size_across,
self->size_along);
}
i += item->n_items;
}
}
static void
gtk_cover_flow_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GtkListBase *base = GTK_LIST_BASE (object);
switch (property_id)
{
case PROP_FACTORY:
g_value_set_object (value, gtk_list_item_manager_get_factory (gtk_list_base_get_manager (base)));
break;
case PROP_MODEL:
g_value_set_object (value, gtk_list_base_get_model (base));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gtk_cover_flow_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkWidget *child;
GtkListItemManagerItem *item;
item = gtk_list_item_manager_get_nth (gtk_list_base_get_manager (GTK_LIST_BASE (widget)),
gtk_list_base_get_anchor (GTK_LIST_BASE (widget)),
NULL);
if (item == NULL || item->widget == NULL)
{
GTK_WIDGET_CLASS (gtk_cover_flow_parent_class)->snapshot (widget, snapshot);
return;
}
for (child = _gtk_widget_get_first_child (widget);
child != item->widget;
child = _gtk_widget_get_next_sibling (child))
gtk_widget_snapshot_child (widget, child, snapshot);
for (child = _gtk_widget_get_last_child (widget);
child != item->widget;
child = _gtk_widget_get_prev_sibling (child))
gtk_widget_snapshot_child (widget, child, snapshot);
gtk_widget_snapshot_child (widget, item->widget, snapshot);
}
static void
gtk_cover_flow_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GtkCoverFlow *self = GTK_COVER_FLOW (object);
switch (property_id)
{
case PROP_FACTORY:
gtk_cover_flow_set_factory (self, g_value_get_object (value));
break;
case PROP_MODEL:
gtk_cover_flow_set_model (self, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gtk_cover_flow_activate_item (GtkWidget *widget,
const char *action_name,
GVariant *parameter)
{
GtkCoverFlow *self = GTK_COVER_FLOW (widget);
guint pos;
if (!g_variant_check_format_string (parameter, "u", FALSE))
return;
g_variant_get (parameter, "u", &pos);
if (pos >= gtk_list_base_get_n_items (GTK_LIST_BASE (self)))
return;
g_signal_emit (widget, signals[ACTIVATE], 0, pos);
}
static void
gtk_cover_flow_class_init (GtkCoverFlowClass *klass)
{
GtkListBaseClass *list_base_class = GTK_LIST_BASE_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
list_base_class->list_item_name = "cover";
list_base_class->list_item_size = sizeof (GtkListItemManagerItem);
list_base_class->list_item_augment_size = sizeof (GtkListItemManagerItemAugment);
list_base_class->list_item_augment_func = gtk_list_item_manager_augment_node;
list_base_class->get_allocation_along = gtk_cover_flow_get_allocation_along;
list_base_class->get_allocation_across = gtk_cover_flow_get_allocation_across;
list_base_class->get_position_from_allocation = gtk_cover_flow_get_position_from_allocation;
list_base_class->move_focus_along = gtk_cover_flow_move_focus_along;
list_base_class->move_focus_across = gtk_cover_flow_move_focus_across;
widget_class->measure = gtk_cover_flow_measure;
widget_class->size_allocate = gtk_cover_flow_size_allocate;
widget_class->snapshot = gtk_cover_flow_snapshot;
gobject_class->get_property = gtk_cover_flow_get_property;
gobject_class->set_property = gtk_cover_flow_set_property;
/**
* GtkCoverFlow:factory:
*
* Factory for populating list items
*/
properties[PROP_FACTORY] =
g_param_spec_object ("factory",
P_("Factory"),
P_("Factory for populating list items"),
GTK_TYPE_LIST_ITEM_FACTORY,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GtkCoverFlow:model:
*
* Model for the items displayed
*/
properties[PROP_MODEL] =
g_param_spec_object ("model",
P_("Model"),
P_("Model for the items displayed"),
G_TYPE_LIST_MODEL,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
/**
* GtkCoverFlow::activate:
* @self: The #GtkCoverFlow
* @position: position of item to activate
*
* The ::activate signal is emitted when an item has been activated by the user,
* usually via activating the GtkCoverFlow|list.activate-item action.
*
* This allows for a convenient way to handle activation in a listview.
* See gtk_list_item_set_activatable() for details on how to use this signal.
*/
signals[ACTIVATE] =
g_signal_new (I_("activate"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__UINT,
G_TYPE_NONE, 1,
G_TYPE_UINT);
g_signal_set_va_marshaller (signals[ACTIVATE],
G_TYPE_FROM_CLASS (gobject_class),
g_cclosure_marshal_VOID__UINTv);
/**
* GtkCoverFlow|list.activate-item:
* @position: position of item to activate
*
* Activates the item given in @position by emitting the GtkCoverFlow::activate
* signal.
*/
gtk_widget_class_install_action (widget_class,
"list.activate-item",
"u",
gtk_cover_flow_activate_item);
gtk_widget_class_set_css_name (widget_class, I_("coverflow"));
}
static void
gtk_cover_flow_init (GtkCoverFlow *self)
{
gtk_list_base_set_anchor_max_widgets (GTK_LIST_BASE (self),
0,
GTK_COVER_FLOW_DISPLAY_ITEMS);
/* FIXME: this should overwrite the property default, but gobject properties... */
gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_HORIZONTAL);
}
/**
* gtk_cover_flow_new:
*
* Creates a new empty #GtkCoverFlow.
*
* You most likely want to call gtk_cover_flow_set_factory() to
* set up a way to map its items to widgets and gtk_cover_flow_set_model()
* to set a model to provide items next.
*
* Returns: a new #GtkCoverFlow
**/
GtkWidget *
gtk_cover_flow_new (void)
{
return g_object_new (GTK_TYPE_COVER_FLOW, NULL);
}
/**
* gtk_cover_flow_new_with_factory:
* @factory: (transfer full): The factory to populate items with
*
* Creates a new #GtkCoverFlow that uses the given @factory for
* mapping items to widgets.
*
* You most likely want to call gtk_cover_flow_set_model() to set
* a model next.
*
* The function takes ownership of the
* argument, so you can write code like
* ```
* cover_flow = gtk_cover_flow_new_with_factory (
* gtk_builder_list_item_factory_newfrom_resource ("/resource.ui"));
* ```
*
* Returns: a new #GtkCoverFlow using the given @factory
**/
GtkWidget *
gtk_cover_flow_new_with_factory (GtkListItemFactory *factory)
{
GtkWidget *result;
g_return_val_if_fail (GTK_IS_LIST_ITEM_FACTORY (factory), NULL);
result = g_object_new (GTK_TYPE_COVER_FLOW,
"factory", factory,
NULL);
g_object_unref (factory);
return result;
}
/**
* gtk_cover_flow_get_model:
* @self: a #GtkCoverFlow
*
* Gets the model that's currently used to read the items displayed.
*
* Returns: (nullable) (transfer none): The model in use
**/
GListModel *
gtk_cover_flow_get_model (GtkCoverFlow *self)
{
g_return_val_if_fail (GTK_IS_COVER_FLOW (self), NULL);
return gtk_list_base_get_model (GTK_LIST_BASE (self));
}
/**
* gtk_cover_flow_set_model:
* @self: a #GtkCoverFlow
* @model: (allow-none) (transfer none): the model to use or %NULL for none
*
* Sets the #GListModel to use.
*
* If the @model is a #GtkSelectionModel, it is used for managing the selection.
* Otherwise, @self creates a #GtkSingleSelection for the selection.
**/
void
gtk_cover_flow_set_model (GtkCoverFlow *self,
GListModel *model)
{
g_return_if_fail (GTK_IS_COVER_FLOW (self));
g_return_if_fail (model == NULL || G_IS_LIST_MODEL (model));
if (!gtk_list_base_set_model (GTK_LIST_BASE (self), model))
return;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]);
}
/**
* gtk_cover_flow_get_factory:
* @self: a #GtkCoverFlow
*
* Gets the factory that's currently used to populate list items.
*
* Returns: (nullable) (transfer none): The factory in use
**/
GtkListItemFactory *
gtk_cover_flow_get_factory (GtkCoverFlow *self)
{
g_return_val_if_fail (GTK_IS_COVER_FLOW (self), NULL);
return gtk_list_item_manager_get_factory (gtk_list_base_get_manager (GTK_LIST_BASE (self)));
}
/**
* gtk_cover_flow_set_factory:
* @self: a #GtkCoverFlow
* @factory: (allow-none) (transfer none): the factory to use or %NULL for none
*
* Sets the #GtkListItemFactory to use for populating list items.
**/
void
gtk_cover_flow_set_factory (GtkCoverFlow *self,
GtkListItemFactory *factory)
{
GtkListItemManager *manager;
g_return_if_fail (GTK_IS_COVER_FLOW (self));
g_return_if_fail (factory == NULL || GTK_LIST_ITEM_FACTORY (factory));
manager = gtk_list_base_get_manager (GTK_LIST_BASE (self));
if (factory == gtk_list_item_manager_get_factory (manager))
return;
gtk_list_item_manager_set_factory (manager, factory);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FACTORY]);
}

View File

@ -1,68 +0,0 @@
/*
* Copyright © 2018 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_COVER_FLOW_H__
#define __GTK_COVER_FLOW_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtklistbase.h>
G_BEGIN_DECLS
#define GTK_TYPE_COVER_FLOW (gtk_cover_flow_get_type ())
#define GTK_COVER_FLOW(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_COVER_FLOW, GtkCoverFlow))
#define GTK_COVER_FLOW_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTK_TYPE_COVER_FLOW, GtkCoverFlowClass))
#define GTK_IS_COVER_FLOW(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_COVER_FLOW))
#define GTK_IS_COVER_FLOW_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTK_TYPE_COVER_FLOW))
#define GTK_COVER_FLOW_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_COVER_FLOW, GtkCoverFlowClass))
/**
* GtkCoverFlow:
*
* GtkCoverFlow is the simple list implementation for GTK's list widgets.
*/
typedef struct _GtkCoverFlow GtkCoverFlow;
typedef struct _GtkCoverFlowClass GtkCoverFlowClass;
GDK_AVAILABLE_IN_ALL
GType gtk_cover_flow_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkWidget * gtk_cover_flow_new (void);
GDK_AVAILABLE_IN_ALL
GtkWidget * gtk_cover_flow_new_with_factory (GtkListItemFactory *factory);
GDK_AVAILABLE_IN_ALL
GListModel * gtk_cover_flow_get_model (GtkCoverFlow *self);
GDK_AVAILABLE_IN_ALL
void gtk_cover_flow_set_model (GtkCoverFlow *self,
GListModel *model);
GDK_AVAILABLE_IN_ALL
void gtk_cover_flow_set_factory (GtkCoverFlow *self,
GtkListItemFactory *factory);
GDK_AVAILABLE_IN_ALL
GtkListItemFactory *
gtk_cover_flow_get_factory (GtkCoverFlow *self);
G_END_DECLS
#endif /* __GTK_COVER_FLOW_H__ */

View File

@ -206,7 +206,6 @@ gtk_public_sources = files([
'gtkconstraintguide.c',
'gtkconstraintlayout.c',
'gtkconstraint.c',
'gtkcoverflow.c',
'gtkcssprovider.c',
'gtkcustomfilter.c',
'gtkcustomlayout.c',
@ -486,7 +485,6 @@ gtk_public_headers = files([
'gtkconstraintguide.h',
'gtkconstraintlayout.h',
'gtkconstraint.h',
'gtkcoverflow.h',
'gtkcssprovider.h',
'gtkcustomfilter.h',
'gtkcustomlayout.h',