Skip to main content

StyledContainer

Struct StyledContainer 

Source
pub struct StyledContainer { /* private fields */ }

Implementations§

Source§

impl StyledContainer

Source

pub fn new( layout_style: LayoutStyle, style: impl Fn(Rect) -> RectStyle + 'static, children: Vec<Box<dyn LayoutItem>>, ) -> Result<Self, LayoutError>

Source

pub fn from_slots( layout_style: LayoutStyle, style: impl Fn(Rect) -> RectStyle + 'static, slots: Vec<ChildSlot>, ) -> Result<Self, LayoutError>

A styled box whose children are a mix of static widgets and reactive fragments (ChildSlots), reconciled into this box’s own node so they inherit its flex direction/gap — the transparent box-with-a-for path (see Container::from_slots).

Source

pub fn with_opacity(self, opacity: impl Fn() -> f32 + 'static) -> Self

Source

pub fn with_transform( self, transform: impl Fn(Rect) -> Option<[f32; 6]> + 'static, ) -> Self

Apply an affine transform (rotate/scale/translate) to the whole box each view(). The closure takes the laid-out rect and returns the 2×3 matrix, or None for identity.

Source

pub fn hover_style(self, f: impl Fn(Rect) -> RectStyle + 'static) -> Self

Paint the box with f while the mouse hovers it (a declarative style swap, like Button). Hover is mouse-only; touch never sets it, so a tap leaves no stuck hover state.

Source

pub fn active_style(self, f: impl Fn(Rect) -> RectStyle + 'static) -> Self

Paint the box with f while a primary pointer is held down inside it — the pressed / CSS :active state, which takes precedence over hover_style. Unlike hover it tracks touch as well as mouse, and it clears on release, on leaving the box, or once the press drags off, so it never sticks.

Source

pub fn disabled(self, f: impl Fn() -> bool + 'static) -> Self

Marks the box unusable while f reads true: it stops taking the pointer, stops tracking hover and the pressed state, stops showing its cursor, and paints its disabled_style ahead of every other state.

Closed here rather than left to each widget because the web never asks anyone to write it: disabled is platform semantics that a selector and the hit-tester read for free, and a catalogue that made every component re-implement it would get a different subset right in each one. The failure it prevents is small and immediate — a control the application has already disabled still lighting up under the pointer and still showing a hand cursor, which says “press me” about something that will do nothing.

Source

pub fn disabled_style(self, f: impl Fn(Rect) -> RectStyle + 'static) -> Self

The paint for the disabled state, which wins over the pressed and hover ones.

Source

pub fn control(self, role: Role) -> Self

The focus ring: drawn over whichever state won, while the box holds focus and should show it.

Composed rather than swapped, unlike the other three, and the difference is the point. Hover, pressed and disabled are answers to “what is this box doing”, so one of them replaces the rest. A ring answers a different question — where the keyboard is going — and a hovered box that lost its ring would hide that answer at the exact moment the user reached for the mouse. Which is why CSS gives focus its own property (outline) rather than another background.

Only the properties the ring names are applied; radius always comes from the box, since a ring sits on a shape it does not get to reshape. Shown on focus::is_focus_visible, so a tap takes focus without drawing one. Declares this box a control, and is the way to build one.

One call because the three halves are one fact, and each alone is a control that does not work: a box that takes a tap but never a key, a ring on something Tab cannot reach, a thing announced to a screen reader that cannot say what it is. Splitting them across three optional builders is how nine catalogue components shipped answering the mouse and nothing else — every one of them compiled, and looked right.

It joins the tab order at this node, answers Enter and Space the way it answers a tap, draws the theme’s focus ring while the keyboard is what reached it (see focus::is_focus_visible), and reports role outwards. A caller that wants a ring of its own still says so with focus_style; this only supplies one when nothing else has.

Deliberately not implied by on_press: a scrim, a click-away backdrop and a drag surface all take presses and none of them is a place the keyboard should stop.

Source

pub fn toggled(self, state: impl Fn() -> bool + 'static) -> Self

Declares that this control carries a checked state, and how to read it.

Only meaningful after control, and only for the roles that have one. Without it a reader announces “checkbox” and stops — and a default of “unticked” would be worse, since it would be confidently wrong for half of them.

Source

pub fn valued(self, read: impl Fn() -> NumericValue + 'static) -> Self

Declares the number this box carries, so a reader says where a slider stands and not only that it is one. The counterpart of toggled for a control whose state is a value.

Source

pub fn focus_style(self, f: impl Fn(Rect) -> RectStyle + 'static) -> Self

Source

pub fn cursor(self, cursor: Cursor) -> Self

Shows cursor while the pointer is over this box, and restores the default when it leaves.

The shape is the app’s statement of what the next press will do — orbit, resize a panel, place a point — so it belongs to the widget that would handle that press, not to a mode the app tracks.

Source

pub fn click_through(self, through: bool) -> Self

Declares that this box does not stand between the pointer and whatever it is drawn over — CSS’s pointer-events: none, and the second consumer of the hook [Overlay] opened.

A box covers what is behind it: since the hit-test walks in paint order, the topmost child under the pointer takes the event whether or not it wants it. That is right for a panel and wrong for a label — a readout floating over a canvas, a badge over a photo, a drag ghost — which is drawn on top precisely so it can be read, and whose whole contract is that the thing underneath still works. A modeller’s transform readout sits across the top of the viewport it reports on; without this, moving the pointer under it stops the operation it is describing.

It is a property of this box only. Children still hit-test normally, so a click-through bar can hold a real button — the same split CSS makes with pointer-events: auto on a child.

Source

pub fn keeping(self, subscription: Effect) -> Self

Give this widget ownership of an Effect, so it runs for exactly as long as the widget exists.

The reactive runtime scopes an effect to the surface it was registered on, which is the right span for a shell-wide subscription and far too coarse for one row of a list: the row goes, the effect stays, and it keeps firing at a node that is gone. Dropping the handle instead is the opposite failure — the effect deregisters, runs once, and stops, with nothing to say so. This is the third answer, and the one an effect that belongs to a widget wants.

Chainable, so several effects can be kept without nesting anything.

Source

pub fn styled_by(self, style: impl Fn() -> LayoutStyle + 'static) -> Self

Keeps the box’s layout style in step with the reactive state it was built from — the theme’s metric tokens, today. style runs now, and again whenever a signal it read changes; the node is restyled in place, so a live theme switch re-spaces the box as well as re-colouring it.

Paint needs nothing like this: a rect or text style is a closure the renderer re-runs every frame, so a token read inside one is already live. A layout style is a value, handed to the layout tree once when the node is made — which is why the reactive read has to be arranged here rather than coming for free.

Give new the same builder, so the node starts at the style it will settle on: StyledContainer::new(shell(), paint, kids)?.styled_by(shell).

Source

pub fn on_press(self, f: impl Fn() + 'static) -> Self

Make the box itself pressable. The callback fires on a tap (release, not press) inside the box; a child widget that handles the press wins, and a scroll gesture started on the box does not fire it.

Source

pub fn maybe_on_press(self, f: Option<impl Fn() + 'static>) -> Self

on_press for a handler the caller may not have supplied.

What a wrapper component needs to forward an optional callback. A box whose press handler is a no-op still reports the tap Handled, so “no handler” would become “swallows the click” — a display-only chip eating a press instead of letting it through. None leaves the box exactly as it was; the maybe_* pairs below say the same for every other event whose absence the box can observe.

Source

pub fn on_alt_press(self, f: impl Fn(PointerButton) + 'static) -> Self

Fire f(button) on a tap with a non-primary button — Secondary (right) or Auxiliary (middle). Same tap-on-release semantics as Self::on_press: a child that handles the press wins, and travel past the tap slop cancels it.

Opt-in per box rather than folded into on_press, because a non-primary press otherwise falls through to whatever is behind it — silently swallowing right-clicks on every pressable box would break that.

Source

pub fn maybe_on_alt_press( self, f: Option<impl Fn(PointerButton) + 'static>, ) -> Self

on_alt_press for a handler the caller may not have supplied.

Source

pub fn on_long_press(self, f: impl Fn() + 'static) -> Self

Fires once a press inside the box is held past ~500ms without moving past the tap slop, instead of on_press’s tap-on-release. There is no dedicated timer in the gesture pipeline, so the threshold is only checked on the next pointer event after the press (a move or the release) — it fires slightly late, never at exactly 500ms, and a release before that next check-in is a normal tap.

Source

pub fn maybe_on_long_press(self, f: Option<impl Fn() + 'static>) -> Self

on_long_press for a handler the caller may not have supplied.

Source

pub fn on_drag_end(self, f: impl Fn(f32, f32) + 'static) -> Self

Make the box draggable. The callback fires with the pointer position (layout space) on a press inside the box and on every move until release — even after the pointer leaves the box. Map the coordinate to a value (slider) or an offset (reorder/resize). Fires once when a drag started on this box ends, with the position it finished at (layout space, local to the box, same as on_drag).

This is what makes a threshold gesture expressible: on_drag alone reports where the pointer is but never that it let go, so a swipe-to-dismiss or a drag-to-open can be tracked and never decided. A drag also ends when the pointer leaves the window or a child consumes the release; those carry no position, so the last one the drag reached is reported instead — the gesture always ends exactly once.

Source

pub fn maybe_on_drag_end(self, f: Option<impl Fn(f32, f32) + 'static>) -> Self

on_drag_end for a handler the caller may not have supplied.

Source

pub fn on_drag(self, f: impl Fn(f32, f32) + 'static) -> Self

Source

pub fn maybe_on_drag(self, f: Option<impl Fn(f32, f32) + 'static>) -> Self

on_drag for a handler the caller may not have supplied.

Source

pub fn drag_button(self, button: PointerButton) -> Self

Let button start the drag too, on top of the primary one that always does.

A slider or a splitter wants exactly one button and gets it by default. A surface with more than one thing to drag needs the others: a modeller orbits with the primary button and pans with the secondary, which is what the OS and every 3D application call those gestures. The handler is the same one — read crate::pointer_buttons inside it to tell which button is doing the dragging.

Source

pub fn drag_threshold(self, px: f32) -> Self

How far the pointer must travel before this box counts as being dragged.

Without it a press is a drag from its first instant, which is right for a slider — pressing the track is how you set the value — and wrong for anything where a click and a drag mean different things on the same button. A viewport is the case: a click picks what is under it, a drag orbits, and telling them apart is the difference between selecting something and nudging the camera by a pixel.

Set it and the two stop overlapping: a stroke that never travels this far fires only on_press, one that does fires only the drag handlers, and neither fires both.

Source

pub fn on_hover(self, f: impl Fn(bool) + 'static) -> Self

Fire f(true) when the mouse enters the box and f(false) when it leaves (mouse only). Independent of hover_style: a box can observe hover without swapping its paint.

Registers the box as a pointer target, like on_scroll does for the same reason: a surface that carves its input region from its content (a click-through overlay) never receives a move event over a box it left out of that region, so a hover it did not register is a hover it can’t observe.

Source

pub fn maybe_on_hover(self, f: Option<impl Fn(bool) + 'static>) -> Self

on_hover for a handler the caller may not have supplied.

Source

pub fn on_pointer_move(self, f: impl Fn(f32, f32) + 'static) -> Self

Fire f(x, y) with the pointer position — local to the box, as on_drag reports it — on every move over it.

The continuous half of on_hover, which reports only the crossings. It is what a surface that answers to where the pointer is needs: highlighting the face under the cursor, previewing a snap, stretching a dimension line. Fires for touch as well as mouse, since a drag on a touchscreen asks the same question.

Source

pub fn maybe_on_pointer_move( self, f: Option<impl Fn(f32, f32) + 'static>, ) -> Self

on_pointer_move for a handler the caller may not have supplied.

Source

pub fn on_scroll(self, f: impl Fn(f32, f32) + 'static) -> Self

Fire f(dx, dy) with the wheel delta while the pointer is over the box — scroll-to-adjust on a control (a volume or brightness chip, a stepper), or zoom on a viewport. Deltas are normalised to pixels, matching ScrollArea: a line delta counts as 20px, so one wheel notch is roughly ±60.

Targeted by hit-testing the wheel’s own position, so it answers a wheel that arrives before the pointer has moved at all. A scrollable child (a scroll area inside the box) gets first refusal and keeps it.

Source

pub fn maybe_on_scroll(self, f: Option<impl Fn(f32, f32) + 'static>) -> Self

on_scroll for a handler the caller may not have supplied.

Source

pub fn on_key(self, f: impl Fn(&Key) + 'static) -> Self

Fire f(&key) on every key press. This is a GLOBAL handler (key events reach every widget; there is no per-widget focus), so it suits app-level shortcuts, not focused text entry.

It stands aside while a text entry holds focus and the press is text it would take (focus::text_entry_takes_key) — so a shortcut on 3 does not also fire when the user types 3 into a field, while ⌘S still reaches it. Read the modifiers with crate::modifiers: key events carry them, but pointer events do not, so the state registry is the one answer that works everywhere.

Source

pub fn maybe_on_key(self, f: Option<impl Fn(&Key) + 'static>) -> Self

on_key for a handler the caller may not have supplied.

Source

pub fn on_focus(self, f: impl Fn(bool) + 'static) -> Self

Make the box focusable and fire f(true)/f(false) when it gains/loses keyboard focus. It joins the tab order (Tab/Shift-Tab reach it) and takes focus on tap. Use it to drive a focus ring or to build a custom focusable widget on top of a box.

Source

pub fn maybe_on_focus(self, f: Option<impl Fn(bool) + 'static>) -> Self

on_focus for a handler the caller may not have supplied.

Trait Implementations§

Source§

impl Component for StyledContainer

Source§

fn view(&self) -> RenderNode

Source§

fn on_event(&mut self, event: &Event) -> EventResult

Source§

fn debug_name(&self) -> &'static str

Human-readable widget type name for the devtools tree inspector.
Source§

impl Drop for StyledContainer

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl LayoutItem for StyledContainer

Source§

fn layout_node(&self) -> NodeId

Source§

fn pointer_opaque(&self) -> bool

Whether this widget stands in front of whatever its siblings drew underneath it, for a pointer event its parent is hit-testing. Read more

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<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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> 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