use crate::{prelude::*, winit::UiState}; use std::time::{Duration, Instant}; use winit::dpi::{LogicalPosition, LogicalSize}; pub struct Selector; impl WidgetAttr for Selector { type Input = WidgetRef; fn run(ui: &mut Ui, container: &WidgetRef, id: Self::Input) { let container = container.clone(); ui.register_event( &container.clone(), CursorSense::click_or_drag(), move |mut ctx| { let ui = ctx.ui; let region = ui.window_region(&id).unwrap(); let id_pos = region.top_left; let container_pos = ui.window_region(&container).unwrap().top_left; ctx.data.cursor += container_pos - id_pos; ctx.data.size = region.size(); select(ui, id.clone(), ctx.state, ctx.data); }, ); } } pub struct Selectable; impl WidgetAttr for Selectable { type Input = (); fn run(ui: &mut Ui, id: &WidgetRef, _: Self::Input) { let id = id.clone(); ui.register_event(&id.clone(), CursorSense::click_or_drag(), move |ctx| { select(ctx.ui, id.clone(), ctx.state, ctx.data); }); } } fn select(ui: &mut Ui, id: WidgetRef, state: &mut UiState, data: CursorData) { let now = Instant::now(); let recent = (now - state.last_click) < Duration::from_millis(300); state.last_click = now; id.get_mut() .select(data.cursor, data.size, data.sense.is_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); }