Skip to main content

Application

Trait Application 

Source
pub trait Application {
    type Message: Clone + Send + 'static;

Show 42 methods // Required methods fn update(&mut self, message: Self::Message) -> Command<Self::Message>; fn view(&self, theme: &Theme) -> Box<dyn Widget<Self::Message>>; // Provided methods fn init(&mut self) -> Command<Self::Message> { ... } fn effects(&mut self) -> Command<Self::Message> { ... } fn location(&self) -> Option<String> { ... } fn location_replaces(&self) -> bool { ... } fn location_stack(&self) -> Vec<String> { ... } fn open_location(&mut self, location: &str) -> Command<Self::Message> { ... } fn instance_id(&self) -> Option<String> { ... } fn location_strategy(&self) -> LocationStrategy { ... } fn subscription(&self) -> Subscription<Self::Message> { ... } fn tray(&self) -> Option<Tray<Self::Message>> { ... } fn taskbar(&self) -> Taskbar { ... } fn global_shortcuts(&self) -> Vec<GlobalShortcut<Self::Message>> { ... } fn theme(&self) -> Theme { ... } fn dark_theme(&self) -> Option<Theme> { ... } fn theme_mode(&self) -> ThemeMode { ... } fn high_contrast_theme(&self) -> Option<Theme> { ... } fn high_contrast_dark_theme(&self) -> Option<Theme> { ... } fn resolved_theme( &self, brightness: Brightness, high_contrast: bool, ) -> Theme { ... } fn theme_animation_duration(&self) -> f32 { ... } fn theme_animation_curve(&self) -> Curve { ... } fn tick(&mut self, _dt: f32) -> bool { ... } fn title(&self) -> String { ... } fn icon(&self) -> AppIcon { ... } fn window_size(&self) -> Option<(f32, f32)> { ... } fn accessibility(&self) -> AccessibilityOverrides { ... } fn density(&self) -> f32 { ... } fn scroll_behavior(&self) -> ScrollBehavior { ... } fn supported_locales(&self) -> Vec<Locale> { ... } fn locale(&self) -> Option<Locale> { ... } fn resolved_locale(&self, preferred: &[Locale]) -> Locale { ... } fn localizations(&self) -> Option<Rc<dyn Localizations>> { ... } fn on_resize(&mut self, _width: f32, _height: f32) { ... } fn on_lifecycle(&mut self, _state: Lifecycle) { ... } fn on_insets(&mut self, _insets: WindowInsets) { ... } fn save_state(&self) -> Option<Vec<u8>> { ... } fn restore_state(&mut self, _bytes: &[u8]) { ... } fn can_go_back(&self) -> bool { ... } fn back_gesture(&mut self, _progress: f32) { ... } fn back_gesture_end(&mut self, _velocity: f32) { ... } fn go_back(&mut self) { ... }
}
Expand description

What an application supplies to the framework: an Elm-style message model.

Required Associated Types§

Source

type Message: Clone + Send + 'static

The message type the interface emits and Application::update consumes.

Send + 'static, because effects (Command) cross threads.

Required Methods§

Source

fn update(&mut self, message: Self::Message) -> Command<Self::Message>

Advances the state in response to a message, and returns the effects to run: I/O, background tasks and the like. Use Command::none for none.

Source

fn view(&self, theme: &Theme) -> Box<dyn Widget<Self::Message>>

Builds the widget tree for the current theme.

It is not told the size. The framework installs a description of the surface — its size, its pixel ratio, the intrusions the platform last reported — around every call to this, and any widget built here reads it with MediaQuery::of(). A Scaffold takes no size because of that, and neither does an AppBar or a Navigator.

That is the reference’s arrangement, and it is not a convenience: a size passed as an argument gets carried down by hand, arithmetic gets done on it, and one of those subtractions is eventually wrong. Milestone 392 is what that looks like when it happens — a whole screen laid out to the width of its widest line.

Provided Methods§

Source

fn init(&mut self) -> Command<Self::Message>

The effect to run at startup, such as an initial load.

Source

fn effects(&mut self) -> Command<Self::Message>

Effects the application asked for outside an update — from a build, say, or from a component that has no message to return them with. The shell asks after every frame and after every message, and runs what comes back like any other command. An application that returns its effects from update never needs it.

Source

fn location(&self) -> Option<String>

Where the application is, as an address: /users/42?tab=posts. None — the default — for an application with no addresses, which the shell then leaves alone.

On the web the shell asks after every message and every frame, and shows the answer in the address bar: a new location becomes a new entry of the browser’s history, going back to a location the history already holds goes back in it rather than adding one, and the very first answer replaces the address the page was opened at instead of adding to it — so a redirect on the way in leaves no entry to be trapped by. Other platforms have nowhere to show it yet.

Source

fn location_replaces(&self) -> bool

Whether the move that led to location swapped the page — a router’s replace — rather than adding one. The browser’s entry is then swapped too, instead of a new one being added behind it. false by default.

Source

fn location_stack(&self) -> Vec<String>

The locations of the pages beneath the one shown, the lowest first, and location last. Used once, when the page is opened at an address deep in the application: the browser’s history is made to hold the pages beneath too, so that going back — the application’s own or the browser’s — has somewhere to land inside the application. The default is the location alone.

Source

fn open_location(&mut self, location: &str) -> Command<Self::Message>

A location was asked for from outside: the address the page was opened at, or the one the browser’s back and forward buttons landed on. Move to it — or to wherever it redirects, and the shell corrects the address bar to match. Called with a location the application may already be at; that is a no-op to do, not to report.

The launch address is delivered once, before the first frame, and only when the address carried one: a bare page keeps the application’s own start.

Source

fn instance_id(&self) -> Option<String>

Whether the application is one window, and its name: on a desktop, a second process started with a link — the operating system’s way of opening myapp://orders/42 — hands the link to the first and ends, instead of opening a second window. None, the default, lets every process be its own.

The name tells this application from the others on the machine; a reverse domain (com.example.myapp) is what one is. Links reach open_location as locations — see location_of_link.

Source

fn location_strategy(&self) -> LocationStrategy

How location is written in the address bar. See LocationStrategy.

Source

fn subscription(&self) -> Subscription<Self::Message>

Continuous sources of messages — timers and so on — declared from the state. The framework starts and stops them by diffing every cycle.

Source

fn tray(&self) -> Option<Tray<Self::Message>>

The application’s tray icon, declared from the state like its subscriptions: built when one is declared, changed when the description changes, taken away when there is none. See Tray. Acted on on the desktop with the tray feature; ignored elsewhere.

Source

fn taskbar(&self) -> Taskbar

What the application’s taskbar button shows — a count, a progress — declared from the state and followed by the shell. See Taskbar. Acted on on the desktop with the taskbar feature; ignored elsewhere.

Source

fn global_shortcuts(&self) -> Vec<GlobalShortcut<Self::Message>>

The application’s global shortcuts — combinations that reach it from any window — declared from the state: registered when declared, given back when withdrawn. See GlobalShortcut. Acted on on the desktop with the global-shortcuts feature; ignored elsewhere.

Source

fn theme(&self) -> Theme

The application’s theme — its light one, where it has two (app.dart:425).

This is the whole answer for an application with a single theme. One that follows the system supplies a dark_theme beside it and lets theme_mode choose; the framework resolves the pair every frame and fades between them, so nothing here has to be an animated blend and no application needs to hold a fade’s progress in its own state.

The default is the light theme, which is the reference’s (app.dart:415). It was dark here until milestone 452 named this slot the light one: a theme() that answers dark and a dark_theme() beside it is a contradiction an application would have had to work around.

Source

fn dark_theme(&self) -> Option<Theme>

The theme to use when a dark interface is asked for (app.dart:447).

None — the default — means the application has only the one theme, and Application::theme is used whatever the platform reports. Answer with a dark theme and the framework switches to it by itself, following Application::theme_mode.

This is the hook that makes the platform’s brightness usable. The shell has reported it since milestone 380 — MediaQuery::platform_brightness, read from the window manager on desktop and from the system settings on Android — but until an application could name a second theme there was nothing to switch to, and every application that wanted to follow the system had to read the brightness and write the crossfade itself.

Source

fn theme_mode(&self) -> ThemeMode

Which of the two themes is on display (app.dart:502): the platform’s choice by default, or one of them pinned.

ThemeMode::System follows MediaQuery::platform_brightness, which is what an application with a System / Light / Dark setting leaves it on until the reader picks one of the other two.

Source

fn high_contrast_theme(&self) -> Option<Theme>

The theme to use when the platform asks for higher contrast (app.dart:460); None falls back to Application::theme.

The setting is the reader’s, reported by the platform and readable at Accessibility::high_contrast. A design that already meets the contrast ratios has nothing to add here, which is why the default is to add nothing.

Source

fn high_contrast_dark_theme(&self) -> Option<Theme>

The theme for a dark, high-contrast interface (app.dart:476); None falls back to Application::dark_theme, then to Application::high_contrast_theme, then to Application::theme — the reference’s own order, rung for rung.

Source

fn resolved_theme(&self, brightness: Brightness, high_contrast: bool) -> Theme

Which of this application’s themes is on display, given what the platform reports — the reference’s _themeBuilder (app.dart:995), rung for rung.

A dark, high-contrast interface takes high_contrast_dark_theme, then dark_theme, then high_contrast_theme; a dark one takes dark_theme; a high-contrast one takes high_contrast_theme; and anything still unanswered takes theme, which every application has.

The fallbacks are the point. An application supplying only a dark_theme is right about dark mode and silent about contrast, and gets its dark theme on a high-contrast device rather than being sent back to its light one.

The framework calls this every frame; an application rarely does. It is public because there is no BuildContext here to ask, so anything outside the frame loop that needs the theme an application would be showing — an off-screen renderer, a golden harness, a test — has to be able to ask self for it. Overriding it replaces the rungs above wholesale.

Source

fn theme_animation_duration(&self) -> f32

How long the framework takes to cross from one theme to the next, in seconds (app.dart:516); 0 switches at once. The default is the reference’s 200 ms.

Every change of theme is animated, not only a light/dark switch: a new seed colour, a different density of tokens, anything at all that makes the resolved theme a different value. The application does not run the fade and does not hold its progress — it names the two themes and the mode, and the framework blends.

A reader who has asked for reduced motion gets the change at once whatever this says, as with every implicit animation the framework runs.

Source

fn theme_animation_curve(&self) -> Curve

The shape of that crossing (app.dart:526); linear by default, as in the reference. Ignored when Application::theme_animation_duration is 0.

Source

fn tick(&mut self, _dt: f32) -> bool

Advances the app’s own animations — a screen transition, a gesture settling — by dt seconds. Returns true while something is still moving, in which case the framework asks for another frame.

The theme fade is not one of them: since milestone 452 the framework runs it.

Source

fn title(&self) -> String

The window’s title.

Source

fn icon(&self) -> AppIcon

The application’s icon: the frus logo unless it says otherwise. On the desktop it is the window’s, on the Web the tab’s; see AppIcon for what it does on each platform, and for how to change or remove it.

Source

fn window_size(&self) -> Option<(f32, f32)>

The window’s desired initial logical size; None for the system default. Ignored on the Web, where the page decides how big the canvas is.

Source

fn accessibility(&self) -> AccessibilityOverrides

What this application wants to say about the accessibility settings instead of the platform.

The platform is asked first, because the settings belong to the person using the device and not to the program. This hook lays an application’s own answers over that, one setting at a time — a settings screen with a reduce motion switch of its own speaks for that and stays quiet about the rest.

The default is AccessibilityOverrides::NONE: nothing said, every answer the user’s. None per field is what makes that expressible; a plain Accessibility could not, a false in it being indistinguishable from silence.

The framework honours disable_animations itself, by completing implicit animations at once rather than over time. The rest reach the widgets through MediaQuery::of.

Source

fn density(&self) -> f32

The interface’s density: an application-level zoom factor, 1.0 by default, applied on top of the system DPI scale. 1.2 grows the whole UI by 20%, 0.9 tightens it. It can change at runtime through the state.

Source

fn scroll_behavior(&self) -> ScrollBehavior

How the application’s scrollables behave: their physics, their scrollbars, what they show past an edge and how they read a fling, all from one frus_widgets::ScrollBehavior put in force at the root of the tree.

The default, frus_widgets::ScrollBehavior::material, follows the theme’s platform, so an application whose theme says iOS bounces and hides its scrollbars on any device. Change what it changes and keep the rest:

ⓘ
fn scroll_behavior(&self) -> ScrollBehavior {
    ScrollBehavior::material().with_scrollbars(false)
}

A subtree can put another in force with a frus_widgets::ScrollConfiguration, and a single scrollable can still ask for its own physics or scrollbars.

Breaking (milestone 616): this replaces scroll_physics(), scrollbars() and overscroll_indicator(), each of which decided one of these on its own, from the build target.

Source

fn supported_locales(&self) -> Vec<Locale>

The languages this application has (app.dart’s supportedLocales), best first — the answer to what can I actually show this reader?

The default is ["en"], which is what every string in the framework was written in before any of them could be translated. The order matters: it decides ties, so an application listing en-US before en-GB has said which English a reader who asked only for en should get, and the first entry is what a reader whose languages are all unavailable ends up with.

An application that translates nothing can leave this alone and lose nothing: the resolution then always answers en, which is where it was.

Source

fn locale(&self) -> Option<Locale>

A language pinned by the application, over the reader’s own (app.dart’s locale); None — the default — follows the device.

This is what an application’s Language setting writes to. It is still resolved against supported_locales, so pinning one the application does not have gives the nearest thing it does have rather than nothing.

Source

fn resolved_locale(&self, preferred: &[Locale]) -> Locale

Which language the interface ends up in, given what the reader prefers.

preferred is the platform’s list, best first. An application that pinned a locale replaces that list with the one it named — the reference does the same, resolving the pin rather than obeying it blindly — and everything then goes through locale::resolve, which is the reference’s basicLocaleListResolution (app.dart:146).

The framework calls this every frame and installs the answer, so a language setting changed while the application is running is obeyed on the next one. Override it to negotiate differently — the reference’s localeListResolutionCallback.

Source

fn localizations(&self) -> Option<Rc<dyn Localizations>>

The words the framework says on this application’s behalf, in the reader’s language: the label on a back arrow, the word on a notification’s cross, a calendar’s month names and which day its weeks start on.

None — the default — leaves them in English, which is what they were before any of them could be translated. Answer with a table and the shell installs it every frame, so an application that changes language while it is running is obeyed on the next one.

See frus_widgets::localizations.

Source

fn on_resize(&mut self, _width: f32, _height: f32)

Called when the surface’s logical size changes, whether the window was resized or the density changed. It lets the app react to a breakpoint change in its own logic — closing a drawer as things narrow, say — beyond simply re-rendering.

Source

fn on_lifecycle(&mut self, _state: Lifecycle)

Called at every lifecycle transition (see Lifecycle): Resumed in the foreground, Inactive when the window loses focus, Paused in the background with the surface lost, Detached just before closing. The default does nothing. This is where an app suspends and resumes its work — timers, sensors — or persists its state.

Source

fn on_insets(&mut self, _insets: WindowInsets)

Called when the window insets change, split by nature: padding is the system bars and the notch, which are static, while view_insets is the software keyboard, which is dynamic — avoiding the keyboard means pushing the content away by insets.safe(). In logical px. Always zero on desktop.

Source

fn save_state(&self) -> Option<Vec<u8>>

Live reload, in development: a serialised snapshot of the state, captured just before a recompiled binary relaunches the application (FRUS_WATCH=1). None, the default, means the app opts out, and a reload then starts from a fresh state. The byte format belongs to the app.

Source

fn restore_state(&mut self, _bytes: &[u8])

Rehydrates the state from an Application::save_state snapshot taken by the previous binary; called before Application::init. The bytes come from another version of the code, so tolerate unexpected formats — ignoring beats panicking.

Source

fn can_go_back(&self) -> bool

Can the app go back? This enables the edge back gesture.

Source

fn back_gesture(&mut self, _progress: f32)

The back gesture is progressing (0 → 1), so view can preview it.

Source

fn back_gesture_end(&mut self, _velocity: f32)

The back gesture was released, with the finger’s velocity in fractions per second. It is up to the app to commit or cancel, usually through an animated settle in tick.

Source

fn go_back(&mut self)

The system asked to go back — Android’s back button, the browser’s Back, a back key — with no finger on the page: a pop, played as a page leaves, not as a swipe let go (milestone 622). Called only when Application::can_go_back says yes.

The default plays it as a back gesture let go at once, which is all an application that only answers the gesture can do. One that pops its own pages overrides it; an application built from components does, through its router.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§