dash-frontend: clock, wgui: refactoring, non-panicking casts
This commit is contained in:
34
Cargo.lock
generated
34
Cargo.lock
generated
@@ -125,12 +125,6 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04"
|
checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "android-tzdata"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "android_system_properties"
|
name = "android_system_properties"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
@@ -882,16 +876,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.41"
|
version = "0.4.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
|
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android-tzdata",
|
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"windows-link",
|
"windows-link 0.2.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1366,6 +1359,7 @@ name = "dash-frontend"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"chrono",
|
||||||
"glam",
|
"glam",
|
||||||
"log",
|
"log",
|
||||||
"rust-embed",
|
"rust-embed",
|
||||||
@@ -5737,7 +5731,7 @@ dependencies = [
|
|||||||
"windows-collections",
|
"windows-collections",
|
||||||
"windows-core 0.61.2",
|
"windows-core 0.61.2",
|
||||||
"windows-future",
|
"windows-future",
|
||||||
"windows-link",
|
"windows-link 0.1.3",
|
||||||
"windows-numerics",
|
"windows-numerics",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -5768,7 +5762,7 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-implement",
|
"windows-implement",
|
||||||
"windows-interface",
|
"windows-interface",
|
||||||
"windows-link",
|
"windows-link 0.1.3",
|
||||||
"windows-result 0.3.4",
|
"windows-result 0.3.4",
|
||||||
"windows-strings",
|
"windows-strings",
|
||||||
]
|
]
|
||||||
@@ -5780,7 +5774,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
|
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-core 0.61.2",
|
"windows-core 0.61.2",
|
||||||
"windows-link",
|
"windows-link 0.1.3",
|
||||||
"windows-threading",
|
"windows-threading",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -5812,6 +5806,12 @@ version = "0.1.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-link"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-numerics"
|
name = "windows-numerics"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@@ -5819,7 +5819,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
|
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-core 0.61.2",
|
"windows-core 0.61.2",
|
||||||
"windows-link",
|
"windows-link 0.1.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -5837,7 +5837,7 @@ version = "0.3.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
|
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-link",
|
"windows-link 0.1.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -5846,7 +5846,7 @@ version = "0.4.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
|
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-link",
|
"windows-link 0.1.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -5944,7 +5944,7 @@ version = "0.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
|
checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-link",
|
"windows-link 0.1.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -9,3 +9,4 @@ wgui = { path = "../wgui/" }
|
|||||||
glam = { workspace = true }
|
glam = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
rust-embed = "8.7.2"
|
rust-embed = "8.7.2"
|
||||||
|
chrono = "0.4.42"
|
||||||
|
|||||||
@@ -101,7 +101,7 @@
|
|||||||
|
|
||||||
<!-- Right bottom side -->
|
<!-- Right bottom side -->
|
||||||
<div margin_right="16">
|
<div margin_right="16">
|
||||||
<label text="12:34" size="16" />
|
<label id="label_time" size="16" />
|
||||||
</div>
|
</div>
|
||||||
</rectangle>
|
</rectangle>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
use std::{cell::RefCell, collections::VecDeque, rc::Rc};
|
use std::{cell::RefCell, collections::VecDeque, rc::Rc};
|
||||||
|
|
||||||
|
use chrono::Timelike;
|
||||||
use glam::Vec2;
|
use glam::Vec2;
|
||||||
use wgui::{
|
use wgui::{
|
||||||
components::button::ComponentButton,
|
components::button::ComponentButton,
|
||||||
drawing,
|
drawing,
|
||||||
event::EventListenerCollection,
|
event::{CallbackDataCommon, EventAlterables, EventListenerCollection},
|
||||||
globals::WguiGlobals,
|
globals::WguiGlobals,
|
||||||
layout::{LayoutParams, RcLayout},
|
i18n::Translation,
|
||||||
|
layout::{LayoutParams, RcLayout, WidgetID},
|
||||||
parser::{ParseDocumentParams, ParserState},
|
parser::{ParseDocumentParams, ParserState},
|
||||||
|
widget::label::WidgetLabel,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::tab::{
|
use crate::tab::{
|
||||||
@@ -28,6 +31,10 @@ pub struct Frontend {
|
|||||||
current_tab: Option<Box<dyn Tab>>,
|
current_tab: Option<Box<dyn Tab>>,
|
||||||
|
|
||||||
tasks: VecDeque<FrontendTask>,
|
tasks: VecDeque<FrontendTask>,
|
||||||
|
|
||||||
|
ticks: u32,
|
||||||
|
|
||||||
|
label_time_id: WidgetID,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type RcFrontend = Rc<RefCell<Frontend>>;
|
pub type RcFrontend = Rc<RefCell<Frontend>>;
|
||||||
@@ -64,40 +71,73 @@ impl Frontend {
|
|||||||
let mut tasks = VecDeque::<FrontendTask>::new();
|
let mut tasks = VecDeque::<FrontendTask>::new();
|
||||||
tasks.push_back(FrontendTask::SetTab(TabType::Home));
|
tasks.push_back(FrontendTask::SetTab(TabType::Home));
|
||||||
|
|
||||||
|
let label_time_id = state.get_widget_id("label_time")?;
|
||||||
|
|
||||||
let res = Rc::new(RefCell::new(Self {
|
let res = Rc::new(RefCell::new(Self {
|
||||||
layout: rc_layout.clone(),
|
layout: rc_layout.clone(),
|
||||||
state,
|
state,
|
||||||
current_tab: None,
|
current_tab: None,
|
||||||
globals,
|
globals,
|
||||||
tasks,
|
tasks,
|
||||||
|
ticks: 0,
|
||||||
|
label_time_id,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Frontend::register_buttons(&res)?;
|
Frontend::register_widgets(&res)?;
|
||||||
|
|
||||||
Ok((res, rc_layout))
|
Ok((res, rc_layout))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(
|
pub fn update(
|
||||||
|
&mut self,
|
||||||
rc_this: &RcFrontend,
|
rc_this: &RcFrontend,
|
||||||
listeners: &mut EventListenerCollection<(), ()>,
|
listeners: &mut EventListenerCollection<(), ()>,
|
||||||
width: f32,
|
width: f32,
|
||||||
height: f32,
|
height: f32,
|
||||||
timestep_alpha: f32,
|
timestep_alpha: f32,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let mut this = rc_this.borrow_mut();
|
while let Some(task) = self.tasks.pop_front() {
|
||||||
|
self.process_task(rc_this, task, listeners)?;
|
||||||
while let Some(task) = this.tasks.pop_front() {
|
|
||||||
this.process_task(rc_this, task, listeners)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this
|
self.tick(width, height, timestep_alpha)?;
|
||||||
.layout
|
self.ticks += 1;
|
||||||
.borrow_mut()
|
|
||||||
.update(Vec2::new(width, height), timestep_alpha)?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tick(&mut self, width: f32, height: f32, timestep_alpha: f32) -> anyhow::Result<()> {
|
||||||
|
let mut layout = self.layout.borrow_mut();
|
||||||
|
|
||||||
|
let mut alterables = EventAlterables::default();
|
||||||
|
let mut common = CallbackDataCommon {
|
||||||
|
alterables: &mut alterables,
|
||||||
|
state: &layout.state,
|
||||||
|
};
|
||||||
|
|
||||||
|
// fixme: timer events instead of this thing
|
||||||
|
if self.ticks % 1000 == 0 {
|
||||||
|
self.update_time(&mut common);
|
||||||
|
}
|
||||||
|
|
||||||
|
layout.update(Vec2::new(width, height), timestep_alpha)?;
|
||||||
|
layout.process_alterables(alterables)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_time(&self, common: &mut CallbackDataCommon) {
|
||||||
|
let Some(mut label) = common.state.widgets.get_as::<WidgetLabel>(self.label_time_id) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let now = chrono::Local::now();
|
||||||
|
let hours = now.hour();
|
||||||
|
let minutes = now.minute();
|
||||||
|
|
||||||
|
label.set_text(common, Translation::from_raw_text(&format!("{hours:02}:{minutes:02}")));
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_layout(&self) -> &RcLayout {
|
pub fn get_layout(&self) -> &RcLayout {
|
||||||
&self.layout
|
&self.layout
|
||||||
}
|
}
|
||||||
@@ -151,7 +191,7 @@ impl Frontend {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_buttons(rc_this: &RcFrontend) -> anyhow::Result<()> {
|
fn register_widgets(rc_this: &RcFrontend) -> anyhow::Result<()> {
|
||||||
let this = rc_this.borrow_mut();
|
let this = rc_this.borrow_mut();
|
||||||
let btn_home = this.state.fetch_component_as::<ComponentButton>("btn_side_home")?;
|
let btn_home = this.state.fetch_component_as::<ComponentButton>("btn_side_home")?;
|
||||||
let btn_apps = this.state.fetch_component_as::<ComponentButton>("btn_side_apps")?;
|
let btn_apps = this.state.fetch_component_as::<ComponentButton>("btn_side_apps")?;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use crate::testbed::{Testbed, TestbedUpdateParams};
|
use crate::testbed::{Testbed, TestbedUpdateParams};
|
||||||
use dash_frontend::Frontend;
|
|
||||||
use wgui::{event::EventListenerCollection, layout::RcLayout};
|
use wgui::{event::EventListenerCollection, layout::RcLayout};
|
||||||
|
|
||||||
pub struct TestbedDashboard {
|
pub struct TestbedDashboard {
|
||||||
@@ -17,7 +16,8 @@ impl TestbedDashboard {
|
|||||||
|
|
||||||
impl Testbed for TestbedDashboard {
|
impl Testbed for TestbedDashboard {
|
||||||
fn update(&mut self, params: TestbedUpdateParams) -> anyhow::Result<()> {
|
fn update(&mut self, params: TestbedUpdateParams) -> anyhow::Result<()> {
|
||||||
Frontend::update(
|
let mut frontend = self.frontend.borrow_mut();
|
||||||
|
frontend.update(
|
||||||
&self.frontend,
|
&self.frontend,
|
||||||
params.listeners,
|
params.listeners,
|
||||||
params.width,
|
params.width,
|
||||||
|
|||||||
@@ -32,15 +32,14 @@ fn button_click_callback(
|
|||||||
label: Widget,
|
label: Widget,
|
||||||
text: &'static str,
|
text: &'static str,
|
||||||
) -> ButtonClickCallback {
|
) -> ButtonClickCallback {
|
||||||
Box::new(move |e| {
|
Box::new(move |mut e| {
|
||||||
label.get_as_mut::<WidgetLabel>().set_text(
|
label
|
||||||
&mut e.state.globals.i18n(),
|
.get_as_mut::<WidgetLabel>()
|
||||||
Translation::from_raw_text(text),
|
.unwrap()
|
||||||
);
|
.set_text(&mut e.as_common(), Translation::from_raw_text(text));
|
||||||
|
|
||||||
button.try_cast::<ComponentButton>()?.set_text(
|
button.try_cast::<ComponentButton>()?.set_text(
|
||||||
e.state,
|
&mut e.as_common(),
|
||||||
e.alterables,
|
|
||||||
Translation::from_raw_text("this button has been clicked"),
|
Translation::from_raw_text("this button has been clicked"),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -93,12 +92,8 @@ impl TestbedGeneric {
|
|||||||
|
|
||||||
let button_click_me = state.fetch_component_as::<ComponentButton>("button_click_me")?;
|
let button_click_me = state.fetch_component_as::<ComponentButton>("button_click_me")?;
|
||||||
let button = button_click_me.clone();
|
let button = button_click_me.clone();
|
||||||
button_click_me.on_click(Box::new(move |e| {
|
button_click_me.on_click(Box::new(move |mut e| {
|
||||||
button.set_text(
|
button.set_text(&mut e.as_common(), Translation::from_raw_text("congrats!"));
|
||||||
e.state,
|
|
||||||
e.alterables,
|
|
||||||
Translation::from_raw_text("congrats!"),
|
|
||||||
);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -116,12 +111,10 @@ impl TestbedGeneric {
|
|||||||
|
|
||||||
let cb_first = state.fetch_component_as::<ComponentCheckbox>("cb_first")?;
|
let cb_first = state.fetch_component_as::<ComponentCheckbox>("cb_first")?;
|
||||||
let label = label_cur_option.widget.clone();
|
let label = label_cur_option.widget.clone();
|
||||||
cb_first.on_toggle(Box::new(move |e| {
|
cb_first.on_toggle(Box::new(move |mut e| {
|
||||||
let mut widget = label.get_as_mut::<WidgetLabel>();
|
let mut widget = label.get_as_mut::<WidgetLabel>().unwrap();
|
||||||
widget.set_text(
|
let text = format!("checkbox toggle: {}", e.checked);
|
||||||
&mut e.state.globals.i18n(),
|
widget.set_text(&mut e.as_common(), Translation::from_raw_text(&text));
|
||||||
Translation::from_raw_text(&format!("checkbox toggle: {}", e.checked)),
|
|
||||||
);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use crate::{
|
|||||||
animation::{Animation, AnimationEasing},
|
animation::{Animation, AnimationEasing},
|
||||||
components::{Component, ComponentBase, ComponentTrait, InitData},
|
components::{Component, ComponentBase, ComponentTrait, InitData},
|
||||||
drawing::{self, Color},
|
drawing::{self, Color},
|
||||||
event::{EventAlterables, EventListenerCollection, EventListenerKind, ListenerHandleVec},
|
event::{CallbackDataCommon, EventAlterables, EventListenerCollection, EventListenerKind, ListenerHandleVec},
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::{Layout, LayoutState, WidgetID},
|
layout::{Layout, LayoutState, WidgetID},
|
||||||
renderer_vk::text::{FontWeight, TextStyle},
|
renderer_vk::text::{FontWeight, TextStyle},
|
||||||
@@ -46,6 +46,16 @@ pub struct ButtonClickEvent<'a> {
|
|||||||
pub state: &'a LayoutState,
|
pub state: &'a LayoutState,
|
||||||
pub alterables: &'a mut EventAlterables,
|
pub alterables: &'a mut EventAlterables,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ButtonClickEvent<'_> {
|
||||||
|
pub const fn as_common(&mut self) -> CallbackDataCommon {
|
||||||
|
CallbackDataCommon {
|
||||||
|
alterables: self.alterables,
|
||||||
|
state: self.state,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type ButtonClickCallback = Box<dyn Fn(ButtonClickEvent) -> anyhow::Result<()>>;
|
pub type ButtonClickCallback = Box<dyn Fn(ButtonClickEvent) -> anyhow::Result<()>>;
|
||||||
|
|
||||||
struct State {
|
struct State {
|
||||||
@@ -61,7 +71,6 @@ struct Data {
|
|||||||
initial_hover_border_color: drawing::Color,
|
initial_hover_border_color: drawing::Color,
|
||||||
id_label: WidgetID, // Label
|
id_label: WidgetID, // Label
|
||||||
id_rect: WidgetID, // Rectangle
|
id_rect: WidgetID, // Rectangle
|
||||||
node_label: taffy::NodeId,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ComponentButton {
|
pub struct ComponentButton {
|
||||||
@@ -79,15 +88,12 @@ impl ComponentTrait for ComponentButton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ComponentButton {
|
impl ComponentButton {
|
||||||
pub fn set_text(&self, state: &LayoutState, alterables: &mut EventAlterables, text: Translation) {
|
pub fn set_text(&self, common: &mut CallbackDataCommon, text: Translation) {
|
||||||
let globals = state.globals.clone();
|
let Some(mut label) = common.state.widgets.get_as::<WidgetLabel>(self.data.id_label) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
state.widgets.call(self.data.id_label, |label: &mut WidgetLabel| {
|
label.set_text(common, text);
|
||||||
label.set_text(&mut globals.i18n(), text);
|
|
||||||
});
|
|
||||||
|
|
||||||
alterables.mark_redraw();
|
|
||||||
alterables.mark_dirty(self.data.node_label);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_click(&self, func: ButtonClickCallback) {
|
pub fn on_click(&self, func: ButtonClickCallback) {
|
||||||
@@ -115,7 +121,7 @@ fn anim_hover_in(data: Rc<Data>, state: Rc<RefCell<State>>, widget_id: WidgetID)
|
|||||||
2,
|
2,
|
||||||
AnimationEasing::OutQuad,
|
AnimationEasing::OutQuad,
|
||||||
Box::new(move |common, anim_data| {
|
Box::new(move |common, anim_data| {
|
||||||
let rect = anim_data.obj.get_as_mut::<WidgetRectangle>();
|
let rect = anim_data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
anim_hover(rect, &data, anim_data.pos, state.borrow().down);
|
anim_hover(rect, &data, anim_data.pos, state.borrow().down);
|
||||||
common.alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
}),
|
}),
|
||||||
@@ -128,7 +134,7 @@ fn anim_hover_out(data: Rc<Data>, state: Rc<RefCell<State>>, widget_id: WidgetID
|
|||||||
8,
|
8,
|
||||||
AnimationEasing::OutQuad,
|
AnimationEasing::OutQuad,
|
||||||
Box::new(move |common, anim_data| {
|
Box::new(move |common, anim_data| {
|
||||||
let rect = anim_data.obj.get_as_mut::<WidgetRectangle>();
|
let rect = anim_data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
anim_hover(rect, &data, 1.0 - anim_data.pos, state.borrow().down);
|
anim_hover(rect, &data, 1.0 - anim_data.pos, state.borrow().down);
|
||||||
common.alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
}),
|
}),
|
||||||
@@ -190,7 +196,7 @@ fn register_event_mouse_press<U1, U2>(
|
|||||||
Box::new(move |common, event_data, _, _| {
|
Box::new(move |common, event_data, _, _| {
|
||||||
let mut state = state.borrow_mut();
|
let mut state = state.borrow_mut();
|
||||||
|
|
||||||
let rect = event_data.obj.get_as_mut::<WidgetRectangle>();
|
let rect = event_data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
anim_hover(rect, &data, 1.0, true);
|
anim_hover(rect, &data, 1.0, true);
|
||||||
|
|
||||||
if state.hovered {
|
if state.hovered {
|
||||||
@@ -216,7 +222,7 @@ fn register_event_mouse_release<U1, U2>(
|
|||||||
data.id_rect,
|
data.id_rect,
|
||||||
EventListenerKind::MouseRelease,
|
EventListenerKind::MouseRelease,
|
||||||
Box::new(move |common, event_data, _, _| {
|
Box::new(move |common, event_data, _, _| {
|
||||||
let rect = event_data.obj.get_as_mut::<WidgetRectangle>();
|
let rect = event_data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
anim_hover(rect, &data, 1.0, false);
|
anim_hover(rect, &data, 1.0, false);
|
||||||
|
|
||||||
let mut state = state.borrow_mut();
|
let mut state = state.borrow_mut();
|
||||||
@@ -272,7 +278,7 @@ pub fn construct<U1, U2>(
|
|||||||
|
|
||||||
let light_text = (params.color.r + params.color.g + params.color.b) < 1.5;
|
let light_text = (params.color.r + params.color.g + params.color.b) < 1.5;
|
||||||
|
|
||||||
let (id_label, node_label) = layout.add_child(
|
let (id_label, _node_label) = layout.add_child(
|
||||||
id_rect,
|
id_rect,
|
||||||
WidgetLabel::create(
|
WidgetLabel::create(
|
||||||
&mut globals.get(),
|
&mut globals.get(),
|
||||||
@@ -295,7 +301,6 @@ pub fn construct<U1, U2>(
|
|||||||
let data = Rc::new(Data {
|
let data = Rc::new(Data {
|
||||||
id_label,
|
id_label,
|
||||||
id_rect,
|
id_rect,
|
||||||
node_label,
|
|
||||||
initial_color: params.color,
|
initial_color: params.color,
|
||||||
initial_border_color: params.border_color,
|
initial_border_color: params.border_color,
|
||||||
initial_hover_color: params.hover_color,
|
initial_hover_color: params.hover_color,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use crate::{
|
|||||||
animation::{Animation, AnimationEasing},
|
animation::{Animation, AnimationEasing},
|
||||||
components::{Component, ComponentBase, ComponentTrait, InitData},
|
components::{Component, ComponentBase, ComponentTrait, InitData},
|
||||||
drawing::Color,
|
drawing::Color,
|
||||||
event::{EventAlterables, EventListenerCollection, EventListenerKind, ListenerHandleVec},
|
event::{CallbackDataCommon, EventAlterables, EventListenerCollection, EventListenerKind, ListenerHandleVec},
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::{self, Layout, LayoutState, WidgetID},
|
layout::{self, Layout, LayoutState, WidgetID},
|
||||||
renderer_vk::text::{FontWeight, TextStyle},
|
renderer_vk::text::{FontWeight, TextStyle},
|
||||||
@@ -42,6 +42,16 @@ pub struct CheckboxToggleEvent<'a> {
|
|||||||
pub alterables: &'a mut EventAlterables,
|
pub alterables: &'a mut EventAlterables,
|
||||||
pub checked: bool,
|
pub checked: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl CheckboxToggleEvent<'_> {
|
||||||
|
pub const fn as_common(&mut self) -> CallbackDataCommon {
|
||||||
|
CallbackDataCommon {
|
||||||
|
alterables: self.alterables,
|
||||||
|
state: self.state,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type CheckboxToggleCallback = Box<dyn Fn(CheckboxToggleEvent) -> anyhow::Result<()>>;
|
pub type CheckboxToggleCallback = Box<dyn Fn(CheckboxToggleEvent) -> anyhow::Result<()>>;
|
||||||
|
|
||||||
struct State {
|
struct State {
|
||||||
@@ -51,14 +61,13 @@ struct State {
|
|||||||
on_toggle: Option<CheckboxToggleCallback>,
|
on_toggle: Option<CheckboxToggleCallback>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::struct_field_names)]
|
||||||
struct Data {
|
struct Data {
|
||||||
id_container: WidgetID, // Rectangle, transparent if not hovered
|
id_container: WidgetID, // Rectangle, transparent if not hovered
|
||||||
|
|
||||||
//id_outer_box: WidgetID, // Rectangle, parent of container
|
//id_outer_box: WidgetID, // Rectangle, parent of container
|
||||||
id_inner_box: WidgetID, // Rectangle, parent of outer_box
|
id_inner_box: WidgetID, // Rectangle, parent of outer_box
|
||||||
id_label: WidgetID, // Label, parent of container
|
id_label: WidgetID, // Label, parent of container
|
||||||
|
|
||||||
node_label: taffy::NodeId,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ComponentCheckbox {
|
pub struct ComponentCheckbox {
|
||||||
@@ -85,15 +94,12 @@ fn set_box_checked(widgets: &layout::WidgetMap, data: &Data, checked: bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ComponentCheckbox {
|
impl ComponentCheckbox {
|
||||||
pub fn set_text(&self, state: &LayoutState, alterables: &mut EventAlterables, text: Translation) {
|
pub fn set_text(&self, state: &LayoutState, common: &mut CallbackDataCommon, text: Translation) {
|
||||||
let globals = state.globals.clone();
|
let Some(mut label) = state.widgets.get_as::<WidgetLabel>(self.data.id_label) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
state.widgets.call(self.data.id_label, |label: &mut WidgetLabel| {
|
label.set_text(common, text);
|
||||||
label.set_text(&mut globals.i18n(), text);
|
|
||||||
});
|
|
||||||
|
|
||||||
alterables.mark_redraw();
|
|
||||||
alterables.mark_dirty(self.data.node_label);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_checked(&self, state: &LayoutState, alterables: &mut EventAlterables, checked: bool) {
|
pub fn set_checked(&self, state: &LayoutState, alterables: &mut EventAlterables, checked: bool) {
|
||||||
@@ -123,7 +129,7 @@ fn anim_hover_in(state: Rc<RefCell<State>>, widget_id: WidgetID) -> Animation {
|
|||||||
5,
|
5,
|
||||||
AnimationEasing::OutQuad,
|
AnimationEasing::OutQuad,
|
||||||
Box::new(move |common, anim_data| {
|
Box::new(move |common, anim_data| {
|
||||||
let rect = anim_data.obj.get_as_mut::<WidgetRectangle>();
|
let rect = anim_data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
anim_hover(rect, anim_data.pos, state.borrow().down);
|
anim_hover(rect, anim_data.pos, state.borrow().down);
|
||||||
common.alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
}),
|
}),
|
||||||
@@ -136,7 +142,7 @@ fn anim_hover_out(state: Rc<RefCell<State>>, widget_id: WidgetID) -> Animation {
|
|||||||
8,
|
8,
|
||||||
AnimationEasing::OutQuad,
|
AnimationEasing::OutQuad,
|
||||||
Box::new(move |common, anim_data| {
|
Box::new(move |common, anim_data| {
|
||||||
let rect = anim_data.obj.get_as_mut::<WidgetRectangle>();
|
let rect = anim_data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
anim_hover(rect, 1.0 - anim_data.pos, state.borrow().down);
|
anim_hover(rect, 1.0 - anim_data.pos, state.borrow().down);
|
||||||
common.alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
}),
|
}),
|
||||||
@@ -198,7 +204,7 @@ fn register_event_mouse_press<U1, U2>(
|
|||||||
Box::new(move |common, event_data, _, _| {
|
Box::new(move |common, event_data, _, _| {
|
||||||
let mut state = state.borrow_mut();
|
let mut state = state.borrow_mut();
|
||||||
|
|
||||||
let rect = event_data.obj.get_as_mut::<WidgetRectangle>();
|
let rect = event_data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
anim_hover(rect, 1.0, true);
|
anim_hover(rect, 1.0, true);
|
||||||
|
|
||||||
if state.hovered {
|
if state.hovered {
|
||||||
@@ -224,7 +230,7 @@ fn register_event_mouse_release<U1, U2>(
|
|||||||
data.id_container,
|
data.id_container,
|
||||||
EventListenerKind::MouseRelease,
|
EventListenerKind::MouseRelease,
|
||||||
Box::new(move |common, event_data, _, _| {
|
Box::new(move |common, event_data, _, _| {
|
||||||
let rect = event_data.obj.get_as_mut::<WidgetRectangle>();
|
let rect = event_data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
anim_hover(rect, 1.0, false);
|
anim_hover(rect, 1.0, false);
|
||||||
|
|
||||||
let mut state = state.borrow_mut();
|
let mut state = state.borrow_mut();
|
||||||
@@ -327,7 +333,7 @@ pub fn construct<U1, U2>(
|
|||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let (id_label, node_label) = layout.add_child(
|
let (id_label, _node_label) = layout.add_child(
|
||||||
id_container,
|
id_container,
|
||||||
WidgetLabel::create(
|
WidgetLabel::create(
|
||||||
&mut globals.get(),
|
&mut globals.get(),
|
||||||
@@ -346,7 +352,6 @@ pub fn construct<U1, U2>(
|
|||||||
id_container,
|
id_container,
|
||||||
id_inner_box,
|
id_inner_box,
|
||||||
id_label,
|
id_label,
|
||||||
node_label,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let state = Rc::new(RefCell::new(State {
|
let state = Rc::new(RefCell::new(State {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
any::AnyTrait,
|
any::AnyTrait,
|
||||||
event::{self, EventAlterables},
|
event::{self, CallbackDataCommon, EventAlterables},
|
||||||
layout::LayoutState,
|
layout::LayoutState,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -15,6 +15,15 @@ pub struct InitData<'a> {
|
|||||||
pub alterables: &'a mut EventAlterables,
|
pub alterables: &'a mut EventAlterables,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InitData<'_> {
|
||||||
|
const fn as_common(&mut self) -> CallbackDataCommon {
|
||||||
|
CallbackDataCommon {
|
||||||
|
alterables: self.alterables,
|
||||||
|
state: self.state,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// common component data
|
// common component data
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ComponentBase {
|
pub struct ComponentBase {
|
||||||
@@ -32,7 +41,6 @@ pub struct Component(pub Rc<dyn ComponentTrait>);
|
|||||||
pub type ComponentWeak = std::rc::Weak<dyn ComponentTrait>;
|
pub type ComponentWeak = std::rc::Weak<dyn ComponentTrait>;
|
||||||
|
|
||||||
impl Component {
|
impl Component {
|
||||||
|
|
||||||
pub fn weak(&self) -> ComponentWeak {
|
pub fn weak(&self) -> ComponentWeak {
|
||||||
Rc::downgrade(&self.0)
|
Rc::downgrade(&self.0)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ use crate::{
|
|||||||
animation::{Animation, AnimationEasing},
|
animation::{Animation, AnimationEasing},
|
||||||
components::{Component, ComponentBase, ComponentTrait, InitData},
|
components::{Component, ComponentBase, ComponentTrait, InitData},
|
||||||
drawing::{self},
|
drawing::{self},
|
||||||
event::{self, CallbackDataCommon, EventAlterables, EventListenerCollection, EventListenerKind, ListenerHandleVec},
|
event::{self, CallbackDataCommon, EventListenerCollection, EventListenerKind, ListenerHandleVec},
|
||||||
i18n::{I18n, Translation},
|
i18n::Translation,
|
||||||
layout::{Layout, LayoutState, WidgetID},
|
layout::{Layout, WidgetID},
|
||||||
renderer_vk::{
|
renderer_vk::{
|
||||||
text::{FontWeight, HorizontalAlign, TextStyle},
|
text::{FontWeight, HorizontalAlign, TextStyle},
|
||||||
util,
|
util,
|
||||||
@@ -69,7 +69,7 @@ impl ComponentTrait for ComponentSlider {
|
|||||||
fn init(&self, init_data: &mut InitData) {
|
fn init(&self, init_data: &mut InitData) {
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
let value = state.values.value;
|
let value = state.values.value;
|
||||||
state.set_value(init_data.state, &self.data, init_data.alterables, value);
|
state.set_value(&mut init_data.as_common(), &self.data, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn base(&mut self) -> &mut ComponentBase {
|
fn base(&mut self) -> &mut ComponentBase {
|
||||||
@@ -125,25 +125,26 @@ impl State {
|
|||||||
let target_value = self.values.get_from_normalized(norm);
|
let target_value = self.values.get_from_normalized(norm);
|
||||||
let val = target_value;
|
let val = target_value;
|
||||||
|
|
||||||
self.set_value(common.state, data, common.alterables, val);
|
self.set_value(common, data, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_text(i18n: &mut I18n, text: &mut WidgetLabel, value: f32) {
|
fn update_text(common: &mut CallbackDataCommon, text: &mut WidgetLabel, value: f32) {
|
||||||
// round displayed value, should be sufficient for now
|
// round displayed value, should be sufficient for now
|
||||||
text.set_text(i18n, Translation::from_raw_text(&format!("{}", value.round())));
|
text.set_text(common, Translation::from_raw_text(&format!("{}", value.round())));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_value(&mut self, state: &LayoutState, data: &Data, alterables: &mut EventAlterables, value: f32) {
|
fn set_value(&mut self, common: &mut CallbackDataCommon, data: &Data, value: f32) {
|
||||||
//common.call_on_widget(data.slider_handle_id, |_div: &mut Div| {});
|
//common.call_on_widget(data.slider_handle_id, |_div: &mut Div| {});
|
||||||
self.values.value = value;
|
self.values.value = value;
|
||||||
let mut style = state.tree.style(data.slider_handle_node).unwrap().clone();
|
let mut style = common.state.tree.style(data.slider_handle_node).unwrap().clone();
|
||||||
conf_handle_style(&self.values, data.slider_body_node, &mut style, &state.tree);
|
conf_handle_style(&self.values, data.slider_body_node, &mut style, &common.state.tree);
|
||||||
alterables.mark_dirty(data.slider_handle_node);
|
common.alterables.mark_dirty(data.slider_handle_node);
|
||||||
alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
alterables.set_style(data.slider_handle_node, style);
|
common.alterables.set_style(data.slider_handle_node, style);
|
||||||
state.widgets.call(data.slider_text_id, |label: &mut WidgetLabel| {
|
|
||||||
Self::update_text(&mut state.globals.i18n(), label, value);
|
if let Some(mut label) = common.state.widgets.get_as::<WidgetLabel>(data.slider_text_id) {
|
||||||
});
|
Self::update_text(common, &mut label, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +174,7 @@ fn on_enter_anim(common: &mut event::CallbackDataCommon, handle_id: WidgetID) {
|
|||||||
20,
|
20,
|
||||||
AnimationEasing::OutBack,
|
AnimationEasing::OutBack,
|
||||||
Box::new(move |common, data| {
|
Box::new(move |common, data| {
|
||||||
let rect = data.obj.get_as_mut::<WidgetRectangle>();
|
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
data.data.transform = get_anim_transform(data.pos, data.widget_size);
|
data.data.transform = get_anim_transform(data.pos, data.widget_size);
|
||||||
anim_rect(rect, data.pos);
|
anim_rect(rect, data.pos);
|
||||||
common.alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
@@ -187,7 +188,7 @@ fn on_leave_anim(common: &mut event::CallbackDataCommon, handle_id: WidgetID) {
|
|||||||
10,
|
10,
|
||||||
AnimationEasing::OutQuad,
|
AnimationEasing::OutQuad,
|
||||||
Box::new(move |common, data| {
|
Box::new(move |common, data| {
|
||||||
let rect = data.obj.get_as_mut::<WidgetRectangle>();
|
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
data.data.transform = get_anim_transform(1.0 - data.pos, data.widget_size);
|
data.data.transform = get_anim_transform(1.0 - data.pos, data.widget_size);
|
||||||
anim_rect(rect, 1.0 - data.pos);
|
anim_rect(rect, 1.0 - data.pos);
|
||||||
common.alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ impl Event {
|
|||||||
&& pos.y < transform.pos.y + transform.dim.y
|
&& pos.y < transform.pos.y + transform.dim.y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn test_mouse_within_transform(&self, transform: &Transform) -> bool {
|
pub fn test_mouse_within_transform(&self, transform: &Transform) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::MouseDown(evt) => Self::test_transform_pos(transform, evt.pos),
|
Self::MouseDown(evt) => Self::test_transform_pos(transform, evt.pos),
|
||||||
@@ -130,10 +129,17 @@ pub struct CallbackDataCommon<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CallbackDataCommon<'_> {
|
impl CallbackDataCommon<'_> {
|
||||||
|
|
||||||
pub fn i18n(&self) -> RefMut<I18n> {
|
pub fn i18n(&self) -> RefMut<I18n> {
|
||||||
self.state.globals.i18n()
|
self.state.globals.i18n()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// helper function
|
||||||
|
pub fn mark_widget_dirty(&mut self, id: WidgetID) {
|
||||||
|
if let Some(node_id) = self.state.nodes.get(id) {
|
||||||
|
self.alterables.mark_dirty(*node_id);
|
||||||
|
}
|
||||||
|
self.alterables.mark_redraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CallbackData<'a> {
|
pub struct CallbackData<'a> {
|
||||||
@@ -153,7 +159,7 @@ pub enum CallbackMetadata {
|
|||||||
|
|
||||||
impl CallbackMetadata {
|
impl CallbackMetadata {
|
||||||
// helper function
|
// helper function
|
||||||
|
|
||||||
pub const fn get_mouse_pos_absolute(&self) -> Option<Vec2> {
|
pub const fn get_mouse_pos_absolute(&self) -> Option<Vec2> {
|
||||||
match *self {
|
match *self {
|
||||||
Self::MouseButton(b) => Some(b.pos),
|
Self::MouseButton(b) => Some(b.pos),
|
||||||
@@ -162,7 +168,6 @@ impl CallbackMetadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn get_mouse_pos_relative(&self, transform_stack: &TransformStack) -> Option<Vec2> {
|
pub fn get_mouse_pos_relative(&self, transform_stack: &TransformStack) -> Option<Vec2> {
|
||||||
let mouse_pos_abs = self.get_mouse_pos_absolute()?;
|
let mouse_pos_abs = self.get_mouse_pos_absolute()?;
|
||||||
Some(mouse_pos_abs - transform_stack.get_pos())
|
Some(mouse_pos_abs - transform_stack.get_pos())
|
||||||
@@ -209,18 +214,11 @@ pub struct EventListener<U1, U2> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<U1, U2> EventListener<U1, U2> {
|
impl<U1, U2> EventListener<U1, U2> {
|
||||||
|
|
||||||
pub fn callback_for_kind(
|
pub fn callback_for_kind(
|
||||||
&self,
|
&self,
|
||||||
kind: EventListenerKind,
|
kind: EventListenerKind,
|
||||||
) -> Option<
|
) -> Option<&impl Fn(&mut CallbackDataCommon, &mut CallbackData, &mut U1, &mut U2) -> anyhow::Result<()>> {
|
||||||
&impl Fn(&mut CallbackDataCommon, &mut CallbackData, &mut U1, &mut U2) -> anyhow::Result<()>,
|
if self.kind == kind { Some(&self.callback) } else { None }
|
||||||
> {
|
|
||||||
if self.kind == kind {
|
|
||||||
Some(&self.callback)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,7 +309,6 @@ impl<U1, U2> EventListenerCollection<U1, U2> {
|
|||||||
log::debug!("EventListenerCollection: cleaned-up {count} expired events");
|
log::debug!("EventListenerCollection: cleaned-up {count} expired events");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn get(&self, widget_id: WidgetID) -> Option<&EventListenerVec<U1, U2>> {
|
pub fn get(&self, widget_id: WidgetID) -> Option<&EventListenerVec<U1, U2>> {
|
||||||
self.map.get(widget_id)
|
self.map.get(widget_id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,10 +29,8 @@ impl Widget {
|
|||||||
Self(Rc::new(RefCell::new(widget_state)))
|
Self(Rc::new(RefCell::new(widget_state)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// panics on failure
|
pub fn get_as_mut<T: 'static>(&self) -> Option<RefMut<T>> {
|
||||||
// TODO: panic-less alternative
|
RefMut::filter_map(self.0.borrow_mut(), |w| w.obj.get_as_mut::<T>()).ok()
|
||||||
pub fn get_as_mut<T: 'static>(&self) -> RefMut<T> {
|
|
||||||
RefMut::map(self.0.borrow_mut(), |w| w.obj.get_as_mut::<T>())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn state(&self) -> RefMut<WidgetState> {
|
pub fn state(&self) -> RefMut<WidgetState> {
|
||||||
@@ -54,7 +52,7 @@ impl WidgetMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_as<T: 'static>(&self, handle: WidgetID) -> Option<RefMut<T>> {
|
pub fn get_as<T: 'static>(&self, handle: WidgetID) -> Option<RefMut<T>> {
|
||||||
Some(self.0.get(handle)?.get_as_mut::<T>())
|
self.0.get(handle)?.get_as_mut::<T>()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, handle: WidgetID) -> Option<&Widget> {
|
pub fn get(&self, handle: WidgetID) -> Option<&Widget> {
|
||||||
@@ -62,16 +60,20 @@ impl WidgetMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert(&mut self, obj: Widget) -> WidgetID {
|
pub fn insert(&mut self, obj: Widget) -> WidgetID {
|
||||||
self.0.insert(obj)
|
self
|
||||||
|
.0
|
||||||
|
.try_insert_with_key::<_, ()>(|widget_id| {
|
||||||
|
obj.state().obj.set_id(widget_id);
|
||||||
|
Ok(obj)
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_single(&mut self, handle: WidgetID) {
|
pub fn remove_single(&mut self, handle: WidgetID) {
|
||||||
self.0.remove(handle);
|
self.0.remove(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// cast to specific widget type, does nothing if widget ID is expired
|
// cast to specific widget type, does nothing if widget ID is expired or the type is wrong
|
||||||
// panics in case if the widget type is wrong
|
|
||||||
// TODO: panic-less alternative
|
|
||||||
pub fn call<WIDGET, FUNC>(&self, widget_id: WidgetID, func: FUNC)
|
pub fn call<WIDGET, FUNC>(&self, widget_id: WidgetID, func: FUNC)
|
||||||
where
|
where
|
||||||
WIDGET: WidgetObj,
|
WIDGET: WidgetObj,
|
||||||
@@ -82,7 +84,9 @@ impl WidgetMap {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
func(&mut widget.get_as_mut::<WIDGET>());
|
if let Some(mut casted) = widget.get_as_mut::<WIDGET>() {
|
||||||
|
func(&mut casted);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +155,7 @@ impl Layout {
|
|||||||
) -> anyhow::Result<(WidgetID, taffy::NodeId)> {
|
) -> anyhow::Result<(WidgetID, taffy::NodeId)> {
|
||||||
let parent_node = *self.state.nodes.get(parent_widget_id).unwrap();
|
let parent_node = *self.state.nodes.get(parent_widget_id).unwrap();
|
||||||
|
|
||||||
self.needs_redraw = true;
|
self.mark_redraw();
|
||||||
|
|
||||||
add_child_internal(
|
add_child_internal(
|
||||||
&mut self.state.tree,
|
&mut self.state.tree,
|
||||||
@@ -181,7 +185,7 @@ impl Layout {
|
|||||||
self.collect_children_ids_recursive(widget_id, &mut ids);
|
self.collect_children_ids_recursive(widget_id, &mut ids);
|
||||||
|
|
||||||
if !ids.is_empty() {
|
if !ids.is_empty() {
|
||||||
self.needs_redraw = true;
|
self.mark_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (widget_id, node_id) in ids {
|
for (widget_id, node_id) in ids {
|
||||||
@@ -191,6 +195,10 @@ impl Layout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const fn mark_redraw(&mut self) {
|
||||||
|
self.needs_redraw = true;
|
||||||
|
}
|
||||||
|
|
||||||
fn process_pending_components(&mut self) -> anyhow::Result<()> {
|
fn process_pending_components(&mut self) -> anyhow::Result<()> {
|
||||||
let mut alterables = EventAlterables::default();
|
let mut alterables = EventAlterables::default();
|
||||||
|
|
||||||
@@ -365,7 +373,7 @@ impl Layout {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.needs_redraw = true;
|
self.mark_redraw();
|
||||||
log::debug!("re-computing layout, size {}x{}", size.x, size.y);
|
log::debug!("re-computing layout, size {}x{}", size.x, size.y);
|
||||||
self.prev_size = size;
|
self.prev_size = size;
|
||||||
|
|
||||||
@@ -429,13 +437,13 @@ impl Layout {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_alterables(&mut self, alterables: EventAlterables) -> anyhow::Result<()> {
|
pub fn process_alterables(&mut self, alterables: EventAlterables) -> anyhow::Result<()> {
|
||||||
for node in alterables.dirty_nodes {
|
for node in alterables.dirty_nodes {
|
||||||
self.state.tree.mark_dirty(node)?;
|
self.state.tree.mark_dirty(node)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if alterables.needs_redraw {
|
if alterables.needs_redraw {
|
||||||
self.needs_redraw = true;
|
self.mark_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
if alterables.trigger_haptics {
|
if alterables.trigger_haptics {
|
||||||
@@ -443,7 +451,7 @@ impl Layout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !alterables.animations.is_empty() {
|
if !alterables.animations.is_empty() {
|
||||||
self.needs_redraw = true;
|
self.mark_redraw();
|
||||||
for anim in alterables.animations {
|
for anim in alterables.animations {
|
||||||
self.animations.add(anim);
|
self.animations.add(anim);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -709,7 +709,7 @@ impl CustomAttribInfo<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_widget_as<T: 'static>(&self) -> Option<RefMut<T>> {
|
pub fn get_widget_as<T: 'static>(&self) -> Option<RefMut<T>> {
|
||||||
Some(self.widgets.get(self.widget_id)?.get_as_mut::<T>())
|
self.widgets.get(self.widget_id)?.get_as_mut::<T>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
|
use slotmap::Key;
|
||||||
|
|
||||||
|
use crate::layout::WidgetID;
|
||||||
|
|
||||||
use super::{WidgetObj, WidgetState};
|
use super::{WidgetObj, WidgetState};
|
||||||
|
|
||||||
pub struct WidgetDiv {}
|
pub struct WidgetDiv {
|
||||||
|
id: WidgetID,
|
||||||
|
}
|
||||||
|
|
||||||
impl WidgetDiv {
|
impl WidgetDiv {
|
||||||
pub fn create() -> WidgetState {
|
pub fn create() -> WidgetState {
|
||||||
WidgetState::new(Box::new(Self {}))
|
WidgetState::new(Box::new(Self { id: WidgetID::null() }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12,4 +18,12 @@ impl WidgetObj for WidgetDiv {
|
|||||||
fn draw(&mut self, _state: &mut super::DrawState, _params: &super::DrawParams) {
|
fn draw(&mut self, _state: &mut super::DrawState, _params: &super::DrawParams) {
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_id(&self) -> WidgetID {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_id(&mut self, id: WidgetID) {
|
||||||
|
self.id = id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
use cosmic_text::{Attrs, Buffer, Metrics, Shaping, Wrap};
|
use cosmic_text::{Attrs, Buffer, Metrics, Shaping, Wrap};
|
||||||
|
use slotmap::Key;
|
||||||
use taffy::AvailableSpace;
|
use taffy::AvailableSpace;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::{self, Boundary},
|
drawing::{self, Boundary},
|
||||||
|
event::CallbackDataCommon,
|
||||||
globals::Globals,
|
globals::Globals,
|
||||||
i18n::{I18n, Translation},
|
i18n::{I18n, Translation},
|
||||||
|
layout::WidgetID,
|
||||||
renderer_vk::text::{FONT_SYSTEM, TextStyle},
|
renderer_vk::text::{FONT_SYSTEM, TextStyle},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -19,6 +22,8 @@ pub struct WidgetLabelParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct WidgetLabel {
|
pub struct WidgetLabel {
|
||||||
|
id: WidgetID,
|
||||||
|
|
||||||
params: WidgetLabelParams,
|
params: WidgetLabelParams,
|
||||||
buffer: Rc<RefCell<Buffer>>,
|
buffer: Rc<RefCell<Buffer>>,
|
||||||
last_boundary: Boundary,
|
last_boundary: Boundary,
|
||||||
@@ -52,12 +57,15 @@ impl WidgetLabel {
|
|||||||
params,
|
params,
|
||||||
buffer: Rc::new(RefCell::new(buffer)),
|
buffer: Rc::new(RefCell::new(buffer)),
|
||||||
last_boundary: Boundary::default(),
|
last_boundary: Boundary::default(),
|
||||||
|
id: WidgetID::null(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_text(&mut self, i18n: &mut I18n, translation: Translation) {
|
// set text without layout/re-render update.
|
||||||
|
// Not recommended unless the widget wasn't rendered yet (first init).
|
||||||
|
pub fn set_text_simple(&mut self, i18n: &mut I18n, translation: Translation) -> bool {
|
||||||
if self.params.content == translation {
|
if self.params.content == translation {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.params.content = translation;
|
self.params.content = translation;
|
||||||
@@ -72,6 +80,15 @@ impl WidgetLabel {
|
|||||||
Shaping::Advanced,
|
Shaping::Advanced,
|
||||||
self.params.style.align.map(Into::into),
|
self.params.style.align.map(Into::into),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
// set text and check if it needs to be re-rendered/re-layouted
|
||||||
|
pub fn set_text(&mut self, common: &mut CallbackDataCommon, translation: Translation) {
|
||||||
|
if self.set_text_simple(&mut common.i18n(), translation) {
|
||||||
|
common.mark_widget_dirty(self.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,4 +135,12 @@ impl WidgetObj for WidgetLabel {
|
|||||||
let height = total_lines as f32 * buffer.metrics().line_height;
|
let height = total_lines as f32 * buffer.metrics().line_height;
|
||||||
taffy::Size { width, height }
|
taffy::Size { width, height }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_id(&self) -> WidgetID {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_id(&mut self, id: WidgetID) {
|
||||||
|
self.id = id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,6 +111,10 @@ pub struct DrawParams<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait WidgetObj: AnyTrait {
|
pub trait WidgetObj: AnyTrait {
|
||||||
|
// every widget stores their of id for convenience reasons
|
||||||
|
fn get_id(&self) -> WidgetID;
|
||||||
|
fn set_id(&mut self, id: WidgetID); // always set at insertion
|
||||||
|
|
||||||
fn draw(&mut self, state: &mut DrawState, params: &DrawParams);
|
fn draw(&mut self, state: &mut DrawState, params: &DrawParams);
|
||||||
fn measure(
|
fn measure(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -173,18 +177,14 @@ pub fn get_scrollbar_info(l: &taffy::Layout) -> Option<ScrollbarInfo> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl dyn WidgetObj {
|
impl dyn WidgetObj {
|
||||||
// panics on failure
|
pub fn get_as<T: 'static>(&self) -> Option<&T> {
|
||||||
// TODO: panic-less alternative
|
|
||||||
pub fn get_as<T: 'static>(&self) -> &T {
|
|
||||||
let any = self.as_any();
|
let any = self.as_any();
|
||||||
any.downcast_ref::<T>().unwrap()
|
any.downcast_ref::<T>()
|
||||||
}
|
}
|
||||||
|
|
||||||
// panics on failure
|
pub fn get_as_mut<T: 'static>(&mut self) -> Option<&mut T> {
|
||||||
// TODO: panic-less alternative
|
|
||||||
pub fn get_as_mut<T: 'static>(&mut self) -> &mut T {
|
|
||||||
let any = self.as_any_mut();
|
let any = self.as_any_mut();
|
||||||
any.downcast_mut::<T>().unwrap()
|
any.downcast_mut::<T>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
|
use slotmap::Key;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::{self, GradientMode},
|
drawing::{self, GradientMode},
|
||||||
|
layout::WidgetID,
|
||||||
widget::util::WLength,
|
widget::util::WLength,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -19,11 +22,15 @@ pub struct WidgetRectangleParams {
|
|||||||
|
|
||||||
pub struct WidgetRectangle {
|
pub struct WidgetRectangle {
|
||||||
pub params: WidgetRectangleParams,
|
pub params: WidgetRectangleParams,
|
||||||
|
id: WidgetID,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WidgetRectangle {
|
impl WidgetRectangle {
|
||||||
pub fn create(params: WidgetRectangleParams) -> WidgetState {
|
pub fn create(params: WidgetRectangleParams) -> WidgetState {
|
||||||
WidgetState::new(Box::new(Self { params }))
|
WidgetState::new(Box::new(Self {
|
||||||
|
params,
|
||||||
|
id: WidgetID::null(),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,9 +40,7 @@ impl WidgetObj for WidgetRectangle {
|
|||||||
|
|
||||||
let round_units = match self.params.round {
|
let round_units = match self.params.round {
|
||||||
WLength::Units(units) => units as u8,
|
WLength::Units(units) => units as u8,
|
||||||
WLength::Percent(percent) => {
|
WLength::Percent(percent) => (f32::min(boundary.size.x, boundary.size.y) * percent / 2.0) as u8,
|
||||||
(f32::min(boundary.size.x, boundary.size.y) * percent / 2.0) as u8
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
state.primitives.push(drawing::RenderPrimitive {
|
state.primitives.push(drawing::RenderPrimitive {
|
||||||
@@ -52,4 +57,12 @@ impl WidgetObj for WidgetRectangle {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_id(&self) -> WidgetID {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_id(&mut self, id: WidgetID) {
|
||||||
|
self.id = id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
use cosmic_text::{Attrs, Buffer, Color, Shaping, Weight};
|
use cosmic_text::{Attrs, Buffer, Color, Shaping, Weight};
|
||||||
|
use slotmap::Key;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::{self},
|
drawing::{self},
|
||||||
|
layout::WidgetID,
|
||||||
renderer_vk::text::{
|
renderer_vk::text::{
|
||||||
DEFAULT_METRICS, FONT_SYSTEM,
|
DEFAULT_METRICS, FONT_SYSTEM,
|
||||||
custom_glyph::{CustomGlyph, CustomGlyphData},
|
custom_glyph::{CustomGlyph, CustomGlyphData},
|
||||||
@@ -21,11 +23,15 @@ pub struct WidgetSpriteParams {
|
|||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct WidgetSprite {
|
pub struct WidgetSprite {
|
||||||
params: WidgetSpriteParams,
|
params: WidgetSpriteParams,
|
||||||
|
id: WidgetID,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WidgetSprite {
|
impl WidgetSprite {
|
||||||
pub fn create(params: WidgetSpriteParams) -> WidgetState {
|
pub fn create(params: WidgetSpriteParams) -> WidgetState {
|
||||||
WidgetState::new(Box::new(Self { params }))
|
WidgetState::new(Box::new(Self {
|
||||||
|
params,
|
||||||
|
id: WidgetID::null(),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,9 +68,7 @@ impl WidgetObj for WidgetSprite {
|
|||||||
{
|
{
|
||||||
let mut font_system = FONT_SYSTEM.lock();
|
let mut font_system = FONT_SYSTEM.lock();
|
||||||
let mut buffer = buffer.borrow_with(&mut font_system);
|
let mut buffer = buffer.borrow_with(&mut font_system);
|
||||||
let attrs = Attrs::new()
|
let attrs = Attrs::new().color(Color::rgb(255, 0, 255)).weight(Weight::BOLD);
|
||||||
.color(Color::rgb(255, 0, 255))
|
|
||||||
.weight(Weight::BOLD);
|
|
||||||
|
|
||||||
// set text last in order to avoid expensive re-shaping
|
// set text last in order to avoid expensive re-shaping
|
||||||
buffer.set_text("Error", &attrs, Shaping::Basic);
|
buffer.set_text("Error", &attrs, Shaping::Basic);
|
||||||
@@ -85,4 +89,12 @@ impl WidgetObj for WidgetSprite {
|
|||||||
) -> taffy::Size<f32> {
|
) -> taffy::Size<f32> {
|
||||||
taffy::Size::ZERO
|
taffy::Size::ZERO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_id(&self) -> WidgetID {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_id(&mut self, id: WidgetID) {
|
||||||
|
self.id = id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -324,7 +324,7 @@ fn on_enter_anim(
|
|||||||
10,
|
10,
|
||||||
AnimationEasing::OutBack,
|
AnimationEasing::OutBack,
|
||||||
Box::new(move |common, data| {
|
Box::new(move |common, data| {
|
||||||
let rect = data.obj.get_as_mut::<WidgetRectangle>();
|
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
set_anim_color(&key_state, rect, data.pos);
|
set_anim_color(&key_state, rect, data.pos);
|
||||||
data.data.transform = get_anim_transform(data.pos, data.widget_size);
|
data.data.transform = get_anim_transform(data.pos, data.widget_size);
|
||||||
common.alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
@@ -342,7 +342,7 @@ fn on_leave_anim(
|
|||||||
15,
|
15,
|
||||||
AnimationEasing::OutQuad,
|
AnimationEasing::OutQuad,
|
||||||
Box::new(move |common, data| {
|
Box::new(move |common, data| {
|
||||||
let rect = data.obj.get_as_mut::<WidgetRectangle>();
|
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
set_anim_color(&key_state, rect, 1.0 - data.pos);
|
set_anim_color(&key_state, rect, 1.0 - data.pos);
|
||||||
data.data.transform = get_anim_transform(1.0 - data.pos, data.widget_size);
|
data.data.transform = get_anim_transform(1.0 - data.pos, data.widget_size);
|
||||||
common.alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
@@ -358,7 +358,7 @@ fn on_press_anim(
|
|||||||
if key_state.drawn_state.get() {
|
if key_state.drawn_state.get() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let rect = data.obj.get_as_mut::<WidgetRectangle>();
|
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
rect.params.border_color = Color::new(1.0, 1.0, 1.0, 1.0);
|
rect.params.border_color = Color::new(1.0, 1.0, 1.0, 1.0);
|
||||||
common.alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
key_state.drawn_state.set(true);
|
key_state.drawn_state.set(true);
|
||||||
@@ -372,7 +372,7 @@ fn on_release_anim(
|
|||||||
if !key_state.drawn_state.get() {
|
if !key_state.drawn_state.get() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let rect = data.obj.get_as_mut::<WidgetRectangle>();
|
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
rect.params.border_color = key_state.border_color;
|
rect.params.border_color = key_state.border_color;
|
||||||
common.alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
key_state.drawn_state.set(false);
|
key_state.drawn_state.set(false);
|
||||||
|
|||||||
@@ -55,9 +55,9 @@ where
|
|||||||
if let Some(s) =
|
if let Some(s) =
|
||||||
tz_str.and_then(|tz| tz.split('/').next_back().map(|x| x.replace('_', " ")))
|
tz_str.and_then(|tz| tz.split('/').next_back().map(|x| x.replace('_', " ")))
|
||||||
{
|
{
|
||||||
label.set_text(&mut i18n, Translation::from_raw_text(&s));
|
label.set_text_simple(&mut i18n, Translation::from_raw_text(&s));
|
||||||
} else {
|
} else {
|
||||||
label.set_text(&mut i18n, Translation::from_raw_text("Local"));
|
label.set_text_simple(&mut i18n, Translation::from_raw_text("Local"));
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@@ -73,7 +73,7 @@ where
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let mut i18n = panel.layout.state.globals.i18n();
|
let mut i18n = panel.layout.state.globals.i18n();
|
||||||
label.set_text(&mut i18n, Translation::from_raw_text("ERR"));
|
label.set_text_simple(&mut i18n, Translation::from_raw_text("ERR"));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -158,7 +158,7 @@ struct ClockState {
|
|||||||
|
|
||||||
fn clock_on_tick(
|
fn clock_on_tick(
|
||||||
clock: &ClockState,
|
clock: &ClockState,
|
||||||
common: &event::CallbackDataCommon,
|
common: &mut event::CallbackDataCommon,
|
||||||
data: &mut event::CallbackData,
|
data: &mut event::CallbackData,
|
||||||
) {
|
) {
|
||||||
let date_time = clock.timezone.as_ref().map_or_else(
|
let date_time = clock.timezone.as_ref().map_or_else(
|
||||||
@@ -166,6 +166,6 @@ fn clock_on_tick(
|
|||||||
|tz| format!("{}", Local::now().with_timezone(tz).format(&clock.format)),
|
|tz| format!("{}", Local::now().with_timezone(tz).format(&clock.format)),
|
||||||
);
|
);
|
||||||
|
|
||||||
let label = data.obj.get_as_mut::<WidgetLabel>();
|
let label = data.obj.get_as_mut::<WidgetLabel>().unwrap();
|
||||||
label.set_text(&mut common.i18n(), Translation::from_raw_text(&date_time));
|
label.set_text(common, Translation::from_raw_text(&date_time));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user