summaryrefslogtreecommitdiffstats
path: root/graphics/src/widget
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/src/widget')
-rw-r--r--graphics/src/widget/button.rs12
-rw-r--r--graphics/src/widget/canvas.rs116
-rw-r--r--graphics/src/widget/canvas/cache.rs8
-rw-r--r--graphics/src/widget/canvas/frame.rs69
-rw-r--r--graphics/src/widget/canvas/geometry.rs6
-rw-r--r--graphics/src/widget/canvas/path.rs21
-rw-r--r--graphics/src/widget/canvas/path/builder.rs65
-rw-r--r--graphics/src/widget/canvas/program.rs50
-rw-r--r--graphics/src/widget/canvas/text.rs9
-rw-r--r--graphics/src/widget/checkbox.rs10
-rw-r--r--graphics/src/widget/column.rs5
-rw-r--r--graphics/src/widget/container.rs11
-rw-r--r--graphics/src/widget/image.rs25
-rw-r--r--graphics/src/widget/image/viewer.rs2
-rw-r--r--graphics/src/widget/pane_grid.rs26
-rw-r--r--graphics/src/widget/pick_list.rs9
-rw-r--r--graphics/src/widget/progress_bar.rs5
-rw-r--r--graphics/src/widget/qr_code.rs23
-rw-r--r--graphics/src/widget/radio.rs11
-rw-r--r--graphics/src/widget/row.rs5
-rw-r--r--graphics/src/widget/rule.rs3
-rw-r--r--graphics/src/widget/scrollable.rs13
-rw-r--r--graphics/src/widget/slider.rs5
-rw-r--r--graphics/src/widget/space.rs1
-rw-r--r--graphics/src/widget/svg.rs20
-rw-r--r--graphics/src/widget/text.rs7
-rw-r--r--graphics/src/widget/text_input.rs13
-rw-r--r--graphics/src/widget/toggler.rs10
-rw-r--r--graphics/src/widget/tooltip.rs11
29 files changed, 245 insertions, 326 deletions
diff --git a/graphics/src/widget/button.rs b/graphics/src/widget/button.rs
deleted file mode 100644
index 7b40c47b..00000000
--- a/graphics/src/widget/button.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//! Allow your users to perform actions by pressing a button.
-//!
-//! A [`Button`] has some local [`State`].
-use crate::Renderer;
-
-pub use iced_native::widget::button::{State, Style, StyleSheet};
-
-/// A widget that produces a message when clicked.
-///
-/// This is an alias of an `iced_native` button with an `iced_wgpu::Renderer`.
-pub type Button<'a, Message, Backend> =
- iced_native::widget::Button<'a, Message, Renderer<Backend>>;
diff --git a/graphics/src/widget/canvas.rs b/graphics/src/widget/canvas.rs
index 65d7e37e..88403fd7 100644
--- a/graphics/src/widget/canvas.rs
+++ b/graphics/src/widget/canvas.rs
@@ -3,16 +3,6 @@
//! A [`Canvas`] widget can be used to draw different kinds of 2D shapes in a
//! [`Frame`]. It can be used for animation, data visualization, game graphics,
//! and more!
-use crate::renderer::{self, Renderer};
-use crate::{Backend, Primitive};
-
-use iced_native::layout;
-use iced_native::mouse;
-use iced_native::{
- Clipboard, Element, Layout, Length, Point, Rectangle, Shell, Size, Vector,
- Widget,
-};
-use std::marker::PhantomData;
pub mod event;
pub mod path;
@@ -37,34 +27,32 @@ pub use program::Program;
pub use stroke::{LineCap, LineDash, LineJoin, Stroke};
pub use text::Text;
+use crate::{Backend, Primitive, Renderer};
+
+use iced_native::layout::{self, Layout};
+use iced_native::mouse;
+use iced_native::renderer;
+use iced_native::widget::tree::{self, Tree};
+use iced_native::{
+ Clipboard, Element, Length, Point, Rectangle, Shell, Size, Vector, Widget,
+};
+
+use std::marker::PhantomData;
+
/// A widget capable of drawing 2D graphics.
///
-/// # Examples
-/// The repository has a couple of [examples] showcasing how to use a
-/// [`Canvas`]:
-///
-/// - [`clock`], an application that uses the [`Canvas`] widget to draw a clock
-/// and its hands to display the current time.
-/// - [`game_of_life`], an interactive version of the Game of Life, invented by
-/// John Conway.
-/// - [`solar_system`], an animated solar system drawn using the [`Canvas`] widget
-/// and showcasing how to compose different transforms.
-///
-/// [examples]: https://github.com/hecrj/iced/tree/master/examples
-/// [`clock`]: https://github.com/hecrj/iced/tree/master/examples/clock
-/// [`game_of_life`]: https://github.com/hecrj/iced/tree/master/examples/game_of_life
-/// [`solar_system`]: https://github.com/hecrj/iced/tree/master/examples/solar_system
-///
/// ## Drawing a simple circle
/// If you want to get a quick overview, here's how we can draw a simple circle:
///
/// ```no_run
/// # mod iced {
-/// # pub use iced_graphics::canvas;
-/// # pub use iced_native::{Color, Rectangle};
+/// # pub mod widget {
+/// # pub use iced_graphics::widget::canvas;
+/// # }
+/// # pub use iced_native::{Color, Rectangle, Theme};
/// # }
-/// use iced::canvas::{self, Canvas, Cursor, Fill, Frame, Geometry, Path, Program};
-/// use iced::{Color, Rectangle};
+/// use iced::widget::canvas::{self, Canvas, Cursor, Fill, Frame, Geometry, Path, Program};
+/// use iced::{Color, Rectangle, Theme};
///
/// // First, we define the data we need for drawing
/// #[derive(Debug)]
@@ -74,7 +62,9 @@ pub use text::Text;
///
/// // Then, we implement the `Program` trait
/// impl Program<()> for Circle {
-/// fn draw(&self, bounds: Rectangle, _cursor: Cursor) -> Vec<Geometry>{
+/// type State = ();
+///
+/// fn draw(&self, _state: &(), _theme: &Theme, bounds: Rectangle, _cursor: Cursor) -> Vec<Geometry>{
/// // We prepare a new `Frame`
/// let mut frame = Frame::new(bounds.size());
///
@@ -93,14 +83,21 @@ pub use text::Text;
/// let canvas = Canvas::new(Circle { radius: 50.0 });
/// ```
#[derive(Debug)]
-pub struct Canvas<Message, P: Program<Message>> {
+pub struct Canvas<Message, Theme, P>
+where
+ P: Program<Message, Theme>,
+{
width: Length,
height: Length,
program: P,
- phantom: PhantomData<Message>,
+ message_: PhantomData<Message>,
+ theme_: PhantomData<Theme>,
}
-impl<Message, P: Program<Message>> Canvas<Message, P> {
+impl<Message, Theme, P> Canvas<Message, Theme, P>
+where
+ P: Program<Message, Theme>,
+{
const DEFAULT_SIZE: u16 = 100;
/// Creates a new [`Canvas`].
@@ -109,7 +106,8 @@ impl<Message, P: Program<Message>> Canvas<Message, P> {
width: Length::Units(Self::DEFAULT_SIZE),
height: Length::Units(Self::DEFAULT_SIZE),
program,
- phantom: PhantomData,
+ message_: PhantomData,
+ theme_: PhantomData,
}
}
@@ -126,11 +124,20 @@ impl<Message, P: Program<Message>> Canvas<Message, P> {
}
}
-impl<Message, P, B> Widget<Message, Renderer<B>> for Canvas<Message, P>
+impl<Message, P, B, T> Widget<Message, Renderer<B, T>> for Canvas<Message, T, P>
where
- P: Program<Message>,
+ P: Program<Message, T>,
B: Backend,
{
+ fn tag(&self) -> tree::Tag {
+ struct Tag<T>(T);
+ tree::Tag::of::<Tag<P::State>>()
+ }
+
+ fn state(&self) -> tree::State {
+ tree::State::new(P::State::default())
+ }
+
fn width(&self) -> Length {
self.width
}
@@ -141,7 +148,7 @@ where
fn layout(
&self,
- _renderer: &Renderer<B>,
+ _renderer: &Renderer<B, T>,
limits: &layout::Limits,
) -> layout::Node {
let limits = limits.width(self.width).height(self.height);
@@ -152,10 +159,11 @@ where
fn on_event(
&mut self,
+ tree: &mut Tree,
event: iced_native::Event,
layout: Layout<'_>,
cursor_position: Point,
- _renderer: &Renderer<B>,
+ _renderer: &Renderer<B, T>,
_clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
) -> event::Status {
@@ -174,8 +182,10 @@ where
let cursor = Cursor::from_window_position(cursor_position);
if let Some(canvas_event) = canvas_event {
+ let state = tree.state.downcast_mut::<P::State>();
+
let (event_status, message) =
- self.program.update(canvas_event, bounds, cursor);
+ self.program.update(state, canvas_event, bounds, cursor);
if let Some(message) = message {
shell.publish(message);
@@ -189,20 +199,24 @@ where
fn mouse_interaction(
&self,
+ tree: &Tree,
layout: Layout<'_>,
cursor_position: Point,
_viewport: &Rectangle,
- _renderer: &Renderer<B>,
+ _renderer: &Renderer<B, T>,
) -> mouse::Interaction {
let bounds = layout.bounds();
let cursor = Cursor::from_window_position(cursor_position);
+ let state = tree.state.downcast_ref::<P::State>();
- self.program.mouse_interaction(bounds, cursor)
+ self.program.mouse_interaction(state, bounds, cursor)
}
fn draw(
&self,
- renderer: &mut Renderer<B>,
+ tree: &Tree,
+ renderer: &mut Renderer<B, T>,
+ theme: &T,
_style: &renderer::Style,
layout: Layout<'_>,
cursor_position: Point,
@@ -218,12 +232,13 @@ where
let translation = Vector::new(bounds.x, bounds.y);
let cursor = Cursor::from_window_position(cursor_position);
+ let state = tree.state.downcast_ref::<P::State>();
renderer.with_translation(translation, |renderer| {
renderer.draw_primitive(Primitive::Group {
primitives: self
.program
- .draw(bounds, cursor)
+ .draw(state, theme, bounds, cursor)
.into_iter()
.map(Geometry::into_primitive)
.collect(),
@@ -232,14 +247,17 @@ where
}
}
-impl<'a, Message, P, B> From<Canvas<Message, P>>
- for Element<'a, Message, Renderer<B>>
+impl<'a, Message, P, B, T> From<Canvas<Message, T, P>>
+ for Element<'a, Message, Renderer<B, T>>
where
- Message: 'static,
- P: Program<Message> + 'a,
+ Message: 'a,
+ P: Program<Message, T> + 'a,
B: Backend,
+ T: 'a,
{
- fn from(canvas: Canvas<Message, P>) -> Element<'a, Message, Renderer<B>> {
+ fn from(
+ canvas: Canvas<Message, T, P>,
+ ) -> Element<'a, Message, Renderer<B, T>> {
Element::new(canvas)
}
}
diff --git a/graphics/src/widget/canvas/cache.rs b/graphics/src/widget/canvas/cache.rs
index a469417d..49873ac9 100644
--- a/graphics/src/widget/canvas/cache.rs
+++ b/graphics/src/widget/canvas/cache.rs
@@ -1,7 +1,5 @@
-use crate::{
- canvas::{Frame, Geometry},
- Primitive,
-};
+use crate::widget::canvas::{Frame, Geometry};
+use crate::Primitive;
use iced_native::Size;
use std::{cell::RefCell, sync::Arc};
@@ -37,7 +35,7 @@ impl Cache {
}
/// Clears the [`Cache`], forcing a redraw the next time it is used.
- pub fn clear(&mut self) {
+ pub fn clear(&self) {
*self.state.borrow_mut() = State::Empty;
}
diff --git a/graphics/src/widget/canvas/frame.rs b/graphics/src/widget/canvas/frame.rs
index 357dfa62..516539ca 100644
--- a/graphics/src/widget/canvas/frame.rs
+++ b/graphics/src/widget/canvas/frame.rs
@@ -2,11 +2,10 @@ use std::borrow::Cow;
use iced_native::{Point, Rectangle, Size, Vector};
-use crate::{
- canvas::path,
- canvas::{Fill, Geometry, Path, Stroke, Text},
- triangle, Primitive,
-};
+use crate::triangle;
+use crate::widget::canvas::path;
+use crate::widget::canvas::{Fill, Geometry, Path, Stroke, Text};
+use crate::Primitive;
use lyon::tessellation;
@@ -110,7 +109,7 @@ impl Frame {
)
};
- let _ = result.expect("Tessellate path");
+ result.expect("Tessellate path");
}
/// Draws an axis-aligned rectangle given its top-left corner coordinate and
@@ -141,10 +140,9 @@ impl Frame {
let options =
tessellation::FillOptions::default().with_fill_rule(rule.into());
- let _ = self
- .fill_tessellator
+ self.fill_tessellator
.tessellate_rectangle(
- &lyon::math::Rect::new(top_left, size.into()),
+ &lyon::math::Box2D::new(top_left, top_left + size),
&options,
&mut buffers,
)
@@ -189,7 +187,7 @@ impl Frame {
)
};
- let _ = result.expect("Stroke path");
+ result.expect("Stroke path");
}
/// Draws the characters of the given [`Text`] on the [`Frame`], filling
@@ -253,6 +251,45 @@ impl Frame {
self.transforms.current = self.transforms.previous.pop().unwrap();
}
+ /// Executes the given drawing operations within a [`Rectangle`] region,
+ /// clipping any geometry that overflows its bounds. Any transformations
+ /// performed are local to the provided closure.
+ ///
+ /// This method is useful to perform drawing operations that need to be
+ /// clipped.
+ #[inline]
+ pub fn with_clip(&mut self, region: Rectangle, f: impl FnOnce(&mut Frame)) {
+ let mut frame = Frame::new(region.size());
+
+ f(&mut frame);
+
+ let primitives = frame.into_primitives();
+
+ let (text, meshes) = primitives
+ .into_iter()
+ .partition(|primitive| matches!(primitive, Primitive::Text { .. }));
+
+ let translation = Vector::new(region.x, region.y);
+
+ self.primitives.push(Primitive::Group {
+ primitives: vec![
+ Primitive::Translate {
+ translation,
+ content: Box::new(Primitive::Group { primitives: meshes }),
+ },
+ Primitive::Translate {
+ translation,
+ content: Box::new(Primitive::Clip {
+ bounds: Rectangle::with_size(region.size()),
+ content: Box::new(Primitive::Group {
+ primitives: text,
+ }),
+ }),
+ },
+ ],
+ });
+ }
+
/// Applies a translation to the current transform of the [`Frame`].
#[inline]
pub fn translate(&mut self, translation: Vector) {
@@ -287,7 +324,13 @@ impl Frame {
}
/// Produces the [`Geometry`] representing everything drawn on the [`Frame`].
- pub fn into_geometry(mut self) -> Geometry {
+ pub fn into_geometry(self) -> Geometry {
+ Geometry::from_primitive(Primitive::Group {
+ primitives: self.into_primitives(),
+ })
+ }
+
+ fn into_primitives(mut self) -> Vec<Primitive> {
if !self.buffers.indices.is_empty() {
self.primitives.push(Primitive::Mesh2D {
buffers: triangle::Mesh2D {
@@ -298,9 +341,7 @@ impl Frame {
});
}
- Geometry::from_primitive(Primitive::Group {
- primitives: self.primitives,
- })
+ self.primitives
}
}
diff --git a/graphics/src/widget/canvas/geometry.rs b/graphics/src/widget/canvas/geometry.rs
index 8915cda1..e8ac621d 100644
--- a/graphics/src/widget/canvas/geometry.rs
+++ b/graphics/src/widget/canvas/geometry.rs
@@ -22,9 +22,3 @@ impl Geometry {
self.0
}
}
-
-impl From<Geometry> for Primitive {
- fn from(geometry: Geometry) -> Primitive {
- geometry.0
- }
-}
diff --git a/graphics/src/widget/canvas/path.rs b/graphics/src/widget/canvas/path.rs
index 1728f060..aeb2589e 100644
--- a/graphics/src/widget/canvas/path.rs
+++ b/graphics/src/widget/canvas/path.rs
@@ -7,10 +7,10 @@ mod builder;
pub use arc::Arc;
pub use builder::Builder;
-use crate::canvas::LineDash;
+use crate::widget::canvas::LineDash;
use iced_native::{Point, Size};
-use lyon::algorithms::walk::{walk_along_path, RepeatedPattern};
+use lyon::algorithms::walk::{walk_along_path, RepeatedPattern, WalkerEvent};
use lyon::path::iterator::PathIterator;
/// An immutable set of points that may or may not be connected.
@@ -73,22 +73,20 @@ impl Path {
pub(super) fn dashed(path: &Path, line_dash: LineDash<'_>) -> Path {
Path::new(|builder| {
- let segments_odd = (line_dash.segments.len() % 2 == 1).then(|| {
- [&line_dash.segments[..], &line_dash.segments[..]].concat()
- });
+ let segments_odd = (line_dash.segments.len() % 2 == 1)
+ .then(|| [line_dash.segments, line_dash.segments].concat());
let mut draw_line = false;
walk_along_path(
path.raw().iter().flattened(0.01),
0.0,
+ lyon::tessellation::StrokeOptions::DEFAULT_TOLERANCE,
&mut RepeatedPattern {
- callback: |position: lyon::algorithms::math::Point,
- _tangent,
- _distance| {
+ callback: |event: WalkerEvent<'_>| {
let point = Point {
- x: position.x,
- y: position.y,
+ x: event.position.x,
+ y: event.position.y,
};
if draw_line {
@@ -103,8 +101,7 @@ pub(super) fn dashed(path: &Path, line_dash: LineDash<'_>) -> Path {
},
index: line_dash.offset,
intervals: segments_odd
- .as_ref()
- .map(Vec::as_slice)
+ .as_deref()
.unwrap_or(line_dash.segments),
},
);
diff --git a/graphics/src/widget/canvas/path/builder.rs b/graphics/src/widget/canvas/path/builder.rs
index d04dbdde..5121aa68 100644
--- a/graphics/src/widget/canvas/path/builder.rs
+++ b/graphics/src/widget/canvas/path/builder.rs
@@ -1,4 +1,4 @@
-use crate::canvas::path::{arc, Arc, Path};
+use crate::widget::canvas::path::{arc, Arc, Path};
use iced_native::{Point, Size};
use lyon::path::builder::SvgPathBuilder;
@@ -8,7 +8,7 @@ use lyon::path::builder::SvgPathBuilder;
/// Once a [`Path`] is built, it can no longer be mutated.
#[allow(missing_debug_implementations)]
pub struct Builder {
- raw: lyon::path::builder::WithSvg<lyon::path::path::Builder>,
+ raw: lyon::path::builder::WithSvg<lyon::path::path::BuilderImpl>,
}
impl Builder {
@@ -42,22 +42,61 @@ impl Builder {
/// Adds a circular arc to the [`Path`] with the given control points and
/// radius.
///
- /// The arc is connected to the previous point by a straight line, if
- /// necessary.
+ /// This essentially draws a straight line segment from the current
+ /// position to `a`, but fits a circular arc of `radius` tangent to that
+ /// segment and tangent to the line between `a` and `b`.
+ ///
+ /// With another `.line_to(b)`, the result will be a path connecting the
+ /// starting point and `b` with straight line segments towards `a` and a
+ /// circular arc smoothing out the corner at `a`.
+ ///
+ /// See [the HTML5 specification of `arcTo`](https://html.spec.whatwg.org/multipage/canvas.html#building-paths:dom-context-2d-arcto)
+ /// for more details and examples.
pub fn arc_to(&mut self, a: Point, b: Point, radius: f32) {
use lyon::{math, path};
- let a = math::Point::new(a.x, a.y);
+ let start = self.raw.current_position();
+ let mid = math::Point::new(a.x, a.y);
+ let end = math::Point::new(b.x, b.y);
+
+ if start == mid || mid == end || radius == 0.0 {
+ let _ = self.raw.line_to(mid);
+ return;
+ }
+
+ let double_area = start.x * (mid.y - end.y)
+ + mid.x * (end.y - start.y)
+ + end.x * (start.y - mid.y);
- if self.raw.current_position() != a {
- let _ = self.raw.line_to(a);
+ if double_area == 0.0 {
+ let _ = self.raw.line_to(mid);
+ return;
}
- let _ = self.raw.arc_to(
+ let to_start = (start - mid).normalize();
+ let to_end = (end - mid).normalize();
+
+ let inner_angle = to_start.dot(to_end).acos();
+
+ let origin_angle = inner_angle / 2.0;
+
+ let origin_adjacent = radius / origin_angle.tan();
+
+ let arc_start = mid + to_start * origin_adjacent;
+ let arc_end = mid + to_end * origin_adjacent;
+
+ let sweep = to_start.cross(to_end) < 0.0;
+
+ let _ = self.raw.line_to(arc_start);
+
+ self.raw.arc_to(
math::Vector::new(radius, radius),
math::Angle::radians(0.0),
- path::ArcFlags::default(),
- math::Point::new(b.x, b.y),
+ path::ArcFlags {
+ large_arc: false,
+ sweep,
+ },
+ arc_end,
);
}
@@ -151,3 +190,9 @@ impl Builder {
}
}
}
+
+impl Default for Builder {
+ fn default() -> Self {
+ Self::new()
+ }
+}
diff --git a/graphics/src/widget/canvas/program.rs b/graphics/src/widget/canvas/program.rs
index 85a2f67b..656dbfa6 100644
--- a/graphics/src/widget/canvas/program.rs
+++ b/graphics/src/widget/canvas/program.rs
@@ -1,6 +1,7 @@
-use crate::canvas::event::{self, Event};
-use crate::canvas::{Cursor, Geometry};
-use iced_native::{mouse, Rectangle};
+use crate::widget::canvas::event::{self, Event};
+use crate::widget::canvas::mouse;
+use crate::widget::canvas::{Cursor, Geometry};
+use crate::Rectangle;
/// The state and logic of a [`Canvas`].
///
@@ -8,8 +9,11 @@ use iced_native::{mouse, Rectangle};
/// application.
///
/// [`Canvas`]: crate::widget::Canvas
-pub trait Program<Message> {
- /// Updates the state of the [`Program`].
+pub trait Program<Message, Theme = iced_native::Theme> {
+ /// The internal state mutated by the [`Program`].
+ type State: Default + 'static;
+
+ /// Updates the [`State`](Self::State) of the [`Program`].
///
/// When a [`Program`] is used in a [`Canvas`], the runtime will call this
/// method for each [`Event`].
@@ -21,7 +25,8 @@ pub trait Program<Message> {
///
/// [`Canvas`]: crate::widget::Canvas
fn update(
- &mut self,
+ &self,
+ _state: &mut Self::State,
_event: Event,
_bounds: Rectangle,
_cursor: Cursor,
@@ -36,7 +41,13 @@ pub trait Program<Message> {
///
/// [`Frame`]: crate::widget::canvas::Frame
/// [`Cache`]: crate::widget::canvas::Cache
- fn draw(&self, bounds: Rectangle, cursor: Cursor) -> Vec<Geometry>;
+ fn draw(
+ &self,
+ state: &Self::State,
+ theme: &Theme,
+ bounds: Rectangle,
+ cursor: Cursor,
+ ) -> Vec<Geometry>;
/// Returns the current mouse interaction of the [`Program`].
///
@@ -46,6 +57,7 @@ pub trait Program<Message> {
/// [`Canvas`]: crate::widget::Canvas
fn mouse_interaction(
&self,
+ _state: &Self::State,
_bounds: Rectangle,
_cursor: Cursor,
) -> mouse::Interaction {
@@ -53,28 +65,38 @@ pub trait Program<Message> {
}
}
-impl<T, Message> Program<Message> for &mut T
+impl<Message, Theme, T> Program<Message, Theme> for &T
where
- T: Program<Message>,
+ T: Program<Message, Theme>,
{
+ type State = T::State;
+
fn update(
- &mut self,
+ &self,
+ state: &mut Self::State,
event: Event,
bounds: Rectangle,
cursor: Cursor,
) -> (event::Status, Option<Message>) {
- T::update(self, event, bounds, cursor)
+ T::update(self, state, event, bounds, cursor)
}
- fn draw(&self, bounds: Rectangle, cursor: Cursor) -> Vec<Geometry> {
- T::draw(self, bounds, cursor)
+ fn draw(
+ &self,
+ state: &Self::State,
+ theme: &Theme,
+ bounds: Rectangle,
+ cursor: Cursor,
+ ) -> Vec<Geometry> {
+ T::draw(self, state, theme, bounds, cursor)
}
fn mouse_interaction(
&self,
+ state: &Self::State,
bounds: Rectangle,
cursor: Cursor,
) -> mouse::Interaction {
- T::mouse_interaction(self, bounds, cursor)
+ T::mouse_interaction(self, state, bounds, cursor)
}
}
diff --git a/graphics/src/widget/canvas/text.rs b/graphics/src/widget/canvas/text.rs
index ab070a70..056f8204 100644
--- a/graphics/src/widget/canvas/text.rs
+++ b/graphics/src/widget/canvas/text.rs
@@ -6,7 +6,14 @@ use crate::{Color, Font, Point};
pub struct Text {
/// The contents of the text
pub content: String,
- /// The position where to begin drawing the text (top-left corner coordinates)
+ /// The position of the text relative to the alignment properties.
+ /// By default, this position will be relative to the top-left corner coordinate meaning that
+ /// if the horizontal and vertical alignments are unchanged, this property will tell where the
+ /// top-left corner of the text should be placed.
+ /// By changing the horizontal_alignment and vertical_alignment properties, you are are able to
+ /// change what part of text is placed at this positions.
+ /// For example, when the horizontal_alignment and vertical_alignment are set to Center, the
+ /// center of the text will be placed at the given position NOT the top-left coordinate.
pub position: Point,
/// The color of the text
pub color: Color,
diff --git a/graphics/src/widget/checkbox.rs b/graphics/src/widget/checkbox.rs
deleted file mode 100644
index 0d2e93f9..00000000
--- a/graphics/src/widget/checkbox.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//! Show toggle controls using checkboxes.
-use crate::Renderer;
-
-pub use iced_style::checkbox::{Style, StyleSheet};
-
-/// A box that can be checked.
-///
-/// This is an alias of an `iced_native` checkbox with an `iced_wgpu::Renderer`.
-pub type Checkbox<'a, Message, Backend> =
- iced_native::widget::Checkbox<'a, Message, Renderer<Backend>>;
diff --git a/graphics/src/widget/column.rs b/graphics/src/widget/column.rs
deleted file mode 100644
index 561681d5..00000000
--- a/graphics/src/widget/column.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-use crate::Renderer;
-
-/// A container that distributes its contents vertically.
-pub type Column<'a, Message, Backend> =
- iced_native::widget::Column<'a, Message, Renderer<Backend>>;
diff --git a/graphics/src/widget/container.rs b/graphics/src/widget/container.rs
deleted file mode 100644
index 99996f3b..00000000
--- a/graphics/src/widget/container.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//! Decorate content and apply alignment.
-use crate::Renderer;
-
-pub use iced_style::container::{Style, StyleSheet};
-
-/// An element decorating some content.
-///
-/// This is an alias of an `iced_native` container with a default
-/// `Renderer`.
-pub type Container<'a, Message, Backend> =
- iced_native::widget::Container<'a, Message, Renderer<Backend>>;
diff --git a/graphics/src/widget/image.rs b/graphics/src/widget/image.rs
deleted file mode 100644
index 76152484..00000000
--- a/graphics/src/widget/image.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-//! Display images in your user interface.
-pub mod viewer;
-
-use crate::backend::{self, Backend};
-use crate::{Primitive, Rectangle, Renderer};
-
-use iced_native::image;
-
-pub use iced_native::widget::image::{Image, Viewer};
-pub use image::Handle;
-
-impl<B> image::Renderer for Renderer<B>
-where
- B: Backend + backend::Image,
-{
- type Handle = image::Handle;
-
- fn dimensions(&self, handle: &image::Handle) -> (u32, u32) {
- self.backend().dimensions(handle)
- }
-
- fn draw(&mut self, handle: image::Handle, bounds: Rectangle) {
- self.draw_primitive(Primitive::Image { handle, bounds })
- }
-}
diff --git a/graphics/src/widget/image/viewer.rs b/graphics/src/widget/image/viewer.rs
deleted file mode 100644
index 9260990a..00000000
--- a/graphics/src/widget/image/viewer.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-//! Zoom and pan on an image.
-pub use iced_native::widget::image::Viewer;
diff --git a/graphics/src/widget/pane_grid.rs b/graphics/src/widget/pane_grid.rs
deleted file mode 100644
index 95189920..00000000
--- a/graphics/src/widget/pane_grid.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-//! Let your users split regions of your application and organize layout dynamically.
-//!
-//! [![Pane grid - Iced](https://thumbs.gfycat.com/MixedFlatJellyfish-small.gif)](https://gfycat.com/mixedflatjellyfish)
-//!
-//! # Example
-//! The [`pane_grid` example] showcases how to use a [`PaneGrid`] with resizing,
-//! drag and drop, and hotkey support.
-//!
-//! [`pane_grid` example]: https://github.com/hecrj/iced/tree/0.3/examples/pane_grid
-use crate::Renderer;
-
-pub use iced_native::widget::pane_grid::{
- Axis, Configuration, Content, Direction, DragEvent, Node, Pane,
- ResizeEvent, Split, State, TitleBar,
-};
-
-pub use iced_style::pane_grid::{Line, StyleSheet};
-
-/// A collection of panes distributed using either vertical or horizontal splits
-/// to completely fill the space available.
-///
-/// [![Pane grid - Iced](https://thumbs.gfycat.com/MixedFlatJellyfish-small.gif)](https://gfycat.com/mixedflatjellyfish)
-///
-/// This is an alias of an `iced_native` pane grid with an `iced_wgpu::Renderer`.
-pub type PaneGrid<'a, Message, Backend> =
- iced_native::widget::PaneGrid<'a, Message, Renderer<Backend>>;
diff --git a/graphics/src/widget/pick_list.rs b/graphics/src/widget/pick_list.rs
deleted file mode 100644
index f3ac12b8..00000000
--- a/graphics/src/widget/pick_list.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//! Display a dropdown list of selectable values.
-use crate::Renderer;
-
-pub use iced_native::widget::pick_list::State;
-pub use iced_style::pick_list::{Style, StyleSheet};
-
-/// A widget allowing the selection of a single value from a list of options.
-pub type PickList<'a, T, Message, Backend> =
- iced_native::widget::PickList<'a, T, Message, Renderer<Backend>>;
diff --git a/graphics/src/widget/progress_bar.rs b/graphics/src/widget/progress_bar.rs
deleted file mode 100644
index 3666ecfd..00000000
--- a/graphics/src/widget/progress_bar.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-//! Allow your users to visually track the progress of a computation.
-//!
-//! A [`ProgressBar`] has a range of possible values and a current value,
-//! as well as a length, height and style.
-pub use iced_native::widget::progress_bar::*;
diff --git a/graphics/src/widget/qr_code.rs b/graphics/src/widget/qr_code.rs
index 907794b7..12ce5b1f 100644
--- a/graphics/src/widget/qr_code.rs
+++ b/graphics/src/widget/qr_code.rs
@@ -1,9 +1,10 @@
//! Encode and display information in a QR code.
-use crate::canvas;
use crate::renderer::{self, Renderer};
+use crate::widget::canvas;
use crate::Backend;
use iced_native::layout;
+use iced_native::widget::Tree;
use iced_native::{
Color, Element, Layout, Length, Point, Rectangle, Size, Vector, Widget,
};
@@ -47,7 +48,7 @@ impl<'a> QRCode<'a> {
}
}
-impl<'a, Message, B> Widget<Message, Renderer<B>> for QRCode<'a>
+impl<'a, Message, B, T> Widget<Message, Renderer<B, T>> for QRCode<'a>
where
B: Backend,
{
@@ -61,21 +62,20 @@ where
fn layout(
&self,
- _renderer: &Renderer<B>,
+ _renderer: &Renderer<B, T>,
_limits: &layout::Limits,
) -> layout::Node {
let side_length = (self.state.width + 2 * QUIET_ZONE) as f32
* f32::from(self.cell_size);
- layout::Node::new(Size::new(
- f32::from(side_length),
- f32::from(side_length),
- ))
+ layout::Node::new(Size::new(side_length, side_length))
}
fn draw(
&self,
- renderer: &mut Renderer<B>,
+ _state: &Tree,
+ renderer: &mut Renderer<B, T>,
+ _theme: &T,
_style: &renderer::Style,
layout: Layout<'_>,
_cursor_position: Point,
@@ -127,12 +127,13 @@ where
}
}
-impl<'a, Message, B> Into<Element<'a, Message, Renderer<B>>> for QRCode<'a>
+impl<'a, Message, B, T> From<QRCode<'a>>
+ for Element<'a, Message, Renderer<B, T>>
where
B: Backend,
{
- fn into(self) -> Element<'a, Message, Renderer<B>> {
- Element::new(self)
+ fn from(qr_code: QRCode<'a>) -> Self {
+ Self::new(qr_code)
}
}
diff --git a/graphics/src/widget/radio.rs b/graphics/src/widget/radio.rs
deleted file mode 100644
index 20d72747..00000000
--- a/graphics/src/widget/radio.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//! Create choices using radio buttons.
-use crate::Renderer;
-
-pub use iced_style::radio::{Style, StyleSheet};
-
-/// A circular button representing a choice.
-///
-/// This is an alias of an `iced_native` radio button with an
-/// `iced_wgpu::Renderer`.
-pub type Radio<'a, Message, Backend> =
- iced_native::widget::Radio<'a, Message, Renderer<Backend>>;
diff --git a/graphics/src/widget/row.rs b/graphics/src/widget/row.rs
deleted file mode 100644
index 5bee3fd5..00000000
--- a/graphics/src/widget/row.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-use crate::Renderer;
-
-/// A container that distributes its contents horizontally.
-pub type Row<'a, Message, Backend> =
- iced_native::widget::Row<'a, Message, Renderer<Backend>>;
diff --git a/graphics/src/widget/rule.rs b/graphics/src/widget/rule.rs
deleted file mode 100644
index b96924fa..00000000
--- a/graphics/src/widget/rule.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-//! Display a horizontal or vertical rule for dividing content.
-
-pub use iced_native::widget::rule::*;
diff --git a/graphics/src/widget/scrollable.rs b/graphics/src/widget/scrollable.rs
deleted file mode 100644
index 3fdaf668..00000000
--- a/graphics/src/widget/scrollable.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//! Navigate an endless amount of content with a scrollbar.
-use crate::Renderer;
-
-pub use iced_native::widget::scrollable::State;
-pub use iced_style::scrollable::{Scrollbar, Scroller, StyleSheet};
-
-/// A widget that can vertically display an infinite amount of content
-/// with a scrollbar.
-///
-/// This is an alias of an `iced_native` scrollable with a default
-/// `Renderer`.
-pub type Scrollable<'a, Message, Backend> =
- iced_native::widget::Scrollable<'a, Message, Renderer<Backend>>;
diff --git a/graphics/src/widget/slider.rs b/graphics/src/widget/slider.rs
deleted file mode 100644
index 96dc6ec4..00000000
--- a/graphics/src/widget/slider.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-//! Display an interactive selector of a single value from a range of values.
-//!
-//! A [`Slider`] has some local [`State`].
-pub use iced_native::widget::slider::{Slider, State};
-pub use iced_style::slider::{Handle, HandleShape, Style, StyleSheet};
diff --git a/graphics/src/widget/space.rs b/graphics/src/widget/space.rs
deleted file mode 100644
index 77e93dbb..00000000
--- a/graphics/src/widget/space.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub use iced_native::widget::Space;
diff --git a/graphics/src/widget/svg.rs b/graphics/src/widget/svg.rs
deleted file mode 100644
index 5817a552..00000000
--- a/graphics/src/widget/svg.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-//! Display vector graphics in your application.
-use crate::backend::{self, Backend};
-use crate::{Primitive, Rectangle, Renderer};
-use iced_native::svg;
-
-pub use iced_native::widget::svg::Svg;
-pub use svg::Handle;
-
-impl<B> svg::Renderer for Renderer<B>
-where
- B: Backend + backend::Svg,
-{
- fn dimensions(&self, handle: &svg::Handle) -> (u32, u32) {
- self.backend().viewport_dimensions(handle)
- }
-
- fn draw(&mut self, handle: svg::Handle, bounds: Rectangle) {
- self.draw_primitive(Primitive::Svg { handle, bounds })
- }
-}
diff --git a/graphics/src/widget/text.rs b/graphics/src/widget/text.rs
deleted file mode 100644
index 43516fca..00000000
--- a/graphics/src/widget/text.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//! Write some text for your users to read.
-use crate::Renderer;
-
-/// A paragraph of text.
-///
-/// This is an alias of an `iced_native` text with an `iced_wgpu::Renderer`.
-pub type Text<Backend> = iced_native::widget::Text<Renderer<Backend>>;
diff --git a/graphics/src/widget/text_input.rs b/graphics/src/widget/text_input.rs
deleted file mode 100644
index 87384d7e..00000000
--- a/graphics/src/widget/text_input.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//! Display fields that can be filled with text.
-//!
-//! A [`TextInput`] has some local [`State`].
-use crate::Renderer;
-
-pub use iced_native::widget::text_input::State;
-pub use iced_style::text_input::{Style, StyleSheet};
-
-/// A field that can be filled with text.
-///
-/// This is an alias of an `iced_native` text input with an `iced_wgpu::Renderer`.
-pub type TextInput<'a, Message, Backend> =
- iced_native::widget::TextInput<'a, Message, Renderer<Backend>>;
diff --git a/graphics/src/widget/toggler.rs b/graphics/src/widget/toggler.rs
deleted file mode 100644
index 9053e6ed..00000000
--- a/graphics/src/widget/toggler.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//! Show toggle controls using togglers.
-use crate::Renderer;
-
-pub use iced_style::toggler::{Style, StyleSheet};
-
-/// A toggler that can be toggled.
-///
-/// This is an alias of an `iced_native` toggler with an `iced_wgpu::Renderer`.
-pub type Toggler<'a, Message, Backend> =
- iced_native::widget::Toggler<'a, Message, Renderer<Backend>>;
diff --git a/graphics/src/widget/tooltip.rs b/graphics/src/widget/tooltip.rs
deleted file mode 100644
index 7dc12ed4..00000000
--- a/graphics/src/widget/tooltip.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//! Decorate content and apply alignment.
-use crate::Renderer;
-
-/// An element decorating some content.
-///
-/// This is an alias of an `iced_native` tooltip with a default
-/// `Renderer`.
-pub type Tooltip<'a, Message, Backend> =
- iced_native::widget::Tooltip<'a, Message, Renderer<Backend>>;
-
-pub use iced_native::widget::tooltip::Position;