breakfilemaker.gd 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. extends Control
  2. const FIXED_POINT_COUNT := 2
  3. var points := [] # Stores Vector2 points
  4. var point_size := 10
  5. var dragged_point_index := -1
  6. signal automation_updated(values: Array)
  7. func _ready():
  8. set_process_unhandled_input(true)
  9. # these two are fixed: only Y-movable, not deletable
  10. var window = get_window().size
  11. var uiscale = get_window().content_scale_factor
  12. points.append(Vector2(0, (((window.y / 2) - (22 * uiscale)) / uiscale)))
  13. points.append(Vector2(window.x / uiscale, (((window.y / 2) - (22 * uiscale)) / uiscale)))
  14. func _unhandled_input(event):
  15. var pos = get_local_mouse_position()
  16. if event is InputEventMouseButton:
  17. # --- double-click: delete only if not fixed, otherwise add new --
  18. if event.button_index == MOUSE_BUTTON_LEFT and event.double_click:
  19. var idx = get_point_at_pos(pos)
  20. if idx >= FIXED_POINT_COUNT:
  21. points.remove_at(idx)
  22. elif idx == -1:
  23. points.append(pos)
  24. queue_redraw()
  25. # --- begin drag on press ---
  26. elif event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
  27. dragged_point_index = get_point_at_pos(pos)
  28. # --- end drag on release ---
  29. elif event.button_index == MOUSE_BUTTON_LEFT and not event.pressed:
  30. dragged_point_index = -1
  31. elif event is InputEventMouseMotion and dragged_point_index != -1:
  32. # if it’s one of the first two, constrain to Y only:
  33. if dragged_point_index < FIXED_POINT_COUNT:
  34. points[dragged_point_index].y = clamp(pos.y, 0, get_window().size.y -45)
  35. else:
  36. points[dragged_point_index].x = clamp(pos.x, 0, get_window().size.x)
  37. points[dragged_point_index].y = clamp(pos.y, 0, get_window().size.y - 45)
  38. queue_redraw()
  39. func _draw():
  40. var sorted = []
  41. sorted = points.duplicate()
  42. sorted.sort_custom(sort_points)
  43. for i in range(points.size() - 1):
  44. draw_dashed_line(sorted[i], sorted[i + 1], Color(0.1, 0.1, 0.1, 0.6), 2.0, 6.0, true, true)
  45. for point in points:
  46. draw_rect(Rect2(point.x - (point_size / 2), point.y - (point_size / 2), point_size, point_size), Color(0.1, 0.1, 0.1, 0.8))
  47. func sort_points(a, b):
  48. return a.x < b.x
  49. func get_point_at_pos(pos: Vector2) -> int:
  50. # find any point within radius + padding
  51. for i in range(points.size()):
  52. if points[i].distance_to(pos) <= point_size + 2:
  53. return i
  54. return -1
  55. func emit_automation_data():
  56. emit_signal("automation_updated", points)
  57. func _on_save_automation_button_down() -> void:
  58. emit_automation_data()
  59. func read_automation(stored_points: Array):
  60. points = stored_points.duplicate()
  61. func reset_automation():
  62. points = []
  63. var window = get_window().size
  64. points.append(Vector2(0, (window.y / 2) - 22))
  65. points.append(Vector2(window.x, (window.y / 2) - 22))