iced_core/widget.rs
1//! Create custom widgets and operate on them.
2pub mod operation;
3pub mod text;
4pub mod tree;
5
6mod id;
7
8pub use id::Id;
9pub use operation::Operation;
10pub use text::Text;
11pub use tree::Tree;
12
13use crate::layout::{self, Layout};
14use crate::mouse;
15use crate::overlay;
16use crate::renderer;
17use crate::{Clipboard, Event, Length, Rectangle, Shell, Size, Vector};
18
19/// A component that displays information and allows interaction.
20///
21/// If you want to build your own widgets, you will need to implement this
22/// trait.
23///
24/// # Examples
25/// The repository has some [examples] showcasing how to implement a custom
26/// widget:
27///
28/// - [`bezier_tool`], a Paint-like tool for drawing Bézier curves using
29/// [`lyon`].
30/// - [`custom_widget`], a demonstration of how to build a custom widget that
31/// draws a circle.
32/// - [`geometry`], a custom widget showcasing how to draw geometry with the
33/// `Mesh2D` primitive in [`iced_wgpu`].
34///
35/// [examples]: https://github.com/iced-rs/iced/tree/0.13/examples
36/// [`bezier_tool`]: https://github.com/iced-rs/iced/tree/0.13/examples/bezier_tool
37/// [`custom_widget`]: https://github.com/iced-rs/iced/tree/0.13/examples/custom_widget
38/// [`geometry`]: https://github.com/iced-rs/iced/tree/0.13/examples/geometry
39/// [`lyon`]: https://github.com/nical/lyon
40/// [`iced_wgpu`]: https://github.com/iced-rs/iced/tree/0.13/wgpu
41pub trait Widget<Message, Theme, Renderer>
42where
43 Renderer: crate::Renderer,
44{
45 /// Returns the [`Size`] of the [`Widget`] in lengths.
46 fn size(&self) -> Size<Length>;
47
48 /// Returns a [`Size`] hint for laying out the [`Widget`].
49 ///
50 /// This hint may be used by some widget containers to adjust their sizing strategy
51 /// during construction.
52 fn size_hint(&self) -> Size<Length> {
53 self.size()
54 }
55
56 /// Returns the [`layout::Node`] of the [`Widget`].
57 ///
58 /// This [`layout::Node`] is used by the runtime to compute the [`Layout`] of the
59 /// user interface.
60 fn layout(
61 &self,
62 tree: &mut Tree,
63 renderer: &Renderer,
64 limits: &layout::Limits,
65 ) -> layout::Node;
66
67 /// Draws the [`Widget`] using the associated `Renderer`.
68 fn draw(
69 &self,
70 tree: &Tree,
71 renderer: &mut Renderer,
72 theme: &Theme,
73 style: &renderer::Style,
74 layout: Layout<'_>,
75 cursor: mouse::Cursor,
76 viewport: &Rectangle,
77 );
78
79 /// Returns the [`Tag`] of the [`Widget`].
80 ///
81 /// [`Tag`]: tree::Tag
82 fn tag(&self) -> tree::Tag {
83 tree::Tag::stateless()
84 }
85
86 /// Returns the [`State`] of the [`Widget`].
87 ///
88 /// [`State`]: tree::State
89 fn state(&self) -> tree::State {
90 tree::State::None
91 }
92
93 /// Returns the state [`Tree`] of the children of the [`Widget`].
94 fn children(&self) -> Vec<Tree> {
95 Vec::new()
96 }
97
98 /// Reconciles the [`Widget`] with the provided [`Tree`].
99 fn diff(&self, _tree: &mut Tree) {}
100
101 /// Applies an [`Operation`] to the [`Widget`].
102 fn operate(
103 &self,
104 _state: &mut Tree,
105 _layout: Layout<'_>,
106 _renderer: &Renderer,
107 _operation: &mut dyn Operation,
108 ) {
109 }
110
111 /// Processes a runtime [`Event`].
112 ///
113 /// By default, it does nothing.
114 fn update(
115 &mut self,
116 _state: &mut Tree,
117 _event: &Event,
118 _layout: Layout<'_>,
119 _cursor: mouse::Cursor,
120 _renderer: &Renderer,
121 _clipboard: &mut dyn Clipboard,
122 _shell: &mut Shell<'_, Message>,
123 _viewport: &Rectangle,
124 ) {
125 }
126
127 /// Returns the current [`mouse::Interaction`] of the [`Widget`].
128 ///
129 /// By default, it returns [`mouse::Interaction::Idle`].
130 fn mouse_interaction(
131 &self,
132 _state: &Tree,
133 _layout: Layout<'_>,
134 _cursor: mouse::Cursor,
135 _viewport: &Rectangle,
136 _renderer: &Renderer,
137 ) -> mouse::Interaction {
138 mouse::Interaction::None
139 }
140
141 /// Returns the overlay of the [`Widget`], if there is any.
142 fn overlay<'a>(
143 &'a mut self,
144 _state: &'a mut Tree,
145 _layout: Layout<'_>,
146 _renderer: &Renderer,
147 _translation: Vector,
148 ) -> Option<overlay::Element<'a, Message, Theme, Renderer>> {
149 None
150 }
151}