use crate::render::{RenderContext, TextAlign, TextBaseline};
use crate::types::{Rect, WidgetState};
use super::settings::ShapeSelectorSettings;
use super::style::SelectorButtonStyle;
use super::theme::ShapeSelectorTheme;
use super::types::{ShapeSelectorRenderKind, ShapeSelectorView, ThemePresetView, UIStyleView};
pub fn draw_shape_selector(
ctx: &mut dyn RenderContext,
rect: Rect,
state: WidgetState,
settings: &ShapeSelectorSettings,
kind: &ShapeSelectorRenderKind<'_>,
) {
match kind {
ShapeSelectorRenderKind::Shape
| ShapeSelectorRenderKind::ThemePreset
| ShapeSelectorRenderKind::UIStyle => {
let _ = (ctx, rect, state, settings);
}
ShapeSelectorRenderKind::Custom(f) => {
f(ctx, rect, state, settings);
}
}
}
pub fn draw_shape_selector_button<F>(
ctx: &mut dyn RenderContext,
rect: Rect,
view: &ShapeSelectorView<'_>,
font: &str,
style: &dyn SelectorButtonStyle,
theme: &dyn ShapeSelectorTheme,
draw_shape: F,
)
where
F: FnOnce(&mut dyn RenderContext, Rect, &str),
{
let r = style.radius();
let bg = if view.selected {
theme.selector_active_bg()
} else if view.hovered {
theme.selector_hover_bg()
} else {
theme.selector_idle_bg()
};
ctx.set_fill_color(bg);
ctx.fill_rounded_rect(rect.x, rect.y, rect.width, rect.height, r);
let (border_color, border_w) = if view.selected {
(theme.selector_selected_border(), style.selected_border_width())
} else if view.hovered {
(theme.selector_hover_border(), style.border_width())
} else {
(theme.selector_idle_border(), style.border_width())
};
ctx.set_stroke_color(border_color);
ctx.set_stroke_width(border_w);
ctx.set_line_dash(&[]);
ctx.stroke_rounded_rect(rect.x, rect.y, rect.width, rect.height, r);
let inset = 3.0_f64;
let inner = Rect::new(
rect.x + inset,
rect.y + inset,
(rect.width - inset * 2.0).max(0.0),
(rect.height - inset * 2.0).max(0.0),
);
let shape_color = if view.selected {
theme.selector_active_text()
} else {
theme.selector_idle_text()
};
draw_shape(ctx, inner, shape_color);
if let Some(label) = view.label {
ctx.set_font(font);
ctx.set_fill_color(theme.selector_label_text());
ctx.set_text_align(TextAlign::Center);
ctx.set_text_baseline(TextBaseline::Top);
ctx.fill_text(
label,
rect.center_x(),
rect.y + rect.height + style.label_gap(),
);
}
}
pub fn draw_theme_preset_button(
ctx: &mut dyn RenderContext,
rect: Rect,
view: &ThemePresetView<'_>,
font: &str,
style: &dyn SelectorButtonStyle,
theme: &dyn ShapeSelectorTheme,
) {
let r = style.radius();
let bg = if view.selected {
theme.selector_active_bg()
} else if view.hovered {
theme.selector_hover_bg()
} else {
theme.selector_idle_bg()
};
ctx.set_fill_color(bg);
ctx.fill_rounded_rect(rect.x, rect.y, rect.width, rect.height, r);
let (border_color, border_w) = if view.selected {
(theme.selector_selected_border(), style.selected_border_width())
} else if view.hovered {
(theme.selector_hover_border(), style.border_width())
} else {
(theme.selector_idle_border(), style.border_width())
};
ctx.set_stroke_color(border_color);
ctx.set_stroke_width(border_w);
ctx.set_line_dash(&[]);
ctx.stroke_rounded_rect(rect.x, rect.y, rect.width, rect.height, r);
const SWATCH_SIZE: f64 = 18.0;
let swatch_x = rect.x + 6.0;
let swatch_y = rect.center_y() - SWATCH_SIZE / 2.0;
ctx.set_fill_color(view.preview_color);
ctx.fill_rect(swatch_x, swatch_y, SWATCH_SIZE, SWATCH_SIZE);
ctx.set_stroke_color(view.swatch_border_color);
ctx.set_stroke_width(1.0);
ctx.set_line_dash(&[]);
ctx.stroke_rect(swatch_x, swatch_y, SWATCH_SIZE, SWATCH_SIZE);
let text_color = if view.selected {
theme.selector_active_text()
} else {
theme.selector_label_text()
};
ctx.set_font(font);
ctx.set_fill_color(text_color);
ctx.set_text_align(TextAlign::Left);
ctx.set_text_baseline(TextBaseline::Middle);
ctx.fill_text(view.label, rect.x + 30.0, rect.center_y());
}
pub fn draw_ui_style_button(
ctx: &mut dyn RenderContext,
rect: Rect,
view: &UIStyleView<'_>,
font: &str,
style: &dyn SelectorButtonStyle,
theme: &dyn ShapeSelectorTheme,
) {
let r = style.radius();
let bg = if view.selected {
theme.selector_active_bg()
} else if view.hovered {
theme.selector_hover_bg()
} else {
theme.selector_idle_bg()
};
ctx.set_fill_color(bg);
ctx.fill_rounded_rect(rect.x, rect.y, rect.width, rect.height, r);
let (border_color, border_w) = if view.selected {
(theme.selector_selected_border(), style.selected_border_width())
} else if view.hovered {
(theme.selector_hover_border(), style.border_width())
} else {
(theme.selector_idle_border(), style.border_width())
};
ctx.set_stroke_color(border_color);
ctx.set_stroke_width(border_w);
ctx.set_line_dash(&[]);
ctx.stroke_rounded_rect(rect.x, rect.y, rect.width, rect.height, r);
let text_color = if view.selected {
theme.selector_active_text()
} else {
theme.selector_label_text()
};
ctx.set_font(font);
ctx.set_fill_color(text_color);
ctx.set_text_align(TextAlign::Center);
ctx.set_text_baseline(TextBaseline::Middle);
ctx.fill_text(view.label, rect.center_x(), rect.center_y());
}