Make iced_core::Button customizable
Now it supports: - Any kind of content - Custom border radius - Custom background
This commit is contained in:
parent
a0234d5bce
commit
10e10e5e06
35 changed files with 288 additions and 160 deletions
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue