mod button;
mod icon_button;
mod split_button;
mod variant;
pub use button::{Button, ButtonExt};
pub use icon_button::IconButton;
pub use split_button::SplitButton;
pub use variant::ButtonVariant;
use crate::theming;
use crate::tokens::DESIGN_TOKENS;
use egui::{Color32, Pos2, Response, Sense, Ui, Vec2};
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub enum ButtonSize {
SM,
#[default]
MD,
LG,
XL,
}
impl ButtonSize {
#[inline]
pub fn pixels(&self) -> f32 {
match self {
ButtonSize::SM => DESIGN_TOKENS.sizing.button_sm,
ButtonSize::MD => DESIGN_TOKENS.sizing.button_md,
ButtonSize::LG => DESIGN_TOKENS.sizing.button_lg,
ButtonSize::XL => DESIGN_TOKENS.sizing.button_xl,
}
}
}
pub fn button_bg(ui: &Ui, hovered: bool, selected: bool) -> Color32 {
if selected && hovered {
theming::active_hover_color(ui)
} else if selected {
theming::sel_color(ui)
} else if hovered {
theming::hover_color(ui)
} else {
Color32::TRANSPARENT
}
}
pub fn icon_color(ui: &Ui, hovered: bool, selected: bool) -> Color32 {
let visuals = &ui.style().visuals;
if selected || hovered {
visuals.widgets.active.fg_stroke.color
} else {
visuals.widgets.noninteractive.fg_stroke.color
}
}
pub fn dialog_close_button(ui: &mut Ui) -> Response {
let btn_size = Vec2::splat(DESIGN_TOKENS.sizing.icon_xl);
let (rect, response) = ui.allocate_exact_size(btn_size, Sense::click());
let is_hovered = response.hovered();
let stroke_color = if is_hovered {
ui.style().visuals.selection.bg_fill
} else {
ui.style().visuals.selection.bg_fill.gamma_multiply(0.7)
};
let stroke_width = DESIGN_TOKENS.spacing.hairline + 0.5;
ui.painter().rect_stroke(
rect,
DESIGN_TOKENS.rounding.sm,
egui::Stroke::new(stroke_width, stroke_color),
egui::StrokeKind::Inside,
);
let center = rect.center();
let half = DESIGN_TOKENS.spacing.sm + 1.0;
ui.painter().line_segment(
[
Pos2::new(center.x - half, center.y - half),
Pos2::new(center.x + half, center.y + half),
],
egui::Stroke::new(stroke_width, stroke_color),
);
ui.painter().line_segment(
[
Pos2::new(center.x + half, center.y - half),
Pos2::new(center.x - half, center.y + half),
],
egui::Stroke::new(stroke_width, stroke_color),
);
response
}