diff options
author | Carlos Soriano <csoriano@gnome.org> | 2017-03-10 14:10:45 +0100 |
---|---|---|
committer | Carlos Soriano <csoriano@gnome.org> | 2017-03-10 15:26:15 +0100 |
commit | 1a1e367fd0a098e97f542b63e7361ba68a9166da (patch) | |
tree | afef01fedd5f71dc41f5e856a0ecc4d81161abba | |
parent | 8eaea9080fdd6adc1597d54d65c0ddb1e01973ed (diff) | |
download | nautilus-1a1e367fd0a098e97f542b63e7361ba68a9166da.tar.gz |
nautilus-view-icon: Rework selection and loading
Better performance, code design and fixes some issues.
-rw-r--r-- | src/nautilus-view-icon-controller.c | 64 | ||||
-rw-r--r-- | src/nautilus-view-icon-ui.c | 61 | ||||
-rw-r--r-- | src/nautilus-view-icon-ui.h | 4 | ||||
-rw-r--r-- | src/nautilus-view-item-model.c | 42 | ||||
-rw-r--r-- | src/nautilus-view-item-model.h | 5 | ||||
-rw-r--r-- | src/nautilus-view-model.c | 76 | ||||
-rw-r--r-- | src/nautilus-view-model.h | 8 |
7 files changed, 114 insertions, 146 deletions
diff --git a/src/nautilus-view-icon-controller.c b/src/nautilus-view-icon-controller.c index 507eb9464..9c32a1893 100644 --- a/src/nautilus-view-icon-controller.c +++ b/src/nautilus-view-icon-controller.c @@ -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); } diff --git a/src/nautilus-view-icon-ui.c b/src/nautilus-view-icon-ui.c index 6df82a7ba..1f2639f4a 100644 --- a/src/nautilus-view-icon-ui.c +++ b/src/nautilus-view-icon-ui.c @@ -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 diff --git a/src/nautilus-view-icon-ui.h b/src/nautilus-view-icon-ui.h index 5361acc17..e8832759a 100644 --- a/src/nautilus-view-icon-ui.h +++ b/src/nautilus-view-icon-ui.h @@ -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 diff --git a/src/nautilus-view-item-model.c b/src/nautilus-view-item-model.c index 970fb284a..e50f2d800 100644 --- a/src/nautilus-view-item-model.c +++ b/src/nautilus-view-item-model.c @@ -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) { diff --git a/src/nautilus-view-item-model.h b/src/nautilus-view-item-model.h index 39a8bc0dd..16870de7a 100644 --- a/src/nautilus-view-item-model.h +++ b/src/nautilus-view-item-model.h @@ -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); diff --git a/src/nautilus-view-model.c b/src/nautilus-view-model.c index 2f054e5e2..f45ecef96 100644 --- a/src/nautilus-view-model.c +++ b/src/nautilus-view-model.c @@ -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); } diff --git a/src/nautilus-view-model.h b/src/nautilus-view-model.h index 9734032ed..5e64d842e 100644 --- a/src/nautilus-view-model.h +++ b/src/nautilus-view-model.h @@ -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 |