mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-01 00:11:29 +00:00
listbox: Add multi-selection API
This commit adds API for dealing with multi-selection. It is identical to the flow box API for this purpose. The implementation is still limited to single-selection, and will be updated in subsequent commits.
This commit is contained in:
parent
d6cc9bd7cb
commit
463c89e540
228
gtk/gtklistbox.c
228
gtk/gtklistbox.c
@ -107,6 +107,9 @@ enum {
|
|||||||
ACTIVATE_CURSOR_ROW,
|
ACTIVATE_CURSOR_ROW,
|
||||||
TOGGLE_CURSOR_ROW,
|
TOGGLE_CURSOR_ROW,
|
||||||
MOVE_CURSOR,
|
MOVE_CURSOR,
|
||||||
|
SELECTED_ROWS_CHANGED,
|
||||||
|
SELECT_ALL,
|
||||||
|
UNSELECT_ALL,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -377,6 +380,8 @@ gtk_list_box_class_init (GtkListBoxClass *klass)
|
|||||||
* The ::row-selected signal is emitted when a new row is selected, or
|
* The ::row-selected signal is emitted when a new row is selected, or
|
||||||
* (with a %NULL @row) when the selection is cleared.
|
* (with a %NULL @row) when the selection is cleared.
|
||||||
*
|
*
|
||||||
|
* Also see #GtkListBox::selected-rows-changed.
|
||||||
|
*
|
||||||
* Since: 3.10
|
* Since: 3.10
|
||||||
*/
|
*/
|
||||||
signals[ROW_SELECTED] =
|
signals[ROW_SELECTED] =
|
||||||
@ -389,6 +394,63 @@ gtk_list_box_class_init (GtkListBoxClass *klass)
|
|||||||
G_TYPE_NONE, 1,
|
G_TYPE_NONE, 1,
|
||||||
GTK_TYPE_LIST_BOX_ROW);
|
GTK_TYPE_LIST_BOX_ROW);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GtkListBox::selected-rows-changed:
|
||||||
|
* @list_box: the #GtkListBox on wich the signal is emitted
|
||||||
|
*
|
||||||
|
* The ::selected-rows-changed signal is emitted when the
|
||||||
|
* set of selected rows changes.
|
||||||
|
*
|
||||||
|
* Since: 3.14
|
||||||
|
*/
|
||||||
|
signals[SELECTED_ROWS_CHANGED] = g_signal_new ("selected-rows-changed",
|
||||||
|
GTK_TYPE_LIST_BOX,
|
||||||
|
G_SIGNAL_RUN_FIRST,
|
||||||
|
G_STRUCT_OFFSET (GtkListBoxClass, selected_rows_changed),
|
||||||
|
NULL, NULL,
|
||||||
|
g_cclosure_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GtkListBox::select-all:
|
||||||
|
* @box: the #GtkListBox on which the signal is emitted
|
||||||
|
*
|
||||||
|
* The ::select-all signal is a [keybinding signal][GtkBindingSignal]
|
||||||
|
* which gets emitted to select all children of the box, if the selection
|
||||||
|
* mode permits it.
|
||||||
|
*
|
||||||
|
* The default bindings for this signal is Ctrl-a.
|
||||||
|
*
|
||||||
|
* Since: 3.14
|
||||||
|
*/
|
||||||
|
signals[SELECT_ALL] = g_signal_new ("select-all",
|
||||||
|
GTK_TYPE_LIST_BOX,
|
||||||
|
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||||||
|
G_STRUCT_OFFSET (GtkListBoxClass, select_all),
|
||||||
|
NULL, NULL,
|
||||||
|
g_cclosure_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GtkListBox::unselect-all:
|
||||||
|
* @box: the #GtkListBox on which the signal is emitted
|
||||||
|
*
|
||||||
|
* The ::unselect-all signal is a [keybinding signal][GtkBindingSignal]
|
||||||
|
* which gets emitted to unselect all children of the box, if the selection
|
||||||
|
* mode permits it.
|
||||||
|
*
|
||||||
|
* The default bindings for this signal is Ctrl-Shift-a.
|
||||||
|
*
|
||||||
|
* Since: 3.14
|
||||||
|
*/
|
||||||
|
signals[UNSELECT_ALL] = g_signal_new ("unselect-all",
|
||||||
|
GTK_TYPE_LIST_BOX,
|
||||||
|
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||||||
|
G_STRUCT_OFFSET (GtkListBoxClass, unselect_all),
|
||||||
|
NULL, NULL,
|
||||||
|
g_cclosure_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GtkListBox::row-activated:
|
* GtkListBox::row-activated:
|
||||||
* @list_box: the #GtkListBox
|
* @list_box: the #GtkListBox
|
||||||
@ -576,10 +638,142 @@ gtk_list_box_select_row (GtkListBox *list_box,
|
|||||||
GtkListBoxRow *row)
|
GtkListBoxRow *row)
|
||||||
{
|
{
|
||||||
g_return_if_fail (GTK_IS_LIST_BOX (list_box));
|
g_return_if_fail (GTK_IS_LIST_BOX (list_box));
|
||||||
|
g_return_if_fail (row == NULL || GTK_IS_LIST_BOX_ROW (row));
|
||||||
|
|
||||||
gtk_list_box_update_selected (list_box, row);
|
gtk_list_box_update_selected (list_box, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_list_box_unselect_row:
|
||||||
|
* @list_box: a #GtkListBox
|
||||||
|
* @row: the row to unselected
|
||||||
|
*
|
||||||
|
* Unselects a single row of @list_box, if the selection
|
||||||
|
* mode allows it.
|
||||||
|
*
|
||||||
|
* Since: 3.14
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gtk_list_box_unselect_row (GtkListBox *list_box,
|
||||||
|
GtkListBoxRow *row)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GTK_IS_LIST_BOX (list_box));
|
||||||
|
g_return_if_fail (GTK_IS_LIST_BOX_ROW (row));
|
||||||
|
|
||||||
|
gtk_list_box_update_selected (list_box, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_list_box_select_all:
|
||||||
|
* @list_box: a #GtkListBox
|
||||||
|
*
|
||||||
|
* Select all children of @list_box, if the selection
|
||||||
|
* mode allows it.
|
||||||
|
*
|
||||||
|
* Since: 3.14
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gtk_list_box_select_all (GtkListBox *list_box)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GTK_IS_LIST_BOX (list_box));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_list_box_unselect_all:
|
||||||
|
* @list_box: a #GtkListBox
|
||||||
|
*
|
||||||
|
* Unselect all children of @list_box, if the selection
|
||||||
|
* mode allows it.
|
||||||
|
*
|
||||||
|
* Since: 3.14
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gtk_list_box_unselect_all (GtkListBox *list_box)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GTK_IS_LIST_BOX (list_box));
|
||||||
|
|
||||||
|
gtk_list_box_update_selected (list_box, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GtkListBoxForeachFunc:
|
||||||
|
* @list_box: a #GtkListBox
|
||||||
|
* @row: a #GtkListBoxRow
|
||||||
|
* @user_data: (closure): user data
|
||||||
|
*
|
||||||
|
* A function used by gtk_list_box_selected_foreach().
|
||||||
|
* It will be called on every selected child of the @list_box.
|
||||||
|
*
|
||||||
|
* Since: 3.14
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_list_box_selected_foreach:
|
||||||
|
* @list_box: a #GtkListBox
|
||||||
|
* @func: (scope call): the function to call for each selected child
|
||||||
|
* @data: user data to pass to the function
|
||||||
|
*
|
||||||
|
* Calls a function for each selected child.
|
||||||
|
*
|
||||||
|
* Note that the selection cannot be modified from within
|
||||||
|
* this function.
|
||||||
|
*
|
||||||
|
* Since: 3.14
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gtk_list_box_selected_foreach (GtkListBox *list_box,
|
||||||
|
GtkListBoxForeachFunc func,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GtkListBoxPrivate *priv = gtk_list_box_get_instance_private (list_box);
|
||||||
|
GtkListBoxRow *row;
|
||||||
|
GSequenceIter *iter;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_LIST_BOX (list_box));
|
||||||
|
|
||||||
|
for (iter = g_sequence_get_begin_iter (priv->children);
|
||||||
|
!g_sequence_iter_is_end (iter);
|
||||||
|
iter = g_sequence_iter_next (iter))
|
||||||
|
{
|
||||||
|
row = g_sequence_get (iter);
|
||||||
|
if (gtk_list_box_row_is_selected (row))
|
||||||
|
(*func) (list_box, row, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_list_box_get_selected_children:
|
||||||
|
* @list_box: a #GtkListBox
|
||||||
|
*
|
||||||
|
* Creates a list of all selected children.
|
||||||
|
*
|
||||||
|
* Returns: (element-type GtkListBoxRow) (transfer container):
|
||||||
|
* A #GList containing the #GtkWidget for each selected child.
|
||||||
|
* Free with g_list_free() when done.
|
||||||
|
*
|
||||||
|
* Since: 3.14
|
||||||
|
*/
|
||||||
|
GList *
|
||||||
|
gtk_list_box_get_selected_children (GtkListBox *list_box)
|
||||||
|
{
|
||||||
|
GtkListBoxPrivate *priv = gtk_list_box_get_instance_private (list_box);
|
||||||
|
GtkListBoxRow *row;
|
||||||
|
GSequenceIter *iter;
|
||||||
|
GList *selected = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GTK_IS_LIST_BOX (list_box), NULL);
|
||||||
|
|
||||||
|
for (iter = g_sequence_get_begin_iter (priv->children);
|
||||||
|
!g_sequence_iter_is_end (iter);
|
||||||
|
iter = g_sequence_iter_next (iter))
|
||||||
|
{
|
||||||
|
row = g_sequence_get (iter);
|
||||||
|
if (gtk_list_box_row_is_selected (row))
|
||||||
|
selected = g_list_prepend (selected, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_list_reverse (selected);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_list_box_set_placeholder:
|
* gtk_list_box_set_placeholder:
|
||||||
@ -1099,8 +1293,10 @@ gtk_list_box_update_selected (GtkListBox *list_box,
|
|||||||
gtk_widget_set_state_flags (GTK_WIDGET (priv->selected_row),
|
gtk_widget_set_state_flags (GTK_WIDGET (priv->selected_row),
|
||||||
GTK_STATE_FLAG_SELECTED,
|
GTK_STATE_FLAG_SELECTED,
|
||||||
FALSE);
|
FALSE);
|
||||||
g_signal_emit (list_box, signals[ROW_SELECTED], 0,
|
|
||||||
priv->selected_row);
|
g_signal_emit (list_box, signals[ROW_SELECTED], 0, priv->selected_row);
|
||||||
|
g_signal_emit (list_box, signals[SELECTED_ROWS_CHANGED], 0);
|
||||||
|
|
||||||
gtk_widget_queue_draw (GTK_WIDGET (list_box));
|
gtk_widget_queue_draw (GTK_WIDGET (list_box));
|
||||||
}
|
}
|
||||||
_gtk_list_box_accessible_selection_changed (list_box);
|
_gtk_list_box_accessible_selection_changed (list_box);
|
||||||
@ -2812,6 +3008,34 @@ gtk_list_box_row_get_index (GtkListBoxRow *row)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_list_box_row_is_selected:
|
||||||
|
* @row: a #GtkListBoxRow
|
||||||
|
*
|
||||||
|
* Returns whether the child is currently selected in its
|
||||||
|
* #GtkListBox container.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if @row is selected
|
||||||
|
*
|
||||||
|
* Since: 3.14
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gtk_list_box_row_is_selected (GtkListBoxRow *row)
|
||||||
|
{
|
||||||
|
GtkListBox *list_box;
|
||||||
|
GtkListBoxPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GTK_IS_LIST_BOX_ROW (row), FALSE);
|
||||||
|
|
||||||
|
list_box = gtk_list_box_row_get_box (row);
|
||||||
|
if (list_box == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
priv = gtk_list_box_get_instance_private (list_box);
|
||||||
|
|
||||||
|
return priv->selected_row == row;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_list_box_row_finalize (GObject *obj)
|
gtk_list_box_row_finalize (GObject *obj)
|
||||||
{
|
{
|
||||||
|
@ -73,6 +73,9 @@ struct _GtkListBoxClass
|
|||||||
void (*move_cursor) (GtkListBox *list_box,
|
void (*move_cursor) (GtkListBox *list_box,
|
||||||
GtkMovementStep step,
|
GtkMovementStep step,
|
||||||
gint count);
|
gint count);
|
||||||
|
void (*selected_rows_changed) (GtkListBox *box);
|
||||||
|
void (*select_all) (GtkListBox *box);
|
||||||
|
void (*unselect_all) (GtkListBox *box);
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
|
|
||||||
@ -80,9 +83,6 @@ struct _GtkListBoxClass
|
|||||||
void (*_gtk_reserved1) (void);
|
void (*_gtk_reserved1) (void);
|
||||||
void (*_gtk_reserved2) (void);
|
void (*_gtk_reserved2) (void);
|
||||||
void (*_gtk_reserved3) (void);
|
void (*_gtk_reserved3) (void);
|
||||||
void (*_gtk_reserved4) (void);
|
|
||||||
void (*_gtk_reserved5) (void);
|
|
||||||
void (*_gtk_reserved6) (void);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GTK_TYPE_LIST_BOX_ROW (gtk_list_box_row_get_type ())
|
#define GTK_TYPE_LIST_BOX_ROW (gtk_list_box_row_get_type ())
|
||||||
@ -180,6 +180,8 @@ gint gtk_list_box_row_get_index (GtkListBoxRow *row);
|
|||||||
GDK_AVAILABLE_IN_3_10
|
GDK_AVAILABLE_IN_3_10
|
||||||
void gtk_list_box_row_changed (GtkListBoxRow *row);
|
void gtk_list_box_row_changed (GtkListBoxRow *row);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_3_14
|
||||||
|
gboolean gtk_list_box_row_is_selected (GtkListBoxRow *row);
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_3_10
|
GDK_AVAILABLE_IN_3_10
|
||||||
GType gtk_list_box_get_type (void) G_GNUC_CONST;
|
GType gtk_list_box_get_type (void) G_GNUC_CONST;
|
||||||
@ -209,6 +211,25 @@ void gtk_list_box_set_adjustment (GtkListBox
|
|||||||
GtkAdjustment *adjustment);
|
GtkAdjustment *adjustment);
|
||||||
GDK_AVAILABLE_IN_3_10
|
GDK_AVAILABLE_IN_3_10
|
||||||
GtkAdjustment *gtk_list_box_get_adjustment (GtkListBox *list_box);
|
GtkAdjustment *gtk_list_box_get_adjustment (GtkListBox *list_box);
|
||||||
|
|
||||||
|
typedef void (* GtkListBoxForeachFunc) (GtkListBox *box,
|
||||||
|
GtkListBoxRow *row,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_3_14
|
||||||
|
void gtk_list_box_selected_foreach (GtkListBox *list_box,
|
||||||
|
GtkListBoxForeachFunc func,
|
||||||
|
gpointer data);
|
||||||
|
GDK_AVAILABLE_IN_3_14
|
||||||
|
GList *gtk_list_box_get_selected_rows (GtkListBox *list_box);
|
||||||
|
GDK_AVAILABLE_IN_3_14
|
||||||
|
void gtk_list_box_unselect_row (GtkListBox *list_box,
|
||||||
|
GtkListBoxRow *row);
|
||||||
|
GDK_AVAILABLE_IN_3_14
|
||||||
|
void gtk_list_box_select_all (GtkListBox *list_box);
|
||||||
|
GDK_AVAILABLE_IN_3_14
|
||||||
|
void gtk_list_box_unselect_all (GtkListBox *list_box);
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_3_10
|
GDK_AVAILABLE_IN_3_10
|
||||||
void gtk_list_box_set_selection_mode (GtkListBox *list_box,
|
void gtk_list_box_set_selection_mode (GtkListBox *list_box,
|
||||||
GtkSelectionMode mode);
|
GtkSelectionMode mode);
|
||||||
@ -249,6 +270,7 @@ GDK_AVAILABLE_IN_3_10
|
|||||||
GtkWidget* gtk_list_box_new (void);
|
GtkWidget* gtk_list_box_new (void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user