mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 06:00:22 +00:00
listview: Add private GtkListFactoryWidget
This is a split of GtkListItemWidget into the generic parts of factory using widgets. On top of it there's GtkListItemWidget, which takes care of GtkListItem.
This commit is contained in:
parent
107133ec6d
commit
608be08b0d
@ -119,7 +119,7 @@ gtk_column_list_item_factory_update (GtkListItemFactory *factory,
|
||||
gtk_list_item_get_item (list_item),
|
||||
gtk_list_item_get_selected (list_item));
|
||||
|
||||
cell_item = gtk_list_item_widget_get_list_item (GTK_LIST_ITEM_WIDGET (child));
|
||||
cell_item = gtk_list_factory_widget_get_object (GTK_LIST_FACTORY_WIDGET (child));
|
||||
if (cell_item)
|
||||
{
|
||||
selectable &= gtk_list_item_get_selectable (cell_item);
|
||||
|
@ -146,7 +146,7 @@ gtk_column_list_view_create_list_widget (GtkListBase *base)
|
||||
"row",
|
||||
GTK_ACCESSIBLE_ROLE_ROW);
|
||||
|
||||
gtk_list_item_widget_set_single_click_activate (GTK_LIST_ITEM_WIDGET (result), self->single_click_activate);
|
||||
gtk_list_factory_widget_set_single_click_activate (GTK_LIST_FACTORY_WIDGET (result), self->single_click_activate);
|
||||
|
||||
return GTK_LIST_ITEM_BASE (result);
|
||||
}
|
||||
|
@ -915,7 +915,7 @@ gtk_drop_down_set_factory (GtkDropDown *self,
|
||||
if (!g_set_object (&self->factory, factory))
|
||||
return;
|
||||
|
||||
gtk_list_item_widget_set_factory (GTK_LIST_ITEM_WIDGET (self->button_item), factory);
|
||||
gtk_list_factory_widget_set_factory (GTK_LIST_FACTORY_WIDGET (self->button_item), factory);
|
||||
if (self->list_factory == NULL)
|
||||
gtk_list_view_set_factory (GTK_LIST_VIEW (self->popup_list), factory);
|
||||
|
||||
|
@ -268,7 +268,7 @@ gtk_grid_view_create_list_widget (GtkListBase *base)
|
||||
"child",
|
||||
GTK_ACCESSIBLE_ROLE_GRID_CELL);
|
||||
|
||||
gtk_list_item_widget_set_single_click_activate (GTK_LIST_ITEM_WIDGET (result), self->single_click_activate);
|
||||
gtk_list_factory_widget_set_single_click_activate (GTK_LIST_FACTORY_WIDGET (result), self->single_click_activate);
|
||||
|
||||
return GTK_LIST_ITEM_BASE (result);
|
||||
}
|
||||
@ -1230,7 +1230,7 @@ gtk_grid_view_set_factory (GtkGridView *self,
|
||||
tile = gtk_rb_tree_node_get_next (tile))
|
||||
{
|
||||
if (tile->widget)
|
||||
gtk_list_item_widget_set_factory (GTK_LIST_ITEM_WIDGET (tile->widget), factory);
|
||||
gtk_list_factory_widget_set_factory (GTK_LIST_FACTORY_WIDGET (tile->widget), factory);
|
||||
}
|
||||
|
||||
|
||||
@ -1357,7 +1357,7 @@ gtk_grid_view_set_single_click_activate (GtkGridView *self,
|
||||
tile = gtk_rb_tree_node_get_next (tile))
|
||||
{
|
||||
if (tile->widget)
|
||||
gtk_list_item_widget_set_single_click_activate (GTK_LIST_ITEM_WIDGET (tile->widget), single_click_activate);
|
||||
gtk_list_factory_widget_set_single_click_activate (GTK_LIST_FACTORY_WIDGET (tile->widget), single_click_activate);
|
||||
}
|
||||
|
||||
|
||||
|
643
gtk/gtklistfactorywidget.c
Normal file
643
gtk/gtklistfactorywidget.c
Normal file
@ -0,0 +1,643 @@
|
||||
/*
|
||||
* Copyright © 2023 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 "gtklistfactorywidgetprivate.h"
|
||||
|
||||
#include "gtkbinlayout.h"
|
||||
#include "gtkeventcontrollermotion.h"
|
||||
#include "gtkgestureclick.h"
|
||||
#include "gtklistitemfactoryprivate.h"
|
||||
#include "gtklistbaseprivate.h"
|
||||
#include "gtkwidget.h"
|
||||
|
||||
typedef struct _GtkListFactoryWidgetPrivate GtkListFactoryWidgetPrivate;
|
||||
struct _GtkListFactoryWidgetPrivate
|
||||
{
|
||||
GtkListItemFactory *factory;
|
||||
|
||||
gpointer object;
|
||||
gboolean single_click_activate;
|
||||
gboolean selectable;
|
||||
gboolean activatable;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ACTIVATABLE,
|
||||
PROP_FACTORY,
|
||||
PROP_SELECTABLE,
|
||||
PROP_SINGLE_CLICK_ACTIVATE,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ACTIVATE_SIGNAL,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkListFactoryWidget, gtk_list_factory_widget, GTK_TYPE_LIST_ITEM_BASE)
|
||||
|
||||
static GParamSpec *properties[N_PROPS] = { NULL, };
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_activate_signal (GtkListFactoryWidget *self)
|
||||
{
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
|
||||
if (priv->activatable)
|
||||
return;
|
||||
|
||||
gtk_widget_activate_action (GTK_WIDGET (self),
|
||||
"list.activate-item",
|
||||
"u",
|
||||
gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)));
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gtk_list_factory_widget_default_create_object (GtkListFactoryWidget *self)
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_default_setup_object (GtkListFactoryWidget *self,
|
||||
gpointer object)
|
||||
{
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
|
||||
priv->object = object;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_setup_func (gpointer object,
|
||||
gpointer data)
|
||||
{
|
||||
GTK_LIST_FACTORY_WIDGET_GET_CLASS (data)->setup_object (data, object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_setup_factory (GtkListFactoryWidget *self)
|
||||
{
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
gpointer object;
|
||||
|
||||
object = GTK_LIST_FACTORY_WIDGET_GET_CLASS (self)->create_object (self);
|
||||
|
||||
gtk_list_item_factory_setup (priv->factory,
|
||||
object,
|
||||
gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL,
|
||||
gtk_list_factory_widget_setup_func,
|
||||
self);
|
||||
|
||||
g_assert (priv->object == object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_default_teardown_object (GtkListFactoryWidget *self,
|
||||
gpointer object)
|
||||
{
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
|
||||
priv->object = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_teardown_func (gpointer object,
|
||||
gpointer data)
|
||||
{
|
||||
GTK_LIST_FACTORY_WIDGET_GET_CLASS (data)->teardown_object (data, object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_teardown_factory (GtkListFactoryWidget *self)
|
||||
{
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
gpointer item = priv->object;
|
||||
|
||||
gtk_list_item_factory_teardown (priv->factory,
|
||||
item,
|
||||
gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL,
|
||||
gtk_list_factory_widget_teardown_func,
|
||||
self);
|
||||
|
||||
g_assert (priv->object == NULL);
|
||||
g_object_unref (item);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_default_update_object (GtkListFactoryWidget *self,
|
||||
gpointer object,
|
||||
guint position,
|
||||
gpointer item,
|
||||
gboolean selected)
|
||||
{
|
||||
GTK_LIST_ITEM_BASE_CLASS (gtk_list_factory_widget_parent_class)->update (GTK_LIST_ITEM_BASE (self),
|
||||
position,
|
||||
item,
|
||||
selected);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GtkListFactoryWidget *widget;
|
||||
guint position;
|
||||
gpointer item;
|
||||
gboolean selected;
|
||||
} GtkListFactoryWidgetUpdate;
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_update_func (gpointer object,
|
||||
gpointer data)
|
||||
{
|
||||
GtkListFactoryWidgetUpdate *update = data;
|
||||
|
||||
GTK_LIST_FACTORY_WIDGET_GET_CLASS (update->widget)->update_object (update->widget,
|
||||
object,
|
||||
update->position,
|
||||
update->item,
|
||||
update->selected);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_update (GtkListItemBase *base,
|
||||
guint position,
|
||||
gpointer item,
|
||||
gboolean selected)
|
||||
{
|
||||
GtkListFactoryWidget *self = GTK_LIST_FACTORY_WIDGET (base);
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
GtkListFactoryWidgetUpdate update = { self, position, item, selected };
|
||||
|
||||
if (priv->object)
|
||||
{
|
||||
gtk_list_item_factory_update (priv->factory,
|
||||
priv->object,
|
||||
gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL,
|
||||
item != NULL,
|
||||
gtk_list_factory_widget_update_func,
|
||||
&update);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_list_factory_widget_update_func (NULL, &update);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_root (GtkWidget *widget)
|
||||
{
|
||||
GtkListFactoryWidget *self = GTK_LIST_FACTORY_WIDGET (widget);
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_list_factory_widget_parent_class)->root (widget);
|
||||
|
||||
if (priv->factory)
|
||||
gtk_list_factory_widget_setup_factory (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_unroot (GtkWidget *widget)
|
||||
{
|
||||
GtkListFactoryWidget *self = GTK_LIST_FACTORY_WIDGET (widget);
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_list_factory_widget_parent_class)->unroot (widget);
|
||||
|
||||
if (priv->object)
|
||||
gtk_list_factory_widget_teardown_factory (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkListFactoryWidget *self = GTK_LIST_FACTORY_WIDGET (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_ACTIVATABLE:
|
||||
gtk_list_factory_widget_set_activatable (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_FACTORY:
|
||||
gtk_list_factory_widget_set_factory (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_SELECTABLE:
|
||||
gtk_list_factory_widget_set_selectable (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_SINGLE_CLICK_ACTIVATE:
|
||||
gtk_list_factory_widget_set_single_click_activate (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_dispose (GObject *object)
|
||||
{
|
||||
GtkListFactoryWidget *self = GTK_LIST_FACTORY_WIDGET (object);
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
|
||||
g_assert (priv->object == NULL);
|
||||
|
||||
g_clear_object (&priv->factory);
|
||||
|
||||
G_OBJECT_CLASS (gtk_list_factory_widget_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_select_action (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkListFactoryWidget *self = GTK_LIST_FACTORY_WIDGET (widget);
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
gboolean modify, extend;
|
||||
|
||||
if (!priv->selectable)
|
||||
return;
|
||||
|
||||
g_variant_get (parameter, "(bb)", &modify, &extend);
|
||||
|
||||
gtk_widget_activate_action (GTK_WIDGET (self),
|
||||
"list.select-item",
|
||||
"(ubb)",
|
||||
gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)), modify, extend);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_scroll_to_action (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action (widget,
|
||||
"list.scroll-to-item",
|
||||
"u",
|
||||
gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (widget)));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_class_init (GtkListFactoryWidgetClass *klass)
|
||||
{
|
||||
GtkListItemBaseClass *base_class = GTK_LIST_ITEM_BASE_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
klass->activate_signal = gtk_list_factory_widget_activate_signal;
|
||||
klass->create_object = gtk_list_factory_widget_default_create_object;
|
||||
klass->setup_object = gtk_list_factory_widget_default_setup_object;
|
||||
klass->update_object = gtk_list_factory_widget_default_update_object;
|
||||
klass->teardown_object = gtk_list_factory_widget_default_teardown_object;
|
||||
|
||||
base_class->update = gtk_list_factory_widget_update;
|
||||
|
||||
widget_class->root = gtk_list_factory_widget_root;
|
||||
widget_class->unroot = gtk_list_factory_widget_unroot;
|
||||
|
||||
gobject_class->set_property = gtk_list_factory_widget_set_property;
|
||||
gobject_class->dispose = gtk_list_factory_widget_dispose;
|
||||
|
||||
properties[PROP_ACTIVATABLE] =
|
||||
g_param_spec_boolean ("activatable", NULL, NULL,
|
||||
FALSE,
|
||||
G_PARAM_WRITABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_FACTORY] =
|
||||
g_param_spec_object ("factory", NULL, NULL,
|
||||
GTK_TYPE_LIST_ITEM_FACTORY,
|
||||
G_PARAM_WRITABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_SELECTABLE] =
|
||||
g_param_spec_boolean ("selectable", NULL, NULL,
|
||||
FALSE,
|
||||
G_PARAM_WRITABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_SINGLE_CLICK_ACTIVATE] =
|
||||
g_param_spec_boolean ("single-click-activate", NULL, NULL,
|
||||
FALSE,
|
||||
G_PARAM_WRITABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
||||
|
||||
signals[ACTIVATE_SIGNAL] =
|
||||
g_signal_new (I_("activate-keybinding"),
|
||||
G_OBJECT_CLASS_TYPE (gobject_class),
|
||||
G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
|
||||
G_STRUCT_OFFSET (GtkListFactoryWidgetClass, activate_signal),
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
gtk_widget_class_set_activate_signal (widget_class, signals[ACTIVATE_SIGNAL]);
|
||||
|
||||
/**
|
||||
* GtkListItem|listitem.select:
|
||||
* @modify: %TRUE to toggle the existing selection, %FALSE to select
|
||||
* @extend: %TRUE to extend the selection
|
||||
*
|
||||
* Changes selection if the item is selectable.
|
||||
* If the item is not selectable, nothing happens.
|
||||
*
|
||||
* This function will emit the list.select-item action and the resulting
|
||||
* behavior, in particular the interpretation of @modify and @extend
|
||||
* depends on the view containing this listitem. See for example
|
||||
* GtkListView|list.select-item or GtkGridView|list.select-item.
|
||||
*/
|
||||
gtk_widget_class_install_action (widget_class,
|
||||
"listitem.select",
|
||||
"(bb)",
|
||||
gtk_list_factory_widget_select_action);
|
||||
|
||||
/**
|
||||
* GtkListItem|listitem.scroll-to:
|
||||
*
|
||||
* Moves the visible area of the list to this item with the minimum amount
|
||||
* of scrolling required. If the item is already visible, nothing happens.
|
||||
*/
|
||||
gtk_widget_class_install_action (widget_class,
|
||||
"listitem.scroll-to",
|
||||
NULL,
|
||||
gtk_list_factory_widget_scroll_to_action);
|
||||
|
||||
gtk_widget_class_add_binding_signal (widget_class, GDK_KEY_Return, 0,
|
||||
"activate-keybinding", 0);
|
||||
gtk_widget_class_add_binding_signal (widget_class, GDK_KEY_ISO_Enter, 0,
|
||||
"activate-keybinding", 0);
|
||||
gtk_widget_class_add_binding_signal (widget_class, GDK_KEY_KP_Enter, 0,
|
||||
"activate-keybinding", 0);
|
||||
|
||||
/* note that some of these may get overwritten by child widgets,
|
||||
* such as GtkTreeExpander */
|
||||
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_space, 0,
|
||||
"listitem.select", "(bb)", TRUE, FALSE);
|
||||
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_space, GDK_CONTROL_MASK,
|
||||
"listitem.select", "(bb)", TRUE, FALSE);
|
||||
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_space, GDK_SHIFT_MASK,
|
||||
"listitem.select", "(bb)", TRUE, FALSE);
|
||||
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_space, GDK_CONTROL_MASK | GDK_SHIFT_MASK,
|
||||
"listitem.select", "(bb)", TRUE, FALSE);
|
||||
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_KP_Space, 0,
|
||||
"listitem.select", "(bb)", TRUE, FALSE);
|
||||
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_KP_Space, GDK_CONTROL_MASK,
|
||||
"listitem.select", "(bb)", TRUE, FALSE);
|
||||
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_KP_Space, GDK_SHIFT_MASK,
|
||||
"listitem.select", "(bb)", TRUE, FALSE);
|
||||
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_KP_Space, GDK_CONTROL_MASK | GDK_SHIFT_MASK,
|
||||
"listitem.select", "(bb)", TRUE, FALSE);
|
||||
|
||||
/* This gets overwritten by gtk_list_factory_widget_new() but better safe than sorry */
|
||||
gtk_widget_class_set_css_name (widget_class, I_("row"));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_click_gesture_pressed (GtkGestureClick *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
GtkListFactoryWidget *self)
|
||||
{
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
GtkWidget *widget = GTK_WIDGET (self);
|
||||
|
||||
if (!priv->selectable && !priv->activatable)
|
||||
{
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->activatable)
|
||||
{
|
||||
if (n_press == 2 && !priv->single_click_activate)
|
||||
{
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
gtk_widget_activate_action (GTK_WIDGET (self),
|
||||
"list.activate-item",
|
||||
"u",
|
||||
gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)));
|
||||
}
|
||||
}
|
||||
|
||||
if (gtk_widget_get_focus_on_click (widget))
|
||||
gtk_widget_grab_focus (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_click_gesture_released (GtkGestureClick *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
GtkListFactoryWidget *self)
|
||||
{
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
|
||||
if (priv->activatable)
|
||||
{
|
||||
if (n_press == 1 && priv->single_click_activate)
|
||||
{
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
gtk_widget_activate_action (GTK_WIDGET (self),
|
||||
"list.activate-item",
|
||||
"u",
|
||||
gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->selectable)
|
||||
{
|
||||
GdkModifierType state;
|
||||
GdkEvent *event;
|
||||
gboolean extend, modify;
|
||||
|
||||
event = gtk_gesture_get_last_event (GTK_GESTURE (gesture),
|
||||
gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture)));
|
||||
state = gdk_event_get_modifier_state (event);
|
||||
extend = (state & GDK_SHIFT_MASK) != 0;
|
||||
modify = (state & GDK_CONTROL_MASK) != 0;
|
||||
|
||||
gtk_widget_activate_action (GTK_WIDGET (self),
|
||||
"list.select-item",
|
||||
"(ubb)",
|
||||
gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)), modify, extend);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_hover_cb (GtkEventControllerMotion *controller,
|
||||
double x,
|
||||
double y,
|
||||
GtkListFactoryWidget *self)
|
||||
{
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
|
||||
if (!priv->single_click_activate)
|
||||
return;
|
||||
|
||||
if (priv->selectable)
|
||||
{
|
||||
gtk_widget_activate_action (GTK_WIDGET (self),
|
||||
"list.select-item",
|
||||
"(ubb)",
|
||||
gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)), FALSE, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_factory_widget_init (GtkListFactoryWidget *self)
|
||||
{
|
||||
GtkEventController *controller;
|
||||
GtkGesture *gesture;
|
||||
|
||||
gtk_widget_set_focusable (GTK_WIDGET (self), TRUE);
|
||||
|
||||
gesture = gtk_gesture_click_new ();
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
|
||||
GTK_PHASE_BUBBLE);
|
||||
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (gesture),
|
||||
FALSE);
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture),
|
||||
GDK_BUTTON_PRIMARY);
|
||||
g_signal_connect (gesture, "pressed",
|
||||
G_CALLBACK (gtk_list_factory_widget_click_gesture_pressed), self);
|
||||
g_signal_connect (gesture, "released",
|
||||
G_CALLBACK (gtk_list_factory_widget_click_gesture_released), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect (controller, "enter", G_CALLBACK (gtk_list_factory_widget_hover_cb), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
}
|
||||
|
||||
gpointer
|
||||
gtk_list_factory_widget_get_object (GtkListFactoryWidget *self)
|
||||
{
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
|
||||
return priv->object;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_list_factory_widget_set_factory (GtkListFactoryWidget *self,
|
||||
GtkListItemFactory *factory)
|
||||
{
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
|
||||
if (priv->factory == factory)
|
||||
return;
|
||||
|
||||
if (priv->factory)
|
||||
{
|
||||
if (priv->object)
|
||||
gtk_list_factory_widget_teardown_factory (self);
|
||||
g_clear_object (&priv->factory);
|
||||
}
|
||||
|
||||
if (factory)
|
||||
{
|
||||
priv->factory = g_object_ref (factory);
|
||||
|
||||
if (gtk_widget_get_root (GTK_WIDGET (self)))
|
||||
gtk_list_factory_widget_setup_factory (self);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FACTORY]);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_list_factory_widget_set_single_click_activate (GtkListFactoryWidget *self,
|
||||
gboolean single_click_activate)
|
||||
{
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
|
||||
if (priv->single_click_activate == single_click_activate)
|
||||
return;
|
||||
|
||||
priv->single_click_activate = single_click_activate;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SINGLE_CLICK_ACTIVATE]);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_list_factory_widget_get_single_click_activate (GtkListFactoryWidget *self)
|
||||
{
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
|
||||
return priv->single_click_activate;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_list_factory_widget_set_activatable (GtkListFactoryWidget *self,
|
||||
gboolean activatable)
|
||||
{
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
|
||||
if (priv->activatable == activatable)
|
||||
return;
|
||||
|
||||
priv->activatable = activatable;
|
||||
|
||||
if (activatable)
|
||||
gtk_widget_add_css_class (GTK_WIDGET (self), "activatable");
|
||||
else
|
||||
gtk_widget_remove_css_class (GTK_WIDGET (self), "activatable");
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SINGLE_CLICK_ACTIVATE]);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_list_factory_widget_get_activatable (GtkListFactoryWidget *self)
|
||||
{
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
|
||||
return priv->activatable;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_list_factory_widget_set_selectable (GtkListFactoryWidget *self,
|
||||
gboolean selectable)
|
||||
{
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
|
||||
if (priv->selectable == selectable)
|
||||
return;
|
||||
|
||||
priv->selectable = selectable;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SINGLE_CLICK_ACTIVATE]);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_list_factory_widget_get_selectable (GtkListFactoryWidget *self)
|
||||
{
|
||||
GtkListFactoryWidgetPrivate *priv = gtk_list_factory_widget_get_instance_private (self);
|
||||
|
||||
return priv->selectable;
|
||||
}
|
86
gtk/gtklistfactorywidgetprivate.h
Normal file
86
gtk/gtklistfactorywidgetprivate.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright © 2023 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_LIST_FACTORY_WIDGET_PRIVATE_H__
|
||||
#define __GTK_LIST_FACTORY_WIDGET_PRIVATE_H__
|
||||
|
||||
#include "gtklistitembaseprivate.h"
|
||||
|
||||
#include "gtklistitemfactory.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_LIST_FACTORY_WIDGET (gtk_list_factory_widget_get_type ())
|
||||
#define GTK_LIST_FACTORY_WIDGET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_LIST_FACTORY_WIDGET, GtkListFactoryWidget))
|
||||
#define GTK_LIST_FACTORY_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTK_TYPE_LIST_FACTORY_WIDGET, GtkListFactoryWidgetClass))
|
||||
#define GTK_IS_LIST_FACTORY_WIDGET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_LIST_FACTORY_WIDGET))
|
||||
#define GTK_IS_LIST_FACTORY_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTK_TYPE_LIST_FACTORY_WIDGET))
|
||||
#define GTK_LIST_FACTORY_WIDGET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_LIST_FACTORY_WIDGET, GtkListFactoryWidgetClass))
|
||||
|
||||
typedef struct _GtkListFactoryWidget GtkListFactoryWidget;
|
||||
typedef struct _GtkListFactoryWidgetClass GtkListFactoryWidgetClass;
|
||||
|
||||
struct _GtkListFactoryWidget
|
||||
{
|
||||
GtkListItemBase parent_instance;
|
||||
};
|
||||
|
||||
struct _GtkListFactoryWidgetClass
|
||||
{
|
||||
GtkListItemBaseClass parent_class;
|
||||
|
||||
void (* activate_signal) (GtkListFactoryWidget *self);
|
||||
|
||||
gpointer (* create_object) (GtkListFactoryWidget *self);
|
||||
void (* setup_object) (GtkListFactoryWidget *self,
|
||||
gpointer object);
|
||||
void (* update_object) (GtkListFactoryWidget *self,
|
||||
gpointer object,
|
||||
guint position,
|
||||
gpointer item,
|
||||
gboolean selected);
|
||||
void (* teardown_object) (GtkListFactoryWidget *self,
|
||||
gpointer object);
|
||||
};
|
||||
|
||||
GType gtk_list_factory_widget_get_type (void) G_GNUC_CONST;
|
||||
|
||||
gpointer gtk_list_factory_widget_get_object (GtkListFactoryWidget *self);
|
||||
|
||||
void gtk_list_factory_widget_set_factory (GtkListFactoryWidget *self,
|
||||
GtkListItemFactory *factory);
|
||||
GtkListItemFactory * gtk_list_factory_widget_get_factory (GtkListFactoryWidget *self);
|
||||
|
||||
void gtk_list_factory_widget_set_single_click_activate
|
||||
(GtkListFactoryWidget *self,
|
||||
gboolean single_click_activate);
|
||||
gboolean gtk_list_factory_widget_get_single_click_activate
|
||||
(GtkListFactoryWidget *self);
|
||||
|
||||
void gtk_list_factory_widget_set_activatable (GtkListFactoryWidget *self,
|
||||
gboolean activatable);
|
||||
gboolean gtk_list_factory_widget_get_activatable (GtkListFactoryWidget *self);
|
||||
|
||||
void gtk_list_factory_widget_set_selectable (GtkListFactoryWidget *self,
|
||||
gboolean activatable);
|
||||
gboolean gtk_list_factory_widget_get_selectable (GtkListFactoryWidget *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_LIST_FACTORY_WIDGET_PRIVATE_H__ */
|
@ -417,6 +417,9 @@ gtk_list_item_set_selectable (GtkListItem *self,
|
||||
|
||||
self->selectable = selectable;
|
||||
|
||||
if (self->owner)
|
||||
gtk_list_factory_widget_set_selectable (GTK_LIST_FACTORY_WIDGET (self->owner), selectable);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTABLE]);
|
||||
}
|
||||
|
||||
@ -464,7 +467,7 @@ gtk_list_item_set_activatable (GtkListItem *self,
|
||||
self->activatable = activatable;
|
||||
|
||||
if (self->owner)
|
||||
gtk_list_item_widget_set_activatable (self->owner, activatable);
|
||||
gtk_list_factory_widget_set_activatable (GTK_LIST_FACTORY_WIDGET (self->owner), activatable);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIVATABLE]);
|
||||
}
|
||||
|
@ -32,47 +32,7 @@
|
||||
#include "gtkwidget.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
|
||||
typedef struct _GtkListItemWidgetPrivate GtkListItemWidgetPrivate;
|
||||
struct _GtkListItemWidgetPrivate
|
||||
{
|
||||
GtkListItemFactory *factory;
|
||||
GtkListItem *list_item;
|
||||
|
||||
gboolean single_click_activate;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_FACTORY,
|
||||
PROP_SINGLE_CLICK_ACTIVATE,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ACTIVATE_SIGNAL,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkListItemWidget, gtk_list_item_widget, GTK_TYPE_LIST_ITEM_BASE)
|
||||
|
||||
static GParamSpec *properties[N_PROPS] = { NULL, };
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_activate_signal (GtkListItemWidget *self)
|
||||
{
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
|
||||
if (priv->list_item && !priv->list_item->activatable)
|
||||
return;
|
||||
|
||||
gtk_widget_activate_action (GTK_WIDGET (self),
|
||||
"list.activate-item",
|
||||
"u",
|
||||
gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)));
|
||||
}
|
||||
G_DEFINE_TYPE (GtkListItemWidget, gtk_list_item_widget, GTK_TYPE_LIST_FACTORY_WIDGET)
|
||||
|
||||
static gboolean
|
||||
gtk_list_item_widget_focus (GtkWidget *widget,
|
||||
@ -117,7 +77,6 @@ static gboolean
|
||||
gtk_list_item_widget_grab_focus (GtkWidget *widget)
|
||||
{
|
||||
GtkListItemWidget *self = GTK_LIST_ITEM_WIDGET (widget);
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
GtkWidget *child;
|
||||
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
@ -128,28 +87,34 @@ gtk_list_item_widget_grab_focus (GtkWidget *widget)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (priv->list_item == NULL ||
|
||||
!priv->list_item->selectable)
|
||||
if (!gtk_list_factory_widget_get_selectable (GTK_LIST_FACTORY_WIDGET (self)))
|
||||
return FALSE;
|
||||
|
||||
return GTK_WIDGET_CLASS (gtk_list_item_widget_parent_class)->grab_focus (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_setup_func (gpointer object,
|
||||
gpointer data)
|
||||
static gpointer
|
||||
gtk_list_item_widget_create_object (GtkListFactoryWidget *fw)
|
||||
{
|
||||
GtkListItemWidget *self = data;
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
return gtk_list_item_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_setup_object (GtkListFactoryWidget *fw,
|
||||
gpointer object)
|
||||
{
|
||||
GtkListItemWidget *self = GTK_LIST_ITEM_WIDGET (fw);
|
||||
GtkListItem *list_item = object;
|
||||
|
||||
priv->list_item = list_item;
|
||||
GTK_LIST_FACTORY_WIDGET_CLASS (gtk_list_item_widget_parent_class)->setup_object (fw, object);
|
||||
|
||||
list_item->owner = self;
|
||||
|
||||
if (list_item->child)
|
||||
gtk_list_item_widget_add_child (self, list_item->child);
|
||||
|
||||
gtk_list_item_widget_set_activatable (self, list_item->activatable);
|
||||
gtk_list_factory_widget_set_activatable (fw, list_item->activatable);
|
||||
gtk_list_factory_widget_set_selectable (fw, list_item->selectable);
|
||||
|
||||
gtk_list_item_do_notify (list_item,
|
||||
gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL,
|
||||
@ -158,432 +123,82 @@ gtk_list_item_widget_setup_func (gpointer object,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_setup_factory (GtkListItemWidget *self)
|
||||
gtk_list_item_widget_teardown_object (GtkListFactoryWidget *fw,
|
||||
gpointer object)
|
||||
{
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
GtkListItem *list_item;
|
||||
|
||||
list_item = gtk_list_item_new ();
|
||||
|
||||
gtk_list_item_factory_setup (priv->factory,
|
||||
G_OBJECT (list_item),
|
||||
gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL,
|
||||
gtk_list_item_widget_setup_func,
|
||||
self);
|
||||
|
||||
g_assert (priv->list_item == list_item);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_teardown_func (gpointer object,
|
||||
gpointer data)
|
||||
{
|
||||
GtkListItemWidget *self = data;
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
GtkListItemWidget *self = GTK_LIST_ITEM_WIDGET (fw);
|
||||
GtkListItem *list_item = object;
|
||||
|
||||
g_assert (priv->list_item == list_item);
|
||||
GTK_LIST_FACTORY_WIDGET_CLASS (gtk_list_item_widget_parent_class)->teardown_object (fw, object);
|
||||
|
||||
priv->list_item = NULL;
|
||||
list_item->owner = NULL;
|
||||
|
||||
if (list_item->child)
|
||||
gtk_list_item_widget_remove_child (self, list_item->child);
|
||||
|
||||
gtk_list_item_widget_set_activatable (self, FALSE);
|
||||
gtk_list_factory_widget_set_activatable (fw, FALSE);
|
||||
gtk_list_factory_widget_set_selectable (fw, FALSE);
|
||||
|
||||
gtk_list_item_do_notify (list_item,
|
||||
gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL,
|
||||
gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)) != GTK_INVALID_LIST_POSITION,
|
||||
gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (self)));
|
||||
|
||||
/* FIXME: This is technically not correct, the child is user code, isn't it? */
|
||||
gtk_list_item_set_child (list_item, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_teardown_factory (GtkListItemWidget *self)
|
||||
gtk_list_item_widget_update_object (GtkListFactoryWidget *fw,
|
||||
gpointer object,
|
||||
guint position,
|
||||
gpointer item,
|
||||
gboolean selected)
|
||||
{
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
GtkListItem *list_item = priv->list_item;
|
||||
|
||||
gtk_list_item_factory_teardown (priv->factory,
|
||||
G_OBJECT (list_item),
|
||||
gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL,
|
||||
gtk_list_item_widget_teardown_func,
|
||||
self);
|
||||
|
||||
g_assert (priv->list_item == NULL);
|
||||
g_object_unref (list_item);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GtkListItemWidget *widget;
|
||||
guint position;
|
||||
gpointer item;
|
||||
gboolean selected;
|
||||
} GtkListItemWidgetUpdate;
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_update_func (gpointer object,
|
||||
gpointer data)
|
||||
{
|
||||
GtkListItemWidgetUpdate *update = data;
|
||||
GtkListItemWidget *self = GTK_LIST_ITEM_WIDGET (fw);
|
||||
GtkListItemBase *base = GTK_LIST_ITEM_BASE (self);
|
||||
GtkListItem *list_item = object;
|
||||
/* Track notify manually instead of freeze/thaw_notify for performance reasons. */
|
||||
gboolean notify_item = FALSE, notify_position = FALSE, notify_selected = FALSE;
|
||||
GtkListItemWidget *self = update->widget;
|
||||
GtkListItemBase *base = GTK_LIST_ITEM_BASE (self);
|
||||
|
||||
/* FIXME: It's kinda evil to notify external objects from here... */
|
||||
notify_item = gtk_list_item_base_get_item (base) != update->item;
|
||||
notify_position = gtk_list_item_base_get_position (base) != update->position;
|
||||
notify_selected = gtk_list_item_base_get_selected (base) != update->selected;
|
||||
notify_item = gtk_list_item_base_get_item (base) != item;
|
||||
notify_position = gtk_list_item_base_get_position (base) != position;
|
||||
notify_selected = gtk_list_item_base_get_selected (base) != selected;
|
||||
|
||||
GTK_LIST_FACTORY_WIDGET_CLASS (gtk_list_item_widget_parent_class)->update_object (fw,
|
||||
object,
|
||||
position,
|
||||
item,
|
||||
selected);
|
||||
|
||||
GTK_LIST_ITEM_BASE_CLASS (gtk_list_item_widget_parent_class)->update (base,
|
||||
update->position,
|
||||
update->item,
|
||||
update->selected);
|
||||
if (list_item)
|
||||
gtk_list_item_do_notify (list_item, notify_item, notify_position, notify_selected);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_update (GtkListItemBase *base,
|
||||
guint position,
|
||||
gpointer item,
|
||||
gboolean selected)
|
||||
{
|
||||
GtkListItemWidget *self = GTK_LIST_ITEM_WIDGET (base);
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
GtkListItemWidgetUpdate update = { self, position, item, selected };
|
||||
|
||||
if (priv->list_item)
|
||||
{
|
||||
gtk_list_item_factory_update (priv->factory,
|
||||
G_OBJECT (priv->list_item),
|
||||
gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL,
|
||||
item != NULL,
|
||||
gtk_list_item_widget_update_func,
|
||||
&update);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_list_item_widget_update_func (NULL, &update);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_root (GtkWidget *widget)
|
||||
{
|
||||
GtkListItemWidget *self = GTK_LIST_ITEM_WIDGET (widget);
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_list_item_widget_parent_class)->root (widget);
|
||||
|
||||
if (priv->factory)
|
||||
gtk_list_item_widget_setup_factory (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_unroot (GtkWidget *widget)
|
||||
{
|
||||
GtkListItemWidget *self = GTK_LIST_ITEM_WIDGET (widget);
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_list_item_widget_parent_class)->unroot (widget);
|
||||
|
||||
if (priv->list_item)
|
||||
gtk_list_item_widget_teardown_factory (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkListItemWidget *self = GTK_LIST_ITEM_WIDGET (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_FACTORY:
|
||||
gtk_list_item_widget_set_factory (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_SINGLE_CLICK_ACTIVATE:
|
||||
gtk_list_item_widget_set_single_click_activate (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_dispose (GObject *object)
|
||||
{
|
||||
GtkListItemWidget *self = GTK_LIST_ITEM_WIDGET (object);
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
|
||||
g_assert (priv->list_item == NULL);
|
||||
|
||||
g_clear_object (&priv->factory);
|
||||
|
||||
G_OBJECT_CLASS (gtk_list_item_widget_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_select_action (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkListItemWidget *self = GTK_LIST_ITEM_WIDGET (widget);
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
gboolean modify, extend;
|
||||
|
||||
if (priv->list_item && !priv->list_item->selectable)
|
||||
return;
|
||||
|
||||
g_variant_get (parameter, "(bb)", &modify, &extend);
|
||||
|
||||
gtk_widget_activate_action (GTK_WIDGET (self),
|
||||
"list.select-item",
|
||||
"(ubb)",
|
||||
gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)), modify, extend);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_scroll_to_action (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action (widget,
|
||||
"list.scroll-to-item",
|
||||
"u",
|
||||
gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (widget)));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_class_init (GtkListItemWidgetClass *klass)
|
||||
{
|
||||
GtkListItemBaseClass *base_class = GTK_LIST_ITEM_BASE_CLASS (klass);
|
||||
GtkListFactoryWidgetClass *factory_class = GTK_LIST_FACTORY_WIDGET_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
klass->activate_signal = gtk_list_item_widget_activate_signal;
|
||||
|
||||
base_class->update = gtk_list_item_widget_update;
|
||||
factory_class->create_object = gtk_list_item_widget_create_object;
|
||||
factory_class->setup_object = gtk_list_item_widget_setup_object;
|
||||
factory_class->update_object = gtk_list_item_widget_update_object;
|
||||
factory_class->teardown_object = gtk_list_item_widget_teardown_object;
|
||||
|
||||
widget_class->focus = gtk_list_item_widget_focus;
|
||||
widget_class->grab_focus = gtk_list_item_widget_grab_focus;
|
||||
widget_class->root = gtk_list_item_widget_root;
|
||||
widget_class->unroot = gtk_list_item_widget_unroot;
|
||||
|
||||
gobject_class->set_property = gtk_list_item_widget_set_property;
|
||||
gobject_class->dispose = gtk_list_item_widget_dispose;
|
||||
|
||||
properties[PROP_FACTORY] =
|
||||
g_param_spec_object ("factory", NULL, NULL,
|
||||
GTK_TYPE_LIST_ITEM_FACTORY,
|
||||
G_PARAM_WRITABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_SINGLE_CLICK_ACTIVATE] =
|
||||
g_param_spec_boolean ("single-click-activate", NULL, NULL,
|
||||
FALSE,
|
||||
G_PARAM_WRITABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
||||
|
||||
signals[ACTIVATE_SIGNAL] =
|
||||
g_signal_new (I_("activate-keybinding"),
|
||||
G_OBJECT_CLASS_TYPE (gobject_class),
|
||||
G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
|
||||
G_STRUCT_OFFSET (GtkListItemWidgetClass, activate_signal),
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
gtk_widget_class_set_activate_signal (widget_class, signals[ACTIVATE_SIGNAL]);
|
||||
|
||||
/**
|
||||
* GtkListItem|listitem.select:
|
||||
* @modify: %TRUE to toggle the existing selection, %FALSE to select
|
||||
* @extend: %TRUE to extend the selection
|
||||
*
|
||||
* Changes selection if the item is selectable.
|
||||
* If the item is not selectable, nothing happens.
|
||||
*
|
||||
* This function will emit the list.select-item action and the resulting
|
||||
* behavior, in particular the interpretation of @modify and @extend
|
||||
* depends on the view containing this listitem. See for example
|
||||
* GtkListView|list.select-item or GtkGridView|list.select-item.
|
||||
*/
|
||||
gtk_widget_class_install_action (widget_class,
|
||||
"listitem.select",
|
||||
"(bb)",
|
||||
gtk_list_item_widget_select_action);
|
||||
|
||||
/**
|
||||
* GtkListItem|listitem.scroll-to:
|
||||
*
|
||||
* Moves the visible area of the list to this item with the minimum amount
|
||||
* of scrolling required. If the item is already visible, nothing happens.
|
||||
*/
|
||||
gtk_widget_class_install_action (widget_class,
|
||||
"listitem.scroll-to",
|
||||
NULL,
|
||||
gtk_list_item_widget_scroll_to_action);
|
||||
|
||||
gtk_widget_class_add_binding_signal (widget_class, GDK_KEY_Return, 0,
|
||||
"activate-keybinding", 0);
|
||||
gtk_widget_class_add_binding_signal (widget_class, GDK_KEY_ISO_Enter, 0,
|
||||
"activate-keybinding", 0);
|
||||
gtk_widget_class_add_binding_signal (widget_class, GDK_KEY_KP_Enter, 0,
|
||||
"activate-keybinding", 0);
|
||||
|
||||
/* note that some of these may get overwritten by child widgets,
|
||||
* such as GtkTreeExpander */
|
||||
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_space, 0,
|
||||
"listitem.select", "(bb)", TRUE, FALSE);
|
||||
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_space, GDK_CONTROL_MASK,
|
||||
"listitem.select", "(bb)", TRUE, FALSE);
|
||||
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_space, GDK_SHIFT_MASK,
|
||||
"listitem.select", "(bb)", TRUE, FALSE);
|
||||
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_space, GDK_CONTROL_MASK | GDK_SHIFT_MASK,
|
||||
"listitem.select", "(bb)", TRUE, FALSE);
|
||||
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_KP_Space, 0,
|
||||
"listitem.select", "(bb)", TRUE, FALSE);
|
||||
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_KP_Space, GDK_CONTROL_MASK,
|
||||
"listitem.select", "(bb)", TRUE, FALSE);
|
||||
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_KP_Space, GDK_SHIFT_MASK,
|
||||
"listitem.select", "(bb)", TRUE, FALSE);
|
||||
gtk_widget_class_add_binding_action (widget_class, GDK_KEY_KP_Space, GDK_CONTROL_MASK | GDK_SHIFT_MASK,
|
||||
"listitem.select", "(bb)", TRUE, FALSE);
|
||||
|
||||
/* This gets overwritten by gtk_list_item_widget_new() but better safe than sorry */
|
||||
gtk_widget_class_set_css_name (widget_class, I_("row"));
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_click_gesture_pressed (GtkGestureClick *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
GtkListItemWidget *self)
|
||||
{
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
GtkWidget *widget = GTK_WIDGET (self);
|
||||
|
||||
if (priv->list_item && !priv->list_item->selectable && !priv->list_item->activatable)
|
||||
{
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!priv->list_item || priv->list_item->activatable)
|
||||
{
|
||||
if (n_press == 2 && !priv->single_click_activate)
|
||||
{
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
gtk_widget_activate_action (GTK_WIDGET (self),
|
||||
"list.activate-item",
|
||||
"u",
|
||||
gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)));
|
||||
}
|
||||
}
|
||||
|
||||
if (gtk_widget_get_focus_on_click (widget))
|
||||
gtk_widget_grab_focus (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_click_gesture_released (GtkGestureClick *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
GtkListItemWidget *self)
|
||||
{
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
|
||||
if (!priv->list_item || priv->list_item->activatable)
|
||||
{
|
||||
if (n_press == 1 && priv->single_click_activate)
|
||||
{
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
gtk_widget_activate_action (GTK_WIDGET (self),
|
||||
"list.activate-item",
|
||||
"u",
|
||||
gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!priv->list_item || priv->list_item->selectable)
|
||||
{
|
||||
GdkModifierType state;
|
||||
GdkEvent *event;
|
||||
gboolean extend, modify;
|
||||
|
||||
event = gtk_gesture_get_last_event (GTK_GESTURE (gesture),
|
||||
gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture)));
|
||||
state = gdk_event_get_modifier_state (event);
|
||||
extend = (state & GDK_SHIFT_MASK) != 0;
|
||||
modify = (state & GDK_CONTROL_MASK) != 0;
|
||||
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
gtk_widget_activate_action (GTK_WIDGET (self),
|
||||
"list.select-item",
|
||||
"(ubb)",
|
||||
gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)), modify, extend);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_hover_cb (GtkEventControllerMotion *controller,
|
||||
double x,
|
||||
double y,
|
||||
GtkListItemWidget *self)
|
||||
{
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
|
||||
if (!priv->single_click_activate)
|
||||
return;
|
||||
|
||||
if (!priv->list_item || priv->list_item->selectable)
|
||||
{
|
||||
gtk_widget_activate_action (GTK_WIDGET (self),
|
||||
"list.select-item",
|
||||
"(ubb)",
|
||||
gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)), FALSE, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_init (GtkListItemWidget *self)
|
||||
{
|
||||
GtkEventController *controller;
|
||||
GtkGesture *gesture;
|
||||
|
||||
gtk_widget_set_focusable (GTK_WIDGET (self), TRUE);
|
||||
|
||||
gesture = gtk_gesture_click_new ();
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
|
||||
GTK_PHASE_BUBBLE);
|
||||
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (gesture),
|
||||
FALSE);
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture),
|
||||
GDK_BUTTON_PRIMARY);
|
||||
g_signal_connect (gesture, "pressed",
|
||||
G_CALLBACK (gtk_list_item_widget_click_gesture_pressed), self);
|
||||
g_signal_connect (gesture, "released",
|
||||
G_CALLBACK (gtk_list_item_widget_click_gesture_released), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect (controller, "enter", G_CALLBACK (gtk_list_item_widget_hover_cb), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
@ -600,57 +215,6 @@ gtk_list_item_widget_new (GtkListItemFactory *factory,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_list_item_widget_set_factory (GtkListItemWidget *self,
|
||||
GtkListItemFactory *factory)
|
||||
{
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
|
||||
if (priv->factory == factory)
|
||||
return;
|
||||
|
||||
if (priv->factory)
|
||||
{
|
||||
if (priv->list_item)
|
||||
gtk_list_item_widget_teardown_factory (self);
|
||||
g_clear_object (&priv->factory);
|
||||
}
|
||||
|
||||
if (factory)
|
||||
{
|
||||
priv->factory = g_object_ref (factory);
|
||||
|
||||
if (gtk_widget_get_root (GTK_WIDGET (self)))
|
||||
gtk_list_item_widget_setup_factory (self);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FACTORY]);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_list_item_widget_set_single_click_activate (GtkListItemWidget *self,
|
||||
gboolean single_click_activate)
|
||||
{
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
|
||||
if (priv->single_click_activate == single_click_activate)
|
||||
return;
|
||||
|
||||
priv->single_click_activate = single_click_activate;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SINGLE_CLICK_ACTIVATE]);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_list_item_widget_set_activatable (GtkListItemWidget *self,
|
||||
gboolean activatable)
|
||||
{
|
||||
if (activatable)
|
||||
gtk_widget_add_css_class (GTK_WIDGET (self), "activatable");
|
||||
else
|
||||
gtk_widget_remove_css_class (GTK_WIDGET (self), "activatable");
|
||||
}
|
||||
|
||||
void
|
||||
gtk_list_item_widget_add_child (GtkListItemWidget *self,
|
||||
GtkWidget *child)
|
||||
@ -694,11 +258,3 @@ gtk_list_item_widget_remove_child (GtkListItemWidget *self,
|
||||
gtk_widget_unparent (child);
|
||||
}
|
||||
|
||||
GtkListItem *
|
||||
gtk_list_item_widget_get_list_item (GtkListItemWidget *self)
|
||||
{
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
|
||||
return priv->list_item;
|
||||
}
|
||||
|
||||
|
@ -20,9 +20,7 @@
|
||||
#ifndef __GTK_LIST_ITEM_WIDGET_PRIVATE_H__
|
||||
#define __GTK_LIST_ITEM_WIDGET_PRIVATE_H__
|
||||
|
||||
#include "gtklistitembaseprivate.h"
|
||||
|
||||
#include "gtklistitemfactory.h"
|
||||
#include "gtklistfactorywidgetprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -38,14 +36,12 @@ typedef struct _GtkListItemWidgetClass GtkListItemWidgetClass;
|
||||
|
||||
struct _GtkListItemWidget
|
||||
{
|
||||
GtkListItemBase parent_instance;
|
||||
GtkListFactoryWidget parent_instance;
|
||||
};
|
||||
|
||||
struct _GtkListItemWidgetClass
|
||||
{
|
||||
GtkListItemBaseClass parent_class;
|
||||
|
||||
void (* activate_signal) (GtkListItemWidget *self);
|
||||
GtkListFactoryWidgetClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_list_item_widget_get_type (void) G_GNUC_CONST;
|
||||
@ -54,15 +50,6 @@ GtkWidget * gtk_list_item_widget_new (GtkListItemFact
|
||||
const char *css_name,
|
||||
GtkAccessibleRole role);
|
||||
|
||||
GtkListItem * gtk_list_item_widget_get_list_item (GtkListItemWidget *self);
|
||||
|
||||
void gtk_list_item_widget_set_factory (GtkListItemWidget *self,
|
||||
GtkListItemFactory *factory);
|
||||
void gtk_list_item_widget_set_single_click_activate
|
||||
(GtkListItemWidget *self,
|
||||
gboolean single_click_activate);
|
||||
void gtk_list_item_widget_set_activatable (GtkListItemWidget *self,
|
||||
gboolean activatable);
|
||||
void gtk_list_item_widget_add_child (GtkListItemWidget *self,
|
||||
GtkWidget *child);
|
||||
void gtk_list_item_widget_reorder_child (GtkListItemWidget *self,
|
||||
|
@ -226,7 +226,7 @@ gtk_list_view_create_list_widget (GtkListBase *base)
|
||||
"row",
|
||||
GTK_ACCESSIBLE_ROLE_LIST_ITEM);
|
||||
|
||||
gtk_list_item_widget_set_single_click_activate (GTK_LIST_ITEM_WIDGET (result), self->single_click_activate);
|
||||
gtk_list_factory_widget_set_single_click_activate (GTK_LIST_FACTORY_WIDGET (result), self->single_click_activate);
|
||||
|
||||
return GTK_LIST_ITEM_BASE (result);
|
||||
}
|
||||
@ -954,7 +954,7 @@ gtk_list_view_set_factory (GtkListView *self,
|
||||
tile = gtk_rb_tree_node_get_next (tile))
|
||||
{
|
||||
if (tile->widget)
|
||||
gtk_list_item_widget_set_factory (GTK_LIST_ITEM_WIDGET (tile->widget), factory);
|
||||
gtk_list_factory_widget_set_factory (GTK_LIST_FACTORY_WIDGET (tile->widget), factory);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FACTORY]);
|
||||
@ -1030,7 +1030,7 @@ gtk_list_view_set_single_click_activate (GtkListView *self,
|
||||
tile = gtk_rb_tree_node_get_next (tile))
|
||||
{
|
||||
if (tile->widget)
|
||||
gtk_list_item_widget_set_single_click_activate (GTK_LIST_ITEM_WIDGET (tile->widget), single_click_activate);
|
||||
gtk_list_factory_widget_set_single_click_activate (GTK_LIST_FACTORY_WIDGET (tile->widget), single_click_activate);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SINGLE_CLICK_ACTIVATE]);
|
||||
|
@ -269,6 +269,7 @@ gtk_public_sources = files([
|
||||
'gtklistbase.c',
|
||||
'gtklinkbutton.c',
|
||||
'gtklistbox.c',
|
||||
'gtklistfactorywidget.c',
|
||||
'gtklistitem.c',
|
||||
'gtklistitembase.c',
|
||||
'gtklistitemfactory.c',
|
||||
|
Loading…
Reference in New Issue
Block a user