fix(button): image button rendering fixes

This commit is contained in:
Michael Aaron Murphy 2023-11-11 01:10:05 +01:00 committed by Michael Murphy
parent 6c7a080209
commit 14614e4e03
4 changed files with 64 additions and 40 deletions

View file

@ -82,7 +82,7 @@ pub fn appearance(
} }
Button::Image => { Button::Image => {
appearance.background = Some(Background::Color(cosmic.bg_color().into())); appearance.background = None;
appearance.text_color = Some(cosmic.accent.base.into()); appearance.text_color = Some(cosmic.accent.base.into());
appearance.icon_color = Some(cosmic.accent.base.into()); appearance.icon_color = Some(cosmic.accent.base.into());
@ -90,7 +90,7 @@ pub fn appearance(
appearance.border_radius = (*corner_radii).into(); appearance.border_radius = (*corner_radii).into();
if focused { if focused {
appearance.border_width = 3.0; appearance.border_width = 2.0;
appearance.border_color = cosmic.accent.base.into(); appearance.border_color = cosmic.accent.base.into();
} }
@ -178,13 +178,18 @@ impl StyleSheet for crate::Theme {
return hovered(focused, self); return hovered(focused, self);
} }
appearance(self, focused, style, |component| { appearance(
( self,
component.hover.into(), focused || matches!(style, Button::Image),
Some(component.on.into()), style,
Some(component.on.into()), |component| {
) (
}) component.hover.into(),
Some(component.on.into()),
Some(component.on.into()),
)
},
)
} }
fn pressed(&self, focused: bool, style: &Self::Style) -> Appearance { fn pressed(&self, focused: bool, style: &Self::Style) -> Appearance {
@ -200,4 +205,8 @@ impl StyleSheet for crate::Theme {
) )
}) })
} }
fn selection_background(&self) -> Background {
Background::Color(self.cosmic().bg_color().into())
}
} }

View file

@ -62,9 +62,9 @@ where
.width(builder.width) .width(builder.width)
.height(builder.height) .height(builder.height)
.apply(widget::button) .apply(widget::button)
.padding(0)
.selected(builder.variant.selected) .selected(builder.variant.selected)
.id(builder.id) .id(builder.id)
.padding(0)
.on_press_maybe(builder.on_press) .on_press_maybe(builder.on_press)
.style(builder.style) .style(builder.style)
.into() .into()

View file

@ -80,4 +80,7 @@ pub trait StyleSheet {
/// Produces the pressed [`Appearance`] of a button. /// Produces the pressed [`Appearance`] of a button.
fn pressed(&self, focused: bool, style: &Self::Style) -> Appearance; fn pressed(&self, focused: bool, style: &Self::Style) -> Appearance;
/// Background color of the selection indicator
fn selection_background(&self) -> Background;
} }

View file

@ -154,7 +154,7 @@ where
/// Sets the widget to a selected state. /// Sets the widget to a selected state.
/// ///
/// Displays a selection indicator on image buttons. /// Displays a selection indicator on image buttons.
pub(super) fn selected(mut self, selected: bool) -> Self { pub fn selected(mut self, selected: bool) -> Self {
self.selected = selected.then(|| Selected { self.selected = selected.then(|| Selected {
icon: crate::widget::icon::from_name("object-select-symbolic") icon: crate::widget::icon::from_name("object-select-symbolic")
.size(16) .size(16)
@ -323,20 +323,21 @@ where
theme, theme,
&self.style, &self.style,
|| tree.state.downcast_ref::<State>(), || tree.state.downcast_ref::<State>(),
); |renderer, styling| {
self.content.as_widget().draw(
self.content.as_widget().draw( &tree.children[0],
&tree.children[0], renderer,
renderer, theme,
theme, &renderer::Style {
&renderer::Style { icon_color: styling.icon_color.unwrap_or(renderer_style.icon_color),
icon_color: styling.icon_color.unwrap_or(renderer_style.icon_color), text_color: styling.text_color.unwrap_or(renderer_style.icon_color),
text_color: styling.text_color.unwrap_or(renderer_style.icon_color), scale_factor: renderer_style.scale_factor,
scale_factor: renderer_style.scale_factor, },
content_layout,
cursor,
&bounds,
);
}, },
content_layout,
cursor,
&bounds,
); );
if let Some(ref selected) = self.selected { if let Some(ref selected) = self.selected {
@ -345,16 +346,14 @@ where
bounds: Rectangle { bounds: Rectangle {
width: 24.0, width: 24.0,
height: 20.0, height: 20.0,
x: bounds.x, x: bounds.x + styling.border_width,
y: bounds.y + (bounds.height - 20.0), y: bounds.y + (bounds.height - 20.0 - styling.border_width),
}, },
border_radius: [0.0, 8.0, 0.0, 8.0].into(), border_radius: [0.0, 8.0, 0.0, 8.0].into(),
border_width: 0.0, border_width: 0.0,
border_color: Color::TRANSPARENT, border_color: Color::TRANSPARENT,
}, },
styling theme.selection_background(),
.background
.unwrap_or(Background::Color(Color::TRANSPARENT)),
); );
iced_core::svg::Renderer::draw( iced_core::svg::Renderer::draw(
@ -364,8 +363,8 @@ where
Rectangle { Rectangle {
width: 16.0, width: 16.0,
height: 16.0, height: 16.0,
x: bounds.x + 4.0, x: bounds.x + 5.0 + styling.border_width,
y: bounds.y + (bounds.height - 16.0), y: bounds.y + (bounds.height - 18.0 - styling.border_width),
}, },
); );
} }
@ -604,6 +603,7 @@ pub fn draw<'a, Renderer: iced_core::Renderer>(
style_sheet: &dyn StyleSheet<Style = <Renderer::Theme as StyleSheet>::Style>, style_sheet: &dyn StyleSheet<Style = <Renderer::Theme as StyleSheet>::Style>,
style: &<Renderer::Theme as StyleSheet>::Style, style: &<Renderer::Theme as StyleSheet>::Style,
state: impl FnOnce() -> &'a State, state: impl FnOnce() -> &'a State,
draw_contents: impl FnOnce(&mut Renderer, Appearance),
) -> Appearance ) -> Appearance
where where
Renderer::Theme: StyleSheet, Renderer::Theme: StyleSheet,
@ -663,22 +663,34 @@ where
); );
} }
// Draw the button background first.
if let Some(background) = styling.background {
renderer.fill_quad(
renderer::Quad {
bounds,
border_radius: styling.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
},
background,
);
}
// Then draw the button contents onto the background.
draw_contents(renderer, styling);
// Finish by drawing the border above the contents.
renderer.fill_quad( renderer.fill_quad(
renderer::Quad { renderer::Quad {
bounds: Rectangle { bounds,
x: bounds.x + if is_selected { -1.0 } else { 0.0 },
y: bounds.y + if is_selected { -1.0 } else { 0.0 },
width: bounds.width + if is_selected { 2.0 } else { 0.0 },
height: bounds.height + if is_selected { 2.0 } else { 0.0 },
},
border_radius: styling.border_radius, border_radius: styling.border_radius,
border_width: styling.border_width, border_width: styling.border_width,
border_color: styling.border_color, border_color: styling.border_color,
}, },
styling Color::TRANSPARENT,
.background
.unwrap_or(Background::Color(Color::TRANSPARENT)),
); );
} else {
draw_contents(renderer, styling);
} }
styling styling