pub struct NodeMut<'a, Msg> { /* private fields */ }Expand description
Adjusts the node just added. Every method changes the node in place, so the result can be ignored or chained.
Implementations§
Source§impl<'a, Msg> NodeMut<'a, Msg>
impl<'a, Msg> NodeMut<'a, Msg>
Sourcepub fn id(self, name: impl Into<String>) -> Self
pub fn id(self, name: impl Into<String>) -> Self
Names the node. Name widgets whose position among their siblings can change (list rows, optional widgets) so their state and focus follow them.
Sourcepub fn fill_width(self) -> Self
pub fn fill_width(self) -> Self
Takes all width left.
Sourcepub fn fill_height(self) -> Self
pub fn fill_height(self) -> Self
Takes all height left.
Sourcepub fn justify(self, align: Align) -> Self
pub fn justify(self, align: Align) -> Self
Places children along the main axis of a row or column (both axes of a stack).
Sourcepub fn selectable(self, selectable: bool) -> Self
pub fn selectable(self, selectable: bool) -> Self
Whether a mouse drag may select text in this node. Nothing is selectable unless asked:
true makes the node a selection region, so a drag that starts inside it selects text
within the node only (widgets such as CodeView and Markdown are regions by
themselves). false keeps selection out of the node and everything inside it, also out
of regions within it, e.g. for a secret shown inside a selectable log.
Source§impl<Msg: Clone + 'static> NodeMut<'_, Msg>
impl<Msg: Clone + 'static> NodeMut<'_, Msg>
Sourcepub fn on_action(
self,
scope: Scope,
action: impl Into<String>,
message: Msg,
) -> Self
pub fn on_action( self, scope: Scope, action: impl Into<String>, message: Msg, ) -> Self
While keyboard focus is on this node or inside it, a key bound to the keymap action
action of scope sends message instead of reaching App::action.
This is how an application tells where a shortcut was pressed. With focus elsewhere the
same key reaches App::action as usual, so one key can mean two things: leave a
terminal while inside it, go back into it from outside. The focus in force when the key
arrives decides, however it got there (tab, a click, Command::focus),
so nothing has to be tracked in application state.
The innermost node that answers the action wins. The key must first get past the focused
widgets: a widget that uses it (a text field typing a character) keeps it, and a
Terminal lets it out only for actions named with its
pass_through. The actions the runtime owns (quit, focus-next, focus-prev,
debug, copy, paste, toggle-panel) are not answered here; the keys of copy and
paste are claimed with on_clipboard instead. Call once per action.
use qframe::env::Env;
use qframe::prelude::*;
use qframe::widgets::TextInput;
#[derive(Clone, Debug, PartialEq)]
enum Msg {
Leave,
Enter,
}
struct Editor;
impl App for Editor {
type Msg = Msg;
fn update(&mut self, msg: Msg) -> Command<Msg> {
match msg {
Msg::Leave => Command::focus("files"),
Msg::Enter => Command::focus("note"),
}
}
fn view(&self, ui: &mut View<'_, Msg>) {
ui.add(List::new(["notes.md", "todo.md"].map(ListItem::new))).id("files");
ui.add(TextInput::new("")).id("note").on_action(Scope::App, "switch", Msg::Leave);
}
// Reached only while focus is outside the note.
fn action(&self, name: &str) -> Option<Msg> {
(name == "switch").then_some(Msg::Enter)
}
}
let mut env = Env::builtin();
env.keymap_mut().bind(Scope::App, "switch", &["alt+s".parse().unwrap()]);
let mut app = Harness::with_env(Editor, env, 30, 3);
app.press("alt+s");
assert!(app.is_focused("note"));
app.press("alt+s");
assert!(app.is_focused("files"));Sourcepub fn on_clipboard(self, key: ClipboardKey, message: Msg) -> Self
pub fn on_clipboard(self, key: ClipboardKey, message: Msg) -> Self
While keyboard focus is on this node or inside it, the clipboard key key sends
message: a list of things other than text, such as a file manager’s rows, cuts, copies
and pastes its own entries with the keys a text field uses for text.
The keys are claimed, not taken away. Every place text is copied from keeps them first:
- Text selected with the mouse is what Ctrl+C copies while it is there, wherever the focus is, and while it is there Ctrl+X and Ctrl+V are not claimed either: the person is working with that text, not with the node.
- The focused widget sees the key before the node does, so a text field inside the node
copies and cuts its own text. Pasting into a field goes through the runtime’s
pasteaction, which a claim ofClipboardKey::Pasteanswers first, so a node that holds a field claims only the keys it does not share with it. - With focus outside the node, the keys do what they do without it.
This rides on the same answering as on_action, one step after it in
the key’s way and for the runtime’s own copy and paste, which on_action never answers,
and for Ctrl+X, which has no keymap action. A widget could match the chords in its own key
handling instead, as a text field does, but then every list, table and grid would need a
way to be told what the keys mean; claiming them on the node gives that to anything that
can be focused. The innermost node that claims a key wins. Call once per key.
use qframe::prelude::*;
use qframe::widget::ClipboardKey;
#[derive(Clone, Debug, PartialEq)]
enum Msg {
Copy,
}
struct Shelf {
copied: bool,
}
impl App for Shelf {
type Msg = Msg;
fn update(&mut self, msg: Msg) -> Command<Msg> {
match msg {
Msg::Copy => self.copied = true,
}
Command::none()
}
fn view(&self, ui: &mut View<'_, Msg>) {
ui.add(List::new(["a.txt", "b.txt"].map(ListItem::new)))
.id("shelf")
.on_clipboard(ClipboardKey::Copy, Msg::Copy);
}
}
let mut app = Harness::new(Shelf { copied: false }, 20, 3);
app.press("ctrl+c");
assert!(!app.app().copied, "nothing is focused yet");
app.press("tab").press("ctrl+c");
assert!(app.app().copied);Source§impl<Msg: 'static> NodeMut<'_, Msg>
impl<Msg: 'static> NodeMut<'_, Msg>
Sourcepub fn wrap(self, wrap: bool) -> Self
pub fn wrap(self, wrap: bool) -> Self
Moves the children of a row that do not fit to the next line, instead of letting them run past the row’s edge. Off by default; a row whose children fit lays out exactly as it does without it.
Lines are filled in order: each child takes the width it measures, and a child that does not fit after the ones already on the line starts the next line. A child wider than the whole row gets a line of its own and the row’s width, where it narrows or cuts as it does in any row too narrow for it. The row measures as tall as all its lines, so the widgets after it move down.
Every line is laid out as a row of its own: gap falls between the
children of a line, never at its start or end; justify places each
line in the room it leaves; a spacer or another filling child takes
what is left on its own line. A spacer stays on the line of the child before it; when
that line has no room even for the gap before it, the spacer is left out, since at the
start of the next line it would only push that line away from the edge.
Lines touch; line_gap puts empty rows between them. The option has
no effect on anything but a row.
use qframe::prelude::*;
fn actions(ui: &mut View<'_, ()>) {
ui.row(|ui| {
ui.add(Button::new("Install").on_press(()));
ui.add(Button::new("Show the command").on_press(()));
ui.add(Button::new("Cancel").on_press(()));
})
.gap(1)
.wrap(true);
}Auto Trait Implementations§
impl<'a, Msg> !RefUnwindSafe for NodeMut<'a, Msg>
impl<'a, Msg> !Send for NodeMut<'a, Msg>
impl<'a, Msg> !Sync for NodeMut<'a, Msg>
impl<'a, Msg> !UnwindSafe for NodeMut<'a, Msg>
impl<'a, Msg> Freeze for NodeMut<'a, Msg>
impl<'a, Msg> Unpin for NodeMut<'a, Msg>
impl<'a, Msg> UnsafeUnpin for NodeMut<'a, Msg>where
&'a mut Node<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