#![allow(unused_mut)]
use cgmath::Point2;
use std::cell::RefCell;
use stretch::node::Node;
use crate::prelude::OnDemand;
use crate::{
foundation::{ChildBounds, Helper, Id, KeyEvent, MouseEvent, Slot, TextEvent, WidgetClipEvent},
widgets::Widget,
};
use super::WidgetComponent;
pub trait ElementVisitor {
fn visit_child_elements(&self, element: &dyn Element);
}
pub trait ComponentElement: Element {
fn build(&self) -> &dyn Widget;
fn forget_child(&self, child: &dyn Element);
fn mount(&self, parent: Option<&dyn Element>, new_slot: Option<Slot>);
fn perform_rebuild();
fn visit_children(&self, visitor: &dyn ElementVisitor);
}
pub trait RenderObjectElement: Element {
}
pub trait Element
where
Self: AsRef<RefCell<WidgetComponent>>,
{
fn children_at_point(
&self,
x: f32,
y: f32,
into: Option<Vec<WidgetComponent>>,
) -> Vec<WidgetComponent> {
todo!()
}
fn topmost_child_at_point(&self, x: f32, y: f32) -> Option<&Box<dyn Element>> {
let comp = self.as_ref().borrow();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
todo!()
}
fn contains(&self, x: f32, y: f32) -> bool {
let comp = self.as_ref().borrow();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
let inside = Helper::in_rect(x, y, comp.x, comp.y, comp.w, comp.h);
if comp.clip.is_none() {
return inside;
}
inside
}
fn onclipchanged(&self) {
let comp = self.as_ref().borrow();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
}
fn clip(&self) -> Option<Id> {
let comp = self.as_ref().borrow();
comp.clip
}
fn set_clip(&self, other: Option<Id>) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
comp.clip = other;
if let Some(clip) = comp.clip {
} else if comp.onclip.is_some() {
let _ = comp.onclip.get().try_send(WidgetClipEvent {
clipped: true,
h: 0.0,
w: 0.0,
x: 0.0,
y: 0.0,
});
}
}
#[inline]
fn set_visible_only(&self, visible: bool) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
comp.update_vis_state = false;
comp.visible = visible;
comp.update_vis_state = true;
}
fn visible(&self) -> bool {
let comp = self.as_ref().borrow();
comp.visible
}
fn vis_state(&self) -> bool {
let comp = self.as_ref().borrow();
comp.vis_state
}
fn set_visible(&self, visible: bool) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
comp.visible = visible;
if comp.update_vis_state {
comp.vis_state = visible;
}
if comp.onvisible.is_some() {
let visible = comp.visible;
let _ = comp.onvisible.get().try_send(visible);
}
if let Some(widget) = comp.canvas.as_mut() {
widget.focus_invalid = true;
}
}
fn find_top_parent(&self, from: Option<&WidgetComponent>) -> Option<WidgetComponent> {
let comp = self.as_ref().borrow();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
todo!()
}
fn add(&self, child: &dyn Element) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if let Some(parent) = child.parent() {
parent.remove(child.id());
if parent.id() != self.id() {
comp.children.push(child.id());
child.set_parent(Some(self.id()));
if comp.onchildadd.is_some() {
let _ = comp.onchildadd.get().try_send(child.id());
}
}
if let Some(widget) = comp.canvas.as_ref() {
widget.sync_depth();
}
}
}
fn remove(&self, child: Id) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if let Some(index) = comp.children.iter().position(|x| x == &child) {
comp.children.remove(index);
if comp.onchildremove.is_some() {
let _ = comp.onchildremove.get().try_send(child);
}
if let Some(widget) = comp.canvas.as_ref() {
widget.sync_depth();
}
}
}
fn children_bounds(&self) -> ChildBounds {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if comp.children.is_empty() {
comp.children_bounds.x = 0.0;
comp.children_bounds.y = 0.0;
comp.children_bounds.w = 0.0;
comp.children_bounds.h = 0.0;
comp.children_bounds.x_local = 0.0;
comp.children_bounds.y_local = 0.0;
return comp.children_bounds;
}
let mut current_x: f32 = 0.0;
let mut current_y: f32 = 0.0;
let mut current_r: f32 = 0.0;
let mut current_b: f32 = 0.0;
let mut real_x: f32 = 0.0;
let mut real_y: f32 = 0.0;
comp.children_bounds.x_local = current_x;
comp.children_bounds.y_local = current_y;
comp.children_bounds.x = real_x;
comp.children_bounds.y = real_y;
comp.children_bounds.w = current_r;
comp.children_bounds.h = current_b;
comp.children_bounds
}
fn render(&self) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if comp.renderable && comp.onrender.is_some() {
let _ = comp.onrender.get().try_send(());
}
}
fn keyup(&self, e: &mut KeyEvent) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if comp.onkeyup.is_some() {
let _ = comp.onkeyup.get().try_send(e.clone());
}
}
fn keydown(&self, e: &mut KeyEvent) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if comp.onkeydown.is_some() {
let _ = comp.onkeydown.get().try_send(e.clone());
}
}
fn textinput(&self, e: &mut TextEvent) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if comp.ontextinput.is_some() {
let _ = comp.ontextinput.get().try_send(e.clone());
}
}
fn mousemove(&self, e: &mut MouseEvent) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if comp.onmousemove.is_some() {
let _ = comp.onmousemove.get().try_send(e.clone());
}
}
fn mouseup(&self, e: &mut MouseEvent) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if comp.onmouseup.is_some() {
let _ = comp.onmouseup.get().try_send(e.clone());
}
}
fn mousewheel(&self, e: &mut MouseEvent) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if comp.onmousewheel.is_some() {
let _ = comp.onmousewheel.get().try_send(e.clone());
}
}
fn mousedown(&self, e: &mut MouseEvent) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if comp.onmousedown.is_some() {
let _ = comp.onmousedown.get().try_send(e.clone());
}
}
fn mouseenter(&self, e: &mut MouseEvent) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if comp.onmouseenter.is_some() {
let _ = comp.onmouseenter.get().try_send(e.clone());
}
comp.ishovered = true;
}
fn mouseleave(&self, e: &mut MouseEvent) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if comp.onmouseleave.is_some() {
let _ = comp.onmouseleave.get().try_send(e.clone());
}
comp.ishovered = false;
}
fn destroy_children(&self) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
while let Some(child) = comp.children.pop() {
}
}
fn destroy(&self) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"attempt to destroy control twice `$self` ($name)"
);
self.unmark();
self.unfocus();
self.uncapture();
self.destroy_children();
if let Some(clip) = comp.clip {
todo!()
}
if let Some(parent) = comp.parent {
}
if comp.ondestroy.is_some() {
let _ = comp.ondestroy.get().try_send(());
}
comp.user = None;
comp.destroyed = true;
}
fn update(&self, dt: f32) {
log::info!("Update Default Element Impl");
let comp = self.as_ref().borrow();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
}
fn focus(&self) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if let Some(canvas) = comp.canvas.as_ref() {
if canvas.id() == self.id() {
return;
}
}
let pre = if let Some(canvas) = comp.canvas.as_ref() {
canvas.focused == Some(self.id())
} else {
false
};
if let Some(canvas) = comp.canvas.as_mut() {
canvas.focused = Some(self.id());
}
if !pre && comp.onfocused.is_some() {
let _ = comp.onfocused.get().try_send(true);
}
}
fn unfocus(&self) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if let Some(canvas) = comp.canvas.as_ref() {
if canvas.id() == self.id() {
return;
}
}
if let Some(canvas) = comp.canvas.as_mut() {
if let Some(focused) = canvas.focused {
if focused == self.id() {
canvas.focused = None;
if comp.onfocused.is_some() {
let _ = comp.onfocused.get().try_send(false);
}
}
}
}
}
fn capture(&self) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if let Some(canvas) = comp.canvas.as_ref() {
if canvas.id() == self.id() {
return;
}
}
let pre = if let Some(canvas) = comp.canvas.as_ref() {
if let Some(captured) = canvas.captured {
captured == self.id()
} else {
false
}
} else {
false
};
if let Some(canvas) = comp.canvas.as_mut() {
canvas.captured = Some(self.id());
}
if !pre && comp.oncaptured.is_some() {
let _ = comp.oncaptured.get().try_send(true);
}
}
fn uncapture(&self) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if let Some(canvas) = comp.canvas.as_mut() {
if canvas.id() == self.id() {
return;
}
if let Some(captured) = canvas.captured {
if captured == self.id() {
canvas.captured = None;
if comp.oncaptured.is_some() {
let _ = comp.oncaptured.get().try_send(false);
}
}
}
}
}
fn mark(&self) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if let Some(canvas) = comp.canvas.as_ref() {
if canvas.id() == self.id() {
return;
}
}
let pre = if let Some(ref canvas) = comp.canvas.as_ref() {
if let Some(marked) = canvas.marked {
marked == self.id()
} else {
false
}
} else {
false
};
if let Some(ref mut canvas) = comp.canvas.as_mut() {
canvas.marked = Some(self.id());
}
if !pre && comp.onmarked.is_some() {
let _ = comp.onmarked.get().try_send(true);
}
}
fn unmark(&self) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if let Some(canvas) = comp.canvas.as_mut() {
if canvas.id() == self.id() {
return;
}
if let Some(marked) = canvas.marked {
if marked == self.id() {
canvas.marked = None;
if comp.onmarked.is_some() {
let _ = comp.onmarked.get().try_send(false);
}
}
}
}
}
fn refresh_bounds(&self) {
let mut comp = self.as_ref().borrow_mut();
if comp.onbounds.is_some() {
let _ = comp.onbounds.get().try_send(());
}
}
fn bounds_changed(&self, dx: f32, dy: f32, dw: f32, dh: f32) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
if comp.updating {
return;
}
if comp.onbounds.is_some() {
let _ = comp.onbounds.get().try_send(());
}
}
fn set_pos(&self, x: f32, y: f32) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
comp.updating = true;
let dx = x - comp.x;
let dy = y - comp.y;
comp.x = x;
comp.y = y;
comp.updating = false;
self.bounds_changed(dx, dy, 0.0, 0.0);
}
fn set_size(&self, w: f32, h: f32) {
log::info!("Set Size Default Impl {}x{}", w, h);
let (dw, dh) = {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
comp.updating = true;
let dw = w - comp.w;
let dh = h - comp.h;
comp.w = w;
comp.h = h;
comp.updating = false;
(dw, dh)
};
self.bounds_changed(0.0, 0.0, dw, dh);
}
#[inline]
fn destroyed(&self) -> bool {
let comp = self.as_ref().borrow();
comp.destroyed
}
#[inline]
fn right(&self) -> f32 {
let comp = self.as_ref().borrow();
comp.x + comp.w
}
#[inline]
fn bottom(&self) -> f32 {
let comp = self.as_ref().borrow();
comp.y + comp.h
}
fn x(&self) -> f32 {
let comp = self.as_ref().borrow();
comp.x
}
fn set_x(&self, x: f32) {
let mut comp = self.as_ref().borrow_mut();
let dx = x - self.x();
comp.x = x;
if !comp.ignore_spatial {
comp.ignore_spatial = true;
match comp.parent {
Some(parent) => {
}
None => {
comp.x_local = comp.x; }
}
comp.ignore_spatial = false;
}
self.bounds_changed(dx, 0.0, 0.0, 0.0);
}
fn y(&self) -> f32 {
let comp = self.as_ref().borrow();
comp.y
}
fn set_y(&self, y: f32) {
let mut comp = self.as_ref().borrow_mut();
let dy = y - comp.y;
comp.y = y;
if !comp.ignore_spatial {
comp.ignore_spatial = true;
match comp.parent {
Some(parent) => {
}
None => {
comp.y_local = comp.y; }
}
comp.ignore_spatial = false;
}
self.bounds_changed(0.0, dy, 0.0, 0.0);
}
fn w_min(&self) -> f32 {
let comp = self.as_ref().borrow();
comp.w_min
}
fn set_w_min(&self, w_min: f32) {
let mut comp = self.as_ref().borrow_mut();
comp.w_min = w_min;
if comp.w < comp.w_min {
comp.w = comp.w_min;
}
}
fn h_min(&self) -> f32 {
let comp = self.as_ref().borrow();
comp.h_min
}
fn set_h_min(&self, h_min: f32) {
let mut comp = self.as_ref().borrow_mut();
comp.h_min = h_min;
if comp.h < comp.h_min {
comp.h = comp.h_min;
}
}
fn w_max(&self) -> f32 {
let comp = self.as_ref().borrow();
comp.w_max
}
fn set_w_max(&self, w_max: f32) {
let mut comp = self.as_ref().borrow_mut();
comp.w_max = w_max;
if comp.w > comp.w_max {
comp.w = comp.w_max;
}
}
fn h_max(&self) -> f32 {
let comp = self.as_ref().borrow();
comp.h_max
}
fn set_h_max(&self, _h_max: f32) {
let mut comp = self.as_ref().borrow_mut();
comp.h_max = _h_max;
if comp.h > comp.h_max {
comp.h = comp.h_max;
}
}
fn w(&self) -> f32 {
let comp = self.as_ref().borrow();
comp.w
}
fn set_w(&self, w: f32) {
let dw = {
let mut comp = self.as_ref().borrow_mut();
let mut w = if w < comp.w_min { comp.w_min } else { w };
w = if w > comp.w_max && comp.w_max != 0.0 {
comp.w_max
} else {
w
};
let dw = w - comp.w;
comp.w = w;
dw
};
self.bounds_changed(0.0, 0.0, dw, 0.0);
}
fn h(&self) -> f32 {
let comp = self.as_ref().borrow();
comp.h
}
fn set_h(&self, h: f32) {
let dh = {
let mut comp = self.as_ref().borrow_mut();
let mut h = if h < comp.h_min { comp.h_min } else { h };
h = if h > comp.h_max && comp.h_max != 0.0 {
comp.h_max
} else {
h
};
let dh = h - comp.h;
comp.h = h;
dh
};
self.bounds_changed(0.0, 0.0, 0.0, dh);
}
fn set_x_local(&self, x: f32) {
let mut comp = self.as_ref().borrow_mut();
comp.x_local = x;
if !comp.ignore_spatial {
comp.ignore_spatial = true;
match comp.parent {
Some(parent) => {
}
None => {
comp.x = comp.x_local;
}
}
comp.ignore_spatial = false;
}
}
fn set_y_local(&self, y: f32) {
let mut comp = self.as_ref().borrow_mut();
comp.y_local = y;
if !comp.ignore_spatial {
comp.ignore_spatial = true;
match comp.parent {
Some(parent) => {
}
None => {
comp.y = comp.y_local;
}
}
comp.ignore_spatial = false;
}
}
fn x_local(&self) -> f32 {
let comp = self.as_ref().borrow();
comp.x_local
}
fn y_local(&self) -> f32 {
let comp = self.as_ref().borrow();
comp.y_local
}
#[inline]
fn nodes(&self) -> i32 {
let comp = self.as_ref().borrow();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
let mut nodes = 1;
nodes
}
#[inline]
fn is_focused(&self) -> bool {
let comp = self.as_ref().borrow();
comp.isfocused
}
fn set_focused(&self, focused: bool) {
let mut comp = self.as_ref().borrow_mut();
comp.isfocused = focused;
}
#[inline]
fn is_captured(&self) -> bool {
let comp = self.as_ref().borrow();
comp.iscaptured
}
fn set_captured(&self, captured: bool) {
let mut comp = self.as_ref().borrow_mut();
comp.iscaptured = captured;
}
#[inline]
fn is_marked(&self) -> bool {
let comp = self.as_ref().borrow();
comp.ismarked
}
fn set_marked(&self, marked: bool) {
let mut comp = self.as_ref().borrow_mut();
comp.ismarked = marked
}
#[inline]
fn depth_offset(&self) -> f32 {
let comp = self.as_ref().borrow();
comp.depth_offset
}
#[inline]
fn depth(&self) -> f32 {
let comp = self.as_ref().borrow();
comp.depth
}
fn set_depth(&self, depth: f32) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
comp.depth = depth;
if comp.ondepth.is_some() {
let depth = comp.depth;
let _ = comp.ondepth.get().try_send(depth);
}
}
#[inline]
fn mouse_input(&self) -> bool {
let comp = self.as_ref().borrow();
comp.mouse_input
}
#[inline]
fn key_input(&self) -> bool {
let comp = self.as_ref().borrow();
comp.key_input
}
#[inline]
fn parent(&self) -> Option<&dyn Element> {
todo!()
}
fn set_parent(&self, p: Option<Id>) {
let mut comp = self.as_ref().borrow_mut();
assert!(
!comp.destroyed,
"Widget was already destroyed but is being interacted with"
);
comp.parent = p;
if let Some(parent) = comp.parent {
}
}
#[inline]
fn id(&self) -> Id {
let comp = self.as_ref().borrow();
comp.id
}
fn node(&self) -> Option<Node> {
None
}
fn relayout(&self, origin: Point2<f32>) {}
}
impl PartialEq for dyn Element {
fn eq(&self, other: &Self) -> bool {
self.id() == other.id()
}
}