Struct raui_core::application::Application [−][src]
pub struct Application {
pub animations_delta_time: Scalar,
// some fields omitted
}
Expand description
Contains and orchestrates application layout, animations, interactions, etc.
See the application
module for more information and examples.
Fields
animations_delta_time: Scalar
The amount of time between the last update, used when calculating animation progress
Implementations
Setup the application with a given a setup function
We need to run the setup
function for the application to register components and
properties if we want to support serialization of the UI. We pass it a function that will do
the actual registration.
Note: RAUI will work fine without running any
setup
if UI serialization is not required.
Example
application.setup(setup /* the core setup function from the RAUI prelude */);
If you use crates like the raui_material
crate you will want to call it’s setup function
as well.
application.setup(raui_material::setup);
Get the ChangeNotifier
for the Application
Having the ChangeNotifier
allows you to check whether the application has changed and
allows you to force application updates by marking the app as changed.
ChangeNotifier
s are also used to create data bindingss.
Register’s a component under a string name used when serializing the UI
This function is often used in setup
functions for registering batches of
components.
Example
fn my_widget(ctx: WidgetContext) -> WidgetNode {
todo!("make awesome widget");
}
fn setup_widgets(app: &mut Application) {
app.register_component("my_widget", my_widget);
}
let mut application = Application::new();
application.setup(setup_widgets);
Unregisters a component
Register’s a property type under a string name used when serializing the UI
This function is often used in setup
functions for registering batches of
properties.
Example
#[derive(PropsData, Debug, Default, Copy, Clone, Serialize, Deserialize)]
struct MyProp {
awesome: bool,
}
fn setup_properties(app: &mut Application) {
app.register_props::<MyProp>("MyProp");
}
let mut application = Application::new();
application.setup(setup_properties);
Unregisters a property type
See register_props
Serialize the given Props
to a PrefabValue
Deserialize Props
from a PrefabValue
Serialize a WidgetNode
to a PrefabValue
Deserialize a WidgetNode
from a PrefabValue
Get the reason that the application state was last invalidated and caused to re-process
Force mark the application as needing to re-process
Get the WidgetNode
for the application tree
Get the application widget tree rendered to raw WidgetUnit
’s
Get the application Layout
data
Update the application widget tree
Render the application
pub fn render_change<R, T, E>(
&mut self,
mapping: &CoordsMapping,
renderer: &mut R
) -> Result<Option<T>, E> where
R: Renderer<T, E>,
pub fn render_change<R, T, E>(
&mut self,
mapping: &CoordsMapping,
renderer: &mut R
) -> Result<Option<T>, E> where
R: Renderer<T, E>,
Render the application, but only if something effecting the rendering has changed and it needs to be re-rendered
pub fn layout<L, E>(
&mut self,
mapping: &CoordsMapping,
layout_engine: &mut L
) -> Result<(), E> where
L: LayoutEngine<E>,
pub fn layout<L, E>(
&mut self,
mapping: &CoordsMapping,
layout_engine: &mut L
) -> Result<(), E> where
L: LayoutEngine<E>,
Calculate application layout
pub fn layout_change<L, E>(
&mut self,
mapping: &CoordsMapping,
layout_engine: &mut L
) -> Result<bool, E> where
L: LayoutEngine<E>,
pub fn layout_change<L, E>(
&mut self,
mapping: &CoordsMapping,
layout_engine: &mut L
) -> Result<bool, E> where
L: LayoutEngine<E>,
Calculate application layout, but only if something effecting application layout has changed and the layout needs to be re-done
pub fn interact<I, R, E>(&mut self, interactions_engine: &mut I) -> Result<R, E> where
I: InteractionsEngine<R, E>,
pub fn interact<I, R, E>(&mut self, interactions_engine: &mut I) -> Result<R, E> where
I: InteractionsEngine<R, E>,
Perform interactions on the application using the given interaction engine
Send a message to the given widget
Send raw message data to the given widget
Get the list of signals that have been sent by widgets
Get the list of signals that have been sent by widgets, consuming the current list so that further calls will not include previously sent signals
Set the props of a given widget
Get read access to the given widget’s Props
in a closure and update the widget’s props
to the props that were returned by the closure
Get mutable access to the cloned Props
of a widget in a closure and update the widget’s
props to the value of the clone props after the closure modifies them
process()
application, even if no changes have been detected
pub fn forced_process_with_context<'b>(
&mut self,
process_context: &mut ProcessContext<'b>
) -> bool
pub fn forced_process_with_context<'b>(
&mut self,
process_context: &mut ProcessContext<'b>
) -> bool
process()
application, even if no changes have been detected
Process the application, updating animations, applying state changes, handling widget messages, etc.
Process the application and provide a custom ProcessContext
Process Context
The process_context
argument allows you to provide the UI’s components with mutable or
immutable access to application data. This grants powerful, direct control over the
application to the UI’s widgets, but has some caveats and it is easy to fall into
anti-patterns when using.
You should consider carefully whether or not a process context is the best way to facilitate your use-case before using this feature. See caveats below for more explanation.
Caveats
RAUI provides other ways to facilitate UI integration with external data that should generally be preferred over using a process context. The primary mechanisms are:
DataBinding
s and widget messages, for having the application send data to widgets- signals for having widgets send data to the application.
The main difference between using a DataBinding
and a process context is the fact that
RAUI is able to more granularly update the widget tree in response to data changes when
using DataBinding
, but it has no way to know know when data in a process context
changes.
When you use a process context you are now responsible for either running
forced_process_with_context
every frame to make sure
that the UI is always updated when the process context changes, or by manually calling
mark_dirty
when the process context has changed to make sure that the
next process_with_context()
call will actually update the application.
Example
/// Some sort of application data
///
/// Pretend this data cannot be cloned because it has some special requirements.
struct AppData {
counter: i32
}
// Make our data
let mut app_data = AppData {
counter: 0,
};
let mut app = Application::new();
// Do application stuff like interactions, layout, etc...
// Now when it is time to process our application we create a process context and we put
// a _mutable reference_ to our app data in the context. This means we don't have to have
// ownership of our `AppData` struct, which is useful when the UI event loop doesn't
// own the data it needs access to.
// Now we call `process` with our process context
app.process_with_context(ProcessContext::new().insert_mut(&mut app_data));
Now, in our components we can access the AppData
through the widget’s WidgetContext
fn my_component(ctx: WidgetContext) -> WidgetNode {
let app_data = ctx.process_context.get_mut::<AppData>().unwrap();
let counter = &mut app_data.counter;
*counter += 1;
// widget stuff...
}