add WguiFontSystem, remove FONT_SYSTEM singleton, custom fonts, add Light font weight
there are a few gzip-compressed ttf as for now, looks like variable fonts aren't parsed properly by cosmic_text. Not sure why. Also, we probably need to have a fallback for CJK characters in the future, or just fallback to the built-in ones in the OS.
This commit is contained in:
5
Cargo.lock
generated
5
Cargo.lock
generated
@@ -1852,9 +1852,9 @@ checksum = "b7ac824320a75a52197e8f2d787f6a38b6718bb6897a35142d749af3c0e8f4fe"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.1.2"
|
version = "1.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d"
|
checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
@@ -6278,6 +6278,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"cosmic-text",
|
"cosmic-text",
|
||||||
"etagere",
|
"etagere",
|
||||||
|
"flate2",
|
||||||
"glam",
|
"glam",
|
||||||
"image",
|
"image",
|
||||||
"log",
|
"log",
|
||||||
|
|||||||
BIN
dash-frontend/assets/Quicksand-Bold.ttf.gz
Normal file
BIN
dash-frontend/assets/Quicksand-Bold.ttf.gz
Normal file
Binary file not shown.
BIN
dash-frontend/assets/Quicksand-Light.ttf.gz
Normal file
BIN
dash-frontend/assets/Quicksand-Light.ttf.gz
Normal file
Binary file not shown.
BIN
dash-frontend/assets/Quicksand-Regular.ttf.gz
Normal file
BIN
dash-frontend/assets/Quicksand-Regular.ttf.gz
Normal file
Binary file not shown.
@@ -100,6 +100,8 @@
|
|||||||
<rectangle
|
<rectangle
|
||||||
width="100%"
|
width="100%"
|
||||||
height="48"
|
height="48"
|
||||||
|
min_height="48"
|
||||||
|
max_height="48"
|
||||||
box_sizing="border_box"
|
box_sizing="border_box"
|
||||||
round="8"
|
round="8"
|
||||||
flex_direction="row"
|
flex_direction="row"
|
||||||
@@ -130,7 +132,7 @@
|
|||||||
|
|
||||||
<!-- Right bottom side -->
|
<!-- Right bottom side -->
|
||||||
<div margin_right="16">
|
<div margin_right="16">
|
||||||
<label id="label_time" size="16" />
|
<label id="label_time" size="16" weight="light" />
|
||||||
</div>
|
</div>
|
||||||
</rectangle>
|
</rectangle>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ use std::{cell::RefCell, collections::VecDeque, rc::Rc};
|
|||||||
use chrono::Timelike;
|
use chrono::Timelike;
|
||||||
use glam::Vec2;
|
use glam::Vec2;
|
||||||
use wgui::{
|
use wgui::{
|
||||||
assets::AssetPath,
|
assets::{AssetPath, AssetProvider},
|
||||||
components::button::ComponentButton,
|
components::button::ComponentButton,
|
||||||
event::{CallbackDataCommon, EventAlterables},
|
font_config::WguiFontConfig,
|
||||||
globals::WguiGlobals,
|
globals::WguiGlobals,
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::{LayoutParams, RcLayout, WidgetID},
|
layout::{LayoutParams, RcLayout, WidgetID},
|
||||||
@@ -54,7 +54,22 @@ pub enum FrontendTask {
|
|||||||
|
|
||||||
impl Frontend {
|
impl Frontend {
|
||||||
pub fn new(params: InitParams) -> anyhow::Result<(RcFrontend, RcLayout)> {
|
pub fn new(params: InitParams) -> anyhow::Result<(RcFrontend, RcLayout)> {
|
||||||
let globals = WguiGlobals::new(Box::new(assets::Asset {}), wgui::globals::Defaults::default())?;
|
let mut assets = Box::new(assets::Asset {});
|
||||||
|
|
||||||
|
let font_binary_bold = assets.load_from_path_gzip("Quicksand-Bold.ttf.gz")?;
|
||||||
|
let font_binary_regular = assets.load_from_path_gzip("Quicksand-Regular.ttf.gz")?;
|
||||||
|
let font_binary_light = assets.load_from_path_gzip("Quicksand-Light.ttf.gz")?;
|
||||||
|
|
||||||
|
let globals = WguiGlobals::new(
|
||||||
|
assets,
|
||||||
|
wgui::globals::Defaults::default(),
|
||||||
|
&WguiFontConfig {
|
||||||
|
binaries: vec![&font_binary_regular, &font_binary_bold, &font_binary_light],
|
||||||
|
family_name_sans_serif: "Quicksand",
|
||||||
|
family_name_serif: "Quicksand",
|
||||||
|
family_name_monospace: "",
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
let (layout, state) = wgui::parser::new_layout_from_assets(
|
let (layout, state) = wgui::parser::new_layout_from_assets(
|
||||||
&ParseDocumentParams {
|
&ParseDocumentParams {
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
use wgui::{
|
use wgui::{
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
components::button::ComponentButton,
|
components::button::ComponentButton,
|
||||||
|
event::CallbackDataCommon,
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
|
layout::Widget,
|
||||||
parser::{Fetchable, ParseDocumentParams, ParserState},
|
parser::{Fetchable, ParseDocumentParams, ParserState},
|
||||||
widget::label::WidgetLabel,
|
widget::label::WidgetLabel,
|
||||||
};
|
};
|
||||||
@@ -23,7 +25,7 @@ impl Tab for TabHome {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_label_hello(label_hello: &mut WidgetLabel, i18n: &mut wgui::i18n::I18n, settings: &settings::Settings) {
|
fn configure_label_hello(common: &mut CallbackDataCommon, label_hello: Widget, settings: &settings::Settings) {
|
||||||
let mut username = various::get_username();
|
let mut username = various::get_username();
|
||||||
// first character as uppercase
|
// first character as uppercase
|
||||||
if let Some(first) = username.chars().next() {
|
if let Some(first) = username.chars().next() {
|
||||||
@@ -32,12 +34,13 @@ fn configure_label_hello(label_hello: &mut WidgetLabel, i18n: &mut wgui::i18n::I
|
|||||||
}
|
}
|
||||||
|
|
||||||
let translated = if !settings.home_screen.hide_username {
|
let translated = if !settings.home_screen.hide_username {
|
||||||
i18n.translate_and_replace("HELLO_USER", ("{USER}", &username))
|
common.i18n().translate_and_replace("HELLO_USER", ("{USER}", &username))
|
||||||
} else {
|
} else {
|
||||||
i18n.translate("HELLO").to_string()
|
common.i18n().translate("HELLO").to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
label_hello.set_text_simple(i18n, Translation::from_raw_text(&translated));
|
let mut label_hello = label_hello.get_as_mut::<WidgetLabel>().unwrap();
|
||||||
|
label_hello.set_text(common, Translation::from_raw_text(&translated));
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TabHome {
|
impl TabHome {
|
||||||
@@ -52,8 +55,9 @@ impl TabHome {
|
|||||||
params.parent_id,
|
params.parent_id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut label_hello = state.fetch_widget_as::<WidgetLabel>(¶ms.layout.state, "label_hello")?;
|
let mut c = params.layout.start_common();
|
||||||
configure_label_hello(&mut label_hello, &mut params.globals.i18n(), params.settings);
|
let widget_label = state.fetch_widget(&c.layout.state, "label_hello")?.widget;
|
||||||
|
configure_label_hello(&mut c.common(), widget_label, params.settings);
|
||||||
|
|
||||||
let btn_apps = state.fetch_component_as::<ComponentButton>("btn_apps")?;
|
let btn_apps = state.fetch_component_as::<ComponentButton>("btn_apps")?;
|
||||||
let btn_games = state.fetch_component_as::<ComponentButton>("btn_games")?;
|
let btn_games = state.fetch_component_as::<ComponentButton>("btn_games")?;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
use wgui::{
|
use wgui::{
|
||||||
components::button::ComponentButton,
|
components::button::ComponentButton,
|
||||||
event::CallbackDataCommon,
|
|
||||||
globals::WguiGlobals,
|
globals::WguiGlobals,
|
||||||
layout::{Layout, WidgetID},
|
layout::{Layout, WidgetID},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
use glam::{vec2, Vec2};
|
use glam::{Vec2, vec2};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use testbed::{testbed_any::TestbedAny, Testbed};
|
use testbed::{Testbed, testbed_any::TestbedAny};
|
||||||
use timestep::Timestep;
|
use timestep::Timestep;
|
||||||
|
use tracing_subscriber::EnvFilter;
|
||||||
use tracing_subscriber::filter::LevelFilter;
|
use tracing_subscriber::filter::LevelFilter;
|
||||||
use tracing_subscriber::layer::SubscriberExt;
|
use tracing_subscriber::layer::SubscriberExt;
|
||||||
use tracing_subscriber::util::SubscriberInitExt;
|
use tracing_subscriber::util::SubscriberInitExt;
|
||||||
use tracing_subscriber::EnvFilter;
|
|
||||||
use vulkan::init_window;
|
use vulkan::init_window;
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
|
Validated, VulkanError,
|
||||||
command_buffer::CommandBufferUsage,
|
command_buffer::CommandBufferUsage,
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{view::ImageView, ImageUsage},
|
image::{ImageUsage, view::ImageView},
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, CompositeAlpha, PresentMode, Surface, SurfaceInfo, Swapchain,
|
CompositeAlpha, PresentMode, Surface, SurfaceInfo, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreateInfo, SwapchainPresentInfo,
|
SwapchainPresentInfo, acquire_next_image,
|
||||||
},
|
},
|
||||||
sync::GpuFuture,
|
sync::GpuFuture,
|
||||||
Validated, VulkanError,
|
|
||||||
};
|
};
|
||||||
use wgui::{
|
use wgui::{
|
||||||
event::{MouseButtonIndex, MouseDownEvent, MouseMotionEvent, MouseUpEvent, MouseWheelEvent},
|
event::{MouseButtonIndex, MouseDownEvent, MouseMotionEvent, MouseUpEvent, MouseWheelEvent},
|
||||||
gfx::{cmd::WGfxClearMode, WGfx},
|
gfx::{WGfx, cmd::WGfxClearMode},
|
||||||
renderer_vk::{self},
|
renderer_vk::{self},
|
||||||
};
|
};
|
||||||
use winit::{
|
use winit::{
|
||||||
@@ -32,7 +32,7 @@ use winit::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
rate_limiter::RateLimiter,
|
rate_limiter::RateLimiter,
|
||||||
testbed::{
|
testbed::{
|
||||||
testbed_dashboard::TestbedDashboard, testbed_generic::TestbedGeneric, TestbedUpdateParams,
|
TestbedUpdateParams, testbed_dashboard::TestbedDashboard, testbed_generic::TestbedGeneric,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -337,7 +337,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut layout = testbed.layout().borrow_mut();
|
let mut layout = testbed.layout().borrow_mut();
|
||||||
|
let globals = layout.state.globals.clone();
|
||||||
|
let mut globals = globals.get();
|
||||||
|
|
||||||
let mut draw_params = wgui::drawing::DrawParams {
|
let mut draw_params = wgui::drawing::DrawParams {
|
||||||
|
globals: &mut globals,
|
||||||
layout: &mut layout,
|
layout: &mut layout,
|
||||||
debug_draw: debug_draw_enabled,
|
debug_draw: debug_draw_enabled,
|
||||||
alpha: timestep.alpha,
|
alpha: timestep.alpha,
|
||||||
@@ -347,7 +351,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
drop(layout);
|
drop(layout);
|
||||||
|
|
||||||
let draw_result = render_context
|
let draw_result = render_context
|
||||||
.draw(&mut shared_context, &mut cmd_buf, &primitives)
|
.draw(
|
||||||
|
&globals.font_system,
|
||||||
|
&mut shared_context,
|
||||||
|
&mut cmd_buf,
|
||||||
|
&primitives,
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
if debug_draw_enabled {
|
if debug_draw_enabled {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use crate::{
|
|||||||
use glam::Vec2;
|
use glam::Vec2;
|
||||||
use wgui::{
|
use wgui::{
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
|
font_config::WguiFontConfig,
|
||||||
globals::WguiGlobals,
|
globals::WguiGlobals,
|
||||||
layout::{LayoutParams, RcLayout},
|
layout::{LayoutParams, RcLayout},
|
||||||
parser::{ParseDocumentParams, ParserState},
|
parser::{ParseDocumentParams, ParserState},
|
||||||
@@ -24,6 +25,7 @@ impl TestbedAny {
|
|||||||
let globals = WguiGlobals::new(
|
let globals = WguiGlobals::new(
|
||||||
Box::new(assets::Asset {}),
|
Box::new(assets::Asset {}),
|
||||||
wgui::globals::Defaults::default(),
|
wgui::globals::Defaults::default(),
|
||||||
|
&WguiFontConfig::default(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let (layout, state) = wgui::parser::new_layout_from_assets(
|
let (layout, state) = wgui::parser::new_layout_from_assets(
|
||||||
|
|||||||
@@ -8,11 +8,12 @@ use glam::Vec2;
|
|||||||
use wgui::{
|
use wgui::{
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
components::{
|
components::{
|
||||||
|
Component,
|
||||||
button::{ButtonClickCallback, ComponentButton},
|
button::{ButtonClickCallback, ComponentButton},
|
||||||
checkbox::ComponentCheckbox,
|
checkbox::ComponentCheckbox,
|
||||||
Component,
|
|
||||||
},
|
},
|
||||||
drawing::Color,
|
drawing::Color,
|
||||||
|
font_config::WguiFontConfig,
|
||||||
globals::WguiGlobals,
|
globals::WguiGlobals,
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::{Layout, LayoutParams, RcLayout, Widget},
|
layout::{Layout, LayoutParams, RcLayout, Widget},
|
||||||
@@ -76,6 +77,7 @@ impl TestbedGeneric {
|
|||||||
let globals = WguiGlobals::new(
|
let globals = WguiGlobals::new(
|
||||||
Box::new(assets::Asset {}),
|
Box::new(assets::Asset {}),
|
||||||
wgui::globals::Defaults::default(),
|
wgui::globals::Defaults::default(),
|
||||||
|
&WguiFontConfig::default(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let extra = ParseDocumentExtra {
|
let extra = ParseDocumentExtra {
|
||||||
|
|||||||
@@ -30,3 +30,4 @@ taffy = "0.9.1"
|
|||||||
vulkano = { workspace = true }
|
vulkano = { workspace = true }
|
||||||
vulkano-shaders = { workspace = true }
|
vulkano-shaders = { workspace = true }
|
||||||
rust-embed = { workspace = true }
|
rust-embed = { workspace = true }
|
||||||
|
flate2 = "1.1.5"
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use flate2::read::GzDecoder;
|
||||||
|
use std::io::Read;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
@@ -74,6 +76,13 @@ impl Default for AssetPathOwned {
|
|||||||
|
|
||||||
pub trait AssetProvider {
|
pub trait AssetProvider {
|
||||||
fn load_from_path(&mut self, path: &str) -> anyhow::Result<Vec<u8>>;
|
fn load_from_path(&mut self, path: &str) -> anyhow::Result<Vec<u8>>;
|
||||||
|
fn load_from_path_gzip(&mut self, path: &str) -> anyhow::Result<Vec<u8>> {
|
||||||
|
let compressed = self.load_from_path(path)?;
|
||||||
|
let mut gz = GzDecoder::new(&compressed[..]);
|
||||||
|
let mut out = Vec::new();
|
||||||
|
gz.read_to_end(&mut out)?;
|
||||||
|
Ok(out)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace "./foo/bar/../file.txt" with "./foo/file.txt"
|
// replace "./foo/bar/../file.txt" with "./foo/file.txt"
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ use crate::{
|
|||||||
animation::{Animation, AnimationEasing},
|
animation::{Animation, AnimationEasing},
|
||||||
components::{Component, ComponentBase, ComponentTrait, InitData},
|
components::{Component, ComponentBase, ComponentTrait, InitData},
|
||||||
drawing::Color,
|
drawing::Color,
|
||||||
event::{CallbackDataCommon, EventAlterables, EventListenerCollection, EventListenerID, EventListenerKind},
|
event::{CallbackDataCommon, EventListenerCollection, EventListenerID, EventListenerKind},
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::{self, LayoutState, WidgetID, WidgetPair},
|
layout::{self, WidgetID, WidgetPair},
|
||||||
renderer_vk::text::{FontWeight, TextStyle},
|
renderer_vk::text::{FontWeight, TextStyle},
|
||||||
widget::{
|
widget::{
|
||||||
ConstructEssentials, EventResult,
|
ConstructEssentials, EventResult,
|
||||||
@@ -53,6 +53,7 @@ struct State {
|
|||||||
|
|
||||||
#[allow(clippy::struct_field_names)]
|
#[allow(clippy::struct_field_names)]
|
||||||
struct Data {
|
struct Data {
|
||||||
|
#[allow(dead_code)]
|
||||||
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
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ pub struct InitData<'a> {
|
|||||||
// common component data
|
// common component data
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ComponentBase {
|
pub struct ComponentBase {
|
||||||
|
#[allow(dead_code)]
|
||||||
lhandles: Vec<EventListenerID>,
|
lhandles: Vec<EventListenerID>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,8 @@ struct State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Data {
|
struct Data {
|
||||||
body: WidgetID, // Div
|
#[allow(dead_code)]
|
||||||
|
body: WidgetID, // Div
|
||||||
slider_handle_rect_id: WidgetID, // Rectangle
|
slider_handle_rect_id: WidgetID, // Rectangle
|
||||||
slider_text_id: WidgetID, // Text
|
slider_text_id: WidgetID, // Text
|
||||||
slider_handle_node: taffy::NodeId,
|
slider_handle_node: taffy::NodeId,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use taffy::TraversePartialTree;
|
|||||||
use crate::{
|
use crate::{
|
||||||
drawing,
|
drawing,
|
||||||
event::EventAlterables,
|
event::EventAlterables,
|
||||||
|
globals::Globals,
|
||||||
layout::Widget,
|
layout::Widget,
|
||||||
renderer_vk::text::{TextShadow, custom_glyph::CustomGlyph},
|
renderer_vk::text::{TextShadow, custom_glyph::CustomGlyph},
|
||||||
stack::{self, ScissorBoundary, ScissorStack, TransformStack},
|
stack::{self, ScissorBoundary, ScissorStack, TransformStack},
|
||||||
@@ -169,6 +170,7 @@ pub enum RenderPrimitive {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct DrawParams<'a> {
|
pub struct DrawParams<'a> {
|
||||||
|
pub globals: &'a Globals,
|
||||||
pub layout: &'a mut Layout,
|
pub layout: &'a mut Layout,
|
||||||
pub debug_draw: bool,
|
pub debug_draw: bool,
|
||||||
pub alpha: f32, // timestep alpha, 0.0 - 1.0, used for motion interpolation if rendering above tick rate: smoother animations or scrolling
|
pub alpha: f32, // timestep alpha, 0.0 - 1.0, used for motion interpolation if rendering above tick rate: smoother animations or scrolling
|
||||||
@@ -347,6 +349,7 @@ pub fn draw(params: &mut DrawParams) -> anyhow::Result<Vec<RenderPrimitive>> {
|
|||||||
let mut alterables = EventAlterables::default();
|
let mut alterables = EventAlterables::default();
|
||||||
|
|
||||||
let mut state = DrawState {
|
let mut state = DrawState {
|
||||||
|
globals: params.globals,
|
||||||
primitives: &mut primitives,
|
primitives: &mut primitives,
|
||||||
transform_stack: &mut transform_stack,
|
transform_stack: &mut transform_stack,
|
||||||
scissor_stack: &mut scissor_stack,
|
scissor_stack: &mut scissor_stack,
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ use std::{
|
|||||||
any::{Any, TypeId},
|
any::{Any, TypeId},
|
||||||
cell::RefMut,
|
cell::RefMut,
|
||||||
collections::HashSet,
|
collections::HashSet,
|
||||||
ops::Deref,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use glam::Vec2;
|
use glam::Vec2;
|
||||||
|
|||||||
45
wgui/src/font_config.rs
Normal file
45
wgui/src/font_config.rs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
use parking_lot::Mutex;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct WguiFontConfig<'a> {
|
||||||
|
pub binaries: Vec<&'a [u8]>,
|
||||||
|
pub family_name_sans_serif: &'a str,
|
||||||
|
pub family_name_serif: &'a str,
|
||||||
|
pub family_name_monospace: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct WguiFontSystem {
|
||||||
|
pub system: Mutex<cosmic_text::FontSystem>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WguiFontSystem {
|
||||||
|
pub fn new(config: &WguiFontConfig) -> Self {
|
||||||
|
let mut db = cosmic_text::fontdb::Database::new();
|
||||||
|
|
||||||
|
let system = if config.binaries.is_empty() {
|
||||||
|
cosmic_text::FontSystem::new()
|
||||||
|
} else {
|
||||||
|
for binary in &config.binaries {
|
||||||
|
// binary data is copied and preserved here
|
||||||
|
db.load_font_data(binary.to_vec());
|
||||||
|
}
|
||||||
|
|
||||||
|
if !config.family_name_sans_serif.is_empty() {
|
||||||
|
db.set_sans_serif_family(config.family_name_sans_serif);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !config.family_name_serif.is_empty() {
|
||||||
|
db.set_serif_family(config.family_name_serif);
|
||||||
|
}
|
||||||
|
|
||||||
|
// we don't require anything special, at least for now
|
||||||
|
let locale = String::from("C");
|
||||||
|
|
||||||
|
cosmic_text::FontSystem::new_with_locale_and_db(locale, db)
|
||||||
|
};
|
||||||
|
|
||||||
|
Self {
|
||||||
|
system: Mutex::new(system),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ use std::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
assets::{AssetPath, AssetProvider},
|
assets::{AssetPath, AssetProvider},
|
||||||
assets_internal, drawing,
|
assets_internal, drawing,
|
||||||
|
font_config::{WguiFontConfig, WguiFontSystem},
|
||||||
i18n::I18n,
|
i18n::I18n,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -31,13 +32,18 @@ pub struct Globals {
|
|||||||
pub assets_builtin: Box<dyn AssetProvider>,
|
pub assets_builtin: Box<dyn AssetProvider>,
|
||||||
pub i18n_builtin: I18n,
|
pub i18n_builtin: I18n,
|
||||||
pub defaults: Defaults,
|
pub defaults: Defaults,
|
||||||
|
pub font_system: WguiFontSystem,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct WguiGlobals(Rc<RefCell<Globals>>);
|
pub struct WguiGlobals(Rc<RefCell<Globals>>);
|
||||||
|
|
||||||
impl WguiGlobals {
|
impl WguiGlobals {
|
||||||
pub fn new(mut assets_builtin: Box<dyn AssetProvider>, defaults: Defaults) -> anyhow::Result<Self> {
|
pub fn new(
|
||||||
|
mut assets_builtin: Box<dyn AssetProvider>,
|
||||||
|
defaults: Defaults,
|
||||||
|
font_config: &WguiFontConfig,
|
||||||
|
) -> anyhow::Result<Self> {
|
||||||
let i18n_builtin = I18n::new(&mut assets_builtin)?;
|
let i18n_builtin = I18n::new(&mut assets_builtin)?;
|
||||||
let assets_internal = Box::new(assets_internal::AssetInternal {});
|
let assets_internal = Box::new(assets_internal::AssetInternal {});
|
||||||
|
|
||||||
@@ -46,6 +52,7 @@ impl WguiGlobals {
|
|||||||
assets_builtin,
|
assets_builtin,
|
||||||
i18n_builtin,
|
i18n_builtin,
|
||||||
defaults,
|
defaults,
|
||||||
|
font_system: WguiFontSystem::new(font_config),
|
||||||
}))))
|
}))))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,4 +88,8 @@ impl WguiGlobals {
|
|||||||
pub fn assets_builtin(&self) -> RefMut<'_, Box<dyn AssetProvider>> {
|
pub fn assets_builtin(&self) -> RefMut<'_, Box<dyn AssetProvider>> {
|
||||||
RefMut::map(self.0.borrow_mut(), |x| &mut x.assets_builtin)
|
RefMut::map(self.0.borrow_mut(), |x| &mut x.assets_builtin)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn font_system(&self) -> RefMut<'_, WguiFontSystem> {
|
||||||
|
RefMut::map(self.0.borrow_mut(), |x| &mut x.font_system)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ impl I18n {
|
|||||||
log::info!("Guessed system language: {lang}");
|
log::info!("Guessed system language: {lang}");
|
||||||
|
|
||||||
match lang.as_str() {
|
match lang.as_str() {
|
||||||
"en" | "pl" | "it" | "ja" | "es" => {}
|
"en" | "pl" | "it" | "ja" | "es" | "de" => {}
|
||||||
_ => {
|
_ => {
|
||||||
log::warn!("Unsupported language \"{}\", defaulting to \"en\".", lang.as_str());
|
log::warn!("Unsupported language \"{}\", defaulting to \"en\".", lang.as_str());
|
||||||
|
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ fn add_child_internal(
|
|||||||
|
|
||||||
pub struct LayoutCommon<'a> {
|
pub struct LayoutCommon<'a> {
|
||||||
alterables: EventAlterables,
|
alterables: EventAlterables,
|
||||||
layout: &'a mut Layout,
|
pub layout: &'a mut Layout,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayoutCommon<'_> {
|
impl LayoutCommon<'_> {
|
||||||
@@ -564,6 +564,8 @@ impl Layout {
|
|||||||
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;
|
||||||
|
|
||||||
|
let globals = self.state.globals.get();
|
||||||
|
|
||||||
self.state.tree.compute_layout_with_measure(
|
self.state.tree.compute_layout_with_measure(
|
||||||
self.tree_root_node,
|
self.tree_root_node,
|
||||||
taffy::Size {
|
taffy::Size {
|
||||||
@@ -583,7 +585,10 @@ impl Layout {
|
|||||||
None => taffy::Size::ZERO,
|
None => taffy::Size::ZERO,
|
||||||
Some(h) => {
|
Some(h) => {
|
||||||
if let Some(w) = self.state.widgets.get(*h) {
|
if let Some(w) = self.state.widgets.get(*h) {
|
||||||
w.0.borrow_mut().obj.measure(known_dimensions, available_space)
|
w.0
|
||||||
|
.borrow_mut()
|
||||||
|
.obj
|
||||||
|
.measure(&globals, known_dimensions, available_space)
|
||||||
} else {
|
} else {
|
||||||
taffy::Size::ZERO
|
taffy::Size::ZERO
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ mod assets_internal;
|
|||||||
pub mod components;
|
pub mod components;
|
||||||
pub mod drawing;
|
pub mod drawing;
|
||||||
pub mod event;
|
pub mod event;
|
||||||
|
pub mod font_config;
|
||||||
pub mod gfx;
|
pub mod gfx;
|
||||||
pub mod globals;
|
pub mod globals;
|
||||||
pub mod i18n;
|
pub mod i18n;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ mod widget_rectangle;
|
|||||||
mod widget_sprite;
|
mod widget_sprite;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
assets::{normalize_path, AssetPath, AssetPathOwned},
|
assets::{AssetPath, AssetPathOwned, normalize_path},
|
||||||
components::{Component, ComponentWeak},
|
components::{Component, ComponentWeak},
|
||||||
drawing::{self},
|
drawing::{self},
|
||||||
globals::WguiGlobals,
|
globals::WguiGlobals,
|
||||||
@@ -624,7 +624,7 @@ pub fn replace_vars(input: &str, vars: &HashMap<Rc<str>, Rc<str>>) -> Rc<str> {
|
|||||||
if let Some(replacement) = vars.get(input_var) {
|
if let Some(replacement) = vars.get(input_var) {
|
||||||
replacement.clone()
|
replacement.clone()
|
||||||
} else {
|
} else {
|
||||||
log::warn!("failed to replace var named \"{input_var}\" (not found)");
|
// failed to find var, return an empty string
|
||||||
Rc::from("")
|
Rc::from("")
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ pub fn parse_text_style(attribs: &[AttribPair]) -> TextStyle {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"weight" => match value {
|
"weight" => match value {
|
||||||
|
"light" => style.weight = Some(FontWeight::Light),
|
||||||
"normal" => style.weight = Some(FontWeight::Normal),
|
"normal" => style.weight = Some(FontWeight::Normal),
|
||||||
"bold" => style.weight = Some(FontWeight::Bold),
|
"bold" => style.weight = Some(FontWeight::Bold),
|
||||||
_ => {
|
_ => {
|
||||||
|
|||||||
@@ -7,13 +7,14 @@ use vulkano::pipeline::graphics::viewport;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::{self},
|
drawing::{self},
|
||||||
|
font_config,
|
||||||
gfx::{WGfx, cmd::GfxCommandBuffer},
|
gfx::{WGfx, cmd::GfxCommandBuffer},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
rect::{RectPipeline, RectRenderer},
|
rect::{RectPipeline, RectRenderer},
|
||||||
text::{
|
text::{
|
||||||
DEFAULT_METRICS, FONT_SYSTEM, SWASH_CACHE, TextArea, TextBounds,
|
DEFAULT_METRICS, SWASH_CACHE, TextArea, TextBounds,
|
||||||
text_atlas::{TextAtlas, TextPipeline},
|
text_atlas::{TextAtlas, TextPipeline},
|
||||||
text_renderer::TextRenderer,
|
text_renderer::TextRenderer,
|
||||||
},
|
},
|
||||||
@@ -51,6 +52,7 @@ impl RendererPass<'_> {
|
|||||||
|
|
||||||
fn submit(
|
fn submit(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
font_system: &font_config::WguiFontSystem,
|
||||||
gfx: &Arc<WGfx>,
|
gfx: &Arc<WGfx>,
|
||||||
viewport: &mut Viewport,
|
viewport: &mut Viewport,
|
||||||
cmd_buf: &mut GfxCommandBuffer,
|
cmd_buf: &mut GfxCommandBuffer,
|
||||||
@@ -90,7 +92,7 @@ impl RendererPass<'_> {
|
|||||||
self.rect_renderer.render(gfx, viewport, &vk_scissor, cmd_buf)?;
|
self.rect_renderer.render(gfx, viewport, &vk_scissor, cmd_buf)?;
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut font_system = FONT_SYSTEM.lock();
|
let mut font_system = font_system.system.lock();
|
||||||
let mut swash_cache = SWASH_CACHE.lock();
|
let mut swash_cache = SWASH_CACHE.lock();
|
||||||
|
|
||||||
self.text_renderer.prepare(
|
self.text_renderer.prepare(
|
||||||
@@ -217,6 +219,7 @@ impl Context {
|
|||||||
|
|
||||||
pub fn draw(
|
pub fn draw(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
font_system: &font_config::WguiFontSystem,
|
||||||
shared: &mut SharedContext,
|
shared: &mut SharedContext,
|
||||||
cmd_buf: &mut GfxCommandBuffer,
|
cmd_buf: &mut GfxCommandBuffer,
|
||||||
primitives: &[drawing::RenderPrimitive],
|
primitives: &[drawing::RenderPrimitive],
|
||||||
@@ -302,7 +305,13 @@ impl Context {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for mut pass in passes {
|
for mut pass in passes {
|
||||||
pass.submit(&shared.gfx, &mut self.viewport, cmd_buf, &mut atlas.text_atlas)?;
|
pass.submit(
|
||||||
|
font_system,
|
||||||
|
&shared.gfx,
|
||||||
|
&mut self.viewport,
|
||||||
|
cmd_buf,
|
||||||
|
&mut atlas.text_atlas,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ use parking_lot::Mutex;
|
|||||||
|
|
||||||
use crate::drawing::{self};
|
use crate::drawing::{self};
|
||||||
|
|
||||||
pub static FONT_SYSTEM: LazyLock<Mutex<FontSystem>> = LazyLock::new(|| Mutex::new(FontSystem::new()));
|
|
||||||
pub static SWASH_CACHE: LazyLock<Mutex<SwashCache>> = LazyLock::new(|| Mutex::new(SwashCache::new()));
|
pub static SWASH_CACHE: LazyLock<Mutex<SwashCache>> = LazyLock::new(|| Mutex::new(SwashCache::new()));
|
||||||
|
|
||||||
/// Used in case no `font_size` is defined
|
/// Used in case no `font_size` is defined
|
||||||
@@ -102,6 +101,7 @@ impl From<FontStyle> for Style {
|
|||||||
|
|
||||||
#[derive(Default, Debug, Clone, Copy)]
|
#[derive(Default, Debug, Clone, Copy)]
|
||||||
pub enum FontWeight {
|
pub enum FontWeight {
|
||||||
|
Light,
|
||||||
#[default]
|
#[default]
|
||||||
Normal,
|
Normal,
|
||||||
Bold,
|
Bold,
|
||||||
@@ -110,6 +110,7 @@ pub enum FontWeight {
|
|||||||
impl From<FontWeight> for Weight {
|
impl From<FontWeight> for Weight {
|
||||||
fn from(value: FontWeight) -> Self {
|
fn from(value: FontWeight) -> Self {
|
||||||
match value {
|
match value {
|
||||||
|
FontWeight::Light => Self::LIGHT,
|
||||||
FontWeight::Normal => Self::NORMAL,
|
FontWeight::Normal => Self::NORMAL,
|
||||||
FontWeight::Bold => Self::BOLD,
|
FontWeight::Bold => Self::BOLD,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ use crate::{
|
|||||||
drawing::{self, Boundary, PrimitiveExtent},
|
drawing::{self, Boundary, PrimitiveExtent},
|
||||||
event::CallbackDataCommon,
|
event::CallbackDataCommon,
|
||||||
globals::Globals,
|
globals::Globals,
|
||||||
i18n::{I18n, Translation},
|
i18n::Translation,
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
renderer_vk::text::{TextStyle, FONT_SYSTEM},
|
renderer_vk::text::TextStyle,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{WidgetObj, WidgetState};
|
use super::{WidgetObj, WidgetState};
|
||||||
@@ -41,7 +41,7 @@ impl WidgetLabel {
|
|||||||
|
|
||||||
let mut buffer = Buffer::new_empty(metrics);
|
let mut buffer = Buffer::new_empty(metrics);
|
||||||
{
|
{
|
||||||
let mut font_system = FONT_SYSTEM.lock();
|
let mut font_system = globals.font_system.system.lock();
|
||||||
let mut buffer = buffer.borrow_with(&mut font_system);
|
let mut buffer = buffer.borrow_with(&mut font_system);
|
||||||
buffer.set_wrap(wrap);
|
buffer.set_wrap(wrap);
|
||||||
|
|
||||||
@@ -63,19 +63,19 @@ impl WidgetLabel {
|
|||||||
|
|
||||||
// set text without layout/re-render update.
|
// set text without layout/re-render update.
|
||||||
// Not recommended unless the widget wasn't rendered yet (first init).
|
// Not recommended unless the widget wasn't rendered yet (first init).
|
||||||
pub fn set_text_simple(&mut self, i18n: &mut I18n, translation: Translation) -> bool {
|
pub fn set_text_simple(&mut self, globals: &mut Globals, translation: Translation) -> bool {
|
||||||
if self.params.content == translation {
|
if self.params.content == translation {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.params.content = translation;
|
self.params.content = translation;
|
||||||
let attrs = Attrs::from(&self.params.style);
|
let attrs = Attrs::from(&self.params.style);
|
||||||
let mut font_system = FONT_SYSTEM.lock();
|
let mut font_system = globals.font_system.system.lock();
|
||||||
|
|
||||||
let mut buffer = self.buffer.borrow_mut();
|
let mut buffer = self.buffer.borrow_mut();
|
||||||
buffer.set_rich_text(
|
buffer.set_rich_text(
|
||||||
&mut font_system,
|
&mut font_system,
|
||||||
[(self.params.content.generate(i18n).as_ref(), attrs)],
|
[(self.params.content.generate(&mut globals.i18n_builtin).as_ref(), attrs)],
|
||||||
&Attrs::new(),
|
&Attrs::new(),
|
||||||
Shaping::Advanced,
|
Shaping::Advanced,
|
||||||
self.params.style.align.map(Into::into),
|
self.params.style.align.map(Into::into),
|
||||||
@@ -93,7 +93,9 @@ impl WidgetLabel {
|
|||||||
|
|
||||||
// set text and check if it needs to be re-rendered/re-layouted
|
// set text and check if it needs to be re-rendered/re-layouted
|
||||||
pub fn set_text(&mut self, common: &mut CallbackDataCommon, translation: Translation) {
|
pub fn set_text(&mut self, common: &mut CallbackDataCommon, translation: Translation) {
|
||||||
if self.set_text_simple(&mut common.i18n(), translation) {
|
let mut globals = common.state.globals.get();
|
||||||
|
|
||||||
|
if self.set_text_simple(&mut globals, translation) {
|
||||||
common.mark_widget_dirty(self.id);
|
common.mark_widget_dirty(self.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,7 +115,7 @@ impl WidgetObj for WidgetLabel {
|
|||||||
|
|
||||||
if self.last_boundary != boundary {
|
if self.last_boundary != boundary {
|
||||||
self.last_boundary = boundary;
|
self.last_boundary = boundary;
|
||||||
let mut font_system = FONT_SYSTEM.lock();
|
let mut font_system = state.globals.font_system.system.lock();
|
||||||
let mut buffer = self.buffer.borrow_mut();
|
let mut buffer = self.buffer.borrow_mut();
|
||||||
buffer.set_size(&mut font_system, Some(boundary.size.x), Some(boundary.size.y));
|
buffer.set_size(&mut font_system, Some(boundary.size.x), Some(boundary.size.y));
|
||||||
}
|
}
|
||||||
@@ -130,6 +132,7 @@ impl WidgetObj for WidgetLabel {
|
|||||||
|
|
||||||
fn measure(
|
fn measure(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
globals: &Globals,
|
||||||
known_dimensions: taffy::Size<Option<f32>>,
|
known_dimensions: taffy::Size<Option<f32>>,
|
||||||
available_space: taffy::Size<taffy::AvailableSpace>,
|
available_space: taffy::Size<taffy::AvailableSpace>,
|
||||||
) -> taffy::Size<f32> {
|
) -> taffy::Size<f32> {
|
||||||
@@ -140,7 +143,8 @@ impl WidgetObj for WidgetLabel {
|
|||||||
AvailableSpace::Definite(width) => Some(width),
|
AvailableSpace::Definite(width) => Some(width),
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut font_system = FONT_SYSTEM.lock();
|
let wgui_font_system = &globals.font_system;
|
||||||
|
let mut font_system = wgui_font_system.system.lock();
|
||||||
let mut buffer = self.buffer.borrow_mut();
|
let mut buffer = self.buffer.borrow_mut();
|
||||||
|
|
||||||
buffer.set_size(&mut font_system, width_constraint, None);
|
buffer.set_size(&mut font_system, width_constraint, None);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use crate::{
|
|||||||
EventListenerKind::{self, InternalStateChange, MouseLeave},
|
EventListenerKind::{self, InternalStateChange, MouseLeave},
|
||||||
MouseWheelEvent,
|
MouseWheelEvent,
|
||||||
},
|
},
|
||||||
|
globals::Globals,
|
||||||
layout::{Layout, LayoutState, WidgetID},
|
layout::{Layout, LayoutState, WidgetID},
|
||||||
stack::{ScissorStack, TransformStack},
|
stack::{ScissorStack, TransformStack},
|
||||||
};
|
};
|
||||||
@@ -108,6 +109,7 @@ impl WidgetState {
|
|||||||
|
|
||||||
// global draw params
|
// global draw params
|
||||||
pub struct DrawState<'a> {
|
pub struct DrawState<'a> {
|
||||||
|
pub globals: &'a Globals,
|
||||||
pub layout: &'a Layout,
|
pub layout: &'a Layout,
|
||||||
pub primitives: &'a mut Vec<RenderPrimitive>,
|
pub primitives: &'a mut Vec<RenderPrimitive>,
|
||||||
pub transform_stack: &'a mut TransformStack,
|
pub transform_stack: &'a mut TransformStack,
|
||||||
@@ -151,6 +153,7 @@ pub trait WidgetObj: AnyTrait {
|
|||||||
|
|
||||||
fn measure(
|
fn measure(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
_globals: &Globals,
|
||||||
_known_dimensions: taffy::Size<Option<f32>>,
|
_known_dimensions: taffy::Size<Option<f32>>,
|
||||||
_available_space: taffy::Size<taffy::AvailableSpace>,
|
_available_space: taffy::Size<taffy::AvailableSpace>,
|
||||||
) -> taffy::Size<f32> {
|
) -> taffy::Size<f32> {
|
||||||
@@ -181,11 +184,7 @@ impl EventResult {
|
|||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn merge(self, other: Self) -> Self {
|
pub fn merge(self, other: Self) -> Self {
|
||||||
if self > other {
|
if self > other { self } else { other }
|
||||||
self
|
|
||||||
} else {
|
|
||||||
other
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ use slotmap::Key;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::{self, PrimitiveExtent},
|
drawing::{self, PrimitiveExtent},
|
||||||
|
globals::Globals,
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
renderer_vk::text::{
|
renderer_vk::text::{
|
||||||
|
DEFAULT_METRICS,
|
||||||
custom_glyph::{CustomGlyph, CustomGlyphData},
|
custom_glyph::{CustomGlyph, CustomGlyphData},
|
||||||
DEFAULT_METRICS, FONT_SYSTEM,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -67,7 +68,7 @@ impl WidgetObj for WidgetSprite {
|
|||||||
let mut buffer = Buffer::new_empty(DEFAULT_METRICS);
|
let mut buffer = Buffer::new_empty(DEFAULT_METRICS);
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut font_system = FONT_SYSTEM.lock();
|
let mut font_system = state.globals.font_system.system.lock();
|
||||||
let mut buffer = buffer.borrow_with(&mut font_system);
|
let mut buffer = buffer.borrow_with(&mut font_system);
|
||||||
let attrs = Attrs::new().color(Color::rgb(255, 0, 255)).weight(Weight::BOLD);
|
let attrs = Attrs::new().color(Color::rgb(255, 0, 255)).weight(Weight::BOLD);
|
||||||
|
|
||||||
@@ -88,6 +89,7 @@ impl WidgetObj for WidgetSprite {
|
|||||||
|
|
||||||
fn measure(
|
fn measure(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
_globals: &Globals,
|
||||||
_known_dimensions: taffy::Size<Option<f32>>,
|
_known_dimensions: taffy::Size<Option<f32>>,
|
||||||
_available_space: taffy::Size<taffy::AvailableSpace>,
|
_available_space: taffy::Size<taffy::AvailableSpace>,
|
||||||
) -> taffy::Size<f32> {
|
) -> taffy::Size<f32> {
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ use wgui::{
|
|||||||
event::{self, EventCallback},
|
event::{self, EventCallback},
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::Layout,
|
layout::Layout,
|
||||||
parser::{parse_color_hex, CustomAttribsInfoOwned},
|
parser::{CustomAttribsInfoOwned, parse_color_hex},
|
||||||
widget::{label::WidgetLabel, EventResult},
|
widget::{EventResult, label::WidgetLabel},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::state::AppState;
|
use crate::state::AppState;
|
||||||
@@ -123,13 +123,13 @@ pub(super) fn setup_custom_label<S: 'static>(
|
|||||||
|
|
||||||
let pretty_tz = maybe_pretty_tz.as_ref().map_or("Local", |x| x.as_str());
|
let pretty_tz = maybe_pretty_tz.as_ref().map_or("Local", |x| x.as_str());
|
||||||
|
|
||||||
let mut i18n = layout.state.globals.i18n();
|
let mut globals = layout.state.globals.get();
|
||||||
layout
|
layout
|
||||||
.state
|
.state
|
||||||
.widgets
|
.widgets
|
||||||
.get_as::<WidgetLabel>(attribs.widget_id)
|
.get_as::<WidgetLabel>(attribs.widget_id)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.set_text_simple(&mut i18n, Translation::from_raw_text(pretty_tz));
|
.set_text_simple(&mut globals, Translation::from_raw_text(pretty_tz));
|
||||||
|
|
||||||
// does not need to be dynamic
|
// does not need to be dynamic
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::{cell::RefCell, rc::Rc, sync::Arc};
|
use std::{cell::RefCell, rc::Rc, sync::Arc};
|
||||||
|
|
||||||
use button::setup_custom_button;
|
use button::setup_custom_button;
|
||||||
use glam::{vec2, Affine2, Vec2};
|
use glam::{Affine2, Vec2, vec2};
|
||||||
use label::setup_custom_label;
|
use label::setup_custom_label;
|
||||||
use vulkano::{command_buffer::CommandBufferUsage, image::view::ImageView};
|
use vulkano::{command_buffer::CommandBufferUsage, image::view::ImageView};
|
||||||
use wgui::{
|
use wgui::{
|
||||||
@@ -15,14 +15,14 @@ use wgui::{
|
|||||||
layout::{Layout, LayoutParams, WidgetID},
|
layout::{Layout, LayoutParams, WidgetID},
|
||||||
parser::ParserState,
|
parser::ParserState,
|
||||||
renderer_vk::context::Context as WguiContext,
|
renderer_vk::context::Context as WguiContext,
|
||||||
widget::{label::WidgetLabel, rectangle::WidgetRectangle, EventResult},
|
widget::{EventResult, label::WidgetLabel, rectangle::WidgetRectangle},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::input::{Haptics, HoverResult, PointerHit, PointerMode},
|
backend::input::{Haptics, HoverResult, PointerHit, PointerMode},
|
||||||
graphics::{CommandBuffers, ExtentExt},
|
graphics::{CommandBuffers, ExtentExt},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
windowing::backend::{ui_transform, FrameMeta, OverlayBackend, ShouldRender},
|
windowing::backend::{FrameMeta, OverlayBackend, ShouldRender, ui_transform},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{timer::GuiTimer, timestep::Timestep};
|
use super::{timer::GuiTimer, timestep::Timestep};
|
||||||
@@ -237,13 +237,21 @@ impl<S: 'static> OverlayBackend for GuiPanel<S> {
|
|||||||
wgui::gfx::cmd::WGfxClearMode::Clear([0.0, 0.0, 0.0, 0.0]),
|
wgui::gfx::cmd::WGfxClearMode::Clear([0.0, 0.0, 0.0, 0.0]),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let globals = self.layout.state.globals.clone(); // sorry
|
||||||
|
let mut globals = globals.get();
|
||||||
|
|
||||||
let primitives = wgui::drawing::draw(&mut wgui::drawing::DrawParams {
|
let primitives = wgui::drawing::draw(&mut wgui::drawing::DrawParams {
|
||||||
|
globals: &mut globals,
|
||||||
layout: &mut self.layout,
|
layout: &mut self.layout,
|
||||||
debug_draw: false,
|
debug_draw: false,
|
||||||
alpha,
|
alpha,
|
||||||
})?;
|
})?;
|
||||||
self.context
|
self.context.draw(
|
||||||
.draw(&mut app.wgui_shared, &mut cmd_buf, &primitives)?;
|
&globals.font_system,
|
||||||
|
&mut app.wgui_shared,
|
||||||
|
&mut cmd_buf,
|
||||||
|
&primitives,
|
||||||
|
)?;
|
||||||
cmd_buf.end_rendering()?;
|
cmd_buf.end_rendering()?;
|
||||||
buf.push(cmd_buf.build()?);
|
buf.push(cmd_buf.build()?);
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
use glam::Affine3A;
|
use glam::Affine3A;
|
||||||
use idmap::IdMap;
|
use idmap::IdMap;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{SmallVec, smallvec};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use wgui::{
|
use wgui::{
|
||||||
gfx::WGfx, globals::WguiGlobals, renderer_vk::context::SharedContext as WSharedContext,
|
font_config::WguiFontConfig, gfx::WGfx, globals::WguiGlobals,
|
||||||
|
renderer_vk::context::SharedContext as WSharedContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "wayvr")]
|
#[cfg(feature = "wayvr")]
|
||||||
@@ -97,6 +98,7 @@ impl AppState {
|
|||||||
wgui_globals: WguiGlobals::new(
|
wgui_globals: WguiGlobals::new(
|
||||||
Box::new(gui::asset::GuiAsset {}),
|
Box::new(gui::asset::GuiAsset {}),
|
||||||
wgui::globals::Defaults::default(),
|
wgui::globals::Defaults::default(),
|
||||||
|
&WguiFontConfig::default(),
|
||||||
)?,
|
)?,
|
||||||
|
|
||||||
#[cfg(feature = "osc")]
|
#[cfg(feature = "osc")]
|
||||||
|
|||||||
Reference in New Issue
Block a user