working divs
This commit is contained in:
+56
-12
@@ -1,13 +1,27 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use crate::widget::{Element, Widget};
|
use crate::{
|
||||||
|
extensions::Handler,
|
||||||
|
style::RawTransform,
|
||||||
|
widget::{Element, Widget},
|
||||||
|
RenderWrapperEvent,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct Div {
|
pub struct Div {
|
||||||
pub children: Vec<Arc<Widget>>,
|
transform: Mutex<RawTransform>,
|
||||||
|
color: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Element for Arc<Div> {
|
||||||
|
fn render(&mut self, scope: &mut crate::render_scope::RenderScope) {
|
||||||
|
let (w, h) = scope.get_size_or_parent();
|
||||||
|
scope.draw_rect(w, h, self.color);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn after_render(&mut self, scope: &crate::render_scope::RenderScope) {
|
||||||
|
*self.transform.lock().unwrap() = scope.get_transform().clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Element for Div {
|
|
||||||
fn as_any(&self) -> &dyn std::any::Any {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -18,14 +32,44 @@ impl Element for Div {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Div {
|
impl Div {
|
||||||
pub fn new() -> Self {
|
pub fn new(color: u32) -> Arc<Self> {
|
||||||
Div {
|
Arc::new(Div {
|
||||||
children: Vec::new(),
|
transform: Mutex::new(RawTransform::new()),
|
||||||
}
|
color,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw<E: Element + 'static>(&mut self, element: E) -> &Arc<Widget> {
|
pub fn draw(self: &Arc<Self>, element: &Arc<Widget>) -> Arc<Self> {
|
||||||
self.children.push(Arc::new(Widget::new(Box::new(element))));
|
let r2 = self.clone();
|
||||||
self.children.last().unwrap()
|
let r = self.clone();
|
||||||
|
element.component(Handler::new(move |elem, e: &RenderWrapperEvent| {
|
||||||
|
let scope = e.get_scope();
|
||||||
|
scope.clear();
|
||||||
|
|
||||||
|
let transform = r2.transform.lock().unwrap();
|
||||||
|
|
||||||
|
let (w, h) = scope.get_parent_size();
|
||||||
|
scope.set_parent_size(transform.width, transform.height);
|
||||||
|
|
||||||
|
if let Some(t) = elem.get() {
|
||||||
|
scope.set_transform(&t);
|
||||||
|
}
|
||||||
|
|
||||||
|
elem.0.lock().unwrap().render(scope);
|
||||||
|
|
||||||
|
if let Some(t) = elem.get() {
|
||||||
|
scope.set_transform(&t);
|
||||||
|
}
|
||||||
|
|
||||||
|
let elem_transform = scope.get_transform_mut();
|
||||||
|
elem_transform.x += transform.x;
|
||||||
|
elem_transform.y += transform.y;
|
||||||
|
|
||||||
|
scope.draw();
|
||||||
|
elem.0.lock().unwrap().after_render(&scope);
|
||||||
|
|
||||||
|
scope.set_parent_size(w, h);
|
||||||
|
}));
|
||||||
|
r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-22
@@ -3,7 +3,7 @@ pub mod tick;
|
|||||||
pub mod velocity;
|
pub mod velocity;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
any::{Any, TypeId},
|
any::Any,
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
@@ -23,12 +23,9 @@ pub trait Event: Send + Sync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Handler(
|
pub struct Handler<E: Event>(Arc<Mutex<dyn FnMut(&Arc<Widget>, &E) + Send + Sync>>);
|
||||||
Arc<Mutex<dyn FnMut(&Arc<Widget>, &dyn Event) + Send + Sync>>,
|
|
||||||
TypeId,
|
|
||||||
);
|
|
||||||
|
|
||||||
impl Component for Handler {
|
impl<E: Event + 'static> Component for Handler<E> {
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -38,28 +35,17 @@ impl Component for Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Handler {
|
impl<E: Event + 'static> Handler<E> {
|
||||||
pub fn new<E: Event + 'static, F: FnMut(&Arc<Widget>, &E) + Send + Sync + 'static>(
|
pub fn new<F: FnMut(&Arc<Widget>, &E) + Send + Sync + 'static>(f: F) -> Handler<E> {
|
||||||
mut f: F,
|
Handler(Arc::new(Mutex::new(f)))
|
||||||
) -> Handler {
|
|
||||||
Handler(
|
|
||||||
Arc::new(Mutex::new(move |w: &Arc<Widget>, e: &dyn Event| {
|
|
||||||
if let Some(e) = e.as_any().downcast_ref::<E>() {
|
|
||||||
f(w, e)
|
|
||||||
}
|
|
||||||
})),
|
|
||||||
TypeId::of::<E>(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call<E: Event>(&self, w: &Arc<Widget>, e: &E) {
|
pub fn call(&self, w: &Arc<Widget>, e: &E) {
|
||||||
if e.as_any().type_id() == self.1 {
|
|
||||||
(self.0.lock().unwrap())(w, e)
|
(self.0.lock().unwrap())(w, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for Handler {
|
impl<T: Event> Debug for Handler<T> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "Handler")
|
write!(f, "Handler")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ impl Extension for TickExtension {
|
|||||||
let mut tick = 0;
|
let mut tick = 0;
|
||||||
loop {
|
loop {
|
||||||
for w in &widgets {
|
for w in &widgets {
|
||||||
if let Some(on_tick) = w.get::<Handler>() {
|
if let Some(on_tick) = w.get::<Handler<TickEvent>>() {
|
||||||
on_tick.call(&w, &TickEvent(tick))
|
on_tick.call(&w, &TickEvent(tick))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-1
@@ -1,7 +1,7 @@
|
|||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
extensions::Extension,
|
extensions::{Extension, Handler},
|
||||||
render_scope::RenderScope,
|
render_scope::RenderScope,
|
||||||
style::Transform,
|
style::Transform,
|
||||||
widget::{Element, Widget},
|
widget::{Element, Widget},
|
||||||
@@ -20,6 +20,17 @@ pub struct Screen {
|
|||||||
extensions: Vec<Arc<Mutex<Box<dyn Extension>>>>,
|
extensions: Vec<Arc<Mutex<Box<dyn Extension>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event!(RenderWrapperEvent(*mut RenderScope));
|
||||||
|
|
||||||
|
impl RenderWrapperEvent {
|
||||||
|
pub fn get_scope(&self) -> &mut RenderScope {
|
||||||
|
unsafe { &mut *self.0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for RenderWrapperEvent {}
|
||||||
|
unsafe impl Sync for RenderWrapperEvent {}
|
||||||
|
|
||||||
impl Screen {
|
impl Screen {
|
||||||
pub fn new() -> Screen {
|
pub fn new() -> Screen {
|
||||||
Screen {
|
Screen {
|
||||||
@@ -56,9 +67,14 @@ impl Screen {
|
|||||||
|
|
||||||
pub fn render(&self) -> std::io::Result<()> {
|
pub fn render(&self) -> std::io::Result<()> {
|
||||||
let mut scope = RenderScope::new();
|
let mut scope = RenderScope::new();
|
||||||
|
let (w, h) = crossterm::terminal::size().unwrap();
|
||||||
|
scope.set_parent_size(w, h);
|
||||||
|
|
||||||
utils::clear()?;
|
utils::clear()?;
|
||||||
for elem in &self.widgets {
|
for elem in &self.widgets {
|
||||||
|
if let Some(wrapper) = elem.get::<Handler<RenderWrapperEvent>>() {
|
||||||
|
wrapper.call(elem, &RenderWrapperEvent(&mut scope));
|
||||||
|
} else {
|
||||||
scope.clear();
|
scope.clear();
|
||||||
if let Some(t) = elem.get() {
|
if let Some(t) = elem.get() {
|
||||||
scope.set_transform(&t);
|
scope.set_transform(&t);
|
||||||
@@ -74,6 +90,9 @@ impl Screen {
|
|||||||
scope.set_transform(&t);
|
scope.set_transform(&t);
|
||||||
}
|
}
|
||||||
scope.draw();
|
scope.draw();
|
||||||
|
|
||||||
|
elem.0.lock().unwrap().after_render(&scope);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-11
@@ -1,9 +1,6 @@
|
|||||||
use osui::{
|
use osui::{
|
||||||
extensions::{
|
elements::div::Div,
|
||||||
id::{Id, IdExtension},
|
extensions::{id::IdExtension, tick::TickExtension},
|
||||||
tick::{TickEvent, TickExtension},
|
|
||||||
Handler,
|
|
||||||
},
|
|
||||||
style::Transform,
|
style::Transform,
|
||||||
Screen,
|
Screen,
|
||||||
};
|
};
|
||||||
@@ -14,14 +11,17 @@ fn main() {
|
|||||||
screen.extension(document.clone());
|
screen.extension(document.clone());
|
||||||
screen.extension(TickExtension(10));
|
screen.extension(TickExtension(10));
|
||||||
|
|
||||||
|
let my_div = Div::new(0xff0000);
|
||||||
|
|
||||||
|
screen
|
||||||
|
.draw(my_div.clone())
|
||||||
|
.component(Transform::center().dimensions(21, 3));
|
||||||
|
|
||||||
|
my_div.draw(
|
||||||
screen
|
screen
|
||||||
.draw(format!("Hello, World!"))
|
.draw(format!("Hello, World!"))
|
||||||
.component(Handler::new(move |w, e: &TickEvent| {
|
.component(Transform::center()),
|
||||||
if e.0 == 30 {
|
);
|
||||||
w.set_component(Transform::center());
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
.component(Id(69));
|
|
||||||
|
|
||||||
screen.run().unwrap();
|
screen.run().unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
+38
-1
@@ -1,13 +1,17 @@
|
|||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
style::{RawTransform, Transform},
|
style::{RawTransform, Transform},
|
||||||
utils::{self, hex_ansi_bg},
|
utils::{self, hex_ansi_bg},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
enum RenderMethod {
|
enum RenderMethod {
|
||||||
Text(String),
|
Text(String),
|
||||||
Rectangle(u16, u16, u32),
|
Rectangle(u16, u16, u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct RenderScope {
|
pub struct RenderScope {
|
||||||
transform: RawTransform,
|
transform: RawTransform,
|
||||||
render_stack: Vec<RenderMethod>,
|
render_stack: Vec<RenderMethod>,
|
||||||
@@ -26,7 +30,6 @@ impl RenderScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_transform(&mut self, transform: &Transform) {
|
pub fn set_transform(&mut self, transform: &Transform) {
|
||||||
(self.parent_width, self.parent_height) = crossterm::terminal::size().unwrap();
|
|
||||||
transform.use_dimensions(&mut self.transform);
|
transform.use_dimensions(&mut self.transform);
|
||||||
transform.use_position(self.parent_width, self.parent_height, &mut self.transform);
|
transform.use_position(self.parent_width, self.parent_height, &mut self.transform);
|
||||||
}
|
}
|
||||||
@@ -76,7 +79,41 @@ impl RenderScope {
|
|||||||
(self.transform.width, self.transform.height)
|
(self.transform.width, self.transform.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_size_or_parent(&self) -> (u16, u16) {
|
||||||
|
(
|
||||||
|
if self.transform.width == 0 {
|
||||||
|
self.parent_width
|
||||||
|
} else {
|
||||||
|
self.transform.width
|
||||||
|
},
|
||||||
|
if self.transform.height == 0 {
|
||||||
|
self.parent_height
|
||||||
|
} else {
|
||||||
|
self.transform.height
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_parent_size(&self) -> (u16, u16) {
|
pub fn get_parent_size(&self) -> (u16, u16) {
|
||||||
(self.parent_width, self.parent_height)
|
(self.parent_width, self.parent_height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_parent_size(&mut self, width: u16, height: u16) {
|
||||||
|
self.parent_width = width;
|
||||||
|
self.parent_height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_transform_mut(&mut self) -> &mut RawTransform {
|
||||||
|
&mut self.transform
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_transform(&self) -> &RawTransform {
|
||||||
|
&self.transform
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for RenderScope {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "RenderScope")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::component;
|
use crate::component;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct RawTransform {
|
pub struct RawTransform {
|
||||||
pub x: u16,
|
pub x: u16,
|
||||||
pub y: u16,
|
pub y: u16,
|
||||||
@@ -57,6 +58,11 @@ impl Transform {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn right(mut self) -> Self {
|
||||||
|
self.x = Position::End;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn margin(mut self, x: i32, y: i32) -> Self {
|
pub fn margin(mut self, x: i32, y: i32) -> Self {
|
||||||
self.mx = x;
|
self.mx = x;
|
||||||
self.my = y;
|
self.my = y;
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ pub type BoxedComponent = Box<dyn Component + Send + Sync>;
|
|||||||
pub trait Element: Send + Sync {
|
pub trait Element: Send + Sync {
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
fn render(&mut self, scope: &mut RenderScope) {}
|
fn render(&mut self, scope: &mut RenderScope) {}
|
||||||
|
#[allow(unused)]
|
||||||
|
fn after_render(&mut self, scope: &RenderScope) {}
|
||||||
fn as_any(&self) -> &dyn Any;
|
fn as_any(&self) -> &dyn Any;
|
||||||
fn as_any_mut(&mut self) -> &mut dyn Any;
|
fn as_any_mut(&mut self) -> &mut dyn Any;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user