Skip to content

Commit

Permalink
rework -a option
Browse files Browse the repository at this point in the history
-a option now shows a drag all button at the top of the file list
instead of always dragging all files

fix warnings

fix comment
  • Loading branch information
Cyanistic committed Sep 2, 2024
1 parent ef303f8 commit e9d73fb
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 52 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Options:
-W, --content-width <WIDTH> Min width of the main window [default: 360]
-H, --content-height <HEIGHT> Default height of the main window [default: 360]
-I, --from-stdin Accept paths from stdin
-a, --all Drag all the items together
-a, --all Show a drag all button
-A, --all-compact Show only the number of items and drag them together
-n, --no-click Don't open files on click
-b, --basename Always show basename of each file
Expand Down
110 changes: 73 additions & 37 deletions src/list_view.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use glib_macros::clone;
use gtk::gdk::*;
use glib::clone;
use gtk::gio::{self, ListStore};
use gtk::prelude::*;
use gtk::{
gdk, CenterBox, DragSource, Label, ListItem, ListView, MultiSelection, SignalListItemFactory,
Widget,
};
use gtk::gdk::*;
use gtk::prelude::*;

use crate::file_object::FileObject;
use crate::util::{
Expand Down Expand Up @@ -48,33 +48,25 @@ fn build_list_data() -> (MultiSelection, SignalListItemFactory) {

fn create_drag_source(row: &CenterBox, selection: &MultiSelection) -> DragSource {
let drag_source = DragSource::new();
if ARGS.get().unwrap().all {
setup_drag_source_all(
&drag_source,
&selection.model().unwrap().downcast::<ListStore>().unwrap(),
);
} else {
drag_source.connect_prepare(clone!(@weak row, @weak selection, => @default-return None, move |me, _, _| {
// This will prevent the click to trigger, a drag should happen!
me.set_state(gtk::EventSequenceState::Claimed);
let selected = selection.selection();
let mut files : Vec<String> = Vec::with_capacity(selected.size() as usize);

for index in 0..selected.size() {
files.push(selection.item(selected.nth(index as u32)).unwrap().downcast::<FileObject>().unwrap().file().uri().to_string());
}

// Is the activated row also selected?
let row_file = get_file(&row).uri().to_string();
if !files.contains(&row_file)
{
selection.unselect_all();
generate_content_provider(&[row_file])
} else {
generate_content_provider(&files)
}
}));
}
drag_source.connect_prepare(clone!(@weak row, @weak selection, => @default-return None, move |me, _, _| {
// This will prevent the click to trigger, a drag should happen!
me.set_state(gtk::EventSequenceState::Claimed);
let selected = selection.selection();
let mut files : Vec<String> = Vec::with_capacity(selected.size() as usize);
for index in 0..selected.size() {
files.push(selection.item(selected.nth(index as u32)).unwrap().downcast::<FileObject>().unwrap().file().uri().to_string());
}

// Is the activated row also selected?
let row_file = get_file(&row).uri().to_string();
if !files.contains(&row_file)
{
selection.unselect_all();
generate_content_provider(&[row_file])
} else {
generate_content_provider(&files)
}
}));

if ARGS.get().unwrap().and_exit {
drag_source_and_exit(&drag_source);
Expand Down Expand Up @@ -151,13 +143,17 @@ fn setup_factory(factory: &SignalListItemFactory, list: &MultiSelection) {

// show either relative or absolute path
// only used for the display label
let str = if ARGS.get().unwrap().basename || file_object
.file()
.has_parent(Some(CURRENT_DIRECTORY.get().unwrap())
) {
file_object.file()
.basename().unwrap()
.to_str().unwrap()
let str = if ARGS.get().unwrap().basename
|| file_object
.file()
.has_parent(Some(CURRENT_DIRECTORY.get().unwrap()))
{
file_object
.file()
.basename()
.unwrap()
.to_str()
.unwrap()
.to_string()
} else {
path.to_owned()
Expand All @@ -180,3 +176,43 @@ fn setup_factory(factory: &SignalListItemFactory, list: &MultiSelection) {
}
});
}

/// Creates an outer box that adds a drag all button to the top
pub fn create_outer_box(list: &ListWidget) -> gtk::Box {
let outer_box = gtk::Box::new(gtk::Orientation::Vertical, 0);
let row = gtk::CenterBox::builder()
.height_request(ARGS.get().unwrap().icon_size)
.focusable(true)
.build();
let label = Label::builder()
.label("Drag All Items")
.css_classes(["drag"])
.hexpand(true)
.tooltip_text("Drag All Items")
.ellipsize(gtk::pango::EllipsizeMode::End);
row.set_center_widget(Some(&label.build()));

let drag_source = DragSource::new();
setup_drag_source_all(&drag_source, &list.list_model);
if !ARGS.get().unwrap().no_click {
let gesture_click = create_gesture_click(&row);
row.add_controller(gesture_click);
}
if ARGS.get().unwrap().and_exit {
drag_source_and_exit(&drag_source);
}

// Add styling
let provider = gtk::CssProvider::new();
provider.load_from_data(include_str!("style.css"));
gtk::style_context_add_provider_for_display(
&gtk::gdk::Display::default().expect("Could not connect to a display."),
&provider,
gtk::STYLE_PROVIDER_PRIORITY_APPLICATION,
);

row.add_controller(drag_source);
outer_box.append(&row);
outer_box.append(&list.widget);
outer_box
}
24 changes: 17 additions & 7 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ use compact_view::generate_compact_view;
use file_object::FileObject;
use gtk::gio::{ApplicationFlags, ListStore};
use gtk::glib::{self, clone, set_program_name, Continue, MainContext, Priority};
use gtk::prelude::*;
use gtk::{gio, Application, ApplicationWindow, EventControllerKey, PolicyType, ScrolledWindow};
use list_view::generate_list_view;
use gtk::prelude::*;
use list_view::{create_outer_box, generate_list_view};

mod compact_view;
mod file_object;
Expand Down Expand Up @@ -63,7 +63,7 @@ struct Cli {
#[arg(short = 'I', long)]
from_stdin: bool,

/// Drag all the items together
/// Show a drag all button
#[arg(short = 'a', long)]
all: bool,

Expand Down Expand Up @@ -115,17 +115,27 @@ fn build_ui(app: &Application) {
);
}
// Create a scrollable list
let list_data = if ARGS.get().unwrap().all_compact {
generate_compact_view()
let (outer_box, list_data) = if ARGS.get().unwrap().all_compact {
// Create compact list
(None, generate_compact_view())
} else if ARGS.get().unwrap().all {
// Create regular list with a drag all button
let list = generate_list_view();
(Some(create_outer_box(&list).upcast::<gtk::Widget>()), list)
} else {
generate_list_view()
// Create regular list
(None, generate_list_view())
};

let scrolled_window = ScrolledWindow::builder()
.hscrollbar_policy(PolicyType::Never) // Disable horizontal scrolling
.vexpand(true)
.hexpand(true)
.child(&list_data.widget)
.child(if let Some(outer_box) = &outer_box {
outer_box
} else {
&list_data.widget
})
.build();

let titlebar = gtk::HeaderBar::builder()
Expand Down
14 changes: 7 additions & 7 deletions src/util.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use gtk::gdk::{ContentProvider, DragAction, FileList};
use gtk::gio::{self, File, ListStore};
use gtk::glib::{clone, Bytes};
use gtk::prelude::*;
use gtk::{gdk, glib, DragSource, DropTarget, EventSequenceState, Widget};
use gtk::prelude::*;

use crate::file_object::FileObject;
use crate::ARGS;
Expand Down Expand Up @@ -31,13 +31,13 @@ pub fn generate_content_provider<'a>(
paths: impl IntoIterator<Item = &'a String>,
) -> Option<ContentProvider> {
let mut uri_list = paths
.into_iter()
.cloned()
.collect::<Vec<String>>()
.join("\r\n");
.into_iter()
.cloned()
.collect::<Vec<String>>()
.join("\r\n");

if uri_list.is_empty() {
return None
return None;
} else {
uri_list += "\r\n";
let bytes = Bytes::from(uri_list.as_bytes());
Expand Down

0 comments on commit e9d73fb

Please sign in to comment.