notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

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 }