[gtk/wip/otte/listview: 94/112] wip: Add GtkCoverFlow
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/listview: 94/112] wip: Add GtkCoverFlow
- Date: Tue, 5 Nov 2019 23:11:32 +0000 (UTC)
commit 31fd8dc38b7fc0770511f927ddc6842309dc2ae6
Author: Benjamin Otte <otte redhat com>
Date: Sun Oct 27 08:03:03 2019 +0100
wip: Add GtkCoverFlow
The widget mostly works out of the box, but some tweaking may be
necessary (in particular in the theme) and the gtk-demo changes might
require removing before this is production-ready.
gtk/gtk.h | 1 +
gtk/gtkcoverflow.c | 704 +++++++++++++++++++++++++++++++
gtk/gtkcoverflow.h | 68 +++
gtk/gtklistbase.c | 9 +
gtk/gtklistbaseprivate.h | 1 +
gtk/meson.build | 2 +
gtk/theme/Adwaita/_common.scss | 6 +
gtk/theme/Adwaita/gtk-contained-dark.css | 50 +--
gtk/theme/Adwaita/gtk-contained.css | 6 +-
9 files changed, 821 insertions(+), 26 deletions(-)
---
diff --git a/gtk/gtk.h b/gtk/gtk.h
index 6e43644911..1ac3f3a767 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -87,6 +87,7 @@
#include <gtk/gtkconstraintlayout.h>
#include <gtk/gtkconstraint.h>
#include <gtk/gtkcontainer.h>
+#include <gtk/gtkcoverflow.h>
#include <gtk/gtkcssprovider.h>
#include <gtk/gtkcustomlayout.h>
#include <gtk/gtkdebug.h>
diff --git a/gtk/gtkcoverflow.c b/gtk/gtkcoverflow.c
new file mode 100644
index 0000000000..1e0915973e
--- /dev/null
+++ b/gtk/gtkcoverflow.c
@@ -0,0 +1,704 @@
+/*
+ * 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]);
+}
diff --git a/gtk/gtkcoverflow.h b/gtk/gtkcoverflow.h
new file mode 100644
index 0000000000..55253862bf
--- /dev/null
+++ b/gtk/gtkcoverflow.h
@@ -0,0 +1,68 @@
+/*
+ * 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__ */
diff --git a/gtk/gtklistbase.c b/gtk/gtklistbase.c
index 6867a7263d..bbdb45b74d 100644
--- a/gtk/gtklistbase.c
+++ b/gtk/gtklistbase.c
@@ -1326,6 +1326,15 @@ gtk_list_base_get_manager (GtkListBase *self)
return priv->item_manager;
}
+guint
+gtk_list_base_get_anchor (GtkListBase *self)
+{
+ GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
+
+ return gtk_list_item_tracker_get_position (priv->item_manager,
+ priv->anchor);
+}
+
/*
* gtk_list_base_set_anchor:
* @self: a #GtkListBase
diff --git a/gtk/gtklistbaseprivate.h b/gtk/gtklistbaseprivate.h
index fd4e8a2ea7..06757985d3 100644
--- a/gtk/gtklistbaseprivate.h
+++ b/gtk/gtklistbaseprivate.h
@@ -80,6 +80,7 @@ void gtk_list_base_update_adjustments (GtkListBase
int *across,
int *along);
+guint gtk_list_base_get_anchor (GtkListBase *self);
void gtk_list_base_set_anchor (GtkListBase *self,
guint anchor_pos,
double anchor_align_across,
diff --git a/gtk/meson.build b/gtk/meson.build
index de40b25d2c..87ecdf95ef 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -212,6 +212,7 @@ gtk_public_sources = files([
'gtkconstraintlayout.c',
'gtkconstraint.c',
'gtkcontainer.c',
+ 'gtkcoverflow.c',
'gtkcssprovider.c',
'gtkdialog.c',
'gtkdirectorylist.c',
@@ -487,6 +488,7 @@ gtk_public_headers = files([
'gtkconstraintlayout.h',
'gtkconstraint.h',
'gtkcontainer.h',
+ 'gtkcoverflow.h',
'gtkcssprovider.h',
'gtkcustomlayout.h',
'gtkdebug.h',
diff --git a/gtk/theme/Adwaita/_common.scss b/gtk/theme/Adwaita/_common.scss
index 655563aeb3..e686ccfd68 100644
--- a/gtk/theme/Adwaita/_common.scss
+++ b/gtk/theme/Adwaita/_common.scss
@@ -160,6 +160,12 @@ flowbox {
}
}
+coverflow cover {
+ color: $text_color;
+ background-color: $base_color;
+ border: 1px solid black;
+}
+
.content-view .tile {
margin: 2px;
background-color: if($variant=='light', transparent, black);
diff --git a/gtk/theme/Adwaita/gtk-contained-dark.css b/gtk/theme/Adwaita/gtk-contained-dark.css
index 9a276f64f6..d40fcb59f9 100644
--- a/gtk/theme/Adwaita/gtk-contained-dark.css
+++ b/gtk/theme/Adwaita/gtk-contained-dark.css
@@ -48,6 +48,8 @@ flowbox flowboxchild { padding: 3px; }
flowbox flowboxchild:selected { outline-offset: -2px; }
+coverflow cover { color: white; background-color: #2d2d2d; border: 1px solid black; }
+
.content-view .tile { margin: 2px; background-color: black; border-radius: 0; padding: 0; }
.content-view .tile:backdrop { background-color: #232323; }
@@ -82,7 +84,7 @@ assistant .sidebar label { padding: 6px 12px; }
assistant .sidebar label.highlight { background-color: #5a5a59; }
-.osd popover.background > arrow, .osd popover.background > contents, popover.background.touch-selection >
arrow, popover.background.touch-selection > contents, popover.background.magnifier > arrow,
popover.background.magnifier > contents, .app-notification, .app-notification.frame, .osd .scale-popup, .osd
{ color: #eeeeec; border: none; background-color: rgba(37, 37, 38, 0.7); background-clip: padding-box;
text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; }
+.osd popover.background > arrow, .osd popover.background > contents, popover.background.touch-selection >
arrow, popover.background.touch-selection > contents, popover.background.magnifier > arrow,
popover.background.magnifier > contents, .app-notification, .app-notification.frame, .osd .scale-popup, .osd
{ color: #eeeeec; border: none; background-color: rgba(38, 38, 38, 0.7); background-clip: padding-box;
text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; }
.osd popover.background > arrow:backdrop, .osd popover.background > contents:backdrop,
popover.background.touch-selection > arrow:backdrop, popover.background.touch-selection > contents:backdrop,
popover.background.magnifier > arrow:backdrop, popover.background.magnifier > contents:backdrop,
.app-notification:backdrop, .osd .scale-popup:backdrop, .osd:backdrop { text-shadow: none; -gtk-icon-shadow:
none; }
@@ -267,7 +269,7 @@ row:selected button.sidebar-button:not(:active):not(:checked):not(:hover):not(di
row:selected button.sidebar-button:not(:active):not(:checked):not(:hover):not(disabled):backdrop,
row:selected button.flat:not(:active):not(:checked):not(:hover):not(disabled):backdrop { color: #919190; }
-button.osd { min-width: 26px; min-height: 32px; color: #eeeeec; border-radius: 5px; color: #eeeeec;
border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(37, 37, 38,
0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none;
-gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); border: none; box-shadow: none; }
+button.osd { min-width: 26px; min-height: 32px; color: #eeeeec; border-radius: 5px; color: #eeeeec;
border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38,
0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none;
-gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); border: none; box-shadow: none; }
button.osd.image-button { min-width: 30px; }
@@ -279,9 +281,9 @@ button.osd:active, button.osd:checked { color: white; border-color: rgba(0, 0, 0
button.osd:disabled:backdrop, button.osd:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7);
background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box;
box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; border: none; }
-button.osd:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent;
background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow:
none; -gtk-icon-shadow: none; border: none; }
+button.osd:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent;
background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow:
none; -gtk-icon-shadow: none; border: none; }
-popover.background.touch-selection button, popover.background.magnifier button, .app-notification button,
.app-notification.frame button, .osd button { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7);
background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box;
box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color:
rgba(238, 238, 236, 0.3); }
+popover.background.touch-selection button, popover.background.magnifier button, .app-notification button,
.app-notification.frame button, .osd button { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7);
background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box;
box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color:
rgba(238, 238, 236, 0.3); }
popover.background.touch-selection button:hover, popover.background.magnifier button:hover,
.app-notification button:hover, .osd button:hover { color: white; border-color: rgba(0, 0, 0, 0.7);
background-color: transparent; background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box;
box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color:
rgba(238, 238, 236, 0.3); }
@@ -289,7 +291,7 @@ popover.background.touch-selection button:active:backdrop, popover.background.ma
popover.background.touch-selection button:disabled:backdrop, popover.background.magnifier
button:disabled:backdrop, .app-notification button:disabled:backdrop, popover.background.touch-selection
button:disabled, popover.background.magnifier button:disabled, .app-notification button:disabled, .osd
button:disabled:backdrop, .osd button:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7);
background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box;
box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
-popover.background.touch-selection button:backdrop, popover.background.magnifier button:backdrop,
.app-notification button:backdrop, .osd button:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7);
background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box;
box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
+popover.background.touch-selection button:backdrop, popover.background.magnifier button:backdrop,
.app-notification button:backdrop, .osd button:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7);
background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box;
box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
popover.background.touch-selection button.flat, popover.background.magnifier button.flat, .app-notification
button.flat, .osd button.flat { border-color: transparent; background-color: transparent; background-image:
none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; box-shadow:
none; text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; }
@@ -499,7 +501,7 @@ button:link > label:active, button:visited > label:active, *:link:active, button
*:selected button:link > label:active, *:selected button:visited > label:active, *:selected *:link:active,
*:selected button:active:link, *:selected button:active:visited { color: #d0ddec; }
-button:link > label:disabled, button:visited > label:disabled, button:link > label:disabled:backdrop,
button:visited > label:disabled:backdrop, *:link:disabled, button:disabled:link, button:disabled:visited,
*:link:disabled:backdrop, button:disabled:backdrop:link, button:disabled:backdrop:visited { color: rgba(140,
140, 141, 0.8); }
+button:link > label:disabled, button:visited > label:disabled, button:link > label:disabled:backdrop,
button:visited > label:disabled:backdrop, *:link:disabled, button:disabled:link, button:disabled:visited,
*:link:disabled:backdrop, button:disabled:backdrop:link, button:disabled:backdrop:visited { color: rgba(141,
141, 141, 0.8); }
button:link > label:backdrop:backdrop:hover, button:visited > label:backdrop:backdrop:hover, button:link >
label:backdrop:backdrop:hover:selected, button:visited > label:backdrop:backdrop:hover:selected, button:link
label:backdrop, button:visited > label:backdrop, *:link:backdrop:backdrop:hover,
button:backdrop:backdrop:hover:link, button:backdrop:backdrop:hover:visited,
*:link:backdrop:backdrop:hover:selected, button:backdrop:backdrop:hover:selected:link,
button:backdrop:backdrop:hover:selected:visited, .selection-mode .titlebar:not(headerbar)
.subtitle:backdrop:backdrop:hover:link, .selection-mode.titlebar:not(headerbar)
.subtitle:backdrop:backdrop:hover:link, .selection-mode headerbar .subtitle:backdrop:backdrop:hover:link,
headerbar.selection-mode .subtitle:backdrop:backdrop:hover:link, *:link:backdrop, button:backdrop:link,
button:backdrop:visited { color: #15539e; }
@@ -566,7 +568,7 @@ spinbutton.vertical button.up { border-bottom-style: none; border-bottom-left-ra
spinbutton.vertical button.down { border-top-style: none; border-top-left-radius: 0;
border-top-right-radius: 0; }
-.osd spinbutton.vertical button:first-child { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7);
background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box;
box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color:
rgba(238, 238, 236, 0.3); }
+.osd spinbutton.vertical button:first-child { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7);
background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box;
box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color:
rgba(238, 238, 236, 0.3); }
.osd spinbutton.vertical button:first-child:hover { color: white; border-color: rgba(0, 0, 0, 0.7);
background-color: transparent; background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box;
box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color:
rgba(238, 238, 236, 0.3); }
@@ -574,7 +576,7 @@ spinbutton.vertical button.down { border-top-style: none; border-top-left-radius
.osd spinbutton.vertical button:first-child:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7);
background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box;
box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
-.osd spinbutton.vertical button:first-child:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7);
background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box;
box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
+.osd spinbutton.vertical button:first-child:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7);
background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box;
box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
treeview spinbutton:not(.vertical) { min-height: 0; border-style: none; border-radius: 0; }
@@ -592,7 +594,7 @@ toolbar { padding: 4px 3px 3px 4px; }
.osd toolbar { background-color: transparent; }
-toolbar.osd { padding: 13px; border: none; border-radius: 5px; background-color: rgba(37, 37, 38, 0.7); }
+toolbar.osd { padding: 13px; border: none; border-radius: 5px; background-color: rgba(38, 38, 38, 0.7); }
toolbar.osd.left, toolbar.osd.right, toolbar.osd.top, toolbar.osd.bottom { border-radius: 0; }
@@ -615,7 +617,7 @@ searchbar > revealer > box { padding: 6px; border-width: 0 0 1px; }
.inline-toolbar:backdrop, .location-bar:backdrop, searchbar > revealer > box:backdrop { border-color:
#202020; background-color: #2e2e2e; box-shadow: none; transition: 200ms ease-out; }
/*************** Header bars * */
-.titlebar:not(headerbar), headerbar { padding: 0 6px; min-height: 46px; border-width: 0 0 1px; border-style:
solid; border-color: #070707; border-radius: 0; border-spacing: 6px; background: #1b1b1b linear-gradient(to
top, #252526, #2b2b2b); box-shadow: inset 0 1px rgba(238, 238, 236, 0.07); /* Darken switchbuttons for
headerbars. issue #1588 */ /* hide the close button separator */ }
+.titlebar:not(headerbar), headerbar { padding: 0 6px; min-height: 46px; border-width: 0 0 1px; border-style:
solid; border-color: #070707; border-radius: 0; border-spacing: 6px; background: #1b1b1b linear-gradient(to
top, #262626, #2b2b2b); box-shadow: inset 0 1px rgba(238, 238, 236, 0.07); /* Darken switchbuttons for
headerbars. issue #1588 */ /* hide the close button separator */ }
.titlebar:backdrop:not(headerbar), headerbar:backdrop { border-color: #202020; background-color: #353535;
background-image: none; box-shadow: inset 0 1px rgba(238, 238, 236, 0.07); transition: 200ms ease-out; }
@@ -1149,7 +1151,7 @@ switch:backdrop:disabled slider label, switch:backdrop:disabled slider { color:
.view.content-view.check:active:not(list), iconview.content-view.check:active:not(list), .content-view .tile
check:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent;
background-color: rgba(21, 83, 158, 0.95); border-radius: 5px; background-image: none; transition: 200ms;
box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
-.view.content-view.check:backdrop:not(list), iconview.content-view.check:backdrop:not(list), .content-view
.tile check:backdrop:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent;
background-color: rgba(89, 89, 90, 0.95); border-radius: 5px; background-image: none; transition: 200ms;
box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
+.view.content-view.check:backdrop:not(list), iconview.content-view.check:backdrop:not(list), .content-view
.tile check:backdrop:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent;
background-color: rgba(90, 90, 90, 0.95); border-radius: 5px; background-image: none; transition: 200ms;
box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
.view.content-view.check:checked:not(list), iconview.content-view.check:checked:not(list), .content-view
.tile check:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec;
background-color: rgba(21, 83, 158, 0.95); border-radius: 5px; background-image: none; transition: 200ms;
box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic');
-gtk-icon-shadow: none; }
@@ -1157,11 +1159,11 @@ switch:backdrop:disabled slider label, switch:backdrop:disabled slider { color:
.view.content-view.check:checked:active:not(list), iconview.content-view.check:checked:active:not(list),
.content-view .tile check:checked:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color:
#eeeeec; background-color: rgba(21, 83, 158, 0.95); border-radius: 5px; background-image: none; transition:
200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic');
-gtk-icon-shadow: none; }
-.view.content-view.check:backdrop:checked:not(list), iconview.content-view.check:backdrop:checked:not(list),
.content-view .tile check:backdrop:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color:
rgba(238, 238, 236, 0.8); background-color: rgba(89, 89, 90, 0.95); border-radius: 5px; background-image:
none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source:
-gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
+.view.content-view.check:backdrop:checked:not(list), iconview.content-view.check:backdrop:checked:not(list),
.content-view .tile check:backdrop:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color:
rgba(238, 238, 236, 0.8); background-color: rgba(90, 90, 90, 0.95); border-radius: 5px; background-image:
none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source:
-gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
checkbutton.text-button, radiobutton.text-button { padding: 2px 0; outline-offset: 0; border-spacing: 4px; }
-check, radio { margin: 0 4px; min-height: 14px; min-width: 14px; border: 1px solid; -gtk-icon-source: none;
color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #070707; text-shadow: 0 -1px rgba(0,
0, 0, 0.834353); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.834353); background-image: linear-gradient(to
bottom, #2d2d2d 20%, #252526 90%); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0,
0.1), 0 1px 2px rgba(0, 0, 0, 0.07); }
+check, radio { margin: 0 4px; min-height: 14px; min-width: 14px; border: 1px solid; -gtk-icon-source: none;
color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #070707; text-shadow: 0 -1px rgba(0,
0, 0, 0.834353); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.834353); background-image: linear-gradient(to
bottom, #2d2d2d 20%, #262626 90%); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0,
0.1), 0 1px 2px rgba(0, 0, 0, 0.07); }
check:only-child, radio:only-child { margin: 0; }
@@ -1189,13 +1191,13 @@ check:backdrop:disabled, radio:backdrop:disabled { border-color: #202020; backgr
check:backdrop:disabled label, check:backdrop:disabled, radio:backdrop:disabled label,
radio:backdrop:disabled { color: #5b5b5b; }
-.osd check, .osd radio { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent;
background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px
rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3);
}
+.osd check, .osd radio { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent;
background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px
rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3);
}
-.osd check:hover, .osd radio:hover { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color:
transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: inset
0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236,
0.3); }
+.osd check:hover, .osd radio:hover { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color:
transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset
0 1px rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236,
0.3); }
.osd check:active, .osd radio:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color:
transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none;
text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
-.osd check:backdrop, .osd radio:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7);
background-color: transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box;
box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
+.osd check:backdrop, .osd radio:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7);
background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box;
box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
.osd check:disabled, .osd radio:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7);
background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box;
box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
@@ -1288,7 +1290,7 @@ scale fill:disabled:backdrop, scale fill:disabled { border-color: transparent; b
.osd scale fill:disabled:backdrop, .osd scale fill:disabled { border-color: transparent; background-color:
transparent; }
-scale slider { color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #070707; text-shadow:
0 -1px rgba(0, 0, 0, 0.834353); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.834353); background-image:
linear-gradient(to bottom, #2d2d2d 20%, #252526 90%); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0
1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); border: 1px solid black; border-radius: 100%;
transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: background, border,
box-shadow; }
+scale slider { color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #070707; text-shadow:
0 -1px rgba(0, 0, 0, 0.834353); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.834353); background-image:
linear-gradient(to bottom, #2d2d2d 20%, #262626 90%); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0
1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); border: 1px solid black; border-radius: 100%;
transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: background, border,
box-shadow; }
scale slider:hover { color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #070707;
box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07);
background-image: linear-gradient(to bottom, #353535 20%, #2b2b2b 90%); }
@@ -1308,17 +1310,17 @@ scale slider:backdrop:disabled label, scale slider:backdrop:disabled { color: #5
row:selected scale slider:disabled, row:selected scale slider { border-color: #030c17; }
-.osd scale slider { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent;
background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px
rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3);
border-color: rgba(0, 0, 0, 0.7); background-color: #252526; }
+.osd scale slider { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent;
background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px
rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3);
border-color: rgba(0, 0, 0, 0.7); background-color: #262626; }
-.osd scale slider:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent;
background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px
rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3);
background-color: #252526; }
+.osd scale slider:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent;
background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px
rgba(255, 255, 255, 0.1); text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3);
background-color: #262626; }
-.osd scale slider:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent;
background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow:
none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); background-color: #252526; }
+.osd scale slider:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent;
background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow:
none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); background-color: #262626; }
-.osd scale slider:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color:
transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none;
text-shadow: none; -gtk-icon-shadow: none; background-color: #252526; }
+.osd scale slider:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color:
transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none;
text-shadow: none; -gtk-icon-shadow: none; background-color: #262626; }
-.osd scale slider:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color:
transparent; background-image: image(rgba(37, 37, 38, 0.7)); background-clip: padding-box; box-shadow: none;
text-shadow: none; -gtk-icon-shadow: none; background-color: #252526; }
+.osd scale slider:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color:
transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: none;
text-shadow: none; -gtk-icon-shadow: none; background-color: #262626; }
-.osd scale slider:backdrop:disabled { background-color: #252526; }
+.osd scale slider:backdrop:disabled { background-color: #262626; }
scale value { color: alpha(currentColor,0.55); }
@@ -1650,7 +1652,7 @@ row.activatable:selected.has-open-popup, row.activatable:selected:hover { backgr
row.activatable:selected:backdrop { background-color: #15539e; }
/********************* App Notifications * */
-.app-notification, .app-notification.frame { padding: 10px; border-radius: 0 0 5px 5px; background-color:
rgba(37, 37, 38, 0.7); background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.2), transparent 2px);
background-clip: padding-box; }
+.app-notification, .app-notification.frame { padding: 10px; border-radius: 0 0 5px 5px; background-color:
rgba(38, 38, 38, 0.7); background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.2), transparent 2px);
background-clip: padding-box; }
.app-notification:backdrop, .app-notification.frame:backdrop { background-image: none; transition: 200ms
ease-out; }
diff --git a/gtk/theme/Adwaita/gtk-contained.css b/gtk/theme/Adwaita/gtk-contained.css
index 676ffdd847..7a832ff6cc 100644
--- a/gtk/theme/Adwaita/gtk-contained.css
+++ b/gtk/theme/Adwaita/gtk-contained.css
@@ -48,6 +48,8 @@ flowbox flowboxchild { padding: 3px; }
flowbox flowboxchild:selected { outline-offset: -2px; }
+coverflow cover { color: black; background-color: #ffffff; border: 1px solid black; }
+
.content-view .tile { margin: 2px; background-color: transparent; border-radius: 0; padding: 0; }
.content-view .tile:backdrop { background-color: transparent; }
@@ -1163,7 +1165,7 @@ row:selected switch slider:checked, row:selected switch slider { border-color: #
.view.content-view.check:active:not(list), iconview.content-view.check:active:not(list), .content-view .tile
check:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent;
background-color: rgba(53, 132, 228, 0.95); border-radius: 5px; background-image: none; transition: 200ms;
box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
-.view.content-view.check:backdrop:not(list), iconview.content-view.check:backdrop:not(list), .content-view
.tile check:backdrop:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent;
background-color: rgba(140, 140, 141, 0.95); border-radius: 5px; background-image: none; transition: 200ms;
box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
+.view.content-view.check:backdrop:not(list), iconview.content-view.check:backdrop:not(list), .content-view
.tile check:backdrop:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent;
background-color: rgba(141, 141, 141, 0.95); border-radius: 5px; background-image: none; transition: 200ms;
box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
.view.content-view.check:checked:not(list), iconview.content-view.check:checked:not(list), .content-view
.tile check:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec;
background-color: rgba(53, 132, 228, 0.95); border-radius: 5px; background-image: none; transition: 200ms;
box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic');
-gtk-icon-shadow: none; }
@@ -1171,7 +1173,7 @@ row:selected switch slider:checked, row:selected switch slider { border-color: #
.view.content-view.check:checked:active:not(list), iconview.content-view.check:checked:active:not(list),
.content-view .tile check:checked:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color:
#eeeeec; background-color: rgba(53, 132, 228, 0.95); border-radius: 5px; background-image: none; transition:
200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic');
-gtk-icon-shadow: none; }
-.view.content-view.check:backdrop:checked:not(list), iconview.content-view.check:backdrop:checked:not(list),
.content-view .tile check:backdrop:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color:
rgba(238, 238, 236, 0.8); background-color: rgba(140, 140, 141, 0.95); border-radius: 5px; background-image:
none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source:
-gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
+.view.content-view.check:backdrop:checked:not(list), iconview.content-view.check:backdrop:checked:not(list),
.content-view .tile check:backdrop:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color:
rgba(238, 238, 236, 0.8); background-color: rgba(141, 141, 141, 0.95); border-radius: 5px; background-image:
none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source:
-gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
checkbutton.text-button, radiobutton.text-button { padding: 2px 0; outline-offset: 0; border-spacing: 4px; }
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]