Skip to content

Commit

Permalink
feat: add new filerow widget
Browse files Browse the repository at this point in the history
  • Loading branch information
alainm23 committed Sep 30, 2024
1 parent 75ad30f commit 221d46a
Show file tree
Hide file tree
Showing 4 changed files with 228 additions and 93 deletions.
106 changes: 19 additions & 87 deletions src/Frontend/Widgets/FilePane.vala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ namespace Taxi {
private PathBar path_bar;
private Gtk.ListBox list_box;
private Gtk.Stack stack;
private Gtk.Popover menu_popover;

public signal void file_dragged (string uri);
public signal void transfer (string uri);
Expand Down Expand Up @@ -80,9 +79,11 @@ namespace Taxi {

child = toolbar;

list_box.row_activated.connect ((row) => {
var uri = row.get_data<GLib.Uri> ("uri");
var type = row.get_data<FileType> ("type");
list_box.row_activated.connect ((value) => {
var row = (FileRow) value;

var uri = row.uri;
var type = row.file_type;
if (type == FileType.DIRECTORY) {
navigate (uri);
} else {
Expand All @@ -93,11 +94,11 @@ namespace Taxi {
path_bar.navigate.connect (uri => navigate (uri));
path_bar.transfer.connect (on_pathbar_transfer);

var drop_target = new Gtk.DropTarget (typeof (Gtk.ListBoxRow), Gdk.DragAction.COPY);
var drop_target = new Gtk.DropTarget (typeof (FileRow), Gdk.DragAction.COPY);
list_box.add_controller (drop_target);
drop_target.drop.connect ((value, x, y) => {
var row = (Gtk.ListBoxRow) value;
var uri = row.get_data<GLib.Uri> ("uri");
var row = (FileRow) value;
var uri = row.uri;

if (uri != null) {
file_dragged (uri.to_string ());
Expand All @@ -121,8 +122,8 @@ namespace Taxi {

do {
row = list_box.get_row_at_index (row_index);
if (row.get_data<Gtk.CheckButton> ("checkbutton").get_active ()) {
uri_list.add (current_uri.to_string () + "/" + row.get_data<string> ("name"));
if (((FileRow)row).active) {
uri_list.add (current_uri.to_string () + "/" + ((FileRow)row).file_name);
}

row_index++;
Expand All @@ -135,14 +136,20 @@ namespace Taxi {
clear_children (list_box);
// Have to convert to gee list because glib list sort function is buggy
// (it randomly removes items...)
var gee_list = glib_to_gee<FileInfo> (file_list);
var gee_list = glib_to_gee<GLib.FileInfo> (file_list);
alphabetical_order (gee_list);
foreach (FileInfo file_info in gee_list) {
foreach (GLib.FileInfo file_info in gee_list) {
if (file_info.get_name ().get_char (0) == '.') {
continue;
}

var row = new_row (file_info);
var row = new FileRow (file_info);
row.current_uri = current_uri;
row.on_checkbutton_toggle.connect (on_checkbutton_toggle);
row.on_delete.connect (() => {

});

if (row != null) {
list_box.append (row);
}
Expand Down Expand Up @@ -173,71 +180,6 @@ namespace Taxi {
});
}

private Gtk.ListBoxRow? new_row (FileInfo file_info) {
var checkbox = new Gtk.CheckButton ();
checkbox.toggled.connect (on_checkbutton_toggle);

var icon = new Gtk.Image.from_gicon (file_info.get_icon ());

var name = new Gtk.Label (file_info.get_name ());
name.halign = Gtk.Align.START;
name.hexpand = true;

var row = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6) {
hexpand = true,
margin_top = 6,
margin_bottom = 6,
margin_start = 12,
margin_end = 12
};
row.append (checkbox);
row.append (icon);
row.append (name);

if (file_info.get_file_type () == FileType.REGULAR) {
var size = new Gtk.Label (bit_string_format (file_info.get_size ()));
size.add_css_class (Granite.STYLE_CLASS_DIM_LABEL);
row.append (size);
}

GLib.Uri uri;
try {
uri = GLib.Uri.parse_relative (current_uri, file_info.get_name (), PARSE_RELAXED);
} catch (Error e) {
message (e.message);
return null;
}

var ebrow = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
ebrow.append (row);
ebrow.set_data ("name", file_info.get_name ());
ebrow.set_data ("type", file_info.get_file_type ());

var lbrow = new Gtk.ListBoxRow () {
hexpand = true,
child = ebrow
};
lbrow.set_data ("uri", uri);
lbrow.set_data ("name", file_info.get_name ());
lbrow.set_data ("type", file_info.get_file_type ());
lbrow.set_data ("checkbutton", checkbox);

var drag_source = new Gtk.DragSource ();
drag_source.set_actions (Gdk.DragAction.COPY);
lbrow.add_controller (drag_source);

drag_source.prepare.connect ((x, y) => {
return new Gdk.ContentProvider.for_value (lbrow);
});

drag_source.drag_begin.connect ((source, drag) => {
var paintable = new Gtk.WidgetPaintable (lbrow);
source.set_icon (paintable, 0, 0);
});

return lbrow;
}

private void on_checkbutton_toggle () {
if (get_marked_row_uris ().size > 0) {
path_bar.transfer_button_sensitive = true;
Expand All @@ -262,15 +204,5 @@ namespace Taxi {
public void stop_spinner () {
stack.visible_child_name = "list";
}

private string bit_string_format (int64 bytes) {
var floatbytes = (float) bytes;
int i;
for (i = 0; floatbytes >= 1000.0f || i > 6; i++) {
floatbytes /= 1000.0f;
}
string[] measurement = { "bytes", "kB", "MB", "GB", "TB", "PB", "EB" };
return "%.3g %s".printf (floatbytes, measurement [i]);
}
}
}
195 changes: 195 additions & 0 deletions src/Frontend/Widgets/FileRow.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
/***
Copyright (C) 2014 Kiran John Hampal <[email protected]>
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License version 3, as published
by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranties of
MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses>
***/

namespace Taxi {

class FileRow : Gtk.ListBoxRow {
public GLib.FileInfo file_info { get; construct; }

private Gtk.CheckButton checkbox;
private Gtk.Popover menu_popover;

GLib.Uri _current_uri;
public GLib.Uri current_uri {
get {
return _current_uri;
}

set {
_current_uri = value;
}
}

GLib.Uri _uri;
public GLib.Uri? uri {
get {
try {
_uri = GLib.Uri.parse_relative (current_uri, file_info.get_name (), PARSE_RELAXED);
} catch (Error e) {
message (e.message);
}

return _uri;
}
}

public string file_name {
get {
return file_info.get_name ();
}
}

public GLib.FileType file_type {
get {
return file_info.get_file_type ();
}
}

public bool active {
get {
return checkbox.active;
}
}

public signal void on_checkbutton_toggle ();
public signal void on_delete ();

public FileRow (GLib.FileInfo file_info) {
Object (
file_info: file_info
);
}

construct {
checkbox = new Gtk.CheckButton ();
checkbox.toggled.connect (() => {
on_checkbutton_toggle ();
});

var icon = new Gtk.Image.from_gicon (file_info.get_icon ()) {
pixel_size = 24
};

var name = new Gtk.Label (file_info.get_name ());
name.halign = Gtk.Align.START;
name.hexpand = true;

var row = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6) {
hexpand = true,
margin_top = 6,
margin_bottom = 6,
margin_start = 12,
margin_end = 12
};
row.append (checkbox);
row.append (icon);
row.append (name);

if (file_info.get_file_type () == FileType.REGULAR) {
var size = new Gtk.Label (bit_string_format (file_info.get_size ()));
size.add_css_class (Granite.STYLE_CLASS_DIM_LABEL);
row.append (size);
}

child = row;
build_dnd ();

var menu_gesture = new Gtk.GestureClick () {
button = 3
};
add_controller (menu_gesture);
menu_gesture.pressed.connect ((n_press, x, y) => {
build_context_menu (x, y);
});
}

private void build_context_menu (double x, double y) {
if (menu_popover != null) {
menu_popover.pointing_to = { ((int) x), (int) y, 1, 1 };
menu_popover.popup ();
return;
}

var open_menu = new Gtk.Button () {
child = new Gtk.Label (_("Open")) {
halign = START
},
css_classes = { Granite.STYLE_CLASS_MENUITEM }
};

var delete_menu = new Gtk.Button () {
child = new Gtk.Label (_("Delete")) {
halign = START
},
css_classes = { Granite.STYLE_CLASS_MENUITEM }
};

var menu_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) {
margin_top = 3,
margin_bottom = 3
};

menu_box.append (open_menu);
menu_box.append (delete_menu);

menu_popover = new Gtk.Popover () {
has_arrow = false,
halign = Gtk.Align.START,
child = menu_box,
width_request = 250
};

menu_popover.set_parent (this);
menu_popover.pointing_to = { ((int) x), (int) y, 1, 1 };
menu_popover.popup ();

open_menu.clicked.connect (() => {
menu_popover.popdown ();
open_menu.activate_action_variant ("win.open", new Variant.string (uri.to_string ()));
});

delete_menu.clicked.connect (() => {
menu_popover.popdown ();
open_menu.activate_action_variant ("win.delete", new Variant.string (uri.to_string ()));
});
}

private void build_dnd () {
var drag_source = new Gtk.DragSource ();
drag_source.set_actions (Gdk.DragAction.COPY);
add_controller (drag_source);

drag_source.prepare.connect ((x, y) => {
return new Gdk.ContentProvider.for_value (this);
});

drag_source.drag_begin.connect ((source, drag) => {
var paintable = new Gtk.WidgetPaintable (this);
source.set_icon (paintable, 0, 0);
});
}

private string bit_string_format (int64 bytes) {
var floatbytes = (float) bytes;
int i;
for (i = 0; floatbytes >= 1000.0f || i > 6; i++) {
floatbytes /= 1000.0f;
}
string[] measurement = { "bytes", "kB", "MB", "GB", "TB", "PB", "EB" };
return "%.3g %s".printf (floatbytes, measurement [i]);
}
}
}
Loading

0 comments on commit 221d46a

Please sign in to comment.