Implemented the ElementRenderer for widgets
This commit is contained in:
+22
-30
@@ -1,10 +1,14 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
prelude::ElementRenderer,
|
||||||
|
style::RawTransform,
|
||||||
widget::{Element, Widget},
|
widget::{Element, Widget},
|
||||||
NoRender, NoRenderRoot,
|
NoRenderRoot,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub struct DivRenderer<'a>(pub &'a mut RawTransform);
|
||||||
|
|
||||||
pub struct Div {
|
pub struct Div {
|
||||||
children: Vec<Arc<Widget>>,
|
children: Vec<Arc<Widget>>,
|
||||||
size: (u16, u16),
|
size: (u16, u16),
|
||||||
@@ -35,39 +39,17 @@ impl Element for Div {
|
|||||||
ctx: &crate::extensions::Context,
|
ctx: &crate::extensions::Context,
|
||||||
) {
|
) {
|
||||||
let mut transform = scope.get_transform().clone();
|
let mut transform = scope.get_transform().clone();
|
||||||
|
let mut renderer = DivRenderer(&mut transform);
|
||||||
|
|
||||||
let (w, h) = scope.get_parent_size();
|
let (w, h) = scope.get_parent_size();
|
||||||
scope.set_parent_size(transform.width, transform.height);
|
scope.set_parent_size(renderer.0.width, renderer.0.height);
|
||||||
|
|
||||||
for elem in &self.children {
|
for widget in &self.children {
|
||||||
if elem.get::<NoRender>().is_some() {
|
scope.render_widget(&mut renderer, ctx, widget);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
scope.clear();
|
|
||||||
|
|
||||||
if let Some(style) = elem.get() {
|
|
||||||
scope.set_style(style);
|
|
||||||
}
|
|
||||||
if let Some(t) = elem.get() {
|
|
||||||
scope.set_transform(&t);
|
|
||||||
}
|
|
||||||
elem.get_elem().render(scope, ctx);
|
|
||||||
ctx.render(elem, scope);
|
|
||||||
if let Some(t) = elem.get() {
|
|
||||||
scope.set_transform(&t);
|
|
||||||
}
|
|
||||||
let t = scope.get_transform_mut();
|
|
||||||
transform.width = transform.width.max(t.x + t.width + (t.px * 2));
|
|
||||||
transform.height = transform.height.max(t.y + t.height + (t.py * 2));
|
|
||||||
t.x += transform.x + transform.px;
|
|
||||||
t.y += transform.y + transform.py;
|
|
||||||
|
|
||||||
scope.draw();
|
|
||||||
elem.get_elem().after_render(scope, ctx);
|
|
||||||
ctx.after_render(elem, scope);
|
|
||||||
}
|
}
|
||||||
scope.set_parent_size(w, h);
|
scope.set_parent_size(w, h);
|
||||||
self.size = (transform.width, transform.height);
|
|
||||||
|
self.size = (renderer.0.width, renderer.0.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_child(&mut self, element: &Arc<Widget>) {
|
fn draw_child(&mut self, element: &Arc<Widget>) {
|
||||||
@@ -83,3 +65,13 @@ impl Element for Div {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ElementRenderer for DivRenderer<'_> {
|
||||||
|
fn before_draw(&mut self, scope: &mut crate::prelude::RenderScope, _widget: &Arc<Widget>) {
|
||||||
|
let t = scope.get_transform_mut();
|
||||||
|
self.0.width = self.0.width.max(t.width + (t.px * 2));
|
||||||
|
self.0.height = self.0.height.max(t.height + (t.py * 2));
|
||||||
|
t.x += self.0.x + self.0.px;
|
||||||
|
t.y += self.0.y + self.0.py;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+43
-62
@@ -1,10 +1,15 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
prelude::ElementRenderer,
|
||||||
|
style::RawTransform,
|
||||||
widget::{Element, Widget},
|
widget::{Element, Widget},
|
||||||
NoRender, NoRenderRoot,
|
NoRenderRoot,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub struct RowRenderer<'a>(&'a mut RawTransform, u16, &'a mut u16);
|
||||||
|
pub struct ColumnRenderer<'a>(&'a mut RawTransform, u16, &'a mut u16);
|
||||||
|
|
||||||
pub struct FlexRow {
|
pub struct FlexRow {
|
||||||
pub gap: u16,
|
pub gap: u16,
|
||||||
children: Vec<Arc<Widget>>,
|
children: Vec<Arc<Widget>>,
|
||||||
@@ -56,43 +61,16 @@ impl Element for FlexRow {
|
|||||||
let transform_before = transform.clone();
|
let transform_before = transform.clone();
|
||||||
let (w, h) = scope.get_parent_size();
|
let (w, h) = scope.get_parent_size();
|
||||||
scope.set_parent_size(transform.width, transform.height);
|
scope.set_parent_size(transform.width, transform.height);
|
||||||
|
|
||||||
let mut v = 0;
|
let mut v = 0;
|
||||||
|
|
||||||
for elem in &self.children {
|
let mut renderer = RowRenderer(&mut transform, self.gap, &mut v);
|
||||||
if elem.get::<NoRender>().is_some() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
scope.clear();
|
for widget in &self.children {
|
||||||
if let Some(style) = elem.get() {
|
scope.render_widget(&mut renderer, ctx, widget);
|
||||||
scope.set_style(style);
|
|
||||||
}
|
|
||||||
if let Some(t) = elem.get() {
|
|
||||||
scope.set_transform(&t);
|
|
||||||
}
|
|
||||||
elem.get_elem().render(scope, ctx);
|
|
||||||
ctx.render(elem, scope);
|
|
||||||
if let Some(t) = elem.get() {
|
|
||||||
scope.set_transform(&t);
|
|
||||||
}
|
|
||||||
let t = scope.get_transform_mut();
|
|
||||||
transform.width = transform.width.max(t.width);
|
|
||||||
transform.height = transform.height.max(v + t.height);
|
|
||||||
t.x += transform.x;
|
|
||||||
t.y += transform.y + v;
|
|
||||||
v += t.height + self.gap + (t.py * 2);
|
|
||||||
t.px += transform.px;
|
|
||||||
t.py += transform.py;
|
|
||||||
|
|
||||||
scope.draw();
|
|
||||||
|
|
||||||
elem.get_elem().after_render(scope, ctx);
|
|
||||||
ctx.after_render(elem, scope);
|
|
||||||
}
|
}
|
||||||
scope.set_parent_size(w, h);
|
scope.set_parent_size(w, h);
|
||||||
self.size = (transform.width, transform.height);
|
|
||||||
scope.set_transform_raw(transform_before);
|
scope.set_transform_raw(transform_before);
|
||||||
|
self.size = (transform.width, transform.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_child(&mut self, element: &Arc<Widget>) {
|
fn draw_child(&mut self, element: &Arc<Widget>) {
|
||||||
@@ -128,39 +106,12 @@ impl Element for FlexCol {
|
|||||||
let transform_before = transform.clone();
|
let transform_before = transform.clone();
|
||||||
let (w, h) = scope.get_parent_size();
|
let (w, h) = scope.get_parent_size();
|
||||||
scope.set_parent_size(transform.width, transform.height);
|
scope.set_parent_size(transform.width, transform.height);
|
||||||
|
|
||||||
let mut v = 0;
|
let mut v = 0;
|
||||||
|
|
||||||
for elem in &self.children {
|
let mut renderer = ColumnRenderer(&mut transform, self.gap, &mut v);
|
||||||
if elem.get::<NoRender>().is_some() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
scope.clear();
|
for widget in &self.children {
|
||||||
if let Some(style) = elem.get() {
|
scope.render_widget(&mut renderer, ctx, widget);
|
||||||
scope.set_style(style);
|
|
||||||
}
|
|
||||||
if let Some(t) = elem.get() {
|
|
||||||
scope.set_transform(&t);
|
|
||||||
}
|
|
||||||
elem.get_elem().render(scope, ctx);
|
|
||||||
ctx.render(elem, scope);
|
|
||||||
if let Some(t) = elem.get() {
|
|
||||||
scope.set_transform(&t);
|
|
||||||
}
|
|
||||||
let t = scope.get_transform_mut();
|
|
||||||
transform.width = transform.width.max(v + t.width + (t.px * 2));
|
|
||||||
transform.height = transform.height.max(t.height + (t.py * 2));
|
|
||||||
t.x += transform.x + v;
|
|
||||||
t.y += transform.y;
|
|
||||||
v += t.width + self.gap + (t.px * 2);
|
|
||||||
t.px += transform.px;
|
|
||||||
t.py += transform.py;
|
|
||||||
|
|
||||||
scope.draw();
|
|
||||||
|
|
||||||
elem.get_elem().after_render(scope, ctx);
|
|
||||||
ctx.after_render(elem, scope);
|
|
||||||
}
|
}
|
||||||
scope.set_parent_size(w, h);
|
scope.set_parent_size(w, h);
|
||||||
scope.set_transform_raw(transform_before);
|
scope.set_transform_raw(transform_before);
|
||||||
@@ -180,3 +131,33 @@ impl Element for FlexCol {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ElementRenderer for RowRenderer<'_> {
|
||||||
|
fn before_draw(&mut self, scope: &mut crate::prelude::RenderScope, _widget: &Arc<Widget>) {
|
||||||
|
let t = scope.get_transform_mut();
|
||||||
|
self.0.width = self.0.width.max(*self.2 + t.width + (t.px * 2));
|
||||||
|
self.0.height = self.0.height.max(t.height + (t.py * 2));
|
||||||
|
|
||||||
|
t.x += self.0.x;
|
||||||
|
t.y += self.0.y + *self.2;
|
||||||
|
*self.2 += t.height + self.1 + (t.py * 2);
|
||||||
|
|
||||||
|
t.px += self.0.px;
|
||||||
|
t.py += self.0.py;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ElementRenderer for ColumnRenderer<'_> {
|
||||||
|
fn before_draw(&mut self, scope: &mut crate::prelude::RenderScope, _widget: &Arc<Widget>) {
|
||||||
|
let t = scope.get_transform_mut();
|
||||||
|
self.0.width = self.0.width.max(*self.2 + t.width + (t.px * 2));
|
||||||
|
self.0.height = self.0.height.max(t.height + (t.py * 2));
|
||||||
|
|
||||||
|
t.x += self.0.x + *self.2;
|
||||||
|
t.y += self.0.y;
|
||||||
|
*self.2 += t.width + self.1 + (t.px * 2);
|
||||||
|
|
||||||
|
t.px += self.0.px;
|
||||||
|
t.py += self.0.py;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ use std::sync::Arc;
|
|||||||
use crossterm::event::{KeyCode, KeyEvent};
|
use crossterm::event::{KeyCode, KeyEvent};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
prelude::DivRenderer,
|
||||||
widget::{Element, Widget},
|
widget::{Element, Widget},
|
||||||
NoRender, NoRenderRoot,
|
NoRenderRoot,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Paginator {
|
pub struct Paginator {
|
||||||
@@ -38,38 +39,16 @@ impl Element for Paginator {
|
|||||||
scope: &mut crate::render_scope::RenderScope,
|
scope: &mut crate::render_scope::RenderScope,
|
||||||
ctx: &crate::extensions::Context,
|
ctx: &crate::extensions::Context,
|
||||||
) {
|
) {
|
||||||
if let Some(elem) = self.children.get(self.index) {
|
if let Some(widget) = self.children.get(self.index) {
|
||||||
if elem.get::<NoRender>().is_some() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut transform = scope.get_transform().clone();
|
let mut transform = scope.get_transform().clone();
|
||||||
|
let mut renderer = DivRenderer(&mut transform);
|
||||||
let (w, h) = scope.get_parent_size();
|
let (w, h) = scope.get_parent_size();
|
||||||
scope.set_parent_size(transform.width, transform.height);
|
scope.set_parent_size(renderer.0.width, renderer.0.height);
|
||||||
scope.clear();
|
|
||||||
|
|
||||||
if let Some(style) = elem.get() {
|
scope.render_widget(&mut renderer, ctx, widget);
|
||||||
scope.set_style(style);
|
|
||||||
}
|
|
||||||
if let Some(t) = elem.get() {
|
|
||||||
scope.set_transform(&t);
|
|
||||||
}
|
|
||||||
elem.get_elem().render(scope, ctx);
|
|
||||||
if let Some(t) = elem.get() {
|
|
||||||
scope.set_transform(&t);
|
|
||||||
}
|
|
||||||
let t = scope.get_transform_mut();
|
|
||||||
transform.width = transform.width.max(t.x + t.width + (t.px * 2));
|
|
||||||
transform.height = transform.height.max(t.y + t.height + (t.py * 2));
|
|
||||||
t.x += transform.x + transform.px;
|
|
||||||
t.y += transform.y + transform.py;
|
|
||||||
|
|
||||||
scope.draw();
|
|
||||||
elem.get_elem().after_render(scope, ctx);
|
|
||||||
ctx.after_render(elem, scope);
|
|
||||||
|
|
||||||
scope.set_parent_size(w, h);
|
scope.set_parent_size(w, h);
|
||||||
self.size = (transform.width, transform.height);
|
self.size = (renderer.0.width, renderer.0.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -21,7 +21,7 @@ use crate::{
|
|||||||
pub trait ElementRenderer {
|
pub trait ElementRenderer {
|
||||||
/// Called right after the `after_render` function is called
|
/// Called right after the `after_render` function is called
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
fn on_after_render(&mut self, scope: &mut RenderScope, widget: &Arc<Widget>) {}
|
fn before_draw(&mut self, scope: &mut RenderScope, widget: &Arc<Widget>) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a single render instruction.
|
/// Represents a single render instruction.
|
||||||
@@ -330,11 +330,13 @@ impl RenderScope {
|
|||||||
if let Some(t) = widget.get() {
|
if let Some(t) = widget.get() {
|
||||||
self.set_transform(&t);
|
self.set_transform(&t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderer.before_draw(self, widget);
|
||||||
|
|
||||||
self.draw();
|
self.draw();
|
||||||
|
|
||||||
widget.get_elem().after_render(self, ctx);
|
widget.get_elem().after_render(self, ctx);
|
||||||
ctx.after_render(widget, self);
|
ctx.after_render(widget, self);
|
||||||
renderer.on_after_render(self, widget);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
widget.auto_refresh();
|
widget.auto_refresh();
|
||||||
|
|||||||
Reference in New Issue
Block a user