mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-08-04 21:05:29 +00:00
refactor(core/mercury): remove unnecessary Child
[no changelog]
This commit is contained in:
parent
1212a7319a
commit
888e384f79
@ -6,9 +6,7 @@ use crate::{
|
|||||||
strutil::TString,
|
strutil::TString,
|
||||||
translations::TR,
|
translations::TR,
|
||||||
ui::{
|
ui::{
|
||||||
component::{
|
component::{base::Never, Bar, Component, Empty, Event, EventCtx, Label, Split},
|
||||||
base::Never, Bar, Child, Component, ComponentExt, Empty, Event, EventCtx, Label, Split,
|
|
||||||
},
|
|
||||||
display::loader::{loader_circular_uncompress, LoaderDimensions},
|
display::loader::{loader_circular_uncompress, LoaderDimensions},
|
||||||
geometry::{Insets, Offset, Rect},
|
geometry::{Insets, Offset, Rect},
|
||||||
model_mercury::constant,
|
model_mercury::constant,
|
||||||
@ -30,7 +28,7 @@ const LOADER_SPEED: u16 = 5;
|
|||||||
pub struct CoinJoinProgress<U> {
|
pub struct CoinJoinProgress<U> {
|
||||||
value: u16,
|
value: u16,
|
||||||
indeterminate: bool,
|
indeterminate: bool,
|
||||||
content: Child<Frame<Split<Empty, U>>>,
|
content: Frame<Split<Empty, U>>,
|
||||||
// Label is not a child since circular loader paints large black rectangle which overlaps it.
|
// Label is not a child since circular loader paints large black rectangle which overlaps it.
|
||||||
// To work around this, draw label every time loader is drawn.
|
// To work around this, draw label every time loader is drawn.
|
||||||
label: Label<'static>,
|
label: Label<'static>,
|
||||||
@ -65,8 +63,7 @@ where
|
|||||||
content: Frame::centered(
|
content: Frame::centered(
|
||||||
TR::coinjoin__title_progress.into(),
|
TR::coinjoin__title_progress.into(),
|
||||||
Split::bottom(RECTANGLE_HEIGHT, 0, Empty, inner),
|
Split::bottom(RECTANGLE_HEIGHT, 0, Empty, inner),
|
||||||
)
|
),
|
||||||
.into_child(),
|
|
||||||
label: Label::centered(text, theme::TEXT_NORMAL),
|
label: Label::centered(text, theme::TEXT_NORMAL),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
strutil::TString,
|
strutil::TString,
|
||||||
ui::{
|
ui::{
|
||||||
component::{Child, Component, Event, EventCtx, Label, Never, Pad},
|
component::{Component, Event, EventCtx, Label, Never, Pad},
|
||||||
constant::screen,
|
constant::screen,
|
||||||
geometry::{Alignment2D, Point, Rect},
|
geometry::{Alignment2D, Point, Rect},
|
||||||
shape,
|
shape,
|
||||||
@ -26,9 +26,9 @@ const STYLE: &ResultStyle = &super::theme::RESULT_ERROR;
|
|||||||
|
|
||||||
pub struct ErrorScreen<'a> {
|
pub struct ErrorScreen<'a> {
|
||||||
bg: Pad,
|
bg: Pad,
|
||||||
title: Child<Label<'a>>,
|
title: Label<'a>,
|
||||||
message: Child<Label<'a>>,
|
message: Label<'a>,
|
||||||
footer: Child<ResultFooter<'a>>,
|
footer: ResultFooter<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ErrorScreen<'a> {
|
impl<'a> ErrorScreen<'a> {
|
||||||
@ -42,9 +42,9 @@ impl<'a> ErrorScreen<'a> {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
bg: Pad::with_background(FATAL_ERROR_COLOR).with_clear(),
|
bg: Pad::with_background(FATAL_ERROR_COLOR).with_clear(),
|
||||||
title: Child::new(title),
|
title,
|
||||||
message: Child::new(message),
|
message,
|
||||||
footer: Child::new(footer),
|
footer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
strutil::TString,
|
strutil::TString,
|
||||||
ui::{
|
ui::{
|
||||||
component::{
|
component::{image::Image, Component, Event, EventCtx, Label, Swipe, SwipeDirection},
|
||||||
image::Image, Child, Component, Event, EventCtx, Label, Swipe, SwipeDirection,
|
|
||||||
},
|
|
||||||
display,
|
display,
|
||||||
geometry::{Insets, Rect},
|
geometry::{Insets, Rect},
|
||||||
model_mercury::component::{fido_icons::get_fido_icon_data, theme, ScrollBar},
|
model_mercury::component::{fido_icons::get_fido_icon_data, theme, ScrollBar},
|
||||||
@ -30,7 +28,7 @@ pub struct FidoConfirm<F: Fn(usize) -> TString<'static>, U> {
|
|||||||
page_swipe: Swipe,
|
page_swipe: Swipe,
|
||||||
app_name: Label<'static>,
|
app_name: Label<'static>,
|
||||||
account_name: Label<'static>,
|
account_name: Label<'static>,
|
||||||
icon: Child<Image>,
|
icon: Image,
|
||||||
/// Function/closure that will return appropriate page on demand.
|
/// Function/closure that will return appropriate page on demand.
|
||||||
get_account: F,
|
get_account: F,
|
||||||
scrollbar: ScrollBar,
|
scrollbar: ScrollBar,
|
||||||
@ -79,7 +77,7 @@ where
|
|||||||
app_name: Label::centered(app_name, theme::TEXT_DEMIBOLD),
|
app_name: Label::centered(app_name, theme::TEXT_DEMIBOLD),
|
||||||
account_name: Label::centered(current_account, theme::TEXT_DEMIBOLD),
|
account_name: Label::centered(current_account, theme::TEXT_DEMIBOLD),
|
||||||
page_swipe,
|
page_swipe,
|
||||||
icon: Child::new(Image::new(icon_data)),
|
icon: Image::new(icon_data),
|
||||||
get_account,
|
get_account,
|
||||||
scrollbar,
|
scrollbar,
|
||||||
fade: Cell::new(false),
|
fade: Cell::new(false),
|
||||||
|
@ -2,7 +2,7 @@ use crate::{
|
|||||||
strutil::TString,
|
strutil::TString,
|
||||||
ui::{
|
ui::{
|
||||||
component::{
|
component::{
|
||||||
maybe::paint_overlapping, Child, Component, Event, EventCtx, Label, Maybe, Swipe,
|
maybe::paint_overlapping, Component, Event, EventCtx, Label, Maybe, Swipe,
|
||||||
SwipeDirection,
|
SwipeDirection,
|
||||||
},
|
},
|
||||||
geometry::{Alignment, Grid, Insets, Rect},
|
geometry::{Alignment, Grid, Insets, Rect},
|
||||||
@ -24,17 +24,17 @@ pub enum MnemonicKeyboardMsg {
|
|||||||
|
|
||||||
pub struct MnemonicKeyboard<T> {
|
pub struct MnemonicKeyboard<T> {
|
||||||
/// Initial prompt, displayed on empty input.
|
/// Initial prompt, displayed on empty input.
|
||||||
prompt: Child<Maybe<Label<'static>>>,
|
prompt: Maybe<Label<'static>>,
|
||||||
/// Delete a char button.
|
/// Delete a char button.
|
||||||
erase: Child<Maybe<Button>>,
|
erase: Maybe<Button>,
|
||||||
/// Go to previous word button
|
/// Go to previous word button
|
||||||
back: Child<Maybe<Button>>,
|
back: Maybe<Button>,
|
||||||
/// Input area, acting as the auto-complete and confirm button.
|
/// Input area, acting as the auto-complete and confirm button.
|
||||||
input: Child<Maybe<T>>,
|
input: Maybe<T>,
|
||||||
/// Area with keypads - used for rounded overlay
|
/// Area with keypads - used for rounded overlay
|
||||||
keypad_area: Rect,
|
keypad_area: Rect,
|
||||||
/// Key buttons.
|
/// Key buttons.
|
||||||
keys: [Child<Button>; MNEMONIC_KEY_COUNT],
|
keys: [Button; MNEMONIC_KEY_COUNT],
|
||||||
/// Swipe controller - allowing for going to the previous word.
|
/// Swipe controller - allowing for going to the previous word.
|
||||||
swipe: Swipe,
|
swipe: Swipe,
|
||||||
/// Whether going back is allowed (is not on the very first word).
|
/// Whether going back is allowed (is not on the very first word).
|
||||||
@ -56,26 +56,20 @@ where
|
|||||||
.styled(theme::button_default())
|
.styled(theme::button_default())
|
||||||
.with_expanded_touch_area(Insets::right(BACK_BUTTON_RIGHT_EXPAND));
|
.with_expanded_touch_area(Insets::right(BACK_BUTTON_RIGHT_EXPAND));
|
||||||
Self {
|
Self {
|
||||||
prompt: Child::new(Maybe::new(
|
prompt: Maybe::new(
|
||||||
theme::BG,
|
theme::BG,
|
||||||
Label::centered(prompt, theme::TEXT_MAIN_GREY_LIGHT).vertically_centered(),
|
Label::centered(prompt, theme::TEXT_MAIN_GREY_LIGHT).vertically_centered(),
|
||||||
prompt_visible,
|
prompt_visible,
|
||||||
)),
|
),
|
||||||
erase: Child::new(Maybe::new(theme::BG, erase_btn, !prompt_visible)),
|
erase: Maybe::new(theme::BG, erase_btn, !prompt_visible),
|
||||||
back: Child::new(Maybe::new(
|
back: Maybe::new(theme::BG, back_btn, prompt_visible && can_go_back),
|
||||||
theme::BG,
|
input: Maybe::new(theme::BG, input, !prompt_visible),
|
||||||
back_btn,
|
|
||||||
prompt_visible && can_go_back,
|
|
||||||
)),
|
|
||||||
input: Child::new(Maybe::new(theme::BG, input, !prompt_visible)),
|
|
||||||
keypad_area: Rect::zero(),
|
keypad_area: Rect::zero(),
|
||||||
keys: T::keys()
|
keys: T::keys().map(|t| {
|
||||||
.map(|t| {
|
Button::with_text(t.into())
|
||||||
Button::with_text(t.into())
|
.styled(theme::button_keyboard())
|
||||||
.styled(theme::button_keyboard())
|
.with_text_align(Alignment::Center)
|
||||||
.with_text_align(Alignment::Center)
|
}),
|
||||||
})
|
|
||||||
.map(Child::new),
|
|
||||||
swipe: Swipe::new().right(),
|
swipe: Swipe::new().right(),
|
||||||
can_go_back,
|
can_go_back,
|
||||||
}
|
}
|
||||||
@ -90,32 +84,23 @@ where
|
|||||||
/// completion mask and the pending key.
|
/// completion mask and the pending key.
|
||||||
fn toggle_key_buttons(&mut self, ctx: &mut EventCtx) {
|
fn toggle_key_buttons(&mut self, ctx: &mut EventCtx) {
|
||||||
for (key, btn) in self.keys.iter_mut().enumerate() {
|
for (key, btn) in self.keys.iter_mut().enumerate() {
|
||||||
let enabled = self
|
let enabled = self.input.inner().can_key_press_lead_to_a_valid_word(key);
|
||||||
.input
|
btn.enable_if(ctx, enabled);
|
||||||
.inner()
|
|
||||||
.inner()
|
|
||||||
.can_key_press_lead_to_a_valid_word(key);
|
|
||||||
btn.mutate(ctx, |ctx, b| b.enable_if(ctx, enabled));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// After edit operations, we need to either show or hide the prompt, the
|
/// After edit operations, we need to either show or hide the prompt, the
|
||||||
/// input, the erase button and the back button.
|
/// input, the erase button and the back button.
|
||||||
fn toggle_prompt_or_input(&mut self, ctx: &mut EventCtx) {
|
fn toggle_prompt_or_input(&mut self, ctx: &mut EventCtx) {
|
||||||
let prompt_visible = self.input.inner().inner().is_empty();
|
let prompt_visible = self.input.inner().is_empty();
|
||||||
self.prompt
|
self.prompt.show_if(ctx, prompt_visible);
|
||||||
.mutate(ctx, |ctx, p| p.show_if(ctx, prompt_visible));
|
self.input.show_if(ctx, !prompt_visible);
|
||||||
self.input
|
self.erase.show_if(ctx, !prompt_visible);
|
||||||
.mutate(ctx, |ctx, i| i.show_if(ctx, !prompt_visible));
|
self.back.show_if(ctx, prompt_visible && self.can_go_back);
|
||||||
self.erase
|
|
||||||
.mutate(ctx, |ctx, b| b.show_if(ctx, !prompt_visible));
|
|
||||||
self.back.mutate(ctx, |ctx, b| {
|
|
||||||
b.show_if(ctx, prompt_visible && self.can_go_back)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mnemonic(&self) -> Option<&'static str> {
|
pub fn mnemonic(&self) -> Option<&'static str> {
|
||||||
self.input.inner().inner().mnemonic()
|
self.input.inner().mnemonic()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,14 +166,12 @@ where
|
|||||||
|
|
||||||
match self.erase.event(ctx, event) {
|
match self.erase.event(ctx, event) {
|
||||||
Some(ButtonMsg::Clicked) => {
|
Some(ButtonMsg::Clicked) => {
|
||||||
self.input
|
self.input.inner_mut().on_backspace_click(ctx);
|
||||||
.mutate(ctx, |ctx, i| i.inner_mut().on_backspace_click(ctx));
|
|
||||||
self.on_input_change(ctx);
|
self.on_input_change(ctx);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Some(ButtonMsg::LongPressed) => {
|
Some(ButtonMsg::LongPressed) => {
|
||||||
self.input
|
self.input.inner_mut().on_backspace_long_press(ctx);
|
||||||
.mutate(ctx, |ctx, i| i.inner_mut().on_backspace_long_press(ctx));
|
|
||||||
self.on_input_change(ctx);
|
self.on_input_change(ctx);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -196,8 +179,7 @@ where
|
|||||||
}
|
}
|
||||||
for (key, btn) in self.keys.iter_mut().enumerate() {
|
for (key, btn) in self.keys.iter_mut().enumerate() {
|
||||||
if let Some(ButtonMsg::Clicked) = btn.event(ctx, event) {
|
if let Some(ButtonMsg::Clicked) = btn.event(ctx, event) {
|
||||||
self.input
|
self.input.inner_mut().on_key_click(ctx, key);
|
||||||
.mutate(ctx, |ctx, i| i.inner_mut().on_key_click(ctx, key));
|
|
||||||
self.on_input_change(ctx);
|
self.on_input_change(ctx);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -213,7 +195,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
||||||
if self.input.inner().inner().is_empty() {
|
if self.input.inner().is_empty() {
|
||||||
self.prompt.render(target);
|
self.prompt.render(target);
|
||||||
if self.can_go_back {
|
if self.can_go_back {
|
||||||
self.back.render(target);
|
self.back.render(target);
|
||||||
|
@ -3,8 +3,8 @@ use crate::{
|
|||||||
translations::TR,
|
translations::TR,
|
||||||
ui::{
|
ui::{
|
||||||
component::{
|
component::{
|
||||||
base::ComponentExt, text::common::TextBox, Child, Component, Event, EventCtx, Label,
|
base::ComponentExt, text::common::TextBox, Component, Event, EventCtx, Label, Maybe,
|
||||||
Maybe, Never, Swipe, SwipeDirection,
|
Never, Swipe, SwipeDirection,
|
||||||
},
|
},
|
||||||
display,
|
display,
|
||||||
geometry::{Alignment, Grid, Insets, Offset, Rect},
|
geometry::{Alignment, Grid, Insets, Offset, Rect},
|
||||||
@ -75,14 +75,14 @@ impl From<KeyboardLayout> for ButtonContent {
|
|||||||
|
|
||||||
pub struct PassphraseKeyboard {
|
pub struct PassphraseKeyboard {
|
||||||
page_swipe: Swipe,
|
page_swipe: Swipe,
|
||||||
input: Child<Input>,
|
input: Input,
|
||||||
input_prompt: Child<Label<'static>>,
|
input_prompt: Label<'static>,
|
||||||
erase_btn: Child<Maybe<Button>>,
|
erase_btn: Maybe<Button>,
|
||||||
cancel_btn: Child<Maybe<Button>>,
|
cancel_btn: Maybe<Button>,
|
||||||
confirm_btn: Child<Button>,
|
confirm_btn: Button,
|
||||||
next_btn: Child<Button>,
|
next_btn: Button,
|
||||||
keypad_area: Rect,
|
keypad_area: Rect,
|
||||||
keys: [Child<Button>; KEY_COUNT],
|
keys: [Button; KEY_COUNT],
|
||||||
active_layout: KeyboardLayout,
|
active_layout: KeyboardLayout,
|
||||||
fade: Cell<bool>,
|
fade: Cell<bool>,
|
||||||
}
|
}
|
||||||
@ -105,43 +105,38 @@ impl PassphraseKeyboard {
|
|||||||
|
|
||||||
let confirm_btn = Button::with_icon(theme::ICON_SIMPLE_CHECKMARK24)
|
let confirm_btn = Button::with_icon(theme::ICON_SIMPLE_CHECKMARK24)
|
||||||
.styled(theme::button_passphrase_confirm())
|
.styled(theme::button_passphrase_confirm())
|
||||||
.with_radius(15)
|
.with_radius(15);
|
||||||
.into_child();
|
|
||||||
|
|
||||||
let next_btn = Button::new(active_layout.next().into())
|
let next_btn = Button::new(active_layout.next().into())
|
||||||
.styled(theme::button_passphrase_next())
|
.styled(theme::button_passphrase_next())
|
||||||
.with_text_align(Alignment::Center)
|
.with_text_align(Alignment::Center);
|
||||||
.into_child();
|
|
||||||
|
|
||||||
let erase_btn = Button::with_icon(theme::ICON_DELETE)
|
let erase_btn = Button::with_icon(theme::ICON_DELETE)
|
||||||
.styled(theme::button_keyboard_erase())
|
.styled(theme::button_keyboard_erase())
|
||||||
.with_long_press(theme::ERASE_HOLD_DURATION)
|
.with_long_press(theme::ERASE_HOLD_DURATION)
|
||||||
.initially_enabled(false);
|
.initially_enabled(false);
|
||||||
let erase_btn = Maybe::hidden(theme::BG, erase_btn).into_child();
|
let erase_btn = Maybe::hidden(theme::BG, erase_btn);
|
||||||
|
|
||||||
let cancel_btn =
|
let cancel_btn =
|
||||||
Button::with_icon(theme::ICON_CLOSE).styled(theme::button_keyboard_cancel());
|
Button::with_icon(theme::ICON_CLOSE).styled(theme::button_keyboard_cancel());
|
||||||
let cancel_btn = Maybe::visible(theme::BG, cancel_btn).into_child();
|
let cancel_btn = Maybe::visible(theme::BG, cancel_btn);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
page_swipe: Swipe::horizontal(),
|
page_swipe: Swipe::horizontal(),
|
||||||
input: Input::new().into_child(),
|
input: Input::new(),
|
||||||
input_prompt: Label::left_aligned(
|
input_prompt: Label::left_aligned(
|
||||||
TString::from_translation(TR::passphrase__title_enter),
|
TString::from_translation(TR::passphrase__title_enter),
|
||||||
theme::label_keyboard(),
|
theme::label_keyboard(),
|
||||||
)
|
),
|
||||||
.into_child(),
|
|
||||||
erase_btn,
|
erase_btn,
|
||||||
cancel_btn,
|
cancel_btn,
|
||||||
confirm_btn,
|
confirm_btn,
|
||||||
next_btn,
|
next_btn,
|
||||||
keypad_area: Rect::zero(),
|
keypad_area: Rect::zero(),
|
||||||
keys: KEYBOARD[active_layout.to_usize().unwrap()].map(|text| {
|
keys: KEYBOARD[active_layout.to_usize().unwrap()].map(|text| {
|
||||||
Child::new(
|
Button::new(Self::key_content(text))
|
||||||
Button::new(Self::key_content(text))
|
.styled(theme::button_keyboard())
|
||||||
.styled(theme::button_keyboard())
|
.with_text_align(Alignment::Center)
|
||||||
.with_text_align(Alignment::Center),
|
|
||||||
)
|
|
||||||
}),
|
}),
|
||||||
active_layout,
|
active_layout,
|
||||||
fade: Cell::new(false),
|
fade: Cell::new(false),
|
||||||
@ -174,8 +169,7 @@ impl PassphraseKeyboard {
|
|||||||
_ => self.active_layout,
|
_ => self.active_layout,
|
||||||
};
|
};
|
||||||
// Clear the pending state.
|
// Clear the pending state.
|
||||||
self.input
|
self.input.multi_tap.clear_pending_state(ctx);
|
||||||
.mutate(ctx, |ctx, i| i.multi_tap.clear_pending_state(ctx));
|
|
||||||
// Update keys.
|
// Update keys.
|
||||||
self.replace_keys_contents(ctx);
|
self.replace_keys_contents(ctx);
|
||||||
// Reset backlight to normal level on next paint.
|
// Reset backlight to normal level on next paint.
|
||||||
@ -186,13 +180,12 @@ impl PassphraseKeyboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn replace_keys_contents(&mut self, ctx: &mut EventCtx) {
|
fn replace_keys_contents(&mut self, ctx: &mut EventCtx) {
|
||||||
self.next_btn.mutate(ctx, |ctx, b| {
|
self.next_btn
|
||||||
b.set_content(ctx, self.active_layout.next().into());
|
.set_content(ctx, self.active_layout.next().into());
|
||||||
});
|
|
||||||
for (i, btn) in self.keys.iter_mut().enumerate() {
|
for (i, btn) in self.keys.iter_mut().enumerate() {
|
||||||
let text = KEYBOARD[self.active_layout.to_usize().unwrap()][i];
|
let text = KEYBOARD[self.active_layout.to_usize().unwrap()][i];
|
||||||
let content = Self::key_content(text);
|
let content = Self::key_content(text);
|
||||||
btn.mutate(ctx, |ctx, b| b.set_content(ctx, content));
|
btn.set_content(ctx, content);
|
||||||
btn.request_complete_repaint(ctx);
|
btn.request_complete_repaint(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,15 +194,11 @@ impl PassphraseKeyboard {
|
|||||||
fn after_edit(&mut self, ctx: &mut EventCtx) {
|
fn after_edit(&mut self, ctx: &mut EventCtx) {
|
||||||
// When the input is empty, enable cancel button. Otherwise show erase and
|
// When the input is empty, enable cancel button. Otherwise show erase and
|
||||||
// confirm button.
|
// confirm button.
|
||||||
let is_empty = self.input.inner().textbox.is_empty();
|
let is_empty = self.input.textbox.is_empty();
|
||||||
self.erase_btn.mutate(ctx, |ctx, btn| {
|
self.erase_btn.show_if(ctx, !is_empty);
|
||||||
btn.show_if(ctx, !is_empty);
|
self.erase_btn.inner_mut().enable_if(ctx, !is_empty);
|
||||||
btn.inner_mut().enable_if(ctx, !is_empty);
|
self.cancel_btn.show_if(ctx, is_empty);
|
||||||
});
|
self.cancel_btn.inner_mut().enable_if(ctx, is_empty);
|
||||||
self.cancel_btn.mutate(ctx, |ctx, btn| {
|
|
||||||
btn.show_if(ctx, is_empty);
|
|
||||||
btn.inner_mut().enable_if(ctx, is_empty);
|
|
||||||
});
|
|
||||||
|
|
||||||
self.update_input_btns_state(ctx);
|
self.update_input_btns_state(ctx);
|
||||||
}
|
}
|
||||||
@ -218,13 +207,11 @@ impl PassphraseKeyboard {
|
|||||||
fn update_input_btns_state(&mut self, ctx: &mut EventCtx) {
|
fn update_input_btns_state(&mut self, ctx: &mut EventCtx) {
|
||||||
let active_states = self.get_buttons_active_states();
|
let active_states = self.get_buttons_active_states();
|
||||||
for (key, btn) in self.keys.iter_mut().enumerate() {
|
for (key, btn) in self.keys.iter_mut().enumerate() {
|
||||||
btn.mutate(ctx, |ctx, b| {
|
if active_states[key] {
|
||||||
if active_states[key] {
|
btn.enable(ctx);
|
||||||
b.enable(ctx);
|
} else {
|
||||||
} else {
|
btn.disable(ctx);
|
||||||
b.disable(ctx);
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,9 +228,9 @@ impl PassphraseKeyboard {
|
|||||||
/// We should disable the input when the passphrase has reached maximum
|
/// We should disable the input when the passphrase has reached maximum
|
||||||
/// length and we are not cycling through the characters.
|
/// length and we are not cycling through the characters.
|
||||||
fn is_button_active(&self, key: usize) -> bool {
|
fn is_button_active(&self, key: usize) -> bool {
|
||||||
let textbox_not_full = self.input.inner().textbox.len() < MAX_LENGTH;
|
let textbox_not_full = self.input.textbox.len() < MAX_LENGTH;
|
||||||
let key_is_pending = {
|
let key_is_pending = {
|
||||||
if let Some(pending) = self.input.inner().multi_tap.pending_key() {
|
if let Some(pending) = self.input.multi_tap.pending_key() {
|
||||||
pending == key
|
pending == key
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@ -253,7 +240,7 @@ impl PassphraseKeyboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn passphrase(&self) -> &str {
|
pub fn passphrase(&self) -> &str {
|
||||||
self.input.inner().textbox.content()
|
self.input.textbox.content()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,9 +294,8 @@ impl Component for PassphraseKeyboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
|
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
|
||||||
if self.input.inner().multi_tap.is_timeout_event(event) {
|
if self.input.multi_tap.is_timeout_event(event) {
|
||||||
self.input
|
self.input.multi_tap.clear_pending_state(ctx);
|
||||||
.mutate(ctx, |ctx, i| i.multi_tap.clear_pending_state(ctx));
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if let Some(swipe) = self.page_swipe.event(ctx, event) {
|
if let Some(swipe) = self.page_swipe.event(ctx, event) {
|
||||||
@ -331,18 +317,14 @@ impl Component for PassphraseKeyboard {
|
|||||||
|
|
||||||
match self.erase_btn.event(ctx, event) {
|
match self.erase_btn.event(ctx, event) {
|
||||||
Some(ButtonMsg::Clicked) => {
|
Some(ButtonMsg::Clicked) => {
|
||||||
self.input.mutate(ctx, |ctx, i| {
|
self.input.multi_tap.clear_pending_state(ctx);
|
||||||
i.multi_tap.clear_pending_state(ctx);
|
self.input.textbox.delete_last(ctx);
|
||||||
i.textbox.delete_last(ctx);
|
|
||||||
});
|
|
||||||
self.after_edit(ctx);
|
self.after_edit(ctx);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Some(ButtonMsg::LongPressed) => {
|
Some(ButtonMsg::LongPressed) => {
|
||||||
self.input.mutate(ctx, |ctx, i| {
|
self.input.multi_tap.clear_pending_state(ctx);
|
||||||
i.multi_tap.clear_pending_state(ctx);
|
self.input.textbox.clear(ctx);
|
||||||
i.textbox.clear(ctx);
|
|
||||||
});
|
|
||||||
self.after_edit(ctx);
|
self.after_edit(ctx);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -362,11 +344,9 @@ impl Component for PassphraseKeyboard {
|
|||||||
if let Some(ButtonMsg::Clicked) = btn.event(ctx, event) {
|
if let Some(ButtonMsg::Clicked) = btn.event(ctx, event) {
|
||||||
// Key button was clicked. If this button is pending, let's cycle the pending
|
// Key button was clicked. If this button is pending, let's cycle the pending
|
||||||
// character in textbox. If not, let's just append the first character.
|
// character in textbox. If not, let's just append the first character.
|
||||||
let text = Self::key_text(btn.inner().content());
|
let text = Self::key_text(btn.content());
|
||||||
self.input.mutate(ctx, |ctx, i| {
|
let edit = text.map(|c| self.input.multi_tap.click_key(ctx, key, c));
|
||||||
let edit = text.map(|c| i.multi_tap.click_key(ctx, key, c));
|
self.input.textbox.apply(ctx, edit);
|
||||||
i.textbox.apply(ctx, edit);
|
|
||||||
});
|
|
||||||
self.after_edit(ctx);
|
self.after_edit(ctx);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -383,7 +363,7 @@ impl Component for PassphraseKeyboard {
|
|||||||
self.next_btn.render(target);
|
self.next_btn.render(target);
|
||||||
self.erase_btn.render(target);
|
self.erase_btn.render(target);
|
||||||
self.confirm_btn.render(target);
|
self.confirm_btn.render(target);
|
||||||
if self.input.inner().textbox.is_empty() {
|
if self.input.textbox.is_empty() {
|
||||||
self.cancel_btn.render(target);
|
self.cancel_btn.render(target);
|
||||||
// FIXME: when prompt fixed in Figma
|
// FIXME: when prompt fixed in Figma
|
||||||
// self.input_prompt.render(target);
|
// self.input_prompt.render(target);
|
||||||
|
@ -8,7 +8,7 @@ use crate::{
|
|||||||
component::{
|
component::{
|
||||||
base::{AttachType, ComponentExt},
|
base::{AttachType, ComponentExt},
|
||||||
text::TextStyle,
|
text::TextStyle,
|
||||||
Child, Component, Event, EventCtx, Label, Never, Pad, SwipeDirection, TimerToken,
|
Component, Event, EventCtx, Label, Never, Pad, SwipeDirection, TimerToken,
|
||||||
},
|
},
|
||||||
display::Font,
|
display::Font,
|
||||||
event::TouchEvent,
|
event::TouchEvent,
|
||||||
@ -246,12 +246,12 @@ pub struct PinKeyboard<'a> {
|
|||||||
allow_cancel: bool,
|
allow_cancel: bool,
|
||||||
show_erase: bool,
|
show_erase: bool,
|
||||||
show_cancel: bool,
|
show_cancel: bool,
|
||||||
major_prompt: Child<Label<'a>>,
|
major_prompt: Label<'a>,
|
||||||
minor_prompt: Child<Label<'a>>,
|
minor_prompt: Label<'a>,
|
||||||
major_warning: Option<Child<Label<'a>>>,
|
major_warning: Option<Label<'a>>,
|
||||||
keypad_area: Rect,
|
keypad_area: Rect,
|
||||||
textbox_area: Rect,
|
textbox_area: Rect,
|
||||||
textbox: Child<PinDots>,
|
textbox: PinDots,
|
||||||
erase_btn: Button,
|
erase_btn: Button,
|
||||||
cancel_btn: Button,
|
cancel_btn: Button,
|
||||||
confirm_btn: Button,
|
confirm_btn: Button,
|
||||||
@ -282,15 +282,13 @@ impl<'a> PinKeyboard<'a> {
|
|||||||
allow_cancel,
|
allow_cancel,
|
||||||
show_erase: false,
|
show_erase: false,
|
||||||
show_cancel: allow_cancel,
|
show_cancel: allow_cancel,
|
||||||
major_prompt: Label::left_aligned(major_prompt, theme::label_keyboard()).into_child(),
|
major_prompt: Label::left_aligned(major_prompt, theme::label_keyboard()),
|
||||||
minor_prompt: Label::right_aligned(minor_prompt, theme::label_keyboard_minor())
|
minor_prompt: Label::right_aligned(minor_prompt, theme::label_keyboard_minor()),
|
||||||
.into_child(),
|
major_warning: major_warning
|
||||||
major_warning: major_warning.map(|text| {
|
.map(|text| Label::left_aligned(text, theme::label_keyboard_warning())),
|
||||||
Label::left_aligned(text, theme::label_keyboard_warning()).into_child()
|
|
||||||
}),
|
|
||||||
keypad_area: Rect::zero(),
|
keypad_area: Rect::zero(),
|
||||||
textbox_area: Rect::zero(),
|
textbox_area: Rect::zero(),
|
||||||
textbox: PinDots::new(theme::label_default()).into_child(),
|
textbox: PinDots::new(theme::label_default()),
|
||||||
erase_btn,
|
erase_btn,
|
||||||
cancel_btn,
|
cancel_btn,
|
||||||
confirm_btn: Button::with_icon(theme::ICON_SIMPLE_CHECKMARK24)
|
confirm_btn: Button::with_icon(theme::ICON_SIMPLE_CHECKMARK24)
|
||||||
@ -318,8 +316,8 @@ impl<'a> PinKeyboard<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn pin_modified(&mut self, ctx: &mut EventCtx) {
|
fn pin_modified(&mut self, ctx: &mut EventCtx) {
|
||||||
let is_full = self.textbox.inner().is_full();
|
let is_full = self.textbox.is_full();
|
||||||
let is_empty = self.textbox.inner().is_empty();
|
let is_empty = self.textbox.is_empty();
|
||||||
|
|
||||||
self.textbox.request_complete_repaint(ctx);
|
self.textbox.request_complete_repaint(ctx);
|
||||||
|
|
||||||
@ -343,7 +341,7 @@ impl<'a> PinKeyboard<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn pin(&self) -> &str {
|
pub fn pin(&self) -> &str {
|
||||||
self.textbox.inner().pin()
|
self.textbox.pin()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_button_alpha(&self, x: usize, y: usize, attach_time: f32, close_time: f32) -> u8 {
|
fn get_button_alpha(&self, x: usize, y: usize, attach_time: f32, close_time: f32) -> u8 {
|
||||||
@ -454,12 +452,12 @@ impl Component for PinKeyboard<'_> {
|
|||||||
}
|
}
|
||||||
match self.erase_btn.event(ctx, event) {
|
match self.erase_btn.event(ctx, event) {
|
||||||
Some(ButtonMsg::Clicked) => {
|
Some(ButtonMsg::Clicked) => {
|
||||||
self.textbox.mutate(ctx, |ctx, t| t.pop(ctx));
|
self.textbox.pop(ctx);
|
||||||
self.pin_modified(ctx);
|
self.pin_modified(ctx);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Some(ButtonMsg::LongPressed) => {
|
Some(ButtonMsg::LongPressed) => {
|
||||||
self.textbox.mutate(ctx, |ctx, t| t.clear(ctx));
|
self.textbox.clear(ctx);
|
||||||
self.pin_modified(ctx);
|
self.pin_modified(ctx);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -469,7 +467,7 @@ impl Component for PinKeyboard<'_> {
|
|||||||
if let Some(Clicked) = btn.0.event(ctx, event) {
|
if let Some(Clicked) = btn.0.event(ctx, event) {
|
||||||
if let ButtonContent::Text(text) = btn.0.content() {
|
if let ButtonContent::Text(text) = btn.0.content() {
|
||||||
text.map(|text| {
|
text.map(|text| {
|
||||||
self.textbox.mutate(ctx, |ctx, t| t.push(ctx, text));
|
self.textbox.push(ctx, text);
|
||||||
});
|
});
|
||||||
self.pin_modified(ctx);
|
self.pin_modified(ctx);
|
||||||
return None;
|
return None;
|
||||||
@ -493,7 +491,7 @@ impl Component for PinKeyboard<'_> {
|
|||||||
self.erase_btn.render_with_alpha(target, erase_alpha);
|
self.erase_btn.render_with_alpha(target, erase_alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.textbox.inner().is_empty() {
|
if self.textbox.is_empty() {
|
||||||
if let Some(ref w) = self.major_warning {
|
if let Some(ref w) = self.major_warning {
|
||||||
w.render(target);
|
w.render(target);
|
||||||
} else {
|
} else {
|
||||||
@ -710,7 +708,7 @@ impl crate::trace::Trace for PinKeyboard<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.string("digits_order", digits_order.as_str().into());
|
t.string("digits_order", digits_order.as_str().into());
|
||||||
t.string("pin", self.textbox.inner().pin().into());
|
t.string("pin", self.textbox.pin().into());
|
||||||
t.bool("display_digits", self.textbox.inner().display_digits);
|
t.bool("display_digits", self.textbox.display_digits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,8 @@ use crate::{
|
|||||||
strutil::{self, TString},
|
strutil::{self, TString},
|
||||||
ui::{
|
ui::{
|
||||||
component::{
|
component::{
|
||||||
base::ComponentExt,
|
|
||||||
text::paragraphs::{Paragraph, Paragraphs},
|
text::paragraphs::{Paragraph, Paragraphs},
|
||||||
Child, Component, Event, EventCtx, Pad, SwipeDirection,
|
Component, Event, EventCtx, Pad, SwipeDirection,
|
||||||
},
|
},
|
||||||
display::Font,
|
display::Font,
|
||||||
event::SwipeEvent,
|
event::SwipeEvent,
|
||||||
@ -23,8 +22,8 @@ pub enum NumberInputDialogMsg {
|
|||||||
|
|
||||||
pub struct NumberInputDialog {
|
pub struct NumberInputDialog {
|
||||||
area: Rect,
|
area: Rect,
|
||||||
input: Child<NumberInput>,
|
input: NumberInput,
|
||||||
paragraphs: Child<Paragraphs<Paragraph<'static>>>,
|
paragraphs: Paragraphs<Paragraph<'static>>,
|
||||||
paragraphs_pad: Pad,
|
paragraphs_pad: Pad,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,15 +31,14 @@ impl NumberInputDialog {
|
|||||||
pub fn new(min: u32, max: u32, init_value: u32, text: TString<'static>) -> Result<Self, Error> {
|
pub fn new(min: u32, max: u32, init_value: u32, text: TString<'static>) -> Result<Self, Error> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
area: Rect::zero(),
|
area: Rect::zero(),
|
||||||
input: NumberInput::new(min, max, init_value).into_child(),
|
input: NumberInput::new(min, max, init_value),
|
||||||
paragraphs: Paragraphs::new(Paragraph::new(&theme::TEXT_MAIN_GREY_LIGHT, text))
|
paragraphs: Paragraphs::new(Paragraph::new(&theme::TEXT_MAIN_GREY_LIGHT, text)),
|
||||||
.into_child(),
|
|
||||||
paragraphs_pad: Pad::with_background(theme::BG),
|
paragraphs_pad: Pad::with_background(theme::BG),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn value(&self) -> u32 {
|
pub fn value(&self) -> u32 {
|
||||||
self.input.inner().value
|
self.input.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +67,7 @@ impl Component for NumberInputDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Event::Swipe(SwipeEvent::End(SwipeDirection::Up)) = event {
|
if let Event::Swipe(SwipeEvent::End(SwipeDirection::Up)) = event {
|
||||||
return Some(NumberInputDialogMsg::Confirmed(self.input.inner().value));
|
return Some(NumberInputDialogMsg::Confirmed(self.input.value));
|
||||||
}
|
}
|
||||||
self.paragraphs.event(ctx, event);
|
self.paragraphs.event(ctx, event);
|
||||||
None
|
None
|
||||||
@ -101,8 +99,8 @@ pub enum NumberInputMsg {
|
|||||||
|
|
||||||
pub struct NumberInput {
|
pub struct NumberInput {
|
||||||
area: Rect,
|
area: Rect,
|
||||||
dec: Child<Button>,
|
dec: Button,
|
||||||
inc: Child<Button>,
|
inc: Button,
|
||||||
min: u32,
|
min: u32,
|
||||||
max: u32,
|
max: u32,
|
||||||
value: u32,
|
value: u32,
|
||||||
@ -110,12 +108,8 @@ pub struct NumberInput {
|
|||||||
|
|
||||||
impl NumberInput {
|
impl NumberInput {
|
||||||
pub fn new(min: u32, max: u32, value: u32) -> Self {
|
pub fn new(min: u32, max: u32, value: u32) -> Self {
|
||||||
let dec = Button::with_icon(theme::ICON_MINUS)
|
let dec = Button::with_icon(theme::ICON_MINUS).styled(theme::button_counter());
|
||||||
.styled(theme::button_counter())
|
let inc = Button::with_icon(theme::ICON_PLUS).styled(theme::button_counter());
|
||||||
.into_child();
|
|
||||||
let inc = Button::with_icon(theme::ICON_PLUS)
|
|
||||||
.styled(theme::button_counter())
|
|
||||||
.into_child();
|
|
||||||
let value = value.clamp(min, max);
|
let value = value.clamp(min, max);
|
||||||
Self {
|
Self {
|
||||||
area: Rect::zero(),
|
area: Rect::zero(),
|
||||||
@ -150,10 +144,8 @@ impl Component for NumberInput {
|
|||||||
changed = true;
|
changed = true;
|
||||||
};
|
};
|
||||||
if changed {
|
if changed {
|
||||||
self.dec
|
self.dec.enable_if(ctx, self.value > self.min);
|
||||||
.mutate(ctx, |ctx, btn| btn.enable_if(ctx, self.value > self.min));
|
self.inc.enable_if(ctx, self.value < self.max);
|
||||||
self.inc
|
|
||||||
.mutate(ctx, |ctx, btn| btn.enable_if(ctx, self.value < self.max));
|
|
||||||
ctx.request_paint();
|
ctx.request_paint();
|
||||||
return Some(NumberInputMsg::Changed(self.value));
|
return Some(NumberInputMsg::Changed(self.value));
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use crate::{
|
|||||||
strutil::{ShortString, TString},
|
strutil::{ShortString, TString},
|
||||||
translations::TR,
|
translations::TR,
|
||||||
ui::{
|
ui::{
|
||||||
component::{base::ComponentExt, Child, Component, Event, EventCtx},
|
component::{Component, Event, EventCtx},
|
||||||
constant::screen,
|
constant::screen,
|
||||||
display,
|
display,
|
||||||
event::TouchEvent,
|
event::TouchEvent,
|
||||||
@ -18,7 +18,7 @@ pub enum NumberInputSliderDialogMsg {
|
|||||||
|
|
||||||
pub struct NumberInputSliderDialog {
|
pub struct NumberInputSliderDialog {
|
||||||
area: Rect,
|
area: Rect,
|
||||||
input: Child<NumberInputSlider>,
|
input: NumberInputSlider,
|
||||||
footer: Footer<'static>,
|
footer: Footer<'static>,
|
||||||
min: u16,
|
min: u16,
|
||||||
max: u16,
|
max: u16,
|
||||||
@ -30,7 +30,7 @@ impl NumberInputSliderDialog {
|
|||||||
pub fn new(min: u16, max: u16, init_value: u16) -> Self {
|
pub fn new(min: u16, max: u16, init_value: u16) -> Self {
|
||||||
Self {
|
Self {
|
||||||
area: Rect::zero(),
|
area: Rect::zero(),
|
||||||
input: NumberInputSlider::new(min, max, init_value).into_child(),
|
input: NumberInputSlider::new(min, max, init_value),
|
||||||
footer: Footer::new::<TString<'static>>(
|
footer: Footer::new::<TString<'static>>(
|
||||||
TR::instructions__swipe_horizontally.into(),
|
TR::instructions__swipe_horizontally.into(),
|
||||||
Some(TR::setting__adjust.into()),
|
Some(TR::setting__adjust.into()),
|
||||||
@ -43,7 +43,7 @@ impl NumberInputSliderDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn value(&self) -> u16 {
|
pub fn value(&self) -> u16 {
|
||||||
self.input.inner().value
|
self.input.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ impl Component for NumberInputSliderDialog {
|
|||||||
if let Some(value) = self.input.event(ctx, event) {
|
if let Some(value) = self.input.event(ctx, event) {
|
||||||
self.val = value;
|
self.val = value;
|
||||||
|
|
||||||
if self.val == self.init_val || self.input.inner().touching {
|
if self.val == self.init_val || self.input.touching {
|
||||||
self.footer
|
self.footer
|
||||||
.update_instruction(ctx, TR::instructions__swipe_horizontally);
|
.update_instruction(ctx, TR::instructions__swipe_horizontally);
|
||||||
self.footer.update_description(ctx, TR::setting__adjust);
|
self.footer.update_description(ctx, TR::setting__adjust);
|
||||||
|
@ -4,10 +4,9 @@ use crate::{
|
|||||||
strutil::TString,
|
strutil::TString,
|
||||||
ui::{
|
ui::{
|
||||||
component::{
|
component::{
|
||||||
base::ComponentExt,
|
|
||||||
paginated::Paginate,
|
paginated::Paginate,
|
||||||
text::paragraphs::{Paragraph, Paragraphs},
|
text::paragraphs::{Paragraph, Paragraphs},
|
||||||
Child, Component, Event, EventCtx, Label, Never, Pad,
|
Component, Event, EventCtx, Label, Never, Pad,
|
||||||
},
|
},
|
||||||
display::{self, Font, LOADER_MAX},
|
display::{self, Font, LOADER_MAX},
|
||||||
geometry::{Insets, Offset, Rect},
|
geometry::{Insets, Offset, Rect},
|
||||||
@ -23,11 +22,11 @@ use crate::{
|
|||||||
use super::theme;
|
use super::theme;
|
||||||
|
|
||||||
pub struct Progress {
|
pub struct Progress {
|
||||||
title: Child<Label<'static>>,
|
title: Label<'static>,
|
||||||
value: u16,
|
value: u16,
|
||||||
loader_y_offset: i16,
|
loader_y_offset: i16,
|
||||||
indeterminate: bool,
|
indeterminate: bool,
|
||||||
description: Child<Paragraphs<Paragraph<'static>>>,
|
description: Paragraphs<Paragraph<'static>>,
|
||||||
description_pad: Pad,
|
description_pad: Pad,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,14 +39,13 @@ impl Progress {
|
|||||||
description: TString<'static>,
|
description: TString<'static>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
title: Label::centered(title, theme::label_progress()).into_child(),
|
title: Label::centered(title, theme::label_progress()),
|
||||||
value: 0,
|
value: 0,
|
||||||
loader_y_offset: 0,
|
loader_y_offset: 0,
|
||||||
indeterminate,
|
indeterminate,
|
||||||
description: Paragraphs::new(
|
description: Paragraphs::new(
|
||||||
Paragraph::new(&theme::TEXT_NORMAL, description).centered(),
|
Paragraph::new(&theme::TEXT_NORMAL, description).centered(),
|
||||||
)
|
),
|
||||||
.into_child(),
|
|
||||||
description_pad: Pad::with_background(theme::BG),
|
description_pad: Pad::with_background(theme::BG),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,10 +58,9 @@ impl Component for Progress {
|
|||||||
let description_lines = 1 + self
|
let description_lines = 1 + self
|
||||||
.description
|
.description
|
||||||
.inner()
|
.inner()
|
||||||
.inner()
|
|
||||||
.content()
|
.content()
|
||||||
.map(|t| t.chars().filter(|c| *c == '\n').count() as i16);
|
.map(|t| t.chars().filter(|c| *c == '\n').count() as i16);
|
||||||
let (title, rest) = Self::AREA.split_top(self.title.inner().max_size().y);
|
let (title, rest) = Self::AREA.split_top(self.title.max_size().y);
|
||||||
let (loader, description) =
|
let (loader, description) =
|
||||||
rest.split_bottom(Font::NORMAL.line_height() * description_lines);
|
rest.split_bottom(Font::NORMAL.line_height() * description_lines);
|
||||||
let loader = loader.inset(Insets::top(theme::CONTENT_BORDER));
|
let loader = loader.inset(Insets::top(theme::CONTENT_BORDER));
|
||||||
@ -80,14 +77,12 @@ impl Component for Progress {
|
|||||||
if !animation_disabled() {
|
if !animation_disabled() {
|
||||||
ctx.request_paint();
|
ctx.request_paint();
|
||||||
}
|
}
|
||||||
self.description.mutate(ctx, |ctx, para| {
|
if self.description.inner_mut().content() != &new_description {
|
||||||
if para.inner_mut().content() != &new_description {
|
self.description.inner_mut().update(new_description);
|
||||||
para.inner_mut().update(new_description);
|
self.description.change_page(0); // Recompute bounding box.
|
||||||
para.change_page(0); // Recompute bounding box.
|
ctx.request_paint();
|
||||||
ctx.request_paint();
|
self.description_pad.clear();
|
||||||
self.description_pad.clear();
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
strutil::TString,
|
strutil::TString,
|
||||||
ui::{
|
ui::{
|
||||||
component::{text::TextStyle, Child, Component, Event, EventCtx, Label, Never, Pad},
|
component::{text::TextStyle, Component, Event, EventCtx, Label, Never, Pad},
|
||||||
constant::screen,
|
constant::screen,
|
||||||
display::{self, Color, Font, Icon},
|
display::{self, Color, Font, Icon},
|
||||||
geometry::{Alignment2D, Insets, Offset, Point, Rect},
|
geometry::{Alignment2D, Insets, Offset, Point, Rect},
|
||||||
@ -117,8 +117,8 @@ pub struct ResultScreen<'a> {
|
|||||||
footer_pad: Pad,
|
footer_pad: Pad,
|
||||||
style: &'a ResultStyle,
|
style: &'a ResultStyle,
|
||||||
icon: Icon,
|
icon: Icon,
|
||||||
message: Child<Label<'a>>,
|
message: Label<'a>,
|
||||||
footer: Child<ResultFooter<'a>>,
|
footer: ResultFooter<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ResultScreen<'a> {
|
impl<'a> ResultScreen<'a> {
|
||||||
@ -134,8 +134,8 @@ impl<'a> ResultScreen<'a> {
|
|||||||
footer_pad: Pad::with_background(style.bg_color),
|
footer_pad: Pad::with_background(style.bg_color),
|
||||||
style,
|
style,
|
||||||
icon,
|
icon,
|
||||||
message: Child::new(Label::centered(message, style.message_style())),
|
message: Label::centered(message, style.message_style()),
|
||||||
footer: Child::new(ResultFooter::new(footer, style)),
|
footer: ResultFooter::new(footer, style),
|
||||||
};
|
};
|
||||||
|
|
||||||
if complete_draw {
|
if complete_draw {
|
||||||
|
Loading…
Reference in New Issue
Block a user