use crate::render::{RenderContext, TextAlign, TextBaseline};
use crate::types::{Rect, WidgetState};
use crate::ui::widgets::atomic::button::state::SplitButtonHoverZone;
use super::settings::DropdownTriggerSettings;
use super::style::{DropdownFieldStyle, SplitDropdownStyle};
use super::theme::DropdownTriggerTheme;
use super::types::{DropdownFieldView, DropdownTriggerRenderKind, SplitDropdownView};
pub fn draw_dropdown_trigger(
ctx: &mut dyn RenderContext,
rect: Rect,
state: WidgetState,
settings: &DropdownTriggerSettings,
kind: &DropdownTriggerRenderKind<'_>,
) -> (Rect, Rect) {
match kind {
DropdownTriggerRenderKind::Split => {
let _ = state;
(rect, rect)
}
DropdownTriggerRenderKind::Field => {
let _ = state;
(rect, rect)
}
DropdownTriggerRenderKind::Custom(f) => {
f(ctx, rect, state, settings);
(rect, rect)
}
}
}
pub fn draw_split_dropdown(
ctx: &mut dyn RenderContext,
rect: Rect,
view: &SplitDropdownView<'_>,
font: &str,
style: &dyn SplitDropdownStyle,
theme: &dyn DropdownTriggerTheme,
) -> (Rect, Rect) {
let cw = style.chevron_width();
let text_w = rect.width - cw;
let text_rect = Rect::new(rect.x, rect.y, text_w, rect.height);
let chev_rect = Rect::new(rect.x + text_w, rect.y, cw, rect.height);
let r = style.radius();
let bw = style.border_width();
ctx.set_fill_color(theme.dropdown_field_bg());
ctx.fill_rounded_rect(rect.x, rect.y, rect.width, rect.height, r);
match view.hovered_zone {
SplitButtonHoverZone::Main => {
ctx.set_fill_color(theme.dropdown_field_bg_hover());
ctx.save();
ctx.clip_rect(rect.x, rect.y, text_w, rect.height);
ctx.fill_rounded_rect(rect.x, rect.y, rect.width, rect.height, r);
ctx.restore();
}
SplitButtonHoverZone::Chevron => {
ctx.set_fill_color(theme.dropdown_field_bg_hover());
ctx.save();
ctx.clip_rect(rect.x + text_w, rect.y, cw, rect.height);
ctx.fill_rounded_rect(rect.x, rect.y, rect.width, rect.height, r);
ctx.restore();
}
SplitButtonHoverZone::None => {}
}
ctx.set_stroke_color(theme.dropdown_field_border());
ctx.set_stroke_width(bw);
ctx.set_line_dash(&[]);
ctx.stroke_rounded_rect(rect.x, rect.y, rect.width, rect.height, r);
ctx.set_font(font);
ctx.set_text_align(TextAlign::Left);
ctx.set_text_baseline(TextBaseline::Middle);
ctx.set_fill_color(theme.dropdown_field_text());
ctx.fill_text(view.current_label, rect.x + style.text_padding_x(), rect.center_y());
ctx.set_stroke_color(theme.dropdown_field_border());
ctx.set_stroke_width(bw);
ctx.set_line_dash(&[]);
ctx.begin_path();
ctx.move_to(rect.x + text_w, rect.y);
ctx.line_to(rect.x + text_w, rect.y + rect.height);
ctx.stroke();
let arrow_cx = chev_rect.center_x();
let arrow_cy = chev_rect.center_y();
let hb = 3.0_f64;
let ah = 3.0_f64;
ctx.set_fill_color(theme.dropdown_chevron_color());
ctx.begin_path();
ctx.move_to(arrow_cx - hb, arrow_cy - ah);
ctx.line_to(arrow_cx + hb, arrow_cy - ah);
ctx.line_to(arrow_cx, arrow_cy + ah);
ctx.close_path();
ctx.fill();
(text_rect, chev_rect)
}
pub fn draw_dropdown_field(
ctx: &mut dyn RenderContext,
rect: Rect,
view: &DropdownFieldView<'_>,
font: &str,
style: &dyn DropdownFieldStyle,
theme: &dyn DropdownTriggerTheme,
) -> Rect {
let r = style.radius();
let bw = style.border_width();
let cs = style.chevron_size();
let cmr = style.chevron_margin_right();
let bg = if view.hovered || view.open {
theme.dropdown_field_bg_hover()
} else {
theme.dropdown_field_bg()
};
ctx.set_fill_color(bg);
ctx.fill_rounded_rect(rect.x, rect.y, rect.width, rect.height, r);
ctx.set_stroke_color(theme.dropdown_field_border());
ctx.set_stroke_width(bw);
ctx.set_line_dash(&[]);
ctx.stroke_rounded_rect(rect.x, rect.y, rect.width, rect.height, r);
ctx.set_font(font);
ctx.set_text_align(TextAlign::Left);
ctx.set_text_baseline(TextBaseline::Middle);
ctx.set_fill_color(theme.dropdown_field_text());
ctx.fill_text(view.current_label, rect.x + style.text_padding_x(), rect.center_y());
let arrow_x = rect.x + rect.width - cs - cmr;
let arrow_cy = rect.center_y();
let hb = cs / 4.0;
let ah = cs / 4.0;
let acx = arrow_x + cs / 2.0;
ctx.set_fill_color(theme.dropdown_chevron_color());
ctx.begin_path();
ctx.move_to(acx - hb, arrow_cy - ah);
ctx.line_to(acx + hb, arrow_cy - ah);
ctx.line_to(acx, arrow_cy + ah);
ctx.close_path();
ctx.fill();
rect
}