#include "nautilus-view-icon-item-ui.h" #include "nautilus-view-item-model.h" #include "nautilus-container-max-width.h" #include "nautilus-file.h" #include "nautilus-thumbnails.h" struct _NautilusViewIconItemUi { GtkFlowBoxChild parent_instance; NautilusViewItemModel *model; NautilusContainerMaxWidth *item_container; GtkWidget *icon; GtkLabel *label; }; G_DEFINE_TYPE (NautilusViewIconItemUi, nautilus_view_icon_item_ui, GTK_TYPE_FLOW_BOX_CHILD) enum { PROP_0, PROP_MODEL, N_PROPS }; static GtkWidget * create_icon (NautilusViewIconItemUi *self) { NautilusFileIconFlags flags; g_autoptr (GdkPixbuf) icon_pixbuf = NULL; GtkImage *icon; GtkBox *fixed_height_box; GtkStyleContext *style_context; NautilusFile *file; guint icon_size; file = nautilus_view_item_model_get_file (self->model); icon_size = nautilus_view_item_model_get_icon_size (self->model); flags = NAUTILUS_FILE_ICON_FLAGS_USE_THUMBNAILS | NAUTILUS_FILE_ICON_FLAGS_FORCE_THUMBNAIL_SIZE | NAUTILUS_FILE_ICON_FLAGS_USE_EMBLEMS | NAUTILUS_FILE_ICON_FLAGS_USE_ONE_EMBLEM; icon_pixbuf = nautilus_file_get_icon_pixbuf (file, icon_size, TRUE, 1, flags); icon = GTK_IMAGE (gtk_image_new_from_pixbuf (icon_pixbuf)); gtk_widget_set_hexpand (GTK_WIDGET (icon), TRUE); gtk_widget_set_vexpand (GTK_WIDGET (icon), TRUE); gtk_widget_set_valign (GTK_WIDGET (icon), GTK_ALIGN_CENTER); gtk_widget_set_halign (GTK_WIDGET (icon), GTK_ALIGN_CENTER); fixed_height_box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 0)); gtk_widget_set_valign (GTK_WIDGET (fixed_height_box), GTK_ALIGN_CENTER); gtk_widget_set_halign (GTK_WIDGET (fixed_height_box), GTK_ALIGN_CENTER); gtk_widget_set_size_request (GTK_WIDGET (fixed_height_box), icon_size, icon_size); if (nautilus_can_thumbnail (file) && nautilus_file_should_show_thumbnail (file)) { style_context = gtk_widget_get_style_context (GTK_WIDGET (fixed_height_box)); gtk_style_context_add_class (style_context, "icon-background"); } gtk_box_pack_start (fixed_height_box, GTK_WIDGET (icon), FALSE, FALSE, 0); return GTK_WIDGET (fixed_height_box); } static void update_icon (NautilusViewIconItemUi *self) { GtkBox *box; guint icon_size; icon_size = nautilus_view_item_model_get_icon_size (self->model); nautilus_container_max_width_set_max_width (NAUTILUS_CONTAINER_MAX_WIDTH (self->item_container), icon_size); box = GTK_BOX (gtk_bin_get_child (GTK_BIN (self->item_container))); if (self->icon) { gtk_container_remove (GTK_CONTAINER (box), GTK_WIDGET (self->icon)); } self->icon = create_icon (self); gtk_widget_show_all (GTK_WIDGET (self->icon)); gtk_box_pack_start (box, GTK_WIDGET (self->icon), FALSE, FALSE, 0); } static void on_view_item_file_changed (GObject *object, GParamSpec *pspec, gpointer user_data) { NautilusViewIconItemUi *self = NAUTILUS_VIEW_ICON_ITEM_UI (user_data); NautilusFile *file; file = nautilus_view_item_model_get_file (self->model); if (self->icon) { update_icon (self); } if (self->label) { gtk_label_set_text (self->label, nautilus_file_get_display_name (file)); } } static void on_view_item_size_changed (GObject *object, GParamSpec *pspec, gpointer user_data) { NautilusViewIconItemUi *self = NAUTILUS_VIEW_ICON_ITEM_UI (user_data); if (self->icon) { update_icon (self); } } static void constructed (GObject *object) { NautilusViewIconItemUi *self = NAUTILUS_VIEW_ICON_ITEM_UI (object); GtkBox *container; GtkBox *item_selection_background; GtkLabel *label; GtkStyleContext *style_context; NautilusFile *file; guint icon_size; G_OBJECT_CLASS (nautilus_view_icon_item_ui_parent_class)->constructed (object); file = nautilus_view_item_model_get_file (self->model); icon_size = nautilus_view_item_model_get_icon_size (self->model); container = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 0)); /* This container is for having a constant selection background, instead of * the dinamically sized one of the GtkFlowBox */ item_selection_background = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 0)); gtk_widget_set_halign (GTK_WIDGET (item_selection_background), GTK_ALIGN_CENTER); gtk_widget_set_valign (GTK_WIDGET (item_selection_background), GTK_ALIGN_START); self->item_container = nautilus_container_max_width_new (); self->icon = create_icon (self); gtk_box_pack_start (container, GTK_WIDGET (self->icon), FALSE, FALSE, 0); label = GTK_LABEL (gtk_label_new (nautilus_file_get_display_name (file))); gtk_widget_show (GTK_WIDGET (label)); #if PANGO_VERSION_CHECK (1, 44, 4) { PangoAttrList *attr_list = pango_attr_list_new (); pango_attr_list_insert (attr_list, pango_attr_insert_hyphens_new (FALSE)); gtk_label_set_attributes (label, attr_list); pango_attr_list_unref (attr_list); } #endif gtk_label_set_ellipsize (label, PANGO_ELLIPSIZE_MIDDLE); gtk_label_set_line_wrap (label, TRUE); gtk_label_set_line_wrap_mode (label, PANGO_WRAP_WORD_CHAR); gtk_label_set_lines (label, 3); gtk_label_set_justify (label, GTK_JUSTIFY_CENTER); gtk_widget_set_valign (GTK_WIDGET (label), GTK_ALIGN_START); gtk_box_pack_end (container, GTK_WIDGET (label), TRUE, TRUE, 0); style_context = gtk_widget_get_style_context (GTK_WIDGET (item_selection_background)); gtk_style_context_add_class (style_context, "icon-item-background"); gtk_widget_set_valign (GTK_WIDGET (container), GTK_ALIGN_START); gtk_widget_set_halign (GTK_WIDGET (container), GTK_ALIGN_CENTER); gtk_container_add (GTK_CONTAINER (self->item_container), GTK_WIDGET (container)); nautilus_container_max_width_set_max_width (NAUTILUS_CONTAINER_MAX_WIDTH (self->item_container), icon_size); gtk_container_add (GTK_CONTAINER (item_selection_background), GTK_WIDGET (self->item_container)); gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (item_selection_background)); gtk_widget_show_all (GTK_WIDGET (self)); g_signal_connect (self->model, "notify::icon-size", (GCallback) on_view_item_size_changed, self); g_signal_connect (self->model, "notify::file", (GCallback) on_view_item_file_changed, self); } static void finalize (GObject *object) { NautilusViewIconItemUi *self = (NautilusViewIconItemUi *) object; g_signal_handlers_disconnect_by_data (self->model, self); G_OBJECT_CLASS (nautilus_view_icon_item_ui_parent_class)->finalize (object); } static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NautilusViewIconItemUi *self = NAUTILUS_VIEW_ICON_ITEM_UI (object); switch (prop_id) { case PROP_MODEL: { g_value_set_object (value, self->model); } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void set_model (NautilusViewIconItemUi *self, NautilusViewItemModel *model) { self->model = g_object_ref (model); } static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NautilusViewIconItemUi *self = NAUTILUS_VIEW_ICON_ITEM_UI (object); switch (prop_id) { case PROP_MODEL: { set_model (self, g_value_get_object (value)); } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void nautilus_view_icon_item_ui_class_init (NautilusViewIconItemUiClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = finalize; object_class->get_property = get_property; object_class->set_property = set_property; object_class->constructed = constructed; g_object_class_install_property (object_class, PROP_MODEL, g_param_spec_object ("model", "Item model", "The item model that this UI reprensents", NAUTILUS_TYPE_VIEW_ITEM_MODEL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } static void nautilus_view_icon_item_ui_init (NautilusViewIconItemUi *self) { } NautilusViewIconItemUi * nautilus_view_icon_item_ui_new (NautilusViewItemModel *model) { return g_object_new (NAUTILUS_TYPE_VIEW_ICON_ITEM_UI, "model", model, NULL); } NautilusViewItemModel * nautilus_view_icon_item_ui_get_model (NautilusViewIconItemUi *self) { return self->model; }