Aspirational examples for app developer contract.
This commit is contained in:
56
aspirational_examples/06_renderer_extensions.rs
Normal file
56
aspirational_examples/06_renderer_extensions.rs
Normal file
@@ -0,0 +1,56 @@
|
||||
//! Aspirational RUIN app API for explicit renderer/platform extensions.
|
||||
//!
|
||||
//! Intentionally non-compiling; this is a design sketch.
|
||||
|
||||
use ruin::prelude::*;
|
||||
use ruin::renderer::native::prelude::*;
|
||||
use ruin::renderer::web::prelude::*;
|
||||
|
||||
#[ruin_runtime::async_main]
|
||||
async fn main() -> ruin::Result<()> {
|
||||
App::new()
|
||||
.window(Window::new().title("RUIN Renderer Extensions").size(980.0, 720.0))
|
||||
.mount::<PortableRoot>()
|
||||
.run()
|
||||
.await
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn PortableRoot() -> impl View {
|
||||
let selected_tab = use_signal(|| 0usize);
|
||||
|
||||
let shared_content = view! {
|
||||
column(fill = true, gap = 16, padding = 20) {
|
||||
text(role = TextRole::Heading(1), size = 28, weight = FontWeight::Semibold) {
|
||||
"Portable baseline first"
|
||||
}
|
||||
text(color = colors::muted()) {
|
||||
"The common subset should live in the main prelude. Anything renderer-specific \
|
||||
should require an explicit extension trait so the callsite makes the portability \
|
||||
tradeoff obvious."
|
||||
}
|
||||
segmented_control(value = selected_tab) {
|
||||
segment(index = 0) { "Overview" }
|
||||
segment(index = 1) { "Details" }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
view! {
|
||||
stack(fill = true) {
|
||||
#[cfg(target_family = "wasm")]
|
||||
{
|
||||
shared_content
|
||||
.dom_element("section")
|
||||
.dom_attribute("data-tab", selected_tab.get().to_string())
|
||||
}
|
||||
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
{
|
||||
shared_content
|
||||
.native_surface_role(SurfaceRole::Panel)
|
||||
.native_backdrop_blur(18.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user