summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml2
-rw-r--r--core/src/background.rs7
-rw-r--r--core/src/color.rs8
-rw-r--r--core/src/lib.rs2
-rw-r--r--core/src/widget/button.rs96
-rw-r--r--core/src/widget/text.rs2
-rw-r--r--examples/tour.rs52
-rw-r--r--native/src/element.rs27
-rw-r--r--native/src/lib.rs12
-rw-r--r--native/src/style.rs4
-rw-r--r--native/src/widget.rs2
-rw-r--r--native/src/widget/button.rs26
-rw-r--r--native/src/widget/checkbox.rs4
-rw-r--r--native/src/widget/column.rs2
-rw-r--r--native/src/widget/image.rs4
-rw-r--r--native/src/widget/radio.rs4
-rw-r--r--native/src/widget/row.rs2
-rw-r--r--native/src/widget/slider.rs2
-rw-r--r--native/src/widget/text.rs2
-rw-r--r--src/lib.rs3
-rw-r--r--web/src/element.rs8
-rw-r--r--web/src/widget/button.rs10
-rw-r--r--wgpu/src/lib.rs2
-rw-r--r--wgpu/src/primitive.rs12
-rw-r--r--wgpu/src/quad.rs6
-rw-r--r--wgpu/src/renderer.rs76
-rw-r--r--wgpu/src/renderer/button.rs45
-rw-r--r--wgpu/src/renderer/checkbox.rs2
-rw-r--r--wgpu/src/renderer/image.rs2
-rw-r--r--wgpu/src/renderer/radio.rs2
-rw-r--r--wgpu/src/renderer/text.rs5
-rw-r--r--wgpu/src/shader/quad.frag12
-rw-r--r--wgpu/src/shader/quad.frag.spvbin2900 -> 3196 bytes
-rw-r--r--wgpu/src/shader/quad.vert3
-rw-r--r--wgpu/src/shader/quad.vert.spvbin2364 -> 2544 bytes
35 files changed, 288 insertions, 160 deletions
diff --git a/Cargo.toml b/Cargo.toml
index dbe24606..52fc483f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -19,6 +19,8 @@ members = [
"core",
"native",
"web",
+ "wgpu",
+ "winit",
]
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
diff --git a/core/src/background.rs b/core/src/background.rs
new file mode 100644
index 00000000..59b67a2c
--- /dev/null
+++ b/core/src/background.rs
@@ -0,0 +1,7 @@
+use crate::Color;
+
+#[derive(Debug, Clone, Copy, PartialEq)]
+pub enum Background {
+ Color(Color),
+ // TODO: Add gradient and image variants
+}
diff --git a/core/src/color.rs b/core/src/color.rs
index 2b64c78d..79910dd8 100644
--- a/core/src/color.rs
+++ b/core/src/color.rs
@@ -17,6 +17,14 @@ impl Color {
a: 1.0,
};
+ /// The white color.
+ pub const WHITE: Color = Color {
+ r: 1.0,
+ g: 1.0,
+ b: 1.0,
+ a: 1.0,
+ };
+
pub fn into_linear(self) -> [f32; 4] {
// As described in:
// https://en.wikipedia.org/wiki/SRGB#The_reverse_transformation
diff --git a/core/src/lib.rs b/core/src/lib.rs
index 1f43b2b7..877a8f85 100644
--- a/core/src/lib.rs
+++ b/core/src/lib.rs
@@ -1,6 +1,7 @@
pub mod widget;
mod align;
+mod background;
mod color;
mod justify;
mod length;
@@ -9,6 +10,7 @@ mod rectangle;
mod vector;
pub use align::Align;
+pub use background::Background;
pub use color::Color;
pub use justify::Justify;
pub use length::Length;
diff --git a/core/src/widget/button.rs b/core/src/widget/button.rs
index b98bb443..a57f2dd8 100644
--- a/core/src/widget/button.rs
+++ b/core/src/widget/button.rs
@@ -5,68 +5,58 @@
//! [`Button`]: struct.Button.html
//! [`State`]: struct.State.html
-use crate::{Align, Length};
+use crate::{Align, Background, Length};
/// A generic widget that produces a message when clicked.
-///
-/// # Example
-///
-/// ```
-/// use iced_core::{button, Button};
-///
-/// pub enum Message {
-/// ButtonClicked,
-/// }
-///
-/// let state = &mut button::State::new();
-///
-/// Button::new(state, "Click me!")
-/// .on_press(Message::ButtonClicked);
-/// ```
-///
-/// ![Button drawn by Coffee's renderer](https://github.com/hecrj/coffee/blob/bda9818f823dfcb8a7ad0ff4940b4d4b387b5208/images/ui/button.png?raw=true)
-pub struct Button<'a, Message> {
+pub struct Button<'a, Message, Element> {
/// The current state of the button
pub state: &'a mut State,
- /// The label of the button
- pub label: String,
+ pub content: Element,
/// The message to produce when the button is pressed
pub on_press: Option<Message>,
- pub class: Class,
-
pub width: Length,
+ pub padding: u16,
+
+ pub background: Option<Background>,
+
+ pub border_radius: u16,
+
pub align_self: Option<Align>,
}
-impl<'a, Message> std::fmt::Debug for Button<'a, Message>
+impl<'a, Message, Element> std::fmt::Debug for Button<'a, Message, Element>
where
Message: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Button")
.field("state", &self.state)
- .field("label", &self.label)
.field("on_press", &self.on_press)
.finish()
}
}
-impl<'a, Message> Button<'a, Message> {
+impl<'a, Message, Element> Button<'a, Message, Element> {
/// Creates a new [`Button`] with some local [`State`] and the given label.
///
/// [`Button`]: struct.Button.html
/// [`State`]: struct.State.html
- pub fn new(state: &'a mut State, label: &str) -> Self {
+ pub fn new<E>(state: &'a mut State, content: E) -> Self
+ where
+ E: Into<Element>,
+ {
Button {
state,
- label: String::from(label),
+ content: content.into(),
on_press: None,
- class: Class::Primary,
width: Length::Shrink,
+ padding: 0,
+ background: None,
+ border_radius: 0,
align_self: None,
}
}
@@ -79,6 +69,21 @@ impl<'a, Message> Button<'a, Message> {
self
}
+ pub fn padding(mut self, padding: u16) -> Self {
+ self.padding = padding;
+ self
+ }
+
+ pub fn background(mut self, background: Background) -> Self {
+ self.background = Some(background);
+ self
+ }
+
+ pub fn border_radius(mut self, border_radius: u16) -> Self {
+ self.border_radius = border_radius;
+ self
+ }
+
/// Sets the alignment of the [`Button`] itself.
///
/// This is useful if you want to override the default alignment given by
@@ -90,16 +95,6 @@ impl<'a, Message> Button<'a, Message> {
self
}
- /// Sets the [`Class`] of the [`Button`].
- ///
- ///
- /// [`Button`]: struct.Button.html
- /// [`Class`]: enum.Class.html
- pub fn class(mut self, class: Class) -> Self {
- self.class = class;
- self
- }
-
/// Sets the message that will be produced when the [`Button`] is pressed.
///
/// [`Button`]: struct.Button.html
@@ -133,26 +128,3 @@ impl State {
self.is_pressed
}
}
-
-/// The type of a [`Button`].
-///
-/// ![Different buttons drawn by the built-in renderer in Coffee](https://github.com/hecrj/coffee/blob/bda9818f823dfcb8a7ad0ff4940b4d4b387b5208/images/ui/button_classes.png?raw=true)
-///
-/// [`Button`]: struct.Button.html
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum Class {
- /// The [`Button`] performs the main action.
- ///
- /// [`Button`]: struct.Button.html
- Primary,
-
- /// The [`Button`] performs an alternative action.
- ///
- /// [`Button`]: struct.Button.html
- Secondary,
-
- /// The [`Button`] performs a productive action.
- ///
- /// [`Button`]: struct.Button.html
- Positive,
-}
diff --git a/core/src/widget/text.rs b/core/src/widget/text.rs
index 427d9471..cd94dbb2 100644
--- a/core/src/widget/text.rs
+++ b/core/src/widget/text.rs
@@ -1,5 +1,5 @@
//! Write some text for your users to read.
-use crate::{Color, Length};
+use crate::{Align, Color, Length};
/// A paragraph of text.
///
diff --git a/examples/tour.rs b/examples/tour.rs
index 5f24eb87..96590c0e 100644
--- a/examples/tour.rs
+++ b/examples/tour.rs
@@ -1,7 +1,7 @@
use iced::{
- button, slider, text::HorizontalAlignment, Align, Button, Checkbox, Color,
- Column, Element, Image, Justify, Length, Radio, Row, Slider, Text,
- UserInterface,
+ button, slider, text::HorizontalAlignment, Align, Background, Button,
+ Checkbox, Color, Column, Element, Image, Justify, Length, Radio, Row,
+ Slider, Text, UserInterface,
};
pub fn main() {
@@ -59,9 +59,8 @@ impl UserInterface for Tour {
if steps.has_previous() {
controls = controls.push(
- Button::new(back_button, "Back")
- .on_press(Message::BackPressed)
- .class(button::Class::Secondary),
+ secondary_button(back_button, "Back")
+ .on_press(Message::BackPressed),
);
}
@@ -69,7 +68,8 @@ impl UserInterface for Tour {
if steps.can_continue() {
controls = controls.push(
- Button::new(next_button, "Next").on_press(Message::NextPressed),
+ primary_button(next_button, "Next")
+ .on_press(Message::NextPressed),
);
}
@@ -546,6 +546,44 @@ impl<'a> Step {
}
}
+fn button<'a, Message>(
+ state: &'a mut button::State,
+ label: &str,
+) -> Button<'a, Message> {
+ Button::new(
+ state,
+ Text::new(label)
+ .color(Color::WHITE)
+ .horizontal_alignment(HorizontalAlignment::Center),
+ )
+ .padding(10)
+ .border_radius(10)
+}
+
+fn primary_button<'a, Message>(
+ state: &'a mut button::State,
+ label: &str,
+) -> Button<'a, Message> {
+ button(state, label).background(Background::Color(Color {
+ r: 0.3,
+ g: 0.3,
+ b: 0.8,
+ a: 1.0,
+ }))
+}
+
+fn secondary_button<'a, Message>(
+ state: &'a mut button::State,
+ label: &str,
+) -> Button<'a, Message> {
+ button(state, label).background(Background::Color(Color {
+ r: 0.8,
+ g: 0.8,
+ b: 0.8,
+ a: 1.0,
+ }))
+}
+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Language {
Rust,
diff --git a/native/src/element.rs b/native/src/element.rs
index 417e3463..cf96b7ea 100644
--- a/native/src/element.rs
+++ b/native/src/element.rs
@@ -41,6 +41,10 @@ where
}
}
+ pub fn node(&self, renderer: &Renderer) -> Node {
+ self.widget.node(renderer)
+ }
+
pub fn draw(
&self,
renderer: &mut Renderer,
@@ -97,22 +101,22 @@ where
///
/// ```
/// # mod counter {
- /// # use iced_native::{button, Button};
+ /// # use iced_native::{text, Text};
/// #
/// # #[derive(Debug, Clone, Copy)]
/// # pub enum Message {}
- /// # pub struct Counter(button::State);
+ /// # pub struct Counter;
/// #
/// # impl Counter {
- /// # pub fn view(&mut self) -> Button<Message> {
- /// # Button::new(&mut self.0, "_")
+ /// # pub fn view(&mut self) -> Text {
+ /// # Text::new("")
/// # }
/// # }
/// # }
/// #
/// # mod iced_wgpu {
/// # use iced_native::{
- /// # button, row, Button, Node, Point, Rectangle, Style, Layout, Row
+ /// # text, row, Text, Node, Point, Rectangle, Style, Layout, Row
/// # };
/// # pub struct Renderer;
/// #
@@ -127,16 +131,15 @@ where
/// # ) {}
/// # }
/// #
- /// # impl button::Renderer for Renderer {
- /// # fn node<Message>(&self, _button: &Button<'_, Message>) -> Node {
+ /// # impl text::Renderer for Renderer {
+ /// # fn node(&self, _text: &Text) -> Node {
/// # Node::new(Style::default())
/// # }
/// #
- /// # fn draw<Message>(
+ /// # fn draw(
/// # &mut self,
- /// # _button: &Button<'_, Message>,
+ /// # _text: &Text,
/// # _layout: Layout<'_>,
- /// # _cursor_position: Point,
/// # ) {}
/// # }
/// # }
@@ -289,7 +292,7 @@ where
A: Copy,
Renderer: crate::Renderer,
{
- fn node(&self, renderer: &mut Renderer) -> Node {
+ fn node(&self, renderer: &Renderer) -> Node {
self.widget.node(renderer)
}
@@ -359,7 +362,7 @@ impl<'a, Message, Renderer> Widget<Message, Renderer>
where
Renderer: crate::Renderer + renderer::Debugger,
{
- fn node(&self, renderer: &mut Renderer) -> Node {
+ fn node(&self, renderer: &Renderer) -> Node {
self.element.widget.node(renderer)
}
diff --git a/native/src/lib.rs b/native/src/lib.rs
index 6067f49d..18ce3a37 100644
--- a/native/src/lib.rs
+++ b/native/src/lib.rs
@@ -89,14 +89,14 @@
//! # impl button::Renderer for Renderer {
//! # fn node<Message>(
//! # &self,
-//! # _button: &Button<'_, Message>
+//! # _button: &Button<'_, Message, Self>
//! # ) -> Node {
//! # Node::new(Style::default())
//! # }
//! #
//! # fn draw<Message>(
//! # &mut self,
-//! # _button: &Button<'_, Message>,
+//! # _button: &Button<'_, Message, Self>,
//! # _layout: Layout<'_>,
//! # _cursor_position: Point,
//! # ) {}
@@ -125,7 +125,7 @@
//! .push(
//! // The increment button. We tell it to produce an
//! // `IncrementPressed` message when pressed
-//! Button::new(&mut self.increment_button, "+")
+//! Button::new(&mut self.increment_button, Text::new("+"))
//! .on_press(Message::IncrementPressed),
//! )
//! .push(
@@ -135,7 +135,7 @@
//! .push(
//! // The decrement button. We tell it to produce a
//! // `DecrementPressed` message when pressed
-//! Button::new(&mut self.decrement_button, "-")
+//! Button::new(&mut self.decrement_button, Text::new("-"))
//! .on_press(Message::DecrementPressed),
//! )
//! }
@@ -212,7 +212,9 @@ mod user_interface;
pub(crate) use iced_core::Vector;
-pub use iced_core::{Align, Color, Justify, Length, Point, Rectangle};
+pub use iced_core::{
+ Align, Background, Color, Justify, Length, Point, Rectangle,
+};
#[doc(no_inline)]
pub use stretch::{geometry::Size, number::Number};
diff --git a/native/src/style.rs b/native/src/style.rs
index b1c49fd4..70a7ff74 100644
--- a/native/src/style.rs
+++ b/native/src/style.rs
@@ -74,12 +74,12 @@ impl Style {
self
}
- pub(crate) fn align_items(mut self, align: Align) -> Self {
+ pub fn align_items(mut self, align: Align) -> Self {
self.0.align_items = into_align_items(align);
self
}
- pub(crate) fn justify_content(mut self, justify: Justify) -> Self {
+ pub fn justify_content(mut self, justify: Justify) -> Self {
self.0.justify_content = into_justify_content(justify);
self
}
diff --git a/native/src/widget.rs b/native/src/widget.rs
index eff098a6..b7181c1b 100644
--- a/native/src/widget.rs
+++ b/native/src/widget.rs
@@ -67,7 +67,7 @@ where
/// [`Node`]: ../struct.Node.html
/// [`Widget`]: trait.Widget.html
/// [`Layout`]: ../struct.Layout.html
- fn node(&self, renderer: &mut Renderer) -> Node;
+ fn node(&self, renderer: &Renderer) -> Node;
/// Draws the [`Widget`] using the associated `Renderer`.
///
diff --git a/native/src/widget/button.rs b/native/src/widget/button.rs
index 5ae4e045..1f881660 100644
--- a/native/src/widget/button.rs
+++ b/native/src/widget/button.rs
@@ -10,14 +10,18 @@ use crate::input::{mouse, ButtonState};
use crate::{Element, Event, Hasher, Layout, Node, Point, Widget};
use std::hash::Hash;
-pub use iced_core::button::*;
+pub use iced_core::button::State;
-impl<'a, Message, Renderer> Widget<Message, Renderer> for Button<'a, Message>
+pub type Button<'a, Message, Renderer> =
+ iced_core::Button<'a, Message, Element<'a, Message, Renderer>>;
+
+impl<'a, Message, Renderer> Widget<Message, Renderer>
+ for Button<'a, Message, Renderer>
where
Renderer: self::Renderer,
Message: Copy + std::fmt::Debug,
{
- fn node(&self, renderer: &mut Renderer) -> Node {
+ fn node(&self, renderer: &Renderer) -> Node {
renderer.node(&self)
}
@@ -68,9 +72,9 @@ where
}
fn hash_layout(&self, state: &mut Hasher) {
- self.label.hash(state);
self.width.hash(state);
self.align_self.hash(state);
+ self.content.hash_layout(state);
}
}
@@ -81,31 +85,33 @@ where
///
/// [`Button`]: struct.Button.html
/// [renderer]: ../../renderer/index.html
-pub trait Renderer: crate::Renderer {
+pub trait Renderer: crate::Renderer + Sized {
/// Creates a [`Node`] for the provided [`Button`].
///
/// [`Node`]: ../../struct.Node.html
/// [`Button`]: struct.Button.html
- fn node<Message>(&self, button: &Button<'_, Message>) -> Node;
+ fn node<Message>(&self, button: &Button<'_, Message, Self>) -> Node;
/// Draws a [`Button`].
///
/// [`Button`]: struct.Button.html
fn draw<Message>(
&mut self,
- button: &Button<'_, Message>,
+ button: &Button<'_, Message, Self>,
layout: Layout<'_>,
cursor_position: Point,
) -> Self::Primitive;
}
-impl<'a, Message, Renderer> From<Button<'a, Message>>
+impl<'a, Message, Renderer> From<Button<'a, Message, Renderer>>
for Element<'a, Message, Renderer>
where
- Renderer: self::Renderer,
+ Renderer: 'static + self::Renderer,
Message: 'static + Copy + std::fmt::Debug,
{
- fn from(button: Button<'a, Message>) -> Element<'a, Message, Renderer> {
+ fn from(
+ button: Button<'a, Message, Renderer>,
+ ) -> Element<'a, Message, Renderer> {
Element::new(button)
}
}
diff --git a/native/src/widget/checkbox.rs b/native/src/widget/checkbox.rs
index 1954305a..c069bfdc 100644
--- a/native/src/widget/checkbox.rs
+++ b/native/src/widget/checkbox.rs
@@ -10,7 +10,7 @@ impl<Message, Renderer> Widget<Message, Renderer> for Checkbox<Message>
where
Renderer: self::Renderer,
{
- fn node(&self, renderer: &mut Renderer) -> Node {
+ fn node(&self, renderer: &Renderer) -> Node {
renderer.node(&self)
}
@@ -64,7 +64,7 @@ pub trait Renderer: crate::Renderer {
///
/// [`Node`]: ../../struct.Node.html
/// [`Checkbox`]: struct.Checkbox.html
- fn node<Message>(&mut self, checkbox: &Checkbox<Message>) -> Node;
+ fn node<Message>(&self, checkbox: &Checkbox<Message>) -> Node;
/// Draws a [`Checkbox`].
///
diff --git a/native/src/widget/column.rs b/native/src/widget/column.rs
index 6228d711..7e10e662 100644
--- a/native/src/widget/column.rs
+++ b/native/src/widget/column.rs
@@ -11,7 +11,7 @@ impl<'a, Message, Renderer> Widget<Message, Renderer>
where
Renderer: self::Renderer,
{
- fn node(&self, renderer: &mut Renderer) -> Node {
+ fn node(&self, renderer: &Renderer) -> Node {
let mut children: Vec<Node> = self
.children
.iter()
diff --git a/native/src/widget/image.rs b/native/src/widget/image.rs
index 2bce36c2..5197d5b1 100644
--- a/native/src/widget/image.rs
+++ b/native/src/widget/image.rs
@@ -11,7 +11,7 @@ where
Renderer: self::Renderer<I>,
I: Clone,
{
- fn node(&self, renderer: &mut Renderer) -> Node {
+ fn node(&self, renderer: &Renderer) -> Node {
renderer.node(&self)
}
@@ -45,7 +45,7 @@ pub trait Renderer<I>: crate::Renderer {
///
/// [`Node`]: ../../struct.Node.html
/// [`Image`]: struct.Image.html
- fn node(&mut self, image: &Image<I>) -> Node;
+ fn node(&self, image: &Image<I>) -> Node;
/// Draws an [`Image`].
///
diff --git a/native/src/widget/radio.rs b/native/src/widget/radio.rs
index 1bc052aa..22308f81 100644
--- a/native/src/widget/radio.rs
+++ b/native/src/widget/radio.rs
@@ -11,7 +11,7 @@ where
Renderer: self::Renderer,
Message: Copy + std::fmt::Debug,
{
- fn node(&self, renderer: &mut Renderer) -> Node {
+ fn node(&self, renderer: &Renderer) -> Node {
renderer.node(&self)
}
@@ -61,7 +61,7 @@ pub trait Renderer: crate::Renderer {
///
/// [`Node`]: ../../struct.Node.html
/// [`Radio`]: struct.Radio.html
- fn node<Message>(&mut self, radio: &Radio<Message>) -> Node;
+ fn node<Message>(&self, radio: &Radio<Message>) -> Node;
/// Draws a [`Radio`] button.
///
diff --git a/native/src/widget/row.rs b/native/src/widget/row.rs
index 9d023210..b1d4a5b2 100644
--- a/native/src/widget/row.rs
+++ b/native/src/widget/row.rs
@@ -11,7 +11,7 @@ impl<'a, Message, Renderer> Widget<Message, Renderer>
where
Renderer: self::Renderer,
{
- fn node(&self, renderer: &mut Renderer) -> Node {
+ fn node(&self, renderer: &Renderer) -> Node {
let mut children: Vec<Node> = self
.children
.iter()
diff --git a/native/src/widget/slider.rs b/native/src/widget/slider.rs
index 77095cb7..643efdf4 100644
--- a/native/src/widget/slider.rs
+++ b/native/src/widget/slider.rs
@@ -15,7 +15,7 @@ impl<'a, Message, Renderer> Widget<Message, Renderer> for Slider<'a, Message>
where
Renderer: self::Renderer,
{
- fn node(&self, renderer: &mut Renderer) -> Node {
+ fn node(&self, renderer: &Renderer) -> Node {
renderer.node(&self)
}
diff --git a/native/src/widget/text.rs b/native/src/widget/text.rs
index a032b4fc..62f2d7b7 100644
--- a/native/src/widget/text.rs
+++ b/native/src/widget/text.rs
@@ -9,7 +9,7 @@ impl<Message, Renderer> Widget<Message, Renderer> for Text
where
Renderer: self::Renderer,
{
- fn node(&self, renderer: &mut Renderer) -> Node {
+ fn node(&self, renderer: &Renderer) -> Node {
renderer.node(&self)
}
diff --git a/src/lib.rs b/src/lib.rs
index c5a34dcd..2e65ed6c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,12 +1,13 @@
pub use iced_wgpu::{Primitive, Renderer};
pub use iced_winit::{
- button, slider, text, winit, Align, Button, Checkbox, Color, Image,
+ button, slider, text, winit, Align, Background, Checkbox, Color, Image,
Justify, Length, Radio, Slider, Text,
};
pub type Element<'a, Message> = iced_winit::Element<'a, Message, Renderer>;
pub type Row<'a, Message> = iced_winit::Row<'a, Message, Renderer>;
pub type Column<'a, Message> = iced_winit::Column<'a, Message, Renderer>;
+pub type Button<'a, Message> = iced_winit::Button<'a, Message, Renderer>;
pub trait UserInterface {
type Message;
diff --git a/web/src/element.rs b/web/src/element.rs
index 8270d8db..a2b78c69 100644
--- a/web/src/element.rs
+++ b/web/src/element.rs
@@ -14,6 +14,14 @@ impl<'a, Message> Element<'a, Message> {
}
}
+ pub fn node<'b>(
+ &self,
+ bump: &'b bumpalo::Bump,
+ bus: &Bus<Message>,
+ ) -> dodrio::Node<'b> {
+ self.widget.node(bump, bus)
+ }
+
pub fn explain(self, _color: Color) -> Element<'a, Message> {
self
}
diff --git a/web/src/widget/button.rs b/web/src/widget/button.rs
index 23a4165a..257034a7 100644
--- a/web/src/widget/button.rs
+++ b/web/src/widget/button.rs
@@ -2,7 +2,10 @@ use crate::{Bus, Element, Widget};
use dodrio::bumpalo;
-pub use iced_core::button::*;
+pub use iced_core::button::State;
+
+pub type Button<'a, Message> =
+ iced_core::Button<'a, Message, Element<'a, Message>>;
impl<'a, Message> Widget<Message> for Button<'a, Message>
where
@@ -15,9 +18,8 @@ where
) -> dodrio::Node<'b> {
use dodrio::builder::*;
- let label = bumpalo::format!(in bump, "{}", self.label);
-
- let mut node = button(bump).children(vec![text(label.into_bump_str())]);
+ let mut node =
+ button(bump).children(vec![self.content.node(bump, bus)]);
if let Some(on_press) = self.on_press {
let event_bus = bus.clone();
diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs
index 33d8f5ed..8f8d50e9 100644
--- a/wgpu/src/lib.rs
+++ b/wgpu/src/lib.rs
@@ -8,5 +8,5 @@ pub(crate) use quad::Quad;
pub(crate) use transformation::Transformation;
pub use mouse_cursor::MouseCursor;
-pub use primitive::{Background, Primitive};
+pub use primitive::Primitive;
pub use renderer::{Renderer, Target};
diff --git a/wgpu/src/primitive.rs b/wgpu/src/primitive.rs
index f6730a1f..b664689b 100644
--- a/wgpu/src/primitive.rs
+++ b/wgpu/src/primitive.rs
@@ -1,4 +1,4 @@
-use iced_native::{Color, Rectangle};
+use iced_native::{text, Background, Color, Rectangle};
#[derive(Debug, Clone)]
pub enum Primitive {
@@ -9,16 +9,14 @@ pub enum Primitive {
Text {
content: String,
bounds: Rectangle,
+ color: Color,
size: f32,
+ horizontal_alignment: text::HorizontalAlignment,
+ vertical_alignment: text::VerticalAlignment,
},
Quad {
bounds: Rectangle,
background: Background,
+ border_radius: u16,
},
}
-
-#[derive(Debug, Clone, Copy, PartialEq)]
-pub enum Background {
- Color(Color),
- // TODO: Add gradient and image variants
-}
diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs
index d0126bbd..adb294f0 100644
--- a/wgpu/src/quad.rs
+++ b/wgpu/src/quad.rs
@@ -123,6 +123,11 @@ impl Pipeline {
format: wgpu::VertexFormat::Float4,
offset: 4 * (2 + 2),
},
+ wgpu::VertexAttributeDescriptor {
+ shader_location: 4,
+ format: wgpu::VertexFormat::Uint,
+ offset: 4 * (2 + 2 + 4),
+ },
],
},
],
@@ -262,6 +267,7 @@ pub struct Quad {
pub position: [f32; 2],
pub scale: [f32; 2],
pub color: [f32; 4],
+ pub border_radius: u32,
}
impl Quad {
diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs
index 9883943b..ae5692e3 100644
--- a/wgpu/src/renderer.rs
+++ b/wgpu/src/renderer.rs
@@ -1,5 +1,7 @@
-use crate::{quad, Background, Primitive, Quad, Transformation};
-use iced_native::{renderer::Debugger, Color, Layout, Point, Widget};
+use crate::{quad, Primitive, Quad, Transformation};
+use iced_native::{
+ renderer::Debugger, Background, Color, Layout, Point, Widget,
+};
use raw_window_handle::HasRawWindowHandle;
use wgpu::{
@@ -159,20 +161,74 @@ impl Renderer {
content,
bounds,
size,
- } => self.glyph_brush.borrow_mut().queue(Section {
- text: &content,
- screen_position: (bounds.x, bounds.y),
- bounds: (bounds.width, bounds.height),
- scale: wgpu_glyph::Scale { x: *size, y: *size },
- ..Default::default()
- }),
- Primitive::Quad { bounds, background } => {
+ color,
+ horizontal_alignment,
+ vertical_alignment,
+ } => {
+ let x = match horizontal_alignment {
+ iced_native::text::HorizontalAlignment::Left => bounds.x,
+ iced_native::text::HorizontalAlignment::Center => {
+ bounds.x + bounds.width / 2.0
+ }
+ iced_native::text::HorizontalAlignment::Right => {
+ bounds.x + bounds.width
+ }
+ };
+
+ let y = match vertical_alignment {
+ iced_native::text::VerticalAlignment::Top => bounds.y,
+ iced_native::text::VerticalAlignment::Center => {
+ bounds.y + bounds.height / 2.0
+ }
+ iced_native::text::VerticalAlignment::Bottom => {
+ bounds.y + bounds.height
+ }
+ };
+
+ self.glyph_brush.borrow_mut().queue(Section {
+ text: &content,
+ screen_position: (x, y),
+ bounds: (bounds.width, bounds.height),
+ scale: wgpu_glyph::Scale { x: *size, y: *size },
+ color: color.into_linear(),
+ layout: wgpu_glyph::Layout::default()
+ .h_align(match horizontal_alignment {
+ iced_native::text::HorizontalAlignment::Left => {
+ wgpu_glyph::HorizontalAlign::Left
+ }
+ iced_native::text::HorizontalAlignment::Center => {
+ wgpu_glyph::HorizontalAlign::Center
+ }
+ iced_native::text::HorizontalAlignment::Right => {
+ wgpu_glyph::HorizontalAlign::Right
+ }
+ })
+ .v_align(match vertical_alignment {
+ iced_native::text::VerticalAlignment::Top => {
+ wgpu_glyph::VerticalAlign::Top
+ }
+ iced_native::text::VerticalAlignment::Center => {
+ wgpu_glyph::VerticalAlign::Center
+ }
+ iced_native::text::VerticalAlignment::Bottom => {
+ wgpu_glyph::VerticalAlign::Bottom
+ }
+ }),
+ ..Default::default()
+ })
+ }
+ Primitive::Quad {
+ bounds,
+ background,
+ border_radius,
+ } => {
self.quads.push(Quad {
position: [bounds.x, bounds.y],
scale: [bounds.width, bounds.height],
color: match background {
Background::Color(color) => color.into_linear(),
},
+ border_radius: u32::from(*border_radius),
});
}
}
diff --git a/wgpu/src/renderer/button.rs b/wgpu/src/renderer/button.rs
index f75b44f7..00fcd0eb 100644
--- a/wgpu/src/renderer/button.rs
+++ b/wgpu/src/renderer/button.rs
@@ -1,22 +1,26 @@
-use crate::{Background, Primitive, Renderer};
-use iced_native::{button, Button, Color, Layout, Length, Node, Point, Style};
+use crate::{Primitive, Renderer};
+use iced_native::{
+ button, Align, Background, Button, Color, Layout, Length, Node, Point,
+ Style,
+};
impl button::Renderer for Renderer {
- fn node<Message>(&self, button: &Button<Message>) -> Node {
+ fn node<Message>(&self, button: &Button<Message, Self>) -> Node {
let style = Style::default()
.width(button.width)
- .min_height(Length::Units(30))
+ .padding(button.padding)
.min_width(Length::Units(100))
- .align_self(button.align_self);
+ .align_self(button.align_self)
+ .align_items(Align::Stretch);
- Node::new(style)
+ Node::with_children(style, vec![button.content.node(self)])
}
fn draw<Message>(
&mut self,
- button: &Button<Message>,
+ button: &Button<Message, Self>,
layout: Layout<'_>,
- _cursor_position: Point,
+ cursor_position: Point,
) -> Self::Primitive {
let bounds = layout.bounds();
@@ -24,18 +28,21 @@ impl button::Renderer for Renderer {
primitives: vec![
Primitive::Quad {
bounds,
- background: Background::Color(Color {
- r: 0.8,
- b: 0.8,
- g: 0.8,
- a: 1.0,
- }),
- },
- Primitive::Text {
- content: button.label.clone(),
- size: 20.0,
- bounds: layout.bounds(),
+ background: button.background.unwrap_or(Background::Color(
+ Color {
+ r: 0.8,
+ b: 0.8,
+ g: 0.8,
+ a: 1.0,
+ },
+ )),
+ border_radius: button.border_radius,
},
+ button.content.draw(
+ self,
+ layout.children().next().unwrap(),
+ cursor_position,
+ ),
],
}
}
diff --git a/wgpu/src/renderer/checkbox.rs b/wgpu/src/renderer/checkbox.rs
index c94a2157..16d5734f 100644
--- a/wgpu/src/renderer/checkbox.rs
+++ b/wgpu/src/renderer/checkbox.rs
@@ -2,7 +2,7 @@ use crate::{Primitive, Renderer};
use iced_native::{checkbox, Checkbox, Layout, Node, Point, Style};
impl checkbox::Renderer for Renderer {
- fn node<Message>(&mut self, _checkbox: &Checkbox<Message>) -> Node {
+ fn node<Message>(&self, _checkbox: &Checkbox<Message>) -> Node {
Node::new(Style::default())
}
diff --git a/wgpu/src/renderer/image.rs b/wgpu/src/renderer/image.rs
index 6ff39d30..bacc430d 100644
--- a/wgpu/src/renderer/image.rs
+++ b/wgpu/src/renderer/image.rs
@@ -2,7 +2,7 @@ use crate::{Primitive, Renderer};
use iced_native::{image, Image, Layout, Node, Style};
impl image::Renderer<&str> for Renderer {
- fn node(&mut self, _image: &Image<&str>) -> Node {
+ fn node(&self, _image: &Image<&str>) -> Node {
Node::new(Style::default())
}
diff --git a/wgpu/src/renderer/radio.rs b/wgpu/src/renderer/radio.rs
index ce419ae0..fdc0a0fc 100644
--- a/wgpu/src/renderer/radio.rs
+++ b/wgpu/src/renderer/radio.rs
@@ -2,7 +2,7 @@ use crate::{Primitive, Renderer};
use iced_native::{radio, Layout, Node, Point, Radio, Style};
impl radio::Renderer for Renderer {
- fn node<Message>(&mut self, _checkbox: &Radio<Message>) -> Node {
+ fn node<Message>(&self, _checkbox: &Radio<Message>) -> Node {
Node::new(Style::default())
}
diff --git a/wgpu/src/renderer/text.rs b/wgpu/src/renderer/text.rs
index 4434cc22..c89c0b3e 100644
--- a/wgpu/src/renderer/text.rs
+++ b/wgpu/src/renderer/text.rs
@@ -1,5 +1,5 @@
use crate::{Primitive, Renderer};
-use iced_native::{text, Layout, Node, Style, Text};
+use iced_native::{text, Color, Layout, Node, Style, Text};
use wgpu_glyph::{GlyphCruncher, Section};
@@ -72,6 +72,9 @@ impl text::Renderer for Renderer {
content: text.content.clone(),
size: f32::from(text.size.unwrap_or(20)),
bounds: layout.bounds(),
+ color: text.color.unwrap_or(Color::BLACK),
+ horizontal_alignment: text.horizontal_alignment,
+ vertical_alignment: text.vertical_alignment,
}
}
}
diff --git a/wgpu/src/shader/quad.frag b/wgpu/src/shader/quad.frag
index 1fc28bc1..987744db 100644
--- a/wgpu/src/shader/quad.frag
+++ b/wgpu/src/shader/quad.frag
@@ -3,6 +3,7 @@
layout(location = 0) in vec4 v_Color;
layout(location = 1) in vec2 v_Pos;
layout(location = 2) in vec2 v_Scale;
+layout(location = 3) in flat uint v_BorderRadius;
layout(location = 0) out vec4 o_Color;
@@ -26,8 +27,11 @@ float rounded(in vec2 frag_coord, in vec2 position, in vec2 size, float radius,
}
void main() {
- o_Color = vec4(
- v_Color.xyz,
- v_Color.w * rounded(gl_FragCoord.xy, v_Pos, v_Scale, 5.0, 1.0)
- );
+ float radius_alpha = 1.0;
+
+ if(v_BorderRadius > 0.0) {
+ radius_alpha = rounded(gl_FragCoord.xy, v_Pos, v_Scale, v_BorderRadius, 1.0);
+ }
+
+ o_Color = vec4(v_Color.xyz, v_Color.w * radius_alpha);
}
diff --git a/wgpu/src/shader/quad.frag.spv b/wgpu/src/shader/quad.frag.spv
index 19733ecf..063287b3 100644
--- a/wgpu/src/shader/quad.frag.spv
+++ b/wgpu/src/shader/quad.frag.spv
Binary files differ
diff --git a/wgpu/src/shader/quad.vert b/wgpu/src/shader/quad.vert
index 87f6cc53..b7c5cf3e 100644
--- a/wgpu/src/shader/quad.vert
+++ b/wgpu/src/shader/quad.vert
@@ -4,6 +4,7 @@ layout(location = 0) in vec2 v_Pos;
layout(location = 1) in vec2 i_Pos;
layout(location = 2) in vec2 i_Scale;
layout(location = 3) in vec4 i_Color;
+layout(location = 4) in uint i_BorderRadius;
layout (set = 0, binding = 0) uniform Globals {
mat4 u_Transform;
@@ -12,6 +13,7 @@ layout (set = 0, binding = 0) uniform Globals {
layout(location = 0) out vec4 o_Color;
layout(location = 1) out vec2 o_Pos;
layout(location = 2) out vec2 o_Scale;
+layout(location = 3) out uint o_BorderRadius;
void main() {
mat4 i_Transform = mat4(
@@ -24,6 +26,7 @@ void main() {
o_Color = i_Color;
o_Pos = i_Pos;
o_Scale = i_Scale;
+ o_BorderRadius = i_BorderRadius;
gl_Position = u_Transform * i_Transform * vec4(v_Pos, 0.0, 1.0);
}
diff --git a/wgpu/src/shader/quad.vert.spv b/wgpu/src/shader/quad.vert.spv
index 0d13df6c..f62a160c 100644
--- a/wgpu/src/shader/quad.vert.spv
+++ b/wgpu/src/shader/quad.vert.spv
Binary files differ