Skip to main content

EventSpec

Struct EventSpec 

Source
pub struct EventSpec {
Show 19 fields pub on_click: Option<Value>, pub on_drag: Option<Value>, pub on_key: Option<Value>, pub key_up: bool, pub modifier_keys: bool, pub on_context_menu: Option<Value>, pub on_force_click: Option<Value>, pub on_button: Option<Value>, pub buttons: Buttons, pub on_scroll: Option<Value>, pub scroll_axes: ScrollAxes, pub scroll_mods: KeyMods, pub on_hover: Option<Value>, pub on_drop: Option<Value>, pub on_layout: Option<Value>, pub on_change: Option<Value>, pub modal: Option<Value>, pub keep_focus: bool, pub on_focus: Option<Value>,
}
Expand description

Event payloads a node declares. Boxed on NodeSpec because most nodes declare none.

Fields§

§on_click: Option<Value>

Payload emitted as a UiEvent when this node is clicked.

§on_drag: Option<Value>

Makes this node draggable: pressing it starts a pointer-captured drag, and cursor motion until release emits UiEvents of the form {kind="drag", phase="start"|"move"|"end", x, y, dx, dy, tag} with this payload merged in under tag. A drag past the click slop suppresses the node’s on_click, so both can coexist.

§on_key: Option<Value>

Marks this node as a key sink: while it holds key focus, key presses arrive as UiEvents on it as {kind="key", phase="down", code, ...}, with this payload merged in under tag. Clicking the node takes key focus. Releases are not delivered unless the sink also declares key_up: a keymap is the common case, and a keymap that heard both halves would run every binding twice.

§key_up: bool

With on_key: the sink hears releases too, as the same payload with phase="up" (text null, repeat false). For a held-key interaction — WASD, press-and-hold to preview, a key that arms a mode while it is down. A key only comes up where it went down: a release whose press the sink never got is dropped, and focus leaving while a key is held delivers the up first, so nothing is left stuck down. Without it a sink hears presses only, which is what a keymap wants.

§modifier_keys: bool

With on_key: the modifier and lock keys themselves arrive too (Shift, Ctrl, Alt, Super, Caps Lock, Num Lock, Scroll Lock), as codes of their own with their side in location. Without it a modifier is only ever held — in the next key’s shift / ctrl / … and the modifiers event — so a keymap mid-sequence does not read Shift as a key between two others. A terminal speaking kitty’s keyboard protocol asks, and so does a game that binds a lone Shift.

§on_context_menu: Option<Value>

Asks for a context menu: a secondary-button press over this node emits {kind="contextmenu", x, y, tag} on it with this payload under tag, and does nothing else — the press moves no focus, places no caret and produces no click, so right-clicking a selection leaves it selected. x/y are the press in logical viewport coordinates, which is where the menu goes. Asked of the topmost node under the pointer; when that node offers no menu the press reaches the nearest enclosing node that does, the way an unclaimed key reaches the enclosing sink: the event carries the owner’s key and tag, a nested declaration wins over its ancestor’s, a disabled node’s own is skipped, and the walk stops at the modal boundary. Null = the behaviour without a tag.

§on_force_click: Option<Value>

Force-click events: a press that deepened past the second stage of a Force Touch trackpad over this node emits {kind="forceclick", x, y, tag} with this payload under tag. Routed as a secondary press is — no focus moved, no caret, no click — but asked of the topmost node only, with no walk to an enclosing declaration — and the ordinary click the press produces still follows, which is what macOS does.

Text does not need this: a force click over an editor or a selectable scope selects the word and asks the host to look it up, which is what the gesture means on that platform. This is for what the core cannot guess — a force click on a chart, a map, a timeline.

§on_button: Option<Value>

The non-primary buttons as events: a press of a button in buttons over this node emits {kind="button", phase="press", button, x, y, clicks, tag} on it with this payload under tag, and the button is then captured by the node — every pointer move while it is held arrives as phase="move" and its release as phase="release", on this node wherever the pointer is. button is "secondary", "middle" or, for a button past those, its crate::MouseButton::code; x/y are logical viewport coordinates, and on a cells grid the events carry cell: {row, col} as a click does. Several buttons may be held at once, each its own capture; a primary drag is untouched.

Asked of the topmost node under the pointer, and when that node claims no such button the press reaches the nearest enclosing node that does, as a context menu’s does: a disabled node’s own is skipped and the walk stops at the modal boundary. A claimed secondary press is this event instead of a contextmenu event and the stock menu — a nearer on_context_menu still wins, being the nested declaration. Like every non-primary press it moves no focus, places no caret and touches no selection or scrollbar. What it is for: a terminal’s middle-click paste, and the mouse reports a program in it asked for. Null = the behaviour without a tag.

§buttons: Buttons

Which non-primary buttons on_button claims: all three kinds unless the node says otherwise. A pane that wants the middle button and leaves the secondary one to its context menu says Buttons::MIDDLE.

§on_scroll: Option<Value>

Scroll events: the wheel over this node emits {kind="scroll", x, y, dx, dy, lines, tag} with this payload under tag — the delta in logical px as the driver reported it (positive dy is the wheel rolling up, toward earlier content), the pointer’s position, and on a cells grid the whole lines the delta covers (null on any other node), the fraction carried to the next notch. The node takes the wheel on the axes scroll_axes names: a scroll gesture that starts over it is its own, and stays its own until it ends wherever the pointer goes, except on an axis it also scrolls as a container (scroll_x, scroll_y, the offset the app sets from what it hears), where it is answered by its room as a container is: at its edge, a gesture that way passes to the scroller around it; it reaches no scroll container above it, and a container inside it still takes the axes it scrolls while it can move that way, passing this node the rest: the other axis, and a gesture that begins with the container at its limit (unless it says Overscroll::Contain). The core moves nothing — a grid’s origin_line and a canvas’s zoom are the app’s to change. A drag-select held past a grid’s top or bottom edge arrives here too, as the lines the frame scrolled by.

§scroll_axes: ScrollAxes

Which axes on_scroll takes: both unless the node says otherwise. A scroll gesture on an axis the node does not take passes it by, to the scroller around it — a terminal that scrolls its history on y says ScrollAxes::Y, and a sideways swipe that meets it goes on moving the strip it sits in. Meaningless without on_scroll.

§scroll_mods: KeyMods

The modifiers on_scroll is for (backlog F122): with any named, the node hears only a scroll gesture that began with one of them held — and hears it first, wherever in the tree under the pointer the gesture began: ahead of every scroll container and every handler that names none, the innermost such node winning. A wheel with none of them held passes it by as if it declared no on_scroll — a node that is a scroll container too scrolls for it as any other does. What a Ctrl-wheel zoom is declared with, on the window’s root or on the one canvas it zooms: a modified wheel is the more specific ask, and no list under the pointer scrolls for it. Its events carry mods, the modifiers held when the gesture began — the gesture stays this node’s to its end, glide included, whatever is let go meanwhile. None named (the default): a handler like any other. Meaningless without on_scroll.

§on_hover: Option<Value>

Hover events: the pointer entering or leaving this node emits {kind="hover", phase="enter"|"leave", tag} with this payload under tag — for hover-dependent layout (a close button that appears) where a color swap isn’t enough. Implies hover tracking.

§on_drop: Option<Value>

Drop-zone events: files dragged in from the OS over this node emit {kind="drop", phase="enter"|"move"|"leave"|"drop", paths, x, y, tag} with this payload under tag — paths the OS paths as strings, x/y the pointer in viewport coordinates (absent on leave). The zone under the files is the topmost zone by paint order: a node inside a zone resolves to it, and a node that is no zone and has none enclosing it is looked past, so an overlay shown on enter cannot make the zone lose the files. No leave follows a drop. Implies hover tracking.

§on_layout: Option<Value>

Layout events: the rect layout gave this node arrives as {kind="layout", x, y, w, h, parent: {x, y, w, h}, tag} (logical px, viewport coordinates, after scrolling and position easing) — on the node’s first frame and again whenever the rect changes, never on a frame that left it alone. The view reads the numbers layout already produced instead of re-deriving them; a transition that moves the node reports every frame it moves. Needs a stable key across frames.

§on_change: Option<Value>

Slider changes: on a node whose role is Slider, the core turns a press into the value under the pointer, a drag into the value under it, the arrows and assistive technology’s Increment / Decrement into one value_step, PageUp / PageDown into ten, Home / End into the range’s ends — clamped to value_min..value_max, snapped to the step — and emits {kind="change", value, phase="move"|"end", tag} with this payload under tag. The value is proposed, never applied: nothing moves until the view declares it as value_now. Without it a slider’s keys reach the app as the access nudge. Ignored on any other role.

§modal: Option<Value>

Modal: while this node is declared, the Tab ring is its subtree, everything outside it is inert to the pointer, the wheel and assistive technology, and Escape or a press outside emits {kind="dismiss", reason, tag} on it with this payload under tag. The last node declaring it in tree order is the one in effect (a confirm inside a dialog). Null = modal without a tag.

§keep_focus: bool

A press on this node, or anywhere inside it, leaves keyboard focus where it was (keepFocus): a toolbar button, a tab, a divider that acts without taking the keyboard from the editor beside it. Its click, drag and hover are unchanged, and Tab and assistive technology still reach a focusable node in it — it is the pointer’s press alone that stops moving focus.

§on_focus: Option<Value>

Keyboard focus entering or leaving this node’s subtree — the node itself or anything focused inside it — emits {kind="focus", phase="in"|"out", by, tag} with this payload under tag, where by is "pointer", "keyboard", "assistive" or "program": what moved it. Reported once the move has settled — after the input that made it, or at the end of the frame that declared it — so a view reads a change instead of diffing key_focus every frame. Declares nothing interactive.

Implementations§

Source§

impl EventSpec

Source

pub const EMPTY: EventSpec

The group as a node that declares none of it — what NodeSpec’s accessor hands back when the box is None.

Trait Implementations§

Source§

impl Clone for EventSpec

Source§

fn clone(&self) -> EventSpec

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for EventSpec

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Default for EventSpec

Source§

fn default() -> EventSpec

Returns the “default value” for a type. Read more
Source§

impl PartialEq for EventSpec

Source§

fn eq(&self, other: &EventSpec) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for EventSpec

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send> ⓘ

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<T> NoneValue for T
where T: Default,

Source§

type NoneType = T

Source§

fn null_value() -> T

The none-equivalent value.
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more