use crate::{default::UiState, prelude::*}; use std::time::{Duration, Instant}; use winit::dpi::{LogicalPosition, LogicalSize}; event_ctx!(UiState); pub struct Selector; impl WidgetAttr for Selector { type Input = WidgetRef; fn run(ui: &mut Ui, container: WidgetRef, id: Self::Input) { container.on(CursorSense::click_or_drag(), move |ctx| { let ui = &mut ctx.data.ui; let region = ui.window_region(&id).unwrap(); let id_pos = region.top_left; let container_pos = ui.window_region(&container).unwrap().top_left; let pos = ctx.data.pos + container_pos - id_pos; let size = region.size(); select(ui, id, ctx.state, pos, size, ctx.data.sense.is_dragging()); }); } } pub struct Selectable; impl WidgetAttr for Selectable { type Input = (); fn run(ui: &mut Ui, id: WidgetRef, _: Self::Input) { id.on(CursorSense::click_or_drag(), move |ctx| { select( ctx.data.ui, id, ctx.state, ctx.data.pos, ctx.data.size, ctx.data.sense.is_dragging(), ); }); } } fn select( ui: &mut Ui, id: WidgetRef, state: &mut UiState, pos: Vec2, size: Vec2, dragging: bool, ) { let now = Instant::now(); let recent = (now - state.last_click) < Duration::from_millis(300); state.last_click = now; id.get_mut().select(pos, size, dragging, recent); if let Some(region) = ui.window_region(&id) { state.window.set_ime_allowed(true); state.window.set_ime_cursor_area( LogicalPosition::::from(region.top_left.tuple()), LogicalSize::::from(region.size().tuple()), ); } state.focus = Some(id); }