Skip to content

Commit

Permalink
Port to Gtk4 (#90)
Browse files Browse the repository at this point in the history
Fix #80

- [x] Implement DnD
- [x] Refactor Gtk.Menu

---------

Co-authored-by: Ryo Nakano <ryonakaknock3@gmail.com>
  • Loading branch information
alainm23 and ryonakano authored Dec 15, 2024
1 parent 46f60e9 commit 4dcb5b2
Show file tree
Hide file tree
Showing 13 changed files with 501 additions and 522 deletions.
13 changes: 13 additions & 0 deletions data/Application.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,16 @@ button.pathbar {
border-radius: 0;
padding: 0 6px;
}

.linked .combo {
padding: 2.5px 3px;
}

.transition {
transition: all 175ms ease-in-out;
}

.drop-target:drop(active) {
border-radius: 6px;
background: alpha(@color_primary, 0.15);
}
2 changes: 1 addition & 1 deletion po/POTFILES
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ src/Frontend/MainWindow.vala
src/Frontend/Widgets/ConnectBox.vala
src/Frontend/Widgets/FilePane.vala
src/Frontend/Widgets/OperationsPopover.vala
src/Frontend/Widgets/PathBarSeparator.vala
src/Frontend/Widgets/PathBar.vala
src/Frontend/Widgets/FileRow.vala
2 changes: 0 additions & 2 deletions src/API/IFileOperations.vala
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ namespace Taxi {

public signal void operation_added (IOperationInfo operation);
public signal void operation_removed (IOperationInfo operation);
public signal int ask_overwrite (File destination);

public async abstract bool delete_recursive (
File file,
Cancellable? cancellable
Expand Down
18 changes: 14 additions & 4 deletions src/Application.vala
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ public class Taxi.Taxi : Gtk.Application {
protected override void startup () {
base.startup ();

Hdy.init ();
Granite.init ();

var provider = new Gtk.CssProvider ();
provider.load_from_resource ("com/github/alecaddd/taxi/Application.css");
Gtk.StyleContext.add_provider_for_screen (
Gdk.Screen.get_default (),
Gtk.StyleContext.add_provider_for_display (
Gdk.Display.get_default (),
provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
);

Expand All @@ -57,7 +57,17 @@ public class Taxi.Taxi : Gtk.Application {
new ConnectionSaver ()
);

main_window.show_all ();
var settings = new Settings ("com.github.alecaddd.taxi.state");
settings.bind ("window-height", main_window, "default-height", SettingsBindFlags.DEFAULT);
settings.bind ("window-width", main_window, "default-width", SettingsBindFlags.DEFAULT);

if (settings.get_boolean ("maximized")) {
main_window.maximize ();
}

settings.bind ("maximized", main_window, "maximized", SettingsBindFlags.SET);

main_window.present ();
}

public static int main (string[] args) {
Expand Down
33 changes: 32 additions & 1 deletion src/Backend/FileOperations.vala
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ namespace Taxi {
} else if (file_type == FileType.REGULAR) {
var tmp_flag = *flags;
if (*flags == FileCopyFlags.NONE && destination.query_exists ()) {
switch ((ConflictFlag)ask_overwrite (destination)) {
switch ((ConflictFlag) ask_overwrite (destination)) {
case ConflictFlag.REPLACE_ALL:
*flags = FileCopyFlags.OVERWRITE;
tmp_flag = *flags;
Expand All @@ -138,6 +138,7 @@ namespace Taxi {
return;
}
}

yield source.copy_async (
destination,
tmp_flag,
Expand All @@ -149,4 +150,34 @@ namespace Taxi {
}
}
}

private int ask_overwrite (File destination) {
var message_dialog = new Granite.MessageDialog (
_("Replace existing file?"),
_("<i>\"%s\"</i> already exists. You can replace this file, replace all conflicting files or choose not to replace the file by skipping.").printf (destination.get_basename ()),
new ThemedIcon ("dialog-warning"),
Gtk.ButtonsType.CANCEL
) {
modal = true
};

message_dialog.add_button (_("Replace All Conflicts"), ConflictFlag.REPLACE_ALL);
message_dialog.add_button (_("Skip"), ConflictFlag.SKIP);
var replace_button = message_dialog.add_button (_("Replace"), ConflictFlag.REPLACE);
replace_button.add_css_class (Granite.STYLE_CLASS_SUGGESTED_ACTION);

message_dialog.show ();

int response = 0;
var loop = new MainLoop ();
message_dialog.response.connect ((response_id) => {
response = response_id;
message_dialog.destroy ();
loop.quit ();
});

loop.run ();

return response;
}
}
179 changes: 70 additions & 109 deletions src/Frontend/MainWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,24 @@
with program. If not, see <http://www.gnu.org/licenses>
***/

class Taxi.MainWindow : Hdy.ApplicationWindow {
class Taxi.MainWindow : Gtk.ApplicationWindow {
public IConnectionSaver conn_saver { get; construct; }
public IFileOperations file_operation { get; construct; }
public IFileAccess local_access { get; construct; }
public IFileAccess remote_access { get; construct; }

private Granite.Widgets.Toast toast;
private Granite.Toast toast;
private Gtk.Revealer spinner_revealer;
private Gtk.Grid bookmark_list;
private Gtk.Grid outer_box;
private Gtk.Box bookmark_list;
private Gtk.Box outer_box;
private Gtk.MenuButton bookmark_menu_button;
private Gtk.Stack alert_stack;
private ConnectBox connect_box;
private Granite.Widgets.Welcome welcome;
private FilePane local_pane;
private FilePane remote_pane;
private GLib.Uri conn_uri;
private GLib.Settings saved_state;
private Gtk.Popover bookmark_popover;
private Granite.Placeholder welcome;

public MainWindow (
Gtk.Application application,
Expand Down Expand Up @@ -69,52 +69,55 @@ class Taxi.MainWindow : Hdy.ApplicationWindow {
var spinner = new Gtk.Spinner ();
spinner.start ();

var popover = new OperationsPopover (spinner);
var popover = new OperationsPopover ();

var operations_button = new Gtk.MenuButton ();
operations_button.popover = popover;
operations_button.valign = Gtk.Align.CENTER;
operations_button.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
operations_button.add (spinner);
var operations_button = new Gtk.MenuButton () {
popover = popover,
valign = CENTER,
child = spinner
};
operations_button.add_css_class (Granite.STYLE_CLASS_FLAT);

spinner_revealer = new Gtk.Revealer ();
spinner_revealer.transition_type = Gtk.RevealerTransitionType.SLIDE_RIGHT;
spinner_revealer.add (operations_button);
spinner_revealer = new Gtk.Revealer () {
transition_type = Gtk.RevealerTransitionType.SLIDE_RIGHT,
child = operations_button
};

bookmark_list = new Gtk.Grid ();
bookmark_list.margin_top = bookmark_list.margin_bottom = 3;
bookmark_list.orientation = Gtk.Orientation.VERTICAL;
bookmark_list = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
bookmark_list.add_css_class (Granite.STYLE_CLASS_MENU);

var bookmark_scrollbox = new Gtk.ScrolledWindow (null, null);
bookmark_scrollbox.hscrollbar_policy = Gtk.PolicyType.NEVER;
bookmark_scrollbox.max_content_height = 500;
bookmark_scrollbox.propagate_natural_height = true;
bookmark_scrollbox.add (bookmark_list);
bookmark_scrollbox.show ();
var bookmark_scrollbox = new Gtk.ScrolledWindow () {
child = bookmark_list,
hscrollbar_policy = Gtk.PolicyType.NEVER,
max_content_height = 500,
propagate_natural_height = true,
};

var bookmark_popover = new Gtk.Popover (null);
bookmark_popover.add (bookmark_scrollbox);
bookmark_popover = new Gtk.Popover () {
child = bookmark_scrollbox,
width_request = 250
};

bookmark_menu_button = new Gtk.MenuButton ();
bookmark_menu_button.image = new Gtk.Image.from_icon_name ("user-bookmarks", Gtk.IconSize.LARGE_TOOLBAR);
bookmark_menu_button.popover = bookmark_popover;
bookmark_menu_button.tooltip_text = _("Access Bookmarks");
bookmark_menu_button = new Gtk.MenuButton () {
icon_name = "user-bookmarks",
tooltip_text = _("Access Bookmarks"),
popover = bookmark_popover,
valign = CENTER
};
bookmark_menu_button.add_css_class (Granite.STYLE_CLASS_LARGE_ICONS);

update_bookmark_menu ();

var header_bar = new Hdy.HeaderBar () {
custom_title = new Gtk.Label (null),
show_close_button = true
var header_bar = new Adw.HeaderBar () {
show_title = false
};
header_bar.pack_start (connect_box);
header_bar.pack_start (spinner_revealer);
header_bar.pack_start (bookmark_menu_button);

welcome = new Granite.Widgets.Welcome (
_("Connect"),
_("Type a URL and press 'Enter' to\nconnect to a server.")
);
welcome.vexpand = true;
welcome = new Granite.Placeholder (_("Connect")) {
description = _("Type a URL and press 'Enter' to\nconnect to a server."),
};

local_pane = new FilePane ();
local_pane.open.connect (on_local_open);
Expand All @@ -129,49 +132,44 @@ class Taxi.MainWindow : Hdy.ApplicationWindow {
remote_pane.file_dragged.connect (on_remote_file_dragged);
remote_pane.transfer.connect (on_local_file_dragged);

outer_box = new Gtk.Grid ();
outer_box.add (local_pane);
outer_box.add (new Gtk.Separator (Gtk.Orientation.VERTICAL));
outer_box.add (remote_pane);
outer_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
outer_box.append (local_pane);
outer_box.append (new Gtk.Separator (Gtk.Orientation.VERTICAL));
outer_box.append (remote_pane);

var size_group = new Gtk.SizeGroup (Gtk.SizeGroupMode.HORIZONTAL);
size_group.add_widget (local_pane);
size_group.add_widget (remote_pane);

alert_stack = new Gtk.Stack ();
alert_stack.add (welcome);
alert_stack.add (outer_box);
alert_stack.add_child (welcome);
alert_stack.add_child (outer_box);

toast = new Granite.Widgets.Toast ("");
toast = new Granite.Toast ("");

var overlay = new Gtk.Overlay ();
overlay.add (alert_stack);
var overlay = new Gtk.Overlay () {
child = alert_stack
};
overlay.add_overlay (toast);

var grid = new Gtk.Grid ();
grid.attach (header_bar, 0, 0);
grid.attach (overlay, 0, 1);

add (grid);
var grid = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
grid.append (header_bar);
grid.append (overlay);

saved_state = new GLib.Settings ("com.github.alecaddd.taxi.state");
// We need to hide the title area for the split headerbar
var null_title = new Gtk.Grid () {
visible = false
};
set_titlebar (null_title);

default_height = saved_state.get_int ("window-height");
default_width = saved_state.get_int ("window-width");

if (saved_state.get_boolean ("maximized")) {
maximize ();
}
child = grid;

connect_box.connect_initiated.connect (on_connect_initiated);
connect_box.ask_hostname.connect (on_ask_hostname);
connect_box.bookmarked.connect (bookmark);

file_operation.operation_added.connect (popover.add_operation);
file_operation.operation_removed.connect (popover.remove_operation);
file_operation.ask_overwrite.connect (on_ask_overwrite);

key_press_event.connect (connect_box.on_key_press_event);

popover.operations_pending.connect (show_spinner);
popover.operations_finished.connect (hide_spinner);
Expand All @@ -182,9 +180,6 @@ class Taxi.MainWindow : Hdy.ApplicationWindow {
remote_access.connect_to_device.begin (uri, this, (obj, res) => {
if (remote_access.connect_to_device.end (res)) {
alert_stack.visible_child = outer_box;
if (local_pane == null) {
key_press_event.disconnect (connect_box.on_key_press_event);
}
update_pane (Location.LOCAL);
update_pane (Location.REMOTE);
connect_box.show_favorite_icon (
Expand Down Expand Up @@ -221,25 +216,27 @@ class Taxi.MainWindow : Hdy.ApplicationWindow {
}

private void update_bookmark_menu () {
foreach (Gtk.Widget child in bookmark_list.get_children ()) {
child.destroy ();
for (Gtk.Widget? child = bookmark_list.get_first_child (); child != null;) {
Gtk.Widget? next = child.get_next_sibling ();
bookmark_list.remove (child);
child = next;
}

var uri_list = conn_saver.get_saved_conns ();
if (uri_list.length () == 0) {
bookmark_menu_button.sensitive = false;
} else {
foreach (string uri in uri_list) {
var bookmark_item = new Gtk.ModelButton ();
bookmark_item.text = uri;

bookmark_list.add (bookmark_item);

var bookmark_item = new Gtk.Button.with_label (uri);
bookmark_item.add_css_class (Granite.STYLE_CLASS_MENUITEM);
bookmark_item.clicked.connect (() => {
connect_box.go_to_uri (uri);
bookmark_popover.popdown ();
});
bookmark_item.child.halign = START;

bookmark_list.append (bookmark_item);
}
bookmark_list.show_all ();
bookmark_menu_button.sensitive = true;
}
}
Expand Down Expand Up @@ -382,40 +379,4 @@ class Taxi.MainWindow : Hdy.ApplicationWindow {
private GLib.Uri on_ask_hostname () {
return conn_uri;
}

private int on_ask_overwrite (File destination) {
var dialog = new Gtk.MessageDialog (
this,
Gtk.DialogFlags.MODAL,
Gtk.MessageType.QUESTION,
Gtk.ButtonsType.NONE,
_("Replace existing file?")
);
dialog.format_secondary_markup (
_("<i>\"%s\"</i> already exists. You can replace this file, replace all conflicting files or choose not to replace the file by skipping.".printf (destination.get_basename ()))
);
dialog.add_button (_("Replace All Conflicts"), 2);
dialog.add_button (_("Skip"), 0);
dialog.add_button (_("Replace"), 1);
dialog.get_widget_for_response (1).get_style_context ().add_class ("suggested-action");

var response = dialog.run ();
dialog.destroy ();
return response;
}

public override bool configure_event (Gdk.EventConfigure event) {
if (is_maximized) {
saved_state.set_boolean ("maximized", true);
} else {
saved_state.set_boolean ("maximized", false);

int window_width, window_height;
get_size (out window_width, out window_height);
saved_state.set_int ("window-height", window_height);
saved_state.set_int ("window-width", window_width);
}

return base.configure_event (event);
}
}
Loading

0 comments on commit 4dcb5b2

Please sign in to comment.