A card game engine for TCGs, primarily Magic: The Gathering but with support for others
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Revert "Beginning to implement draggable stuff"

This reverts commit f2d9909151f1235ded11ababd7847862d8695419.

-241
-231
gdext/src/draggable.rs
··· 1 - use std::collections::HashMap; 2 - 3 - use godot::{classes::{Control, IControl, InputEvent, InputEventMouseButton, Tween, control::MouseFilter}, prelude::*}; 4 - 5 - /// A draggable object that supports mouse interaction with state-based animation system. 6 - /// 7 - /// This class provides a robust state machine for handling mouse interactions including 8 - /// hover effects, drag operations, and programmatic movement using Tween animations. 9 - /// All interactive cards and objects extend this base class to inherit consistent 10 - /// drag-and-drop behavior. 11 - /// 12 - /// Key Features: 13 - /// - State machine with safe transitions (IDLE → HOVERING → HOLDING → MOVING) 14 - /// - Tween-based animations for smooth hover effects and movement 15 - /// - Mouse interaction handling with proper event management 16 - /// - Z-index management for visual layering during interactions 17 - /// - Extensible design with virtual methods for customization 18 - /// 19 - /// State Transitions: 20 - /// - IDLE: Default state, ready for interaction 21 - /// - HOVERING: Mouse over with visual feedback (scale, rotation, position) 22 - /// - HOLDING: Active drag state following mouse movement 23 - /// - MOVING: Programmatic movement ignoring user input 24 - /// 25 - /// Usage: 26 - /// ``` 27 - /// class_name MyDraggable 28 - /// extends DraggableObject 29 - /// 30 - /// func _can_start_hovering() -> bool: 31 - /// return my_custom_condition 32 - /// ``` 33 - #[derive(GodotClass)] 34 - #[class(base=Control)] 35 - pub struct DraggableObject { 36 - /// Base object (Control) 37 - base: Base<Control>, 38 - /// The speed at which the object moves. 39 - moving_speed: i32, 40 - /// Whether the object can be interacted with. 41 - can_be_interacted_with: bool, 42 - /// The distance the object hovers when interacted with. 43 - hover_distance: i32, 44 - /// The scale multiplier when hovering. 45 - hover_scale: f32, 46 - /// The rotation in degrees when hovering. 47 - hover_rotation: f32, 48 - /// The duration for hover animations. 49 - hover_duration: f32, 50 - /// State Machine 51 - current_state: DraggableState, 52 - /// Mouse tracking 53 - is_mouse_inside: bool, 54 - /// Movement state tracking 55 - is_moving_to_destination: bool, 56 - /// Movement state tracking 57 - current_holding_mouse_position: Vector2, 58 - /// Position and animation tracking 59 - original_position: Vector2, 60 - /// Position and animation tracking 61 - original_scale: Vector2, 62 - /// Position and animation tracking 63 - original_hover_rotation: f32, 64 - /// Position and animation tracking. Track position during hover animation 65 - current_hover_position: Vector2, 66 - /// Move operation tracking 67 - original_destination: Vector2, 68 - /// Move operation tracking 69 - original_rotation: f32, 70 - /// Move operation tracking 71 - destination_degree: f32, 72 - /// Tween objects 73 - move_tween: Option<Tween>, 74 - /// Tween objects 75 - hover_tween: Option<Tween>, 76 - } 77 - 78 - fn allowed_transitions(state: DraggableState) -> Vec<DraggableState> { 79 - match state { 80 - DraggableState::Idle => vec![DraggableState::Hovering, DraggableState::Holding, DraggableState::Moving], 81 - DraggableState::Hovering => vec![DraggableState::Idle, DraggableState::Holding, DraggableState::Moving], 82 - DraggableState::Holding => vec![DraggableState::Idle, DraggableState::Moving], 83 - DraggableState::Moving => vec![DraggableState::Idle] 84 - } 85 - } 86 - 87 - #[godot_api] 88 - impl IControl for DraggableObject { 89 - fn init(base: Base<Control>) -> Self { 90 - Self { 91 - base, 92 - moving_speed: 0, 93 - can_be_interacted_with: true, 94 - hover_distance: 0, 95 - hover_scale: 0., 96 - hover_rotation: 0., 97 - hover_duration: 0., 98 - current_state: DraggableState::Idle, 99 - is_mouse_inside: false, 100 - is_moving_to_destination: false, 101 - current_holding_mouse_position: Vector2::ZERO, 102 - original_position: Vector2::ZERO, 103 - original_scale: Vector2::ZERO, 104 - original_hover_rotation: 0., 105 - current_hover_position: Vector2::ZERO, 106 - original_destination: Vector2::ZERO, 107 - original_rotation: 0., 108 - destination_degree: 0., 109 - move_tween: None, 110 - hover_tween: None, 111 - } 112 - } 113 - 114 - fn ready(&mut self) { 115 - let base = self.base.to_init_gd().clone(); 116 - 117 - self.base 118 - .to_init_gd() 119 - .set_mouse_filter(MouseFilter::STOP); 120 - // connect("mouse_entered", on_mouse_enter) 121 - self.signals() 122 - .mouse_entered() 123 - .connect_self(Self::on_mouse_enter); 124 - // connect("mouse_exited", on_mouse_exit) 125 - self.signals() 126 - .mouse_exited() 127 - .connect_self(Self::on_mouse_exit); 128 - // connect("gui_input", on_gui_input) 129 - self.signals() 130 - .gui_input() 131 - .connect_self(Self::on_gui_input); 132 - 133 - self.original_destination = self.base 134 - .to_init_gd() 135 - .get_global_position(); 136 - self.original_rotation = self.base 137 - .to_init_gd() 138 - .get_rotation(); 139 - self.original_position = self.base 140 - .to_init_gd() 141 - .get_position(); 142 - self.original_scale = self.base 143 - .to_init_gd() 144 - .get_scale(); 145 - self.original_hover_rotation = self.base 146 - .to_init_gd() 147 - .get_rotation(); 148 - } 149 - } 150 - 151 - #[godot_api] 152 - impl DraggableObject { 153 - #[signal] 154 - fn dummy_signal(); 155 - } 156 - 157 - impl DraggableObject { 158 - fn on_mouse_enter(&mut self) { 159 - self.is_mouse_inside = true; 160 - 161 - if self.can_be_interacted_with && self.can_start_hovering() { 162 - self.change_state(DraggableState::Hovering); 163 - } 164 - } 165 - 166 - fn on_mouse_exit(&mut self) { 167 - self.is_mouse_inside = false; 168 - 169 - match self.current_state { 170 - DraggableState::Hovering => self.change_state(DraggableState::Idle), 171 - _ => true 172 - }; 173 - } 174 - 175 - fn on_gui_input(&mut self, event: Gd<InputEvent>) { 176 - if !self.can_be_interacted_with { 177 - return; 178 - } 179 - 180 - if event.is_class("InputEventMouseButton") { 181 - self.handle_mouse_button(event.try_cast::<InputEventMouseButton>().unwrap()); 182 - } 183 - } 184 - 185 - fn can_start_hovering(&mut self) -> bool { 186 - false 187 - } 188 - 189 - fn change_state(&mut self, new_state: DraggableState) -> bool { 190 - if new_state == self.current_state { 191 - return true; 192 - } 193 - 194 - if !allowed_transitions(self.current_state).contains(&new_state) { 195 - return false; 196 - } 197 - 198 - self.exit_state(self.current_state); 199 - 200 - let old_state = self.current_state; 201 - self.current_state = new_state; 202 - 203 - self.enter_state(new_state, old_state); 204 - true 205 - } 206 - 207 - fn handle_mouse_button(&mut self, event: Gd<InputEventMouseButton>) { 208 - 209 - } 210 - 211 - fn exit_state(&mut self, state: DraggableState) { 212 - 213 - } 214 - 215 - fn enter_state(&mut self, new_state: DraggableState, old_state: DraggableState) { 216 - 217 - } 218 - } 219 - 220 - /// Enumeration of possible interaction states for the draggable object. 221 - #[derive(PartialEq, Copy, Clone)] 222 - pub enum DraggableState { 223 - /// Default state - no interaction 224 - Idle, 225 - /// Mouse over state - visual feedback 226 - Hovering, 227 - /// Dragging state - follows mouse 228 - Holding, 229 - /// Programmatic move state - ignores input 230 - Moving 231 - }
-10
gdext/src/lib.rs
··· 1 1 use godot::prelude::*; 2 2 use managrove_core::Game; 3 3 4 - mod draggable; 5 - 6 4 #[derive(GodotClass)] 7 5 #[class(base=Node)] 8 6 struct ManaGroveNode { ··· 22 20 base, 23 21 data: Game::new() 24 22 } 25 - } 26 - 27 - fn ready(&mut self) { 28 - godot_print!("Loaded ManaGrove game"); 29 - } 30 - 31 - fn process(&mut self, delta: f64) { 32 - 33 23 } 34 24 }