summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón <hector0193@gmail.com>2020-04-15 05:43:40 +0200
committerLibravatar GitHub <noreply@github.com>2020-04-15 05:43:40 +0200
commit99352f02fd39250475861209d85f696b50ec9b73 (patch)
tree3bba2a04eb940bee50551601deceebbb8e1c1d8f
parentd0ebcdb9365b47bc28963759499f0c889f90f90f (diff)
parent6d7f2b30cc9fd4022681f766ee3b77cdb6c8de0a (diff)
downloadiced-99352f02fd39250475861209d85f696b50ec9b73.tar.gz
iced-99352f02fd39250475861209d85f696b50ec9b73.tar.bz2
iced-99352f02fd39250475861209d85f696b50ec9b73.zip
Merge pull request #293 from hecrj/improvement/canvas-ergonomics
Improve `Canvas` ergonomics
Diffstat (limited to '')
-rw-r--r--examples/clock/src/main.rs81
-rw-r--r--examples/solar_system/src/main.rs47
-rw-r--r--wgpu/src/widget/canvas/fill.rs6
-rw-r--r--wgpu/src/widget/canvas/frame.rs12
-rw-r--r--wgpu/src/widget/canvas/path.rs29
-rw-r--r--wgpu/src/widget/canvas/path/builder.rs13
-rw-r--r--wgpu/src/widget/canvas/text.rs15
7 files changed, 118 insertions, 85 deletions
diff --git a/examples/clock/src/main.rs b/examples/clock/src/main.rs
index a85a964c..827379fa 100644
--- a/examples/clock/src/main.rs
+++ b/examples/clock/src/main.rs
@@ -95,68 +95,57 @@ impl From<chrono::DateTime<chrono::Local>> for LocalTime {
impl canvas::Drawable for LocalTime {
fn draw(&self, frame: &mut canvas::Frame) {
+ use canvas::Path;
+
let center = frame.center();
let radius = frame.width().min(frame.height()) / 2.0;
- let offset = Vector::new(center.x, center.y);
- let clock = canvas::Path::new(|path| path.circle(center, radius));
+ let clock = Path::circle(center, radius);
+ frame.fill(&clock, Color::from_rgb8(0x12, 0x93, 0xD8));
- frame.fill(
- &clock,
- canvas::Fill::Color(Color::from_rgb8(0x12, 0x93, 0xD8)),
- );
+ let short_hand =
+ Path::line(Point::ORIGIN, Point::new(0.0, -0.5 * radius));
- fn draw_hand(
- n: u32,
- total: u32,
- length: f32,
- offset: Vector,
- path: &mut canvas::path::Builder,
- ) {
- let turns = n as f32 / total as f32;
- let t = 2.0 * std::f32::consts::PI * (turns - 0.25);
+ let long_hand =
+ Path::line(Point::ORIGIN, Point::new(0.0, -0.8 * radius));
- let x = length * t.cos();
- let y = length * t.sin();
+ let thin_stroke = canvas::Stroke {
+ width: radius / 100.0,
+ color: Color::WHITE,
+ line_cap: canvas::LineCap::Round,
+ ..canvas::Stroke::default()
+ };
- path.line_to(Point::new(x, y) + offset);
- }
+ let wide_stroke = canvas::Stroke {
+ width: thin_stroke.width * 3.0,
+ ..thin_stroke
+ };
- let hour_and_minute_hands = canvas::Path::new(|path| {
- path.move_to(center);
- draw_hand(self.hour, 12, 0.5 * radius, offset, path);
+ frame.translate(Vector::new(center.x, center.y));
- path.move_to(center);
- draw_hand(self.minute, 60, 0.8 * radius, offset, path)
+ frame.with_save(|frame| {
+ frame.rotate(hand_rotation(self.hour, 12));
+ frame.stroke(&short_hand, wide_stroke);
});
- frame.stroke(
- &hour_and_minute_hands,
- canvas::Stroke {
- width: radius / 100.0 * 3.0,
- color: Color::WHITE,
- line_cap: canvas::LineCap::Round,
- ..canvas::Stroke::default()
- },
- );
-
- let second_hand = canvas::Path::new(|path| {
- path.move_to(center);
- draw_hand(self.second, 60, 0.8 * radius, offset, path)
+ frame.with_save(|frame| {
+ frame.rotate(hand_rotation(self.minute, 60));
+ frame.stroke(&long_hand, wide_stroke);
});
- frame.stroke(
- &second_hand,
- canvas::Stroke {
- width: radius / 100.0,
- color: Color::WHITE,
- line_cap: canvas::LineCap::Round,
- ..canvas::Stroke::default()
- },
- );
+ frame.with_save(|frame| {
+ frame.rotate(hand_rotation(self.second, 60));
+ frame.stroke(&long_hand, thin_stroke);
+ });
}
}
+fn hand_rotation(n: u32, total: u32) -> f32 {
+ let turns = n as f32 / total as f32;
+
+ 2.0 * std::f32::consts::PI * turns
+}
+
mod time {
use iced::futures;
diff --git a/examples/solar_system/src/main.rs b/examples/solar_system/src/main.rs
index 963f047b..bcd1dc71 100644
--- a/examples/solar_system/src/main.rs
+++ b/examples/solar_system/src/main.rs
@@ -128,14 +128,12 @@ impl State {
impl canvas::Drawable for State {
fn draw(&self, frame: &mut canvas::Frame) {
- use canvas::{Fill, Path, Stroke};
+ use canvas::{Path, Stroke};
use std::f32::consts::PI;
let center = frame.center();
- let space = Path::new(|path| {
- path.rectangle(Point::new(0.0, 0.0), frame.size())
- });
+ let space = Path::rectangle(Point::new(0.0, 0.0), frame.size());
let stars = Path::new(|path| {
for (p, size) in &self.stars {
@@ -143,12 +141,12 @@ impl canvas::Drawable for State {
}
});
- let sun = Path::new(|path| path.circle(center, Self::SUN_RADIUS));
- let orbit = Path::new(|path| path.circle(center, Self::ORBIT_RADIUS));
+ let sun = Path::circle(center, Self::SUN_RADIUS);
+ let orbit = Path::circle(center, Self::ORBIT_RADIUS);
- frame.fill(&space, Fill::Color(Color::BLACK));
- frame.fill(&stars, Fill::Color(Color::WHITE));
- frame.fill(&sun, Fill::Color(Color::from_rgb8(0xF9, 0xD7, 0x1C)));
+ frame.fill(&space, Color::BLACK);
+ frame.fill(&stars, Color::WHITE);
+ frame.fill(&sun, Color::from_rgb8(0xF9, 0xD7, 0x1C));
frame.stroke(
&orbit,
Stroke {
@@ -170,21 +168,13 @@ impl canvas::Drawable for State {
);
frame.translate(Vector::new(Self::ORBIT_RADIUS, 0.0));
- let earth = Path::new(|path| {
- path.circle(Point::ORIGIN, Self::EARTH_RADIUS)
- });
-
- let shadow = Path::new(|path| {
- path.rectangle(
- Point::new(0.0, -Self::EARTH_RADIUS),
- Size::new(
- Self::EARTH_RADIUS * 4.0,
- Self::EARTH_RADIUS * 2.0,
- ),
- )
- });
+ let earth = Path::circle(Point::ORIGIN, Self::EARTH_RADIUS);
+ let shadow = Path::rectangle(
+ Point::new(0.0, -Self::EARTH_RADIUS),
+ Size::new(Self::EARTH_RADIUS * 4.0, Self::EARTH_RADIUS * 2.0),
+ );
- frame.fill(&earth, Fill::Color(Color::from_rgb8(0x6B, 0x93, 0xD6)));
+ frame.fill(&earth, Color::from_rgb8(0x6B, 0x93, 0xD6));
frame.with_save(|frame| {
frame.rotate(
@@ -193,19 +183,16 @@ impl canvas::Drawable for State {
);
frame.translate(Vector::new(0.0, Self::MOON_DISTANCE));
- let moon = Path::new(|path| {
- path.circle(Point::ORIGIN, Self::MOON_RADIUS)
- });
-
- frame.fill(&moon, Fill::Color(Color::WHITE));
+ let moon = Path::circle(Point::ORIGIN, Self::MOON_RADIUS);
+ frame.fill(&moon, Color::WHITE);
});
frame.fill(
&shadow,
- Fill::Color(Color {
+ Color {
a: 0.7,
..Color::BLACK
- }),
+ },
);
});
}
diff --git a/wgpu/src/widget/canvas/fill.rs b/wgpu/src/widget/canvas/fill.rs
index 5ce24cf3..a2010e45 100644
--- a/wgpu/src/widget/canvas/fill.rs
+++ b/wgpu/src/widget/canvas/fill.rs
@@ -12,3 +12,9 @@ impl Default for Fill {
Fill::Color(Color::BLACK)
}
}
+
+impl From<Color> for Fill {
+ fn from(color: Color) -> Fill {
+ Fill::Color(color)
+ }
+}
diff --git a/wgpu/src/widget/canvas/frame.rs b/wgpu/src/widget/canvas/frame.rs
index 940be402..de4717f1 100644
--- a/wgpu/src/widget/canvas/frame.rs
+++ b/wgpu/src/widget/canvas/frame.rs
@@ -89,14 +89,14 @@ impl Frame {
///
/// [`Path`]: path/struct.Path.html
/// [`Frame`]: struct.Frame.html
- pub fn fill(&mut self, path: &Path, fill: Fill) {
+ pub fn fill(&mut self, path: &Path, fill: impl Into<Fill>) {
use lyon::tessellation::{
BuffersBuilder, FillOptions, FillTessellator,
};
let mut buffers = BuffersBuilder::new(
&mut self.buffers,
- FillVertex(match fill {
+ FillVertex(match fill.into() {
Fill::Color(color) => color.into_linear(),
}),
);
@@ -127,11 +127,13 @@ impl Frame {
///
/// [`Path`]: path/struct.Path.html
/// [`Frame`]: struct.Frame.html
- pub fn stroke(&mut self, path: &Path, stroke: Stroke) {
+ pub fn stroke(&mut self, path: &Path, stroke: impl Into<Stroke>) {
use lyon::tessellation::{
BuffersBuilder, StrokeOptions, StrokeTessellator,
};
+ let stroke = stroke.into();
+
let mut buffers = BuffersBuilder::new(
&mut self.buffers,
StrokeVertex(stroke.color.into_linear()),
@@ -173,9 +175,11 @@ impl Frame {
/// [`Text`]: struct.Text.html
/// [`Frame`]: struct.Frame.html
/// [`Canvas`]: struct.Canvas.html
- pub fn fill_text(&mut self, text: Text) {
+ pub fn fill_text(&mut self, text: impl Into<Text>) {
use std::f32;
+ let text = text.into();
+
let position = if self.transforms.current.is_identity {
text.position
} else {
diff --git a/wgpu/src/widget/canvas/path.rs b/wgpu/src/widget/canvas/path.rs
index e7ff47f3..c26bf187 100644
--- a/wgpu/src/widget/canvas/path.rs
+++ b/wgpu/src/widget/canvas/path.rs
@@ -7,6 +7,8 @@ mod builder;
pub use arc::Arc;
pub use builder::Builder;
+use iced_native::{Point, Size};
+
/// An immutable set of points that may or may not be connected.
///
/// A single [`Path`] can represent different kinds of 2D shapes!
@@ -33,6 +35,33 @@ impl Path {
builder.build()
}
+ /// Creates a new [`Path`] representing a line segment given its starting
+ /// and end points.
+ ///
+ /// [`Path`]: struct.Path.html
+ pub fn line(from: Point, to: Point) -> Self {
+ Self::new(|p| {
+ p.move_to(from);
+ p.line_to(to);
+ })
+ }
+
+ /// Creates a new [`Path`] representing a rectangle given its top-left
+ /// corner coordinate and its `Size`.
+ ///
+ /// [`Path`]: struct.Path.html
+ pub fn rectangle(top_left: Point, size: Size) -> Self {
+ Self::new(|p| p.rectangle(top_left, size))
+ }
+
+ /// Creates a new [`Path`] representing a circle given its center
+ /// coordinate and its radius.
+ ///
+ /// [`Path`]: struct.Path.html
+ pub fn circle(center: Point, radius: f32) -> Self {
+ Self::new(|p| p.circle(center, radius))
+ }
+
#[inline]
pub(crate) fn raw(&self) -> &lyon::path::Path {
&self.raw
diff --git a/wgpu/src/widget/canvas/path/builder.rs b/wgpu/src/widget/canvas/path/builder.rs
index a013149e..6511fa52 100644
--- a/wgpu/src/widget/canvas/path/builder.rs
+++ b/wgpu/src/widget/canvas/path/builder.rs
@@ -133,11 +133,14 @@ impl Builder {
///
/// [`Path`]: struct.Path.html
#[inline]
- pub fn rectangle(&mut self, p: Point, size: Size) {
- self.move_to(p);
- self.line_to(Point::new(p.x + size.width, p.y));
- self.line_to(Point::new(p.x + size.width, p.y + size.height));
- self.line_to(Point::new(p.x, p.y + size.height));
+ pub fn rectangle(&mut self, top_left: Point, size: Size) {
+ self.move_to(top_left);
+ self.line_to(Point::new(top_left.x + size.width, top_left.y));
+ self.line_to(Point::new(
+ top_left.x + size.width,
+ top_left.y + size.height,
+ ));
+ self.line_to(Point::new(top_left.x, top_left.y + size.height));
self.close();
}
diff --git a/wgpu/src/widget/canvas/text.rs b/wgpu/src/widget/canvas/text.rs
index d1cf1a0f..c4cae30e 100644
--- a/wgpu/src/widget/canvas/text.rs
+++ b/wgpu/src/widget/canvas/text.rs
@@ -32,3 +32,18 @@ impl Default for Text {
}
}
}
+
+impl From<String> for Text {
+ fn from(content: String) -> Text {
+ Text {
+ content,
+ ..Default::default()
+ }
+ }
+}
+
+impl From<&str> for Text {
+ fn from(content: &str) -> Text {
+ String::from(content).into()
+ }
+}