feat(dtmm): Improve update icon
This commit is contained in:
parent
e434535d96
commit
6a52f3efc2
4 changed files with 70 additions and 15 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -775,6 +775,7 @@ dependencies = [
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-error",
|
"tracing-error",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
|
"usvg",
|
||||||
"zip",
|
"zip",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -29,3 +29,4 @@ time = { version = "0.3.20", features = ["serde", "serde-well-known", "local-off
|
||||||
strip-ansi-escapes = "0.1.1"
|
strip-ansi-escapes = "0.1.1"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
colors-transform = "0.2.11"
|
colors-transform = "0.2.11"
|
||||||
|
usvg = "0.25.0"
|
||||||
|
|
|
@ -1 +1,41 @@
|
||||||
|
use druid::Color;
|
||||||
|
use usvg::{
|
||||||
|
Error, Fill, LineCap, LineJoin, NodeKind, NonZeroPositiveF64, Options, Paint, Stroke, Tree,
|
||||||
|
};
|
||||||
|
|
||||||
pub static ALERT_CIRCLE: &str = include_str!("../../../assets/icons/icons/alert-circle.svg");
|
pub static ALERT_CIRCLE: &str = include_str!("../../../assets/icons/icons/alert-circle.svg");
|
||||||
|
pub static ALERT_TRIANGLE: &str = include_str!("../../../assets/icons/icons/alert-triangle.svg");
|
||||||
|
|
||||||
|
pub fn parse_svg(svg: &str) -> Result<Tree, Error> {
|
||||||
|
let opt = Options::default();
|
||||||
|
Tree::from_str(svg, &opt.to_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn recolor_icon(tree: Tree, stroke: bool, color: Color) -> Tree {
|
||||||
|
let (red, green, blue, _) = color.as_rgba8();
|
||||||
|
|
||||||
|
let mut children = tree.root.children();
|
||||||
|
// The first element is always some kind of background placeholder
|
||||||
|
children.next();
|
||||||
|
|
||||||
|
for node in children {
|
||||||
|
if let NodeKind::Path(ref mut path) = *node.borrow_mut() {
|
||||||
|
if stroke {
|
||||||
|
path.stroke = Some(Stroke {
|
||||||
|
paint: Paint::Color(usvg::Color { red, green, blue }),
|
||||||
|
width: NonZeroPositiveF64::new(2.).expect("the value is not zero"),
|
||||||
|
linecap: LineCap::Round,
|
||||||
|
linejoin: LineJoin::Round,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
path.fill = Some(Fill {
|
||||||
|
paint: Paint::Color(usvg::Color { red, green, blue }),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tree
|
||||||
|
}
|
||||||
|
|
|
@ -2,15 +2,16 @@ use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use druid::im::Vector;
|
use druid::im::Vector;
|
||||||
|
use druid::lens;
|
||||||
use druid::widget::{
|
use druid::widget::{
|
||||||
Checkbox, CrossAxisAlignment, Either, Flex, Image, Label, LineBreaking, List,
|
Checkbox, CrossAxisAlignment, Either, Flex, Image, Label, LineBreaking, List,
|
||||||
MainAxisAlignment, Maybe, Scroll, SizedBox, Split, Svg, SvgData, TextBox, ViewSwitcher,
|
MainAxisAlignment, Maybe, Scroll, SizedBox, Split, Svg, SvgData, TextBox, ViewSwitcher,
|
||||||
};
|
};
|
||||||
use druid::{lens, Data, ImageBuf, LifeCycleCtx};
|
|
||||||
use druid::{
|
use druid::{
|
||||||
Color, FileDialogOptions, FileSpec, FontDescriptor, FontFamily, LensExt, SingleUse, Widget,
|
Color, FileDialogOptions, FileSpec, FontDescriptor, FontFamily, LensExt, SingleUse, Widget,
|
||||||
WidgetExt, WindowDesc, WindowId,
|
WidgetExt, WindowDesc, WindowId,
|
||||||
};
|
};
|
||||||
|
use druid::{Data, ImageBuf, LifeCycleCtx};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
use crate::state::{
|
use crate::state::{
|
||||||
|
@ -18,7 +19,7 @@ use crate::state::{
|
||||||
ACTION_SELECT_MOD, ACTION_SET_WINDOW_HANDLE, ACTION_START_CHECK_UPDATE,
|
ACTION_SELECT_MOD, ACTION_SET_WINDOW_HANDLE, ACTION_START_CHECK_UPDATE,
|
||||||
ACTION_START_DELETE_SELECTED_MOD, ACTION_START_DEPLOY, ACTION_START_RESET_DEPLOYMENT,
|
ACTION_START_DELETE_SELECTED_MOD, ACTION_START_DEPLOY, ACTION_START_RESET_DEPLOYMENT,
|
||||||
};
|
};
|
||||||
use crate::ui::theme::{self, ColorExt};
|
use crate::ui::theme::{self, ColorExt, COLOR_YELLOW_LIGHT};
|
||||||
use crate::ui::widget::border::Border;
|
use crate::ui::widget::border::Border;
|
||||||
use crate::ui::widget::button::Button;
|
use crate::ui::widget::button::Button;
|
||||||
use crate::ui::widget::controller::{
|
use crate::ui::widget::controller::{
|
||||||
|
@ -126,19 +127,31 @@ fn build_mod_list() -> impl Widget<State> {
|
||||||
let name =
|
let name =
|
||||||
Label::raw().lens(lens!((usize, Arc<ModInfo>, bool), 1).then(ModInfo::name.in_arc()));
|
Label::raw().lens(lens!((usize, Arc<ModInfo>, bool), 1).then(ModInfo::name.in_arc()));
|
||||||
|
|
||||||
let version = Label::dynamic(|info: &Arc<ModInfo>, _| {
|
let version = {
|
||||||
let has_update = info
|
let icon = {
|
||||||
.nexus
|
let tree =
|
||||||
|
theme::icons::parse_svg(theme::icons::ALERT_TRIANGLE).expect("invalid SVG");
|
||||||
|
|
||||||
|
let tree = theme::icons::recolor_icon(tree, true, COLOR_YELLOW_LIGHT);
|
||||||
|
|
||||||
|
Svg::new(Arc::new(tree)).fix_height(druid::theme::TEXT_SIZE_NORMAL)
|
||||||
|
};
|
||||||
|
|
||||||
|
Either::new(
|
||||||
|
|info, _| {
|
||||||
|
info.nexus
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|n| info.version != n.version)
|
.map(|n| info.version != n.version)
|
||||||
.unwrap_or(false);
|
.unwrap_or(false)
|
||||||
if has_update {
|
},
|
||||||
format!("! {}", info.version)
|
Flex::row()
|
||||||
} else {
|
.with_child(icon)
|
||||||
info.version.to_string()
|
.with_spacer(3.)
|
||||||
}
|
.with_child(Label::raw().lens(ModInfo::version.in_arc())),
|
||||||
})
|
Label::raw().lens(ModInfo::version.in_arc()),
|
||||||
.lens(lens!((usize, Arc<ModInfo>, bool), 1));
|
)
|
||||||
|
.lens(lens!((usize, Arc<ModInfo>, bool), 1))
|
||||||
|
};
|
||||||
|
|
||||||
let fields = Flex::row()
|
let fields = Flex::row()
|
||||||
.must_fill_main_axis(true)
|
.must_fill_main_axis(true)
|
||||||
|
|
Loading…
Add table
Reference in a new issue