Files
SurfaceSide-UI/scripts/depth_scale.gd
T

65 lines
2.5 KiB
GDScript

@tool
extends Control
var depth_m := 0.0
var maximum_depth_m := 1000.0
var knee_m := 1.0
var warning_fraction := 0.8
var fault_fraction := 0.95
var available := false
func _ready() -> void:
resized.connect(queue_redraw)
theme_changed.connect(queue_redraw)
# log(1 + depth / knee) includes zero and is nearly linear close to the surface.
func normalized_depth(value: float) -> float:
var knee := maxf(knee_m, 0.001)
var maximum := maxf(maximum_depth_m, 0.001)
return log(1 + clampf(value, 0, maximum) / knee) / log(1 + maximum / knee)
func severity() -> int:
var ratio := depth_m / maxf(maximum_depth_m, 0.001)
return 2 if ratio >= fault_fraction else (1 if ratio >= warning_fraction else 0)
func _draw() -> void:
var top := 9.0
var bottom := maxf(top + 1, size.y - 10)
var track := get_theme_color("instrument_grid", "SurfaceSide")
var ink := get_theme_color("font_color", "Label")
var font := get_theme_default_font()
draw_line(Vector2(17, top), Vector2(17, bottom), track, 2, true)
var decade := maxf(knee_m, 0.001)
while decade < maximum_depth_m:
for multiplier in [1.0, 2.0, 5.0]:
var tick: float = decade * multiplier
if tick > 0 and tick < maximum_depth_m:
var y: float = lerpf(top, bottom, normalized_depth(tick))
draw_line(Vector2(14, y), Vector2(21, y), track, 1, true)
decade *= 10
var last_label_y := -100.0
var last_label_value := -1.0
var ticks: Array[float] = [0, maxf(knee_m, 0.001) * 2]
decade = maxf(knee_m, 0.001) * 10
while decade < maximum_depth_m:
ticks.append(decade)
decade *= 10
ticks.append(maximum_depth_m)
for tick in ticks:
if tick < 0 or tick > maximum_depth_m or is_equal_approx(tick, last_label_value):
continue
var y := lerpf(top, bottom, normalized_depth(tick))
if tick != maximum_depth_m and (y - last_label_y < 20 or (bottom - y < 20 and tick != 0)):
continue
draw_line(Vector2(12, y), Vector2(23, y), ink, 1, true)
draw_string(font, Vector2(29, y + 5), String.num(tick, 3).trim_suffix(".0"), HORIZONTAL_ALIGNMENT_LEFT, -1, 14, ink)
last_label_y = y
last_label_value = tick
if available:
var y := lerpf(top, bottom, normalized_depth(depth_m))
var role: String = ["instrument_accent", "warning", "fault"][severity()]
var accent := get_theme_color(role, "SurfaceSide")
draw_line(Vector2(17, top), Vector2(17, y), accent, 3, true)
draw_colored_polygon(PackedVector2Array([Vector2(1, y - 5), Vector2(1, y + 5), Vector2(12, y)]), accent)
draw_line(Vector2(12, y), Vector2(23, y), accent, 3, true)