Automized popup panels using panel script

Working on a instrument project or just finished a project? Show it to others!

Moderators: russ, Ralph

Post Reply
Message
Author
Detlef
Posts: 304
Joined: Mon Nov 16, 2020 9:43 am
Location: Bavaria

Automized popup panels using panel script

#1 Post by Detlef »

Hi,

for my 737 overhead instrument project I am in a phase where I need an efficient way to use the instruments while still changing instruments and adding new instruments.
I decided to make a panel script and a separate instrument, so that I can activate and de-activate other panels from the select instrument on my base panel.
The panel script basically shows groups of instruments. The groups are stacks of instruments. And when pressing for example the "fwd overhead" button on the select instrument, one or more group of instruments pop up on top of the base panel. A frame is automatically drawn arround each layout.

Explaining is somewhat complex. If you are interested you may just look into the panel script code.

1) make a normal instrument panel on the home tab. That panel is the base panel, it must contain the "Panel Select Instrument" and all instruments you always want to see.
2) Go to the Create/Edit Panel tab and make a panel derived from your base panel.
3) Add all instruments you want to have in your popup panels.
4) Add the lua panel script there. Edit it to reflect your instruments and needs. You can use a scale factor in the panel script to fit your instruments. They are then sized and positioned automatically.
5) Test the panel in the create/edit panel tab.
6) Go back to the home tab and make a new panel, AND in doing that select the one you made in create/edit
7) Thats it. I am unable to explain it better. :)

The select instrument looks like this
preview.png
preview.png (23.83 KiB) Viewed 709 times
I use it to pop-up the overhead forward or aft panel, or the control stand.
The panel script is this one:

Code: Select all

-- Detlef von Reusner
-- 23.9.2022

-- Base panel that switches overlays on and off
-- An overlay is a group of instruments. Each group is automatically framed.
-- More than one overlay can be activated at the same time, if it has the same activation_code.
-- This panel must contain all instruments, including all instruments from the switched panels.

local FRAME_WIDTH = 14

local gOverlay = {}
local gOverlayCount = 0

local gMaxStackHeight = 0 -- needed to draw a frame arround the instruments of a panel
local gCurrentStackHeight = 0
local gCurrentStack = 0

-- ================== add instruments for base panel ===================
-- needed only to define the z_order

function AddBaseInstrument(name, order, uuid, offset)
  z_order(instrument_get(uuid, offset), order)
end

local order = -1
AddBaseInstrument("hw panel camera", order, "bc7e35f6-d4d7-4d62-0146-2529ddb3241f")
AddBaseInstrument("hw panel server FS2020", order, "874c8cea-9e44-46d3-a964-ca52c86a9852")
AddBaseInstrument("AP MCP", order, "50ce3410-4fc8-4e2d-a5a3-83871e6315cd")
AddBaseInstrument("efis", order, "0916102e-a4b2-435b-0c2e-a22c22fec75e")
AddBaseInstrument("flap auto brake", order, "d6d822da-9e5c-4300-0ff3-bd17062596ee")
AddBaseInstrument("fmc overlay", order, "a0ef93e5-c208-460c-83be-9964766032e3")
AddBaseInstrument("brake annunc", order, "df46f46f-2622-4d5f-8cbd-30c547dd21fa")
AddBaseInstrument("rudder trim", order, "94d5396f-bf97-41af-b9b7-3c736a3a0e43")
AddBaseInstrument("hw panel gear flaps park brake", order, "fd2825af-8f80-4ef4-9119-fa0ce338f828")
AddBaseInstrument("flexpanel fs2020", order, "624b02b7-9fe1-41e9-8205-456a9aa4629d")
AddBaseInstrument("hw panel ap alt", order, "338d8818-1703-488e-969a-a18193e2789d")
AddBaseInstrument("hw panel ap nav", order, "bab2e412-f1d4-4e52-b81d-4564ad1c8c38")
AddBaseInstrument("master fire warning", order, "6eec81f5-0cb6-4efd-9eb4-712d172cdfca")
AddBaseInstrument("annunc ap", order, "12058a76-661e-40aa-3c50-f2fa3a4877e6")
AddBaseInstrument("hw panel nav radio", order, "a25babd8-4b0f-429f-bd01-94280cb75570")
AddBaseInstrument("nav radio", order, "a2e0618f-8cc6-4c4f-1e89-0e128741dfa4", 0)
AddBaseInstrument("com radio", order, "509cadc9-d22b-4381-816a-171f1a0dce93", 0)
AddBaseInstrument("adf radio", order, "838b04d9-3e61-4432-35ae-46c70aedd7c4")
AddBaseInstrument("hw panel ovhd FS2020", order, "c0a9315e-de0c-4ece-0c71-f8c6a38c85b7")
AddBaseInstrument("nav radio", order, "a2e0618f-8cc6-4c4f-1e89-0e128741dfa4", 1)
AddBaseInstrument("transponder radio", order, "2e38d46d-2b08-4e9a-852f-690b7b64a755")
AddBaseInstrument("com radio", order, "509cadc9-d22b-4381-816a-171f1a0dce93", 1)
AddBaseInstrument("ambient light dimmer", order, "f8f83fd0-af45-4991-38cc-4eabc21e872d")
AddBaseInstrument("system annunc pilot", order, "0b1be2ec-0e95-435f-246c-368f4766f514", 0)
AddBaseInstrument("system annunc copilot", order, "0b1be2ec-0e95-435f-246c-368f4766f514", 1)

AddBaseInstrument("dome white switch", order, "07d92b03-0407-4bfe-9d27-453654255d73", 0)
AddBaseInstrument("Left Exterior Light Switches", order, "af6cbe42-eaa3-44fd-81c5-f8fb2793805e", 0)
AddBaseInstrument("Right Exterior Light Switches", order, "09fb36a5-ba8b-4d60-b857-b3e7da7d8485", 0)

--==================== functions to organize instruments in stacks of a panel ========================

function StartOverlay(overlay_name, activation_code, stack_width, x, y, scale)
  -- instr_width will be used as column width for this panel
  -- x and y marks the top left corner of this panel
  -- for example scale .5 means the instruments sizes are multiplied by .5
  gOverlayCount = gOverlayCount+1
  gOverlay[gOverlayCount] = {}
  
  local p = gOverlay[gOverlayCount]
  
  p.name = overlay_name
  p.group = group_add()
  p.frame = nil
  p.activation_code = activation_code
  -- multiple overlays can use the same activation_code
  -- the activation_code is sent per system variable
  
  p.stack_width = stack_width*scale
  p.x = x
  p.y = y
  p.scale = scale
  gMaxStackHeight = 0
  gCurrentStack = 0
end

function StartStack()
  gCurrentStackHeight = 0
  gCurrentStack = gCurrentStack+1
end

function AddInstrument(name, width, height, uuid, offset)
  local id = instrument_get(uuid, offset)
  group_obj_add(gOverlay[gOverlayCount].group, id)
  z_order(id, 99)
  local x, y, w, h
  x = (gCurrentStack-1)*gOverlay[gOverlayCount].stack_width + gOverlay[gOverlayCount].x + FRAME_WIDTH
  y = gCurrentStackHeight + gOverlay[gOverlayCount].y + FRAME_WIDTH
  w = width*gOverlay[gOverlayCount].scale
  h = height*gOverlay[gOverlayCount].scale
  if w<gOverlay[gOverlayCount].stack_width then
    x = x + (gOverlay[gOverlayCount].stack_width-w)/2 -- horizontally center within the stack
  end
  move(id, x, y, w, h)
  gCurrentStackHeight = gCurrentStackHeight + h
  if gCurrentStackHeight>gMaxStackHeight then gMaxStackHeight=gCurrentStackHeight end
end

function GenerateFrame()
  -- generate an overlay background with a frame
  local x, y, w, h
  x = gOverlay[gOverlayCount].x
  y = gOverlay[gOverlayCount].y
  w = gCurrentStack * gOverlay[gOverlayCount].stack_width + 2*FRAME_WIDTH
  h = gMaxStackHeight + 2*FRAME_WIDTH
  gOverlay[gOverlayCount].frame = canvas_add(x, y, w, h, function()
    _rect(0, 0, w, h)
    _fill("#101010ff")
    _move_to(FRAME_WIDTH/2, FRAME_WIDTH/2)
    _line_to(w - FRAME_WIDTH/2, FRAME_WIDTH/2)
    _line_to(w - FRAME_WIDTH/2, h - FRAME_WIDTH/2)
    _line_to(FRAME_WIDTH/2, h - FRAME_WIDTH/2)
    _line_to(FRAME_WIDTH/2, FRAME_WIDTH/2)
    _stroke("#080808ff", FRAME_WIDTH)
  end)
  z_order(gOverlay[gOverlayCount].frame, -1)
  z_order(gOverlay[gOverlayCount].group, 99)
end

-- ======================= shade base instruments while an overlay is active ===========================

local gShade = canvas_add(200, 0, 3640, 1080, function()
  _rect(0, 0, 3640, 1080)
  _fill("black")
end)
z_order(gShade, 98)
opacity(gShade, .7)
visible(gShade, false)

-- ========== forward overhead panel instruments ========================

StartOverlay("FWD Overhead Panel Left", 1, 400, 1140, 20, .9)

StartStack()
AddInstrument("Flight Control", 400, 560, "2fa3c344-3e29-444d-8966-a146d3147619")
AddInstrument("Fuel Pump Switches", 400, 580, "5f3fdf98-cf3f-47de-b7b5-9b4e13175dc9")

StartStack()
AddInstrument("Standby Power", 400, 280, "518ebdb0-4a93-4477-01bd-514db3230904")
AddInstrument("Generator Switches", 400, 405, "3172aa53-47b5-415e-3366-878815a98a49")
AddInstrument("APU EGT", 200, 200, "15f05f56-760f-4068-af56-c3a0fd64fae8")
AddInstrument("APU & Eng Start Switch", 400, 150, "11ae414a-51a7-4bdb-a0e6-bd54124ee5af")

GenerateFrame()

------------- split

StartOverlay("FWD Overhead Panel Right", 1, 400, 2433, 20, .8)

StartStack()
AddInstrument("Pitot and Window Heat", 400, 460, "62f80aa5-b789-4ac3-3963-44fbce630aaf")
AddInstrument("Anti-Ice", 400, 255, "429f27b5-848e-4e9d-b27b-5d77ffa9a720")
AddInstrument("Hydraulics Switches", 400, 240, "fe61bfa7-21f8-4b7e-a4d3-045a198707cf")
AddInstrument("Doors", 400, 210, "283b8204-1550-4770-313b-9591e7ce92b7")

StartStack()
AddInstrument("Bleed", 400, 550, "94fa5175-840e-47c1-2c74-651487865d74")

GenerateFrame()

-- ============== aft overhead panel instruments =====================

StartOverlay("Aft overhead panel", 2, 400, 1000, 50, 1.0)

StartStack()
AddInstrument("IRS Select Mode", 400, 270, "315ded83-dea9-4a00-33b1-9ff9a6552040")
AddInstrument("LE Devices", 400, 185, "89604fa1-9faf-44e1-916f-049855ac9bb7")

GenerateFrame()

-- =================== panel activation and deactivation =========================

function ShowOverlays(activation_code)
  local active = false
  visible(gShade, activation_code ~= 0)
  for overlay=1,gOverlayCount do
    active = (activation_code == gOverlay[overlay].activation_code)
    visible(gOverlay[overlay].group, active)
    visible(gOverlay[overlay].frame, active)
  end
end

si_variable_subscribe("sivar_activate_panel", "INT", ShowOverlays)
--ShowOverlays(2)

Good luck,
Detlef

Detlef
Posts: 304
Joined: Mon Nov 16, 2020 9:43 am
Location: Bavaria

Re: Automized popup panels using panel script

#2 Post by Detlef »

I forgot the instrument .siff file.

Detlef

Detlef
Posts: 304
Joined: Mon Nov 16, 2020 9:43 am
Location: Bavaria

Re: Automized popup panels using panel script

#3 Post by Detlef »

Simple example, base panel with and without popout panel.
image.png
The more simple example panel script:

Code: Select all

-- Detlef von Reusner
-- 27.9.2022

-- ============== Example ============

-- Base panel that switches overlays on and off
-- An overlay is a group of instruments. Each group is automatically framed.
-- More than one overlay can be activated at the same time, if it has the same activation_code.
-- This panel must contain all instruments, including all instruments from the switched panels.

local FRAME_WIDTH = 14

local gOverlay = {}
local gOverlayCount = 0

local gMaxStackHeight = 0 -- needed to draw a frame arround the instruments of a panel
local gCurrentStackHeight = 0
local gCurrentStack = 0

-- ================== add instruments for base panel ===================
-- needed only to define the z_order

function AddBaseInstrument(name, order, uuid, offset)
  z_order(instrument_get(uuid, offset), order)
end

local order = -1
AddBaseInstrument("master fire warning", order, "6eec81f5-0cb6-4efd-9eb4-712d172cdfca")
AddBaseInstrument("nav radio", order, "a2e0618f-8cc6-4c4f-1e89-0e128741dfa4", 0)
AddBaseInstrument("com radio", order, "509cadc9-d22b-4381-816a-171f1a0dce93", 0)

AddBaseInstrument("dome white switch", order, "07d92b03-0407-4bfe-9d27-453654255d73", 0)


--==================== functions to organize instruments in stacks of a panel ========================

function StartOverlay(overlay_name, activation_code, stack_width, x, y, scale)
  -- instr_width will be used as column width for this panel
  -- x and y marks the top left corner of this panel
  -- for example scale .5 means the instruments sizes are multiplied by .5
  gOverlayCount = gOverlayCount+1
  gOverlay[gOverlayCount] = {}
  
  local p = gOverlay[gOverlayCount]
  
  p.name = overlay_name
  p.group = group_add()
  p.frame = nil
  p.activation_code = activation_code
  -- multiple overlays can use the same activation_code
  -- the activation_code is sent per system variable
  
  p.stack_width = stack_width*scale
  p.x = x
  p.y = y
  p.scale = scale
  gMaxStackHeight = 0
  gCurrentStack = 0
end

function StartStack()
  gCurrentStackHeight = 0
  gCurrentStack = gCurrentStack+1
end

function AddInstrument(name, width, height, uuid, offset)
  local id = instrument_get(uuid, offset)
  group_obj_add(gOverlay[gOverlayCount].group, id)
  z_order(id, 99)
  local x, y, w, h
  x = (gCurrentStack-1)*gOverlay[gOverlayCount].stack_width + gOverlay[gOverlayCount].x + FRAME_WIDTH
  y = gCurrentStackHeight + gOverlay[gOverlayCount].y + FRAME_WIDTH
  w = width*gOverlay[gOverlayCount].scale
  h = height*gOverlay[gOverlayCount].scale
  if w<gOverlay[gOverlayCount].stack_width then
    x = x + (gOverlay[gOverlayCount].stack_width-w)/2 -- horizontally center within the stack
  end
  move(id, x, y, w, h)
  gCurrentStackHeight = gCurrentStackHeight + h
  if gCurrentStackHeight>gMaxStackHeight then gMaxStackHeight=gCurrentStackHeight end
end

function GenerateFrame()
  -- generate an overlay background with a frame
  local x, y, w, h
  x = gOverlay[gOverlayCount].x
  y = gOverlay[gOverlayCount].y
  w = gCurrentStack * gOverlay[gOverlayCount].stack_width + 2*FRAME_WIDTH
  h = gMaxStackHeight + 2*FRAME_WIDTH
  gOverlay[gOverlayCount].frame = canvas_add(x, y, w, h, function()
    _rect(0, 0, w, h)
    _fill("#101010ff")
    _move_to(FRAME_WIDTH/2, FRAME_WIDTH/2)
    _line_to(w - FRAME_WIDTH/2, FRAME_WIDTH/2)
    _line_to(w - FRAME_WIDTH/2, h - FRAME_WIDTH/2)
    _line_to(FRAME_WIDTH/2, h - FRAME_WIDTH/2)
    _line_to(FRAME_WIDTH/2, FRAME_WIDTH/2)
    _stroke("#080808ff", FRAME_WIDTH)
  end)
  z_order(gOverlay[gOverlayCount].frame, -1)
  z_order(gOverlay[gOverlayCount].group, 99)
end

-- ======================= shade base instruments while an overlay is active ===========================

local gShade = canvas_add(200, 0, 3640, 1080, function()
  _rect(0, 0, 3640, 1080)
  _fill("black")
end)
z_order(gShade, 98)
opacity(gShade, .7)
visible(gShade, false)

-- ========== forward overhead panel instruments ========================

StartOverlay("FWD Overhead Panel Right", 1, 400, 300, 20, .5)

StartStack()
AddInstrument("Pitot and Window Heat", 400, 460, "62f80aa5-b789-4ac3-3963-44fbce630aaf")
AddInstrument("Anti-Ice", 400, 255, "429f27b5-848e-4e9d-b27b-5d77ffa9a720")
AddInstrument("Hydraulics Switches", 400, 240, "fe61bfa7-21f8-4b7e-a4d3-045a198707cf")
AddInstrument("Doors", 400, 210, "283b8204-1550-4770-313b-9591e7ce92b7")

GenerateFrame()

-- =================== panel activation and deactivation =========================

function ShowOverlays(activation_code)
  local active = false
  visible(gShade, activation_code ~= 0)
  for overlay=1,gOverlayCount do
    active = (activation_code == gOverlay[overlay].activation_code)
    visible(gOverlay[overlay].group, active)
    visible(gOverlay[overlay].frame, active)
  end
end

si_variable_subscribe("sivar_activate_panel", "INT", ShowOverlays)
--ShowOverlays(2)

Regards,
Detlef

Detlef
Posts: 304
Joined: Mon Nov 16, 2020 9:43 am
Location: Bavaria

Re: Automized popup panels using panel script

#4 Post by Detlef »

The flight sim must be running for the inter-instrument communication to work. I found that out the hard way. :)

Detlef

Post Reply