From 49d2656335c254b9c52948e8e35c11b87bb123f8 Mon Sep 17 00:00:00 2001 From: Sebastian Lohff Date: Sat, 1 Feb 2025 19:00:12 +0100 Subject: [PATCH] Add morse banner The Banner shows all morse signals of the last x seconds. --- scenes/MorseBanner.tscn | 16 ++++++++++ scenes/main.gd | 3 ++ scenes/main.tscn | 18 ++++++++++- scenes/morse_banner.gd | 66 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 scenes/MorseBanner.tscn create mode 100644 scenes/morse_banner.gd diff --git a/scenes/MorseBanner.tscn b/scenes/MorseBanner.tscn new file mode 100644 index 0000000..d5b2468 --- /dev/null +++ b/scenes/MorseBanner.tscn @@ -0,0 +1,16 @@ +[gd_scene load_steps=2 format=3 uid="uid://xqic6oa5d7oc"] + +[ext_resource type="Script" path="res://scenes/morse_banner.gd" id="1_475pl"] + +[node name="MorseBanner" type="Control"] +custom_minimum_size = Vector2(200, 100) +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_475pl") + +[connection signal="reset_buffer" from="." to="." method="_on_reset_buffer"] +[connection signal="set_state" from="." to="." method="_on_set_state"] diff --git a/scenes/main.gd b/scenes/main.gd index d630ebc..0bf2fc6 100644 --- a/scenes/main.gd +++ b/scenes/main.gd @@ -29,6 +29,9 @@ func _ready(): print(OS.get_connected_midi_inputs()) func set_morse_state(state: bool): + %MorseBanner.set_state.emit(state) + %MorseBannerMedium.set_state.emit(state) + %MorseBannerSlow.set_state.emit(state) morse_state = state if state: %ColorRect.color = Color(0, 128, 0) diff --git a/scenes/main.tscn b/scenes/main.tscn index 3ca18bf..6a2e3a9 100644 --- a/scenes/main.tscn +++ b/scenes/main.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=3 format=3 uid="uid://ctak1goemnnc5"] +[gd_scene load_steps=4 format=3 uid="uid://ctak1goemnnc5"] [ext_resource type="Script" path="res://scenes/main.gd" id="1_8bx00"] +[ext_resource type="PackedScene" uid="uid://xqic6oa5d7oc" path="res://scenes/MorseBanner.tscn" id="2_v02md"] [sub_resource type="AudioStreamGenerator" id="AudioStreamGenerator_kvn5v"] mix_rate = 11025.0 @@ -25,6 +26,21 @@ anchor_bottom = 0.5 grow_horizontal = 2 grow_vertical = 2 +[node name="MorseBannerSlow" parent="VBoxContainer" instance=ExtResource("2_v02md")] +unique_name_in_owner = true +layout_mode = 2 +display_sec = 30.0 +stretch_display = true + +[node name="MorseBannerMedium" parent="VBoxContainer" instance=ExtResource("2_v02md")] +unique_name_in_owner = true +layout_mode = 2 +display_sec = 10.0 + +[node name="MorseBanner" parent="VBoxContainer" instance=ExtResource("2_v02md")] +unique_name_in_owner = true +layout_mode = 2 + [node name="ColorRect" type="ColorRect" parent="VBoxContainer"] unique_name_in_owner = true custom_minimum_size = Vector2(200, 100) diff --git a/scenes/morse_banner.gd b/scenes/morse_banner.gd new file mode 100644 index 0000000..d9c94d1 --- /dev/null +++ b/scenes/morse_banner.gd @@ -0,0 +1,66 @@ +extends Control + +signal set_state(state: bool) +signal reset_buffer() + +var color_on := Color(0, 128, 0) +var color_off := Color(0, 0, 0) +var curr_state := false +var last_delta := 0.0 +@export_range(0.1, 120.0) var display_sec := 5.0 +@export var stretch_display := false +var start_time := 0 +var last_state_change_time: int = 0 +var morse_step_perc := 0.45 + +var morse_states: Array[int] = [] + +func _ready(): + _on_reset_buffer() + +func _draw_morse_rect(x: float, width: float, state: bool): + var rect := Rect2(max(x, 0.0), morse_step_perc * size.y, width, (0.5 - morse_step_perc) * size.y) + draw_rect(rect, color_on if state else color_off, true, -1.0, true) + +func _draw(): + # black background + draw_rect(Rect2(0.0, 0.0, size.x, size.y), Color.BLACK) + + var morse_on := curr_state + var first_time := Time.get_ticks_msec() - last_state_change_time + var curr_x := float(size.x) + + var px_per_s := 0.0 + if not stretch_display: + px_per_s = size.x / display_sec + else: + px_per_s = size.x / (Time.get_ticks_msec() - start_time) * 1000.0 + + for duration in [first_time] + morse_states: + var rect_width: float = min(duration / 1000.0 * px_per_s, curr_x) + curr_x -= rect_width + if morse_on: + # at the moment we only draw the morse rects + _draw_morse_rect(curr_x, rect_width, morse_on) + morse_on = not morse_on + if curr_x <= 0.0: + break + +func _process(_delta): + last_delta += _delta + queue_redraw() + +func _on_set_state(state: bool) -> void: + if state == curr_state: + return + curr_state = state + + var now := Time.get_ticks_msec() + morse_states.push_front(now - last_state_change_time) + last_state_change_time = now + + +func _on_reset_buffer() -> void: + last_state_change_time = Time.get_ticks_msec() + start_time = last_state_change_time + morse_states = []