selectionmodel: Add gtk_selection_model_user_select_item()

I'm not sure this should be public API because it's incredibly awkward.
But it should definitely be shared between list widget implementations.
This commit is contained in:
Benjamin Otte
2019-10-19 21:29:52 +02:00
committed by Matthias Clasen
parent 1b105cdbef
commit cb2948eda6
4 changed files with 99 additions and 55 deletions

View File

@@ -352,6 +352,8 @@ gtk_selection_model_select_all
gtk_selection_model_unselect_all
gtk_selection_model_query_range
<SUBSECTION>
gtk_selection_model_user_select_item
<SUBSECTION>
gtk_selection_model_selection_changed
<SUBSECTION Standard>
GTK_SELECTION_MODEL

View File

@@ -616,61 +616,11 @@ gtk_list_view_select_item (GtkListView *self,
gboolean modify,
gboolean extend)
{
GtkSelectionModel *selection_model;
gboolean success = FALSE;
selection_model = gtk_list_item_manager_get_model (self->item_manager);
if (extend)
{
guint start_pos = gtk_list_item_tracker_get_position (self->item_manager, self->selected);
if (start_pos != GTK_INVALID_LIST_POSITION)
{
guint max = MAX (start_pos, pos);
guint min = MIN (start_pos, pos);
if (modify)
{
if (gtk_selection_model_is_selected (selection_model, start_pos))
{
success = gtk_selection_model_select_range (selection_model,
min,
max - min + 1,
FALSE);
}
else
{
success = gtk_selection_model_unselect_range (selection_model,
min,
max - min + 1);
}
}
else
{
success = gtk_selection_model_select_range (selection_model,
min,
max - min + 1,
TRUE);
}
}
/* If there's no range to select or selecting ranges isn't supported
* by the model, fall through to normal setting.
*/
}
if (success)
return;
if (modify)
{
if (gtk_selection_model_is_selected (selection_model, pos))
success = gtk_selection_model_unselect_item (selection_model, pos);
else
success = gtk_selection_model_select_item (selection_model, pos, FALSE);
}
else
{
success = gtk_selection_model_select_item (selection_model, pos, TRUE);
}
if (success)
if (gtk_selection_model_user_select_item (gtk_list_item_manager_get_model (self->item_manager),
pos,
modify,
extend ? gtk_list_item_tracker_get_position (self->item_manager, self->selected)
: GTK_INVALID_LIST_POSITION))
{
gtk_list_item_tracker_set_position (self->item_manager,
self->selected,

View File

@@ -382,3 +382,90 @@ gtk_selection_model_selection_changed (GtkSelectionModel *model,
g_signal_emit (model, signals[SELECTION_CHANGED], 0, position, n_items);
}
/**
* gtk_selection_model_user_select_item:
* @self: a #GtkSelectionModel
* @pos: position selected by the user. If this position is invalid
* no selection will be done.
* @modify: %TRUE if the selection should be modified, %FALSE
* if a new selection should be done. This is usually set
* to %TRUE if the user keeps the <Shift> key pressed.
* @extend_pos: the position to extend the selection from or
* an invalid position like #GTK_INVALID_LIST_POSITION to not
* extend the selection. Selections are usually extended
* from the last selected position if the user presses the
* <Ctrl> key. The last selected position is stored by the
* widget
*
* Does a selection according to how GTK list widgets modify
* selections, both when clicking rows with the mouse or when using
* the keyboard.
*
* Returns: %TRUE if the last selected position for further calls
* to this function should be updated to @pos, %FALSE if the
* last selected position should not change.
**/
gboolean
gtk_selection_model_user_select_item (GtkSelectionModel *self,
guint pos,
gboolean modify,
guint extend_pos)
{
gboolean success = FALSE;
guint n_items;
g_return_val_if_fail (GTK_IS_SELECTION_MODEL (self), FALSE);
n_items = g_list_model_get_n_items (G_LIST_MODEL (self));
if (pos >= n_items)
return FALSE;
if (extend_pos < n_items)
{
guint max = MAX (extend_pos, pos);
guint min = MIN (extend_pos, pos);
if (modify)
{
if (gtk_selection_model_is_selected (self, extend_pos))
{
success = gtk_selection_model_select_range (self,
min,
max - min + 1,
FALSE);
}
else
{
success = gtk_selection_model_unselect_range (self,
min,
max - min + 1);
}
}
else
{
success = gtk_selection_model_select_range (self,
min,
max - min + 1,
TRUE);
}
/* If there's no range to select or selecting ranges isn't supported
* by the model, fall through to normal setting.
*/
}
if (success)
return FALSE;
if (modify)
{
if (gtk_selection_model_is_selected (self, pos))
success = gtk_selection_model_unselect_item (self, pos);
else
success = gtk_selection_model_select_item (self, pos, FALSE);
}
else
{
success = gtk_selection_model_select_item (self, pos, TRUE);
}
return success;
}

View File

@@ -118,6 +118,11 @@ void gtk_selection_model_query_range (GtkSelectionMod
guint *n_items,
gboolean *selected);
GDK_AVAILABLE_IN_ALL
gboolean gtk_selection_model_user_select_item (GtkSelectionModel *self,
guint pos,
gboolean modify,
guint extend_pos);
/* for implementations only */
GDK_AVAILABLE_IN_ALL
void gtk_selection_model_selection_changed (GtkSelectionModel *model,