Skip to content
Snippets Groups Projects
Commit 60d6f92e authored by StarArawn's avatar StarArawn
Browse files

A bunch of new changes:

- Added counter example.
- Added input events and widget event handling.
- Fixed multiple bugs.
- Turned off component diffing until I can figure out a good way of diffing props passed directly to children.
parent 7904e8bf
No related branches found
No related tags found
No related merge requests found
Showing
with 354 additions and 59 deletions
...@@ -2,6 +2,7 @@ use std::sync::{Arc, RwLock}; ...@@ -2,6 +2,7 @@ use std::sync::{Arc, RwLock};
use kayak_core::{ use kayak_core::{
context::KayakContext, context::KayakContext,
render_command::RenderCommand,
styles::{Style, StyleProp, Units}, styles::{Style, StyleProp, Units},
}; };
...@@ -12,6 +13,7 @@ pub struct BevyContext { ...@@ -12,6 +13,7 @@ pub struct BevyContext {
impl BevyContext { impl BevyContext {
pub fn new<F: Fn(&mut Style, &mut KayakContext)>(width: f32, height: f32, f: F) -> Self { pub fn new<F: Fn(&mut Style, &mut KayakContext)>(width: f32, height: f32, f: F) -> Self {
let mut app_styles = Style { let mut app_styles = Style {
render_command: StyleProp::Value(RenderCommand::Window),
width: StyleProp::Value(Units::Pixels(width)), width: StyleProp::Value(Units::Pixels(width)),
height: StyleProp::Value(Units::Pixels(height)), height: StyleProp::Value(Units::Pixels(height)),
..Style::default() ..Style::default()
......
use bevy::{prelude::{Plugin, ResMut}, render2::color::Color}; use bevy::{
input::{mouse::MouseButtonInput, ElementState},
math::Vec2,
prelude::{EventReader, MouseButton, Plugin, Res, ResMut},
render2::color::Color,
window::{CursorMoved, Windows},
};
mod bevy_context; mod bevy_context;
mod camera; mod camera;
...@@ -6,6 +12,7 @@ mod render; ...@@ -6,6 +12,7 @@ mod render;
pub use bevy_context::BevyContext; pub use bevy_context::BevyContext;
pub use camera::*; pub use camera::*;
use kayak_core::InputEvent;
#[derive(Default)] #[derive(Default)]
pub struct BevyKayakUIPlugin; pub struct BevyKayakUIPlugin;
...@@ -22,8 +29,40 @@ pub(crate) fn to_bevy_color(color: &kayak_core::color::Color) -> Color { ...@@ -22,8 +29,40 @@ pub(crate) fn to_bevy_color(color: &kayak_core::color::Color) -> Color {
Color::rgba(color.r, color.g, color.b, color.a) Color::rgba(color.r, color.g, color.b, color.a)
} }
pub fn update(bevy_context: ResMut<BevyContext>) { pub fn update(
bevy_context: ResMut<BevyContext>,
mut cursor_moved_events: EventReader<CursorMoved>,
mut mouse_button_input_events: EventReader<MouseButtonInput>,
windows: Res<Windows>,
) {
let window_size = if let Some(window) = windows.get_primary() {
Vec2::new(window.width(), window.height())
} else {
panic!("Couldn't find primary window!");
};
if let Ok(mut context) = bevy_context.kayak_context.write() { if let Ok(mut context) = bevy_context.kayak_context.write() {
context.render(); context.render();
let mut input_events = Vec::new();
for event in cursor_moved_events.iter() {
input_events.push(InputEvent::MouseMoved((
event.position.x as f32,
window_size.y - event.position.y as f32,
)));
}
for event in mouse_button_input_events.iter() {
match event.button {
MouseButton::Left => {
if event.state == ElementState::Pressed {
input_events.push(InputEvent::MouseLeftClick);
}
}
_ => {}
}
}
context.process_events(input_events);
} }
} }
...@@ -36,7 +36,7 @@ pub fn extract_quads(mut commands: Commands, context: Res<BevyContext>) { ...@@ -36,7 +36,7 @@ pub fn extract_quads(mut commands: Commands, context: Res<BevyContext>) {
extracted_quad: ExtractedQuad { extracted_quad: ExtractedQuad {
rect: Rect { rect: Rect {
min: Vec2::new(layout.posx, layout.posy), min: Vec2::new(layout.posx, layout.posy),
max: Vec2::new(layout.width, layout.height), max: Vec2::new(layout.posx + layout.width, layout.posy + layout.height),
}, },
color: to_bevy_color(background_color), color: to_bevy_color(background_color),
vertex_index: 0, vertex_index: 0,
......
...@@ -42,7 +42,12 @@ fn startup(mut commands: Commands, windows: Res<Windows>) { ...@@ -42,7 +42,12 @@ fn startup(mut commands: Commands, windows: Res<Windows>) {
let parent_id: Option<Index> = None; let parent_id: Option<Index> = None;
rsx! { rsx! {
<App styles={Some(styles.clone())}> <App styles={Some(styles.clone())}>
<TestState>{}</TestState> <Window position={(50.0, 50.0)} size={(300.0, 300.0)} title={"Window 1".to_string()}>
{}
</Window>
<Window position={(800.0, 50.0)} size={(200.0, 200.0)} title={"Window 2".to_string()}>
{}
</Window>
</App> </App>
} }
}); });
......
use bevy::{
math::Vec2,
prelude::{App as BevyApp, Commands, Res},
window::{WindowDescriptor, Windows},
PipelinedDefaultPlugins,
};
use bevy_kayak_ui::{BevyContext, BevyKayakUIPlugin, UICameraBundle};
use kayak_components::{Button, Text, Window};
use kayak_core::{
styles::{Style, StyleProp, Units},
EventType, Index, OnEvent,
};
use kayak_ui::components::App;
use kayak_ui::core::{rsx, widget};
#[widget]
fn Counter() {
let count = {
let x = context.create_state(0i32).unwrap();
*x
};
let text_styles = Style {
bottom: StyleProp::Value(Units::Stretch(1.0)),
left: StyleProp::Value(Units::Stretch(1.0)),
right: StyleProp::Value(Units::Stretch(1.0)),
top: StyleProp::Value(Units::Stretch(1.0)),
height: StyleProp::Value(Units::Pixels(26.0)),
..Default::default()
};
let id = self.get_id();
let on_event = OnEvent::new(move |context, event| match event.event_type {
EventType::Click => {
context.set_current_id(id);
context.set_state(count + 1);
}
_ => {}
});
rsx! {
<>
<Window position={(50.0, 50.0)} size={(300.0, 300.0)} title={"Counter Example".to_string()}>
<Text size={16.0} content={format!("Current Count: {}", count).to_string()}>{}</Text>
<Button on_event={Some(on_event)}>
<Text styles={Some(text_styles)} size={24.0} content={"Count!".to_string()}>{}</Text>
</Button>
</Window>
</>
}
}
fn startup(mut commands: Commands, windows: Res<Windows>) {
commands.spawn_bundle(UICameraBundle::new());
let window_size = if let Some(window) = windows.get_primary() {
Vec2::new(window.width(), window.height())
} else {
panic!("Couldn't find primary window!");
};
let context = BevyContext::new(window_size.x, window_size.y, |styles, context| {
// Hack to trick the proc macro for right now..
let parent_id: Option<Index> = None;
rsx! {
<App styles={Some(styles.clone())}>
<Counter />
</App>
}
});
commands.insert_resource(context);
}
fn main() {
BevyApp::new()
.insert_resource(WindowDescriptor {
width: 1270.0,
height: 720.0,
title: String::from("UI Example"),
..Default::default()
})
.add_plugins(PipelinedDefaultPlugins)
.add_plugin(BevyKayakUIPlugin)
.add_startup_system(startup)
.run();
}
use kayak_core::{
color::Color,
render_command::RenderCommand,
rsx,
styles::{Style, StyleProp, Units},
widget, Children, Fragment,
};
#[widget]
pub fn Button(children: Children, styles: Option<Style>) {
let base_styles = styles.clone().unwrap_or_default();
*styles = Some(Style {
render_command: StyleProp::Value(RenderCommand::Quad),
height: if base_styles.height == StyleProp::Default {
StyleProp::Value(Units::Pixels(45.0))
} else {
base_styles.height
},
background_color: if matches!(base_styles.background_color, StyleProp::Default) {
StyleProp::Value(Color::new(0.0781, 0.0898, 0.101, 1.0))
} else {
base_styles.background_color
},
..base_styles
});
rsx! {
<Fragment>
{children}
</Fragment>
}
}
mod app; mod app;
mod background; mod background;
mod button;
mod clip; mod clip;
mod text; mod text;
mod window; mod window;
pub use app::*; pub use app::*;
pub use background::*; pub use background::*;
pub use button::*;
pub use clip::*; pub use clip::*;
pub use text::*; pub use text::*;
pub use window::*; pub use window::*;
...@@ -16,22 +16,6 @@ pub fn Window( ...@@ -16,22 +16,6 @@ pub fn Window(
size: (f32, f32), size: (f32, f32),
title: String, title: String,
) { ) {
// let mut changed_styles = styles.clone().unwrap_or_default();
// changed_styles.render_command = RenderCommand::Quad;
// changed_styles.position_type = Some(PositionType::Absolute);
// changed_styles.background = Some(Color::new(0.0588, 0.0588, 0.588, 1.0));
// changed_styles.position = Some(Rect {
// start: Dimension::Points(position.x),
// end: Dimension::Points(position.x + size.width),
// top: Dimension::Points(position.y),
// bottom: Dimension::Points(position.y + size.height),
// });
// changed_styles.size = Some(Size {
// width: Dimension::Points(size.width),
// height: Dimension::Points(size.height),
// });
// styles = Some(changed_styles);
*styles = Some(Style { *styles = Some(Style {
background_color: StyleProp::Value(Color::new(0.125, 0.125, 0.125, 1.0)), background_color: StyleProp::Value(Color::new(0.125, 0.125, 0.125, 1.0)),
render_command: StyleProp::Value(RenderCommand::Quad), render_command: StyleProp::Value(RenderCommand::Quad),
...@@ -49,12 +33,7 @@ pub fn Window( ...@@ -49,12 +33,7 @@ pub fn Window(
..Style::default() ..Style::default()
}; };
let title_text_styles = Style { let title_text_styles = Style { ..Style::default() };
position_type: StyleProp::Value(PositionType::SelfDirected),
top: StyleProp::Value(Units::Pixels(-22.0)),
left: StyleProp::Value(Units::Pixels(5.0)),
..Style::default()
};
let title = title.clone(); let title = title.clone();
rsx! { rsx! {
......
...@@ -44,6 +44,7 @@ fn main() { ...@@ -44,6 +44,7 @@ fn main() {
height: StyleProp::Value(Units::Pixels(720.0)), height: StyleProp::Value(Units::Pixels(720.0)),
..Style::default() ..Style::default()
}), }),
on_event: None,
}; };
let (_, widget_id) = context.widget_manager.create_widget(0, my_widget, None); let (_, widget_id) = context.widget_manager.create_widget(0, my_widget, None);
......
...@@ -2,12 +2,13 @@ use std::collections::HashMap; ...@@ -2,12 +2,13 @@ use std::collections::HashMap;
use resources::Ref; use resources::Ref;
use crate::widget_manager::WidgetManager; use crate::{node::NodeIndex, widget_manager::WidgetManager, Event, EventType, Index, InputEvent};
pub struct KayakContext { pub struct KayakContext {
component_states: HashMap<crate::Index, resources::Resources>, component_states: HashMap<crate::Index, resources::Resources>,
current_id: crate::Index, current_id: crate::Index,
pub widget_manager: WidgetManager, pub widget_manager: WidgetManager,
last_mouse_position: (f32, f32),
} }
impl std::fmt::Debug for KayakContext { impl std::fmt::Debug for KayakContext {
...@@ -24,6 +25,7 @@ impl KayakContext { ...@@ -24,6 +25,7 @@ impl KayakContext {
component_states: HashMap::new(), component_states: HashMap::new(),
current_id: crate::Index::default(), current_id: crate::Index::default(),
widget_manager: WidgetManager::new(), widget_manager: WidgetManager::new(),
last_mouse_position: (0.0, 0.0),
} }
} }
...@@ -72,10 +74,7 @@ impl KayakContext { ...@@ -72,10 +74,7 @@ impl KayakContext {
); );
} }
} else { } else {
panic!( // Do nothing..
"No state created for component with id: {:?}!",
self.current_id
);
} }
} }
...@@ -99,4 +98,64 @@ impl KayakContext { ...@@ -99,4 +98,64 @@ impl KayakContext {
self.widget_manager.render(); self.widget_manager.render();
self.widget_manager.calculate_layout(); self.widget_manager.calculate_layout();
} }
pub fn process_events(&mut self, input_events: Vec<InputEvent>) {
let mut events_stream = Vec::new();
for (index, _) in self.widget_manager.nodes.iter() {
if let Some(layout) = self.widget_manager.layout_cache.rect.get(&NodeIndex(index)) {
for input_event in input_events.iter() {
match input_event {
InputEvent::MouseMoved(point) => {
// Hover event.
if layout.contains(point) {
let hover_event = Event {
target: index,
event_type: EventType::Hover,
..Event::default()
};
events_stream.push(hover_event);
}
self.last_mouse_position = *point;
}
InputEvent::MouseLeftClick => {
if layout.contains(&self.last_mouse_position) {
let click_event = Event {
target: index,
event_type: EventType::Click,
..Event::default()
};
events_stream.push(click_event);
}
}
}
}
}
}
// Propagate Events
for event in events_stream.iter_mut() {
let mut parents: Vec<Index> = Vec::new();
self.get_all_parents(event.target, &mut parents);
// First call target
let mut target_widget = self.widget_manager.take(event.target);
target_widget.on_event(self, event);
self.widget_manager.repossess(target_widget);
for parent in parents {
if event.should_propagate {
let mut parent_widget = self.widget_manager.take(parent);
parent_widget.on_event(self, event);
self.widget_manager.repossess(parent_widget);
}
}
}
}
fn get_all_parents(&self, current: Index, parents: &mut Vec<Index>) {
if let Some(parent) = self.widget_manager.tree.parents.get(&current) {
parents.push(*parent);
self.get_all_parents(*parent, parents);
}
}
} }
use crate::Index;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Event {
pub target: Index,
pub event_type: EventType,
pub(crate) should_propagate: bool,
}
impl Default for Event {
fn default() -> Self {
Self {
target: Default::default(),
event_type: EventType::Click,
should_propagate: true,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum EventType {
Click,
Hover,
}
...@@ -6,9 +6,11 @@ use crate::{context::KayakContext, styles::Style, Index, Widget}; ...@@ -6,9 +6,11 @@ use crate::{context::KayakContext, styles::Style, Index, Widget};
#[derivative(Debug, PartialEq)] #[derivative(Debug, PartialEq)]
pub struct Fragment { pub struct Fragment {
pub id: Index, pub id: Index,
pub styles: Option<Style>,
#[derivative(Debug = "ignore", PartialEq = "ignore")] #[derivative(Debug = "ignore", PartialEq = "ignore")]
pub children: crate::Children, pub children: crate::Children,
pub styles: Option<Style>, #[derivative(Debug = "ignore", PartialEq = "ignore")]
pub on_event: Option<crate::OnEvent>,
} }
impl Widget for Fragment { impl Widget for Fragment {
...@@ -24,6 +26,14 @@ impl Widget for Fragment { ...@@ -24,6 +26,14 @@ impl Widget for Fragment {
self.styles.clone() self.styles.clone()
} }
fn get_name(&self) -> String {
String::from("Fragment")
}
fn on_event(&mut self, _context: &mut KayakContext, _event: &mut crate::Event) {
// Do nothing.
}
fn render(&mut self, context: &mut KayakContext) { fn render(&mut self, context: &mut KayakContext) {
dbg!("Rendering fragment children!"); dbg!("Rendering fragment children!");
if let Some(children) = self.children.as_ref() { if let Some(children) = self.children.as_ref() {
......
pub enum InputEvent {
MouseMoved((f32, f32)),
MouseLeftClick,
}
...@@ -13,6 +13,13 @@ pub struct Rect { ...@@ -13,6 +13,13 @@ pub struct Rect {
pub z_index: f32, pub z_index: f32,
} }
impl Rect {
pub fn contains(&self, point: &(f32, f32)) -> bool {
(point.0 >= self.posx && point.0 <= self.posx + self.width)
&& (point.1 >= self.posy && point.1 <= self.posy + self.height)
}
}
#[derive(Debug, Default, Clone, Copy)] #[derive(Debug, Default, Clone, Copy)]
pub struct Space { pub struct Space {
pub left: f32, pub left: f32,
......
pub mod color; pub mod color;
pub mod context; pub mod context;
pub mod event;
pub mod fragment; pub mod fragment;
pub(crate) mod generational_arena;
mod input_event;
pub mod layout_cache; pub mod layout_cache;
pub mod node; pub mod node;
pub mod render_command; pub mod render_command;
...@@ -10,19 +13,47 @@ pub mod tree; ...@@ -10,19 +13,47 @@ pub mod tree;
pub mod widget; pub mod widget;
pub mod widget_manager; pub mod widget_manager;
pub(crate) mod generational_arena; use std::sync::{Arc, RwLock};
pub use event::*;
pub use fragment::Fragment;
pub use generational_arena::{Arena, Index}; pub use generational_arena::{Arena, Index};
pub use input_event::*;
pub use kayak_render_macros::{render, rsx, widget};
pub use widget::Widget; pub use widget::Widget;
pub use kayak_render_macros::{render, rsx, widget}; pub type Children =
Option<Arc<dyn Fn(Option<crate::Index>, &mut crate::context::KayakContext) + Send + Sync>>;
pub use fragment::Fragment; #[derive(Clone)]
pub struct OnEvent(
pub Arc<
RwLock<dyn FnMut(&mut crate::context::KayakContext, &mut Event) + Send + Sync + 'static>,
>,
);
impl OnEvent {
pub fn new<F: FnMut(&mut crate::context::KayakContext, &mut Event) + Send + Sync + 'static>(
f: F,
) -> OnEvent {
OnEvent(Arc::new(RwLock::new(f)))
}
}
// impl std::ops::Deref for OnEvent {
// type Target =
// Arc<RwLock<dyn FnMut(&mut crate::context::KayakContext, &mut Event) + Send + Sync>>;
// fn deref(&self) -> &Self::Target {
// &self.0
// }
// }
pub type Children = Option< // impl std::ops::DerefMut for OnEvent {
std::sync::Arc<dyn Fn(Option<crate::Index>, &mut crate::context::KayakContext) + Send + Sync>, // fn deref_mut(&mut self) -> &mut Self::Target {
>; // &mut self.0
// }
// }
pub mod derivative { pub mod derivative {
pub use derivative::*; pub use derivative::*;
......
...@@ -73,11 +73,11 @@ impl<'a> morphorm::Node<'a> for NodeIndex { ...@@ -73,11 +73,11 @@ impl<'a> morphorm::Node<'a> for NodeIndex {
return match node.styles.layout_type { return match node.styles.layout_type {
StyleProp::Default => Some(morphorm::LayoutType::default()), StyleProp::Default => Some(morphorm::LayoutType::default()),
StyleProp::Value(prop) => Some(prop), StyleProp::Value(prop) => Some(prop),
_ => None, _ => Some(morphorm::LayoutType::default()),
}; };
} }
} }
return None; return Some(morphorm::LayoutType::default());
} }
fn position_type(&self, store: &'_ Self::Data) -> Option<morphorm::PositionType> { fn position_type(&self, store: &'_ Self::Data) -> Option<morphorm::PositionType> {
...@@ -86,11 +86,11 @@ impl<'a> morphorm::Node<'a> for NodeIndex { ...@@ -86,11 +86,11 @@ impl<'a> morphorm::Node<'a> for NodeIndex {
return match node.styles.position_type { return match node.styles.position_type {
StyleProp::Default => Some(morphorm::PositionType::default()), StyleProp::Default => Some(morphorm::PositionType::default()),
StyleProp::Value(prop) => Some(prop), StyleProp::Value(prop) => Some(prop),
_ => None, _ => Some(morphorm::PositionType::default()),
}; };
} }
} }
return None; return Some(morphorm::PositionType::default());
} }
fn width(&self, store: &'_ Self::Data) -> Option<morphorm::Units> { fn width(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
...@@ -99,11 +99,11 @@ impl<'a> morphorm::Node<'a> for NodeIndex { ...@@ -99,11 +99,11 @@ impl<'a> morphorm::Node<'a> for NodeIndex {
return match node.styles.width { return match node.styles.width {
StyleProp::Default => Some(morphorm::Units::Stretch(1.0)), StyleProp::Default => Some(morphorm::Units::Stretch(1.0)),
StyleProp::Value(prop) => Some(prop), StyleProp::Value(prop) => Some(prop),
_ => None, _ => Some(morphorm::Units::Stretch(1.0)),
}; };
} }
} }
return None; return Some(morphorm::Units::Stretch(1.0));
} }
fn height(&self, store: &'_ Self::Data) -> Option<morphorm::Units> { fn height(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
...@@ -112,11 +112,11 @@ impl<'a> morphorm::Node<'a> for NodeIndex { ...@@ -112,11 +112,11 @@ impl<'a> morphorm::Node<'a> for NodeIndex {
return match node.styles.height { return match node.styles.height {
StyleProp::Default => Some(morphorm::Units::Stretch(1.0)), StyleProp::Default => Some(morphorm::Units::Stretch(1.0)),
StyleProp::Value(prop) => Some(prop), StyleProp::Value(prop) => Some(prop),
_ => None, _ => Some(morphorm::Units::Stretch(1.0)),
}; };
} }
} }
return None; return Some(morphorm::Units::Stretch(1.0));
} }
fn min_width(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> { fn min_width(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
...@@ -141,11 +141,11 @@ impl<'a> morphorm::Node<'a> for NodeIndex { ...@@ -141,11 +141,11 @@ impl<'a> morphorm::Node<'a> for NodeIndex {
return match node.styles.left { return match node.styles.left {
StyleProp::Default => Some(morphorm::Units::Auto), StyleProp::Default => Some(morphorm::Units::Auto),
StyleProp::Value(prop) => Some(prop), StyleProp::Value(prop) => Some(prop),
_ => None, _ => Some(morphorm::Units::Auto),
}; };
} }
} }
return None; return Some(morphorm::Units::Auto);
} }
fn right(&self, store: &'_ Self::Data) -> Option<morphorm::Units> { fn right(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
...@@ -154,11 +154,11 @@ impl<'a> morphorm::Node<'a> for NodeIndex { ...@@ -154,11 +154,11 @@ impl<'a> morphorm::Node<'a> for NodeIndex {
return match node.styles.right { return match node.styles.right {
StyleProp::Default => Some(morphorm::Units::Auto), StyleProp::Default => Some(morphorm::Units::Auto),
StyleProp::Value(prop) => Some(prop), StyleProp::Value(prop) => Some(prop),
_ => None, _ => Some(morphorm::Units::Auto),
}; };
} }
} }
return None; return Some(morphorm::Units::Auto);
} }
fn top(&self, store: &'_ Self::Data) -> Option<morphorm::Units> { fn top(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
...@@ -167,11 +167,11 @@ impl<'a> morphorm::Node<'a> for NodeIndex { ...@@ -167,11 +167,11 @@ impl<'a> morphorm::Node<'a> for NodeIndex {
return match node.styles.top { return match node.styles.top {
StyleProp::Default => Some(morphorm::Units::Auto), StyleProp::Default => Some(morphorm::Units::Auto),
StyleProp::Value(prop) => Some(prop), StyleProp::Value(prop) => Some(prop),
_ => None, _ => Some(morphorm::Units::Auto),
}; };
} }
} }
return None; return Some(morphorm::Units::Auto);
} }
fn bottom(&self, store: &'_ Self::Data) -> Option<morphorm::Units> { fn bottom(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
...@@ -180,11 +180,11 @@ impl<'a> morphorm::Node<'a> for NodeIndex { ...@@ -180,11 +180,11 @@ impl<'a> morphorm::Node<'a> for NodeIndex {
return match node.styles.bottom { return match node.styles.bottom {
StyleProp::Default => Some(morphorm::Units::Auto), StyleProp::Default => Some(morphorm::Units::Auto),
StyleProp::Value(prop) => Some(prop), StyleProp::Value(prop) => Some(prop),
_ => None, _ => Some(morphorm::Units::Auto),
}; };
} }
} }
return None; return Some(morphorm::Units::Auto);
} }
fn min_left(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> { fn min_left(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
......
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum RenderCommand { pub enum RenderCommand {
Empty, Empty,
Window,
Clip, Clip,
Quad, Quad,
Text { Text {
......
use crate::{color::Color, layout_cache::Rect, render_command::RenderCommand, styles::Style}; use crate::{
color::Color,
layout_cache::Rect,
render_command::RenderCommand,
styles::{Style, StyleProp},
};
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum RenderPrimitive { pub enum RenderPrimitive {
...@@ -34,13 +39,20 @@ impl From<&Style> for RenderPrimitive { ...@@ -34,13 +39,20 @@ impl From<&Style> for RenderPrimitive {
fn from(style: &Style) -> Self { fn from(style: &Style) -> Self {
let render_command = style.render_command.resolve(); let render_command = style.render_command.resolve();
let background_color = if matches!(style.background_color, StyleProp::Default) {
Color::TRANSPARENT
} else {
style.background_color.resolve()
};
match render_command { match render_command {
RenderCommand::Window => Self::Empty,
RenderCommand::Empty => Self::Empty, RenderCommand::Empty => Self::Empty,
RenderCommand::Clip => Self::Clip { RenderCommand::Clip => Self::Clip {
layout: Rect::default(), layout: Rect::default(),
}, },
RenderCommand::Quad => Self::Quad { RenderCommand::Quad => Self::Quad {
background_color: style.background_color.resolve(), background_color: background_color,
layout: Rect::default(), layout: Rect::default(),
}, },
RenderCommand::Text { RenderCommand::Text {
......
...@@ -49,7 +49,7 @@ pub struct Style { ...@@ -49,7 +49,7 @@ pub struct Style {
impl Default for Style { impl Default for Style {
fn default() -> Self { fn default() -> Self {
Self { Self {
background_color: StyleProp::Value(Color::TRANSPARENT), background_color: StyleProp::Default,
render_command: StyleProp::Value(RenderCommand::Empty), render_command: StyleProp::Value(RenderCommand::Empty),
bottom: StyleProp::Default, bottom: StyleProp::Default,
color: StyleProp::Inherit, color: StyleProp::Inherit,
......
use as_any::AsAny; use as_any::AsAny;
use crate::{context::KayakContext, styles::Style, Index}; use crate::{context::KayakContext, styles::Style, Event, Index};
pub trait Widget: std::fmt::Debug + AsAny + Send + Sync { pub trait Widget: std::fmt::Debug + AsAny + Send + Sync {
fn get_id(&self) -> Index; fn get_id(&self) -> Index;
fn set_id(&mut self, id: Index); fn set_id(&mut self, id: Index);
fn get_styles(&self) -> Option<Style>; fn get_styles(&self) -> Option<Style>;
fn get_name(&self) -> String;
fn on_event(&mut self, context: &mut KayakContext, event: &mut Event);
fn render(&mut self, context: &mut KayakContext); fn render(&mut self, context: &mut KayakContext);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment