Imrove file widget menu (fixup 25db512)

- Fix file menu remaining visible after clicking an action
- Fix file menu for images (clicking resulted in hiding of the file widget part)
- Fix styling of file menus for images
- Fix compiler warnings and runtime criticals
This commit is contained in:
fiaxh 2022-01-09 14:28:17 +01:00
parent 25db512297
commit c5461b8536
4 changed files with 54 additions and 48 deletions

View file

@ -111,6 +111,27 @@ window.dino-main .call-box {
margin: 12px 16px 12px 12px; margin: 12px 16px 12px 12px;
} }
window.dino-main .file-image-widget {
border: 1px solid alpha(@theme_fg_color, 0.1);
border-radius: 3px;
}
window.dino-main .file-image-widget .file-box-outer {
color: #eee;
background: rgba(0, 0, 0, 0.5);
}
window.dino-main .file-image-widget .file-box-outer button {
color: #eee;
background: transparent;
border: none;
box-shadow: none;
}
window.dino-main .file-image-widget .file-box-outer button:hover {
background: rgba(100, 100, 100, 0.5);
}
window.dino-main .call-box-outer.incoming { window.dino-main .call-box-outer.incoming {
border-color: alpha(@theme_selected_bg_color, 0.3); border-color: alpha(@theme_selected_bg_color, 0.3);
} }

View file

@ -15,7 +15,7 @@ public class FileDefaultWidget : EventBox {
[GtkChild] public unowned Image content_type_image; [GtkChild] public unowned Image content_type_image;
[GtkChild] public unowned Spinner spinner; [GtkChild] public unowned Spinner spinner;
[GtkChild] public unowned EventBox stack_event_box; [GtkChild] public unowned EventBox stack_event_box;
[GtkChild] public MenuButton file_menu; [GtkChild] public unowned MenuButton file_menu;
public ModelButton file_open_button; public ModelButton file_open_button;
public ModelButton file_save_button; public ModelButton file_save_button;
@ -23,10 +23,10 @@ public class FileDefaultWidget : EventBox {
private FileTransfer.State state; private FileTransfer.State state;
public FileDefaultWidget() { public FileDefaultWidget() {
this.enter_notify_event.connect(on_pointer_entered); this.enter_notify_event.connect(on_pointer_entered_event);
this.leave_notify_event.connect(on_pointer_left); this.leave_notify_event.connect(on_pointer_left_event);
file_open_button = new ModelButton() { text=_("Open"), visible=true }; file_open_button = new ModelButton() { text=_("Open"), visible=true };
file_save_button = new ModelButton() { text=_("Save as..."), visible=true }; file_save_button = new ModelButton() { text=_("Save as"), visible=true };
} }
public void update_file_info(string? mime_type, FileTransfer.State state, long size) { public void update_file_info(string? mime_type, FileTransfer.State state, long size) {
@ -41,15 +41,19 @@ public class FileDefaultWidget : EventBox {
case FileTransfer.State.COMPLETE: case FileTransfer.State.COMPLETE:
mime_label.label = mime_description; mime_label.label = mime_description;
image_stack.set_visible_child_name("content_type_image"); image_stack.set_visible_child_name("content_type_image");
// Create a menu
Gtk.PopoverMenu popover_menu = new Gtk.PopoverMenu(); Gtk.PopoverMenu popover_menu = new Gtk.PopoverMenu();
Box file_menu_box = new Box(Orientation.VERTICAL, 0) { margin=10, visible=true }; Box file_menu_box = new Box(Orientation.VERTICAL, 0) { margin=10, visible=true };
file_menu_box.add(file_open_button); file_menu_box.add(file_open_button);
file_menu_box.add(file_save_button); file_menu_box.add(file_save_button);
popover_menu.add(file_menu_box); popover_menu.add(file_menu_box);
file_menu.popover = popover_menu; file_menu.popover = popover_menu;
file_menu.clicked.connect(() => { file_menu.button_release_event.connect(() => {
popover_menu.visible = true; popover_menu.visible = true;
return true;
}); });
popover_menu.closed.connect(on_pointer_left);
break; break;
case FileTransfer.State.IN_PROGRESS: case FileTransfer.State.IN_PROGRESS:
mime_label.label = _("Downloading %s…").printf(get_size_string(size)); mime_label.label = _("Downloading %s…").printf(get_size_string(size));
@ -74,9 +78,7 @@ public class FileDefaultWidget : EventBox {
} }
} }
private bool on_pointer_entered(Gdk.EventCrossing event) { private bool on_pointer_entered_event(Gdk.EventCrossing event) {
if (event.detail == Gdk.NotifyType.INFERIOR) return false;
event.get_window().set_cursor(new Cursor.for_display(Gdk.Display.get_default(), CursorType.HAND2)); event.get_window().set_cursor(new Cursor.for_display(Gdk.Display.get_default(), CursorType.HAND2));
content_type_image.opacity = 0.7; content_type_image.opacity = 0.7;
if (state == FileTransfer.State.NOT_STARTED) { if (state == FileTransfer.State.NOT_STARTED) {
@ -88,17 +90,21 @@ public class FileDefaultWidget : EventBox {
return false; return false;
} }
private bool on_pointer_left(Gdk.EventCrossing event) { private bool on_pointer_left_event(Gdk.EventCrossing event) {
if (event.detail == Gdk.NotifyType.INFERIOR) return false; if (event.detail == Gdk.NotifyType.INFERIOR) return false;
if (file_menu.popover.visible == true) return false; if (file_menu.popover != null && file_menu.popover.visible) return false;
event.get_window().set_cursor(new Cursor.for_display(Gdk.Display.get_default(), CursorType.XTERM)); event.get_window().set_cursor(new Cursor.for_display(Gdk.Display.get_default(), CursorType.XTERM));
on_pointer_left();
return false;
}
private void on_pointer_left() {
content_type_image.opacity = 0.5; content_type_image.opacity = 0.5;
if (state == FileTransfer.State.NOT_STARTED) { if (state == FileTransfer.State.NOT_STARTED) {
image_stack.set_visible_child_name("content_type_image"); image_stack.set_visible_child_name("content_type_image");
} }
file_menu.visible = false; file_menu.visible = false;
return false;
} }
private static string get_file_icon_name(string? mime_type) { private static string get_file_icon_name(string? mime_type) {

View file

@ -16,7 +16,7 @@ public class FileImageWidget : EventBox {
this.halign = Align.START; this.halign = Align.START;
this.events = EventMask.POINTER_MOTION_MASK; this.events = EventMask.POINTER_MOTION_MASK;
Util.force_css(this, "* { border: 1px solid alpha(@theme_fg_color, 0.1); border-radius: 3px; }"); this.get_style_context().add_class("file-image-widget");
} }
public async void load_from_file(File file, string file_name, int MAX_WIDTH=600, int MAX_HEIGHT=300) throws GLib.Error { public async void load_from_file(File file, string file_name, int MAX_WIDTH=600, int MAX_HEIGHT=300) throws GLib.Error {
@ -52,20 +52,18 @@ public class FileImageWidget : EventBox {
file_default_widget_controller = new FileDefaultWidgetController(file_default_widget); file_default_widget_controller = new FileDefaultWidgetController(file_default_widget);
file_default_widget_controller.set_file(file, file_name, mime_type); file_default_widget_controller.set_file(file, file_name, mime_type);
Util.force_css(file_default_widget, "* { color: #eee; }");
Util.force_css(file_default_widget, "* { background-color: rgba(0, 0, 0, 0.5); }");
Overlay overlay = new Overlay() { visible=true }; Overlay overlay = new Overlay() { visible=true };
overlay.add(image); overlay.add(image);
overlay.add_overlay(file_default_widget); overlay.add_overlay(file_default_widget);
this.enter_notify_event.connect((event) => { this.enter_notify_event.connect((event) => {
if (event.detail == Gdk.NotifyType.INFERIOR) return false;
file_default_widget.visible = true; file_default_widget.visible = true;
return false; return false;
}); });
this.leave_notify_event.connect((event) => { this.leave_notify_event.connect((event) => {
if (event.detail == Gdk.NotifyType.INFERIOR) return false; if (event.detail == Gdk.NotifyType.INFERIOR) return false;
if (file_default_widget.file_menu.popover != null && file_default_widget.file_menu.popover.visible) return false;
file_default_widget.visible = false; file_default_widget.visible = false;
return false; return false;
}); });

View file

@ -123,6 +123,7 @@ public class FileDefaultWidgetController : Object {
private StreamInteractor? stream_interactor; private StreamInteractor? stream_interactor;
private string file_uri; private string file_uri;
private string file_name;
private FileTransfer.State state; private FileTransfer.State state;
public FileDefaultWidgetController(FileDefaultWidget widget) { public FileDefaultWidgetController(FileDefaultWidget widget) {
@ -136,7 +137,7 @@ public class FileDefaultWidgetController : Object {
this.file_transfer = file_transfer; this.file_transfer = file_transfer;
this.stream_interactor = stream_interactor; this.stream_interactor = stream_interactor;
widget.name_label.label = file_transfer.file_name; widget.name_label.label = file_name = file_transfer.file_name;
file_transfer.bind_property("path", this, "file-transfer-path"); file_transfer.bind_property("path", this, "file-transfer-path");
file_transfer.bind_property("state", this, "file-transfer-state"); file_transfer.bind_property("state", this, "file-transfer-state");
@ -152,7 +153,7 @@ public class FileDefaultWidgetController : Object {
public void set_file(File file, string file_name, string? mime_type) { public void set_file(File file, string file_name, string? mime_type) {
file_uri = file.get_uri(); file_uri = file.get_uri();
state = FileTransfer.State.COMPLETE; state = FileTransfer.State.COMPLETE;
widget.name_label.label = file_name; widget.name_label.label = this.file_name = file_name;
widget.update_file_info(mime_type, state, -1); widget.update_file_info(mime_type, state, -1);
} }
@ -170,47 +171,27 @@ public class FileDefaultWidgetController : Object {
} }
} }
private void save_as(Gtk.Dialog dialog, int response_id) { private void save_file() {
var save_dialog = dialog as Gtk.FileChooserDialog; var save_dialog = new FileChooserNative(_("Save as…"), widget.get_toplevel() as Gtk.Window, FileChooserAction.SAVE, null, null);
File file_src; save_dialog.set_do_overwrite_confirmation(true);
switch (response_id) { save_dialog.set_modal(true);
case Gtk.ResponseType.ACCEPT: save_dialog.set_current_name(file_name);
file_src = GLib.File.new_for_uri(file_uri);
if (save_dialog.run() == Gtk.ResponseType.ACCEPT) {
try{ try{
file_src.copy(save_dialog.get_file(), GLib.FileCopyFlags.OVERWRITE, null); GLib.File.new_for_uri(file_uri).copy(save_dialog.get_file(), GLib.FileCopyFlags.OVERWRITE, null);
} catch (Error err) { } catch (Error err) {
warning("Failed copy file %s - %s", file_uri, err.message); warning("Failed copy file %s - %s", file_uri, err.message);
} }
break;
default:
break;
} }
dialog.destroy();
}
private void save_file() {
var save_dialog = new Gtk.FileChooserDialog("Save as...", this as Gtk.Window, Gtk.FileChooserAction.SAVE, Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL, Gtk.Stock.SAVE, Gtk.ResponseType.ACCEPT);
save_dialog.set_do_overwrite_confirmation(true);
save_dialog.set_modal(true);
try {
(save_dialog as Gtk.FileChooser).set_current_name(GLib.Uri.escape_string(GLib.Path.get_basename(file_uri)));
(save_dialog as Gtk.FileChooser).set_uri(GLib.Uri.escape_string(GLib.Path.get_basename(GLib.Uri.unescape_string(file_uri))));
} catch (GLib.Error error) {
warning("Faild to open save dialog: %s\n", error.message);
}
save_dialog.response.connect(save_as);
save_dialog.show();
} }
private bool on_clicked(EventButton event_button) { private bool on_clicked(EventButton event_button) {
switch (state) { switch (state) {
case FileTransfer.State.COMPLETE: case FileTransfer.State.COMPLETE:
if (event_button.button == 1 && this.widget.file_menu.popover.visible == false) { if (event_button.button == 1) {
open_file(); open_file();
} }
if (event_button.button == 3 && this.widget.file_menu.popover.visible == false) {
save_file();
}
break; break;
case FileTransfer.State.NOT_STARTED: case FileTransfer.State.NOT_STARTED:
assert(stream_interactor != null && file_transfer != null); assert(stream_interactor != null && file_transfer != null);