pub struct FileManager<'a, Msg> { /* private fields */ }Expand description
A folder as a tree, with every file operation on it.
The manager is a file view, not an application: it reads the folder, draws it, does the
file operations and says what happened. What opening a file means is always the application’s:
on_open says a path was asked to be opened and nothing more.
The application owns a FileManagerState, hands it every FileManagerMsg and draws it
here. Folders are read on a background thread, never while drawing; a read that takes longer
than about 300 ms shows a small spinner on the folder’s own row, which then stays about 500 ms,
so quick reads never flash one.
What it does: opening and closing folders, one and several selections, the keyboard’s own way through the rows, dragging entries onto a folder to move them, cut and paste, a new file or folder, renaming with the name checked as it is typed, and deleting behind a question. Each operation says what it changed or why it was refused, entry by entry when there were several.
The mouse works as it does in a desktop file explorer, in all three views. A click only
selects; a double click or Enter opens: a file through on_open, a folder by
stepping into it in the list and the icons and by opening or closing it in the tree, where
its chevron and ← and → still do that with one click. Ctrl+click adds an entry to the
selection or takes it out, and Shift+click selects the entries from the last one clicked. A
drag from the free space draws a box, a tone over the cells it covers, and selects the
entries inside it, adding to the selection when Ctrl was held. A drag from a selected entry
carries the whole selection: released on a folder it moves there, or is copied there when
Ctrl is held at the release, and released anywhere else it does nothing. The folder under the
drag takes the accent tone while it can take what is dragged; a folder never takes itself or a
folder inside it. In the list and the icons the row of the shown folder is the way up, so a
drop on it goes into the folder above, as a desktop explorer’s path takes a drop for a parent;
at the root it takes nothing. A terminal that does
not report Ctrl with the pointer always moves. A name already taken in the folder is never
overwritten; the entry says why it stayed. A right click on a selected entry opens the menu of
the selection, and on any other entry selects it and opens its menu.
open_on(Click::Single) opens with one click instead.
What it draws: the root as the top row, so the folder itself has a place for its menu; folders then files, each in name order; an entry whose name the platform does not spell as text shown lossily rather than left out; what was cut faint until it is pasted or let go.
See FileManagerState for a whole application, and
FileManagerState::confined for keeping operations inside the
root.
Keys: the tree’s own (↑/↓ between rows, ←/→ and Enter to open and close a folder, Enter on a
file to open it, Home and End, the menu key on the row the cursor is on), and a desktop file
explorer’s selection keys in all three views: Shift with the arrows, PgUp/PgDn, Home or End
extends the selection from where it started, Space adds or takes out the entry under the
cursor, Ctrl+A selects every entry shown and Esc leaves only the entry under the cursor
selected. Then Ctrl+X, Ctrl+C and Ctrl+V. Ctrl+X cuts the selection and
Ctrl+C copies it, the entry under the cursor when nothing is selected; Ctrl+V pastes what waits
into the folder the list and the icons show, and in the tree into the folder under the cursor,
or the folder holding the file under it. A name already taken there is refused and said, as a
paste from the menu is. The keys are the manager’s only while its rows have focus and no text
is selected with the mouse: a text field keeps copying and pasting text, and selected text is
what Ctrl+C copies, see NodeMut::on_clipboard. Copy
and paste follow the keymap’s copy and paste.
What it can add: each row’s icon by the kind of the entry, see kind_icons,
and those icons in the colours of their families, see kind_tones.
Style keys: the tree’s (list-item, tree-chevron, tree-drop, list-detail, spinner),
the context menu’s and the dialog’s. Texts: quvyta.file-manager.*.
Implementations§
Source§impl<'a, Msg: Clone + 'static> FileManager<'a, Msg>
impl<'a, Msg: Clone + 'static> FileManager<'a, Msg>
Sourcepub fn new(
state: &'a FileManagerState,
wrap: impl Fn(FileManagerMsg) -> Msg + 'static,
) -> Self
pub fn new( state: &'a FileManagerState, wrap: impl Fn(FileManagerMsg) -> Msg + 'static, ) -> Self
A manager showing state; wrap turns the manager’s messages into the application’s.
wrap is a function such as Msg::Files, or a closure that captures what it needs, such
as a screen’s own conversion: move |message| convert(screen::Msg::Files(message)).
Sourcepub fn root_label(self, label: impl Into<String>) -> Self
pub fn root_label(self, label: impl Into<String>) -> Self
What the top row says. The name of the root folder by default; an application with a name of its own for it, such as a project’s, gives that instead.
Sourcepub fn on_open(self, message: impl Fn(&Path) -> Msg + 'static) -> Self
pub fn on_open(self, message: impl Fn(&Path) -> Msg + 'static) -> Self
A file was asked to be opened: a double click or Enter on its row, or a click with
open_on(Click::Single).
The manager has no viewer, tab or window of its own; one application opens the path in a tab, another in a window, and a dialog returns it as the answer. Without this a double click on a file only selects it.
Sourcepub fn open_on(self, click: Click) -> Self
pub fn open_on(self, click: Click) -> Self
How many clicks open an entry: Click::Double, the default, the way a desktop file
explorer opens, so a click is free to select or to start a drag; or Click::Single, a
click that selects and opens at once, for a picker whose rows are only ever opened.
A double click is two presses on the same entry within Click::INTERVAL. Enter opens
either way, and a folder’s chevron in the tree opens and closes it with one click.
Sourcepub fn on_open_terminal(self, message: impl Fn(&Path) -> Msg + 'static) -> Self
pub fn on_open_terminal(self, message: impl Fn(&Path) -> Msg + 'static) -> Self
Offers “Open a terminal here” on a folder’s menu, with the folder’s path.
The wording is the framework’s, so every application says it the same way; what a terminal is stays the application’s own.
The application’s own items on a row’s menu, in a group of their own between the manager’s editing items and its last, destructive one.
The row’s key comes first and what an action there acts on second: the whole selection when
the row is one of several selected, the row alone otherwise, as
FileManagerState::targets works it out.
Sourcepub fn row_mark(self, mark: impl Fn(&str) -> RowMark + 'static) -> Self
pub fn row_mark(self, mark: impl Fn(&str) -> RowMark + 'static) -> Self
What the application says about the look of a row, by key: a sign in a tone, a faint row,
or both. See RowMark.
The manager knows names and folders; what an entry means to the application it cannot know.
qcode marks an entry its backup leaves out with a warning sign and draws the row faint; a
version control panel marks what is ignored. Return RowMark::new() for a row with
nothing to say, which is every row by default.
A mark cannot make a row louder than the manager’s own states: a cut entry and a disabled manager stay faint whatever the mark says, because they are about what can be done rather than about what the entry is.
Sourcepub fn view(self, view: FileView) -> Self
pub fn view(self, view: FileView) -> Self
The shape the folder is drawn in: the tree it is without being asked, a list of rows with their size, date and permissions, or a grid of icons.
The tree shows folders inside folders, opened where they stand. The other two show one
folder at a time: its own row comes first, so the folder has a place for its menu and a way
back out of it, and stepping into a folder shows that folder instead. Which folder is shown
is FileManagerState::folder, and the keys, the menus and every operation are the same
in all three.
The list reads the size, the date and the permissions of a page of entries around the cursor, never of a whole folder; the tree and the icons read none.
Sourcepub fn kind_icons(self, on: bool) -> Self
pub fn kind_icons(self, on: bool) -> Self
Draws each row’s icon by the kind of its entry: the Rust logo on a Rust file, a zipper on
an archive, a folder with a branch on .git, the downloads folder in the home. Off, every
row is a plain folder or file.
A person knows what a file is from its icon before reading its name. The kind comes from
the name alone, see file_kind, so no file is opened to draw
it; whether a file whose name says nothing may be run is the one thing read, with the
folder. Outside a Nerd Font each icon is its family’s shape, so code, pictures and archives
are still told apart.
The icons have no colour of their own, as the plain ones have none: they are drawn in the
row’s quiet colour and take the selected row’s colour with the rest of it. A sign an
application gives with row_mark says something the kind cannot, so it
wins over the kind. Colours by kind are a further layer, kind_tones.
The folders of the home are found by the names the person’s language gives them, read from
user-dirs.dirs once the home is on screen; user_folders gives them
instead.
Sourcepub fn kind_tones(self, on: bool) -> Self
pub fn kind_tones(self, on: bool) -> Self
Colours the icons of kind_icons by their family: folders take the
accent and the files the theme’s series tones, see
KindFamily::tone. A file whose kind is not known keeps
the row’s colour.
The colour only repeats what the shape says, so it adds nothing where tones cannot be told
apart: in sixteen colours and in ASCII it is not drawn. It does nothing without
kind_icons.
Sourcepub fn user_folders(self, folders: &'a UserFolders) -> Self
pub fn user_folders(self, folders: &'a UserFolders) -> Self
The home and its folders kind_icons recognises, in place of the
person’s own, UserFolders::current.
For a manager showing another person’s home, or a test that means a home of its own.
Sourcepub fn id(self, name: impl Into<String>) -> Self
pub fn id(self, name: impl Into<String>) -> Self
Names the rows, so Command::focus(name) gives them
the keyboard: an application that takes the person to another folder, from a list of
places, a path bar or a back button, sends it so ↑ and ↓ move through the new folder at
once.
The name is on the rows themselves, the tree, the list or the icons, whichever is drawn,
not on the column show answers with, which holds the foot too and takes no
focus. The rows are the same widget in all three views, so rows that have the keyboard
keep it when the view changes, named or not.
Sourcepub fn disabled(self, disabled: bool) -> Self
pub fn disabled(self, disabled: bool) -> Self
Draws the rows faint and answers nothing: no click, key, drag or menu, while the application has taken the folder away from the person.
Sourcepub fn show<'v>(self, ui: &'v mut View<'_, Msg>) -> NodeMut<'v, Msg>
pub fn show<'v>(self, ui: &'v mut View<'_, Msg>) -> NodeMut<'v, Msg>
Adds the manager to ui and answers with the column that holds it, to be given a size.
The column holds the rows and, in the list and the icons, the foot under them. It takes no
focus itself; id names the rows inside it, which do.
The dialog that asks for a name is added too while one is asked for; it is a layer and takes no room of its own.
Auto Trait Implementations§
impl<'a, Msg> !RefUnwindSafe for FileManager<'a, Msg>
impl<'a, Msg> !Send for FileManager<'a, Msg>
impl<'a, Msg> !Sync for FileManager<'a, Msg>
impl<'a, Msg> !UnwindSafe for FileManager<'a, Msg>
impl<'a, Msg> Freeze for FileManager<'a, Msg>
impl<'a, Msg> Unpin for FileManager<'a, Msg>
impl<'a, Msg> UnsafeUnpin for FileManager<'a, Msg>where
Rc<dyn Fn(FileManagerMsg) -> Msg>: UnsafeUnpin,
Option<Rc<dyn Fn(&Path) -> Msg>>: UnsafeUnpin,
Option<Rc<dyn Fn(&str, &[String]) -> Vec<ContextItem<Msg>>>>: UnsafeUnpin,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more