ViewId
ViewId is view's identifier and operation handle in Flor runtime. View tree, layout state, event handlers, focus table, scroll state, mouse capture and render resources are all associated to same view through it.
This page targets two scenarios: operating current view in event callbacks, or accessing runtime capabilities through self.view_id in custom view implementation. When only want to configure focus order, prefer reading Focus Builder.
Getting ViewId
Event builder callbacks pass target view's ViewId as first parameter:
Custom views usually save ViewId as field, and create in constructor:
ViewId::new() registers basic ViewState and ViewHandler. ViewId::new_with_layout(...) allows customizing LayoutResolver when creating, generally only used when underlying views or layout system need to take over the initial layout resolver.
Redraw Request
This is Flor view development's highest-level hard rule, please strictly follow it.
No matter whether your view runs in immediate mode or retained mode, whenever internal visual-affecting properties change, must call view_id.request_redraw().
Flor won't automatically track view internal field changes. If you modified color, text, image handle, animation state or any field affecting drawing result, but don't call request_redraw(), window won't redraw, user won't see change.
This rule applies to:
- After updating fields in
on_update_state - After advancing animation state in
on_frame - After modifying internal state in event callbacks
- After changing visual properties in any custom method
If you find visual not updating when implementing custom view, first check whether missed request_redraw() call. Other view development chapters will repeatedly emphasize this point, for example View Trait's lifecycle hooks.
State and Layout
ViewId can read current view's layout and state:
layout() returns Taffy calculated taffy::Layout. abs_location() returns absolute position relative to window top-left corner, this value is written to cache when layout refreshes.
with_state and with_state_mut are closure-style access interfaces: they only hold internal state lock during closure execution. Don't do long-time work in closure, also don't save borrowed state reference out.
get_current_style() and with_current_style(...) read style by current ControlState. Current state affects resolver choosing normal, hover, focus, active or disabled variant.
State Update
update_state hands arbitrary Box<dyn Any> to view instance's View::on_update_state, then requests redraw:
View needs to downcast and update internal fields in its own on_update_state. For example text, image handle, style update objects — these kinds of view private state are all suitable for going through this path.
If enabled class feature, update_class(layer_id, class_str) parses class name, updates layout resolver, and calls view's on_update_class(control_state, class). z-* classes will be recognized as z-index and removed from class list.
View Tree and Window
ViewId records view's relationship in tree and belonging window:
push_view adds child view to current view, rebuilds subtree window attribution, and triggers parent view's on_child_push. Application layer usually organizes tree through ViewBuilder::views, ViewBuilder::push_view or views![] macro; directly calling ViewId::push_view is more suitable for runtime appending child views.
Focus Manipulation
User-side explanation of focus mechanism see Focus Mechanism. Here lists runtime methods related to focus on ViewId.
update_focus_index
update_focus_index updates at runtime whether view participates in focus table.
Some(0) is legal sort value. Only None indicates exiting the focus system.
Current implementation updates by single focus entry: it first removes this ViewId's existing focus entries, then inserts (index, view_id, 0) when Some(index). If view developer implemented multiple virtual focus, initializing focus table will expand by on_focus_count(); runtime update_focus_index currently only inserts virtual focus 0.
set_focus
set_focus sets or cancels current focus.
set_focus(Some(index)) requires this (ViewId, virtual_index) already exists in focus table. Views without focus_index set won't be successfully focused. When passing non-existent virtual focus number, method won't change current focus.
set_focus(None) only clears focus held by this ViewId: if current focus is on it, will trigger blur and let window enter no current focus state; if current focus is on other view, won't clear other view.
is_focused
is_focused judges whether current focus is on this ViewId, doesn't distinguish virtual focus number.
push_focus_scope and pop_focus_scope
These two methods are for runtime focus scope. When opening Modal, Popup, Sidebar, push root view into scope; when closing, pop scope.
After pushing into scope, Tab and Shift+Tab only cycle in this root view's subtree. pop_focus_scope will pop current scope, and try to restore focus before entering scope.
View State
ViewId can judge view's runtime interaction state:
control_state() priority is Disabled > Active > Focus > Hover > Normal. control_state_with_pressed(pressed) allows view to calculate ControlState with a temporary pressed state, but it only considers Disabled, passed pressed, Hover and Normal.
is_active() queries framework recorded pressed state. is_hover() queries belonging window's current hover target.
Visibility and Layer
z_index controls drawing and hit order under same parent node:
set_z_index() updates z-index in storage, and re-sorts sibling child nodes when having parent node.
visual() returns whether current view was marked as visible in most recent draw. Framework internally uses it to skip invisible views' on_frame, custom views generally only need to know: this value comes from drawing phase's visibility cache, not complete replacement of layout style.
Scroll
Scroll capability becomes effective after view registers ScrollState:
scroll_to and scroll_by clamp target value to 0.0..=max. If this ViewId didn't register scroll state, these methods won't change anything. When scroll position changes, will request redraw.
Mouse Capture
When dragging, scrollbar dragging, holding mouse then continuing to track movement, can capture mouse:
After capturing, window records capture_view_id, platform layer also enters mouse capture state. After releasing, events return to normal hit test path.
Transform and Coordinate Conversion
Declarative transform affects view itself and child views' drawing, layout's accumulated transform and hit test:
set_transform and clear_transform request redraw. After layout refresh, framework calculates each view's accumulated transform. When needing to convert window coordinates to view local coordinates, can use:
If no accumulated transform, or transform not invertible, this method returns original coordinates.
Render Resource Loading
ViewId implements LoadRenderResource, can use belonging window's renderer to create image resources:
load_raw_image supports raw frame data and frame delay. After enabling svg feature can also call load_svg. If current ViewId can't find corresponding renderer, these methods return FlorRendererError::RenderNotFound.

