drag.rs (2926B)
1 #[derive(Default, Clone, Debug)] 2 pub struct DragSwitch { 3 state: Option<DragState>, 4 } 5 6 #[derive(Clone, Debug)] 7 struct DragState { 8 start_pos: egui::Pos2, 9 cur_direction: DragDirection, 10 } 11 12 impl DragSwitch { 13 /// should call BEFORE both drag directions get rendered 14 pub fn update(&mut self, horizontal: egui::Id, vertical: egui::Id, ctx: &egui::Context) { 15 let horiz_being_dragged = ctx.is_being_dragged(horizontal); 16 let vert_being_dragged = ctx.is_being_dragged(vertical); 17 18 if !horiz_being_dragged && !vert_being_dragged { 19 self.state = None; 20 return; 21 } 22 23 let Some(state) = &mut self.state else { 24 return; 25 }; 26 27 let Some(cur_pos) = ctx.pointer_interact_pos() else { 28 return; 29 }; 30 31 let dx = (state.start_pos.x - cur_pos.x).abs(); 32 let dy = (state.start_pos.y - cur_pos.y).abs(); 33 34 let new_direction = if dx > dy { 35 DragDirection::Horizontal 36 } else { 37 DragDirection::Vertical 38 }; 39 40 if new_direction == DragDirection::Horizontal 41 && state.cur_direction == DragDirection::Vertical 42 { 43 // drag is occuring mostly in the horizontal direction 44 ctx.set_dragged_id(horizontal); 45 let new_dir = DragDirection::Horizontal; 46 state.cur_direction = new_dir; 47 } else if new_direction == DragDirection::Vertical 48 && state.cur_direction == DragDirection::Horizontal 49 { 50 // drag is occuring mostly in the vertical direction 51 let new_dir = DragDirection::Vertical; 52 state.cur_direction = new_dir; 53 ctx.set_dragged_id(vertical); 54 } 55 } 56 57 /// should call AFTER both drag directions rendered 58 pub fn check_for_drag_start( 59 &mut self, 60 ctx: &egui::Context, 61 horizontal: egui::Id, 62 vertical: egui::Id, 63 ) { 64 let Some(drag_id) = ctx.drag_started_id() else { 65 return; 66 }; 67 68 let cur_direction = if drag_id == horizontal { 69 DragDirection::Horizontal 70 } else if drag_id == vertical { 71 DragDirection::Vertical 72 } else { 73 return; 74 }; 75 76 let Some(cur_pos) = ctx.pointer_interact_pos() else { 77 return; 78 }; 79 80 self.state = Some(DragState { 81 start_pos: cur_pos, 82 cur_direction, 83 }); 84 } 85 } 86 87 #[derive(Debug, PartialEq, Clone)] 88 enum DragDirection { 89 Horizontal, 90 Vertical, 91 } 92 93 pub fn get_drag_id(ui: &egui::Ui, scroll_id: egui::Id) -> egui::Id { 94 ui.id().with(egui::Id::new(scroll_id)).with("area") 95 } 96 97 // unfortunately a Frame makes a new id for the Ui 98 pub fn get_drag_id_through_frame(ui: &egui::Ui, scroll_id: egui::Id) -> egui::Id { 99 ui.id() 100 .with(egui::Id::new("child")) 101 .with(egui::Id::new(scroll_id)) 102 .with("area") 103 }