Skip to content

Instantly share code, notes, and snippets.

@jkrumbiegel
Created July 25, 2025 17:51
Show Gist options
  • Save jkrumbiegel/f46793d7207e42ff6da9ca409b470fb5 to your computer and use it in GitHub Desktop.
Save jkrumbiegel/f46793d7207e42ff6da9ca409b470fb5 to your computer and use it in GitHub Desktop.
Makie tab interface using deletion
function tear_down!(tabgrid)
for e in @view tabgrid.content[end:-1:begin]
if e.content isa GridLayout
tear_down!(e.content)
Makie.GridLayoutBase.remove_from_gridlayout!(e)
else
delete!(e.content)
end
end
trim!(tabgrid)
return
end
function setup!(f, tabgrid)
tear_down!(tabgrid)
f(tabgrid)
return
end
function tab1(gl)
# Satellite Controls Panel
controls_grid = GridLayout(gl[1, 1], tellwidth = false)
# Power and Systems
Label(controls_grid[1, 1], "Power Systems", fontsize = 16, font = :bold, halign = :left)
SliderGrid(controls_grid[2, 1],
(label = "Solar Panel Angle", range = 0:5:180, startvalue = 90),
(label = "Battery Level", range = 0:1:100, startvalue = 85),
(label = "Power Output", range = 0:10:500, startvalue = 250),
width = 250,
)
# System Status
Label(controls_grid[3, 1], "System Status", fontsize = 16, font = :bold, halign = :left)
status_grid = GridLayout(controls_grid[4, 1])
Toggle(status_grid[1, 1], active = true)
Label(status_grid[1, 2], "Main Engine", halign = :left)
Toggle(status_grid[2, 1], active = true)
Label(status_grid[2, 2], "Communication Array", halign = :left)
Toggle(status_grid[3, 1], active = false)
Label(status_grid[3, 2], "Emergency Mode", halign = :left)
# Mission Commands
commands_grid = GridLayout(gl[1, 2])
Label(commands_grid[1, 1], "Mission Commands", fontsize = 16, font = :bold)
Button(commands_grid[2, 1], label = "Deploy Solar Panels")
Button(commands_grid[3, 1], label = "Initiate Data Collection")
Button(commands_grid[4, 1], label = "Emergency Shutdown")
return
end
function tab2(gl)
# Navigation and Orbit Control
nav_grid = GridLayout(gl[1, 1])
Label(nav_grid[1, 1], "Orbital Parameters", fontsize = 16, font = :bold, halign = :left)
SliderGrid(nav_grid[2, 1],
(label = "Altitude (km)", range = 200:10:800, startvalue = 400),
(label = "Inclination (°)", range = 0:1:90, startvalue = 28),
(label = "Orbital Velocity (km/s)", range = 5.0:0.1:12.0, startvalue = 7.8),
(label = "Thrust Vector (°)", range = -180:5:180, startvalue = 0),
width = 250,
)
# Navigation Controls
nav_controls = GridLayout(gl[2, 1])
Label(nav_controls[1, 1], "Navigation Mode", fontsize = 14, font = :bold, halign = :left)
Menu(nav_controls[2, 1], options = ["Automatic", "Manual", "Station Keeping", "Orbit Transfer"])
control_buttons = GridLayout(nav_controls[3, 1])
Button(control_buttons[1, 1], label = "Apply Thrust")
Button(control_buttons[1, 2], label = "Stabilize Orbit")
Button(control_buttons[2, 1], label = "Course Correction")
Button(control_buttons[2, 2], label = "Emergency Maneuver")
return
end
function tab3(gl)
# Communication and Data Systems
comm_grid = GridLayout(gl[1, 1])
Label(comm_grid[1, 1], "Communication Settings", fontsize = 16, font = :bold, halign = :left)
# Communication parameters
SliderGrid(comm_grid[2, 1],
(label = "Signal Strength", range = 0:5:100, startvalue = 75),
(label = "Data Rate (Mbps)", range = 1:1:50, startvalue = 25),
(label = "Antenna Gain (dB)", range = 0:1:40, startvalue = 30),
width = 250,
)
# Ground Station Selection
station_grid = GridLayout(gl[1, 2])
Label(station_grid[1, 1], "Ground Station", fontsize = 14, font = :bold)
Menu(station_grid[2, 1], options = ["Houston Control", "Madrid Deep Space", "Goldstone", "Canberra"])
# Communication Status
Label(station_grid[3, 1], "Link Status", fontsize = 14, font = :bold)
status_indicators = GridLayout(station_grid[4, 1])
Toggle(status_indicators[1, 1], active = true)
Label(status_indicators[1, 2], "Uplink Active", halign = :left)
Toggle(status_indicators[2, 1], active = true)
Label(status_indicators[2, 2], "Downlink Active", halign = :left)
Toggle(status_indicators[3, 1], active = false)
Label(status_indicators[3, 2], "Emergency Channel", halign = :left)
# Data Operations
data_grid = GridLayout(gl[2, :])
Label(data_grid[1, 1], "Data Operations", fontsize = 16, font = :bold, halign = :left)
operations_buttons = GridLayout(data_grid[2, 1])
Button(operations_buttons[1, 1], label = "Start Data Transmission")
Button(operations_buttons[1, 2], label = "Download Telemetry")
Button(operations_buttons[2, 1], label = "Send Command Sequence")
Button(operations_buttons[2, 2], label = "Emergency Contact")
return
end
function make_tabs!(gp, titles_funcs)
n_tabs = length(titles_funcs)
gl = GridLayout(gp)
buttongrid = GridLayout(gl[1, 1], tellwidth = false, halign = :left)
b = Box(gl[2, 1], color = :transparent, strokecolor = :gray90, strokewidth = 1)
translate!(b.blockscene, 0, 0, -10_000)
contentgrid = GridLayout(gl[2, 1], alignmode = Outside(15))
i_active = Observable(1)
bdefs = Makie.block_defaults(Button, Dict(), nothing)
buttons = map(enumerate(titles_funcs)) do (i, (title, func))
b = Button(buttongrid[1, i], label = title, cornerradius = 0, buttoncolor = @lift($i_active == i ? bdefs[:buttoncolor_hover] : bdefs[:buttoncolor]))
on(b.clicks) do _
i_active[] == i && return
setup!(func, contentgrid)
i_active[] = i
end
end
setup!(titles_funcs[1][2], contentgrid)
rowgap!(gl, 0)
colgap!(buttongrid, 0)
return gl
end
f = Figure()
gl = make_tabs!(f[1, 1], ["Satellite Control" => tab1, "Navigation" => tab2, "Communications" => tab3])
gl.tellheight = false
Axis(f[1, 2])
f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment