diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/Cargo.toml | 3 | ||||
-rw-r--r-- | core/README.md | 6 | ||||
-rw-r--r-- | core/src/color.rs | 25 | ||||
-rw-r--r-- | core/src/keyboard.rs | 6 | ||||
-rw-r--r-- | core/src/keyboard/event.rs | 8 | ||||
-rw-r--r-- | core/src/keyboard/hotkey.rs | 18 | ||||
-rw-r--r-- | core/src/keyboard/key_code.rs | 37 | ||||
-rw-r--r-- | core/src/keyboard/modifiers.rs | 79 | ||||
-rw-r--r-- | core/src/keyboard/modifiers_state.rs | 30 | ||||
-rw-r--r-- | core/src/length.rs | 2 | ||||
-rw-r--r-- | core/src/lib.rs | 8 | ||||
-rw-r--r-- | core/src/menu.rs | 145 | ||||
-rw-r--r-- | core/src/mouse/event.rs | 9 | ||||
-rw-r--r-- | core/src/padding.rs | 107 | ||||
-rw-r--r-- | core/src/point.rs | 12 | ||||
-rw-r--r-- | core/src/rectangle.rs | 32 | ||||
-rw-r--r-- | core/src/size.rs | 38 | ||||
-rw-r--r-- | core/src/vector.rs | 21 |
18 files changed, 442 insertions, 144 deletions
diff --git a/core/Cargo.toml b/core/Cargo.toml index b52bf315..54d927af 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_core" -version = "0.2.1" +version = "0.4.0" authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"] edition = "2018" description = "The essential concepts of Iced" @@ -8,6 +8,7 @@ license = "MIT" repository = "https://github.com/hecrj/iced" [dependencies] +bitflags = "1.2" [dependencies.palette] version = "0.5.0" diff --git a/core/README.md b/core/README.md index 641612c0..86d631d2 100644 --- a/core/README.md +++ b/core/README.md @@ -8,7 +8,9 @@ This crate is meant to be a starting point for an Iced runtime. - +<p align="center"> + <img alt="The foundations" src="../docs/graphs/foundations.png" width="50%"> +</p> [documentation]: https://docs.rs/iced_core @@ -16,7 +18,7 @@ This crate is meant to be a starting point for an Iced runtime. Add `iced_core` as a dependency in your `Cargo.toml`: ```toml -iced_core = "0.2" +iced_core = "0.4" ``` __Iced moves fast and the `master` branch can contain breaking changes!__ If diff --git a/core/src/color.rs b/core/src/color.rs index a4c3d87c..c66ee97c 100644 --- a/core/src/color.rs +++ b/core/src/color.rs @@ -43,8 +43,6 @@ impl Color { /// /// In debug mode, it will panic if the values are not in the correct /// range: 0.0 - 1.0 - /// - /// [`Color`]: struct.Color.html pub fn new(r: f32, g: f32, b: f32, a: f32) -> Color { debug_assert!( (0.0..=1.0).contains(&r), @@ -67,29 +65,21 @@ impl Color { } /// Creates a [`Color`] from its RGB components. - /// - /// [`Color`]: struct.Color.html pub const fn from_rgb(r: f32, g: f32, b: f32) -> Color { Color::from_rgba(r, g, b, 1.0f32) } /// Creates a [`Color`] from its RGBA components. - /// - /// [`Color`]: struct.Color.html pub const fn from_rgba(r: f32, g: f32, b: f32, a: f32) -> Color { Color { r, g, b, a } } /// Creates a [`Color`] from its RGB8 components. - /// - /// [`Color`]: struct.Color.html pub fn from_rgb8(r: u8, g: u8, b: u8) -> Color { Color::from_rgba8(r, g, b, 1.0) } /// Creates a [`Color`] from its RGB8 components and an alpha value. - /// - /// [`Color`]: struct.Color.html pub fn from_rgba8(r: u8, g: u8, b: u8, a: f32) -> Color { Color { r: f32::from(r) / 255.0, @@ -100,8 +90,6 @@ impl Color { } /// Converts the [`Color`] into its linear values. - /// - /// [`Color`]: struct.Color.html pub fn into_linear(self) -> [f32; 4] { // As described in: // https://en.wikipedia.org/wiki/SRGB#The_reverse_transformation @@ -122,8 +110,6 @@ impl Color { } /// Inverts the [`Color`] in-place. - /// - /// [`Color`]: struct.Color.html pub fn invert(&mut self) { self.r = 1.0f32 - self.r; self.b = 1.0f32 - self.g; @@ -131,8 +117,6 @@ impl Color { } /// Returns the inverted [`Color`]. - /// - /// [`Color`]: struct.Color.html pub fn inverse(self) -> Color { Color::new(1.0f32 - self.r, 1.0f32 - self.g, 1.0f32 - self.b, self.a) } @@ -152,8 +136,6 @@ impl From<[f32; 4]> for Color { #[cfg(feature = "palette")] /// Converts from palette's `Srgba` type to a [`Color`]. -/// -/// [`Color`]: struct.Color.html impl From<Srgba> for Color { fn from(srgba: Srgba) -> Self { Color::new(srgba.red, srgba.green, srgba.blue, srgba.alpha) @@ -162,8 +144,6 @@ impl From<Srgba> for Color { #[cfg(feature = "palette")] /// Converts from [`Color`] to palette's `Srgba` type. -/// -/// [`Color`]: struct.Color.html impl From<Color> for Srgba { fn from(c: Color) -> Self { Srgba::new(c.r, c.g, c.b, c.a) @@ -172,8 +152,6 @@ impl From<Color> for Srgba { #[cfg(feature = "palette")] /// Converts from palette's `Srgb` type to a [`Color`]. -/// -/// [`Color`]: struct.Color.html impl From<Srgb> for Color { fn from(srgb: Srgb) -> Self { Color::new(srgb.red, srgb.green, srgb.blue, 1.0) @@ -182,9 +160,6 @@ impl From<Srgb> for Color { #[cfg(feature = "palette")] /// Converts from [`Color`] to palette's `Srgb` type. -/// -/// [`Color`]: struct.Color.html -/// [`Srgb`]: ../palette/rgb/type.Srgb.html impl From<Color> for Srgb { fn from(c: Color) -> Self { Srgb::new(c.r, c.g, c.b) diff --git a/core/src/keyboard.rs b/core/src/keyboard.rs index b26bdb3d..cb64701a 100644 --- a/core/src/keyboard.rs +++ b/core/src/keyboard.rs @@ -1,8 +1,10 @@ //! Reuse basic keyboard types. mod event; +mod hotkey; mod key_code; -mod modifiers_state; +mod modifiers; pub use event::Event; +pub use hotkey::Hotkey; pub use key_code::KeyCode; -pub use modifiers_state::ModifiersState; +pub use modifiers::Modifiers; diff --git a/core/src/keyboard/event.rs b/core/src/keyboard/event.rs index d142c3bc..0564c171 100644 --- a/core/src/keyboard/event.rs +++ b/core/src/keyboard/event.rs @@ -1,4 +1,4 @@ -use super::{KeyCode, ModifiersState}; +use super::{KeyCode, Modifiers}; /// A keyboard event. /// @@ -14,7 +14,7 @@ pub enum Event { key_code: KeyCode, /// The state of the modifier keys - modifiers: ModifiersState, + modifiers: Modifiers, }, /// A keyboard key was released. @@ -23,12 +23,12 @@ pub enum Event { key_code: KeyCode, /// The state of the modifier keys - modifiers: ModifiersState, + modifiers: Modifiers, }, /// A unicode character was received. CharacterReceived(char), /// The keyboard modifiers have changed. - ModifiersChanged(ModifiersState), + ModifiersChanged(Modifiers), } diff --git a/core/src/keyboard/hotkey.rs b/core/src/keyboard/hotkey.rs new file mode 100644 index 00000000..310ef286 --- /dev/null +++ b/core/src/keyboard/hotkey.rs @@ -0,0 +1,18 @@ +use crate::keyboard::{KeyCode, Modifiers}; + +/// Representation of a hotkey, consists on the combination of a [`KeyCode`] and [`Modifiers`]. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct Hotkey { + /// The key that represents this hotkey. + pub key: KeyCode, + + /// The list of modifiers that represents this hotkey. + pub modifiers: Modifiers, +} + +impl Hotkey { + /// Creates a new [`Hotkey`] with the given [`Modifiers`] and [`KeyCode`]. + pub fn new(modifiers: Modifiers, key: KeyCode) -> Self { + Self { modifiers, key } + } +} diff --git a/core/src/keyboard/key_code.rs b/core/src/keyboard/key_code.rs index 26020a57..74ead170 100644 --- a/core/src/keyboard/key_code.rs +++ b/core/src/keyboard/key_code.rs @@ -55,7 +55,7 @@ pub enum KeyCode { Y, Z, - /// The Escape key, next to F1 + /// The Escape key, next to F1. Escape, F1, @@ -83,14 +83,14 @@ pub enum KeyCode { F23, F24, - /// Print Screen/SysRq + /// Print Screen/SysRq. Snapshot, - /// Scroll Lock + /// Scroll Lock. Scroll, - /// Pause/Break key, next to Scroll lock + /// Pause/Break key, next to Scroll lock. Pause, - /// `Insert`, next to Backspace + /// `Insert`, next to Backspace. Insert, Home, Delete, @@ -103,11 +103,14 @@ pub enum KeyCode { Right, Down, + /// The Backspace key, right over Enter. Backspace, + /// The Enter key. Enter, + /// The space bar. Space, - /// The "Compose" key on Linux + /// The "Compose" key on Linux. Compose, Caret, @@ -123,12 +126,20 @@ pub enum KeyCode { Numpad7, Numpad8, Numpad9, + NumpadAdd, + NumpadDivide, + NumpadDecimal, + NumpadComma, + NumpadEnter, + NumpadEquals, + NumpadMultiply, + NumpadSubtract, AbntC1, AbntC2, - Add, Apostrophe, Apps, + Asterisk, At, Ax, Backslash, @@ -137,8 +148,6 @@ pub enum KeyCode { Colon, Comma, Convert, - Decimal, - Divide, Equals, Grave, Kana, @@ -152,19 +161,16 @@ pub enum KeyCode { MediaSelect, MediaStop, Minus, - Multiply, Mute, MyComputer, - NavigateForward, // also called "Prior" - NavigateBackward, // also called "Next" + NavigateForward, // also called "Next" + NavigateBackward, // also called "Prior" NextTrack, NoConvert, - NumpadComma, - NumpadEnter, - NumpadEquals, OEM102, Period, PlayPause, + Plus, Power, PrevTrack, RAlt, @@ -176,7 +182,6 @@ pub enum KeyCode { Slash, Sleep, Stop, - Subtract, Sysrq, Tab, Underline, diff --git a/core/src/keyboard/modifiers.rs b/core/src/keyboard/modifiers.rs new file mode 100644 index 00000000..e61f145a --- /dev/null +++ b/core/src/keyboard/modifiers.rs @@ -0,0 +1,79 @@ +use bitflags::bitflags; + +bitflags! { + /// The current state of the keyboard modifiers. + #[derive(Default)] + pub struct Modifiers: u32{ + /// The "shift" key. + const SHIFT = 0b100 << 0; + // const LSHIFT = 0b010 << 0; + // const RSHIFT = 0b001 << 0; + // + /// The "control" key. + const CTRL = 0b100 << 3; + // const LCTRL = 0b010 << 3; + // const RCTRL = 0b001 << 3; + // + /// The "alt" key. + const ALT = 0b100 << 6; + // const LALT = 0b010 << 6; + // const RALT = 0b001 << 6; + // + /// The "windows" key on Windows, "command" key on Mac, and + /// "super" key on Linux. + const LOGO = 0b100 << 9; + // const LLOGO = 0b010 << 9; + // const RLOGO = 0b001 << 9; + } +} + +impl Modifiers { + /// The "command" key. + /// + /// This is normally the main modifier to be used for hotkeys. + /// + /// On macOS, this is equivalent to `Self::LOGO`. + /// Ohterwise, this is equivalent to `Self::CTRL`. + pub const COMMAND: Self = if cfg!(target_os = "macos") { + Self::LOGO + } else { + Self::CTRL + }; + + /// Returns true if the [`SHIFT`] key is pressed in the [`Modifiers`]. + pub fn shift(self) -> bool { + self.contains(Self::SHIFT) + } + + /// Returns true if the [`CTRL`] key is pressed in the [`Modifiers`]. + pub fn control(self) -> bool { + self.contains(Self::CTRL) + } + + /// Returns true if the [`ALT`] key is pressed in the [`Modifiers`]. + pub fn alt(self) -> bool { + self.contains(Self::ALT) + } + + /// Returns true if the [`LOGO`] key is pressed in the [`Modifiers`]. + pub fn logo(self) -> bool { + self.contains(Self::LOGO) + } + + /// Returns true if a "command key" is pressed in the [`Modifiers`]. + /// + /// The "command key" is the main modifier key used to issue commands in the + /// current platform. Specifically: + /// + /// - It is the `logo` or command key (⌘) on macOS + /// - It is the `control` key on other platforms + pub fn command(self) -> bool { + #[cfg(target_os = "macos")] + let is_pressed = self.logo(); + + #[cfg(not(target_os = "macos"))] + let is_pressed = self.control(); + + is_pressed + } +} diff --git a/core/src/keyboard/modifiers_state.rs b/core/src/keyboard/modifiers_state.rs deleted file mode 100644 index 4d24266f..00000000 --- a/core/src/keyboard/modifiers_state.rs +++ /dev/null @@ -1,30 +0,0 @@ -/// The current state of the keyboard modifiers. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] -pub struct ModifiersState { - /// Whether a shift key is pressed - pub shift: bool, - - /// Whether a control key is pressed - pub control: bool, - - /// Whether an alt key is pressed - pub alt: bool, - - /// Whether a logo key is pressed (e.g. windows key, command key...) - pub logo: bool, -} - -impl ModifiersState { - /// Returns true if the current [`ModifiersState`] has at least the same - /// modifiers enabled as the given value, and false otherwise. - /// - /// [`ModifiersState`]: struct.ModifiersState.html - pub fn matches(&self, modifiers: ModifiersState) -> bool { - let shift = !modifiers.shift || self.shift; - let control = !modifiers.control || self.control; - let alt = !modifiers.alt || self.alt; - let logo = !modifiers.logo || self.logo; - - shift && control && alt && logo - } -} diff --git a/core/src/length.rs b/core/src/length.rs index 06d8cf0a..186411a5 100644 --- a/core/src/length.rs +++ b/core/src/length.rs @@ -26,8 +26,6 @@ impl Length { /// The _fill factor_ is a relative unit describing how much of the /// remaining space should be filled when compared to other elements. It /// is only meant to be used by layout engines. - /// - /// [`Length`]: enum.Length.html pub fn fill_factor(&self) -> u16 { match self { Length::Fill => 1, diff --git a/core/src/lib.rs b/core/src/lib.rs index 6b9e612e..c4288158 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -1,11 +1,11 @@ //! The core library of [Iced]. //! -//!  -//! //! This library holds basic types that can be reused and re-exported in //! different runtime implementations. For instance, both [`iced_native`] and //! [`iced_web`] are built on top of `iced_core`. //! +//!  +//! //! [Iced]: https://github.com/hecrj/iced //! [`iced_native`]: https://github.com/hecrj/iced/tree/master/native //! [`iced_web`]: https://github.com/hecrj/iced/tree/master/web @@ -15,6 +15,7 @@ #![forbid(unsafe_code)] #![forbid(rust_2018_idioms)] pub mod keyboard; +pub mod menu; pub mod mouse; mod align; @@ -22,6 +23,7 @@ mod background; mod color; mod font; mod length; +mod padding; mod point; mod rectangle; mod size; @@ -32,6 +34,8 @@ pub use background::Background; pub use color::Color; pub use font::Font; pub use length::Length; +pub use menu::Menu; +pub use padding::Padding; pub use point::Point; pub use rectangle::Rectangle; pub use size::Size; diff --git a/core/src/menu.rs b/core/src/menu.rs new file mode 100644 index 00000000..8a679085 --- /dev/null +++ b/core/src/menu.rs @@ -0,0 +1,145 @@ +//! Build menus for your application. +use crate::keyboard::Hotkey; + +/// Menu representation. +/// +/// This can be used by `shell` implementations to create a menu. +#[derive(Debug, Clone)] +pub struct Menu<Message> { + entries: Vec<Entry<Message>>, +} + +impl<Message> PartialEq for Menu<Message> { + fn eq(&self, other: &Self) -> bool { + self.entries == other.entries + } +} + +impl<Message> Menu<Message> { + /// Creates an empty [`Menu`]. + pub fn new() -> Self { + Self::with_entries(Vec::new()) + } + + /// Creates a new [`Menu`] with the given entries. + pub fn with_entries(entries: Vec<Entry<Message>>) -> Self { + Self { entries } + } + + /// Returns a [`MenuEntry`] iterator. + pub fn iter(&self) -> impl Iterator<Item = &Entry<Message>> { + self.entries.iter() + } + + /// Adds an [`Entry`] to the [`Menu`]. + pub fn push(mut self, entry: Entry<Message>) -> Self { + self.entries.push(entry); + self + } + + /// Maps the `Message` of the [`Menu`] using the provided function. + /// + /// This is useful to compose menus and split them into different + /// abstraction levels. + pub fn map<B>(self, f: impl Fn(Message) -> B + Copy) -> Menu<B> { + // TODO: Use a boxed trait to avoid reallocation of entries + Menu { + entries: self + .entries + .into_iter() + .map(|entry| entry.map(f)) + .collect(), + } + } +} + +/// Represents one of the possible entries used to build a [`Menu`]. +#[derive(Debug, Clone)] +pub enum Entry<Message> { + /// Item for a [`Menu`] + Item { + /// The title of the item + title: String, + /// The [`Hotkey`] to activate the item, if any + hotkey: Option<Hotkey>, + /// The message generated when the item is activated + on_activation: Message, + }, + /// Dropdown for a [`Menu`] + Dropdown { + /// Title of the dropdown + title: String, + /// The submenu of the dropdown + submenu: Menu<Message>, + }, + /// Separator for a [`Menu`] + Separator, +} + +impl<Message> Entry<Message> { + /// Creates an [`Entry::Item`]. + pub fn item<S: Into<String>>( + title: S, + hotkey: impl Into<Option<Hotkey>>, + on_activation: Message, + ) -> Self { + let title = title.into(); + let hotkey = hotkey.into(); + + Self::Item { + title, + hotkey, + on_activation, + } + } + + /// Creates an [`Entry::Dropdown`]. + pub fn dropdown<S: Into<String>>(title: S, submenu: Menu<Message>) -> Self { + let title = title.into(); + + Self::Dropdown { title, submenu } + } + + fn map<B>(self, f: impl Fn(Message) -> B + Copy) -> Entry<B> { + match self { + Self::Item { + title, + hotkey, + on_activation, + } => Entry::Item { + title, + hotkey, + on_activation: f(on_activation), + }, + Self::Dropdown { title, submenu } => Entry::Dropdown { + title, + submenu: submenu.map(f), + }, + Self::Separator => Entry::Separator, + } + } +} + +impl<Message> PartialEq for Entry<Message> { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + ( + Entry::Item { title, hotkey, .. }, + Entry::Item { + title: other_title, + hotkey: other_hotkey, + .. + }, + ) => title == other_title && hotkey == other_hotkey, + ( + Entry::Dropdown { title, submenu }, + Entry::Dropdown { + title: other_title, + submenu: other_submenu, + }, + ) => title == other_title && submenu == other_submenu, + (Entry::Separator, Entry::Separator) => true, + _ => false, + } + } +} diff --git a/core/src/mouse/event.rs b/core/src/mouse/event.rs index 2f07b207..321b8399 100644 --- a/core/src/mouse/event.rs +++ b/core/src/mouse/event.rs @@ -1,3 +1,5 @@ +use crate::Point; + use super::Button; /// A mouse event. @@ -16,11 +18,8 @@ pub enum Event { /// The mouse cursor was moved CursorMoved { - /// The X coordinate of the mouse position - x: f32, - - /// The Y coordinate of the mouse position - y: f32, + /// The new position of the mouse cursor + position: Point, }, /// A mouse button was pressed. diff --git a/core/src/padding.rs b/core/src/padding.rs new file mode 100644 index 00000000..22467d6b --- /dev/null +++ b/core/src/padding.rs @@ -0,0 +1,107 @@ +/// An amount of space to pad for each side of a box +/// +/// You can leverage the `From` trait to build [`Padding`] conveniently: +/// +/// ``` +/// # use iced_core::Padding; +/// # +/// let padding = Padding::from(20); // 20px on all sides +/// let padding = Padding::from([10, 20]); // top/bottom, left/right +/// let padding = Padding::from([5, 10, 15, 20]); // top, right, bottom, left +/// ``` +/// +/// Normally, the `padding` method of a widget will ask for an `Into<Padding>`, +/// so you can easily write: +/// +/// ``` +/// # use iced_core::Padding; +/// # +/// # struct Widget; +/// # +/// impl Widget { +/// # pub fn new() -> Self { Self } +/// # +/// pub fn padding(mut self, padding: impl Into<Padding>) -> Self { +/// // ... +/// self +/// } +/// } +/// +/// let widget = Widget::new().padding(20); // 20px on all sides +/// let widget = Widget::new().padding([10, 20]); // top/bottom, left/right +/// let widget = Widget::new().padding([5, 10, 15, 20]); // top, right, bottom, left +/// ``` +#[derive(Debug, Hash, Copy, Clone)] +pub struct Padding { + /// Top padding + pub top: u16, + /// Right padding + pub right: u16, + /// Bottom padding + pub bottom: u16, + /// Left padding + pub left: u16, +} + +impl Padding { + /// Padding of zero + pub const ZERO: Padding = Padding { + top: 0, + right: 0, + bottom: 0, + left: 0, + }; + + /// Create a Padding that is equal on all sides + pub const fn new(padding: u16) -> Padding { + Padding { + top: padding, + right: padding, + bottom: padding, + left: padding, + } + } + + /// Returns the total amount of vertical [`Padding`]. + pub fn vertical(self) -> u16 { + self.top + self.bottom + } + + /// Returns the total amount of horizontal [`Padding`]. + pub fn horizontal(self) -> u16 { + self.left + self.right + } +} + +impl std::convert::From<u16> for Padding { + fn from(p: u16) -> Self { + Padding { + top: p, + right: p, + bottom: p, + left: p, + } + } +} + +impl std::convert::From<[u16; 2]> for Padding { + fn from(p: [u16; 2]) -> Self { + Padding { + top: p[0], + right: p[1], + bottom: p[0], + left: p[1], + } + } +} + +impl std::convert::From<[u16; 4]> for Padding { + fn from(p: [u16; 4]) -> Self { + Padding { + top: p[0], + right: p[1], + bottom: p[2], + left: p[3], + } + } +} diff --git a/core/src/point.rs b/core/src/point.rs index 3714aa2f..9bf7726b 100644 --- a/core/src/point.rs +++ b/core/src/point.rs @@ -12,20 +12,14 @@ pub struct Point { impl Point { /// The origin (i.e. a [`Point`] at (0, 0)). - /// - /// [`Point`]: struct.Point.html pub const ORIGIN: Point = Point::new(0.0, 0.0); /// Creates a new [`Point`] with the given coordinates. - /// - /// [`Point`]: struct.Point.html pub const fn new(x: f32, y: f32) -> Self { Self { x, y } } /// Computes the distance to another [`Point`]. - /// - /// [`Point`]: struct.Point.html pub fn distance(&self, to: Point) -> f32 { let a = self.x - to.x; let b = self.y - to.y; @@ -46,6 +40,12 @@ impl From<[u16; 2]> for Point { } } +impl From<Point> for [f32; 2] { + fn from(point: Point) -> [f32; 2] { + [point.x, point.y] + } +} + impl std::ops::Add<Vector> for Point { type Output = Self; diff --git a/core/src/rectangle.rs b/core/src/rectangle.rs index ce80c661..4e082051 100644 --- a/core/src/rectangle.rs +++ b/core/src/rectangle.rs @@ -19,10 +19,6 @@ 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, @@ -34,9 +30,6 @@ impl Rectangle<f32> { /// 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, @@ -47,50 +40,33 @@ impl Rectangle<f32> { } /// Returns the [`Point`] at the center of the [`Rectangle`]. - /// - /// [`Point`]: struct.Point.html - /// [`Rectangle`]: struct.Rectangle.html pub fn center(&self) -> Point { Point::new(self.center_x(), self.center_y()) } /// Returns the X coordinate of the [`Point`] at the center of the /// [`Rectangle`]. - /// - /// [`Point`]: struct.Point.html - /// [`Rectangle`]: struct.Rectangle.html pub fn center_x(&self) -> f32 { self.x + self.width / 2.0 } /// Returns the Y coordinate of the [`Point`] at the center of the /// [`Rectangle`]. - /// - /// [`Point`]: struct.Point.html - /// [`Rectangle`]: struct.Rectangle.html pub fn center_y(&self) -> 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 - /// [`Rectangle`]: struct.Rectangle.html pub fn contains(&self, point: Point) -> bool { self.x <= point.x && point.x <= self.x + self.width @@ -99,8 +75,6 @@ impl Rectangle<f32> { } /// Computes the intersection with the given [`Rectangle`]. - /// - /// [`Rectangle`]: struct.Rectangle.html pub fn intersection( &self, other: &Rectangle<f32>, @@ -127,14 +101,12 @@ impl Rectangle<f32> { } /// Snaps the [`Rectangle`] to __unsigned__ integer coordinates. - /// - /// [`Rectangle`]: struct.Rectangle.html pub fn snap(self) -> Rectangle<u32> { Rectangle { x: self.x as u32, y: self.y as u32, - width: self.width.ceil() as u32, - height: self.height.ceil() as u32, + width: self.width as u32, + height: self.height as u32, } } } diff --git a/core/src/size.rs b/core/src/size.rs index aceb5311..6745c6c8 100644 --- a/core/src/size.rs +++ b/core/src/size.rs @@ -1,3 +1,4 @@ +use crate::{Padding, Vector}; use std::f32; /// An amount of space in 2 dimensions. @@ -11,8 +12,6 @@ pub struct Size<T = f32> { impl<T> Size<T> { /// Creates a new [`Size`] with the given width and height. - /// - /// [`Size`]: struct.Size.html pub const fn new(width: T, height: T) -> Self { Size { width, height } } @@ -20,27 +19,19 @@ impl<T> Size<T> { impl Size { /// A [`Size`] with zero width and height. - /// - /// [`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 pub const INFINITY: Size = Size::new(f32::INFINITY, f32::INFINITY); /// Increments the [`Size`] to account for the given padding. - /// - /// [`Size`]: struct.Size.html - pub fn pad(&self, padding: f32) -> Self { + pub fn pad(&self, padding: Padding) -> Self { Size { - width: self.width + padding * 2.0, - height: self.height + padding * 2.0, + width: self.width + padding.horizontal() as f32, + height: self.height + padding.vertical() as f32, } } } @@ -56,3 +47,24 @@ impl From<[u16; 2]> for Size { Size::new(width.into(), height.into()) } } + +impl From<Vector<f32>> for Size { + fn from(vector: Vector<f32>) -> Self { + Size { + width: vector.x, + height: vector.y, + } + } +} + +impl From<Size> for [f32; 2] { + fn from(size: Size) -> [f32; 2] { + [size.width, size.height] + } +} + +impl From<Size> for Vector<f32> { + fn from(size: Size) -> Self { + Vector::new(size.width, size.height) + } +} diff --git a/core/src/vector.rs b/core/src/vector.rs index def3f8c0..92bb7648 100644 --- a/core/src/vector.rs +++ b/core/src/vector.rs @@ -2,20 +2,14 @@ #[derive(Debug, Clone, Copy, PartialEq)] pub struct Vector<T = f32> { /// The X component of the [`Vector`] - /// - /// [`Vector`]: struct.Vector.html pub x: T, /// The Y component of the [`Vector`] - /// - /// [`Vector`]: struct.Vector.html pub y: T, } impl<T> Vector<T> { /// Creates a new [`Vector`] with the given components. - /// - /// [`Vector`]: struct.Vector.html pub const fn new(x: T, y: T) -> Self { Self { x, y } } @@ -65,3 +59,18 @@ where } } } + +impl<T> From<[T; 2]> for Vector<T> { + fn from([x, y]: [T; 2]) -> Self { + Self::new(x, y) + } +} + +impl<T> From<Vector<T>> for [T; 2] +where + T: Copy, +{ + fn from(other: Vector<T>) -> Self { + [other.x, other.y] + } +} |