Draft Style and StyleSheet for Button
This commit is contained in:
parent
4b86c2ff98
commit
c7b170da6d
@ -220,7 +220,26 @@ impl From<surf::Exception> for Error {
|
|||||||
|
|
||||||
fn button<'a>(state: &'a mut button::State, text: &str) -> Button<'a, Message> {
|
fn button<'a>(state: &'a mut button::State, text: &str) -> Button<'a, Message> {
|
||||||
Button::new(state, Text::new(text).color(Color::WHITE))
|
Button::new(state, Text::new(text).color(Color::WHITE))
|
||||||
.background(Color::from_rgb(0.11, 0.42, 0.87))
|
|
||||||
.border_radius(10)
|
|
||||||
.padding(10)
|
.padding(10)
|
||||||
|
.style(style::Button::Primary)
|
||||||
|
}
|
||||||
|
|
||||||
|
mod style {
|
||||||
|
use iced::{button, Background, Color};
|
||||||
|
|
||||||
|
pub enum Button {
|
||||||
|
Primary,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl button::StyleSheet for Button {
|
||||||
|
fn active(&self) -> button::Style {
|
||||||
|
button::Style {
|
||||||
|
background: Some(Background::Color(match self {
|
||||||
|
Button::Primary => Color::from_rgb(0.11, 0.42, 0.87),
|
||||||
|
})),
|
||||||
|
border_radius: 12,
|
||||||
|
shadow_offset: 1.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
use iced::{
|
use iced::{
|
||||||
button, Align, Application, Background, Button, Color, Column, Command,
|
button, Align, Application, Button, Color, Column, Command, Container,
|
||||||
Container, Element, HorizontalAlignment, Length, Row, Settings,
|
Element, HorizontalAlignment, Length, Row, Settings, Subscription, Text,
|
||||||
Subscription, Text,
|
|
||||||
};
|
};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
@ -99,7 +98,7 @@ impl Application for Stopwatch {
|
|||||||
.width(Length::Shrink)
|
.width(Length::Shrink)
|
||||||
.size(40);
|
.size(40);
|
||||||
|
|
||||||
let button = |state, label, color: [f32; 3]| {
|
let button = |state, label, style| {
|
||||||
Button::new(
|
Button::new(
|
||||||
state,
|
state,
|
||||||
Text::new(label)
|
Text::new(label)
|
||||||
@ -107,22 +106,22 @@ impl Application for Stopwatch {
|
|||||||
.horizontal_alignment(HorizontalAlignment::Center),
|
.horizontal_alignment(HorizontalAlignment::Center),
|
||||||
)
|
)
|
||||||
.min_width(80)
|
.min_width(80)
|
||||||
.background(Background::Color(color.into()))
|
|
||||||
.border_radius(10)
|
|
||||||
.padding(10)
|
.padding(10)
|
||||||
|
.style(style)
|
||||||
};
|
};
|
||||||
|
|
||||||
let toggle_button = {
|
let toggle_button = {
|
||||||
let (label, color) = match self.state {
|
let (label, color) = match self.state {
|
||||||
State::Idle => ("Start", [0.11, 0.42, 0.87]),
|
State::Idle => ("Start", style::Button::Primary),
|
||||||
State::Ticking { .. } => ("Stop", [0.9, 0.4, 0.4]),
|
State::Ticking { .. } => ("Stop", style::Button::Destructive),
|
||||||
};
|
};
|
||||||
|
|
||||||
button(&mut self.toggle, label, color).on_press(Message::Toggle)
|
button(&mut self.toggle, label, color).on_press(Message::Toggle)
|
||||||
};
|
};
|
||||||
|
|
||||||
let reset_button = button(&mut self.reset, "Reset", [0.7, 0.7, 0.7])
|
let reset_button =
|
||||||
.on_press(Message::Reset);
|
button(&mut self.reset, "Reset", style::Button::Secondary)
|
||||||
|
.on_press(Message::Reset);
|
||||||
|
|
||||||
let controls = Row::new()
|
let controls = Row::new()
|
||||||
.width(Length::Shrink)
|
.width(Length::Shrink)
|
||||||
@ -180,3 +179,27 @@ mod time {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod style {
|
||||||
|
use iced::{button, Background, Color};
|
||||||
|
|
||||||
|
pub enum Button {
|
||||||
|
Primary,
|
||||||
|
Secondary,
|
||||||
|
Destructive,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl button::StyleSheet for Button {
|
||||||
|
fn active(&self) -> button::Style {
|
||||||
|
button::Style {
|
||||||
|
background: Some(Background::Color(match self {
|
||||||
|
Button::Primary => Color::from_rgb(0.11, 0.42, 0.87),
|
||||||
|
Button::Secondary => Color::from_rgb(0.5, 0.5, 0.5),
|
||||||
|
Button::Destructive => Color::from_rgb(0.8, 0.2, 0.2),
|
||||||
|
})),
|
||||||
|
border_radius: 12,
|
||||||
|
shadow_offset: 1.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -296,7 +296,8 @@ impl Task {
|
|||||||
edit_icon().color([0.5, 0.5, 0.5]),
|
edit_icon().color([0.5, 0.5, 0.5]),
|
||||||
)
|
)
|
||||||
.on_press(TaskMessage::Edit)
|
.on_press(TaskMessage::Edit)
|
||||||
.padding(10),
|
.padding(10)
|
||||||
|
.style(style::Button::NoBackground),
|
||||||
)
|
)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
@ -331,8 +332,7 @@ impl Task {
|
|||||||
)
|
)
|
||||||
.on_press(TaskMessage::Delete)
|
.on_press(TaskMessage::Delete)
|
||||||
.padding(10)
|
.padding(10)
|
||||||
.border_radius(5)
|
.style(style::Button::Destructive),
|
||||||
.background(Color::from_rgb(0.8, 0.2, 0.2)),
|
|
||||||
)
|
)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
@ -361,15 +361,12 @@ impl Controls {
|
|||||||
let label = Text::new(label).size(16).width(Length::Shrink);
|
let label = Text::new(label).size(16).width(Length::Shrink);
|
||||||
let button = if filter == current_filter {
|
let button = if filter == current_filter {
|
||||||
Button::new(state, label.color(Color::WHITE))
|
Button::new(state, label.color(Color::WHITE))
|
||||||
.background(Color::from_rgb(0.2, 0.2, 0.7))
|
.style(style::Button::FilterSelected)
|
||||||
} else {
|
} else {
|
||||||
Button::new(state, label)
|
Button::new(state, label).style(style::Button::NoBackground)
|
||||||
};
|
};
|
||||||
|
|
||||||
button
|
button.on_press(Message::FilterChanged(filter)).padding(8)
|
||||||
.on_press(Message::FilterChanged(filter))
|
|
||||||
.padding(8)
|
|
||||||
.border_radius(10)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Row::new()
|
Row::new()
|
||||||
@ -562,3 +559,39 @@ impl SavedState {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod style {
|
||||||
|
use iced::{button, Background, Color};
|
||||||
|
|
||||||
|
pub enum Button {
|
||||||
|
FilterSelected,
|
||||||
|
NoBackground,
|
||||||
|
Destructive,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl button::StyleSheet for Button {
|
||||||
|
fn active(&self) -> button::Style {
|
||||||
|
match self {
|
||||||
|
Button::FilterSelected => button::Style {
|
||||||
|
background: Some(Background::Color(Color::from_rgb(
|
||||||
|
0.2, 0.2, 0.7,
|
||||||
|
))),
|
||||||
|
border_radius: 10,
|
||||||
|
shadow_offset: 0.0,
|
||||||
|
},
|
||||||
|
Button::NoBackground => button::Style {
|
||||||
|
background: None,
|
||||||
|
border_radius: 0,
|
||||||
|
shadow_offset: 0.0,
|
||||||
|
},
|
||||||
|
Button::Destructive => button::Style {
|
||||||
|
background: Some(Background::Color(Color::from_rgb(
|
||||||
|
0.8, 0.2, 0.2,
|
||||||
|
))),
|
||||||
|
border_radius: 5,
|
||||||
|
shadow_offset: 1.0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -62,8 +62,9 @@ impl Sandbox for Tour {
|
|||||||
|
|
||||||
if steps.has_previous() {
|
if steps.has_previous() {
|
||||||
controls = controls.push(
|
controls = controls.push(
|
||||||
secondary_button(back_button, "Back")
|
button(back_button, "Back")
|
||||||
.on_press(Message::BackPressed),
|
.on_press(Message::BackPressed)
|
||||||
|
.style(style::Button::Secondary),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,8 +72,9 @@ impl Sandbox for Tour {
|
|||||||
|
|
||||||
if steps.can_continue() {
|
if steps.can_continue() {
|
||||||
controls = controls.push(
|
controls = controls.push(
|
||||||
primary_button(next_button, "Next")
|
button(next_button, "Next")
|
||||||
.on_press(Message::NextPressed),
|
.on_press(Message::NextPressed)
|
||||||
|
.style(style::Button::Primary),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -697,24 +699,9 @@ fn button<'a, Message>(
|
|||||||
.horizontal_alignment(HorizontalAlignment::Center),
|
.horizontal_alignment(HorizontalAlignment::Center),
|
||||||
)
|
)
|
||||||
.padding(12)
|
.padding(12)
|
||||||
.border_radius(12)
|
|
||||||
.min_width(100)
|
.min_width(100)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn primary_button<'a, Message>(
|
|
||||||
state: &'a mut button::State,
|
|
||||||
label: &str,
|
|
||||||
) -> Button<'a, Message> {
|
|
||||||
button(state, label).background(Color::from_rgb(0.11, 0.42, 0.87))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn secondary_button<'a, Message>(
|
|
||||||
state: &'a mut button::State,
|
|
||||||
label: &str,
|
|
||||||
) -> Button<'a, Message> {
|
|
||||||
button(state, label).background(Color::from_rgb(0.4, 0.4, 0.4))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum Language {
|
pub enum Language {
|
||||||
Rust,
|
Rust,
|
||||||
@ -757,6 +744,28 @@ pub enum Layout {
|
|||||||
Column,
|
Column,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod style {
|
||||||
|
use iced::{button, Background, Color};
|
||||||
|
|
||||||
|
pub enum Button {
|
||||||
|
Primary,
|
||||||
|
Secondary,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl button::StyleSheet for Button {
|
||||||
|
fn active(&self) -> button::Style {
|
||||||
|
button::Style {
|
||||||
|
background: Some(Background::Color(match self {
|
||||||
|
Button::Primary => Color::from_rgb(0.11, 0.42, 0.87),
|
||||||
|
Button::Secondary => Color::from_rgb(0.5, 0.5, 0.5),
|
||||||
|
})),
|
||||||
|
border_radius: 12,
|
||||||
|
shadow_offset: 1.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This should be gracefully handled by Iced in the future. Probably using our
|
// This should be gracefully handled by Iced in the future. Probably using our
|
||||||
// own proc macro, or maybe the whole process is streamlined by `wasm-pack` at
|
// own proc macro, or maybe the whole process is streamlined by `wasm-pack` at
|
||||||
// some point.
|
// some point.
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
//! [`Windowed`]: renderer/trait.Windowed.html
|
//! [`Windowed`]: renderer/trait.Windowed.html
|
||||||
//! [`UserInterface`]: struct.UserInterface.html
|
//! [`UserInterface`]: struct.UserInterface.html
|
||||||
//! [renderer]: renderer/index.html
|
//! [renderer]: renderer/index.html
|
||||||
#![deny(missing_docs)]
|
//#![deny(missing_docs)]
|
||||||
#![deny(missing_debug_implementations)]
|
#![deny(missing_debug_implementations)]
|
||||||
#![deny(unused_results)]
|
#![deny(unused_results)]
|
||||||
#![deny(unsafe_code)]
|
#![deny(unsafe_code)]
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
button, checkbox, column, radio, row, scrollable, text, text_input,
|
button, checkbox, column, radio, row, scrollable, text, text_input, Color,
|
||||||
Background, Color, Element, Font, HorizontalAlignment, Layout, Point,
|
Element, Font, HorizontalAlignment, Layout, Point, Rectangle, Renderer,
|
||||||
Rectangle, Renderer, Size, VerticalAlignment,
|
Size, VerticalAlignment,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A renderer that does nothing.
|
/// A renderer that does nothing.
|
||||||
@ -117,13 +117,14 @@ impl text_input::Renderer for Null {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl button::Renderer for Null {
|
impl button::Renderer for Null {
|
||||||
|
type Style = ();
|
||||||
|
|
||||||
fn draw(
|
fn draw(
|
||||||
&mut self,
|
&mut self,
|
||||||
_bounds: Rectangle,
|
_bounds: Rectangle,
|
||||||
_cursor_position: Point,
|
_cursor_position: Point,
|
||||||
_is_pressed: bool,
|
_is_pressed: bool,
|
||||||
_background: Option<Background>,
|
_style: &Self::Style,
|
||||||
_border_radius: u16,
|
|
||||||
_content: Self::Output,
|
_content: Self::Output,
|
||||||
) -> Self::Output {
|
) -> Self::Output {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,8 +6,8 @@
|
|||||||
//! [`State`]: struct.State.html
|
//! [`State`]: struct.State.html
|
||||||
use crate::{
|
use crate::{
|
||||||
input::{mouse, ButtonState},
|
input::{mouse, ButtonState},
|
||||||
layout, Background, Clipboard, Element, Event, Hasher, Layout, Length,
|
layout, Clipboard, Element, Event, Hasher, Layout, Length, Point,
|
||||||
Point, Rectangle, Widget,
|
Rectangle, Widget,
|
||||||
};
|
};
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ use std::hash::Hash;
|
|||||||
/// .on_press(Message::ButtonPressed);
|
/// .on_press(Message::ButtonPressed);
|
||||||
/// ```
|
/// ```
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
pub struct Button<'a, Message, Renderer> {
|
pub struct Button<'a, Message, Renderer: self::Renderer> {
|
||||||
state: &'a mut State,
|
state: &'a mut State,
|
||||||
content: Element<'a, Message, Renderer>,
|
content: Element<'a, Message, Renderer>,
|
||||||
on_press: Option<Message>,
|
on_press: Option<Message>,
|
||||||
@ -37,11 +37,13 @@ pub struct Button<'a, Message, Renderer> {
|
|||||||
min_width: u32,
|
min_width: u32,
|
||||||
min_height: u32,
|
min_height: u32,
|
||||||
padding: u16,
|
padding: u16,
|
||||||
background: Option<Background>,
|
style: Renderer::Style,
|
||||||
border_radius: u16,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message, Renderer> Button<'a, Message, Renderer> {
|
impl<'a, Message, Renderer> Button<'a, Message, Renderer>
|
||||||
|
where
|
||||||
|
Renderer: self::Renderer,
|
||||||
|
{
|
||||||
/// Creates a new [`Button`] with some local [`State`] and the given
|
/// Creates a new [`Button`] with some local [`State`] and the given
|
||||||
/// content.
|
/// content.
|
||||||
///
|
///
|
||||||
@ -60,8 +62,7 @@ impl<'a, Message, Renderer> Button<'a, Message, Renderer> {
|
|||||||
min_width: 0,
|
min_width: 0,
|
||||||
min_height: 0,
|
min_height: 0,
|
||||||
padding: 0,
|
padding: 0,
|
||||||
background: None,
|
style: Renderer::Style::default(),
|
||||||
border_radius: 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,23 +106,6 @@ impl<'a, Message, Renderer> Button<'a, Message, Renderer> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the [`Background`] of the [`Button`].
|
|
||||||
///
|
|
||||||
/// [`Button`]: struct.Button.html
|
|
||||||
/// [`Background`]: ../../struct.Background.html
|
|
||||||
pub fn background<T: Into<Background>>(mut self, background: T) -> Self {
|
|
||||||
self.background = Some(background.into());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the border radius of the [`Button`].
|
|
||||||
///
|
|
||||||
/// [`Button`]: struct.Button.html
|
|
||||||
pub fn border_radius(mut self, border_radius: u16) -> Self {
|
|
||||||
self.border_radius = border_radius;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the message that will be produced when the [`Button`] is pressed.
|
/// Sets the message that will be produced when the [`Button`] is pressed.
|
||||||
///
|
///
|
||||||
/// [`Button`]: struct.Button.html
|
/// [`Button`]: struct.Button.html
|
||||||
@ -129,6 +113,11 @@ impl<'a, Message, Renderer> Button<'a, Message, Renderer> {
|
|||||||
self.on_press = Some(msg);
|
self.on_press = Some(msg);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn style(mut self, style: impl Into<Renderer::Style>) -> Self {
|
||||||
|
self.style = style.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The local state of a [`Button`].
|
/// The local state of a [`Button`].
|
||||||
@ -240,8 +229,7 @@ where
|
|||||||
layout.bounds(),
|
layout.bounds(),
|
||||||
cursor_position,
|
cursor_position,
|
||||||
self.state.is_pressed,
|
self.state.is_pressed,
|
||||||
self.background,
|
&self.style,
|
||||||
self.border_radius,
|
|
||||||
content,
|
content,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -260,6 +248,8 @@ where
|
|||||||
/// [`Button`]: struct.Button.html
|
/// [`Button`]: struct.Button.html
|
||||||
/// [renderer]: ../../renderer/index.html
|
/// [renderer]: ../../renderer/index.html
|
||||||
pub trait Renderer: crate::Renderer + Sized {
|
pub trait Renderer: crate::Renderer + Sized {
|
||||||
|
type Style: Default;
|
||||||
|
|
||||||
/// Draws a [`Button`].
|
/// Draws a [`Button`].
|
||||||
///
|
///
|
||||||
/// [`Button`]: struct.Button.html
|
/// [`Button`]: struct.Button.html
|
||||||
@ -268,8 +258,7 @@ pub trait Renderer: crate::Renderer + Sized {
|
|||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
is_pressed: bool,
|
is_pressed: bool,
|
||||||
background: Option<Background>,
|
style: &Self::Style,
|
||||||
border_radius: u16,
|
|
||||||
content: Self::Output,
|
content: Self::Output,
|
||||||
) -> Self::Output;
|
) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -174,7 +174,7 @@
|
|||||||
//! [documentation]: https://docs.rs/iced
|
//! [documentation]: https://docs.rs/iced
|
||||||
//! [examples]: https://github.com/hecrj/iced/tree/master/examples
|
//! [examples]: https://github.com/hecrj/iced/tree/master/examples
|
||||||
//! [`Application`]: trait.Application.html
|
//! [`Application`]: trait.Application.html
|
||||||
#![deny(missing_docs)]
|
//#![deny(missing_docs)]
|
||||||
#![deny(missing_debug_implementations)]
|
#![deny(missing_debug_implementations)]
|
||||||
#![deny(unused_results)]
|
#![deny(unused_results)]
|
||||||
#![deny(unsafe_code)]
|
#![deny(unsafe_code)]
|
||||||
|
|||||||
@ -22,23 +22,7 @@ pub mod widget {
|
|||||||
//!
|
//!
|
||||||
//! [`TextInput`]: text_input/struct.TextInput.html
|
//! [`TextInput`]: text_input/struct.TextInput.html
|
||||||
//! [`text_input::State`]: text_input/struct.State.html
|
//! [`text_input::State`]: text_input/struct.State.html
|
||||||
pub mod button {
|
pub use iced_wgpu::button;
|
||||||
//! Allow your users to perform actions by pressing a button.
|
|
||||||
//!
|
|
||||||
//! A [`Button`] has some local [`State`].
|
|
||||||
//!
|
|
||||||
//! [`Button`]: type.Button.html
|
|
||||||
//! [`State`]: struct.State.html
|
|
||||||
|
|
||||||
/// A widget that produces a message when clicked.
|
|
||||||
///
|
|
||||||
/// This is an alias of an `iced_native` button with a default
|
|
||||||
/// `Renderer`.
|
|
||||||
pub type Button<'a, Message> =
|
|
||||||
iced_winit::Button<'a, Message, iced_wgpu::Renderer>;
|
|
||||||
|
|
||||||
pub use iced_winit::button::State;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub mod scrollable {
|
pub mod scrollable {
|
||||||
//! Navigate an endless amount of content with a scrollbar.
|
//! Navigate an endless amount of content with a scrollbar.
|
||||||
|
|||||||
@ -19,11 +19,13 @@
|
|||||||
//! [`wgpu`]: https://github.com/gfx-rs/wgpu-rs
|
//! [`wgpu`]: https://github.com/gfx-rs/wgpu-rs
|
||||||
//! [WebGPU API]: https://gpuweb.github.io/gpuweb/
|
//! [WebGPU API]: https://gpuweb.github.io/gpuweb/
|
||||||
//! [`wgpu_glyph`]: https://github.com/hecrj/wgpu_glyph
|
//! [`wgpu_glyph`]: https://github.com/hecrj/wgpu_glyph
|
||||||
#![deny(missing_docs)]
|
//#![deny(missing_docs)]
|
||||||
#![deny(missing_debug_implementations)]
|
#![deny(missing_debug_implementations)]
|
||||||
#![deny(unused_results)]
|
#![deny(unused_results)]
|
||||||
#![deny(unsafe_code)]
|
#![deny(unsafe_code)]
|
||||||
#![deny(rust_2018_idioms)]
|
#![deny(rust_2018_idioms)]
|
||||||
|
pub mod widget;
|
||||||
|
|
||||||
mod image;
|
mod image;
|
||||||
mod primitive;
|
mod primitive;
|
||||||
mod quad;
|
mod quad;
|
||||||
@ -31,9 +33,11 @@ mod renderer;
|
|||||||
mod text;
|
mod text;
|
||||||
mod transformation;
|
mod transformation;
|
||||||
|
|
||||||
pub(crate) use crate::image::Image;
|
|
||||||
pub(crate) use quad::Quad;
|
|
||||||
pub(crate) use transformation::Transformation;
|
|
||||||
|
|
||||||
pub use primitive::Primitive;
|
pub use primitive::Primitive;
|
||||||
pub use renderer::{Renderer, Target};
|
pub use renderer::{Renderer, Target};
|
||||||
|
#[doc(no_inline)]
|
||||||
|
pub use widget::*;
|
||||||
|
|
||||||
|
pub(crate) use self::image::Image;
|
||||||
|
pub(crate) use quad::Quad;
|
||||||
|
pub(crate) use transformation::Transformation;
|
||||||
|
|||||||
@ -22,7 +22,7 @@ pub struct Renderer {
|
|||||||
device: Device,
|
device: Device,
|
||||||
queue: Queue,
|
queue: Queue,
|
||||||
quad_pipeline: quad::Pipeline,
|
quad_pipeline: quad::Pipeline,
|
||||||
image_pipeline: crate::image::Pipeline,
|
image_pipeline: image::Pipeline,
|
||||||
text_pipeline: text::Pipeline,
|
text_pipeline: text::Pipeline,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ impl Renderer {
|
|||||||
|
|
||||||
let text_pipeline = text::Pipeline::new(&mut device);
|
let text_pipeline = text::Pipeline::new(&mut device);
|
||||||
let quad_pipeline = quad::Pipeline::new(&mut device);
|
let quad_pipeline = quad::Pipeline::new(&mut device);
|
||||||
let image_pipeline = crate::image::Pipeline::new(&mut device);
|
let image_pipeline = image::Pipeline::new(&mut device);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
device,
|
device,
|
||||||
|
|||||||
@ -1,50 +1,50 @@
|
|||||||
use crate::{Primitive, Renderer};
|
use crate::{button::StyleSheet, Primitive, Renderer};
|
||||||
use iced_native::{button, Background, MouseCursor, Point, Rectangle};
|
use iced_native::{Background, MouseCursor, Point, Rectangle};
|
||||||
|
|
||||||
|
impl iced_native::button::Renderer for Renderer {
|
||||||
|
type Style = Box<dyn StyleSheet>;
|
||||||
|
|
||||||
impl button::Renderer for Renderer {
|
|
||||||
fn draw(
|
fn draw(
|
||||||
&mut self,
|
&mut self,
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
is_pressed: bool,
|
is_pressed: bool,
|
||||||
background: Option<Background>,
|
style: &Box<dyn StyleSheet>,
|
||||||
border_radius: u16,
|
|
||||||
(content, _): Self::Output,
|
(content, _): Self::Output,
|
||||||
) -> Self::Output {
|
) -> Self::Output {
|
||||||
let is_mouse_over = bounds.contains(cursor_position);
|
let is_mouse_over = bounds.contains(cursor_position);
|
||||||
|
|
||||||
// TODO: Render proper shadows
|
// TODO: Render proper shadows
|
||||||
// TODO: Make hovering and pressed styles configurable
|
let styling = if is_mouse_over {
|
||||||
let shadow_offset = if is_mouse_over {
|
|
||||||
if is_pressed {
|
if is_pressed {
|
||||||
0.0
|
style.pressed()
|
||||||
} else {
|
} else {
|
||||||
2.0
|
style.hovered()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
1.0
|
style.active()
|
||||||
};
|
};
|
||||||
|
|
||||||
(
|
(
|
||||||
match background {
|
match styling.background {
|
||||||
None => content,
|
None => content,
|
||||||
Some(background) => Primitive::Group {
|
Some(background) => Primitive::Group {
|
||||||
primitives: vec![
|
primitives: vec![
|
||||||
Primitive::Quad {
|
Primitive::Quad {
|
||||||
bounds: Rectangle {
|
bounds: Rectangle {
|
||||||
x: bounds.x + 1.0,
|
x: bounds.x + 1.0,
|
||||||
y: bounds.y + shadow_offset,
|
y: bounds.y + styling.shadow_offset,
|
||||||
..bounds
|
..bounds
|
||||||
},
|
},
|
||||||
background: Background::Color(
|
background: Background::Color(
|
||||||
[0.0, 0.0, 0.0, 0.5].into(),
|
[0.0, 0.0, 0.0, 0.5].into(),
|
||||||
),
|
),
|
||||||
border_radius,
|
border_radius: styling.border_radius,
|
||||||
},
|
},
|
||||||
Primitive::Quad {
|
Primitive::Quad {
|
||||||
bounds,
|
bounds,
|
||||||
background,
|
background,
|
||||||
border_radius,
|
border_radius: styling.border_radius,
|
||||||
},
|
},
|
||||||
content,
|
content,
|
||||||
],
|
],
|
||||||
|
|||||||
1
wgpu/src/renderer/widget/button/style.rs
Normal file
1
wgpu/src/renderer/widget/button/style.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
1
wgpu/src/widget.rs
Normal file
1
wgpu/src/widget.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod button;
|
||||||
97
wgpu/src/widget/button.rs
Normal file
97
wgpu/src/widget/button.rs
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
//! Allow your users to perform actions by pressing a button.
|
||||||
|
//!
|
||||||
|
//! A [`Button`] has some local [`State`].
|
||||||
|
//!
|
||||||
|
//! [`Button`]: type.Button.html
|
||||||
|
//! [`State`]: struct.State.html
|
||||||
|
use crate::Renderer;
|
||||||
|
use iced_native::Background;
|
||||||
|
|
||||||
|
pub use iced_native::button::State;
|
||||||
|
|
||||||
|
/// 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> = iced_native::Button<'a, Message, Renderer>;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Style {
|
||||||
|
pub shadow_offset: f32,
|
||||||
|
pub background: Option<Background>,
|
||||||
|
pub border_radius: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait StyleSheet {
|
||||||
|
fn active(&self) -> Style;
|
||||||
|
|
||||||
|
fn hovered(&self) -> Style {
|
||||||
|
let active = self.active();
|
||||||
|
|
||||||
|
Style {
|
||||||
|
shadow_offset: active.shadow_offset + 1.0,
|
||||||
|
..active
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pressed(&self) -> Style {
|
||||||
|
Style {
|
||||||
|
shadow_offset: 0.0,
|
||||||
|
..self.active()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn disabled(&self) -> Style {
|
||||||
|
self.active()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Default;
|
||||||
|
|
||||||
|
impl StyleSheet for Default {
|
||||||
|
fn active(&self) -> Style {
|
||||||
|
Style {
|
||||||
|
shadow_offset: 1.0,
|
||||||
|
background: Some(Background::Color([0.5, 0.5, 0.5].into())),
|
||||||
|
border_radius: 5,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hovered(&self) -> Style {
|
||||||
|
Style {
|
||||||
|
shadow_offset: 2.0,
|
||||||
|
background: Some(Background::Color([0.5, 0.5, 0.5].into())),
|
||||||
|
border_radius: 5,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pressed(&self) -> Style {
|
||||||
|
Style {
|
||||||
|
shadow_offset: 0.0,
|
||||||
|
background: Some(Background::Color([0.5, 0.5, 0.5].into())),
|
||||||
|
border_radius: 5,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn disabled(&self) -> Style {
|
||||||
|
Style {
|
||||||
|
shadow_offset: 0.0,
|
||||||
|
background: Some(Background::Color([0.7, 0.7, 0.7].into())),
|
||||||
|
border_radius: 5,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::default::Default for Box<dyn StyleSheet> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Box::new(Default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<T> for Box<dyn StyleSheet>
|
||||||
|
where
|
||||||
|
T: 'static + StyleSheet,
|
||||||
|
{
|
||||||
|
fn from(style: T) -> Self {
|
||||||
|
Box::new(style)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user