#118/#121: the speed fader and the formation editor under a mouse

Both read raw touches, and the project no longer turns clicks into them - the
same routing gap #93 fixed in the research tree. The boost was unreachable on
a desktop and the formation could not be rearranged at all.

Wrappers over the same press/drag logic in each case, never a second
implementation, so the touch and mouse paths cannot drift apart. The wheel
replaces the pinch in the formation editor: a mouse has no second finger, and
zoom is the other half of what that panel does.

The fader gets first refusal on a mouse press in GameController, so dragging
the boost does not also pan or zoom the world behind it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Loïc Wisniewski 2026-08-23 21:59:24 +02:00
commit 8412280e71
4 changed files with 243 additions and 43 deletions

View file

@ -77,17 +77,45 @@ func _blocked_by_modal() -> bool:
return false
# #118: the same fader, driven by a mouse.
#
# The project used to set emulate_touch_from_mouse, which handed every raw
# touch handler a synthetic touch per click; with that gone this control was
# inert on a desktop and there was no other way to reach the boost. Written
# as thin wrappers over the touch path rather than as a second
# implementation, so the two cannot drift - the same mistake #93 fixed in
# the research tree.
const MOUSE_TOUCH_INDEX: int = -2
func handle_mouse_button(event: InputEventMouseButton) -> bool:
if event.button_index != MOUSE_BUTTON_LEFT:
return false
return _press(event.pressed, event.position, MOUSE_TOUCH_INDEX)
func handle_mouse_motion(event: InputEventMouseMotion) -> bool:
if active_touch_index != MOUSE_TOUCH_INDEX:
return false
_update_from_local(event.position - global_position)
return true
func handle_touch(event: InputEventScreenTouch) -> bool:
var local: Vector2 = event.position - global_position
if event.pressed:
return _press(event.pressed, event.position, event.index)
func _press(pressed: bool, at: Vector2, index: int) -> bool:
var local: Vector2 = at - global_position
if pressed:
if not visible or active_touch_index != -1 or _blocked_by_modal():
return false
if not Rect2(Vector2.ZERO, size).has_point(local):
return false
active_touch_index = event.index
active_touch_index = index
_update_from_local(local)
return true
if event.index != active_touch_index:
if index != active_touch_index:
return false
active_touch_index = -1
queue_redraw()