wgui: basic i18n support, refactoring: use LayoutState, translation framework (LLM-based generator)

This commit is contained in:
Aleksander
2025-08-02 23:31:23 +02:00
parent 4e46c45bcf
commit eaa81450b5
45 changed files with 916 additions and 223 deletions

View File

@@ -6,6 +6,7 @@ use crate::{
components::{Component, InitData},
drawing::{self, Color},
event::{CallbackDataCommon, EventListenerCollection, EventListenerKind, ListenerHandleVec},
i18n::Translation,
layout::{Layout, WidgetID},
renderer_vk::text::{FontWeight, TextStyle},
widget::{
@@ -15,8 +16,8 @@ use crate::{
},
};
pub struct Params<'a> {
pub text: &'a str,
pub struct Params {
pub text: Translation,
pub color: drawing::Color,
pub border_color: drawing::Color,
pub round: WLength,
@@ -24,10 +25,10 @@ pub struct Params<'a> {
pub text_style: TextStyle,
}
impl Default for Params<'_> {
impl Default for Params {
fn default() -> Self {
Self {
text: "Text",
text: Translation::from_raw_text(""),
color: drawing::Color::new(1.0, 1.0, 1.0, 1.0),
border_color: drawing::Color::new(0.0, 0.0, 0.0, 1.0),
round: WLength::Units(4.0),
@@ -55,12 +56,14 @@ impl Component for Button {
}
impl Button {
pub fn set_text<C>(&self, common: &mut CallbackDataCommon, text: &str) {
pub fn set_text<C>(&self, common: &mut CallbackDataCommon, text: Translation) {
let globals = common.state.globals.clone();
common
.refs
.state
.widgets
.call(self.data.text_id, |label: &mut TextLabel| {
label.set_text(text);
label.set_text(&mut globals.i18n(), text);
});
common.alterables.mark_redraw();
common.alterables.mark_dirty(self.data.text_node);
@@ -118,6 +121,8 @@ pub fn construct<U1, U2>(
style.justify_content = Some(JustifyContent::Center);
style.padding = length(1.0);
let globals = layout.state.globals.clone();
let (rect_id, _) = layout.add_child(
parent,
Rectangle::create(RectangleParams {
@@ -137,18 +142,21 @@ pub fn construct<U1, U2>(
let (text_id, text_node) = layout.add_child(
rect_id,
TextLabel::create(TextParams {
content: String::from(params.text),
style: TextStyle {
weight: Some(FontWeight::Bold),
color: Some(if light_text {
Color::new(1.0, 1.0, 1.0, 1.0)
} else {
Color::new(0.0, 0.0, 0.0, 1.0)
}),
..params.text_style
TextLabel::create(
&mut globals.i18n(),
TextParams {
content: params.text,
style: TextStyle {
weight: Some(FontWeight::Bold),
color: Some(if light_text {
Color::new(1.0, 1.0, 1.0, 1.0)
} else {
Color::new(0.0, 0.0, 0.0, 1.0)
}),
..params.text_style
},
},
})?,
)?,
taffy::Style {
..Default::default()
},

View File

@@ -1,18 +1,11 @@
use taffy::TaffyTree;
use crate::{
any::AnyTrait,
event::EventAlterables,
layout::{WidgetID, WidgetMap},
};
use crate::{any::AnyTrait, event::EventAlterables, layout::LayoutState};
pub mod button;
pub mod slider;
pub struct InitData<'a> {
pub state: &'a LayoutState,
pub alterables: &'a mut EventAlterables,
pub widgets: &'a WidgetMap,
pub tree: &'a TaffyTree<WidgetID>,
}
pub trait Component: AnyTrait {

View File

@@ -1,10 +1,7 @@
use std::{cell::RefCell, rc::Rc};
use glam::{Mat4, Vec2, Vec3};
use taffy::{
TaffyTree,
prelude::{length, percent},
};
use taffy::prelude::{length, percent};
use crate::{
animation::{Animation, AnimationEasing},
@@ -14,7 +11,8 @@ use crate::{
self, CallbackDataCommon, EventAlterables, EventListenerCollection, EventListenerKind,
ListenerHandleVec,
},
layout::{Layout, WidgetID, WidgetMap},
i18n::{I18n, Translation},
layout::{Layout, LayoutState, WidgetID},
renderer_vk::{
text::{FontWeight, HorizontalAlign, TextStyle},
util,
@@ -76,13 +74,7 @@ impl Component for Slider {
fn init(&self, init_data: &mut InitData) {
let mut state = self.state.borrow_mut();
let value = state.values.value;
state.set_value(
&self.data,
init_data.alterables,
init_data.widgets,
init_data.tree,
value,
);
state.set_value(init_data.state, &self.data, init_data.alterables, value);
}
}
@@ -128,44 +120,42 @@ impl SliderState {
let norm = map_mouse_x_to_normalized(
mouse_pos.x - HANDLE_WIDTH / 2.0,
get_width(data.slider_body_node, common.refs.tree) - HANDLE_WIDTH,
get_width(data.slider_body_node, &common.state.tree) - HANDLE_WIDTH,
);
let target_value = self.values.get_from_normalized(norm);
let val = target_value;
self.set_value(
data,
common.alterables,
common.refs.widgets,
common.refs.tree,
val,
);
self.set_value(common.state, data, common.alterables, val);
}
fn update_text(&self, text: &mut TextLabel, value: f32) {
fn update_text(&self, i18n: &mut I18n, text: &mut TextLabel, value: f32) {
// round displayed value, should be sufficient for now
text.set_text(&format!("{}", value.round()));
text.set_text(
i18n,
Translation::from_raw_text(&format!("{}", value.round())),
);
}
fn set_value(
&mut self,
state: &LayoutState,
data: &Data,
alterables: &mut EventAlterables,
widgets: &WidgetMap,
tree: &TaffyTree<WidgetID>,
value: f32,
) {
//common.call_on_widget(data.slider_handle_id, |_div: &mut Div| {});
self.values.value = value;
let mut style = tree.style(data.slider_handle_node).unwrap().clone();
conf_handle_style(&self.values, data.slider_body_node, &mut style, tree);
let mut style = state.tree.style(data.slider_handle_node).unwrap().clone();
conf_handle_style(&self.values, data.slider_body_node, &mut style, &state.tree);
alterables.mark_dirty(data.slider_handle_node);
alterables.mark_redraw();
alterables.set_style(data.slider_handle_node, style);
widgets.call(data.slider_text_id, |label: &mut TextLabel| {
self.update_text(label, value);
});
state
.widgets
.call(data.slider_text_id, |label: &mut TextLabel| {
self.update_text(&mut state.globals.i18n(), label, value);
});
}
}
@@ -398,16 +388,22 @@ pub fn construct<U1, U2>(
values: params.values,
};
let globals = layout.state.globals.clone();
let mut i18n = globals.i18n();
let (slider_text_id, _) = layout.add_child(
slider_handle_id,
TextLabel::create(TextParams {
content: String::new(),
style: TextStyle {
weight: Some(FontWeight::Bold),
align: Some(HorizontalAlign::Center),
..Default::default()
TextLabel::create(
&mut i18n,
TextParams {
content: Translation::default(),
style: TextStyle {
weight: Some(FontWeight::Bold),
align: Some(HorizontalAlign::Center),
..Default::default()
},
},
})?,
)?,
Default::default(),
)?;