diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 531c70c0d..e3bdf282f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ env: RUST_MIN_VER_WASM_PKGS: "-p xilem_core" # Only some of our examples support Android (primarily due to extra required boilerplate). - ANDROID_TARGETS: -p xilem --example mason_android --example calc_android --example stopwatch_android --example variable_clock_android + ANDROID_TARGETS: -p xilem --example mason_android --example calc_android --example stopwatch_android --example variable_clock_android --example http_cats_android --example to_do_mvc_android # We do not run the masonry snapshot tests, because those currently require a specific font stack # See https://github.com/linebender/xilem/pull/233 diff --git a/xilem/Cargo.toml b/xilem/Cargo.toml index deca00c65..28a599c76 100644 --- a/xilem/Cargo.toml +++ b/xilem/Cargo.toml @@ -45,7 +45,6 @@ path = "examples/http_cats.rs" # cdylib is required for cargo-apk crate-type = ["cdylib"] - [[example]] name = "stopwatch" @@ -55,6 +54,15 @@ path = "examples/stopwatch.rs" # cdylib is required for cargo-apk crate-type = ["cdylib"] +[[example]] +name = "to_do_mvc" + +[[example]] +name = "to_do_mvc_android" +path = "examples/to_do_mvc.rs" +# cdylib is required for cargo-apk +crate-type = ["cdylib"] + [[example]] name = "variable_clock" diff --git a/xilem/examples/to_do_mvc.rs b/xilem/examples/to_do_mvc.rs index 0d1fbbd65..73fd288a5 100644 --- a/xilem/examples/to_do_mvc.rs +++ b/xilem/examples/to_do_mvc.rs @@ -4,8 +4,9 @@ // On Windows platform, don't show a console when opening the app. #![windows_subsystem = "windows"] -use xilem::view::{button, checkbox, flex, textbox, Axis}; -use xilem::{EventLoop, WidgetView, Xilem}; +use winit::error::EventLoopError; +use xilem::view::{button, checkbox, flex, textbox, Axis, FlexSpacer}; +use xilem::{EventLoop, EventLoopBuilder, WidgetView, Xilem}; struct Task { description: String, @@ -66,12 +67,17 @@ fn app_logic(task_list: &mut TaskList) -> impl WidgetView { }) .collect::>(); - flex((first_line, tasks)) + flex(( + FlexSpacer::Fixed(40.), // HACK: Spacer for Androird + first_line, + tasks, + )) } -fn main() { +fn run(event_loop: EventLoopBuilder) -> Result<(), EventLoopError> { let data = TaskList { - next_task: String::new(), + // Add a placeholder task for Android, whilst the + next_task: "My Next Task".into(), tasks: vec![ Task { description: "Buy milk".into(), @@ -89,6 +95,38 @@ fn main() { }; let app = Xilem::new(data, app_logic); - app.run_windowed(EventLoop::with_user_event(), "First Example".into()) - .unwrap(); + app.run_windowed(event_loop, "First Example".into()) +} + +// Boilerplate code for android: Identical across all applications + +#[cfg(not(target_os = "android"))] +#[allow(dead_code)] +// This is treated as dead code by the Android version of the example, but is actually live +// This hackery is required because Cargo doesn't care to support this use case, of one +// example which works across Android and desktop +fn main() -> Result<(), EventLoopError> { + run(EventLoop::with_user_event()) +} + +#[cfg(target_os = "android")] +// Safety: We are following `android_activity`'s docs here +// We believe that there are no other declarations using this name in the compiled objects here +#[allow(unsafe_code)] +#[no_mangle] +fn android_main(app: winit::platform::android::activity::AndroidApp) { + use winit::platform::android::EventLoopBuilderExtAndroid; + + let mut event_loop = EventLoop::with_user_event(); + event_loop.with_android_app(app); + + run(event_loop).expect("Can create app"); +} + +// TODO: This is a hack because of how we handle our examples in Cargo.toml +// Ideally, we change Cargo to be more sensible here? +#[cfg(target_os = "android")] +#[allow(dead_code)] +fn main() { + unreachable!() }