Skip to content

Commit

Permalink
Merge pull request #325 from hecrj/feature/canvas-interaction
Browse files Browse the repository at this point in the history
Canvas interactivity and Game of Life example
  • Loading branch information
hecrj authored May 4, 2020
2 parents 27aad74 + 93c6be5 commit 7dc02a5
Show file tree
Hide file tree
Showing 89 changed files with 2,509 additions and 1,326 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ members = [
"examples/custom_widget",
"examples/download_progress",
"examples/events",
"examples/game_of_life",
"examples/geometry",
"examples/integration",
"examples/pane_grid",
Expand Down
2 changes: 2 additions & 0 deletions core/src/keyboard.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Reuse basic keyboard types.
mod event;
mod key_code;
mod modifiers_state;

pub use event::Event;
pub use key_code::KeyCode;
pub use modifiers_state::ModifiersState;
15 changes: 10 additions & 5 deletions native/src/input/keyboard/event.rs → core/src/keyboard/event.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::{KeyCode, ModifiersState};
use crate::input::ButtonState;

/// A keyboard event.
///
Expand All @@ -9,11 +8,17 @@ use crate::input::ButtonState;
/// [open an issue]: https://github.com/hecrj/iced/issues
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Event {
/// A keyboard key was pressed or released.
Input {
/// The state of the key
state: ButtonState,
/// A keyboard key was pressed.
KeyPressed {
/// The key identifier
key_code: KeyCode,

/// The state of the modifier keys
modifiers: ModifiersState,
},

/// A keyboard key was released.
KeyReleased {
/// The key identifier
key_code: KeyCode,

Expand Down
1 change: 1 addition & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#![forbid(unsafe_code)]
#![forbid(rust_2018_idioms)]
pub mod keyboard;
pub mod mouse;

mod align;
mod background;
Expand Down
7 changes: 3 additions & 4 deletions native/src/input/mouse.rs → core/src/mouse.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
//! Build mouse events.
//! Reuse basic mouse types.
mod button;
mod event;

pub mod click;
mod interaction;

pub use button::Button;
pub use click::Click;
pub use event::{Event, ScrollDelta};
pub use interaction::Interaction;
File renamed without changes.
12 changes: 4 additions & 8 deletions native/src/input/mouse/event.rs → core/src/mouse/event.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::Button;
use crate::input::ButtonState;

/// A mouse event.
///
Expand All @@ -24,14 +23,11 @@ pub enum Event {
y: f32,
},

/// A mouse button was pressed or released.
Input {
/// The state of the button
state: ButtonState,
/// A mouse button was pressed.
ButtonPressed(Button),

/// The button identifier
button: Button,
},
/// A mouse button was released.
ButtonReleased(Button),

/// The mouse wheel was scrolled.
WheelScrolled {
Expand Down
20 changes: 20 additions & 0 deletions core/src/mouse/interaction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/// The interaction of a mouse cursor.
#[derive(Debug, Eq, PartialEq, Clone, Copy, PartialOrd, Ord)]
#[allow(missing_docs)]
pub enum Interaction {
Idle,
Pointer,
Grab,
Text,
Crosshair,
Working,
Grabbing,
ResizingHorizontally,
ResizingVertically,
}

impl Default for Interaction {
fn default() -> Interaction {
Interaction::Idle
}
}
10 changes: 9 additions & 1 deletion core/src/point.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::Vector;

/// A 2D point.
#[derive(Debug, Clone, Copy, PartialEq)]
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct Point {
/// The X coordinate.
pub x: f32,
Expand Down Expand Up @@ -67,3 +67,11 @@ impl std::ops::Sub<Vector> for Point {
}
}
}

impl std::ops::Sub<Point> for Point {
type Output = Vector;

fn sub(self, point: Point) -> Vector {
Vector::new(self.x - point.x, self.y - point.y)
}
}
65 changes: 62 additions & 3 deletions core/src/rectangle.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::Point;
use crate::{Point, Size, Vector};

/// A rectangle.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
Expand All @@ -17,6 +17,35 @@ pub struct Rectangle<T = f32> {
}

impl Rectangle<f32> {
/// Creates a new [`Rectangle`] with its top-left corner in the given
/// [`Point`] and with the provided [`Size`].
///
/// [`Rectangle`]: struct.Rectangle.html
/// [`Point`]: struct.Point.html
/// [`Size`]: struct.Size.html
pub fn new(top_left: Point, size: Size) -> Self {
Self {
x: top_left.x,
y: top_left.y,
width: size.width,
height: size.height,
}
}

/// Creates a new [`Rectangle`] with its top-left corner at the origin
/// and with the provided [`Size`].
///
/// [`Rectangle`]: struct.Rectangle.html
/// [`Size`]: struct.Size.html
pub fn with_size(size: Size) -> Self {
Self {
x: 0.0,
y: 0.0,
width: size.width,
height: size.height,
}
}

/// Returns the [`Point`] at the center of the [`Rectangle`].
///
/// [`Point`]: struct.Point.html
Expand All @@ -43,6 +72,21 @@ impl Rectangle<f32> {
self.y + self.height / 2.0
}

/// Returns the position of the top left corner of the [`Rectangle`].
///
/// [`Rectangle`]: struct.Rectangle.html
pub fn position(&self) -> Point {
Point::new(self.x, self.y)
}

/// Returns the [`Size`] of the [`Rectangle`].
///
/// [`Size`]: struct.Size.html
/// [`Rectangle`]: struct.Rectangle.html
pub fn size(&self) -> Size {
Size::new(self.width, self.height)
}

/// Returns true if the given [`Point`] is contained in the [`Rectangle`].
///
/// [`Point`]: struct.Point.html
Expand Down Expand Up @@ -112,8 +156,23 @@ impl From<Rectangle<f32>> for Rectangle<u32> {
Rectangle {
x: rectangle.x as u32,
y: rectangle.y as u32,
width: rectangle.width.ceil() as u32,
height: rectangle.height.ceil() as u32,
width: (rectangle.width + 0.5).round() as u32,
height: (rectangle.height + 0.5).round() as u32,
}
}
}

impl<T> std::ops::Add<Vector<T>> for Rectangle<T>
where
T: std::ops::Add<Output = T>,
{
type Output = Rectangle<T>;

fn add(self, translation: Vector<T>) -> Self {
Rectangle {
x: self.x + translation.x,
y: self.y + translation.y,
..self
}
}
}
5 changes: 5 additions & 0 deletions core/src/size.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ impl Size {
/// [`Size`]: struct.Size.html
pub const ZERO: Size = Size::new(0., 0.);

/// A [`Size`] with a width and height of 1 unit.
///
/// [`Size`]: struct.Size.html
pub const UNIT: Size = Size::new(1., 1.);

/// A [`Size`] with infinite width and height.
///
/// [`Size`]: struct.Size.html
Expand Down
11 changes: 11 additions & 0 deletions core/src/vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ where
}
}

impl<T> std::ops::Mul<T> for Vector<T>
where
T: std::ops::Mul<Output = T> + Copy,
{
type Output = Self;

fn mul(self, scale: T) -> Self {
Self::new(self.x * scale, self.y * scale)
}
}

impl<T> Default for Vector<T>
where
T: Default,
Expand Down
23 changes: 22 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,27 @@ We have not yet implemented a `LocalStorage` version of the auto-save feature. T

[TodoMVC]: http://todomvc.com/

## [Game of Life](game_of_life)
An interactive version of the [Game of Life], invented by [John Horton Conway].

It runs a simulation in a background thread while allowing interaction with a `Canvas` that displays an infinite grid with zooming, panning, and drawing support.

The relevant code is located in the __[`main`](game_of_life/src/main.rs)__ file.

<div align="center">
<a href="https://gfycat.com/briefaccurateaardvark">
<img src="https://thumbs.gfycat.com/BriefAccurateAardvark-size_restricted.gif">
</a>
</div>

You can run it with `cargo run`:
```
cargo run --package game_of_life
```

[Game of Life]: https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
[John Horton Conway]: https://en.wikipedia.org/wiki/John_Horton_Conway

## [Styling](styling)
An example showcasing custom styling with a light and dark theme.

Expand All @@ -69,7 +90,7 @@ cargo run --package styling
## Extras
A bunch of simpler examples exist:

- [`bezier_tool`](bezier_tool), a Paint-like tool for drawing Bézier curves using [`lyon`].
- [`bezier_tool`](bezier_tool), a Paint-like tool for drawing Bézier curves using the `Canvas` widget.
- [`clock`](clock), an application that uses the `Canvas` widget to draw a clock and its hands to display the current time.
- [`color_palette`](color_palette), a color palette generator based on a user-defined root color.
- [`counter`](counter), the classic counter example explained in the [`README`](../README.md).
Expand Down
5 changes: 1 addition & 4 deletions examples/bezier_tool/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,4 @@ edition = "2018"
publish = false

[dependencies]
iced = { path = "../.." }
iced_native = { path = "../../native" }
iced_wgpu = { path = "../../wgpu" }
lyon = "0.15"
iced = { path = "../..", features = ["canvas"] }
3 changes: 1 addition & 2 deletions examples/bezier_tool/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Bézier tool

A Paint-like tool for drawing Bézier curves using [`lyon`].
A Paint-like tool for drawing Bézier curves using the `Canvas` widget.

The __[`main`]__ file contains all the code of the example.

Expand All @@ -16,4 +16,3 @@ cargo run --package bezier_tool
```

[`main`]: src/main.rs
[`lyon`]: https://github.com/nical/lyon
Loading

0 comments on commit 7dc02a5

Please sign in to comment.