use crate::prelude::*;
pub struct Button<'a, ID> {
region: &'a Region<ID>,
label: &'a str,
border: Option<(u8, u8)>,
}
impl<'a, ID: WidgetId> Button<'a, ID> {
pub const fn new(region: &'a Region<ID>, label: &'a str) -> Button<'a, ID> {
Button {
region,
label,
border: None,
}
}
pub const fn with_border(mut self, border: u8, radius: u8) -> Self {
self.border = Some((border, radius));
self
}
}
impl<DRAW: DrawTarget<Color = COL>, ID: WidgetId, COL: PixelColor> Widget<DRAW, COL>
for Button<'_, ID>
{
fn draw(&mut self, ui: &mut Ui<DRAW, COL>) -> GuiResult<Response> {
#[allow(unused_mut)]
let mut interaction = ui.check_interact(self.region);
let widget_id = self.region.id();
#[cfg(feature = "focus")]
let focused = ui.check_focused(widget_id);
let prevstate = ui.get_widget_state(widget_id)?.status();
let next_state;
match interaction {
Interaction::None => {
#[cfg(feature = "focus")]
{
use crate::focus::Focused;
match focused {
Focused::No => {
next_state = RenderStatus::Rendered;
}
Focused::Yes => {
next_state = RenderStatus::Focused;
interaction = focused.into();
}
Focused::Trigger => {
interaction = focused.into();
next_state = RenderStatus::Triggered;
}
}
}
#[cfg(not(feature = "focus"))]
{
next_state = RenderStatus::Rendered;
}
}
Interaction::Pressed(_) | Interaction::Drag(_) => {
next_state = RenderStatus::Pressed;
}
Interaction::Release(pos) | Interaction::Clicked(pos) => {
next_state = RenderStatus::Released;
interaction = Interaction::Clicked(pos);
}
};
if next_state == prevstate {
return Ok(interaction.into());
}
ui.get_widget_state(widget_id)?.set_status(next_state);
let area = self.region.rectangle();
let font = ui.style().default_font;
let mut text = matrix_utils::make_text(self.label, font, ui.style().text_color);
let (border_width, corner_radius) = self
.border
.unwrap_or((ui.style().border_width, ui.style().corner_radius));
let border_width = border_width as u32;
let corner_radius = corner_radius as u32;
let rounded_rect = matrix_utils::make_rounded_rect(&area, corner_radius);
ui.clear_area(&area)?;
let rect_style = match interaction {
Interaction::None => PrimitiveStyleBuilder::new()
.stroke_color(ui.style().border_color)
.stroke_width(border_width)
.fill_color(ui.style().background_color)
.build(),
_ => {
text.character_style.text_color = ui.style().background_color;
PrimitiveStyleBuilder::new()
.stroke_color(ui.style().background_color)
.stroke_width(border_width)
.fill_color(ui.style().border_color)
.build()
}
};
ui.draw(&rounded_rect.into_styled(rect_style)).ok();
matrix_utils::text_align_translate(&mut text, &area, HorizontalAlign::Center);
ui.draw(&text).ok();
Ok(interaction.into())
}
}