View plugins
This commit is contained in:
@@ -8,7 +8,7 @@ pub fn main() {
|
||||
#[component]
|
||||
fn App(cx: &Arc<Context>) -> View {
|
||||
rsx! {
|
||||
impl my_center(11, 1)
|
||||
impl size_auto, center, redraw
|
||||
Card { content: "Hello World".to_string() }
|
||||
}
|
||||
.view(&cx)
|
||||
@@ -23,9 +23,3 @@ fn Card(cx: &Arc<Context>, content: String) -> View {
|
||||
}
|
||||
.view(&cx)
|
||||
}
|
||||
|
||||
fn my_center(ctx: &mut DrawContext, view: View, w: u16, h: u16) {
|
||||
let (x, y) = ((ctx.area.width - w) / 2, (ctx.area.height - h) / 2);
|
||||
let area = ctx.allocate(x, y, w, h);
|
||||
ctx.draw_view(area, view);
|
||||
}
|
||||
|
||||
+7
-3
@@ -57,9 +57,9 @@ fn emit_plugins(deps: &[ViewPlugin]) -> TokenStream {
|
||||
.map(|d| {
|
||||
let path = &d.path;
|
||||
if let Some(args) = &d.args {
|
||||
quote!( #path(ctx, view #(,#args)*); )
|
||||
quote!( #path(ctx, &view #(,#args)*); )
|
||||
} else {
|
||||
quote!( #path(ctx, view); )
|
||||
quote!( #path(ctx, &view); )
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
@@ -194,7 +194,11 @@ fn emit_node(node: &RsxNode) -> TokenStream {
|
||||
let plugins_emit = emit_plugins(plugins);
|
||||
|
||||
quote! {
|
||||
scope.child(#component_expr, Some(std::sync::Arc::new(|ctx, view| {#plugins_emit})));
|
||||
scope.child(#component_expr, Some(std::sync::Arc::new(|ctx, view| {
|
||||
let area = ctx.allocate(ctx.area.x, ctx.area.y, ctx.area.width, ctx.area.height);
|
||||
ctx.draw_view(area, view.clone());
|
||||
#plugins_emit
|
||||
})));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -43,16 +43,18 @@ use crate::render::DrawContext;
|
||||
pub mod component;
|
||||
pub mod engine;
|
||||
pub mod frontend;
|
||||
pub mod render;
|
||||
pub mod hooks;
|
||||
pub mod render;
|
||||
pub mod view_plugins;
|
||||
|
||||
pub mod prelude {
|
||||
//! Prelude module - Re-exports commonly used items for convenience
|
||||
pub use crate::component::{context::*, scope::*, *};
|
||||
pub use crate::engine::*;
|
||||
pub use crate::frontend::*;
|
||||
pub use crate::render::*;
|
||||
pub use crate::hooks::*;
|
||||
pub use crate::render::*;
|
||||
pub use crate::view_plugins::*;
|
||||
pub use crate::{sleep, Error, Result, View, ViewWrapper};
|
||||
pub use crossterm;
|
||||
pub use osui_macros::{component, rsx};
|
||||
|
||||
+14
-9
@@ -18,7 +18,7 @@ pub enum DrawInstruction {
|
||||
}
|
||||
|
||||
/// Represents the dimensions of a drawable area
|
||||
#[derive(Clone)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Size {
|
||||
/// Width in terminal columns
|
||||
pub width: u16,
|
||||
@@ -27,7 +27,7 @@ pub struct Size {
|
||||
}
|
||||
|
||||
/// Represents a position in 2D space
|
||||
#[derive(Clone)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Point {
|
||||
/// X coordinate (column)
|
||||
pub x: u16,
|
||||
@@ -36,7 +36,7 @@ pub struct Point {
|
||||
}
|
||||
|
||||
/// Represents a rectangular area with position and dimensions
|
||||
#[derive(Clone)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Area {
|
||||
/// X coordinate (column) of the top-left corner
|
||||
pub x: u16,
|
||||
@@ -68,8 +68,8 @@ impl DrawContext {
|
||||
Self {
|
||||
area,
|
||||
allocated: Area {
|
||||
x: u16::MAX,
|
||||
y: u16::MAX,
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
},
|
||||
@@ -80,10 +80,10 @@ impl DrawContext {
|
||||
/// Allocates space within the drawable area and returns the allocated area
|
||||
/// Updates the allocated bounds to include this allocation
|
||||
pub fn allocate(&mut self, x: u16, y: u16, width: u16, height: u16) -> Area {
|
||||
self.allocated.x = self.allocated.x.min(x);
|
||||
self.allocated.y = self.allocated.y.min(y);
|
||||
self.allocated.width = self.allocated.width.max(width);
|
||||
self.allocated.height = self.allocated.height.max(height);
|
||||
self.allocated.x = x;
|
||||
self.allocated.y = y;
|
||||
self.allocated.width = width;
|
||||
self.allocated.height = height;
|
||||
|
||||
Area {
|
||||
x,
|
||||
@@ -108,4 +108,9 @@ impl DrawContext {
|
||||
pub fn draw_view(&mut self, area: Area, view: View) {
|
||||
self.drawing.push(DrawInstruction::View(area, view));
|
||||
}
|
||||
|
||||
/// Clears drawing
|
||||
pub fn clear(&mut self) {
|
||||
self.drawing.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
use crate::{
|
||||
render::{DrawContext, DrawInstruction},
|
||||
View,
|
||||
};
|
||||
|
||||
pub fn x_center(ctx: &mut DrawContext, _view: &View) {
|
||||
ctx.allocated.y = (ctx.area.height - ctx.allocated.height) / 2;
|
||||
}
|
||||
|
||||
pub fn y_center(ctx: &mut DrawContext, _view: &View) {
|
||||
ctx.allocated.y = (ctx.area.height - ctx.allocated.height) / 2;
|
||||
}
|
||||
|
||||
pub fn center(ctx: &mut DrawContext, _view: &View) {
|
||||
ctx.allocated.x = (ctx.area.width - ctx.allocated.width) / 2;
|
||||
ctx.allocated.y = (ctx.area.height - ctx.allocated.height) / 2;
|
||||
}
|
||||
|
||||
pub fn size_auto(ctx: &mut DrawContext, _view: &View) {
|
||||
for i in &ctx.drawing {
|
||||
match i {
|
||||
DrawInstruction::Text(_, text) => {
|
||||
ctx.allocated.width = text.len() as u16;
|
||||
ctx.allocated.height = 1;
|
||||
}
|
||||
DrawInstruction::View(area, view) => {
|
||||
let mut c = DrawContext::new(area.clone());
|
||||
view(&mut c);
|
||||
size_auto(&mut c, view);
|
||||
ctx.allocated.width = c.allocated.width;
|
||||
ctx.allocated.height = c.allocated.height;
|
||||
}
|
||||
DrawInstruction::Child(_, _) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn redraw(ctx: &mut DrawContext, view: &View) {
|
||||
ctx.clear();
|
||||
ctx.draw_view(ctx.allocated.clone(), view.clone());
|
||||
}
|
||||
Reference in New Issue
Block a user