veloren_voxygen/ui/ice/widget/
mouse_detector.rs1use iced::{
2 Clipboard, Element, Event, Hasher, Layout, Length, Point, Rectangle, Size, Widget, layout,
3 mouse,
4};
5use std::hash::Hash;
6
7#[derive(Debug, Default)]
8pub struct State {
9 mouse_over: bool,
10}
11impl State {
12 pub fn mouse_over(&self) -> bool { self.mouse_over }
13}
14
15#[derive(Debug)]
16pub struct MouseDetector<'a> {
17 width: Length,
18 height: Length,
19 state: &'a mut State,
20}
21
22impl<'a> MouseDetector<'a> {
23 pub fn new(state: &'a mut State, width: Length, height: Length) -> Self {
24 Self {
25 width,
26 height,
27 state,
28 }
29 }
30}
31
32impl<M, R> Widget<M, R> for MouseDetector<'_>
33where
34 R: Renderer,
35{
36 fn width(&self) -> Length { self.width }
37
38 fn height(&self) -> Length { self.height }
39
40 fn layout(&self, _renderer: &R, limits: &layout::Limits) -> layout::Node {
41 let limits = limits.width(self.width).height(self.height);
42
43 layout::Node::new(limits.resolve(Size::ZERO))
44 }
45
46 fn draw(
47 &self,
48 renderer: &mut R,
49 _defaults: &R::Defaults,
50 layout: Layout<'_>,
51 _cursor_position: Point,
52 _viewport: &Rectangle,
53 ) -> R::Output {
54 renderer.draw(layout.bounds())
55 }
56
57 fn hash_layout(&self, state: &mut Hasher) {
58 struct Marker;
59 std::any::TypeId::of::<Marker>().hash(state);
60
61 self.width.hash(state);
62 self.height.hash(state);
63 }
64
65 fn on_event(
66 &mut self,
67 event: Event,
68 layout: Layout<'_>,
69 _cursor_position: Point,
70 _renderer: &R,
71 _clipboard: &mut dyn Clipboard,
72 _messages: &mut Vec<M>,
73 ) -> iced::event::Status {
74 if let Event::Mouse(mouse::Event::CursorMoved {
75 position: Point { x, y },
76 }) = event
77 {
78 let bounds = layout.bounds();
79 let mouse_over = x > bounds.x
80 && x < bounds.x + bounds.width
81 && y > bounds.y
82 && y < bounds.y + bounds.height;
83 if mouse_over != self.state.mouse_over {
84 self.state.mouse_over = mouse_over;
85 }
86 }
87
88 iced::event::Status::Ignored
89 }
90}
91
92pub trait Renderer: iced::Renderer {
93 fn draw(&mut self, bounds: Rectangle) -> Self::Output;
94}
95
96impl<'a, M, R> From<MouseDetector<'a>> for Element<'a, M, R>
97where
98 R: Renderer,
99 M: 'a,
100{
101 fn from(mouse_detector: MouseDetector<'a>) -> Element<'a, M, R> { Element::new(mouse_detector) }
102}