use egui::{
Color32, CursorIcon, Response, RichText, Sense, Shape, Stroke, TextStyle, Ui, WidgetText, vec2,
};
use crate::ui::windows::midi_controllers::rules::{Piece, TokenKind};
pub(crate) fn token_color(kind: TokenKind) -> Color32 {
match kind {
TokenKind::Main => Color32::from_rgb(94, 194, 122),
TokenKind::Target => Color32::from_rgb(110, 168, 254),
TokenKind::Effect | TokenKind::Setting | TokenKind::Animation | TokenKind::Parameter => {
Color32::from_rgb(180, 140, 250)
}
TokenKind::Mode => Color32::from_rgb(240, 180, 80),
TokenKind::Encoder | TokenKind::Beat | TokenKind::Blackout => {
Color32::from_rgb(90, 200, 200)
}
}
}
pub(crate) fn token(ui: &mut Ui, text: &str, color: Color32) -> Response {
let galley =
WidgetText::from(RichText::new(text)).into_galley(ui, None, f32::INFINITY, TextStyle::Body);
let (rect, response) = ui.allocate_exact_size(galley.size() + vec2(0.0, 2.0), Sense::click());
if ui.is_rect_visible(rect) {
let color = if response.hovered() || response.has_focus() {
color.gamma_multiply(1.3)
} else {
color
};
ui.painter().galley(rect.min, galley, color);
let underline = rect.bottom() - 1.0;
ui.painter().add(Shape::dashed_line(
&[
egui::pos2(rect.left(), underline),
egui::pos2(rect.right(), underline),
],
Stroke::new(1.0, color.gamma_multiply(0.7)),
3.0,
2.0,
));
}
response.on_hover_cursor(CursorIcon::PointingHand)
}
pub(crate) fn sentence(ui: &mut Ui, pieces: &[Piece]) -> Vec<(TokenKind, Response)> {
let mut tokens = Vec::new();
for piece in pieces {
match piece {
Piece::Text(text) => {
ui.label(text.trim());
}
Piece::Token { kind, text } => {
tokens.push((*kind, token(ui, text, token_color(*kind))))
}
}
}
tokens
}