gui: iced-0.12
This commit is contained in:
parent
64a626d7e8
commit
fdcc302367
1521
gui/Cargo.lock
generated
1521
gui/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -21,8 +21,8 @@ liana_ui = { path = "ui" }
|
||||
backtrace = "0.3"
|
||||
hex = "0.4.3"
|
||||
|
||||
iced = { version = "0.10", default-features = false, features = ["tokio", "svg", "qr_code", "image", "lazy", "wgpu"] }
|
||||
iced_runtime = "0.1.1"
|
||||
iced = { version = "0.12.1", default-features = false, features = ["tokio", "svg", "qr_code", "image", "lazy", "webgl"] }
|
||||
iced_runtime = "0.12.1"
|
||||
|
||||
tokio = {version = "1.21.0", features = ["signal"]}
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
@ -47,6 +47,12 @@ bitcoin_hashes = "0.12"
|
||||
reqwest = { version = "0.11", default-features=false, features = ["rustls-tls"] }
|
||||
rust-ini = "0.19.0"
|
||||
|
||||
|
||||
[patch.crates-io]
|
||||
iced_style = { git = "https://github.com/edouardparis/iced", branch = "patch-0.12.3"}
|
||||
iced_winit = { git = "https://github.com/edouardparis/iced", branch = "patch-0.12.3"}
|
||||
iced_futures = { git = "https://github.com/edouardparis/iced", branch = "patch-0.12.3"}
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
zip = { version = "0.6", default-features=false, features = ["bzip2", "deflate"] }
|
||||
|
||||
|
||||
@ -302,13 +302,13 @@ impl VerifyAddressModal {
|
||||
}
|
||||
|
||||
pub struct ShowQrCodeModal {
|
||||
qr_code: qr_code::State,
|
||||
qr_code: qr_code::Data,
|
||||
address: String,
|
||||
}
|
||||
|
||||
impl ShowQrCodeModal {
|
||||
pub fn new(address: &Address, index: ChildNumber) -> Option<Self> {
|
||||
qr_code::State::new(format!("bitcoin:{}?index={}", address, index))
|
||||
qr_code::Data::new(format!("bitcoin:{}?index={}", address, index))
|
||||
.ok()
|
||||
.map(|qr_code| Self {
|
||||
qr_code,
|
||||
|
||||
@ -6,7 +6,6 @@ use liana_ui::{
|
||||
color,
|
||||
component::{amount::*, badge, button, form, text::*},
|
||||
icon, theme,
|
||||
util::Collection,
|
||||
widget::*,
|
||||
};
|
||||
|
||||
|
||||
@ -8,7 +8,6 @@ use liana_ui::{
|
||||
color,
|
||||
component::{amount::*, button, card, event, form, text::*},
|
||||
icon, theme,
|
||||
util::Collection,
|
||||
widget::*,
|
||||
};
|
||||
|
||||
|
||||
@ -29,7 +29,6 @@ use liana_ui::{
|
||||
},
|
||||
image::*,
|
||||
theme,
|
||||
util::Collection,
|
||||
widget::*,
|
||||
};
|
||||
|
||||
|
||||
@ -23,7 +23,6 @@ use liana_ui::{
|
||||
text::{self, *},
|
||||
},
|
||||
icon, theme,
|
||||
util::Collection,
|
||||
widget::*,
|
||||
};
|
||||
|
||||
@ -426,7 +425,7 @@ pub fn signatures<'a>(
|
||||
Container::new(text(alias))
|
||||
.padding(10)
|
||||
.style(theme::Container::Pill(theme::Pill::Simple)),
|
||||
value.to_string(),
|
||||
liana_ui::widget::Text::new(value.to_string()),
|
||||
tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
@ -522,7 +521,7 @@ fn container_from_fg(
|
||||
Container::new(text(alias))
|
||||
.padding(10)
|
||||
.style(theme::Container::Pill(theme::Pill::Simple)),
|
||||
fg.to_string(),
|
||||
liana_ui::widget::Text::new(fg.to_string()),
|
||||
tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
|
||||
@ -4,7 +4,6 @@ use liana_ui::{
|
||||
color,
|
||||
component::{amount::*, badge, button, card, form, text::*},
|
||||
icon, theme,
|
||||
util::Collection,
|
||||
widget::*,
|
||||
};
|
||||
|
||||
|
||||
@ -21,7 +21,6 @@ use liana_ui::{
|
||||
text::{self, *},
|
||||
},
|
||||
icon, theme,
|
||||
util::Collection,
|
||||
widget::*,
|
||||
};
|
||||
|
||||
@ -216,13 +215,13 @@ pub fn verify_address_modal<'a>(
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn qr_modal<'a>(qr: &'a qr_code::State, address: &'a String) -> Element<'a, Message> {
|
||||
pub fn qr_modal<'a>(qr: &'a qr_code::Data, address: &'a String) -> Element<'a, Message> {
|
||||
Column::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.push(Space::with_width(Length::Fill))
|
||||
.push(
|
||||
Container::new(QRCode::new(qr).cell_size(8))
|
||||
Container::new(QRCode::<liana_ui::theme::Theme>::new(qr).cell_size(8))
|
||||
.padding(10)
|
||||
.style(theme::Container::QrCode),
|
||||
)
|
||||
|
||||
@ -13,7 +13,6 @@ use liana::miniscript::bitcoin::{
|
||||
use liana_ui::{
|
||||
component::{amount::*, button, form, text::*},
|
||||
icon, theme,
|
||||
util::*,
|
||||
widget::*,
|
||||
};
|
||||
|
||||
@ -144,9 +143,10 @@ pub fn recovery_path_view<'a>(
|
||||
selected: bool,
|
||||
) -> Element<'a, Message> {
|
||||
Row::new()
|
||||
.push(checkbox("", selected, move |_| {
|
||||
Message::CreateSpend(CreateSpendMessage::SelectPath(index))
|
||||
}))
|
||||
.push(
|
||||
checkbox("", selected)
|
||||
.on_toggle(move |_| Message::CreateSpend(CreateSpendMessage::SelectPath(index))),
|
||||
)
|
||||
.push(
|
||||
Column::new()
|
||||
.push(
|
||||
@ -170,7 +170,7 @@ pub fn recovery_path_view<'a>(
|
||||
Container::new(text(alias))
|
||||
.padding(5)
|
||||
.style(theme::Container::Pill(theme::Pill::Simple)),
|
||||
fg.to_string(),
|
||||
liana_ui::widget::Text::new(fg.to_string()),
|
||||
tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
|
||||
@ -18,7 +18,6 @@ use liana_ui::{
|
||||
color,
|
||||
component::{badge, button, card, form, separation, text::*, tooltip::tooltip},
|
||||
icon, theme,
|
||||
util::Collection,
|
||||
widget::*,
|
||||
};
|
||||
|
||||
|
||||
@ -15,7 +15,6 @@ use liana_ui::{
|
||||
color,
|
||||
component::{amount::*, badge, button, form, text::*},
|
||||
icon, theme,
|
||||
util::Collection,
|
||||
widget::*,
|
||||
};
|
||||
|
||||
@ -405,9 +404,8 @@ pub fn recipient_view<'a>(
|
||||
None
|
||||
})
|
||||
.push(tooltip::Tooltip::new(
|
||||
checkbox("MAX", is_max_selected, move |_| {
|
||||
CreateSpendMessage::SendMaxToRecipient(index)
|
||||
}),
|
||||
checkbox("MAX", is_max_selected)
|
||||
.on_toggle(move |_| CreateSpendMessage::SendMaxToRecipient(index)),
|
||||
// Add spaces at end so that text is padded at screen edge.
|
||||
"Total amount remaining after paying fee and any other recipients ",
|
||||
tooltip::Position::Bottom,
|
||||
@ -431,9 +429,11 @@ fn coin_list_view<'a>(
|
||||
Row::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.push(checkbox("", selected, move |_| {
|
||||
Message::CreateSpend(CreateSpendMessage::SelectCoin(i))
|
||||
}))
|
||||
.push(
|
||||
checkbox("", selected).on_toggle(move |_| {
|
||||
Message::CreateSpend(CreateSpendMessage::SelectCoin(i))
|
||||
}),
|
||||
)
|
||||
.push(
|
||||
if let Some(label) = coins_labels.get(&coin.outpoint.to_string()) {
|
||||
Container::new(p1_regular(label)).width(Length::Fill)
|
||||
|
||||
@ -7,7 +7,6 @@ use liana_ui::{
|
||||
color,
|
||||
component::{amount::*, badge, button, card, form, text::*},
|
||||
icon, theme,
|
||||
util::Collection,
|
||||
widget::*,
|
||||
};
|
||||
|
||||
|
||||
@ -18,7 +18,6 @@ use liana_ui::{
|
||||
tooltip,
|
||||
},
|
||||
icon, image, theme,
|
||||
util::Collection,
|
||||
widget::*,
|
||||
};
|
||||
|
||||
@ -720,11 +719,10 @@ pub fn participate_xpub<'a>(
|
||||
.push(signer)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(checkbox(
|
||||
"I have shared my extended public key",
|
||||
shared,
|
||||
Message::UserActionDone,
|
||||
))
|
||||
.push(
|
||||
checkbox("I have shared my extended public key", shared)
|
||||
.on_toggle(Message::UserActionDone),
|
||||
)
|
||||
.push(if shared && network_valid {
|
||||
button::primary(None, "Next")
|
||||
.width(Length::Fixed(200.0))
|
||||
@ -807,8 +805,7 @@ pub fn register_descriptor<'a>(
|
||||
.push_maybe(created_desc.then_some(checkbox(
|
||||
"I have registered the descriptor on my device(s)",
|
||||
done,
|
||||
Message::UserActionDone,
|
||||
)))
|
||||
).on_toggle(Message::UserActionDone)))
|
||||
.push(if !created_desc || (done && !processing) {
|
||||
button::primary(None, "Next")
|
||||
.on_press(Message::Next)
|
||||
@ -872,11 +869,9 @@ pub fn backup_descriptor<'a>(
|
||||
.spacing(10)
|
||||
.max_width(1000),
|
||||
))
|
||||
.push(checkbox(
|
||||
"I have backed up my descriptor",
|
||||
done,
|
||||
Message::UserActionDone,
|
||||
))
|
||||
.push(
|
||||
checkbox("I have backed up my descriptor", done).on_toggle(Message::UserActionDone),
|
||||
)
|
||||
.push(if done {
|
||||
button::primary(None, "Next")
|
||||
.on_press(Message::Next)
|
||||
@ -1678,7 +1673,7 @@ pub fn edit_sequence_modal<'a>(sequence: &form::Value<String>) -> Element<'a, Me
|
||||
message::SequenceModal::SequenceEdited(v.to_string()),
|
||||
))
|
||||
})
|
||||
.step(144), // 144 blocks per day
|
||||
.step(144_u16), // 144 blocks per day
|
||||
)
|
||||
.width(Length::Fixed(500.0)),
|
||||
);
|
||||
@ -1821,11 +1816,7 @@ pub fn backup_mnemonic<'a>(
|
||||
)
|
||||
}),
|
||||
)
|
||||
.push(checkbox(
|
||||
"I have backed up my mnemonic",
|
||||
done,
|
||||
Message::UserActionDone,
|
||||
))
|
||||
.push(checkbox("I have backed up my mnemonic", done).on_toggle(Message::UserActionDone))
|
||||
.push(if done {
|
||||
button::primary(None, "Next")
|
||||
.on_press(Message::Next)
|
||||
@ -2041,7 +2032,7 @@ mod threshsold_input {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Message> Component<Message, iced::Renderer<theme::Theme>> for ThresholdInput<Message> {
|
||||
impl<Message> Component<Message, theme::Theme> for ThresholdInput<Message> {
|
||||
type State = ();
|
||||
type Event = Event;
|
||||
|
||||
|
||||
@ -11,7 +11,6 @@ use liana_ui::{
|
||||
color,
|
||||
component::{badge, button, card, modal::Modal, notification, text::*},
|
||||
icon, image, theme,
|
||||
util::*,
|
||||
widget::*,
|
||||
};
|
||||
|
||||
|
||||
@ -19,7 +19,6 @@ use liana_ui::{
|
||||
color,
|
||||
component::{button, notification, text::*},
|
||||
icon,
|
||||
util::Collection,
|
||||
widget::*,
|
||||
};
|
||||
|
||||
|
||||
@ -5,9 +5,9 @@ use std::{error::Error, io::Write, path::PathBuf, process, str::FromStr};
|
||||
use iced::{
|
||||
event::{self, Event},
|
||||
executor,
|
||||
keyboard::{self, KeyCode},
|
||||
subscription,
|
||||
keyboard::{self},
|
||||
widget::{focus_next, focus_previous},
|
||||
window::settings::PlatformSpecific,
|
||||
Application, Command, Settings, Subscription,
|
||||
};
|
||||
use tracing::{error, info};
|
||||
@ -180,14 +180,14 @@ impl Application for GUI {
|
||||
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
|
||||
match (&mut self.state, message) {
|
||||
(_, Message::CtrlC)
|
||||
| (_, Message::Event(iced::Event::Window(iced::window::Event::CloseRequested))) => {
|
||||
| (_, Message::Event(iced::Event::Window(_, iced::window::Event::CloseRequested))) => {
|
||||
match &mut self.state {
|
||||
State::Loader(s) => s.stop(),
|
||||
State::Launcher(s) => s.stop(),
|
||||
State::Installer(s) => s.stop(),
|
||||
State::App(s) => s.stop(),
|
||||
};
|
||||
iced::window::close()
|
||||
iced::window::close(iced::window::Id::MAIN)
|
||||
}
|
||||
(_, Message::KeyPressed(Key::Tab(shift))) => {
|
||||
log::debug!("Tab pressed!");
|
||||
@ -286,22 +286,29 @@ impl Application for GUI {
|
||||
State::App(v) => v.subscription().map(|msg| Message::Run(Box::new(msg))),
|
||||
State::Launcher(v) => v.subscription().map(|msg| Message::Launch(Box::new(msg))),
|
||||
},
|
||||
subscription::events_with(|event, status| match (&event, status) {
|
||||
iced::event::listen_with(|event, status| match (&event, status) {
|
||||
(
|
||||
Event::Keyboard(keyboard::Event::KeyPressed {
|
||||
key_code: KeyCode::Tab,
|
||||
key: iced::keyboard::Key::Named(iced::keyboard::key::Named::Tab),
|
||||
modifiers,
|
||||
..
|
||||
}),
|
||||
event::Status::Ignored,
|
||||
) => Some(Message::KeyPressed(Key::Tab(modifiers.shift()))),
|
||||
(
|
||||
iced::Event::Window(iced::window::Event::CloseRequested),
|
||||
iced::Event::Window(_, iced::window::Event::CloseRequested),
|
||||
event::Status::Ignored,
|
||||
) => Some(Message::Event(event)),
|
||||
_ => None,
|
||||
}),
|
||||
])
|
||||
.with_filter(|event| {
|
||||
matches!(
|
||||
event,
|
||||
iced::Event::Window(_, iced::window::Event::CloseRequested)
|
||||
| iced::Event::Keyboard(_)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn view(&self) -> Element<Self::Message> {
|
||||
@ -436,13 +443,13 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
settings.window.icon = Some(image::liana_app_icon());
|
||||
settings.default_text_size = text::P1_SIZE.into();
|
||||
settings.default_font = liana_ui::font::REGULAR;
|
||||
settings.exit_on_close_request = false;
|
||||
settings.window.exit_on_close_request = false;
|
||||
|
||||
settings.id = Some("Liana".to_string());
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
settings.window.platform_specific = iced::window::PlatformSpecific {
|
||||
settings.window.platform_specific = PlatformSpecific {
|
||||
application_id: "Liana".to_string(),
|
||||
};
|
||||
}
|
||||
|
||||
@ -6,6 +6,6 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
iced = { version = "0.10", default-features = false, features = ["svg", "image", "lazy", "advanced"] }
|
||||
iced = { version = "0.12.1", default-features = false, features = ["svg", "image", "lazy", "qr_code", "advanced", "webgl"] }
|
||||
bitcoin = "0.31"
|
||||
chrono = "0.4"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
pub use bitcoin::Amount;
|
||||
|
||||
use crate::{color, component::text::*, util::Collection, widget::*};
|
||||
use crate::{color, component::text::*, widget::*};
|
||||
|
||||
pub fn amount<'a, T: 'a>(a: &Amount) -> Row<'a, T> {
|
||||
amount_with_size(a, P1_SIZE)
|
||||
|
||||
@ -34,7 +34,7 @@ pub fn error<'a, T: 'a>(message: &'static str, error: String) -> Container<'a, T
|
||||
.align_items(iced::Alignment::Center)
|
||||
.push(icon::warning_icon().style(color::RED))
|
||||
.push(text(message).style(color::RED)),
|
||||
error,
|
||||
Text::new(error),
|
||||
iced::widget::tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Error)),
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
use crate::widget::*;
|
||||
use iced::widget::{column, component, Component};
|
||||
use iced::{
|
||||
advanced,
|
||||
widget::{column, component, Button, Component},
|
||||
Element,
|
||||
};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub struct Collapse<'a, M, H, F, C> {
|
||||
@ -9,13 +12,15 @@ pub struct Collapse<'a, M, H, F, C> {
|
||||
phantom: PhantomData<&'a M>,
|
||||
}
|
||||
|
||||
impl<'a, Message, T, H, F, C> Collapse<'a, Message, H, F, C>
|
||||
impl<'a, Message, T, H, F, C, Theme, Renderer> Collapse<'a, Message, H, F, C>
|
||||
where
|
||||
Renderer: advanced::Renderer,
|
||||
Theme: iced::widget::button::StyleSheet,
|
||||
Message: 'a,
|
||||
T: Into<Message> + Clone + 'a,
|
||||
H: Fn() -> Button<'a, Event<T>> + 'a,
|
||||
F: Fn() -> Button<'a, Event<T>> + 'a,
|
||||
C: Fn() -> Element<'a, T> + 'a,
|
||||
H: Fn() -> Button<'a, Event<T>, Theme, Renderer> + 'a,
|
||||
F: Fn() -> Button<'a, Event<T>, Theme, Renderer> + 'a,
|
||||
C: Fn() -> Element<'a, T, Theme, Renderer> + 'a,
|
||||
{
|
||||
pub fn new(before: H, after: F, content: C) -> Self {
|
||||
Collapse {
|
||||
@ -33,13 +38,15 @@ pub enum Event<T> {
|
||||
Collapse(bool),
|
||||
}
|
||||
|
||||
impl<'a, Message, T, H, F, C> Component<Message, iced::Renderer<crate::theme::Theme>>
|
||||
impl<'a, Message, T, H, F, C, Theme, Renderer> Component<Message, Theme, Renderer>
|
||||
for Collapse<'a, Message, H, F, C>
|
||||
where
|
||||
T: Into<Message> + Clone + 'a,
|
||||
H: Fn() -> Button<'a, Event<T>>,
|
||||
F: Fn() -> Button<'a, Event<T>>,
|
||||
C: Fn() -> Element<'a, T>,
|
||||
H: Fn() -> Button<'a, Event<T>, Theme, Renderer>,
|
||||
F: Fn() -> Button<'a, Event<T>, Theme, Renderer>,
|
||||
C: Fn() -> Element<'a, T, Theme, Renderer>,
|
||||
Renderer: 'a + advanced::Renderer,
|
||||
Theme: 'a + iced::widget::button::StyleSheet,
|
||||
{
|
||||
type State = bool;
|
||||
type Event = Event<T>;
|
||||
@ -54,7 +61,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn view(&self, state: &Self::State) -> Element<Self::Event> {
|
||||
fn view(&self, state: &Self::State) -> Element<Self::Event, Theme, Renderer> {
|
||||
if *state {
|
||||
column![
|
||||
(self.after)().on_press(Event::Collapse(false)),
|
||||
@ -67,14 +74,16 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Message, T, H: 'a, F: 'a, C: 'a> From<Collapse<'a, Message, H, F, C>>
|
||||
for Element<'a, Message>
|
||||
impl<'a, Message, T, H: 'a, F: 'a, C: 'a, Theme, Renderer> From<Collapse<'a, Message, H, F, C>>
|
||||
for Element<'a, Message, Theme, Renderer>
|
||||
where
|
||||
Message: 'a,
|
||||
Renderer: 'a + advanced::Renderer,
|
||||
Theme: 'a + iced::widget::button::StyleSheet,
|
||||
T: Into<Message> + Clone + 'a,
|
||||
H: Fn() -> Button<'a, Event<T>>,
|
||||
F: Fn() -> Button<'a, Event<T>>,
|
||||
C: Fn() -> Element<'a, T>,
|
||||
H: Fn() -> Button<'a, Event<T>, Theme, Renderer>,
|
||||
F: Fn() -> Button<'a, Event<T>, Theme, Renderer>,
|
||||
C: Fn() -> Element<'a, T, Theme, Renderer>,
|
||||
{
|
||||
fn from(c: Collapse<'a, Message, H, F, C>) -> Self {
|
||||
component(c)
|
||||
|
||||
@ -2,7 +2,6 @@ use crate::{
|
||||
color,
|
||||
component::{amount, badge, text},
|
||||
theme,
|
||||
util::Collection,
|
||||
widget::*,
|
||||
};
|
||||
use bitcoin::Amount;
|
||||
@ -12,7 +11,7 @@ use iced::{
|
||||
};
|
||||
|
||||
pub fn unconfirmed_outgoing_event<'a, T: Clone + 'a>(
|
||||
label: Option<iced::widget::Text<'a, iced::Renderer<theme::Theme>>>,
|
||||
label: Option<Text<'a>>,
|
||||
amount: &Amount,
|
||||
msg: T,
|
||||
) -> Container<'a, T> {
|
||||
@ -39,7 +38,7 @@ pub fn unconfirmed_outgoing_event<'a, T: Clone + 'a>(
|
||||
}
|
||||
|
||||
pub fn confirmed_outgoing_event<'a, T: Clone + 'a>(
|
||||
label: Option<iced::widget::Text<'a, iced::Renderer<theme::Theme>>>,
|
||||
label: Option<Text<'a>>,
|
||||
date: chrono::NaiveDateTime,
|
||||
amount: &Amount,
|
||||
msg: T,
|
||||
@ -72,7 +71,7 @@ pub fn confirmed_outgoing_event<'a, T: Clone + 'a>(
|
||||
}
|
||||
|
||||
pub fn unconfirmed_incoming_event<'a, T: Clone + 'a>(
|
||||
label: Option<iced::widget::Text<'a, iced::Renderer<theme::Theme>>>,
|
||||
label: Option<Text<'a>>,
|
||||
amount: &Amount,
|
||||
msg: T,
|
||||
) -> Container<'a, T> {
|
||||
@ -99,7 +98,7 @@ pub fn unconfirmed_incoming_event<'a, T: Clone + 'a>(
|
||||
}
|
||||
|
||||
pub fn confirmed_incoming_event<'a, T: Clone + 'a>(
|
||||
label: Option<iced::widget::Text<'a, iced::Renderer<theme::Theme>>>,
|
||||
label: Option<Text<'a>>,
|
||||
date: chrono::NaiveDateTime,
|
||||
amount: &Amount,
|
||||
msg: T,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use bitcoin::Denomination;
|
||||
use iced::{widget::text_input, Length};
|
||||
|
||||
use crate::{color, component::text, theme, util::Collection, widget::*};
|
||||
use crate::{color, component::text, theme, widget::*};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Value<T> {
|
||||
@ -19,7 +19,7 @@ impl std::default::Default for Value<String> {
|
||||
}
|
||||
|
||||
pub struct Form<'a, Message> {
|
||||
input: text_input::TextInput<'a, Message, iced::Renderer<theme::Theme>>,
|
||||
input: TextInput<'a, Message>,
|
||||
warning: Option<&'a str>,
|
||||
valid: bool,
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::{color, component::text, icon, image, theme, util::*, widget::*};
|
||||
use crate::{color, component::text, icon, image, theme, widget::*};
|
||||
use iced::{
|
||||
widget::{column, container, row, tooltip},
|
||||
Alignment, Length,
|
||||
|
||||
@ -7,20 +7,20 @@ use iced::advanced::{self, Clipboard, Shell};
|
||||
use iced::alignment::Alignment;
|
||||
use iced::event;
|
||||
use iced::mouse;
|
||||
use iced::{Color, Element, Event, Length, Point, Rectangle, Size};
|
||||
use iced::{Color, Element, Event, Length, Point, Rectangle, Size, Vector};
|
||||
|
||||
/// A widget that centers a modal element over some base element
|
||||
pub struct Modal<'a, Message, Renderer> {
|
||||
base: Element<'a, Message, Renderer>,
|
||||
modal: Element<'a, Message, Renderer>,
|
||||
pub struct Modal<'a, Message, Theme, Renderer> {
|
||||
base: Element<'a, Message, Theme, Renderer>,
|
||||
modal: Element<'a, Message, Theme, Renderer>,
|
||||
on_blur: Option<Message>,
|
||||
}
|
||||
|
||||
impl<'a, Message, Renderer> Modal<'a, Message, Renderer> {
|
||||
impl<'a, Message, Theme, Renderer> Modal<'a, Message, Theme, Renderer> {
|
||||
/// Returns a new [`Modal`]
|
||||
pub fn new(
|
||||
base: impl Into<Element<'a, Message, Renderer>>,
|
||||
modal: impl Into<Element<'a, Message, Renderer>>,
|
||||
base: impl Into<Element<'a, Message, Theme, Renderer>>,
|
||||
modal: impl Into<Element<'a, Message, Theme, Renderer>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
base: base.into(),
|
||||
@ -36,7 +36,8 @@ impl<'a, Message, Renderer> Modal<'a, Message, Renderer> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Message, Renderer> Widget<Message, Renderer> for Modal<'a, Message, Renderer>
|
||||
impl<'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer>
|
||||
for Modal<'a, Message, Theme, Renderer>
|
||||
where
|
||||
Renderer: advanced::Renderer,
|
||||
Message: Clone,
|
||||
@ -49,16 +50,19 @@ where
|
||||
tree.diff_children(&[&self.base, &self.modal]);
|
||||
}
|
||||
|
||||
fn width(&self) -> Length {
|
||||
self.base.as_widget().width()
|
||||
fn size(&self) -> Size<Length> {
|
||||
self.base.as_widget().size()
|
||||
}
|
||||
|
||||
fn height(&self) -> Length {
|
||||
self.base.as_widget().height()
|
||||
}
|
||||
|
||||
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> layout::Node {
|
||||
self.base.as_widget().layout(renderer, limits)
|
||||
fn layout(
|
||||
&self,
|
||||
tree: &mut widget::Tree,
|
||||
renderer: &Renderer,
|
||||
limits: &layout::Limits,
|
||||
) -> layout::Node {
|
||||
self.base
|
||||
.as_widget()
|
||||
.layout(&mut tree.children[0], renderer, limits)
|
||||
}
|
||||
|
||||
fn on_event(
|
||||
@ -88,7 +92,7 @@ where
|
||||
&self,
|
||||
state: &widget::Tree,
|
||||
renderer: &mut Renderer,
|
||||
theme: &<Renderer as advanced::Renderer>::Theme,
|
||||
theme: &Theme,
|
||||
style: &renderer::Style,
|
||||
layout: Layout<'_>,
|
||||
cursor: mouse::Cursor,
|
||||
@ -110,16 +114,15 @@ where
|
||||
state: &'b mut Tree,
|
||||
layout: Layout<'_>,
|
||||
_renderer: &Renderer,
|
||||
) -> Option<overlay::Element<'b, Message, Renderer>> {
|
||||
Some(overlay::Element::new(
|
||||
layout.position(),
|
||||
Box::new(Overlay {
|
||||
content: &mut self.modal,
|
||||
tree: &mut state.children[1],
|
||||
size: layout.bounds().size(),
|
||||
on_blur: self.on_blur.clone(),
|
||||
}),
|
||||
))
|
||||
translation: Vector,
|
||||
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
|
||||
Some(overlay::Element::new(Box::new(Overlay {
|
||||
position: layout.position() + translation,
|
||||
content: &mut self.modal,
|
||||
tree: &mut state.children[1],
|
||||
size: layout.bounds().size(),
|
||||
on_blur: self.on_blur.clone(),
|
||||
})))
|
||||
}
|
||||
|
||||
fn mouse_interaction(
|
||||
@ -152,31 +155,32 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
struct Overlay<'a, 'b, Message, Renderer> {
|
||||
content: &'b mut Element<'a, Message, Renderer>,
|
||||
struct Overlay<'a, 'b, Message, Theme, Renderer> {
|
||||
position: Point,
|
||||
content: &'b mut Element<'a, Message, Theme, Renderer>,
|
||||
tree: &'b mut Tree,
|
||||
size: Size,
|
||||
on_blur: Option<Message>,
|
||||
}
|
||||
|
||||
impl<'a, 'b, Message, Renderer> overlay::Overlay<Message, Renderer>
|
||||
for Overlay<'a, 'b, Message, Renderer>
|
||||
impl<'a, 'b, Message, Theme, Renderer> overlay::Overlay<Message, Theme, Renderer>
|
||||
for Overlay<'a, 'b, Message, Theme, Renderer>
|
||||
where
|
||||
Renderer: advanced::Renderer,
|
||||
Message: Clone,
|
||||
{
|
||||
fn layout(&self, renderer: &Renderer, _bounds: Size, position: Point) -> layout::Node {
|
||||
fn layout(&mut self, renderer: &Renderer, _bounds: Size) -> layout::Node {
|
||||
let limits = layout::Limits::new(Size::ZERO, self.size)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill);
|
||||
|
||||
let mut child = self.content.as_widget().layout(renderer, &limits);
|
||||
child.align(Alignment::Center, Alignment::Center, limits.max());
|
||||
let child = self
|
||||
.content
|
||||
.as_widget()
|
||||
.layout(self.tree, renderer, &limits)
|
||||
.align(Alignment::Center, Alignment::Center, limits.max());
|
||||
|
||||
let mut node = layout::Node::with_children(self.size, vec![child]);
|
||||
node.move_to(position);
|
||||
|
||||
node
|
||||
layout::Node::with_children(self.size, vec![child]).move_to(self.position)
|
||||
}
|
||||
|
||||
fn on_event(
|
||||
@ -214,7 +218,7 @@ where
|
||||
fn draw(
|
||||
&self,
|
||||
renderer: &mut Renderer,
|
||||
theme: &Renderer::Theme,
|
||||
theme: &Theme,
|
||||
style: &renderer::Style,
|
||||
layout: Layout<'_>,
|
||||
cursor: mouse::Cursor,
|
||||
@ -222,9 +226,7 @@ where
|
||||
renderer.fill_quad(
|
||||
renderer::Quad {
|
||||
bounds: layout.bounds(),
|
||||
border_radius: Default::default(),
|
||||
border_width: 0.0,
|
||||
border_color: Color::TRANSPARENT,
|
||||
..renderer::Quad::default()
|
||||
},
|
||||
Color {
|
||||
a: 0.80,
|
||||
@ -277,19 +279,24 @@ where
|
||||
&'c mut self,
|
||||
layout: Layout<'_>,
|
||||
renderer: &Renderer,
|
||||
) -> Option<overlay::Element<'c, Message, Renderer>> {
|
||||
self.content
|
||||
.as_widget_mut()
|
||||
.overlay(self.tree, layout.children().next().unwrap(), renderer)
|
||||
) -> Option<overlay::Element<'c, Message, Theme, Renderer>> {
|
||||
self.content.as_widget_mut().overlay(
|
||||
self.tree,
|
||||
layout.children().next().unwrap(),
|
||||
renderer,
|
||||
Vector::ZERO,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Message, Renderer> From<Modal<'a, Message, Renderer>> for Element<'a, Message, Renderer>
|
||||
impl<'a, Message, Theme, Renderer> From<Modal<'a, Message, Theme, Renderer>>
|
||||
for Element<'a, Message, Theme, Renderer>
|
||||
where
|
||||
Renderer: 'a + advanced::Renderer,
|
||||
Message: 'a + Clone,
|
||||
Theme: 'a,
|
||||
{
|
||||
fn from(modal: Modal<'a, Message, Renderer>) -> Self {
|
||||
fn from(modal: Modal<'a, Message, Theme, Renderer>) -> Self {
|
||||
Element::new(modal)
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,6 @@ use crate::{
|
||||
color,
|
||||
component::{collapse, text},
|
||||
icon, theme,
|
||||
util::*,
|
||||
widget::*,
|
||||
};
|
||||
use iced::{
|
||||
|
||||
@ -18,105 +18,85 @@ pub const P2_SIZE: u16 = 17;
|
||||
// 12 * 1.2
|
||||
pub const CAPTION_SIZE: u16 = 15;
|
||||
|
||||
pub fn h1<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
||||
pub fn h1<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
.font(font::BOLD)
|
||||
.size(H1_SIZE)
|
||||
}
|
||||
|
||||
pub fn h2<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
||||
pub fn h2<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
.font(font::BOLD)
|
||||
.size(H2_SIZE)
|
||||
}
|
||||
|
||||
pub fn h3<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
||||
pub fn h3<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
.font(font::BOLD)
|
||||
.size(H3_SIZE)
|
||||
}
|
||||
|
||||
pub fn h4_bold<'a>(
|
||||
content: impl Into<Cow<'a, str>>,
|
||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
||||
pub fn h4_bold<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
.font(font::BOLD)
|
||||
.size(H4_SIZE)
|
||||
}
|
||||
|
||||
pub fn h4_regular<'a>(
|
||||
content: impl Into<Cow<'a, str>>,
|
||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
||||
pub fn h4_regular<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
.font(font::REGULAR)
|
||||
.size(H4_SIZE)
|
||||
}
|
||||
|
||||
pub fn h5_medium<'a>(
|
||||
content: impl Into<Cow<'a, str>>,
|
||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
||||
pub fn h5_medium<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
.font(font::MEDIUM)
|
||||
.size(H5_SIZE)
|
||||
}
|
||||
|
||||
pub fn h5_regular<'a>(
|
||||
content: impl Into<Cow<'a, str>>,
|
||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
||||
pub fn h5_regular<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
.font(font::REGULAR)
|
||||
.size(H5_SIZE)
|
||||
}
|
||||
|
||||
pub fn p1_bold<'a>(
|
||||
content: impl Into<Cow<'a, str>>,
|
||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
||||
pub fn p1_bold<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
.font(font::BOLD)
|
||||
.size(P1_SIZE)
|
||||
}
|
||||
|
||||
pub fn p1_medium<'a>(
|
||||
content: impl Into<Cow<'a, str>>,
|
||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
||||
pub fn p1_medium<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
.font(font::MEDIUM)
|
||||
.size(P1_SIZE)
|
||||
}
|
||||
|
||||
pub fn p1_regular<'a>(
|
||||
content: impl Into<Cow<'a, str>>,
|
||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
||||
pub fn p1_regular<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
.font(font::REGULAR)
|
||||
.size(P1_SIZE)
|
||||
}
|
||||
|
||||
pub fn p2_medium<'a>(
|
||||
content: impl Into<Cow<'a, str>>,
|
||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
||||
pub fn p2_medium<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
.font(font::MEDIUM)
|
||||
.size(P2_SIZE)
|
||||
}
|
||||
|
||||
pub fn p2_regular<'a>(
|
||||
content: impl Into<Cow<'a, str>>,
|
||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
||||
pub fn p2_regular<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
.font(font::REGULAR)
|
||||
.size(P2_SIZE)
|
||||
}
|
||||
|
||||
pub fn caption<'a>(
|
||||
content: impl Into<Cow<'a, str>>,
|
||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
||||
pub fn caption<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
.font(font::REGULAR)
|
||||
.size(CAPTION_SIZE)
|
||||
}
|
||||
|
||||
pub fn text<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
||||
pub fn text<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
p1_regular(content)
|
||||
}
|
||||
|
||||
@ -125,7 +105,7 @@ pub trait Text {
|
||||
fn small(self) -> Self;
|
||||
}
|
||||
|
||||
impl Text for iced::widget::Text<'_, iced::Renderer<Theme>> {
|
||||
impl Text for iced::widget::Text<'_, Theme> {
|
||||
fn bold(self) -> Self {
|
||||
self.font(font::BOLD)
|
||||
}
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
use std::time::Instant;
|
||||
|
||||
use super::theme::Theme;
|
||||
|
||||
use iced::advanced::widget::{Operation, Tree};
|
||||
use iced::advanced::{layout, mouse, overlay, renderer};
|
||||
use iced::advanced::{Clipboard, Layout, Shell, Widget};
|
||||
@ -13,18 +11,18 @@ pub trait Toast {
|
||||
fn body(&self) -> &str;
|
||||
}
|
||||
|
||||
pub struct Manager<'a, Message, Renderer> {
|
||||
content: Element<'a, Message, Renderer>,
|
||||
toasts: Vec<Element<'a, Message, Renderer>>,
|
||||
pub struct Manager<'a, Message, Theme, Renderer> {
|
||||
content: Element<'a, Message, Theme, Renderer>,
|
||||
toasts: Vec<Element<'a, Message, Theme, Renderer>>,
|
||||
}
|
||||
|
||||
impl<'a, Message> Manager<'a, Message, iced::Renderer<Theme>>
|
||||
impl<'a, Message, Theme> Manager<'a, Message, Theme, iced::Renderer>
|
||||
where
|
||||
Message: 'a + Clone,
|
||||
{
|
||||
pub fn new(
|
||||
content: impl Into<Element<'a, Message, iced::Renderer<Theme>>>,
|
||||
toasts: Vec<Element<'a, Message, iced::Renderer<Theme>>>,
|
||||
content: impl Into<Element<'a, Message, Theme, iced::Renderer>>,
|
||||
toasts: Vec<Element<'a, Message, Theme, iced::Renderer>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
content: content.into(),
|
||||
@ -33,20 +31,24 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Message, Renderer> Widget<Message, Renderer> for Manager<'a, Message, Renderer>
|
||||
impl<'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer>
|
||||
for Manager<'a, Message, Theme, Renderer>
|
||||
where
|
||||
Renderer: iced::advanced::Renderer,
|
||||
{
|
||||
fn width(&self) -> Length {
|
||||
self.content.as_widget().width()
|
||||
fn size(&self) -> Size<Length> {
|
||||
self.content.as_widget().size()
|
||||
}
|
||||
|
||||
fn height(&self) -> Length {
|
||||
self.content.as_widget().height()
|
||||
}
|
||||
|
||||
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> layout::Node {
|
||||
self.content.as_widget().layout(renderer, limits)
|
||||
fn layout(
|
||||
&self,
|
||||
tree: &mut Tree,
|
||||
renderer: &Renderer,
|
||||
limits: &layout::Limits,
|
||||
) -> layout::Node {
|
||||
self.content
|
||||
.as_widget()
|
||||
.layout(&mut tree.children[0], renderer, limits)
|
||||
}
|
||||
|
||||
fn tag(&self) -> iced::advanced::widget::tree::Tag {
|
||||
@ -130,7 +132,7 @@ where
|
||||
&self,
|
||||
state: &Tree,
|
||||
renderer: &mut Renderer,
|
||||
theme: &<Renderer as iced::advanced::Renderer>::Theme,
|
||||
theme: &Theme,
|
||||
style: &renderer::Style,
|
||||
layout: Layout<'_>,
|
||||
cursor_position: iced::mouse::Cursor,
|
||||
@ -169,25 +171,26 @@ where
|
||||
state: &'b mut Tree,
|
||||
layout: Layout<'_>,
|
||||
renderer: &Renderer,
|
||||
) -> Option<overlay::Element<'b, Message, Renderer>> {
|
||||
translation: Vector,
|
||||
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
|
||||
let instants = state.state.downcast_mut::<Vec<Option<Instant>>>();
|
||||
|
||||
let (content_state, toasts_state) = state.children.split_at_mut(1);
|
||||
|
||||
let content = self
|
||||
.content
|
||||
.as_widget_mut()
|
||||
.overlay(&mut content_state[0], layout, renderer);
|
||||
let content = self.content.as_widget_mut().overlay(
|
||||
&mut content_state[0],
|
||||
layout,
|
||||
renderer,
|
||||
translation,
|
||||
);
|
||||
|
||||
let toasts = (!self.toasts.is_empty()).then(|| {
|
||||
overlay::Element::new(
|
||||
layout.bounds().position(),
|
||||
Box::new(Overlay {
|
||||
toasts: &mut self.toasts,
|
||||
state: toasts_state,
|
||||
instants,
|
||||
}),
|
||||
)
|
||||
overlay::Element::new(Box::new(Overlay {
|
||||
position: layout.bounds().position() + translation,
|
||||
toasts: &mut self.toasts,
|
||||
state: toasts_state,
|
||||
instants,
|
||||
}))
|
||||
});
|
||||
let overlays = content.into_iter().chain(toasts).collect::<Vec<_>>();
|
||||
|
||||
@ -195,18 +198,19 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
struct Overlay<'a, 'b, Message, Renderer> {
|
||||
toasts: &'b mut [Element<'a, Message, Renderer>],
|
||||
struct Overlay<'a, 'b, Message, Theme, Renderer> {
|
||||
position: Point,
|
||||
toasts: &'b mut [Element<'a, Message, Theme, Renderer>],
|
||||
state: &'b mut [Tree],
|
||||
instants: &'b mut [Option<Instant>],
|
||||
}
|
||||
|
||||
impl<'a, 'b, Message, Renderer> overlay::Overlay<Message, Renderer>
|
||||
for Overlay<'a, 'b, Message, Renderer>
|
||||
impl<'a, 'b, Message, Theme, Renderer> overlay::Overlay<Message, Theme, Renderer>
|
||||
for Overlay<'a, 'b, Message, Theme, Renderer>
|
||||
where
|
||||
Renderer: iced::advanced::Renderer,
|
||||
{
|
||||
fn layout(&self, renderer: &Renderer, bounds: Size, position: Point) -> layout::Node {
|
||||
fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
|
||||
let limits = layout::Limits::new(Size::ZERO, bounds)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill);
|
||||
@ -215,12 +219,15 @@ where
|
||||
layout::flex::Axis::Vertical,
|
||||
renderer,
|
||||
&limits,
|
||||
Length::Fill,
|
||||
Length::Fill,
|
||||
10.into(),
|
||||
10.0,
|
||||
Alignment::End,
|
||||
self.toasts,
|
||||
self.state,
|
||||
)
|
||||
.translate(Vector::new(position.x, position.y))
|
||||
.translate(Vector::new(self.position.x, self.position.y))
|
||||
}
|
||||
|
||||
fn on_event(
|
||||
@ -267,7 +274,7 @@ where
|
||||
fn draw(
|
||||
&self,
|
||||
renderer: &mut Renderer,
|
||||
theme: &<Renderer as iced::advanced::Renderer>::Theme,
|
||||
theme: &Theme,
|
||||
style: &renderer::Style,
|
||||
layout: Layout<'_>,
|
||||
cursor_position: iced::mouse::Cursor,
|
||||
@ -342,12 +349,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Message, Renderer> From<Manager<'a, Message, Renderer>> for Element<'a, Message, Renderer>
|
||||
impl<'a, Message, Theme, Renderer> From<Manager<'a, Message, Theme, Renderer>>
|
||||
for Element<'a, Message, Theme, Renderer>
|
||||
where
|
||||
Renderer: 'a + iced::advanced::Renderer,
|
||||
Message: 'a,
|
||||
Theme: 'a,
|
||||
{
|
||||
fn from(manager: Manager<'a, Message, Renderer>) -> Self {
|
||||
fn from(manager: Manager<'a, Message, Theme, Renderer>) -> Self {
|
||||
Element::new(manager)
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,14 +6,14 @@ use iced::{
|
||||
pub const BOLD: Font = Font {
|
||||
family: Family::Name("IBM Plex Sans"),
|
||||
weight: Weight::Bold,
|
||||
monospaced: false,
|
||||
style: iced::font::Style::Normal,
|
||||
stretch: Stretch::Normal,
|
||||
};
|
||||
|
||||
pub const MEDIUM: Font = Font {
|
||||
family: Family::Name("IBM Plex Sans"),
|
||||
weight: Weight::Medium,
|
||||
monospaced: false,
|
||||
style: iced::font::Style::Normal,
|
||||
stretch: Stretch::Normal,
|
||||
};
|
||||
|
||||
|
||||
@ -4,22 +4,24 @@ pub mod font;
|
||||
pub mod icon;
|
||||
pub mod image;
|
||||
pub mod theme;
|
||||
pub mod util;
|
||||
|
||||
pub mod widget {
|
||||
#![allow(dead_code)]
|
||||
use crate::theme::Theme;
|
||||
|
||||
pub type Renderer = iced::Renderer<Theme>;
|
||||
pub type Element<'a, Message> = iced::Element<'a, Message, Renderer>;
|
||||
pub type Container<'a, Message> = iced::widget::Container<'a, Message, Renderer>;
|
||||
pub type Column<'a, Message> = iced::widget::Column<'a, Message, Renderer>;
|
||||
pub type Row<'a, Message> = iced::widget::Row<'a, Message, Renderer>;
|
||||
pub type Button<'a, Message> = iced::widget::Button<'a, Message, Renderer>;
|
||||
pub type Text<'a> = iced::widget::Text<'a, Renderer>;
|
||||
pub type Tooltip<'a> = iced::widget::Tooltip<'a, Renderer>;
|
||||
pub type ProgressBar = iced::widget::ProgressBar<Renderer>;
|
||||
pub type PickList<'a, Message> = iced::widget::PickList<'a, Message, Renderer>;
|
||||
pub type Scrollable<'a, Message> = iced::widget::Scrollable<'a, Message, Renderer>;
|
||||
pub type Svg = iced::widget::Svg<Renderer>;
|
||||
pub type Renderer = iced::Renderer;
|
||||
pub type Element<'a, Message> = iced::Element<'a, Message, Theme, Renderer>;
|
||||
pub type Container<'a, Message> = iced::widget::Container<'a, Message, Theme, Renderer>;
|
||||
pub type Column<'a, Message> = iced::widget::Column<'a, Message, Theme, Renderer>;
|
||||
pub type Row<'a, Message> = iced::widget::Row<'a, Message, Theme, Renderer>;
|
||||
pub type Button<'a, Message> = iced::widget::Button<'a, Message, Theme, Renderer>;
|
||||
pub type CheckBox<'a, Message> = iced::widget::Checkbox<'a, Message, Theme, Renderer>;
|
||||
pub type Text<'a> = iced::widget::Text<'a, Theme, Renderer>;
|
||||
pub type TextInput<'a, Message> = iced::widget::TextInput<'a, Message, Theme, Renderer>;
|
||||
pub type Tooltip<'a> = iced::widget::Tooltip<'a, Theme, Renderer>;
|
||||
pub type ProgressBar = iced::widget::ProgressBar<Theme>;
|
||||
pub type PickList<'a, T, L, V, Message> =
|
||||
iced::widget::PickList<'a, T, L, V, Message, Theme, Renderer>;
|
||||
pub type Scrollable<'a, Message> = iced::widget::Scrollable<'a, Message, Theme, Renderer>;
|
||||
pub type Svg = iced::widget::Svg<Theme>;
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
use iced::{
|
||||
application,
|
||||
widget::{
|
||||
button, checkbox, container, pick_list, progress_bar, radio, scrollable, slider, svg, text,
|
||||
text_input,
|
||||
button, checkbox, container, pick_list, progress_bar, qr_code, radio, scrollable, slider,
|
||||
svg, text, text_input,
|
||||
},
|
||||
};
|
||||
|
||||
@ -44,9 +44,11 @@ impl iced::overlay::menu::StyleSheet for Theme {
|
||||
iced::overlay::menu::Appearance {
|
||||
text_color: color::GREY_2,
|
||||
background: color::GREY_6.into(),
|
||||
border_width: 0.0,
|
||||
border_radius: 25.0.into(),
|
||||
border_color: color::GREY_2,
|
||||
border: iced::Border {
|
||||
color: color::GREY_2,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
selected_text_color: color::LIGHT_BLACK,
|
||||
selected_background: color::GREEN.into(),
|
||||
}
|
||||
@ -116,8 +118,11 @@ impl container::StyleSheet for Theme {
|
||||
},
|
||||
Container::Border => container::Appearance {
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border_width: 1.0,
|
||||
border_color: color::LIGHT_BLACK,
|
||||
border: iced::Border {
|
||||
color: color::LIGHT_BLACK,
|
||||
width: 1.0,
|
||||
radius: 0.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Container::Card(c) => c.appearance(self),
|
||||
@ -130,7 +135,11 @@ impl container::StyleSheet for Theme {
|
||||
},
|
||||
Container::QrCode => container::Appearance {
|
||||
background: Some(color::WHITE.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
},
|
||||
@ -149,8 +158,11 @@ impl container::StyleSheet for Theme {
|
||||
},
|
||||
Container::Border => container::Appearance {
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border_width: 1.0,
|
||||
border_color: color::GREY_3,
|
||||
border: iced::Border {
|
||||
color: color::GREY_3,
|
||||
width: 1.0,
|
||||
radius: 0.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Container::Card(c) => c.appearance(self),
|
||||
@ -163,7 +175,11 @@ impl container::StyleSheet for Theme {
|
||||
},
|
||||
Container::QrCode => container::Appearance {
|
||||
background: Some(color::WHITE.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
},
|
||||
@ -203,32 +219,44 @@ impl Notification {
|
||||
Self::Pending => container::Appearance {
|
||||
background: Some(iced::Background::Color(color::GREEN)),
|
||||
text_color: color::LIGHT_BLACK.into(),
|
||||
border_width: 1.0,
|
||||
border_color: color::GREEN,
|
||||
border_radius: 25.0.into(),
|
||||
border: iced::Border {
|
||||
color: color::GREEN,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Self::Error => container::Appearance {
|
||||
background: Some(iced::Background::Color(color::ORANGE)),
|
||||
text_color: color::LIGHT_BLACK.into(),
|
||||
border_width: 1.0,
|
||||
border_color: color::ORANGE,
|
||||
border_radius: 25.0.into(),
|
||||
border: iced::Border {
|
||||
color: color::ORANGE,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
},
|
||||
Theme::Dark => match self {
|
||||
Self::Pending => container::Appearance {
|
||||
background: Some(iced::Background::Color(color::GREEN)),
|
||||
text_color: color::LIGHT_BLACK.into(),
|
||||
border_width: 1.0,
|
||||
border_color: color::GREEN,
|
||||
border_radius: 25.0.into(),
|
||||
border: iced::Border {
|
||||
color: color::GREEN,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Self::Error => container::Appearance {
|
||||
background: Some(iced::Background::Color(color::ORANGE)),
|
||||
text_color: color::LIGHT_BLACK.into(),
|
||||
border_width: 1.0,
|
||||
border_color: color::ORANGE,
|
||||
border_radius: 25.0.into(),
|
||||
border: iced::Border {
|
||||
color: color::ORANGE,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -255,23 +283,31 @@ impl Card {
|
||||
},
|
||||
Card::Border => container::Appearance {
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border_radius: 10.0.into(),
|
||||
border_color: color::GREY_2,
|
||||
border_width: 1.0,
|
||||
border: iced::Border {
|
||||
color: color::GREY_2,
|
||||
width: 1.0,
|
||||
radius: 10.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Card::Invalid => container::Appearance {
|
||||
background: Some(color::GREY_2.into()),
|
||||
text_color: color::BLACK.into(),
|
||||
border_width: 1.0,
|
||||
border_color: color::RED,
|
||||
border: iced::Border {
|
||||
color: color::RED,
|
||||
width: 1.0,
|
||||
radius: 0.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Card::Error => container::Appearance {
|
||||
background: Some(color::GREY_2.into()),
|
||||
text_color: color::RED.into(),
|
||||
border_width: 1.0,
|
||||
border_color: color::RED,
|
||||
border: iced::Border {
|
||||
color: color::RED,
|
||||
width: 1.0,
|
||||
radius: 0.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Card::Warning => container::Appearance {
|
||||
@ -283,28 +319,40 @@ impl Card {
|
||||
Theme::Dark => match self {
|
||||
Card::Simple => container::Appearance {
|
||||
background: Some(color::GREY_6.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Card::Border => container::Appearance {
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border_color: color::GREY_5,
|
||||
border_width: 1.0,
|
||||
border: iced::Border {
|
||||
color: color::GREY_5,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Card::Invalid => container::Appearance {
|
||||
background: Some(color::LIGHT_BLACK.into()),
|
||||
text_color: color::RED.into(),
|
||||
border_width: 1.0,
|
||||
border_radius: 25.0.into(),
|
||||
border_color: color::RED,
|
||||
border: iced::Border {
|
||||
color: color::RED,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Card::Error => container::Appearance {
|
||||
background: Some(color::LIGHT_BLACK.into()),
|
||||
text_color: color::RED.into(),
|
||||
border_width: 1.0,
|
||||
border_color: color::RED,
|
||||
border: iced::Border {
|
||||
color: color::RED,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Card::Warning => container::Appearance {
|
||||
@ -328,12 +376,20 @@ impl Badge {
|
||||
fn appearance(&self, _theme: &Theme) -> iced::widget::container::Appearance {
|
||||
match self {
|
||||
Self::Standard => container::Appearance {
|
||||
border_radius: 40.0.into(),
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 40.0.into(),
|
||||
},
|
||||
background: Some(color::GREY_4.into()),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Self::Bitcoin => container::Appearance {
|
||||
border_radius: 40.0.into(),
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 40.0.into(),
|
||||
},
|
||||
background: Some(color::ORANGE.into()),
|
||||
text_color: iced::Color::WHITE.into(),
|
||||
..container::Appearance::default()
|
||||
@ -356,29 +412,43 @@ impl Pill {
|
||||
match self {
|
||||
Self::Primary => container::Appearance {
|
||||
background: Some(color::GREEN.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
text_color: color::LIGHT_BLACK.into(),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Self::Success => container::Appearance {
|
||||
background: Some(color::GREEN.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
text_color: color::LIGHT_BLACK.into(),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Self::Simple => container::Appearance {
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border_width: 1.0,
|
||||
border_color: color::GREY_3,
|
||||
border: iced::Border {
|
||||
color: color::GREY_3,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
text_color: color::GREY_3.into(),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Self::Warning => container::Appearance {
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border_width: 1.0,
|
||||
border_color: color::RED,
|
||||
border: iced::Border {
|
||||
color: color::RED,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
text_color: color::RED.into(),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -415,24 +485,32 @@ pub struct Scrollable {}
|
||||
impl scrollable::StyleSheet for Theme {
|
||||
type Style = Scrollable;
|
||||
|
||||
fn active(&self, _style: &Self::Style) -> scrollable::Scrollbar {
|
||||
scrollable::Scrollbar {
|
||||
background: None,
|
||||
border_width: 0.0,
|
||||
border_color: color::GREY_7,
|
||||
border_radius: 10.0.into(),
|
||||
scroller: scrollable::Scroller {
|
||||
color: color::GREY_7,
|
||||
border_radius: 10.0.into(),
|
||||
border_width: 0.0,
|
||||
border_color: iced::Color::TRANSPARENT,
|
||||
fn active(&self, _style: &Self::Style) -> scrollable::Appearance {
|
||||
scrollable::Appearance {
|
||||
gap: None,
|
||||
container: container::Appearance::default(),
|
||||
scrollbar: scrollable::Scrollbar {
|
||||
background: None,
|
||||
border: iced::Border {
|
||||
color: color::GREY_3,
|
||||
width: 0.0,
|
||||
radius: 10.0.into(),
|
||||
},
|
||||
scroller: scrollable::Scroller {
|
||||
color: color::GREY_7,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 10.0.into(),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn hovered(&self, style: &Self::Style, _is_hovered: bool) -> scrollable::Scrollbar {
|
||||
fn hovered(&self, style: &Self::Style, _is_hovered: bool) -> scrollable::Appearance {
|
||||
let active = self.active(style);
|
||||
scrollable::Scrollbar { ..active }
|
||||
scrollable::Appearance { ..active }
|
||||
}
|
||||
}
|
||||
|
||||
@ -452,27 +530,33 @@ impl pick_list::StyleSheet for Theme {
|
||||
placeholder_color: color::GREY_6,
|
||||
handle_color: color::GREY_6,
|
||||
background: color::GREEN.into(),
|
||||
border_width: 1.0,
|
||||
border_color: color::GREY_7,
|
||||
border_radius: 25.0.into(),
|
||||
border: iced::Border {
|
||||
color: color::GREY_7,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
text_color: iced::Color::BLACK,
|
||||
},
|
||||
PickList::Invalid => pick_list::Appearance {
|
||||
placeholder_color: color::GREY_6,
|
||||
handle_color: color::GREY_6,
|
||||
background: color::GREY_6.into(),
|
||||
border_width: 1.0,
|
||||
border_color: color::RED,
|
||||
border_radius: 25.0.into(),
|
||||
border: iced::Border {
|
||||
color: color::RED,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
text_color: color::RED,
|
||||
},
|
||||
PickList::Secondary => pick_list::Appearance {
|
||||
placeholder_color: color::GREY_3,
|
||||
handle_color: color::GREY_3,
|
||||
background: color::TRANSPARENT.into(),
|
||||
border_width: 1.0,
|
||||
border_color: color::GREY_3,
|
||||
border_radius: 25.0.into(),
|
||||
border: iced::Border {
|
||||
color: color::GREY_3,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
text_color: color::GREY_2,
|
||||
},
|
||||
}
|
||||
@ -493,20 +577,24 @@ impl checkbox::StyleSheet for Theme {
|
||||
if is_selected {
|
||||
checkbox::Appearance {
|
||||
background: color::GREEN.into(),
|
||||
border_width: 0.0,
|
||||
border_color: iced::Color::TRANSPARENT,
|
||||
icon_color: color::GREY_4,
|
||||
text_color: None,
|
||||
border_radius: 4.0.into(),
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 1.0,
|
||||
radius: 4.0.into(),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
checkbox::Appearance {
|
||||
background: color::GREY_4.into(),
|
||||
border_width: 0.0,
|
||||
border_color: iced::Color::TRANSPARENT,
|
||||
icon_color: color::GREEN,
|
||||
text_color: None,
|
||||
border_radius: 4.0.into(),
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 4.0.into(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -539,63 +627,84 @@ impl button::StyleSheet for Theme {
|
||||
Button::Primary => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border_width: 1.0,
|
||||
border_color: color::GREY_7,
|
||||
text_color: color::GREY_2,
|
||||
border: iced::Border {
|
||||
color: color::GREY_7,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
Button::Secondary | Button::SecondaryDestructive | Button::Border => {
|
||||
button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border_width: 1.0,
|
||||
border_color: color::GREY_7,
|
||||
text_color: color::GREY_2,
|
||||
border: iced::Border {
|
||||
color: color::GREY_7,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
}
|
||||
}
|
||||
Button::Destructive => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border_width: 1.0,
|
||||
border_color: color::RED,
|
||||
text_color: color::RED,
|
||||
border: iced::Border {
|
||||
color: color::RED,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
Button::Transparent => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border_width: 0.0,
|
||||
border_color: iced::Color::TRANSPARENT,
|
||||
text_color: color::GREY_2,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
Button::TransparentBorder => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border_width: 0.0,
|
||||
border_color: iced::Color::TRANSPARENT,
|
||||
text_color: color::WHITE,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
Button::Menu(active) => {
|
||||
if *active {
|
||||
button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(color::LIGHT_BLACK.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border_width: 0.0,
|
||||
border_color: iced::Color::TRANSPARENT,
|
||||
text_color: color::WHITE,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
}
|
||||
} else {
|
||||
button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border_width: 0.0,
|
||||
border_color: iced::Color::TRANSPARENT,
|
||||
text_color: color::WHITE,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -610,50 +719,68 @@ impl button::StyleSheet for Theme {
|
||||
Button::Primary => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(color::GREEN.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border_width: 0.0,
|
||||
border_color: iced::Color::TRANSPARENT,
|
||||
text_color: color::LIGHT_BLACK,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
Button::Secondary => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(color::GREEN.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border_width: 0.0,
|
||||
border_color: iced::Color::TRANSPARENT,
|
||||
text_color: color::LIGHT_BLACK,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
Button::Destructive | Button::SecondaryDestructive => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(color::RED.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border_width: 0.0,
|
||||
border_color: iced::Color::TRANSPARENT,
|
||||
text_color: color::LIGHT_BLACK,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
Button::Transparent => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border_width: 0.0,
|
||||
border_color: iced::Color::TRANSPARENT,
|
||||
text_color: color::GREY_2,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
Button::TransparentBorder | Button::Border => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border_width: 1.0,
|
||||
border_color: color::GREEN,
|
||||
text_color: color::WHITE,
|
||||
border: iced::Border {
|
||||
color: color::GREEN,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
Button::Menu(_) => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(color::LIGHT_BLACK.into()),
|
||||
border_radius: 25.0.into(),
|
||||
border_width: 0.0,
|
||||
border_color: iced::Color::TRANSPARENT,
|
||||
text_color: color::WHITE,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -674,16 +801,20 @@ impl text_input::StyleSheet for Theme {
|
||||
Form::Simple => text_input::Appearance {
|
||||
icon_color: color::GREY_7,
|
||||
background: iced::Background::Color(iced::Color::TRANSPARENT),
|
||||
border_radius: 25.0.into(),
|
||||
border_width: 1.0,
|
||||
border_color: color::GREY_7,
|
||||
border: iced::Border {
|
||||
color: color::GREY_7,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
},
|
||||
Form::Invalid => text_input::Appearance {
|
||||
icon_color: color::GREY_7,
|
||||
background: iced::Background::Color(iced::Color::TRANSPARENT),
|
||||
border_radius: 25.0.into(),
|
||||
border_width: 1.0,
|
||||
border_color: color::RED,
|
||||
border: iced::Border {
|
||||
color: color::RED,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -813,3 +944,13 @@ impl svg::StyleSheet for Theme {
|
||||
svg::Appearance::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl qr_code::StyleSheet for Theme {
|
||||
type Style = ();
|
||||
fn appearance(&self, _style: &Self::Style) -> qr_code::Appearance {
|
||||
qr_code::Appearance {
|
||||
cell: color::BLACK,
|
||||
background: color::WHITE,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
/// from hecjr idea on Discord
|
||||
use crate::widget::*;
|
||||
|
||||
pub trait Collection<'a, Message>: Sized {
|
||||
fn push(self, element: impl Into<Element<'a, Message>>) -> Self;
|
||||
|
||||
fn push_maybe(self, element: Option<impl Into<Element<'a, Message>>>) -> Self {
|
||||
match element {
|
||||
Some(element) => self.push(element),
|
||||
None => self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Message> Collection<'a, Message> for Column<'a, Message> {
|
||||
fn push(self, element: impl Into<Element<'a, Message>>) -> Self {
|
||||
Self::push(self, element)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Message> Collection<'a, Message> for Row<'a, Message> {
|
||||
fn push(self, element: impl Into<Element<'a, Message>>) -> Self {
|
||||
Self::push(self, element)
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user