nautilus-view-icon: Rework selection and loading

Better performance, code design and fixes some issues.
parent 8eaea908
......@@ -250,7 +250,7 @@ real_clear (NautilusFilesView *files_view)
{
NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
g_list_store_remove_all (nautilus_view_model_get_g_model (self->model));
nautilus_view_model_remove_all_items (self->model);
}
......@@ -279,13 +279,17 @@ real_get_selection (NautilusFilesView *files_view)
NautilusViewIconController *self;
GList *selected_files = NULL;
GList *l;
g_autoptr (GQueue) selected_items = NULL;
g_autoptr (GList) selected_items = NULL;
self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
selected_items = nautilus_view_model_get_selected (self->model);
for (l = g_queue_peek_head_link (selected_items); l != NULL; l = l->next)
selected_items = gtk_flow_box_get_selected_children (GTK_FLOW_BOX (self->view_ui));
for (l = selected_items; l != NULL; l = l->next)
{
selected_files = g_list_prepend (selected_files, l->data);
NautilusViewItemModel *item_model;
item_model = nautilus_view_icon_item_ui_get_model (NAUTILUS_VIEW_ICON_ITEM_UI (l->data));
selected_files = g_list_prepend (selected_files,
g_object_ref (nautilus_view_item_model_get_file (item_model)));
}
return selected_files;
......@@ -378,7 +382,7 @@ real_set_selection (NautilusFilesView *files_view,
selection_files = convert_glist_to_queue (selection);
selection_item_models = nautilus_view_model_get_items_from_files (self->model, selection_files);
nautilus_view_model_set_selected (self->model, selection_item_models);
nautilus_view_icon_ui_set_selection (self->view_ui, selection_item_models);
nautilus_files_view_notify_selection_changed (files_view);
}
......@@ -603,27 +607,53 @@ on_button_press_event (GtkWidget *widget,
gpointer user_data)
{
NautilusViewIconController *self;
GList *selection;
g_autoptr (GList) selection = NULL;
GtkWidget *child_at_pos;
NautilusViewItemModel *item_model;
GdkEventButton *event_button;
self = NAUTILUS_VIEW_ICON_CONTROLLER (user_data);
event_button = (GdkEventButton *) event;
if ((event_button->button == GDK_BUTTON_SECONDARY))
/* Need to update the selection so the popup has the right actions enabled */
selection = nautilus_view_get_selection (NAUTILUS_VIEW (self));
child_at_pos = GTK_WIDGET (gtk_flow_box_get_child_at_pos (GTK_FLOW_BOX (self->view_ui),
event_button->x, event_button->y));
if (child_at_pos != NULL)
{
/* Need to update the selection so the popup has the right actions enabled */
selection = nautilus_view_get_selection (NAUTILUS_VIEW (self));
child_at_pos = GTK_WIDGET (gtk_flow_box_get_child_at_pos (GTK_FLOW_BOX (self->view_ui),
event_button->x, event_button->y));
NautilusFile *selected_file;
NautilusViewItemModel *item_model;
item_model = nautilus_view_icon_item_ui_get_model (NAUTILUS_VIEW_ICON_ITEM_UI (child_at_pos));
selection = g_list_prepend (selection, nautilus_view_item_model_get_file (item_model));
selected_file = nautilus_view_item_model_get_file (item_model);
if (g_list_find (selection, selected_file) == NULL)
{
g_list_foreach (selection, (GFunc) g_object_unref, NULL);
selection = g_list_append (NULL, selected_file);
}
else
{
selection = g_list_prepend (selection, g_object_ref (selected_file));
}
nautilus_view_set_selection (NAUTILUS_VIEW (self), selection);
nautilus_files_view_pop_up_selection_context_menu (NAUTILUS_FILES_VIEW (self),
event_button);
if (event_button->button == GDK_BUTTON_SECONDARY)
{
nautilus_files_view_pop_up_selection_context_menu (NAUTILUS_FILES_VIEW (self),
event_button);
}
}
else
{
nautilus_view_set_selection (NAUTILUS_VIEW (self), NULL);
if (event_button->button == GDK_BUTTON_SECONDARY)
{
nautilus_files_view_pop_up_background_context_menu (NAUTILUS_FILES_VIEW (self),
event_button);
}
}
g_list_foreach (selection, (GFunc) g_object_unref, NULL);
return GDK_EVENT_STOP;
}
......@@ -727,7 +757,7 @@ real_add_files (NautilusFilesView *files_view,
files_queue = convert_glist_to_queue (files);
item_models = convert_files_to_item_models (self, files_queue);
nautilus_view_model_set_items (self->model, item_models);
nautilus_view_model_add_items (self->model, item_models);
}
......
......@@ -98,25 +98,34 @@ set_property (GObject *object,
}
}
static void
on_view_item_model_selected_changed (GObject *object,
GParamSpec *pspec,
gpointer user_data)
void
nautilus_view_icon_ui_set_selection (NautilusViewIconUi *self,
GQueue *selection)
{
NautilusViewIconUi *self;
NautilusViewItemModel *item_model;
GtkFlowBoxChild *item_ui;
NautilusViewModel *model;
GListStore *gmodel;
gint i = 0;
self = NAUTILUS_VIEW_ICON_UI (user_data);
item_model = NAUTILUS_VIEW_ITEM_MODEL (object);
item_ui = GTK_FLOW_BOX_CHILD (nautilus_view_item_model_get_item_ui (item_model));
if (nautilus_view_item_model_get_is_selected (item_model) && !gtk_flow_box_child_is_selected (item_ui))
{
gtk_flow_box_select_child (GTK_FLOW_BOX (self), item_ui);
}
else if (!nautilus_view_item_model_get_is_selected (item_model) && gtk_flow_box_child_is_selected (item_ui))
model = nautilus_view_icon_controller_get_model (self->controller);
gmodel = nautilus_view_model_get_g_model (model);
while ((item_model = NAUTILUS_VIEW_ITEM_MODEL (g_list_model_get_item (G_LIST_MODEL (gmodel), i))))
{
gtk_flow_box_unselect_child (GTK_FLOW_BOX (self), item_ui);
GtkWidget *item_ui;
item_ui = nautilus_view_item_model_get_item_ui (item_model);
if (g_queue_find (selection, item_model) != NULL)
{
gtk_flow_box_select_child (GTK_FLOW_BOX (self),
GTK_FLOW_BOX_CHILD (item_ui));
}
else
{
gtk_flow_box_unselect_child (GTK_FLOW_BOX (self),
GTK_FLOW_BOX_CHILD (item_ui));
}
i++;
}
}
......@@ -125,7 +134,6 @@ static GtkWidget *
create_widget_func (gpointer item,
gpointer user_data)
{
NautilusViewIconUi *self = NAUTILUS_VIEW_ICON_UI (user_data);
NautilusViewItemModel *item_model = NAUTILUS_VIEW_ITEM_MODEL (item);
NautilusViewIconItemUi *child;
......@@ -133,9 +141,6 @@ create_widget_func (gpointer item,
nautilus_view_item_model_set_item_ui (item_model, GTK_WIDGET (child));
gtk_widget_show (GTK_WIDGET (child));
g_signal_connect (item_model, "notify::selected",
(GCallback) on_view_item_model_selected_changed, self);
return GTK_WIDGET (child);
}
......@@ -161,25 +166,9 @@ on_ui_selected_children_changed (GtkFlowBox *box,
gpointer user_data)
{
NautilusViewIconUi *self;
GList *selected_children_ui;
GList *l;
GList *files_selection;
self = NAUTILUS_VIEW_ICON_UI (user_data);
files_selection = NULL;
selected_children_ui = gtk_flow_box_get_selected_children (GTK_FLOW_BOX (self));
for (l = selected_children_ui; l != NULL; l = l->next)
{
NautilusViewItemModel *item_model;
NautilusFile *file;
item_model = nautilus_view_icon_item_ui_get_model (NAUTILUS_VIEW_ICON_ITEM_UI (l->data));
file = nautilus_view_item_model_get_file (item_model);
files_selection = g_list_prepend (files_selection, file);
}
nautilus_view_set_selection (NAUTILUS_VIEW (self->controller), files_selection);
nautilus_files_view_notify_selection_changed (NAUTILUS_FILES_VIEW (self->controller));
}
static void
......
......@@ -30,6 +30,10 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (NautilusViewIconUi, nautilus_view_icon_ui, NAUTILUS, VIEW_ICON_UI, GtkFlowBox)
NautilusViewIconUi * nautilus_view_icon_ui_new (NautilusViewIconController *controller);
/* TODO: this should become the "nautilus_view_set_selection" once we have a proper
* MVC also in the nautilus-view level. */
void nautilus_view_icon_ui_set_selection (NautilusViewIconUi *self,
GQueue *selection);
G_END_DECLS
......
......@@ -7,7 +7,6 @@ struct _NautilusViewItemModel
guint icon_size;
NautilusFile *file;
GtkLabel *label;
gboolean selected;
GtkWidget *item_ui;
};
......@@ -18,7 +17,6 @@ enum
PROP_0,
PROP_FILE,
PROP_ICON_SIZE,
PROP_SELECTED,
PROP_ITEM_UI,
N_PROPS
};
......@@ -51,12 +49,6 @@ nautilus_view_item_model_get_property (GObject *object,
}
break;
case PROP_SELECTED:
{
g_value_set_boolean (value, self->selected);
}
break;
case PROP_ITEM_UI:
{
g_value_set_object (value, self->item_ui);
......@@ -92,12 +84,6 @@ nautilus_view_item_model_set_property (GObject *object,
}
break;
case PROP_SELECTED:
{
nautilus_view_item_model_set_selected (self, g_value_get_boolean (value));
}
break;
case PROP_ITEM_UI:
{
nautilus_view_item_model_set_item_ui (self, g_value_get_object (value));
......@@ -141,13 +127,6 @@ nautilus_view_item_model_class_init (NautilusViewItemModelClass *klass)
"The file the icon item represents",
NAUTILUS_TYPE_FILE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class,
PROP_SELECTED,
g_param_spec_boolean ("selected",
"Selected",
"Sets the item as selected",
FALSE,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_ITEM_UI,
......@@ -207,27 +186,6 @@ nautilus_view_item_model_set_file (NautilusViewItemModel *self,
g_object_notify (G_OBJECT (self), "file");
}
gboolean
nautilus_view_item_model_get_is_selected (NautilusViewItemModel *self)
{
g_return_val_if_fail (NAUTILUS_IS_VIEW_ITEM_MODEL (self), FALSE);
return self->selected;
}
void
nautilus_view_item_model_set_selected (NautilusViewItemModel *self,
gboolean selected)
{
g_return_if_fail (NAUTILUS_IS_VIEW_ITEM_MODEL (self));
if (self->selected != !!selected)
{
self->selected = !!selected;
g_object_notify (G_OBJECT (self), "selected");
}
}
GtkWidget *
nautilus_view_item_model_get_item_ui (NautilusViewItemModel *self)
{
......
......@@ -25,11 +25,6 @@ void nautilus_view_item_model_set_file (NautilusViewItemModel *self,
NautilusFile * nautilus_view_item_model_get_file (NautilusViewItemModel *self);
void nautilus_view_item_model_set_selected (NautilusViewItemModel *self,
gboolean selected);
gboolean nautilus_view_item_model_get_is_selected (NautilusViewItemModel *self);
void nautilus_view_item_model_set_item_ui (NautilusViewItemModel *self,
GtkWidget *item_ui);
......
......@@ -233,67 +233,57 @@ nautilus_view_model_remove_item (NautilusViewModel *self,
if (item_model != NULL)
{
NautilusFile *file;
file = nautilus_view_item_model_get_file (item_model);
g_list_store_remove (self->internal_model, i);
g_hash_table_remove (self->map_files_to_model, file);
}
}
void
nautilus_view_model_remove_all_items (NautilusViewModel *self)
{
g_list_store_remove_all (self->internal_model);
g_hash_table_remove_all (self->map_files_to_model);
}
void
nautilus_view_model_add_item (NautilusViewModel *self,
NautilusViewItemModel *item)
{
g_hash_table_insert (self->map_files_to_model,
nautilus_view_item_model_get_file (item),
item);
g_list_store_insert_sorted (self->internal_model, item, compare_data_func, self);
}
void
nautilus_view_model_set_selected (NautilusViewModel *self,
GQueue *item_models)
nautilus_view_model_add_items (NautilusViewModel *self,
GQueue *items)
{
g_autofree gpointer *array = NULL;
GList *l;
NautilusViewItemModel *item_model;
gint i = 0;
while ((item_model = g_list_model_get_item (G_LIST_MODEL (self->internal_model), i)))
{
gboolean selected;
selected = FALSE;
for (l = g_queue_peek_head_link (item_models); l != NULL; l = l->next)
{
NautilusViewItemModel *selected_item_model;
selected_item_model = NAUTILUS_VIEW_ITEM_MODEL (l->data);
if (item_model == selected_item_model)
{
selected = TRUE;
break;
}
}
i++;
nautilus_view_item_model_set_selected (item_model, selected);
}
}
int i = 0;
GQueue *
nautilus_view_model_get_selected (NautilusViewModel *self)
{
NautilusViewItemModel *item_model;
GQueue *selected_items;
gint i;
array = g_malloc_n (g_queue_get_length (items),
sizeof (NautilusViewItemModel *));
i = 0;
selected_items = g_queue_new ();
while ((item_model = g_list_model_get_item (G_LIST_MODEL (self->internal_model), i)))
g_hash_table_remove_all (self->map_files_to_model);
for (l = g_queue_peek_head_link (items); l != NULL; l = l->next)
{
if (nautilus_view_item_model_get_is_selected (item_model))
{
g_queue_push_tail (selected_items,
g_object_ref (nautilus_view_item_model_get_file (item_model)));
}
array[i] = l->data;
g_hash_table_insert (self->map_files_to_model,
nautilus_view_item_model_get_file (l->data),
l->data);
i++;
}
return selected_items;
g_list_store_splice (self->internal_model,
g_list_model_get_n_items (G_LIST_MODEL (self->internal_model)),
0, array, g_queue_get_length (items));
g_list_store_sort (self->internal_model, compare_data_func, self);
}
void
......@@ -318,8 +308,8 @@ nautilus_view_model_set_items (NautilusViewModel *self,
}
g_list_store_splice (self->internal_model,
g_list_model_get_n_items (G_LIST_MODEL (self->internal_model)),
0, array, g_queue_get_length (items));
0, g_list_model_get_n_items (G_LIST_MODEL (self->internal_model)),
array, g_queue_get_length (items));
g_list_store_sort (self->internal_model, compare_data_func, self);
}
......@@ -28,13 +28,15 @@ NautilusViewItemModel * nautilus_view_model_get_item_from_file (NautilusViewMode
NautilusFile *file);
GQueue * nautilus_view_model_get_items_from_files (NautilusViewModel *self,
GQueue *files);
/* Don't use inside a loop, use nautilus_view_model_remove_all_items instead. */
void nautilus_view_model_remove_item (NautilusViewModel *self,
NautilusViewItemModel *item);
void nautilus_view_model_remove_all_items (NautilusViewModel *self);
/* Don't use inside a loop, use nautilus_view_model_add_items instead. */
void nautilus_view_model_add_item (NautilusViewModel *self,
NautilusViewItemModel *item);
void nautilus_view_model_set_selected (NautilusViewModel *self,
GQueue *item_models);
GQueue * nautilus_view_model_get_selected (NautilusViewModel *self);
void nautilus_view_model_add_items (NautilusViewModel *self,
GQueue *items);
void nautilus_view_model_set_items (NautilusViewModel *self,
GQueue *items);
G_END_DECLS
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment