diff options
Diffstat (limited to 'src/user_interface.rs')
| -rw-r--r-- | src/user_interface.rs | 116 | 
1 files changed, 116 insertions, 0 deletions
diff --git a/src/user_interface.rs b/src/user_interface.rs new file mode 100644 index 00000000..5d02bf9a --- /dev/null +++ b/src/user_interface.rs @@ -0,0 +1,116 @@ +use crate::{input::mouse, Column, Element, Event, Layout, MouseCursor, Point}; + +use std::hash::Hasher; +use stretch::result; + +pub struct UserInterface<'a, Message, Renderer> { +    hash: u64, +    root: Element<'a, Message, Renderer>, +    layout: result::Layout, +    cursor_position: Point, +} + +impl<'a, Message, Renderer> UserInterface<'a, Message, Renderer> { +    pub fn build( +        root: Element<'a, Message, Renderer>, +        renderer: &Renderer, +        cache: Cache, +    ) -> Self { +        let hasher = &mut crate::Hasher::default(); +        root.hash(hasher); + +        let hash = hasher.finish(); + +        let layout = if hash == cache.hash { +            cache.layout +        } else { +            root.compute_layout(renderer) +        }; + +        UserInterface { +            hash, +            root, +            layout, +            cursor_position: cache.cursor_position, +        } +    } + +    pub fn update( +        &mut self, +        events: std::vec::Drain<'_, Event>, +    ) -> Vec<Message> { +        let mut messages = Vec::new(); + +        for event in events { +            match event { +                Event::Mouse(mouse::Event::CursorMoved { x, y }) => { +                    self.cursor_position = Point::new(x, y); +                } +                _ => {} +            } + +            self.root.widget.on_event( +                event, +                Layout::new(&self.layout), +                self.cursor_position, +                &mut messages, +            ); +        } + +        messages +    } + +    pub fn draw(&self, renderer: &mut Renderer) -> MouseCursor { +        let cursor = self.root.widget.draw( +            renderer, +            Layout::new(&self.layout), +            self.cursor_position, +        ); + +        cursor +    } + +    pub fn into_cache(self) -> Cache { +        Cache { +            hash: self.hash, +            layout: self.layout, +            cursor_position: self.cursor_position, +        } +    } +} + +#[derive(Debug, Clone)] +pub struct Cache { +    hash: u64, +    layout: result::Layout, +    cursor_position: Point, +} + +impl Cache { +    pub fn new() -> Cache { +        let root: Element<'_, (), ()> = Column::new().into(); + +        let hasher = &mut crate::Hasher::default(); +        root.hash(hasher); + +        Cache { +            hash: hasher.finish(), +            layout: root.compute_layout(&()), +            cursor_position: Point::new(0.0, 0.0), +        } +    } +} + +impl Default for Cache { +    fn default() -> Cache { +        Cache::new() +    } +} + +impl PartialEq for Cache { +    fn eq(&self, other: &Cache) -> bool { +        self.hash == other.hash && self.cursor_position == other.cursor_position +    } +} + +impl Eq for Cache {}  | 
