|
@@ -1,7 +1,10 @@
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
use crate::{
|
|
|
- component::Component, layout::{LayoutCache, LayoutNode}, text::TextRenderer, window::{Window, WindowBuilder, WindowComponent, WindowEvent, WindowStateAccess}
|
|
|
+ component::Component,
|
|
|
+ layout::{LayoutCache, LayoutNode},
|
|
|
+ theme::Theme,
|
|
|
+ window::{Window, WindowBuilder, WindowComponent, WindowEvent, WindowStateAccess},
|
|
|
};
|
|
|
|
|
|
#[derive(Debug)]
|
|
@@ -10,15 +13,16 @@ pub enum UIControlMsg {
|
|
|
}
|
|
|
|
|
|
pub trait UIComponent: Sized + Component<ParentMsg = UIControlMsg> {
|
|
|
- fn init(&mut self, ui_handle: UIHandle);
|
|
|
- fn poll(&mut self) -> Vec<UIControlMsg>;
|
|
|
+ fn init(&mut self, ui_handle: &mut UIHandle);
|
|
|
+ fn poll(&mut self, ui_handle: &mut UIHandle) -> Vec<UIControlMsg>;
|
|
|
}
|
|
|
|
|
|
pub(crate) struct UIState {
|
|
|
pub(crate) layout_cache: std::rc::Rc<LayoutCache>,
|
|
|
pub(crate) window_states:
|
|
|
HashMap<winit::window::WindowId, std::rc::Weak<dyn WindowStateAccess>>,
|
|
|
- pub(crate) text_renderer: TextRenderer,
|
|
|
+ // pub(crate) text_renderer: TextRenderer,
|
|
|
+ pub(crate) theme: Theme,
|
|
|
}
|
|
|
|
|
|
pub struct UIHandle<'l> {
|
|
@@ -34,6 +38,10 @@ impl<'l> UIHandle<'l> {
|
|
|
pub fn new_layout_node(&self) -> LayoutNode {
|
|
|
LayoutNode::new(self.state.layout_cache.clone())
|
|
|
}
|
|
|
+
|
|
|
+ pub fn theme(&self) -> &Theme {
|
|
|
+ &self.state.theme
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
pub struct UI<UIC: UIComponent> {
|
|
@@ -55,7 +63,17 @@ impl<UIC: UIComponent> UI<UIC> {
|
|
|
state: UIState {
|
|
|
layout_cache: lcache,
|
|
|
window_states: Default::default(),
|
|
|
- text_renderer: TextRenderer::new(),
|
|
|
+ // text_renderer: TextRenderer::new(),
|
|
|
+ theme: Theme::default_with_font(
|
|
|
+ fontdue::Font::from_bytes(
|
|
|
+ std::fs::read(
|
|
|
+ "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf",
|
|
|
+ )
|
|
|
+ .unwrap(),
|
|
|
+ Default::default(),
|
|
|
+ )
|
|
|
+ .unwrap(),
|
|
|
+ ),
|
|
|
},
|
|
|
event_loop: Some(eloop),
|
|
|
ui_component: uic,
|
|
@@ -100,7 +118,10 @@ impl<UIC: UIComponent> UI<UIC> {
|
|
|
}
|
|
|
|
|
|
fn pump_events(&mut self, eloop: &winit::event_loop::ActiveEventLoop) {
|
|
|
- let evts = self.ui_component.poll();
|
|
|
+ let evts = self.ui_component.poll(&mut UIHandle {
|
|
|
+ eloop,
|
|
|
+ state: &mut self.state,
|
|
|
+ });
|
|
|
for evt in evts.into_iter() {
|
|
|
match evt {
|
|
|
UIControlMsg::Terminate => eloop.exit(),
|
|
@@ -112,7 +133,7 @@ impl<UIC: UIComponent> UI<UIC> {
|
|
|
impl<UIC: UIComponent> winit::application::ApplicationHandler<()> for UI<UIC> {
|
|
|
fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) {
|
|
|
if !self.initialized {
|
|
|
- self.ui_component.init(UIHandle {
|
|
|
+ self.ui_component.init(&mut UIHandle {
|
|
|
eloop: event_loop,
|
|
|
state: &mut self.state,
|
|
|
});
|
|
@@ -156,14 +177,14 @@ impl<UIC: UIComponent> winit::application::ApplicationHandler<()> for UI<UIC> {
|
|
|
|
|
|
pub struct OpinionatedUIComponent<'l, WC: WindowComponent> {
|
|
|
window: Option<Window<WC>>,
|
|
|
- builder: Option<Box<dyn FnOnce(&UIHandle) -> WC + 'l>>,
|
|
|
+ builder: Option<Box<dyn FnOnce(&mut UIHandle) -> WC + 'l>>,
|
|
|
}
|
|
|
|
|
|
-impl<'l, WC: WindowComponent> OpinionatedUIComponent<'l, WC> {
|
|
|
-
|
|
|
-}
|
|
|
+impl<'l, WC: WindowComponent> OpinionatedUIComponent<'l, WC> {}
|
|
|
|
|
|
-impl<'l, WC: WindowComponent<ParentMsg = UIControlMsg>> Component for OpinionatedUIComponent<'l, WC> {
|
|
|
+impl<'l, WC: WindowComponent<ParentMsg = UIControlMsg>> Component
|
|
|
+ for OpinionatedUIComponent<'l, WC>
|
|
|
+{
|
|
|
type ParentMsg = UIControlMsg;
|
|
|
type Msg = UIControlMsg;
|
|
|
|
|
@@ -172,22 +193,26 @@ impl<'l, WC: WindowComponent<ParentMsg = UIControlMsg>> Component for Opinionate
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl<'l, WC: WindowComponent<ParentMsg = UIControlMsg>> UIComponent for OpinionatedUIComponent<'l, WC> {
|
|
|
- fn init(&mut self, mut ui_handle: UIHandle) {
|
|
|
+impl<'l, WC: WindowComponent<ParentMsg = UIControlMsg>> UIComponent
|
|
|
+ for OpinionatedUIComponent<'l, WC>
|
|
|
+{
|
|
|
+ fn init(&mut self, ui_handle: &mut UIHandle) {
|
|
|
if let Some(builder) = self.builder.take() {
|
|
|
self.window = Some(ui_handle.window_builder().build(builder));
|
|
|
}
|
|
|
}
|
|
|
- fn poll(&mut self) -> Vec<UIControlMsg> {
|
|
|
+ fn poll(&mut self, uih: &mut UIHandle) -> Vec<UIControlMsg> {
|
|
|
if let Some(window) = self.window.as_mut() {
|
|
|
- window.poll()
|
|
|
+ window.poll(uih)
|
|
|
} else {
|
|
|
vec![]
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-pub fn make_opinionated_ui<'l, WC: WindowComponent<ParentMsg = UIControlMsg>>(wc: impl 'l + FnOnce(&UIHandle) -> WC) -> UI<OpinionatedUIComponent<'l, WC>> {
|
|
|
+pub fn make_opinionated_ui<'l, WC: WindowComponent<ParentMsg = UIControlMsg>>(
|
|
|
+ wc: impl 'l + FnOnce(&mut UIHandle) -> WC,
|
|
|
+) -> UI<OpinionatedUIComponent<'l, WC>> {
|
|
|
let ouic = OpinionatedUIComponent {
|
|
|
window: None,
|
|
|
builder: Some(Box::new(wc)),
|