Merge #597: Iced 0.12
52e32b6a69c751f68e461f4e858170e4ade6619d Update iced patch branch in guix build (edouardparis) acea67bc35738843144204539833b5767f6c936e Remove transaparency from PickList for tiny-skia (edouardparis) 7801d8cb1f11511cd8e11a556add9e8c62656780 Change descriptor view in installer behind scrollable (edouardparis) c39d544566a76b126fdc4613197d5b937f72fad3 Use wgpu with tiny-skia fallback (edouardparis) 4920291d04302a5d73196b1d8eeb6ce05d7753a2 fix ui button and badge width (edouardparis) de371116371c61c5cd2e3bd0d44cdc849f14c5cf Change text size (edouardparis) a24d9416f62712fc5a5c6fe5d8fa619d06f4006a gui: bump msrv 1.70 (edouardparis) fdcc30236721f2cf7bdffe788127a35ca376d453 gui: iced-0.12 (edouardparis) 64a626d7e871fd82db27b8ddf773231fe1361755 gui: bump iced 0.10 (edouard) Pull request description: This PR does the migration from iced 0.9 to iced 0.12. This new iced version has impact on the fonts size. I reverted the size according to the original UX figma file. The new backend renderer is the `wgpu` with `tiny-skia` as a fallback. `wgpu` is the first class citizen of the iced renderers, it supports everything. The `tiny-skia` has some layout problems and does not support some features that is the reason why this PR introduces tiny change in the theme or long string display (ad69711c4a,88fd0f18e2). In order to keep the MSRV as low as possible, a custom patch of the crates `iced_winit`,`iced_style`, `iced_futures` is added to the Cargo.toml ACKs for top commit: darosior: ACK 52e32b6a69c751f68e461f4e858170e4ade6619d -- it's been tested a bunch, in particular by Kevin. Tree-SHA512: 6afda45c227f0dd864c59aee100895af3f0d511c5a425f4d032c5891f900f2e438de778adaa82c5213dba768e608bf7610b6c78d4cb10a2d7ae59f5b132938f4
This commit is contained in:
commit
b602640d16
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@ -68,7 +68,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
toolchain:
|
toolchain:
|
||||||
- 1.65.0
|
- 1.70.0
|
||||||
- nightly
|
- nightly
|
||||||
os:
|
os:
|
||||||
- ubuntu-latest
|
- ubuntu-latest
|
||||||
|
|||||||
@ -20,7 +20,7 @@ replace-with = "vendored_sources"
|
|||||||
|
|
||||||
[source."https://github.com/edouardparis/iced"]
|
[source."https://github.com/edouardparis/iced"]
|
||||||
git = "https://github.com/edouardparis/iced"
|
git = "https://github.com/edouardparis/iced"
|
||||||
branch = "fix-futures-recipe"
|
branch = "patch-0.12.3"
|
||||||
replace-with = "vendored_sources"
|
replace-with = "vendored_sources"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|||||||
2284
gui/Cargo.lock
generated
2284
gui/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -21,9 +21,8 @@ liana_ui = { path = "ui" }
|
|||||||
backtrace = "0.3"
|
backtrace = "0.3"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
|
|
||||||
iced = { version = "0.9", default-features= false, features = ["tokio", "glow", "svg", "qr_code", "image"] }
|
iced = { version = "0.12.1", default-features = false, features = ["tokio", "svg", "qr_code", "image", "lazy", "wgpu"] }
|
||||||
iced_native = "0.10"
|
iced_runtime = "0.12.1"
|
||||||
iced_lazy = { version = "0.6"}
|
|
||||||
|
|
||||||
tokio = {version = "1.21.0", features = ["signal"]}
|
tokio = {version = "1.21.0", features = ["signal"]}
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
@ -48,8 +47,11 @@ bitcoin_hashes = "0.12"
|
|||||||
reqwest = { version = "0.11", default-features=false, features = ["rustls-tls"] }
|
reqwest = { version = "0.11", default-features=false, features = ["rustls-tls"] }
|
||||||
rust-ini = "0.19.0"
|
rust-ini = "0.19.0"
|
||||||
|
|
||||||
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
iced_futures = { git = "https://github.com/edouardparis/iced", branch = "fix-futures-recipe"}
|
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]
|
[target.'cfg(windows)'.dependencies]
|
||||||
zip = { version = "0.6", default-features=false, features = ["bzip2", "deflate"] }
|
zip = { version = "0.6", default-features=false, features = ["bzip2", "deflate"] }
|
||||||
|
|||||||
@ -9,7 +9,7 @@ let
|
|||||||
pkgs = import <nixpkgs> {};
|
pkgs = import <nixpkgs> {};
|
||||||
in
|
in
|
||||||
pkgs.mkShell rec {
|
pkgs.mkShell rec {
|
||||||
buildInputs = [
|
buildInputs = with pkgs; [
|
||||||
pkgs.expat
|
pkgs.expat
|
||||||
pkgs.fontconfig
|
pkgs.fontconfig
|
||||||
pkgs.freetype
|
pkgs.freetype
|
||||||
@ -17,6 +17,8 @@ pkgs.mkShell rec {
|
|||||||
pkgs.libGL
|
pkgs.libGL
|
||||||
pkgs.pkgconfig
|
pkgs.pkgconfig
|
||||||
pkgs.udev
|
pkgs.udev
|
||||||
|
pkgs.wayland
|
||||||
|
pkgs.libxkbcommon
|
||||||
pkgs.xorg.libX11
|
pkgs.xorg.libX11
|
||||||
pkgs.xorg.libXcursor
|
pkgs.xorg.libXcursor
|
||||||
pkgs.xorg.libXi
|
pkgs.xorg.libXi
|
||||||
|
|||||||
@ -302,13 +302,13 @@ impl VerifyAddressModal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct ShowQrCodeModal {
|
pub struct ShowQrCodeModal {
|
||||||
qr_code: qr_code::State,
|
qr_code: qr_code::Data,
|
||||||
address: String,
|
address: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ShowQrCodeModal {
|
impl ShowQrCodeModal {
|
||||||
pub fn new(address: &Address, index: ChildNumber) -> Option<Self> {
|
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()
|
.ok()
|
||||||
.map(|qr_code| Self {
|
.map(|qr_code| Self {
|
||||||
qr_code,
|
qr_code,
|
||||||
|
|||||||
@ -6,7 +6,6 @@ use liana_ui::{
|
|||||||
color,
|
color,
|
||||||
component::{amount::*, badge, button, form, text::*},
|
component::{amount::*, badge, button, form, text::*},
|
||||||
icon, theme,
|
icon, theme,
|
||||||
util::Collection,
|
|
||||||
widget::*,
|
widget::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,6 @@ use liana_ui::{
|
|||||||
color,
|
color,
|
||||||
component::{amount::*, button, card, event, form, text::*},
|
component::{amount::*, button, card, event, form, text::*},
|
||||||
icon, theme,
|
icon, theme,
|
||||||
util::Collection,
|
|
||||||
widget::*,
|
widget::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,6 @@ use liana_ui::{
|
|||||||
},
|
},
|
||||||
image::*,
|
image::*,
|
||||||
theme,
|
theme,
|
||||||
util::Collection,
|
|
||||||
widget::*,
|
widget::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,6 @@ use liana_ui::{
|
|||||||
text::{self, *},
|
text::{self, *},
|
||||||
},
|
},
|
||||||
icon, theme,
|
icon, theme,
|
||||||
util::Collection,
|
|
||||||
widget::*,
|
widget::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -426,7 +425,7 @@ pub fn signatures<'a>(
|
|||||||
Container::new(text(alias))
|
Container::new(text(alias))
|
||||||
.padding(10)
|
.padding(10)
|
||||||
.style(theme::Container::Pill(theme::Pill::Simple)),
|
.style(theme::Container::Pill(theme::Pill::Simple)),
|
||||||
value.to_string(),
|
liana_ui::widget::Text::new(value.to_string()),
|
||||||
tooltip::Position::Bottom,
|
tooltip::Position::Bottom,
|
||||||
)
|
)
|
||||||
.style(theme::Container::Card(theme::Card::Simple)),
|
.style(theme::Container::Card(theme::Card::Simple)),
|
||||||
@ -439,7 +438,9 @@ pub fn signatures<'a>(
|
|||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
.horizontal_scroll(scrollable::Properties::new().width(2).scroller_width(2)),
|
.direction(scrollable::Direction::Horizontal(
|
||||||
|
scrollable::Properties::new().width(2).scroller_width(2),
|
||||||
|
)),
|
||||||
)
|
)
|
||||||
.padding(15)
|
.padding(15)
|
||||||
} else {
|
} else {
|
||||||
@ -520,7 +521,7 @@ fn container_from_fg(
|
|||||||
Container::new(text(alias))
|
Container::new(text(alias))
|
||||||
.padding(10)
|
.padding(10)
|
||||||
.style(theme::Container::Pill(theme::Pill::Simple)),
|
.style(theme::Container::Pill(theme::Pill::Simple)),
|
||||||
fg.to_string(),
|
liana_ui::widget::Text::new(fg.to_string()),
|
||||||
tooltip::Position::Bottom,
|
tooltip::Position::Bottom,
|
||||||
)
|
)
|
||||||
.style(theme::Container::Card(theme::Card::Simple)),
|
.style(theme::Container::Card(theme::Card::Simple)),
|
||||||
@ -594,7 +595,9 @@ pub fn path_view<'a>(
|
|||||||
)
|
)
|
||||||
.push(row_signed),
|
.push(row_signed),
|
||||||
)
|
)
|
||||||
.horizontal_scroll(scrollable::Properties::new().width(2).scroller_width(2))
|
.direction(scrollable::Direction::Horizontal(
|
||||||
|
scrollable::Properties::new().width(2).scroller_width(2),
|
||||||
|
))
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,6 @@ use liana_ui::{
|
|||||||
color,
|
color,
|
||||||
component::{amount::*, badge, button, card, form, text::*},
|
component::{amount::*, badge, button, card, form, text::*},
|
||||||
icon, theme,
|
icon, theme,
|
||||||
util::Collection,
|
|
||||||
widget::*,
|
widget::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -3,11 +3,10 @@ use std::collections::{HashMap, HashSet};
|
|||||||
use iced::{
|
use iced::{
|
||||||
widget::{
|
widget::{
|
||||||
qr_code::{self, QRCode},
|
qr_code::{self, QRCode},
|
||||||
scrollable,
|
scrollable, Space,
|
||||||
},
|
},
|
||||||
Alignment, Length,
|
Alignment, Length,
|
||||||
};
|
};
|
||||||
use iced_native::widget::Space;
|
|
||||||
|
|
||||||
use liana::miniscript::bitcoin::{
|
use liana::miniscript::bitcoin::{
|
||||||
self,
|
self,
|
||||||
@ -22,7 +21,6 @@ use liana_ui::{
|
|||||||
text::{self, *},
|
text::{self, *},
|
||||||
},
|
},
|
||||||
icon, theme,
|
icon, theme,
|
||||||
util::Collection,
|
|
||||||
widget::*,
|
widget::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -94,10 +92,11 @@ pub fn receive<'a>(
|
|||||||
Length::Fixed(10.0),
|
Length::Fixed(10.0),
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
.horizontal_scroll(
|
.direction(scrollable::Direction::Horizontal(
|
||||||
scrollable::Properties::new()
|
scrollable::Properties::new()
|
||||||
.scroller_width(5),
|
.width(2)
|
||||||
),
|
.scroller_width(2),
|
||||||
|
)),
|
||||||
)
|
)
|
||||||
.width(Length::Fill),
|
.width(Length::Fill),
|
||||||
)
|
)
|
||||||
@ -216,13 +215,13 @@ pub fn verify_address_modal<'a>(
|
|||||||
.into()
|
.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()
|
Column::new()
|
||||||
.push(
|
.push(
|
||||||
Row::new()
|
Row::new()
|
||||||
.push(Space::with_width(Length::Fill))
|
.push(Space::with_width(Length::Fill))
|
||||||
.push(
|
.push(
|
||||||
Container::new(QRCode::new(qr).cell_size(8))
|
Container::new(QRCode::<liana_ui::theme::Theme>::new(qr).cell_size(8))
|
||||||
.padding(10)
|
.padding(10)
|
||||||
.style(theme::Container::QrCode),
|
.style(theme::Container::QrCode),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -13,7 +13,6 @@ use liana::miniscript::bitcoin::{
|
|||||||
use liana_ui::{
|
use liana_ui::{
|
||||||
component::{amount::*, button, form, text::*},
|
component::{amount::*, button, form, text::*},
|
||||||
icon, theme,
|
icon, theme,
|
||||||
util::*,
|
|
||||||
widget::*,
|
widget::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -144,9 +143,10 @@ pub fn recovery_path_view<'a>(
|
|||||||
selected: bool,
|
selected: bool,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
Row::new()
|
Row::new()
|
||||||
.push(checkbox("", selected, move |_| {
|
.push(
|
||||||
Message::CreateSpend(CreateSpendMessage::SelectPath(index))
|
checkbox("", selected)
|
||||||
}))
|
.on_toggle(move |_| Message::CreateSpend(CreateSpendMessage::SelectPath(index))),
|
||||||
|
)
|
||||||
.push(
|
.push(
|
||||||
Column::new()
|
Column::new()
|
||||||
.push(
|
.push(
|
||||||
@ -170,7 +170,7 @@ pub fn recovery_path_view<'a>(
|
|||||||
Container::new(text(alias))
|
Container::new(text(alias))
|
||||||
.padding(5)
|
.padding(5)
|
||||||
.style(theme::Container::Pill(theme::Pill::Simple)),
|
.style(theme::Container::Pill(theme::Pill::Simple)),
|
||||||
fg.to_string(),
|
liana_ui::widget::Text::new(fg.to_string()),
|
||||||
tooltip::Position::Bottom,
|
tooltip::Position::Bottom,
|
||||||
)
|
)
|
||||||
.style(theme::Container::Card(theme::Card::Simple)),
|
.style(theme::Container::Card(theme::Card::Simple)),
|
||||||
|
|||||||
@ -18,7 +18,6 @@ use liana_ui::{
|
|||||||
color,
|
color,
|
||||||
component::{badge, button, card, form, separation, text::*, tooltip::tooltip},
|
component::{badge, button, card, form, separation, text::*, tooltip::tooltip},
|
||||||
icon, theme,
|
icon, theme,
|
||||||
util::Collection,
|
|
||||||
widget::*,
|
widget::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -633,9 +632,9 @@ pub fn wallet_settings<'a>(
|
|||||||
.push(text(descriptor.to_owned()).small())
|
.push(text(descriptor.to_owned()).small())
|
||||||
.push(Space::with_height(Length::Fixed(5.0))),
|
.push(Space::with_height(Length::Fixed(5.0))),
|
||||||
)
|
)
|
||||||
.horizontal_scroll(
|
.direction(scrollable::Direction::Horizontal(
|
||||||
scrollable::Properties::new().width(5).scroller_width(5),
|
scrollable::Properties::new().width(5).scroller_width(5),
|
||||||
),
|
)),
|
||||||
)
|
)
|
||||||
.push(
|
.push(
|
||||||
Row::new()
|
Row::new()
|
||||||
|
|||||||
@ -15,7 +15,6 @@ use liana_ui::{
|
|||||||
color,
|
color,
|
||||||
component::{amount::*, badge, button, form, text::*},
|
component::{amount::*, badge, button, form, text::*},
|
||||||
icon, theme,
|
icon, theme,
|
||||||
util::Collection,
|
|
||||||
widget::*,
|
widget::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -405,9 +404,8 @@ pub fn recipient_view<'a>(
|
|||||||
None
|
None
|
||||||
})
|
})
|
||||||
.push(tooltip::Tooltip::new(
|
.push(tooltip::Tooltip::new(
|
||||||
checkbox("MAX", is_max_selected, move |_| {
|
checkbox("MAX", is_max_selected)
|
||||||
CreateSpendMessage::SendMaxToRecipient(index)
|
.on_toggle(move |_| CreateSpendMessage::SendMaxToRecipient(index)),
|
||||||
}),
|
|
||||||
// Add spaces at end so that text is padded at screen edge.
|
// Add spaces at end so that text is padded at screen edge.
|
||||||
"Total amount remaining after paying fee and any other recipients ",
|
"Total amount remaining after paying fee and any other recipients ",
|
||||||
tooltip::Position::Bottom,
|
tooltip::Position::Bottom,
|
||||||
@ -431,9 +429,11 @@ fn coin_list_view<'a>(
|
|||||||
Row::new()
|
Row::new()
|
||||||
.push(
|
.push(
|
||||||
Row::new()
|
Row::new()
|
||||||
.push(checkbox("", selected, move |_| {
|
.push(
|
||||||
Message::CreateSpend(CreateSpendMessage::SelectCoin(i))
|
checkbox("", selected).on_toggle(move |_| {
|
||||||
}))
|
Message::CreateSpend(CreateSpendMessage::SelectCoin(i))
|
||||||
|
}),
|
||||||
|
)
|
||||||
.push(
|
.push(
|
||||||
if let Some(label) = coins_labels.get(&coin.outpoint.to_string()) {
|
if let Some(label) = coins_labels.get(&coin.outpoint.to_string()) {
|
||||||
Container::new(p1_regular(label)).width(Length::Fill)
|
Container::new(p1_regular(label)).width(Length::Fill)
|
||||||
|
|||||||
@ -7,7 +7,6 @@ use liana_ui::{
|
|||||||
color,
|
color,
|
||||||
component::{amount::*, badge, button, card, form, text::*},
|
component::{amount::*, badge, button, card, form, text::*},
|
||||||
icon, theme,
|
icon, theme,
|
||||||
util::Collection,
|
|
||||||
widget::*,
|
widget::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1626,7 +1626,7 @@ impl From<BackupDescriptor> for Box<dyn Step> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use iced_native::command::Action;
|
use iced_runtime::command::Action;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
pub struct Sandbox<S: Step> {
|
pub struct Sandbox<S: Step> {
|
||||||
|
|||||||
@ -18,7 +18,6 @@ use liana_ui::{
|
|||||||
tooltip,
|
tooltip,
|
||||||
},
|
},
|
||||||
icon, image, theme,
|
icon, image, theme,
|
||||||
util::Collection,
|
|
||||||
widget::*,
|
widget::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -319,7 +318,9 @@ pub fn define_descriptor<'a>(
|
|||||||
)
|
)
|
||||||
.padding(5),
|
.padding(5),
|
||||||
)
|
)
|
||||||
.horizontal_scroll(Properties::new().width(3).scroller_width(3)),
|
.direction(scrollable::Direction::Horizontal(
|
||||||
|
Properties::new().width(3).scroller_width(3),
|
||||||
|
)),
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
.spacing(10);
|
.spacing(10);
|
||||||
@ -436,7 +437,9 @@ pub fn recovery_path_view(
|
|||||||
)
|
)
|
||||||
.padding(5),
|
.padding(5),
|
||||||
)
|
)
|
||||||
.horizontal_scroll(Properties::new().width(3).scroller_width(3)),
|
.direction(scrollable::Direction::Horizontal(
|
||||||
|
Properties::new().width(3).scroller_width(3),
|
||||||
|
)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -568,9 +571,9 @@ pub fn signer_xpubs(xpubs: &[String]) -> Element<Message> {
|
|||||||
.push(
|
.push(
|
||||||
Container::new(
|
Container::new(
|
||||||
scrollable(Container::new(text(xpub).small()).padding(10))
|
scrollable(Container::new(text(xpub).small()).padding(10))
|
||||||
.horizontal_scroll(
|
.direction(scrollable::Direction::Horizontal(
|
||||||
Properties::new().width(5).scroller_width(5),
|
Properties::new().width(5).scroller_width(5),
|
||||||
),
|
)),
|
||||||
)
|
)
|
||||||
.width(Length::Fill),
|
.width(Length::Fill),
|
||||||
)
|
)
|
||||||
@ -641,9 +644,9 @@ pub fn hardware_wallet_xpubs<'a>(
|
|||||||
.push(
|
.push(
|
||||||
Container::new(
|
Container::new(
|
||||||
scrollable(Container::new(text(xpub).small()).padding(10))
|
scrollable(Container::new(text(xpub).small()).padding(10))
|
||||||
.horizontal_scroll(
|
.direction(scrollable::Direction::Horizontal(
|
||||||
Properties::new().width(5).scroller_width(5),
|
Properties::new().width(5).scroller_width(5),
|
||||||
),
|
)),
|
||||||
)
|
)
|
||||||
.width(Length::Fill),
|
.width(Length::Fill),
|
||||||
)
|
)
|
||||||
@ -716,11 +719,10 @@ pub fn participate_xpub<'a>(
|
|||||||
.push(signer)
|
.push(signer)
|
||||||
.width(Length::Fill),
|
.width(Length::Fill),
|
||||||
)
|
)
|
||||||
.push(checkbox(
|
.push(
|
||||||
"I have shared my extended public key",
|
checkbox("I have shared my extended public key", shared)
|
||||||
shared,
|
.on_toggle(Message::UserActionDone),
|
||||||
Message::UserActionDone,
|
)
|
||||||
))
|
|
||||||
.push(if shared && network_valid {
|
.push(if shared && network_valid {
|
||||||
button::primary(None, "Next")
|
button::primary(None, "Next")
|
||||||
.width(Length::Fixed(200.0))
|
.width(Length::Fixed(200.0))
|
||||||
@ -756,7 +758,16 @@ pub fn register_descriptor<'a>(
|
|||||||
.push(card::simple(
|
.push(card::simple(
|
||||||
Column::new()
|
Column::new()
|
||||||
.push(text("The descriptor:").small().bold())
|
.push(text("The descriptor:").small().bold())
|
||||||
.push(text(descriptor.clone()).small())
|
.push(
|
||||||
|
scrollable(
|
||||||
|
Column::new()
|
||||||
|
.push(text(descriptor.to_owned()).small())
|
||||||
|
.push(Space::with_height(Length::Fixed(5.0))),
|
||||||
|
)
|
||||||
|
.direction(scrollable::Direction::Horizontal(
|
||||||
|
scrollable::Properties::new().width(5).scroller_width(5),
|
||||||
|
)),
|
||||||
|
)
|
||||||
.push(
|
.push(
|
||||||
Row::new().push(Column::new().width(Length::Fill)).push(
|
Row::new().push(Column::new().width(Length::Fill)).push(
|
||||||
button::secondary(Some(icon::clipboard_icon()), "Copy")
|
button::secondary(Some(icon::clipboard_icon()), "Copy")
|
||||||
@ -803,8 +814,7 @@ pub fn register_descriptor<'a>(
|
|||||||
.push_maybe(created_desc.then_some(checkbox(
|
.push_maybe(created_desc.then_some(checkbox(
|
||||||
"I have registered the descriptor on my device(s)",
|
"I have registered the descriptor on my device(s)",
|
||||||
done,
|
done,
|
||||||
Message::UserActionDone,
|
).on_toggle(Message::UserActionDone)))
|
||||||
)))
|
|
||||||
.push(if !created_desc || (done && !processing) {
|
.push(if !created_desc || (done && !processing) {
|
||||||
button::primary(None, "Next")
|
button::primary(None, "Next")
|
||||||
.on_press(Message::Next)
|
.on_press(Message::Next)
|
||||||
@ -858,7 +868,16 @@ pub fn backup_descriptor<'a>(
|
|||||||
.push(card::simple(
|
.push(card::simple(
|
||||||
Column::new()
|
Column::new()
|
||||||
.push(text("The descriptor:").small().bold())
|
.push(text("The descriptor:").small().bold())
|
||||||
.push(text(descriptor.clone()).small())
|
.push(
|
||||||
|
scrollable(
|
||||||
|
Column::new()
|
||||||
|
.push(text(descriptor.to_owned()).small())
|
||||||
|
.push(Space::with_height(Length::Fixed(5.0))),
|
||||||
|
)
|
||||||
|
.direction(scrollable::Direction::Horizontal(
|
||||||
|
scrollable::Properties::new().width(5).scroller_width(5),
|
||||||
|
)),
|
||||||
|
)
|
||||||
.push(
|
.push(
|
||||||
Row::new().push(Column::new().width(Length::Fill)).push(
|
Row::new().push(Column::new().width(Length::Fill)).push(
|
||||||
button::secondary(Some(icon::clipboard_icon()), "Copy")
|
button::secondary(Some(icon::clipboard_icon()), "Copy")
|
||||||
@ -868,11 +887,9 @@ pub fn backup_descriptor<'a>(
|
|||||||
.spacing(10)
|
.spacing(10)
|
||||||
.max_width(1000),
|
.max_width(1000),
|
||||||
))
|
))
|
||||||
.push(checkbox(
|
.push(
|
||||||
"I have backed up my descriptor",
|
checkbox("I have backed up my descriptor", done).on_toggle(Message::UserActionDone),
|
||||||
done,
|
)
|
||||||
Message::UserActionDone,
|
|
||||||
))
|
|
||||||
.push(if done {
|
.push(if done {
|
||||||
button::primary(None, "Next")
|
button::primary(None, "Next")
|
||||||
.on_press(Message::Next)
|
.on_press(Message::Next)
|
||||||
@ -1401,7 +1418,9 @@ pub fn defined_descriptor_key<'a>(
|
|||||||
.push(text(name).bold())
|
.push(text(name).bold())
|
||||||
.push(Space::with_height(Length::Fixed(5.0))),
|
.push(Space::with_height(Length::Fixed(5.0))),
|
||||||
)
|
)
|
||||||
.horizontal_scroll(Properties::new().width(5).scroller_width(5)),
|
.direction(scrollable::Direction::Horizontal(
|
||||||
|
Properties::new().width(5).scroller_width(5),
|
||||||
|
)),
|
||||||
)
|
)
|
||||||
.push(image::success_mark_icon().width(Length::Fixed(50.0)))
|
.push(image::success_mark_icon().width(Length::Fixed(50.0)))
|
||||||
.push(Space::with_width(Length::Fixed(1.0))),
|
.push(Space::with_width(Length::Fixed(1.0))),
|
||||||
@ -1672,7 +1691,7 @@ pub fn edit_sequence_modal<'a>(sequence: &form::Value<String>) -> Element<'a, Me
|
|||||||
message::SequenceModal::SequenceEdited(v.to_string()),
|
message::SequenceModal::SequenceEdited(v.to_string()),
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.step(144), // 144 blocks per day
|
.step(144_u16), // 144 blocks per day
|
||||||
)
|
)
|
||||||
.width(Length::Fixed(500.0)),
|
.width(Length::Fixed(500.0)),
|
||||||
);
|
);
|
||||||
@ -1815,11 +1834,7 @@ pub fn backup_mnemonic<'a>(
|
|||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.push(checkbox(
|
.push(checkbox("I have backed up my mnemonic", done).on_toggle(Message::UserActionDone))
|
||||||
"I have backed up my mnemonic",
|
|
||||||
done,
|
|
||||||
Message::UserActionDone,
|
|
||||||
))
|
|
||||||
.push(if done {
|
.push(if done {
|
||||||
button::primary(None, "Next")
|
button::primary(None, "Next")
|
||||||
.on_press(Message::Next)
|
.on_press(Message::Next)
|
||||||
@ -1997,8 +2012,8 @@ fn layout<'a>(
|
|||||||
|
|
||||||
mod threshsold_input {
|
mod threshsold_input {
|
||||||
use iced::alignment::{self, Alignment};
|
use iced::alignment::{self, Alignment};
|
||||||
|
use iced::widget::{component, Component};
|
||||||
use iced::Length;
|
use iced::Length;
|
||||||
use iced_lazy::{self, Component};
|
|
||||||
use liana_ui::{component::text::*, icon, theme, widget::*};
|
use liana_ui::{component::text::*, icon, theme, widget::*};
|
||||||
|
|
||||||
pub struct ThresholdInput<Message> {
|
pub struct ThresholdInput<Message> {
|
||||||
@ -2035,7 +2050,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 State = ();
|
||||||
type Event = Event;
|
type Event = Event;
|
||||||
|
|
||||||
@ -2085,7 +2100,7 @@ mod threshsold_input {
|
|||||||
Message: 'a,
|
Message: 'a,
|
||||||
{
|
{
|
||||||
fn from(numeric_input: ThresholdInput<Message>) -> Self {
|
fn from(numeric_input: ThresholdInput<Message>) -> Self {
|
||||||
iced_lazy::component(numeric_input)
|
component(numeric_input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use iced::{
|
use iced::{
|
||||||
|
alignment::Horizontal,
|
||||||
widget::{tooltip, Space},
|
widget::{tooltip, Space},
|
||||||
Alignment, Command, Length, Subscription,
|
Alignment, Command, Length, Subscription,
|
||||||
};
|
};
|
||||||
@ -10,7 +11,6 @@ use liana_ui::{
|
|||||||
color,
|
color,
|
||||||
component::{badge, button, card, modal::Modal, notification, text::*},
|
component::{badge, button, card, modal::Modal, notification, text::*},
|
||||||
icon, image, theme,
|
icon, image, theme,
|
||||||
util::*,
|
|
||||||
widget::*,
|
widget::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -330,7 +330,7 @@ impl DeleteWalletModal {
|
|||||||
.push(icon::circle_check_icon().style(color::GREEN))
|
.push(icon::circle_check_icon().style(color::GREEN))
|
||||||
.push(text("Wallet successfully deleted").style(color::GREEN))
|
.push(text("Wallet successfully deleted").style(color::GREEN))
|
||||||
})
|
})
|
||||||
.align_x(iced_native::alignment::Horizontal::Center)
|
.align_x(Horizontal::Center)
|
||||||
.width(Length::Fill),
|
.width(Length::Fill),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -19,7 +19,6 @@ use liana_ui::{
|
|||||||
color,
|
color,
|
||||||
component::{button, notification, text::*},
|
component::{button, notification, text::*},
|
||||||
icon,
|
icon,
|
||||||
util::Collection,
|
|
||||||
widget::*,
|
widget::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -64,6 +64,7 @@ impl Logger {
|
|||||||
&& !metadata.target().starts_with("iced_glow")
|
&& !metadata.target().starts_with("iced_glow")
|
||||||
&& !metadata.target().starts_with("glow_glyph")
|
&& !metadata.target().starts_with("glow_glyph")
|
||||||
&& !metadata.target().starts_with("naga")
|
&& !metadata.target().starts_with("naga")
|
||||||
|
&& !metadata.target().starts_with("winit")
|
||||||
&& !metadata.target().starts_with("mio")
|
&& !metadata.target().starts_with("mio")
|
||||||
&& !metadata.target().starts_with("ledger_transport_hid")
|
&& !metadata.target().starts_with("ledger_transport_hid")
|
||||||
})),
|
})),
|
||||||
|
|||||||
@ -5,9 +5,9 @@ use std::{error::Error, io::Write, path::PathBuf, process, str::FromStr};
|
|||||||
use iced::{
|
use iced::{
|
||||||
event::{self, Event},
|
event::{self, Event},
|
||||||
executor,
|
executor,
|
||||||
keyboard::{self, KeyCode},
|
keyboard::{self},
|
||||||
subscription,
|
|
||||||
widget::{focus_next, focus_previous},
|
widget::{focus_next, focus_previous},
|
||||||
|
window::settings::PlatformSpecific,
|
||||||
Application, Command, Settings, Subscription,
|
Application, Command, Settings, Subscription,
|
||||||
};
|
};
|
||||||
use tracing::{error, info};
|
use tracing::{error, info};
|
||||||
@ -90,12 +90,19 @@ pub enum Key {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
CtrlC,
|
CtrlC,
|
||||||
|
FontLoaded(Result<(), iced::font::Error>),
|
||||||
Launch(Box<launcher::Message>),
|
Launch(Box<launcher::Message>),
|
||||||
Install(Box<installer::Message>),
|
Install(Box<installer::Message>),
|
||||||
Load(Box<loader::Message>),
|
Load(Box<loader::Message>),
|
||||||
Run(Box<app::Message>),
|
Run(Box<app::Message>),
|
||||||
Event(iced_native::Event),
|
|
||||||
KeyPressed(Key),
|
KeyPressed(Key),
|
||||||
|
Event(iced::Event),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Result<(), iced::font::Error>> for Message {
|
||||||
|
fn from(value: Result<(), iced::font::Error>) -> Self {
|
||||||
|
Self::FontLoaded(value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn ctrl_c() -> Result<(), ()> {
|
async fn ctrl_c() -> Result<(), ()> {
|
||||||
@ -121,17 +128,12 @@ impl Application for GUI {
|
|||||||
|
|
||||||
fn new((config, log_level): (Config, Option<LevelFilter>)) -> (GUI, Command<Self::Message>) {
|
fn new((config, log_level): (Config, Option<LevelFilter>)) -> (GUI, Command<Self::Message>) {
|
||||||
let logger = Logger::setup(log_level.unwrap_or(LevelFilter::INFO));
|
let logger = Logger::setup(log_level.unwrap_or(LevelFilter::INFO));
|
||||||
match config {
|
let mut cmds = font::loads();
|
||||||
|
cmds.push(Command::perform(ctrl_c(), |_| Message::CtrlC));
|
||||||
|
let state = match config {
|
||||||
Config::Launcher(datadir_path) => {
|
Config::Launcher(datadir_path) => {
|
||||||
let launcher = Launcher::new(datadir_path);
|
let launcher = Launcher::new(datadir_path);
|
||||||
(
|
State::Launcher(Box::new(launcher))
|
||||||
Self {
|
|
||||||
state: State::Launcher(Box::new(launcher)),
|
|
||||||
logger,
|
|
||||||
log_level,
|
|
||||||
},
|
|
||||||
Command::perform(ctrl_c(), |_| Message::CtrlC),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Config::Install(datadir_path, network) => {
|
Config::Install(datadir_path, network) => {
|
||||||
if !datadir_path.exists() {
|
if !datadir_path.exists() {
|
||||||
@ -151,17 +153,8 @@ impl Application for GUI {
|
|||||||
log_level.unwrap_or(LevelFilter::INFO),
|
log_level.unwrap_or(LevelFilter::INFO),
|
||||||
);
|
);
|
||||||
let (install, command) = Installer::new(datadir_path, network);
|
let (install, command) = Installer::new(datadir_path, network);
|
||||||
(
|
cmds.push(command.map(|msg| Message::Install(Box::new(msg))));
|
||||||
Self {
|
State::Installer(Box::new(install))
|
||||||
state: State::Installer(Box::new(install)),
|
|
||||||
logger,
|
|
||||||
log_level,
|
|
||||||
},
|
|
||||||
Command::batch(vec![
|
|
||||||
command.map(|msg| Message::Install(Box::new(msg))),
|
|
||||||
Command::perform(ctrl_c(), |_| Message::CtrlC),
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Config::Run(datadir_path, cfg, network) => {
|
Config::Run(datadir_path, cfg, network) => {
|
||||||
logger.set_running_mode(
|
logger.set_running_mode(
|
||||||
@ -170,37 +163,31 @@ impl Application for GUI {
|
|||||||
log_level.unwrap_or_else(|| cfg.log_level().unwrap_or(LevelFilter::INFO)),
|
log_level.unwrap_or_else(|| cfg.log_level().unwrap_or(LevelFilter::INFO)),
|
||||||
);
|
);
|
||||||
let (loader, command) = Loader::new(datadir_path, cfg, network, None);
|
let (loader, command) = Loader::new(datadir_path, cfg, network, None);
|
||||||
(
|
cmds.push(command.map(|msg| Message::Load(Box::new(msg))));
|
||||||
Self {
|
State::Loader(Box::new(loader))
|
||||||
state: State::Loader(Box::new(loader)),
|
|
||||||
logger,
|
|
||||||
log_level,
|
|
||||||
},
|
|
||||||
Command::batch(vec![
|
|
||||||
command.map(|msg| Message::Load(Box::new(msg))),
|
|
||||||
Command::perform(ctrl_c(), |_| Message::CtrlC),
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
(
|
||||||
|
Self {
|
||||||
|
state,
|
||||||
|
logger,
|
||||||
|
log_level,
|
||||||
|
},
|
||||||
|
Command::batch(cmds),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
|
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
|
||||||
match (&mut self.state, message) {
|
match (&mut self.state, message) {
|
||||||
(_, Message::CtrlC)
|
(_, Message::CtrlC)
|
||||||
| (
|
| (_, Message::Event(iced::Event::Window(_, iced::window::Event::CloseRequested))) => {
|
||||||
_,
|
|
||||||
Message::Event(iced_native::Event::Window(
|
|
||||||
iced_native::window::Event::CloseRequested,
|
|
||||||
)),
|
|
||||||
) => {
|
|
||||||
match &mut self.state {
|
match &mut self.state {
|
||||||
State::Loader(s) => s.stop(),
|
State::Loader(s) => s.stop(),
|
||||||
State::Launcher(s) => s.stop(),
|
State::Launcher(s) => s.stop(),
|
||||||
State::Installer(s) => s.stop(),
|
State::Installer(s) => s.stop(),
|
||||||
State::App(s) => s.stop(),
|
State::App(s) => s.stop(),
|
||||||
};
|
};
|
||||||
iced::window::close()
|
iced::window::close(iced::window::Id::MAIN)
|
||||||
}
|
}
|
||||||
(_, Message::KeyPressed(Key::Tab(shift))) => {
|
(_, Message::KeyPressed(Key::Tab(shift))) => {
|
||||||
log::debug!("Tab pressed!");
|
log::debug!("Tab pressed!");
|
||||||
@ -299,26 +286,26 @@ impl Application for GUI {
|
|||||||
State::App(v) => v.subscription().map(|msg| Message::Run(Box::new(msg))),
|
State::App(v) => v.subscription().map(|msg| Message::Run(Box::new(msg))),
|
||||||
State::Launcher(v) => v.subscription().map(|msg| Message::Launch(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 {
|
Event::Keyboard(keyboard::Event::KeyPressed {
|
||||||
key_code: KeyCode::Tab,
|
key: iced::keyboard::Key::Named(iced::keyboard::key::Named::Tab),
|
||||||
modifiers,
|
modifiers,
|
||||||
..
|
..
|
||||||
}),
|
}),
|
||||||
event::Status::Ignored,
|
event::Status::Ignored,
|
||||||
) => Some(Message::KeyPressed(Key::Tab(modifiers.shift()))),
|
) => Some(Message::KeyPressed(Key::Tab(modifiers.shift()))),
|
||||||
(
|
(
|
||||||
iced::Event::Window(iced_native::window::Event::CloseRequested),
|
iced::Event::Window(_, iced::window::Event::CloseRequested),
|
||||||
event::Status::Ignored,
|
event::Status::Ignored,
|
||||||
) => Some(Message::Event(event)),
|
) => Some(Message::Event(event)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
.with_filter(|(event, _status)| {
|
.with_filter(|event| {
|
||||||
matches!(
|
matches!(
|
||||||
event,
|
event,
|
||||||
iced::Event::Window(iced_native::window::Event::CloseRequested)
|
iced::Event::Window(_, iced::window::Event::CloseRequested)
|
||||||
| iced::Event::Keyboard(_)
|
| iced::Event::Keyboard(_)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -453,11 +440,19 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
setup_panic_hook();
|
setup_panic_hook();
|
||||||
|
|
||||||
let mut settings = Settings::with_flags((config, log_level));
|
let mut settings = Settings::with_flags((config, log_level));
|
||||||
settings.id = Some("liana-gui".to_string());
|
|
||||||
settings.window.icon = Some(image::liana_app_icon());
|
settings.window.icon = Some(image::liana_app_icon());
|
||||||
settings.default_text_size = text::P1_SIZE.into();
|
settings.default_text_size = text::P1_SIZE.into();
|
||||||
settings.default_font = Some(font::REGULAR_BYTES);
|
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 = PlatformSpecific {
|
||||||
|
application_id: "Liana".to_string(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if let Err(e) = GUI::run(settings) {
|
if let Err(e) = GUI::run(settings) {
|
||||||
return Err(format!("Failed to launch UI: {}", e).into());
|
return Err(format!("Failed to launch UI: {}", e).into());
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use iced_native::command::Action;
|
use iced_runtime::command::Action;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::{cache::Cache, message::Message, state::State, wallet::Wallet},
|
app::{cache::Cache, message::Message, state::State, wallet::Wallet},
|
||||||
|
|||||||
@ -6,8 +6,6 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
iced = { version = "0.9", default_features = false, features = ["svg", "image", "glow"] }
|
iced = { version = "0.12.1", default-features = false, features = ["svg", "image", "lazy", "qr_code", "advanced", "webgl"] }
|
||||||
iced_native = "0.10"
|
|
||||||
iced_lazy = { version = "0.6"}
|
|
||||||
bitcoin = "0.31"
|
bitcoin = "0.31"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
|
|||||||
@ -6,8 +6,7 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
iced = "0.9"
|
iced = "0.10"
|
||||||
iced_native = "0.10"
|
|
||||||
web-sys = "0.3.61"
|
web-sys = "0.3.61"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
liana_ui = { path = "../.." }
|
liana_ui = { path = "../.." }
|
||||||
|
|||||||
@ -2,11 +2,12 @@ mod section;
|
|||||||
|
|
||||||
use iced::widget::{button, column, container, row, scrollable, text, Space};
|
use iced::widget::{button, column, container, row, scrollable, text, Space};
|
||||||
use iced::{executor, Application, Command, Length, Settings, Subscription};
|
use iced::{executor, Application, Command, Length, Settings, Subscription};
|
||||||
use liana_ui::{component::text::*, image, theme, widget::*};
|
use liana_ui::{component::text::*, font, image, theme, widget::*};
|
||||||
|
|
||||||
pub fn main() -> iced::Result {
|
pub fn main() -> iced::Result {
|
||||||
let mut settings = Settings::with_flags(Config {});
|
let mut settings = Settings::with_flags(Config {});
|
||||||
settings.default_text_size = P1_SIZE.into();
|
settings.default_text_size = P1_SIZE.into();
|
||||||
|
settings.default_font = font::REGULAR;
|
||||||
DesignSystem::run(settings)
|
DesignSystem::run(settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,11 +22,18 @@ struct DesignSystem {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
Event(iced_native::Event),
|
FontLoaded(Result<(), iced::font::Error>),
|
||||||
|
Event(iced::Event),
|
||||||
Section(usize),
|
Section(usize),
|
||||||
Ignore,
|
Ignore,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Result<(), iced::font::Error>> for Message {
|
||||||
|
fn from(res: Result<(), iced::font::Error>) -> Message {
|
||||||
|
Message::FontLoaded(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Application for DesignSystem {
|
impl Application for DesignSystem {
|
||||||
type Message = Message;
|
type Message = Message;
|
||||||
type Theme = theme::Theme;
|
type Theme = theme::Theme;
|
||||||
@ -49,6 +57,9 @@ impl Application for DesignSystem {
|
|||||||
],
|
],
|
||||||
current: 0,
|
current: 0,
|
||||||
};
|
};
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
let mut cmds: Vec<Command<Self::Message>> = font::loads();
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
{
|
{
|
||||||
use iced_native::{command, window};
|
use iced_native::{command, window};
|
||||||
@ -57,16 +68,12 @@ impl Application for DesignSystem {
|
|||||||
(window.inner_width().unwrap().as_f64().unwrap()) as u32,
|
(window.inner_width().unwrap().as_f64().unwrap()) as u32,
|
||||||
(window.inner_height().unwrap().as_f64().unwrap()) as u32,
|
(window.inner_height().unwrap().as_f64().unwrap()) as u32,
|
||||||
);
|
);
|
||||||
(
|
cmds.push(Command::single(command::Action::Window(
|
||||||
app,
|
window::Action::Resize { width, height },
|
||||||
Command::single(command::Action::Window(window::Action::Resize {
|
)));
|
||||||
width,
|
|
||||||
height,
|
|
||||||
})),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
(app, Command::none())
|
(app, Command::batch(cmds))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, message: Message) -> Command<Self::Message> {
|
fn update(&mut self, message: Message) -> Command<Self::Message> {
|
||||||
@ -76,10 +83,7 @@ impl Application for DesignSystem {
|
|||||||
self.current = i;
|
self.current = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::Event(iced::Event::Window(iced_native::window::Event::Resized {
|
Message::Event(iced::Event::Window(iced::window::Event::Resized { width, height })) => {
|
||||||
width,
|
|
||||||
height,
|
|
||||||
})) => {
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
{
|
{
|
||||||
use iced_native::{command, window};
|
use iced_native::{command, window};
|
||||||
@ -95,7 +99,7 @@ impl Application for DesignSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn subscription(&self) -> Subscription<Self::Message> {
|
fn subscription(&self) -> Subscription<Self::Message> {
|
||||||
iced_native::subscription::events().map(Self::Message::Event)
|
iced::subscription::events().map(Self::Message::Event)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view(&self) -> Element<Message> {
|
fn view(&self) -> Element<Message> {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
pub use bitcoin::Amount;
|
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> {
|
pub fn amount<'a, T: 'a>(a: &Amount) -> Row<'a, T> {
|
||||||
amount_with_size(a, P1_SIZE)
|
amount_with_size(a, P1_SIZE)
|
||||||
|
|||||||
@ -108,7 +108,6 @@ pub fn badge_pill<'a, T: 'a>(label: &'a str, tooltip: &'a str) -> Container<'a,
|
|||||||
tooltip::Tooltip::new(
|
tooltip::Tooltip::new(
|
||||||
Container::new(text::p2_regular(label))
|
Container::new(text::p2_regular(label))
|
||||||
.padding(10)
|
.padding(10)
|
||||||
.width(Length::Fill)
|
|
||||||
.center_x()
|
.center_x()
|
||||||
.style(theme::Container::Pill(theme::Pill::Simple)),
|
.style(theme::Container::Pill(theme::Pill::Simple)),
|
||||||
tooltip,
|
tooltip,
|
||||||
|
|||||||
@ -1,19 +1,28 @@
|
|||||||
use crate::{color, theme, widget::*};
|
use crate::{color, theme, widget::*};
|
||||||
use iced::widget::{button, container, row};
|
use iced::widget::{button, container, row};
|
||||||
use iced::{Alignment, Length};
|
use iced::Alignment;
|
||||||
|
|
||||||
use super::text::text;
|
use super::text::text;
|
||||||
|
|
||||||
pub fn menu<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Button<'a, T> {
|
pub fn menu<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Button<'a, T> {
|
||||||
button::Button::new(content(icon.map(|i| i.style(color::GREY_3)), t).padding(10))
|
button::Button::new(content_menu(icon.map(|i| i.style(color::GREY_3)), t).padding(10))
|
||||||
.style(theme::Button::Menu(false))
|
.style(theme::Button::Menu(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn menu_active<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Button<'a, T> {
|
pub fn menu_active<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Button<'a, T> {
|
||||||
button::Button::new(content(icon.map(|i| i.style(color::GREY_3)), t).padding(10))
|
button::Button::new(content_menu(icon.map(|i| i.style(color::GREY_3)), t).padding(10))
|
||||||
.style(theme::Button::Menu(true))
|
.style(theme::Button::Menu(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn content_menu<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Container<'a, T> {
|
||||||
|
match icon {
|
||||||
|
None => container(text(t)).padding(5),
|
||||||
|
Some(i) => {
|
||||||
|
container(row![i, text(t)].spacing(10).align_items(Alignment::Center)).padding(5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn alert<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Button<'a, T> {
|
pub fn alert<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Button<'a, T> {
|
||||||
button::Button::new(content(icon, t)).style(theme::Button::Destructive)
|
button::Button::new(content(icon, t)).style(theme::Button::Destructive)
|
||||||
}
|
}
|
||||||
@ -40,15 +49,9 @@ pub fn transparent_border<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) ->
|
|||||||
|
|
||||||
fn content<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Container<'a, T> {
|
fn content<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Container<'a, T> {
|
||||||
match icon {
|
match icon {
|
||||||
None => container(text(t)).width(Length::Fill).center_x().padding(5),
|
None => container(text(t)).center_x().padding(5),
|
||||||
Some(i) => container(
|
Some(i) => container(row![i, text(t)].spacing(10).align_items(Alignment::Center))
|
||||||
row![i, text(t)]
|
.center_x()
|
||||||
.spacing(10)
|
.padding(5),
|
||||||
.width(iced::Length::Fill)
|
|
||||||
.align_items(Alignment::Center),
|
|
||||||
)
|
|
||||||
.width(iced::Length::Fill)
|
|
||||||
.center_x()
|
|
||||||
.padding(5),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@ pub fn error<'a, T: 'a>(message: &'static str, error: String) -> Container<'a, T
|
|||||||
.align_items(iced::Alignment::Center)
|
.align_items(iced::Alignment::Center)
|
||||||
.push(icon::warning_icon().style(color::RED))
|
.push(icon::warning_icon().style(color::RED))
|
||||||
.push(text(message).style(color::RED)),
|
.push(text(message).style(color::RED)),
|
||||||
error,
|
Text::new(error),
|
||||||
iced::widget::tooltip::Position::Bottom,
|
iced::widget::tooltip::Position::Bottom,
|
||||||
)
|
)
|
||||||
.style(theme::Container::Card(theme::Card::Error)),
|
.style(theme::Container::Card(theme::Card::Error)),
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
use crate::widget::*;
|
use iced::{
|
||||||
use iced::widget::column;
|
advanced,
|
||||||
use iced_lazy::{self, Component};
|
widget::{column, component, Button, Component},
|
||||||
|
Element,
|
||||||
|
};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
pub struct Collapse<'a, M, H, F, C> {
|
pub struct Collapse<'a, M, H, F, C> {
|
||||||
@ -10,13 +12,15 @@ pub struct Collapse<'a, M, H, F, C> {
|
|||||||
phantom: PhantomData<&'a M>,
|
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
|
where
|
||||||
|
Renderer: advanced::Renderer,
|
||||||
|
Theme: iced::widget::button::StyleSheet,
|
||||||
Message: 'a,
|
Message: 'a,
|
||||||
T: Into<Message> + Clone + 'a,
|
T: Into<Message> + Clone + 'a,
|
||||||
H: Fn() -> Button<'a, Event<T>> + 'a,
|
H: Fn() -> Button<'a, Event<T>, Theme, Renderer> + 'a,
|
||||||
F: Fn() -> Button<'a, Event<T>> + 'a,
|
F: Fn() -> Button<'a, Event<T>, Theme, Renderer> + 'a,
|
||||||
C: Fn() -> Element<'a, T> + 'a,
|
C: Fn() -> Element<'a, T, Theme, Renderer> + 'a,
|
||||||
{
|
{
|
||||||
pub fn new(before: H, after: F, content: C) -> Self {
|
pub fn new(before: H, after: F, content: C) -> Self {
|
||||||
Collapse {
|
Collapse {
|
||||||
@ -34,13 +38,15 @@ pub enum Event<T> {
|
|||||||
Collapse(bool),
|
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>
|
for Collapse<'a, Message, H, F, C>
|
||||||
where
|
where
|
||||||
T: Into<Message> + Clone + 'a,
|
T: Into<Message> + Clone + 'a,
|
||||||
H: Fn() -> Button<'a, Event<T>>,
|
H: Fn() -> Button<'a, Event<T>, Theme, Renderer>,
|
||||||
F: Fn() -> Button<'a, Event<T>>,
|
F: Fn() -> Button<'a, Event<T>, Theme, Renderer>,
|
||||||
C: Fn() -> Element<'a, T>,
|
C: Fn() -> Element<'a, T, Theme, Renderer>,
|
||||||
|
Renderer: 'a + advanced::Renderer,
|
||||||
|
Theme: 'a + iced::widget::button::StyleSheet,
|
||||||
{
|
{
|
||||||
type State = bool;
|
type State = bool;
|
||||||
type Event = Event<T>;
|
type Event = Event<T>;
|
||||||
@ -55,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 {
|
if *state {
|
||||||
column![
|
column![
|
||||||
(self.after)().on_press(Event::Collapse(false)),
|
(self.after)().on_press(Event::Collapse(false)),
|
||||||
@ -68,16 +74,18 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message, T, H: 'a, F: 'a, C: 'a> From<Collapse<'a, Message, H, F, C>>
|
impl<'a, Message, T, H: 'a, F: 'a, C: 'a, Theme, Renderer> From<Collapse<'a, Message, H, F, C>>
|
||||||
for Element<'a, Message>
|
for Element<'a, Message, Theme, Renderer>
|
||||||
where
|
where
|
||||||
Message: 'a,
|
Message: 'a,
|
||||||
|
Renderer: 'a + advanced::Renderer,
|
||||||
|
Theme: 'a + iced::widget::button::StyleSheet,
|
||||||
T: Into<Message> + Clone + 'a,
|
T: Into<Message> + Clone + 'a,
|
||||||
H: Fn() -> Button<'a, Event<T>>,
|
H: Fn() -> Button<'a, Event<T>, Theme, Renderer>,
|
||||||
F: Fn() -> Button<'a, Event<T>>,
|
F: Fn() -> Button<'a, Event<T>, Theme, Renderer>,
|
||||||
C: Fn() -> Element<'a, T>,
|
C: Fn() -> Element<'a, T, Theme, Renderer>,
|
||||||
{
|
{
|
||||||
fn from(c: Collapse<'a, Message, H, F, C>) -> Self {
|
fn from(c: Collapse<'a, Message, H, F, C>) -> Self {
|
||||||
iced_lazy::component(c)
|
component(c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,6 @@ use crate::{
|
|||||||
color,
|
color,
|
||||||
component::{amount, badge, text},
|
component::{amount, badge, text},
|
||||||
theme,
|
theme,
|
||||||
util::Collection,
|
|
||||||
widget::*,
|
widget::*,
|
||||||
};
|
};
|
||||||
use bitcoin::Amount;
|
use bitcoin::Amount;
|
||||||
@ -12,7 +11,7 @@ use iced::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub fn unconfirmed_outgoing_event<'a, T: Clone + 'a>(
|
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,
|
amount: &Amount,
|
||||||
msg: T,
|
msg: T,
|
||||||
) -> Container<'a, 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>(
|
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,
|
date: chrono::NaiveDateTime,
|
||||||
amount: &Amount,
|
amount: &Amount,
|
||||||
msg: T,
|
msg: T,
|
||||||
@ -72,7 +71,7 @@ pub fn confirmed_outgoing_event<'a, T: Clone + 'a>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn unconfirmed_incoming_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,
|
amount: &Amount,
|
||||||
msg: T,
|
msg: T,
|
||||||
) -> Container<'a, 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>(
|
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,
|
date: chrono::NaiveDateTime,
|
||||||
amount: &Amount,
|
amount: &Amount,
|
||||||
msg: T,
|
msg: T,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use bitcoin::Denomination;
|
use bitcoin::Denomination;
|
||||||
use iced::{widget::text_input, Length};
|
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)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Value<T> {
|
pub struct Value<T> {
|
||||||
@ -19,7 +19,7 @@ impl std::default::Default for Value<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Form<'a, Message> {
|
pub struct Form<'a, Message> {
|
||||||
input: text_input::TextInput<'a, Message, iced::Renderer<theme::Theme>>,
|
input: TextInput<'a, Message>,
|
||||||
warning: Option<&'a str>,
|
warning: Option<&'a str>,
|
||||||
valid: bool,
|
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::{
|
use iced::{
|
||||||
widget::{column, container, row, tooltip},
|
widget::{column, container, row, tooltip},
|
||||||
Alignment, Length,
|
Alignment, Length,
|
||||||
|
|||||||
@ -1,23 +1,26 @@
|
|||||||
/// modal widget from https://github.com/iced-rs/iced/blob/master/examples/modal/
|
/// modal widget from https://github.com/iced-rs/iced/blob/master/examples/modal/
|
||||||
use iced_native::alignment::Alignment;
|
use iced::advanced::layout::{self, Layout};
|
||||||
use iced_native::widget::{self, Tree};
|
use iced::advanced::overlay;
|
||||||
use iced_native::{
|
use iced::advanced::renderer;
|
||||||
event, layout, mouse, overlay, renderer, Clipboard, Color, Element, Event, Layout, Length,
|
use iced::advanced::widget::{self, Tree, Widget};
|
||||||
Point, Rectangle, Shell, Size, Widget,
|
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, Vector};
|
||||||
|
|
||||||
/// A widget that centers a modal element over some base element
|
/// A widget that centers a modal element over some base element
|
||||||
pub struct Modal<'a, Message, Renderer> {
|
pub struct Modal<'a, Message, Theme, Renderer> {
|
||||||
base: Element<'a, Message, Renderer>,
|
base: Element<'a, Message, Theme, Renderer>,
|
||||||
modal: Element<'a, Message, Renderer>,
|
modal: Element<'a, Message, Theme, Renderer>,
|
||||||
on_blur: Option<Message>,
|
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`]
|
/// Returns a new [`Modal`]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
base: impl Into<Element<'a, Message, Renderer>>,
|
base: impl Into<Element<'a, Message, Theme, Renderer>>,
|
||||||
modal: impl Into<Element<'a, Message, Renderer>>,
|
modal: impl Into<Element<'a, Message, Theme, Renderer>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
base: base.into(),
|
base: base.into(),
|
||||||
@ -33,9 +36,10 @@ 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
|
where
|
||||||
Renderer: iced_native::Renderer,
|
Renderer: advanced::Renderer,
|
||||||
Message: Clone,
|
Message: Clone,
|
||||||
{
|
{
|
||||||
fn children(&self) -> Vec<Tree> {
|
fn children(&self) -> Vec<Tree> {
|
||||||
@ -46,47 +50,52 @@ where
|
|||||||
tree.diff_children(&[&self.base, &self.modal]);
|
tree.diff_children(&[&self.base, &self.modal]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn width(&self) -> Length {
|
fn size(&self) -> Size<Length> {
|
||||||
self.base.as_widget().width()
|
self.base.as_widget().size()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn height(&self) -> Length {
|
fn layout(
|
||||||
self.base.as_widget().height()
|
&self,
|
||||||
}
|
tree: &mut widget::Tree,
|
||||||
|
renderer: &Renderer,
|
||||||
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> layout::Node {
|
limits: &layout::Limits,
|
||||||
self.base.as_widget().layout(renderer, limits)
|
) -> layout::Node {
|
||||||
|
self.base
|
||||||
|
.as_widget()
|
||||||
|
.layout(&mut tree.children[0], renderer, limits)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(
|
fn on_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut Tree,
|
state: &mut widget::Tree,
|
||||||
event: Event,
|
event: Event,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor_position: Point,
|
cursor: mouse::Cursor,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
|
viewport: &Rectangle,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
self.base.as_widget_mut().on_event(
|
self.base.as_widget_mut().on_event(
|
||||||
&mut state.children[0],
|
&mut state.children[0],
|
||||||
event,
|
event,
|
||||||
layout,
|
layout,
|
||||||
cursor_position,
|
cursor,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
shell,
|
shell,
|
||||||
|
viewport,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
state: &Tree,
|
state: &widget::Tree,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
theme: &<Renderer as iced_native::Renderer>::Theme,
|
theme: &Theme,
|
||||||
style: &renderer::Style,
|
style: &renderer::Style,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor_position: Point,
|
cursor: mouse::Cursor,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
) {
|
) {
|
||||||
self.base.as_widget().draw(
|
self.base.as_widget().draw(
|
||||||
@ -95,7 +104,7 @@ where
|
|||||||
theme,
|
theme,
|
||||||
style,
|
style,
|
||||||
layout,
|
layout,
|
||||||
cursor_position,
|
cursor,
|
||||||
viewport,
|
viewport,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -105,30 +114,29 @@ where
|
|||||||
state: &'b mut Tree,
|
state: &'b mut Tree,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
) -> Option<overlay::Element<'b, Message, Renderer>> {
|
translation: Vector,
|
||||||
Some(overlay::Element::new(
|
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
|
||||||
layout.position(),
|
Some(overlay::Element::new(Box::new(Overlay {
|
||||||
Box::new(Overlay {
|
position: layout.position() + translation,
|
||||||
content: &mut self.modal,
|
content: &mut self.modal,
|
||||||
tree: &mut state.children[1],
|
tree: &mut state.children[1],
|
||||||
size: layout.bounds().size(),
|
size: layout.bounds().size(),
|
||||||
on_blur: self.on_blur.clone(),
|
on_blur: self.on_blur.clone(),
|
||||||
}),
|
})))
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mouse_interaction(
|
fn mouse_interaction(
|
||||||
&self,
|
&self,
|
||||||
state: &Tree,
|
state: &widget::Tree,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor_position: Point,
|
cursor: mouse::Cursor,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
) -> mouse::Interaction {
|
) -> mouse::Interaction {
|
||||||
self.base.as_widget().mouse_interaction(
|
self.base.as_widget().mouse_interaction(
|
||||||
&state.children[0],
|
&state.children[0],
|
||||||
layout,
|
layout,
|
||||||
cursor_position,
|
cursor,
|
||||||
viewport,
|
viewport,
|
||||||
renderer,
|
renderer,
|
||||||
)
|
)
|
||||||
@ -147,38 +155,39 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Overlay<'a, 'b, Message, Renderer> {
|
struct Overlay<'a, 'b, Message, Theme, Renderer> {
|
||||||
content: &'b mut Element<'a, Message, Renderer>,
|
position: Point,
|
||||||
|
content: &'b mut Element<'a, Message, Theme, Renderer>,
|
||||||
tree: &'b mut Tree,
|
tree: &'b mut Tree,
|
||||||
size: Size,
|
size: Size,
|
||||||
on_blur: Option<Message>,
|
on_blur: Option<Message>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, Message, Renderer> overlay::Overlay<Message, Renderer>
|
impl<'a, 'b, Message, Theme, Renderer> overlay::Overlay<Message, Theme, Renderer>
|
||||||
for Overlay<'a, 'b, Message, Renderer>
|
for Overlay<'a, 'b, Message, Theme, Renderer>
|
||||||
where
|
where
|
||||||
Renderer: iced_native::Renderer,
|
Renderer: advanced::Renderer,
|
||||||
Message: Clone,
|
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)
|
let limits = layout::Limits::new(Size::ZERO, self.size)
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.height(Length::Fill);
|
.height(Length::Fill);
|
||||||
|
|
||||||
let mut child = self.content.as_widget().layout(renderer, &limits);
|
let child = self
|
||||||
child.align(Alignment::Center, Alignment::Center, limits.max());
|
.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]);
|
layout::Node::with_children(self.size, vec![child]).move_to(self.position)
|
||||||
node.move_to(position);
|
|
||||||
|
|
||||||
node
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(
|
fn on_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: Event,
|
event: Event,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor_position: Point,
|
cursor: mouse::Cursor,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
@ -187,7 +196,7 @@ where
|
|||||||
|
|
||||||
if let Some(message) = self.on_blur.as_ref() {
|
if let Some(message) = self.on_blur.as_ref() {
|
||||||
if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) = &event {
|
if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) = &event {
|
||||||
if !content_bounds.contains(cursor_position) {
|
if !cursor.is_over(content_bounds) {
|
||||||
shell.publish(message.clone());
|
shell.publish(message.clone());
|
||||||
return event::Status::Captured;
|
return event::Status::Captured;
|
||||||
}
|
}
|
||||||
@ -198,27 +207,26 @@ where
|
|||||||
self.tree,
|
self.tree,
|
||||||
event,
|
event,
|
||||||
layout.children().next().unwrap(),
|
layout.children().next().unwrap(),
|
||||||
cursor_position,
|
cursor,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
shell,
|
shell,
|
||||||
|
&layout.bounds(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
theme: &Renderer::Theme,
|
theme: &Theme,
|
||||||
style: &renderer::Style,
|
style: &renderer::Style,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor_position: Point,
|
cursor: mouse::Cursor,
|
||||||
) {
|
) {
|
||||||
renderer.fill_quad(
|
renderer.fill_quad(
|
||||||
renderer::Quad {
|
renderer::Quad {
|
||||||
bounds: layout.bounds(),
|
bounds: layout.bounds(),
|
||||||
border_radius: renderer::BorderRadius::from(0.0),
|
..renderer::Quad::default()
|
||||||
border_width: 0.0,
|
|
||||||
border_color: Color::TRANSPARENT,
|
|
||||||
},
|
},
|
||||||
Color {
|
Color {
|
||||||
a: 0.80,
|
a: 0.80,
|
||||||
@ -232,7 +240,7 @@ where
|
|||||||
theme,
|
theme,
|
||||||
style,
|
style,
|
||||||
layout.children().next().unwrap(),
|
layout.children().next().unwrap(),
|
||||||
cursor_position,
|
cursor,
|
||||||
&layout.bounds(),
|
&layout.bounds(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -254,26 +262,41 @@ where
|
|||||||
fn mouse_interaction(
|
fn mouse_interaction(
|
||||||
&self,
|
&self,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor_position: Point,
|
cursor: mouse::Cursor,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
) -> mouse::Interaction {
|
) -> mouse::Interaction {
|
||||||
self.content.as_widget().mouse_interaction(
|
self.content.as_widget().mouse_interaction(
|
||||||
self.tree,
|
self.tree,
|
||||||
layout.children().next().unwrap(),
|
layout.children().next().unwrap(),
|
||||||
cursor_position,
|
cursor,
|
||||||
viewport,
|
viewport,
|
||||||
renderer,
|
renderer,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn overlay<'c>(
|
||||||
|
&'c mut self,
|
||||||
|
layout: Layout<'_>,
|
||||||
|
renderer: &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
|
where
|
||||||
Renderer: 'a + iced_native::Renderer,
|
Renderer: 'a + advanced::Renderer,
|
||||||
Message: 'a + Clone,
|
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)
|
Element::new(modal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,6 @@ use crate::{
|
|||||||
color,
|
color,
|
||||||
component::{collapse, text},
|
component::{collapse, text},
|
||||||
icon, theme,
|
icon, theme,
|
||||||
util::*,
|
|
||||||
widget::*,
|
widget::*,
|
||||||
};
|
};
|
||||||
use iced::{
|
use iced::{
|
||||||
|
|||||||
@ -1,122 +1,94 @@
|
|||||||
use crate::{font, theme::Theme};
|
use crate::{font, theme::Theme};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
// 40 * 1.2
|
pub const H1_SIZE: u16 = 40;
|
||||||
pub const H1_SIZE: u16 = 48;
|
pub const H2_SIZE: u16 = 29;
|
||||||
// 29 * 1.2
|
pub const H3_SIZE: u16 = 24;
|
||||||
pub const H2_SIZE: u16 = 35;
|
pub const H4_SIZE: u16 = 20;
|
||||||
// 24 * 1.2
|
pub const H5_SIZE: u16 = 18;
|
||||||
pub const H3_SIZE: u16 = 29;
|
pub const P1_SIZE: u16 = 16;
|
||||||
// 20 * 1.2
|
pub const P2_SIZE: u16 = 14;
|
||||||
pub const H4_SIZE: u16 = 24;
|
pub const CAPTION_SIZE: u16 = 12;
|
||||||
// 18 * 1.2
|
|
||||||
pub const H5_SIZE: u16 = 22;
|
|
||||||
// 16 * 1.2
|
|
||||||
pub const P1_SIZE: u16 = 20;
|
|
||||||
// 14 * 1.2
|
|
||||||
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)
|
iced::widget::Text::new(content)
|
||||||
.font(font::BOLD)
|
.font(font::BOLD)
|
||||||
.size(H1_SIZE)
|
.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)
|
iced::widget::Text::new(content)
|
||||||
.font(font::BOLD)
|
.font(font::BOLD)
|
||||||
.size(H2_SIZE)
|
.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)
|
iced::widget::Text::new(content)
|
||||||
.font(font::BOLD)
|
.font(font::BOLD)
|
||||||
.size(H3_SIZE)
|
.size(H3_SIZE)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn h4_bold<'a>(
|
pub fn h4_bold<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||||
content: impl Into<Cow<'a, str>>,
|
|
||||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
|
||||||
iced::widget::Text::new(content)
|
iced::widget::Text::new(content)
|
||||||
.font(font::BOLD)
|
.font(font::BOLD)
|
||||||
.size(H4_SIZE)
|
.size(H4_SIZE)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn h4_regular<'a>(
|
pub fn h4_regular<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||||
content: impl Into<Cow<'a, str>>,
|
|
||||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
|
||||||
iced::widget::Text::new(content)
|
iced::widget::Text::new(content)
|
||||||
.font(font::REGULAR)
|
.font(font::REGULAR)
|
||||||
.size(H4_SIZE)
|
.size(H4_SIZE)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn h5_medium<'a>(
|
pub fn h5_medium<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||||
content: impl Into<Cow<'a, str>>,
|
|
||||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
|
||||||
iced::widget::Text::new(content)
|
iced::widget::Text::new(content)
|
||||||
.font(font::MEDIUM)
|
.font(font::MEDIUM)
|
||||||
.size(H5_SIZE)
|
.size(H5_SIZE)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn h5_regular<'a>(
|
pub fn h5_regular<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||||
content: impl Into<Cow<'a, str>>,
|
|
||||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
|
||||||
iced::widget::Text::new(content)
|
iced::widget::Text::new(content)
|
||||||
.font(font::REGULAR)
|
.font(font::REGULAR)
|
||||||
.size(H5_SIZE)
|
.size(H5_SIZE)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn p1_bold<'a>(
|
pub fn p1_bold<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||||
content: impl Into<Cow<'a, str>>,
|
|
||||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
|
||||||
iced::widget::Text::new(content)
|
iced::widget::Text::new(content)
|
||||||
.font(font::BOLD)
|
.font(font::BOLD)
|
||||||
.size(P1_SIZE)
|
.size(P1_SIZE)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn p1_medium<'a>(
|
pub fn p1_medium<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||||
content: impl Into<Cow<'a, str>>,
|
|
||||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
|
||||||
iced::widget::Text::new(content)
|
iced::widget::Text::new(content)
|
||||||
.font(font::MEDIUM)
|
.font(font::MEDIUM)
|
||||||
.size(P1_SIZE)
|
.size(P1_SIZE)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn p1_regular<'a>(
|
pub fn p1_regular<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||||
content: impl Into<Cow<'a, str>>,
|
|
||||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
|
||||||
iced::widget::Text::new(content)
|
iced::widget::Text::new(content)
|
||||||
.font(font::REGULAR)
|
.font(font::REGULAR)
|
||||||
.size(P1_SIZE)
|
.size(P1_SIZE)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn p2_medium<'a>(
|
pub fn p2_medium<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||||
content: impl Into<Cow<'a, str>>,
|
|
||||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
|
||||||
iced::widget::Text::new(content)
|
iced::widget::Text::new(content)
|
||||||
.font(font::MEDIUM)
|
.font(font::MEDIUM)
|
||||||
.size(P2_SIZE)
|
.size(P2_SIZE)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn p2_regular<'a>(
|
pub fn p2_regular<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||||
content: impl Into<Cow<'a, str>>,
|
|
||||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
|
||||||
iced::widget::Text::new(content)
|
iced::widget::Text::new(content)
|
||||||
.font(font::REGULAR)
|
.font(font::REGULAR)
|
||||||
.size(P2_SIZE)
|
.size(P2_SIZE)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn caption<'a>(
|
pub fn caption<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||||
content: impl Into<Cow<'a, str>>,
|
|
||||||
) -> iced::widget::Text<'a, iced::Renderer<Theme>> {
|
|
||||||
iced::widget::Text::new(content)
|
iced::widget::Text::new(content)
|
||||||
.font(font::REGULAR)
|
.font(font::REGULAR)
|
||||||
.size(CAPTION_SIZE)
|
.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)
|
p1_regular(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +97,7 @@ pub trait Text {
|
|||||||
fn small(self) -> Self;
|
fn small(self) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Text for iced::widget::Text<'_, iced::Renderer<Theme>> {
|
impl Text for iced::widget::Text<'_, Theme> {
|
||||||
fn bold(self) -> Self {
|
fn bold(self) -> Self {
|
||||||
self.font(font::BOLD)
|
self.font(font::BOLD)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,29 +1,28 @@
|
|||||||
use std::time::Instant;
|
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};
|
||||||
|
use iced::event::{self, Event};
|
||||||
use iced::{Alignment, Element, Length, Point, Rectangle, Size, Vector};
|
use iced::{Alignment, Element, Length, Point, Rectangle, Size, Vector};
|
||||||
use iced_native::widget::{Operation, Tree};
|
|
||||||
use iced_native::{event, layout, mouse, overlay, renderer};
|
|
||||||
use iced_native::{Clipboard, Event, Layout, Shell, Widget};
|
|
||||||
|
|
||||||
pub trait Toast {
|
pub trait Toast {
|
||||||
fn title(&self) -> &str;
|
fn title(&self) -> &str;
|
||||||
fn body(&self) -> &str;
|
fn body(&self) -> &str;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Manager<'a, Message, Renderer> {
|
pub struct Manager<'a, Message, Theme, Renderer> {
|
||||||
content: Element<'a, Message, Renderer>,
|
content: Element<'a, Message, Theme, Renderer>,
|
||||||
toasts: Vec<Element<'a, Message, 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
|
where
|
||||||
Message: 'a + Clone,
|
Message: 'a + Clone,
|
||||||
{
|
{
|
||||||
pub fn new(
|
pub fn new(
|
||||||
content: impl Into<Element<'a, Message, iced::Renderer<Theme>>>,
|
content: impl Into<Element<'a, Message, Theme, iced::Renderer>>,
|
||||||
toasts: Vec<Element<'a, Message, iced::Renderer<Theme>>>,
|
toasts: Vec<Element<'a, Message, Theme, iced::Renderer>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
content: content.into(),
|
content: content.into(),
|
||||||
@ -32,29 +31,33 @@ 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
|
where
|
||||||
Renderer: iced_native::Renderer,
|
Renderer: iced::advanced::Renderer,
|
||||||
{
|
{
|
||||||
fn width(&self) -> Length {
|
fn size(&self) -> Size<Length> {
|
||||||
self.content.as_widget().width()
|
self.content.as_widget().size()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn height(&self) -> Length {
|
fn layout(
|
||||||
self.content.as_widget().height()
|
&self,
|
||||||
|
tree: &mut Tree,
|
||||||
|
renderer: &Renderer,
|
||||||
|
limits: &layout::Limits,
|
||||||
|
) -> layout::Node {
|
||||||
|
self.content
|
||||||
|
.as_widget()
|
||||||
|
.layout(&mut tree.children[0], renderer, limits)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> layout::Node {
|
fn tag(&self) -> iced::advanced::widget::tree::Tag {
|
||||||
self.content.as_widget().layout(renderer, limits)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn tag(&self) -> iced_native::widget::tree::Tag {
|
|
||||||
struct Marker(Vec<Instant>);
|
struct Marker(Vec<Instant>);
|
||||||
iced_native::widget::tree::Tag::of::<Marker>()
|
iced::advanced::widget::tree::Tag::of::<Marker>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn state(&self) -> iced_native::widget::tree::State {
|
fn state(&self) -> iced::advanced::widget::tree::State {
|
||||||
iced_native::widget::tree::State::new(Vec::<Option<Instant>>::new())
|
iced::advanced::widget::tree::State::new(Vec::<Option<Instant>>::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn children(&self) -> Vec<Tree> {
|
fn children(&self) -> Vec<Tree> {
|
||||||
@ -95,7 +98,7 @@ where
|
|||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
operation: &mut dyn Operation<Message>,
|
operation: &mut dyn Operation<Message>,
|
||||||
) {
|
) {
|
||||||
operation.container(None, &mut |operation| {
|
operation.container(None, layout.bounds(), &mut |operation| {
|
||||||
self.content
|
self.content
|
||||||
.as_widget()
|
.as_widget()
|
||||||
.operate(&mut state.children[0], layout, renderer, operation);
|
.operate(&mut state.children[0], layout, renderer, operation);
|
||||||
@ -107,10 +110,11 @@ where
|
|||||||
state: &mut Tree,
|
state: &mut Tree,
|
||||||
event: Event,
|
event: Event,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor_position: Point,
|
cursor_position: iced::mouse::Cursor,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
|
viewport: &Rectangle,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
self.content.as_widget_mut().on_event(
|
self.content.as_widget_mut().on_event(
|
||||||
&mut state.children[0],
|
&mut state.children[0],
|
||||||
@ -120,6 +124,7 @@ where
|
|||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
shell,
|
shell,
|
||||||
|
viewport,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,10 +132,10 @@ where
|
|||||||
&self,
|
&self,
|
||||||
state: &Tree,
|
state: &Tree,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
theme: &<Renderer as iced_native::Renderer>::Theme,
|
theme: &Theme,
|
||||||
style: &renderer::Style,
|
style: &renderer::Style,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor_position: Point,
|
cursor_position: iced::mouse::Cursor,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
) {
|
) {
|
||||||
self.content.as_widget().draw(
|
self.content.as_widget().draw(
|
||||||
@ -148,7 +153,7 @@ where
|
|||||||
&self,
|
&self,
|
||||||
state: &Tree,
|
state: &Tree,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor_position: Point,
|
cursor_position: iced::mouse::Cursor,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
) -> mouse::Interaction {
|
) -> mouse::Interaction {
|
||||||
@ -166,25 +171,26 @@ where
|
|||||||
state: &'b mut Tree,
|
state: &'b mut Tree,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
renderer: &Renderer,
|
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 instants = state.state.downcast_mut::<Vec<Option<Instant>>>();
|
||||||
|
|
||||||
let (content_state, toasts_state) = state.children.split_at_mut(1);
|
let (content_state, toasts_state) = state.children.split_at_mut(1);
|
||||||
|
|
||||||
let content = self
|
let content = self.content.as_widget_mut().overlay(
|
||||||
.content
|
&mut content_state[0],
|
||||||
.as_widget_mut()
|
layout,
|
||||||
.overlay(&mut content_state[0], layout, renderer);
|
renderer,
|
||||||
|
translation,
|
||||||
|
);
|
||||||
|
|
||||||
let toasts = (!self.toasts.is_empty()).then(|| {
|
let toasts = (!self.toasts.is_empty()).then(|| {
|
||||||
overlay::Element::new(
|
overlay::Element::new(Box::new(Overlay {
|
||||||
layout.bounds().position(),
|
position: layout.bounds().position() + translation,
|
||||||
Box::new(Overlay {
|
toasts: &mut self.toasts,
|
||||||
toasts: &mut self.toasts,
|
state: toasts_state,
|
||||||
state: toasts_state,
|
instants,
|
||||||
instants,
|
}))
|
||||||
}),
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
let overlays = content.into_iter().chain(toasts).collect::<Vec<_>>();
|
let overlays = content.into_iter().chain(toasts).collect::<Vec<_>>();
|
||||||
|
|
||||||
@ -192,18 +198,19 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Overlay<'a, 'b, Message, Renderer> {
|
struct Overlay<'a, 'b, Message, Theme, Renderer> {
|
||||||
toasts: &'b mut [Element<'a, Message, Renderer>],
|
position: Point,
|
||||||
|
toasts: &'b mut [Element<'a, Message, Theme, Renderer>],
|
||||||
state: &'b mut [Tree],
|
state: &'b mut [Tree],
|
||||||
instants: &'b mut [Option<Instant>],
|
instants: &'b mut [Option<Instant>],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, Message, Renderer> overlay::Overlay<Message, Renderer>
|
impl<'a, 'b, Message, Theme, Renderer> overlay::Overlay<Message, Theme, Renderer>
|
||||||
for Overlay<'a, 'b, Message, Renderer>
|
for Overlay<'a, 'b, Message, Theme, Renderer>
|
||||||
where
|
where
|
||||||
Renderer: iced_native::Renderer,
|
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)
|
let limits = layout::Limits::new(Size::ZERO, bounds)
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.height(Length::Fill);
|
.height(Length::Fill);
|
||||||
@ -212,23 +219,27 @@ where
|
|||||||
layout::flex::Axis::Vertical,
|
layout::flex::Axis::Vertical,
|
||||||
renderer,
|
renderer,
|
||||||
&limits,
|
&limits,
|
||||||
|
Length::Fill,
|
||||||
|
Length::Fill,
|
||||||
10.into(),
|
10.into(),
|
||||||
10.0,
|
10.0,
|
||||||
Alignment::End,
|
Alignment::End,
|
||||||
self.toasts,
|
self.toasts,
|
||||||
|
self.state,
|
||||||
)
|
)
|
||||||
.translate(Vector::new(position.x, position.y))
|
.translate(Vector::new(self.position.x, self.position.y))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(
|
fn on_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: Event,
|
event: Event,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor_position: Point,
|
cursor_position: iced::mouse::Cursor,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
|
let viewport = layout.bounds();
|
||||||
self.toasts
|
self.toasts
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.zip(self.state.iter_mut())
|
.zip(self.state.iter_mut())
|
||||||
@ -246,6 +257,7 @@ where
|
|||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
&mut local_shell,
|
&mut local_shell,
|
||||||
|
&viewport,
|
||||||
);
|
);
|
||||||
|
|
||||||
if !local_shell.is_empty() {
|
if !local_shell.is_empty() {
|
||||||
@ -262,10 +274,10 @@ where
|
|||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
theme: &<Renderer as iced_native::Renderer>::Theme,
|
theme: &Theme,
|
||||||
style: &renderer::Style,
|
style: &renderer::Style,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor_position: Point,
|
cursor_position: iced::mouse::Cursor,
|
||||||
) {
|
) {
|
||||||
let viewport = layout.bounds();
|
let viewport = layout.bounds();
|
||||||
|
|
||||||
@ -291,9 +303,9 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
operation: &mut dyn iced_native::widget::Operation<Message>,
|
operation: &mut dyn iced::advanced::widget::Operation<Message>,
|
||||||
) {
|
) {
|
||||||
operation.container(None, &mut |operation| {
|
operation.container(None, layout.bounds(), &mut |operation| {
|
||||||
self.toasts
|
self.toasts
|
||||||
.iter()
|
.iter()
|
||||||
.zip(self.state.iter_mut())
|
.zip(self.state.iter_mut())
|
||||||
@ -309,7 +321,7 @@ where
|
|||||||
fn mouse_interaction(
|
fn mouse_interaction(
|
||||||
&self,
|
&self,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor_position: Point,
|
cursor_position: iced::mouse::Cursor,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
renderer: &Renderer,
|
renderer: &Renderer,
|
||||||
) -> mouse::Interaction {
|
) -> mouse::Interaction {
|
||||||
@ -330,19 +342,21 @@ where
|
|||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_over(&self, layout: Layout<'_>, cursor_position: Point) -> bool {
|
fn is_over(&self, layout: Layout<'_>, _renderer: &Renderer, cursor_position: Point) -> bool {
|
||||||
layout
|
layout
|
||||||
.children()
|
.children()
|
||||||
.any(|layout| layout.bounds().contains(cursor_position))
|
.any(|layout| layout.bounds().contains(cursor_position))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
where
|
||||||
Renderer: 'a + iced_native::Renderer,
|
Renderer: 'a + iced::advanced::Renderer,
|
||||||
Message: 'a,
|
Message: 'a,
|
||||||
|
Theme: 'a,
|
||||||
{
|
{
|
||||||
fn from(manager: Manager<'a, Message, Renderer>) -> Self {
|
fn from(manager: Manager<'a, Message, Theme, Renderer>) -> Self {
|
||||||
Element::new(manager)
|
Element::new(manager)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +1,37 @@
|
|||||||
use iced::Font;
|
use iced::{
|
||||||
|
font::{Family, Stretch, Weight},
|
||||||
pub const BOLD: Font = Font::External {
|
Command, Font,
|
||||||
name: "Bold",
|
|
||||||
bytes: include_bytes!("../static/fonts/IBMPlexSans-Bold.ttf"),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const MEDIUM: Font = Font::External {
|
pub const BOLD: Font = Font {
|
||||||
name: "Regular",
|
family: Family::Name("IBM Plex Sans"),
|
||||||
bytes: include_bytes!("../static/fonts/IBMPlexSans-Medium.ttf"),
|
weight: Weight::Bold,
|
||||||
|
style: iced::font::Style::Normal,
|
||||||
|
stretch: Stretch::Normal,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const MEDIUM: Font = Font {
|
||||||
|
family: Family::Name("IBM Plex Sans"),
|
||||||
|
weight: Weight::Medium,
|
||||||
|
style: iced::font::Style::Normal,
|
||||||
|
stretch: Stretch::Normal,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const REGULAR: Font = Font::with_name("IBM Plex Sans");
|
||||||
|
|
||||||
|
pub const BOLD_BYTES: &[u8] = include_bytes!("../static/fonts/IBMPlexSans-Bold.ttf");
|
||||||
|
pub const MEDIUM_BYTES: &[u8] = include_bytes!("../static/fonts/IBMPlexSans-Medium.ttf");
|
||||||
pub const REGULAR_BYTES: &[u8] = include_bytes!("../static/fonts/IBMPlexSans-Regular.ttf");
|
pub const REGULAR_BYTES: &[u8] = include_bytes!("../static/fonts/IBMPlexSans-Regular.ttf");
|
||||||
|
|
||||||
pub const REGULAR: Font = Font::External {
|
pub const ICONEX_ICONS_BYTES: &[u8] = include_bytes!("../static/icons/iconex/iconex-icons.ttf");
|
||||||
name: "Regular",
|
pub const BOOTSTRAP_ICONS_BYTE: &[u8] = include_bytes!("../static/icons/bootstrap-icons.ttf");
|
||||||
bytes: REGULAR_BYTES,
|
|
||||||
};
|
pub fn loads<T: From<Result<(), iced::font::Error>> + 'static>() -> Vec<Command<T>> {
|
||||||
|
vec![
|
||||||
|
iced::font::load(BOLD_BYTES).map(T::from),
|
||||||
|
iced::font::load(MEDIUM_BYTES).map(T::from),
|
||||||
|
iced::font::load(REGULAR_BYTES).map(T::from),
|
||||||
|
iced::font::load(ICONEX_ICONS_BYTES).map(T::from),
|
||||||
|
iced::font::load(BOOTSTRAP_ICONS_BYTE).map(T::from),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@ -1,10 +1,7 @@
|
|||||||
use crate::{component::text::P1_SIZE, widget::*};
|
use crate::{component::text::P1_SIZE, widget::*};
|
||||||
use iced::{alignment, Font, Length};
|
use iced::{alignment, Font, Length};
|
||||||
|
|
||||||
const BOOTSTRAP_ICONS: Font = Font::External {
|
const BOOTSTRAP_ICONS: Font = Font::with_name("bootstrap-icons");
|
||||||
name: "Bootstrap icons",
|
|
||||||
bytes: include_bytes!("../static/icons/bootstrap-icons.ttf"),
|
|
||||||
};
|
|
||||||
|
|
||||||
fn bootstrap_icon(unicode: char) -> Text<'static> {
|
fn bootstrap_icon(unicode: char) -> Text<'static> {
|
||||||
Text::new(unicode.to_string())
|
Text::new(unicode.to_string())
|
||||||
@ -118,10 +115,7 @@ pub fn previous_icon() -> Text<'static> {
|
|||||||
bootstrap_icon('\u{F284}')
|
bootstrap_icon('\u{F284}')
|
||||||
}
|
}
|
||||||
|
|
||||||
const ICONEX_ICONS: Font = Font::External {
|
const ICONEX_ICONS: Font = Font::with_name("Untitled1");
|
||||||
name: "Iconex icons",
|
|
||||||
bytes: include_bytes!("../static/icons/iconex/iconex-icons.ttf"),
|
|
||||||
};
|
|
||||||
|
|
||||||
fn iconex_icon(unicode: char) -> Text<'static> {
|
fn iconex_icon(unicode: char) -> Text<'static> {
|
||||||
Text::new(unicode.to_string())
|
Text::new(unicode.to_string())
|
||||||
|
|||||||
@ -4,22 +4,24 @@ pub mod font;
|
|||||||
pub mod icon;
|
pub mod icon;
|
||||||
pub mod image;
|
pub mod image;
|
||||||
pub mod theme;
|
pub mod theme;
|
||||||
pub mod util;
|
|
||||||
|
|
||||||
pub mod widget {
|
pub mod widget {
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use crate::theme::Theme;
|
use crate::theme::Theme;
|
||||||
|
|
||||||
pub type Renderer = iced::Renderer<Theme>;
|
pub type Renderer = iced::Renderer;
|
||||||
pub type Element<'a, Message> = iced::Element<'a, Message, Renderer>;
|
pub type Element<'a, Message> = iced::Element<'a, Message, Theme, Renderer>;
|
||||||
pub type Container<'a, Message> = iced::widget::Container<'a, Message, Renderer>;
|
pub type Container<'a, Message> = iced::widget::Container<'a, Message, Theme, Renderer>;
|
||||||
pub type Column<'a, Message> = iced::widget::Column<'a, Message, Renderer>;
|
pub type Column<'a, Message> = iced::widget::Column<'a, Message, Theme, Renderer>;
|
||||||
pub type Row<'a, Message> = iced::widget::Row<'a, Message, Renderer>;
|
pub type Row<'a, Message> = iced::widget::Row<'a, Message, Theme, Renderer>;
|
||||||
pub type Button<'a, Message> = iced::widget::Button<'a, Message, Renderer>;
|
pub type Button<'a, Message> = iced::widget::Button<'a, Message, Theme, Renderer>;
|
||||||
pub type Text<'a> = iced::widget::Text<'a, Renderer>;
|
pub type CheckBox<'a, Message> = iced::widget::Checkbox<'a, Message, Theme, Renderer>;
|
||||||
pub type Tooltip<'a> = iced::widget::Tooltip<'a, Renderer>;
|
pub type Text<'a> = iced::widget::Text<'a, Theme, Renderer>;
|
||||||
pub type ProgressBar = iced::widget::ProgressBar<Renderer>;
|
pub type TextInput<'a, Message> = iced::widget::TextInput<'a, Message, Theme, Renderer>;
|
||||||
pub type PickList<'a, Message> = iced::widget::PickList<'a, Message, Renderer>;
|
pub type Tooltip<'a> = iced::widget::Tooltip<'a, Theme, Renderer>;
|
||||||
pub type Scrollable<'a, Message> = iced::widget::Scrollable<'a, Message, Renderer>;
|
pub type ProgressBar = iced::widget::ProgressBar<Theme>;
|
||||||
pub type Svg = iced::widget::Svg<Renderer>;
|
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::{
|
use iced::{
|
||||||
application,
|
application,
|
||||||
widget::{
|
widget::{
|
||||||
button, checkbox, container, pick_list, progress_bar, radio, scrollable, slider, svg, text,
|
button, checkbox, container, pick_list, progress_bar, qr_code, radio, scrollable, slider,
|
||||||
text_input,
|
svg, text, text_input,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -44,9 +44,11 @@ impl iced::overlay::menu::StyleSheet for Theme {
|
|||||||
iced::overlay::menu::Appearance {
|
iced::overlay::menu::Appearance {
|
||||||
text_color: color::GREY_2,
|
text_color: color::GREY_2,
|
||||||
background: color::GREY_6.into(),
|
background: color::GREY_6.into(),
|
||||||
border_width: 0.0,
|
border: iced::Border {
|
||||||
border_radius: 25.0,
|
color: color::GREY_2,
|
||||||
border_color: color::GREY_2,
|
width: 0.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
selected_text_color: color::LIGHT_BLACK,
|
selected_text_color: color::LIGHT_BLACK,
|
||||||
selected_background: color::GREEN.into(),
|
selected_background: color::GREEN.into(),
|
||||||
}
|
}
|
||||||
@ -103,21 +105,24 @@ impl container::StyleSheet for Theme {
|
|||||||
match self {
|
match self {
|
||||||
Theme::Light => match style {
|
Theme::Light => match style {
|
||||||
Container::Transparent => container::Appearance {
|
Container::Transparent => container::Appearance {
|
||||||
background: iced::Color::TRANSPARENT.into(),
|
background: Some(iced::Color::TRANSPARENT.into()),
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Container::Background => container::Appearance {
|
Container::Background => container::Appearance {
|
||||||
background: color::GREY_2.into(),
|
background: Some(color::GREY_2.into()),
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Container::Foreground => container::Appearance {
|
Container::Foreground => container::Appearance {
|
||||||
background: color::GREY_2.into(),
|
background: Some(color::GREY_2.into()),
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Container::Border => container::Appearance {
|
Container::Border => container::Appearance {
|
||||||
background: iced::Color::TRANSPARENT.into(),
|
background: Some(iced::Color::TRANSPARENT.into()),
|
||||||
border_width: 1.0,
|
border: iced::Border {
|
||||||
border_color: color::LIGHT_BLACK,
|
color: color::LIGHT_BLACK,
|
||||||
|
width: 1.0,
|
||||||
|
radius: 0.0.into(),
|
||||||
|
},
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Container::Card(c) => c.appearance(self),
|
Container::Card(c) => c.appearance(self),
|
||||||
@ -125,32 +130,39 @@ impl container::StyleSheet for Theme {
|
|||||||
Container::Pill(c) => c.appearance(self),
|
Container::Pill(c) => c.appearance(self),
|
||||||
Container::Notification(c) => c.appearance(self),
|
Container::Notification(c) => c.appearance(self),
|
||||||
Container::Custom(c) => container::Appearance {
|
Container::Custom(c) => container::Appearance {
|
||||||
background: (*c).into(),
|
background: Some((*c).into()),
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Container::QrCode => container::Appearance {
|
Container::QrCode => container::Appearance {
|
||||||
background: color::WHITE.into(),
|
background: Some(color::WHITE.into()),
|
||||||
border_radius: 25.0,
|
border: iced::Border {
|
||||||
|
color: color::TRANSPARENT,
|
||||||
|
width: 0.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Theme::Dark => match style {
|
Theme::Dark => match style {
|
||||||
Container::Transparent => container::Appearance {
|
Container::Transparent => container::Appearance {
|
||||||
background: iced::Color::TRANSPARENT.into(),
|
background: Some(iced::Color::TRANSPARENT.into()),
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Container::Background => container::Appearance {
|
Container::Background => container::Appearance {
|
||||||
background: color::LIGHT_BLACK.into(),
|
background: Some(color::LIGHT_BLACK.into()),
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Container::Foreground => container::Appearance {
|
Container::Foreground => container::Appearance {
|
||||||
background: color::BLACK.into(),
|
background: Some(color::BLACK.into()),
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Container::Border => container::Appearance {
|
Container::Border => container::Appearance {
|
||||||
background: iced::Color::TRANSPARENT.into(),
|
background: Some(iced::Color::TRANSPARENT.into()),
|
||||||
border_width: 1.0,
|
border: iced::Border {
|
||||||
border_color: color::GREY_3,
|
color: color::GREY_3,
|
||||||
|
width: 1.0,
|
||||||
|
radius: 0.0.into(),
|
||||||
|
},
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Container::Card(c) => c.appearance(self),
|
Container::Card(c) => c.appearance(self),
|
||||||
@ -158,12 +170,16 @@ impl container::StyleSheet for Theme {
|
|||||||
Container::Pill(c) => c.appearance(self),
|
Container::Pill(c) => c.appearance(self),
|
||||||
Container::Notification(c) => c.appearance(self),
|
Container::Notification(c) => c.appearance(self),
|
||||||
Container::Custom(c) => container::Appearance {
|
Container::Custom(c) => container::Appearance {
|
||||||
background: (*c).into(),
|
background: Some((*c).into()),
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Container::QrCode => container::Appearance {
|
Container::QrCode => container::Appearance {
|
||||||
background: color::WHITE.into(),
|
background: Some(color::WHITE.into()),
|
||||||
border_radius: 25.0,
|
border: iced::Border {
|
||||||
|
color: color::TRANSPARENT,
|
||||||
|
width: 0.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -201,34 +217,46 @@ impl Notification {
|
|||||||
match theme {
|
match theme {
|
||||||
Theme::Light => match self {
|
Theme::Light => match self {
|
||||||
Self::Pending => container::Appearance {
|
Self::Pending => container::Appearance {
|
||||||
background: color::GREEN.into(),
|
background: Some(iced::Background::Color(color::GREEN)),
|
||||||
text_color: color::LIGHT_BLACK.into(),
|
text_color: color::LIGHT_BLACK.into(),
|
||||||
border_width: 1.0,
|
border: iced::Border {
|
||||||
border_color: color::GREEN,
|
color: color::GREEN,
|
||||||
border_radius: 25.0,
|
width: 1.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Self::Error => container::Appearance {
|
Self::Error => container::Appearance {
|
||||||
background: color::ORANGE.into(),
|
background: Some(iced::Background::Color(color::ORANGE)),
|
||||||
text_color: color::LIGHT_BLACK.into(),
|
text_color: color::LIGHT_BLACK.into(),
|
||||||
border_width: 1.0,
|
border: iced::Border {
|
||||||
border_color: color::ORANGE,
|
color: color::ORANGE,
|
||||||
border_radius: 25.0,
|
width: 1.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Theme::Dark => match self {
|
Theme::Dark => match self {
|
||||||
Self::Pending => container::Appearance {
|
Self::Pending => container::Appearance {
|
||||||
background: color::GREEN.into(),
|
background: Some(iced::Background::Color(color::GREEN)),
|
||||||
text_color: color::LIGHT_BLACK.into(),
|
text_color: color::LIGHT_BLACK.into(),
|
||||||
border_width: 1.0,
|
border: iced::Border {
|
||||||
border_color: color::GREEN,
|
color: color::GREEN,
|
||||||
border_radius: 25.0,
|
width: 1.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Self::Error => container::Appearance {
|
Self::Error => container::Appearance {
|
||||||
background: color::ORANGE.into(),
|
background: Some(iced::Background::Color(color::ORANGE)),
|
||||||
text_color: color::LIGHT_BLACK.into(),
|
text_color: color::LIGHT_BLACK.into(),
|
||||||
border_width: 1.0,
|
border: iced::Border {
|
||||||
border_color: color::ORANGE,
|
color: color::ORANGE,
|
||||||
border_radius: 25.0,
|
width: 1.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -250,65 +278,85 @@ impl Card {
|
|||||||
match theme {
|
match theme {
|
||||||
Theme::Light => match self {
|
Theme::Light => match self {
|
||||||
Card::Simple => container::Appearance {
|
Card::Simple => container::Appearance {
|
||||||
background: color::GREY_2.into(),
|
background: Some(color::GREY_2.into()),
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Card::Border => container::Appearance {
|
Card::Border => container::Appearance {
|
||||||
background: iced::Color::TRANSPARENT.into(),
|
background: Some(iced::Color::TRANSPARENT.into()),
|
||||||
border_radius: 10.0,
|
border: iced::Border {
|
||||||
border_color: color::GREY_2,
|
color: color::GREY_2,
|
||||||
border_width: 1.0,
|
width: 1.0,
|
||||||
|
radius: 10.0.into(),
|
||||||
|
},
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Card::Invalid => container::Appearance {
|
Card::Invalid => container::Appearance {
|
||||||
background: color::GREY_2.into(),
|
background: Some(color::GREY_2.into()),
|
||||||
text_color: color::BLACK.into(),
|
text_color: color::BLACK.into(),
|
||||||
border_width: 1.0,
|
border: iced::Border {
|
||||||
border_color: color::RED,
|
color: color::RED,
|
||||||
|
width: 1.0,
|
||||||
|
radius: 0.0.into(),
|
||||||
|
},
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Card::Error => container::Appearance {
|
Card::Error => container::Appearance {
|
||||||
background: color::GREY_2.into(),
|
background: Some(color::GREY_2.into()),
|
||||||
text_color: color::RED.into(),
|
text_color: color::RED.into(),
|
||||||
border_width: 1.0,
|
border: iced::Border {
|
||||||
border_color: color::RED,
|
color: color::RED,
|
||||||
|
width: 1.0,
|
||||||
|
radius: 0.0.into(),
|
||||||
|
},
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Card::Warning => container::Appearance {
|
Card::Warning => container::Appearance {
|
||||||
background: color::ORANGE.into(),
|
background: Some(color::ORANGE.into()),
|
||||||
text_color: color::GREY_2.into(),
|
text_color: color::GREY_2.into(),
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Theme::Dark => match self {
|
Theme::Dark => match self {
|
||||||
Card::Simple => container::Appearance {
|
Card::Simple => container::Appearance {
|
||||||
background: color::GREY_6.into(),
|
background: Some(color::GREY_6.into()),
|
||||||
border_radius: 25.0,
|
border: iced::Border {
|
||||||
|
color: color::TRANSPARENT,
|
||||||
|
width: 0.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Card::Border => container::Appearance {
|
Card::Border => container::Appearance {
|
||||||
background: iced::Color::TRANSPARENT.into(),
|
background: Some(iced::Color::TRANSPARENT.into()),
|
||||||
border_radius: 25.0,
|
border: iced::Border {
|
||||||
border_color: color::GREY_5,
|
color: color::GREY_5,
|
||||||
border_width: 1.0,
|
width: 1.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Card::Invalid => container::Appearance {
|
Card::Invalid => container::Appearance {
|
||||||
background: color::LIGHT_BLACK.into(),
|
background: Some(color::LIGHT_BLACK.into()),
|
||||||
text_color: color::RED.into(),
|
text_color: color::RED.into(),
|
||||||
border_width: 1.0,
|
border: iced::Border {
|
||||||
border_radius: 25.0,
|
color: color::RED,
|
||||||
border_color: color::RED,
|
width: 1.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Card::Error => container::Appearance {
|
Card::Error => container::Appearance {
|
||||||
background: color::LIGHT_BLACK.into(),
|
background: Some(color::LIGHT_BLACK.into()),
|
||||||
text_color: color::RED.into(),
|
text_color: color::RED.into(),
|
||||||
border_width: 1.0,
|
border: iced::Border {
|
||||||
border_color: color::RED,
|
color: color::RED,
|
||||||
|
width: 1.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Card::Warning => container::Appearance {
|
Card::Warning => container::Appearance {
|
||||||
background: color::ORANGE.into(),
|
background: Some(color::ORANGE.into()),
|
||||||
text_color: color::LIGHT_BLACK.into(),
|
text_color: color::LIGHT_BLACK.into(),
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
@ -328,13 +376,21 @@ impl Badge {
|
|||||||
fn appearance(&self, _theme: &Theme) -> iced::widget::container::Appearance {
|
fn appearance(&self, _theme: &Theme) -> iced::widget::container::Appearance {
|
||||||
match self {
|
match self {
|
||||||
Self::Standard => container::Appearance {
|
Self::Standard => container::Appearance {
|
||||||
border_radius: 40.0,
|
border: iced::Border {
|
||||||
background: color::GREY_4.into(),
|
color: color::TRANSPARENT,
|
||||||
|
width: 0.0,
|
||||||
|
radius: 40.0.into(),
|
||||||
|
},
|
||||||
|
background: Some(color::GREY_4.into()),
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Self::Bitcoin => container::Appearance {
|
Self::Bitcoin => container::Appearance {
|
||||||
border_radius: 40.0,
|
border: iced::Border {
|
||||||
background: color::ORANGE.into(),
|
color: color::TRANSPARENT,
|
||||||
|
width: 0.0,
|
||||||
|
radius: 40.0.into(),
|
||||||
|
},
|
||||||
|
background: Some(color::ORANGE.into()),
|
||||||
text_color: iced::Color::WHITE.into(),
|
text_color: iced::Color::WHITE.into(),
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
@ -355,30 +411,44 @@ impl Pill {
|
|||||||
fn appearance(&self, _theme: &Theme) -> iced::widget::container::Appearance {
|
fn appearance(&self, _theme: &Theme) -> iced::widget::container::Appearance {
|
||||||
match self {
|
match self {
|
||||||
Self::Primary => container::Appearance {
|
Self::Primary => container::Appearance {
|
||||||
background: color::GREEN.into(),
|
background: Some(color::GREEN.into()),
|
||||||
border_radius: 25.0,
|
border: iced::Border {
|
||||||
|
color: color::TRANSPARENT,
|
||||||
|
width: 0.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
text_color: color::LIGHT_BLACK.into(),
|
text_color: color::LIGHT_BLACK.into(),
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Self::Success => container::Appearance {
|
Self::Success => container::Appearance {
|
||||||
background: color::GREEN.into(),
|
background: Some(color::GREEN.into()),
|
||||||
border_radius: 25.0,
|
border: iced::Border {
|
||||||
|
color: color::TRANSPARENT,
|
||||||
|
width: 0.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
text_color: color::LIGHT_BLACK.into(),
|
text_color: color::LIGHT_BLACK.into(),
|
||||||
..container::Appearance::default()
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Self::Simple => container::Appearance {
|
Self::Simple => container::Appearance {
|
||||||
background: iced::Color::TRANSPARENT.into(),
|
background: Some(iced::Color::TRANSPARENT.into()),
|
||||||
border_radius: 25.0,
|
border: iced::Border {
|
||||||
border_width: 1.0,
|
color: color::GREY_3,
|
||||||
border_color: color::GREY_3,
|
width: 1.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
text_color: color::GREY_3.into(),
|
text_color: color::GREY_3.into(),
|
||||||
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
Self::Warning => container::Appearance {
|
Self::Warning => container::Appearance {
|
||||||
background: iced::Color::TRANSPARENT.into(),
|
background: Some(iced::Color::TRANSPARENT.into()),
|
||||||
border_radius: 25.0,
|
border: iced::Border {
|
||||||
border_width: 1.0,
|
color: color::RED,
|
||||||
border_color: color::RED,
|
width: 1.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
text_color: color::RED.into(),
|
text_color: color::RED.into(),
|
||||||
|
..container::Appearance::default()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -415,24 +485,32 @@ pub struct Scrollable {}
|
|||||||
impl scrollable::StyleSheet for Theme {
|
impl scrollable::StyleSheet for Theme {
|
||||||
type Style = Scrollable;
|
type Style = Scrollable;
|
||||||
|
|
||||||
fn active(&self, _style: &Self::Style) -> scrollable::Scrollbar {
|
fn active(&self, _style: &Self::Style) -> scrollable::Appearance {
|
||||||
scrollable::Scrollbar {
|
scrollable::Appearance {
|
||||||
background: None,
|
gap: None,
|
||||||
border_width: 0.0,
|
container: container::Appearance::default(),
|
||||||
border_color: color::GREY_7,
|
scrollbar: scrollable::Scrollbar {
|
||||||
border_radius: 10.0,
|
background: None,
|
||||||
scroller: scrollable::Scroller {
|
border: iced::Border {
|
||||||
color: color::GREY_7,
|
color: color::GREY_3,
|
||||||
border_radius: 10.0,
|
width: 0.0,
|
||||||
border_width: 0.0,
|
radius: 10.0.into(),
|
||||||
border_color: iced::Color::TRANSPARENT,
|
},
|
||||||
|
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);
|
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,
|
placeholder_color: color::GREY_6,
|
||||||
handle_color: color::GREY_6,
|
handle_color: color::GREY_6,
|
||||||
background: color::GREEN.into(),
|
background: color::GREEN.into(),
|
||||||
border_width: 1.0,
|
border: iced::Border {
|
||||||
border_color: color::GREY_7,
|
color: color::GREY_7,
|
||||||
border_radius: 25.0,
|
width: 1.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
text_color: iced::Color::BLACK,
|
text_color: iced::Color::BLACK,
|
||||||
},
|
},
|
||||||
PickList::Invalid => pick_list::Appearance {
|
PickList::Invalid => pick_list::Appearance {
|
||||||
placeholder_color: color::GREY_6,
|
placeholder_color: color::GREY_6,
|
||||||
handle_color: color::GREY_6,
|
handle_color: color::GREY_6,
|
||||||
background: color::GREY_6.into(),
|
background: color::GREY_6.into(),
|
||||||
border_width: 1.0,
|
border: iced::Border {
|
||||||
border_color: color::RED,
|
color: color::RED,
|
||||||
border_radius: 25.0,
|
width: 1.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
text_color: color::RED,
|
text_color: color::RED,
|
||||||
},
|
},
|
||||||
PickList::Secondary => pick_list::Appearance {
|
PickList::Secondary => pick_list::Appearance {
|
||||||
placeholder_color: color::GREY_3,
|
placeholder_color: color::GREY_6,
|
||||||
handle_color: color::GREY_3,
|
handle_color: color::GREY_6,
|
||||||
background: color::TRANSPARENT.into(),
|
background: color::GREY_6.into(),
|
||||||
border_width: 1.0,
|
border: iced::Border {
|
||||||
border_color: color::GREY_3,
|
color: color::GREY_7,
|
||||||
border_radius: 25.0,
|
width: 1.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
text_color: color::GREY_2,
|
text_color: color::GREY_2,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -493,20 +577,24 @@ impl checkbox::StyleSheet for Theme {
|
|||||||
if is_selected {
|
if is_selected {
|
||||||
checkbox::Appearance {
|
checkbox::Appearance {
|
||||||
background: color::GREEN.into(),
|
background: color::GREEN.into(),
|
||||||
border_width: 0.0,
|
|
||||||
border_color: iced::Color::TRANSPARENT,
|
|
||||||
icon_color: color::GREY_4,
|
icon_color: color::GREY_4,
|
||||||
text_color: None,
|
text_color: None,
|
||||||
border_radius: 4.0,
|
border: iced::Border {
|
||||||
|
color: color::TRANSPARENT,
|
||||||
|
width: 1.0,
|
||||||
|
radius: 4.0.into(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
checkbox::Appearance {
|
checkbox::Appearance {
|
||||||
background: color::GREY_4.into(),
|
background: color::GREY_4.into(),
|
||||||
border_width: 0.0,
|
|
||||||
border_color: iced::Color::TRANSPARENT,
|
|
||||||
icon_color: color::GREEN,
|
icon_color: color::GREEN,
|
||||||
text_color: None,
|
text_color: None,
|
||||||
border_radius: 4.0,
|
border: iced::Border {
|
||||||
|
color: color::TRANSPARENT,
|
||||||
|
width: 0.0,
|
||||||
|
radius: 4.0.into(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -538,64 +626,85 @@ impl button::StyleSheet for Theme {
|
|||||||
Theme::Dark => match style {
|
Theme::Dark => match style {
|
||||||
Button::Primary => button::Appearance {
|
Button::Primary => button::Appearance {
|
||||||
shadow_offset: iced::Vector::default(),
|
shadow_offset: iced::Vector::default(),
|
||||||
background: iced::Color::TRANSPARENT.into(),
|
background: Some(iced::Color::TRANSPARENT.into()),
|
||||||
border_radius: 25.0,
|
|
||||||
border_width: 1.0,
|
|
||||||
border_color: color::GREY_7,
|
|
||||||
text_color: color::GREY_2,
|
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::Secondary | Button::SecondaryDestructive | Button::Border => {
|
||||||
button::Appearance {
|
button::Appearance {
|
||||||
shadow_offset: iced::Vector::default(),
|
shadow_offset: iced::Vector::default(),
|
||||||
background: iced::Color::TRANSPARENT.into(),
|
background: Some(iced::Color::TRANSPARENT.into()),
|
||||||
border_radius: 25.0,
|
|
||||||
border_width: 1.0,
|
|
||||||
border_color: color::GREY_7,
|
|
||||||
text_color: color::GREY_2,
|
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 {
|
Button::Destructive => button::Appearance {
|
||||||
shadow_offset: iced::Vector::default(),
|
shadow_offset: iced::Vector::default(),
|
||||||
background: iced::Color::TRANSPARENT.into(),
|
background: Some(iced::Color::TRANSPARENT.into()),
|
||||||
border_radius: 25.0,
|
|
||||||
border_width: 1.0,
|
|
||||||
border_color: color::RED,
|
|
||||||
text_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 {
|
Button::Transparent => button::Appearance {
|
||||||
shadow_offset: iced::Vector::default(),
|
shadow_offset: iced::Vector::default(),
|
||||||
background: iced::Color::TRANSPARENT.into(),
|
background: Some(iced::Color::TRANSPARENT.into()),
|
||||||
border_radius: 25.0,
|
|
||||||
border_width: 0.0,
|
|
||||||
border_color: iced::Color::TRANSPARENT,
|
|
||||||
text_color: color::GREY_2,
|
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 {
|
Button::TransparentBorder => button::Appearance {
|
||||||
shadow_offset: iced::Vector::default(),
|
shadow_offset: iced::Vector::default(),
|
||||||
background: iced::Color::TRANSPARENT.into(),
|
background: Some(iced::Color::TRANSPARENT.into()),
|
||||||
border_radius: 25.0,
|
|
||||||
border_width: 0.0,
|
|
||||||
border_color: iced::Color::TRANSPARENT,
|
|
||||||
text_color: color::WHITE,
|
text_color: color::WHITE,
|
||||||
|
border: iced::Border {
|
||||||
|
color: color::TRANSPARENT,
|
||||||
|
width: 0.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
|
..button::Appearance::default()
|
||||||
},
|
},
|
||||||
Button::Menu(active) => {
|
Button::Menu(active) => {
|
||||||
if *active {
|
if *active {
|
||||||
button::Appearance {
|
button::Appearance {
|
||||||
shadow_offset: iced::Vector::default(),
|
shadow_offset: iced::Vector::default(),
|
||||||
background: color::LIGHT_BLACK.into(),
|
background: Some(color::LIGHT_BLACK.into()),
|
||||||
border_radius: 25.0,
|
|
||||||
border_width: 0.0,
|
|
||||||
border_color: iced::Color::TRANSPARENT,
|
|
||||||
text_color: color::WHITE,
|
text_color: color::WHITE,
|
||||||
|
border: iced::Border {
|
||||||
|
color: color::TRANSPARENT,
|
||||||
|
width: 0.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
|
..button::Appearance::default()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
button::Appearance {
|
button::Appearance {
|
||||||
shadow_offset: iced::Vector::default(),
|
shadow_offset: iced::Vector::default(),
|
||||||
background: iced::Color::TRANSPARENT.into(),
|
background: Some(iced::Color::TRANSPARENT.into()),
|
||||||
border_radius: 25.0,
|
|
||||||
border_width: 0.0,
|
|
||||||
border_color: iced::Color::TRANSPARENT,
|
|
||||||
text_color: color::WHITE,
|
text_color: color::WHITE,
|
||||||
|
border: iced::Border {
|
||||||
|
color: color::TRANSPARENT,
|
||||||
|
width: 0.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
|
..button::Appearance::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -609,51 +718,69 @@ impl button::StyleSheet for Theme {
|
|||||||
Theme::Dark => match style {
|
Theme::Dark => match style {
|
||||||
Button::Primary => button::Appearance {
|
Button::Primary => button::Appearance {
|
||||||
shadow_offset: iced::Vector::default(),
|
shadow_offset: iced::Vector::default(),
|
||||||
background: color::GREEN.into(),
|
background: Some(color::GREEN.into()),
|
||||||
border_radius: 25.0,
|
|
||||||
border_width: 0.0,
|
|
||||||
border_color: iced::Color::TRANSPARENT,
|
|
||||||
text_color: color::LIGHT_BLACK,
|
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 {
|
Button::Secondary => button::Appearance {
|
||||||
shadow_offset: iced::Vector::default(),
|
shadow_offset: iced::Vector::default(),
|
||||||
background: color::GREEN.into(),
|
background: Some(color::GREEN.into()),
|
||||||
border_radius: 25.0,
|
|
||||||
border_width: 0.0,
|
|
||||||
border_color: iced::Color::TRANSPARENT,
|
|
||||||
text_color: color::LIGHT_BLACK,
|
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 {
|
Button::Destructive | Button::SecondaryDestructive => button::Appearance {
|
||||||
shadow_offset: iced::Vector::default(),
|
shadow_offset: iced::Vector::default(),
|
||||||
background: color::RED.into(),
|
background: Some(color::RED.into()),
|
||||||
border_radius: 25.0,
|
|
||||||
border_width: 0.0,
|
|
||||||
border_color: iced::Color::TRANSPARENT,
|
|
||||||
text_color: color::LIGHT_BLACK,
|
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 {
|
Button::Transparent => button::Appearance {
|
||||||
shadow_offset: iced::Vector::default(),
|
shadow_offset: iced::Vector::default(),
|
||||||
background: iced::Color::TRANSPARENT.into(),
|
background: Some(iced::Color::TRANSPARENT.into()),
|
||||||
border_radius: 25.0,
|
|
||||||
border_width: 0.0,
|
|
||||||
border_color: iced::Color::TRANSPARENT,
|
|
||||||
text_color: color::GREY_2,
|
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 {
|
Button::TransparentBorder | Button::Border => button::Appearance {
|
||||||
shadow_offset: iced::Vector::default(),
|
shadow_offset: iced::Vector::default(),
|
||||||
background: iced::Color::TRANSPARENT.into(),
|
background: Some(iced::Color::TRANSPARENT.into()),
|
||||||
border_radius: 25.0,
|
|
||||||
border_width: 1.0,
|
|
||||||
border_color: color::GREEN,
|
|
||||||
text_color: color::WHITE,
|
text_color: color::WHITE,
|
||||||
|
border: iced::Border {
|
||||||
|
color: color::GREEN,
|
||||||
|
width: 1.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
|
..button::Appearance::default()
|
||||||
},
|
},
|
||||||
Button::Menu(_) => button::Appearance {
|
Button::Menu(_) => button::Appearance {
|
||||||
shadow_offset: iced::Vector::default(),
|
shadow_offset: iced::Vector::default(),
|
||||||
background: color::LIGHT_BLACK.into(),
|
background: Some(color::LIGHT_BLACK.into()),
|
||||||
border_radius: 25.0,
|
|
||||||
border_width: 0.0,
|
|
||||||
border_color: iced::Color::TRANSPARENT,
|
|
||||||
text_color: color::WHITE,
|
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 {
|
Form::Simple => text_input::Appearance {
|
||||||
icon_color: color::GREY_7,
|
icon_color: color::GREY_7,
|
||||||
background: iced::Background::Color(iced::Color::TRANSPARENT),
|
background: iced::Background::Color(iced::Color::TRANSPARENT),
|
||||||
border_radius: 25.0,
|
border: iced::Border {
|
||||||
border_width: 1.0,
|
color: color::GREY_7,
|
||||||
border_color: color::GREY_7,
|
width: 1.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Form::Invalid => text_input::Appearance {
|
Form::Invalid => text_input::Appearance {
|
||||||
icon_color: color::GREY_7,
|
icon_color: color::GREY_7,
|
||||||
background: iced::Background::Color(iced::Color::TRANSPARENT),
|
background: iced::Background::Color(iced::Color::TRANSPARENT),
|
||||||
border_radius: 25.0,
|
border: iced::Border {
|
||||||
border_width: 1.0,
|
color: color::RED,
|
||||||
border_color: color::RED,
|
width: 1.0,
|
||||||
|
radius: 25.0.into(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -729,7 +860,7 @@ impl progress_bar::StyleSheet for Theme {
|
|||||||
progress_bar::Appearance {
|
progress_bar::Appearance {
|
||||||
background: color::GREY_6.into(),
|
background: color::GREY_6.into(),
|
||||||
bar: color::GREEN.into(),
|
bar: color::GREEN.into(),
|
||||||
border_radius: 10.0,
|
border_radius: 10.0.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -746,7 +877,7 @@ impl slider::StyleSheet for Theme {
|
|||||||
let handle = slider::Handle {
|
let handle = slider::Handle {
|
||||||
shape: slider::HandleShape::Rectangle {
|
shape: slider::HandleShape::Rectangle {
|
||||||
width: 8,
|
width: 8,
|
||||||
border_radius: 4.0,
|
border_radius: 4.0.into(),
|
||||||
},
|
},
|
||||||
color: color::BLACK,
|
color: color::BLACK,
|
||||||
border_color: color::GREEN,
|
border_color: color::GREEN,
|
||||||
@ -755,6 +886,7 @@ impl slider::StyleSheet for Theme {
|
|||||||
slider::Appearance {
|
slider::Appearance {
|
||||||
rail: slider::Rail {
|
rail: slider::Rail {
|
||||||
colors: (color::GREEN, iced::Color::TRANSPARENT),
|
colors: (color::GREEN, iced::Color::TRANSPARENT),
|
||||||
|
border_radius: 4.0.into(),
|
||||||
width: 2.0,
|
width: 2.0,
|
||||||
},
|
},
|
||||||
handle,
|
handle,
|
||||||
@ -764,7 +896,7 @@ impl slider::StyleSheet for Theme {
|
|||||||
let handle = slider::Handle {
|
let handle = slider::Handle {
|
||||||
shape: slider::HandleShape::Rectangle {
|
shape: slider::HandleShape::Rectangle {
|
||||||
width: 8,
|
width: 8,
|
||||||
border_radius: 4.0,
|
border_radius: 4.0.into(),
|
||||||
},
|
},
|
||||||
color: color::GREEN,
|
color: color::GREEN,
|
||||||
border_color: color::GREEN,
|
border_color: color::GREEN,
|
||||||
@ -773,6 +905,7 @@ impl slider::StyleSheet for Theme {
|
|||||||
slider::Appearance {
|
slider::Appearance {
|
||||||
rail: slider::Rail {
|
rail: slider::Rail {
|
||||||
colors: (color::GREEN, iced::Color::TRANSPARENT),
|
colors: (color::GREEN, iced::Color::TRANSPARENT),
|
||||||
|
border_radius: 4.0.into(),
|
||||||
width: 2.0,
|
width: 2.0,
|
||||||
},
|
},
|
||||||
handle,
|
handle,
|
||||||
@ -782,7 +915,7 @@ impl slider::StyleSheet for Theme {
|
|||||||
let handle = slider::Handle {
|
let handle = slider::Handle {
|
||||||
shape: slider::HandleShape::Rectangle {
|
shape: slider::HandleShape::Rectangle {
|
||||||
width: 8,
|
width: 8,
|
||||||
border_radius: 4.0,
|
border_radius: 4.0.into(),
|
||||||
},
|
},
|
||||||
color: color::GREEN,
|
color: color::GREEN,
|
||||||
border_color: color::GREEN,
|
border_color: color::GREEN,
|
||||||
@ -791,6 +924,7 @@ impl slider::StyleSheet for Theme {
|
|||||||
slider::Appearance {
|
slider::Appearance {
|
||||||
rail: slider::Rail {
|
rail: slider::Rail {
|
||||||
colors: (color::GREEN, iced::Color::TRANSPARENT),
|
colors: (color::GREEN, iced::Color::TRANSPARENT),
|
||||||
|
border_radius: 4.0.into(),
|
||||||
width: 2.0,
|
width: 2.0,
|
||||||
},
|
},
|
||||||
handle,
|
handle,
|
||||||
@ -810,3 +944,13 @@ impl svg::StyleSheet for Theme {
|
|||||||
svg::Appearance::default()
|
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