From e80da806022d8aaa32f77f3c7f0333cc1c80829b Mon Sep 17 00:00:00 2001 From: fiaxh Date: Tue, 17 Apr 2018 21:46:48 +0200 Subject: Add image preview to file choosers Co-authored-by: Thibaut Girka --- main/CMakeLists.txt | 1 + main/src/ui/conversation_titlebar/file_entry.vala | 8 ++- main/src/ui/manage_accounts/dialog.vala | 6 +- main/src/ui/util/preview_file_chooser_native.vala | 82 +++++++++++++++++++++++ 4 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 main/src/ui/util/preview_file_chooser_native.vala (limited to 'main') diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 58e1ab7d..689610a7 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -127,6 +127,7 @@ SOURCES src/ui/util/accounts_combo_box.vala src/ui/util/helper.vala src/ui/util/label_hybrid.vala + src/ui/util/preview_file_chooser_native.vala CUSTOM_VAPIS ${CMAKE_BINARY_DIR}/exports/xmpp-vala.vapi ${CMAKE_BINARY_DIR}/exports/qlite.vapi diff --git a/main/src/ui/conversation_titlebar/file_entry.vala b/main/src/ui/conversation_titlebar/file_entry.vala index 0f0eb6d6..fb6ac3a0 100644 --- a/main/src/ui/conversation_titlebar/file_entry.vala +++ b/main/src/ui/conversation_titlebar/file_entry.vala @@ -24,6 +24,9 @@ public class FileEntry : Plugins.ConversationTitlebarEntry, Object { public class FileWidget : Button, Plugins.ConversationTitlebarWidget { + private const int PREVIEW_SIZE = 180; + private const int PREVIEW_PADDING = 3; + private Conversation? conversation; private StreamInteractor stream_interactor; @@ -35,9 +38,8 @@ public class FileWidget : Button, Plugins.ConversationTitlebarWidget { } public void on_clicked() { - FileChooserNative chooser = new FileChooserNative ( - "Select file", get_toplevel() as Window, FileChooserAction.OPEN, - "Select", "Cancel"); + PreviewFileChooserNative chooser = new PreviewFileChooserNative("Select file", get_toplevel() as Window, FileChooserAction.OPEN, "Select", "Cancel"); + // long max_file_size = stream_interactor.get_module(Manager.IDENTITY).get_max_file_size(conversation.account); // if (max_file_size != -1) { // FileFilter filter = new FileFilter(); diff --git a/main/src/ui/manage_accounts/dialog.vala b/main/src/ui/manage_accounts/dialog.vala index 8f2b76a7..5706fc8c 100644 --- a/main/src/ui/manage_accounts/dialog.vala +++ b/main/src/ui/manage_accounts/dialog.vala @@ -150,9 +150,7 @@ public class Dialog : Gtk.Dialog { } private void show_select_avatar() { - FileChooserNative chooser = new FileChooserNative ( - _("Select avatar"), this, FileChooserAction.OPEN, - _("Select"), _("Cancel")); + PreviewFileChooserNative chooser = new PreviewFileChooserNative(_("Select avatar"), this, FileChooserAction.OPEN, _("Select"), _("Cancel")); FileFilter filter = new FileFilter(); filter.add_pattern("*.png"); filter.add_pattern("*.jpg"); @@ -162,10 +160,12 @@ public class Dialog : Gtk.Dialog { filter.add_pattern("*.bmp"); filter.set_filter_name(_("Images")); chooser.add_filter(filter); + filter = new FileFilter(); filter.set_filter_name(_("All files")); filter.add_pattern("*"); chooser.add_filter(filter); + if (chooser.run() == Gtk.ResponseType.ACCEPT) { string uri = chooser.get_filename(); stream_interactor.get_module(AvatarManager.IDENTITY).publish(selected_account, uri); diff --git a/main/src/ui/util/preview_file_chooser_native.vala b/main/src/ui/util/preview_file_chooser_native.vala new file mode 100644 index 00000000..6473cde1 --- /dev/null +++ b/main/src/ui/util/preview_file_chooser_native.vala @@ -0,0 +1,82 @@ +using Gdk; +using Gtk; + +using Dino.Entities; + +namespace Dino.Ui { + +public class PreviewFileChooserNative : Object { + private const int PREVIEW_SIZE = 180; + private const int PREVIEW_PADDING = 5; + + private Gtk.FileChooserNative? chooser = null; + private Image preview_image = new Image(); + + public PreviewFileChooserNative(string? title, Gtk.Window? parent, FileChooserAction action, string? accept_label, string? cancel_label) { + chooser = new FileChooserNative(title, parent, action, accept_label, cancel_label); + + chooser.set_preview_widget(this.preview_image); + chooser.use_preview_label = false; + chooser.preview_widget_active = false; + + chooser.update_preview.connect(on_update_preview); + } + + public void add_filter(owned Gtk.FileFilter filter) { + chooser.add_filter(filter); + } + + public SList get_files() { + return chooser.get_files(); + } + + public int run() { + return chooser.run(); + } + + public string? get_filename() { + return chooser.get_filename(); + } + + private void on_update_preview() { + Pixbuf preview_pixbuf = get_preview_pixbuf(); + if (preview_pixbuf != null) { + int extra_space = PREVIEW_SIZE - preview_pixbuf.width; + int smaller_half = extra_space/2; + int larger_half = extra_space - smaller_half; + + preview_image.set_margin_start(PREVIEW_PADDING + smaller_half); + preview_image.set_margin_end(PREVIEW_PADDING + larger_half); + + preview_image.set_from_pixbuf(preview_pixbuf); + chooser.preview_widget_active = true; + } else { + chooser.preview_widget_active = false; + } + } + + private Pixbuf? get_preview_pixbuf() { + string? filename = chooser.get_preview_filename(); + if (filename == null) { + return null; + } + + int width = 0; + int height = 0; + Gdk.PixbufFormat? format = Gdk.Pixbuf.get_file_info(filename, out width, out height); + if (format == null) { + return null; + } + + try { + Gdk.Pixbuf pixbuf = new Gdk.Pixbuf.from_file_at_scale(filename, PREVIEW_SIZE, PREVIEW_SIZE, true); + pixbuf = pixbuf.apply_embedded_orientation(); + return pixbuf; + } catch (Error e) { + return null; + } + } + +} + +} -- cgit v1.2.3-54-g00ecf