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