|
| 1 | +namespace Notejot { |
| 2 | + public class EntryImagesDialog : He.Window { |
| 3 | + public signal void response (int response_id); |
| 4 | + |
| 5 | + private GLib.List<string> image_paths; |
| 6 | + private Gtk.FlowBox image_preview_box; |
| 7 | + private He.Button add_image_button; |
| 8 | + |
| 9 | + public EntryImagesDialog (Gtk.Window parent, GLib.List<string> initial_paths) { |
| 10 | + Object ( |
| 11 | + parent : parent, |
| 12 | + modal: true, |
| 13 | + default_width: 520, |
| 14 | + resizable: false |
| 15 | + ); |
| 16 | + |
| 17 | + this.add_css_class ("dialog-content"); |
| 18 | + this.image_paths = new GLib.List<string> (); |
| 19 | + foreach (var p in initial_paths) { this.image_paths.append (p); } |
| 20 | + |
| 21 | + // Header |
| 22 | + var header_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); |
| 23 | + header_box.set_margin_top (12); |
| 24 | + header_box.set_margin_start (12); |
| 25 | + header_box.set_margin_end (12); |
| 26 | + header_box.set_margin_bottom (12); |
| 27 | + |
| 28 | + var title_label = new Gtk.Label (_("Manage Images")); |
| 29 | + title_label.add_css_class ("title-3"); |
| 30 | + header_box.append (title_label); |
| 31 | + header_box.append (new Gtk.Label ("") { hexpand = true }); |
| 32 | + |
| 33 | + var close_button = new He.Button ("window-close-symbolic", ""); |
| 34 | + close_button.tooltip_text = _("Close"); |
| 35 | + close_button.is_disclosure = true; |
| 36 | + close_button.clicked.connect (() => { |
| 37 | + response (Gtk.ResponseType.CANCEL); |
| 38 | + this.close (); |
| 39 | + }); |
| 40 | + header_box.append (close_button); |
| 41 | + |
| 42 | + var winhandle = new Gtk.WindowHandle (); |
| 43 | + winhandle.set_child (header_box); |
| 44 | + |
| 45 | + // Main content |
| 46 | + var main_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 12); |
| 47 | + main_box.set_margin_top (6); |
| 48 | + main_box.set_margin_bottom (12); |
| 49 | + main_box.set_margin_start (12); |
| 50 | + main_box.set_margin_end (12); |
| 51 | + |
| 52 | + // Toolbar with Add button |
| 53 | + var img_toolbar = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); |
| 54 | + this.add_image_button = new He.Button ("", _("Add Images")); |
| 55 | + this.add_image_button.is_fill = true; |
| 56 | + this.add_image_button.clicked.connect (on_add_images_clicked); |
| 57 | + img_toolbar.append (this.add_image_button); |
| 58 | + main_box.append (img_toolbar); |
| 59 | + |
| 60 | + // Previews |
| 61 | + var scrolled = new Gtk.ScrolledWindow (); |
| 62 | + scrolled.set_policy (Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC); |
| 63 | + this.image_preview_box = new Gtk.FlowBox () { |
| 64 | + min_children_per_line = 4, |
| 65 | + max_children_per_line = 4, |
| 66 | + margin_top = 8, margin_bottom = 8, margin_start = 8, margin_end = 8 |
| 67 | + }; |
| 68 | + scrolled.set_child (this.image_preview_box); |
| 69 | + main_box.append (scrolled); |
| 70 | + |
| 71 | + // Populate previews |
| 72 | + foreach (var p in this.image_paths) { |
| 73 | + add_image_preview (p); |
| 74 | + } |
| 75 | + this.add_image_button.set_sensitive (this.image_paths.length () < 4); |
| 76 | + |
| 77 | + // Bottom buttons |
| 78 | + var button_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 12); |
| 79 | + button_box.set_halign (Gtk.Align.END); |
| 80 | + button_box.set_margin_top (12); |
| 81 | + button_box.set_margin_bottom (12); |
| 82 | + button_box.set_margin_start (12); |
| 83 | + button_box.set_margin_end (12); |
| 84 | + |
| 85 | + var cancel_btn = new He.Button ("", _("Cancel")); |
| 86 | + cancel_btn.is_tint = true; |
| 87 | + cancel_btn.clicked.connect (() => { |
| 88 | + response (Gtk.ResponseType.CANCEL); |
| 89 | + this.close (); |
| 90 | + }); |
| 91 | + button_box.append (cancel_btn); |
| 92 | + |
| 93 | + var save_btn = new He.Button ("", _("Save")); |
| 94 | + save_btn.is_fill = true; |
| 95 | + save_btn.clicked.connect (() => { |
| 96 | + response (Gtk.ResponseType.ACCEPT); |
| 97 | + this.close (); |
| 98 | + }); |
| 99 | + button_box.append (save_btn); |
| 100 | + |
| 101 | + var container = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); |
| 102 | + container.append (winhandle); |
| 103 | + container.append (main_box); |
| 104 | + container.append (button_box); |
| 105 | + this.set_child (container); |
| 106 | + } |
| 107 | + |
| 108 | + private void add_image_preview (string path) { |
| 109 | + var overlay = new Gtk.Overlay (); |
| 110 | + overlay.set_size_request (72, 72); |
| 111 | + var picture = new Gtk.Picture.for_filename (path); |
| 112 | + picture.set_halign (Gtk.Align.CENTER); |
| 113 | + picture.set_can_shrink (true); |
| 114 | + overlay.set_child (picture); |
| 115 | + |
| 116 | + var remove_btn = new He.Button ("window-close-symbolic", ""); |
| 117 | + remove_btn.is_disclosure = true; |
| 118 | + remove_btn.set_halign (Gtk.Align.END); |
| 119 | + remove_btn.set_valign (Gtk.Align.START); |
| 120 | + remove_btn.clicked.connect (() => { |
| 121 | + this.image_paths.remove (path); |
| 122 | + this.image_preview_box.remove (overlay); |
| 123 | + this.add_image_button.set_sensitive (this.image_paths.length () < 4); |
| 124 | + }); |
| 125 | + overlay.add_overlay (remove_btn); |
| 126 | + |
| 127 | + this.image_preview_box.insert (overlay, -1); |
| 128 | + } |
| 129 | + |
| 130 | + private void on_add_images_clicked () { |
| 131 | + if (this.image_paths.length () >= 4)return; |
| 132 | + |
| 133 | + var file_dialog = new Gtk.FileDialog (); |
| 134 | + file_dialog.set_title (_("Select Images")); |
| 135 | + file_dialog.set_accept_label (_("Open")); |
| 136 | + |
| 137 | + var filter = new Gtk.FileFilter (); |
| 138 | + filter.set_filter_name (_("Image Files")); |
| 139 | + filter.add_pixbuf_formats (); |
| 140 | + var list_store = new GLib.ListStore (typeof (Gtk.FileFilter)); |
| 141 | + list_store.append (filter); |
| 142 | + file_dialog.set_filters (list_store); |
| 143 | + |
| 144 | + file_dialog.open_multiple.begin ((Gtk.Window) this.get_root (), null, (obj, res) => { |
| 145 | + try { |
| 146 | + var files = file_dialog.open_multiple.end (res); |
| 147 | + for (int i = 0; i < files.get_n_items (); i++) { |
| 148 | + if (this.image_paths.length () >= 4)break; |
| 149 | + var f = files.get_item (i) as File; |
| 150 | + var p = f.get_path (); |
| 151 | + this.image_paths.append (p); |
| 152 | + add_image_preview (p); |
| 153 | + } |
| 154 | + if (this.image_paths.length () >= 4) { |
| 155 | + this.add_image_button.set_sensitive (false); |
| 156 | + } |
| 157 | + } catch (Error e) { |
| 158 | + } |
| 159 | + }); |
| 160 | + } |
| 161 | + |
| 162 | + public GLib.List<string> get_image_paths () { |
| 163 | + var out_list = new GLib.List<string> (); |
| 164 | + foreach (var p in this.image_paths) out_list.append (p); |
| 165 | + return out_list; |
| 166 | + } |
| 167 | + } |
| 168 | +} |
0 commit comments