From 3349a717fbf44dd8f26d9b4898060162a7c47ac4 Mon Sep 17 00:00:00 2001 From: Alexis Grojean Date: Wed, 25 Oct 2023 16:35:15 +0200 Subject: [PATCH] Add new main menu based on MultiPageMenu gadget. --- .cargo/config.toml | 5 ++++ Cargo.toml | 4 ++++ src/app_ui/menu.rs | 59 ++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 13 +++++----- 4 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 src/app_ui/menu.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index c233973..edf4752 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -7,3 +7,8 @@ target = "nanosplus" [unstable] build-std = ["core"] build-std-features = ["compiler-builtins-mem"] +host-config = true +target-applies-to-host = true + +[host] +rustflags = ["-Ctarget-feature=-crt-static"] \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 468411d..a171768 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,10 @@ edition = "2021" [dependencies] nanos_sdk = { git = "https://github.com/LedgerHQ/ledger-nanos-sdk.git" } nanos_ui = { git = "https://github.com/LedgerHQ/ledger-nanos-ui.git" } +include_gif = { git = "https://github.com/LedgerHQ/sdk_include_gif" } + +[patch."https://github.com/LedgerHQ/ledger-nanos-ui"] +nanos_ui = { path = "ledger-nanos-ui" } [profile.release] opt-level = 'z' diff --git a/src/app_ui/menu.rs b/src/app_ui/menu.rs new file mode 100644 index 0000000..83a5364 --- /dev/null +++ b/src/app_ui/menu.rs @@ -0,0 +1,59 @@ +/***************************************************************************** + * Ledger App Boilerplate Rust. + * (c) 2023 Ledger SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *****************************************************************************/ + +use include_gif::include_gif; +use nanos_sdk::io; +use nanos_ui::bitmaps::{Glyph, BACK, CERTIFICATE, DASHBOARD_X}; +use nanos_ui::ui::{EventOrPageIndex, MultiPageMenu, Page}; + +fn ui_about_menu(comm: &mut io::Comm) -> io::Event { + let pages = [ + &Page::from((["Rust Boilerplate", "(c) 2023 Ledger"], true)), + &Page::from(("Back", &BACK)), + ]; + loop { + match MultiPageMenu::new(comm, &pages).show() { + EventOrPageIndex::Event(e) => return e, + i => match i { + EventOrPageIndex::Index(1) => return ui_menu_main(comm), + _ => (), + }, + } + } +} + +pub fn ui_menu_main(comm: &mut io::Comm) -> io::Event { + const APP_ICON: Glyph = Glyph::from_include(include_gif!("crab.gif")); + let pages = [ + // The from trait allows to create different styles of pages + // without having to use the new() function. + &Page::from((["Boilerplate", "is ready"], &APP_ICON)), + &Page::from((["Version", "2.0.0"], true)), + &Page::from(("About", &CERTIFICATE)), + &Page::from(("Quit", &DASHBOARD_X)), + ]; + loop { + match MultiPageMenu::new(comm, &pages).show() { + EventOrPageIndex::Event(e) => return e, + i => match i { + EventOrPageIndex::Index(2) => return ui_about_menu(comm), + EventOrPageIndex::Index(3) => nanos_sdk::exit_app(0), + _ => (), + }, + } + } +} diff --git a/src/main.rs b/src/main.rs index e70ce1b..81ad549 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,9 @@ #![no_main] mod utils; +mod app_ui { + pub mod menu; +} use core::str::from_utf8; use nanos_sdk::buttons::ButtonEvent; @@ -10,6 +13,8 @@ use nanos_sdk::io; use nanos_sdk::io::SyscallError; use nanos_ui::ui; +use app_ui::menu::ui_menu_main; + nanos_sdk::set_panic!(nanos_sdk::exiting_panic); pub const BIP32_PATH: [u32; 5] = nanos_sdk::ecc::make_bip32_path(b"m/44'/535348'/0'/0/0"); @@ -106,14 +111,10 @@ extern "C" fn sample_main() { let mut comm = io::Comm::new(); loop { - // Draw some 'welcome' screen - ui::SingleMessage::new("W e l c o m e").show(); - // Wait for either a specific button push to exit the app // or an APDU command - match comm.next_event() { - io::Event::Button(ButtonEvent::RightButtonRelease) => nanos_sdk::exit_app(0), - io::Event::Command(ins) => match handle_apdu(&mut comm, ins) { + match ui_menu_main(&mut comm) { + io::Event::Command(ins) => match handle_apdu(&mut comm, ins.into()) { Ok(()) => comm.reply_ok(), Err(sw) => comm.reply(sw), },