summaryrefslogtreecommitdiffstats
path: root/virtual/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'virtual/src/lib.rs')
-rw-r--r--virtual/src/lib.rs107
1 files changed, 96 insertions, 11 deletions
diff --git a/virtual/src/lib.rs b/virtual/src/lib.rs
index 80953872..bab0da15 100644
--- a/virtual/src/lib.rs
+++ b/virtual/src/lib.rs
@@ -1,33 +1,75 @@
-mod element;
pub mod widget;
-pub use element::Element;
-pub use widget::Widget;
+pub(crate) mod flex;
+pub use widget::*;
+
+use iced_native::event::{self, Event};
use iced_native::layout::{self, Layout};
+use iced_native::mouse;
use iced_native::renderer;
-use iced_native::{Hasher, Length, Point, Rectangle};
+use iced_native::{Clipboard, Hasher, Length, Point, Rectangle, Shell};
pub struct Virtual<'a, Message, Renderer> {
state: &'a mut State<Message, Renderer>,
}
+impl<'a, Message, Renderer> Virtual<'a, Message, Renderer>
+where
+ Message: 'static,
+ Renderer: iced_native::Renderer + 'static,
+{
+ pub fn new(
+ state: &'a mut State<Message, Renderer>,
+ content: Element<Message, Renderer>,
+ ) -> Self {
+ let _ = state.diff(content);
+
+ Self { state }
+ }
+}
+
pub struct State<Message, Renderer> {
- widget_tree: widget::Tree<Message, Renderer>,
+ state_tree: widget::Tree<Message, Renderer>,
last_element: Element<Message, Renderer>,
}
+impl<Message, Renderer> State<Message, Renderer>
+where
+ Message: 'static,
+ Renderer: iced_native::Renderer + 'static,
+{
+ pub fn new() -> Self {
+ let last_element = Element::new(widget::Column::new());
+
+ Self {
+ state_tree: widget::Tree::new(&last_element),
+ last_element,
+ }
+ }
+
+ fn diff(&mut self, new_element: Element<Message, Renderer>) {
+ self.state_tree.diff(&self.last_element, &new_element);
+
+ self.last_element = new_element;
+ }
+}
+
impl<'a, Message, Renderer> iced_native::Widget<Message, Renderer>
for Virtual<'a, Message, Renderer>
where
Renderer: iced_native::Renderer,
{
fn width(&self) -> Length {
- self.state.widget_tree.width()
+ self.state.last_element.as_widget().width()
}
fn height(&self) -> Length {
- self.state.widget_tree.height()
+ self.state.last_element.as_widget().height()
+ }
+
+ fn hash_layout(&self, state: &mut Hasher) {
+ self.state.last_element.as_widget().hash_layout(state)
}
fn layout(
@@ -35,11 +77,27 @@ where
renderer: &Renderer,
limits: &layout::Limits,
) -> layout::Node {
- self.state.widget_tree.layout(renderer, limits)
+ self.state.last_element.as_widget().layout(renderer, limits)
}
- fn hash_layout(&self, state: &mut Hasher) {
- self.state.widget_tree.hash_layout(state)
+ fn on_event(
+ &mut self,
+ event: Event,
+ layout: Layout<'_>,
+ cursor_position: Point,
+ renderer: &Renderer,
+ clipboard: &mut dyn Clipboard,
+ shell: &mut Shell<'_, Message>,
+ ) -> event::Status {
+ self.state.last_element.as_widget_mut().on_event(
+ &mut self.state.state_tree,
+ event,
+ layout,
+ cursor_position,
+ renderer,
+ clipboard,
+ shell,
+ )
}
fn draw(
@@ -50,7 +108,8 @@ where
cursor_position: Point,
viewport: &Rectangle,
) {
- self.state.widget_tree.draw(
+ self.state.last_element.as_widget().draw(
+ &self.state.state_tree,
renderer,
style,
layout,
@@ -58,4 +117,30 @@ where
viewport,
)
}
+
+ fn mouse_interaction(
+ &self,
+ layout: Layout<'_>,
+ cursor_position: Point,
+ viewport: &Rectangle,
+ renderer: &Renderer,
+ ) -> mouse::Interaction {
+ self.state.last_element.as_widget().mouse_interaction(
+ &self.state.state_tree,
+ layout,
+ cursor_position,
+ viewport,
+ renderer,
+ )
+ }
+}
+
+impl<'a, Message, Renderer> Into<iced_native::Element<'a, Message, Renderer>>
+ for Virtual<'a, Message, Renderer>
+where
+ Renderer: iced_native::Renderer,
+{
+ fn into(self) -> iced_native::Element<'a, Message, Renderer> {
+ iced_native::Element::new(self)
+ }
}