Skip to content

hal971/AirPanel

Repository files navigation

AirPanel

AirPanel lets you design interactive 2D aircraft cockpit panels (overhead, pedestal, glareshield, MCDU, etc.) and connect them to Microsoft Flight Simulator (2020/2024) via SimConnect. Define your panel in an XML file, use Lua for logic, and AirPanel draws the window and handles every switch, knob, button, and light – no coding of graphics or input handling required. Includes XML Schema validation for error-free development.

A320 Screenshot
Screenshot of the Airbus A320 glareshield panel available in the /Samples/A320 directory

SixPack Screenshot
Screenshot of the classic six pack panel available in the /Samples/SixPack directory

Features

  • Rich control set – Buttons, knobs, multi-position switches and rotary selectors, potentiometers (rotary & linear), wheels, and more.
  • Vector & texture based – Use pure vector graphics or textured animations (e.g., switch levers, rotating knobs).
  • Dynamic properties – Color, position, text, visibility driven by Lua expressions – update in real time.
  • Flexible layout – Absolute/relative positioning, polar offsets, alignment, plus series containers (RectangularSeries, CircularArray).
  • Templates – Reuse common components (annunciators, switches, buttons) with custom parameters.
  • SimConnect integration – Read simulator variables, trigger events, set input events (B: vars), and even execute calculator code via MobiFlight WASM.
  • Touch & mouse – Fully supports mouse (click, drag, wheel) and touch (tap, long press, drag).
  • Multiple panels – Combine several panels in one project; each has its own resizable, movable window.
  • Developer tools – Live reload, bounding boxes, grid overlay, output console, input event inspector.

Getting Started

Installation

  1. Download the latest AirPanelSetup.exe from the Releases page.
  2. Run the installer – it creates the program folder and subfolders:
    • Manuals/ – full tutorial and reference guide
    • Samples/ – example projects (Basic, A320, G1000, SixPack)
    • XSD/ – XML schemas for validation

Running AirPanel

  • Via welcome window – Double‑click AirPanel.exe. Use the file browser or recent projects list to open a .pnl file.
  • Direct open – Double‑click any .pnl file, or pass it as command line argument:
    AirPanel.exe MyPanel.pnl

Once open, right‑click a panel to access the context menu (connect to MSFS, zoom, saved views, developer options, etc.).

Your First Panel

Start from one of the samples in the Samples/Basic folder, e.g., Simple_Switch.pnl. It shows a 3‑position switch controlling two annunciators – entirely defined in XML + Lua, no textures required.

Project File Structure

A .pnl file is XML with a root <AirPanel> element containing:

  • <Import> – include other panel files
  • <Resources> – global textures, fonts, colors, animations
  • <Communication> – register SimVars and events
  • <Panel> – one or more panels, each with:
    • <LuaOnce> – initialization code
    • <LuaLoop> – periodic scripts (with <Delay>)
    • <Layout> – window and scene (grid, background)
    • <Entities> – all visual elements (controls, shapes, text)

Panel Example: Airbus A320 Map Mode Selector

This project defines a 5-position rotary selector for the EFIS map mode control on an Airbus A320 / A330 aircraft; works with IniBuilds Airbus family.

<?xml version="1.0" encoding="utf-8"?>
<!-- ****************** A320 EFIS map mode rotary selector example ********************** -->
 
<!-- Root element with XML Schema validation -->
<AirPanel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://github.com/hal971/AirPanel ../../XSD/AirPanel.xsd"
	xmlns="https://github.com/hal971/AirPanel" >
  
  <!-- GLOBAL RESOURCE DEFINITIONS -->
  <!-- These resources are common to all panels defined in this file or in imported files -->
  <!-- Assets like textures and fonts are preferably defined here -->
  <Resources>
    <!-- Texture for the EFIS knob graphic -->
    <Texture Name="TexEfisKnob" Path="images/EFIS_knob.png" />
    <!-- Custom font for panel text -->
    <Font Name="Gordon" Path="fonts/URW Gordon W01 Medium.ttf" />
  </Resources>

  <!-- SIMCONNECT COMMUNICATION -->
  <Communication>
    <!-- Defines the SimConnect variable for EFIS map mode
      This particular variable refers to the A320/A330 family by IniBuilds 
      The variable can be referenced via an user-defined alias -->
    <SimVar Name="L:INI_MAP_MODE_CAPT_SWITCH" Alias="map_mode_cpt_sel" Units="number" Type="double" />
  </Communication>

  <!-- PANEL CONFIGURATION -->
  <Panel Name="A320 EFIS mode ">
    <!-- LOCAL RESOURCE DEFINITIONS
          These resources are local to each panel
          Colors and Styles are preferably defined here
          Templates can be defined only locally -->
    <Resources>
      <!-- Text styling for panel labels -->
      <Style Name="PanelText" Font="Gordon" Size="14" FillColor="White" Bold="True" LetterSpacing="1" />
      <!-- Custom color definitions -->
      <Color Name="EngravingColor" R="255" G="190" B="0" />  <!-- Amber color for text and graphic -->
      <Color Name="PanelColor" R="80" G="120" B="145" />  <!-- Airbus panel color -->
    </Resources>

    <!-- VISUAL LAYOUT -->
    <Layout>
      <!-- Resizable window without tilebar -->
      <Window Width="200" Height="180" Left="200" Top="100" Antialiasing="8" Resize="true" />
      <!-- 
        Scene properties:
        - Width="0" and Height="0" means same size as window
        - Background color matches Airbus panel gray (PanelColor)
        - 10x10 grid 
      -->
      <Scene Width="0" Height="0" BackgroundColor="PanelColor" GridX="10" GridY="10" />
    </Layout>

    <!-- PANEL ELEMENTS -->
    <Entities>
      <!-- Default settings for all child elements -->
      <Default GridMode="Relative" Layer="11" Text.Layer="20"
        UpdateInterval="100" Text.Style="PanelText">

        <!-- 5-POSITION ROTARY SELECTOR -->
        <!-- dedicated Knob graphic -->
        <!-- 5 Total positions -->
        <!-- Initial rotation at 9 o'clock = -90° -->
        <!-- 45° between positions -->
        <!-- 200 ms Animation duration (rotation time between steps) -->
        <!-- Center position on (10,10) grid coordinates-->
        <!-- Use absolute grid positioning -->
        <Selector Texture="TexEfisKnob" Positions="5" RotationStart="-90" RotationStep="45" RotationTime="200" GridX="10" GridY="10" GridMode="Absolute">

          <!-- 
            POSITION DEFINITIONS
            Braces {} enclose Lua script expressions
            
            Action (Execute when selected):
            - Runs when selector enters this position
            - Sets the sim variable to corresponding mode value
            
            Trigger (Conditional rotation):
            - Continuously evaluated (every 100ms)
            - When returns true, forces selector to rotate to this position
            - Synchronizes physical position with sim state
          -->

          <!-- Position 0: LS (Landing System) -->
          <Position Index="0"
            Action="{setSimVar('map_mode_cpt_sel', 0)}"
            Trigger="{value = (getSimVar('map_mode_cpt_sel') == 0)}" />

          <!-- Position 1: VOR -->
          <Position Index="1"
            Action="{setSimVar('map_mode_cpt_sel', 1)}"
            Trigger="{value = (getSimVar('map_mode_cpt_sel') == 1)}" />

          <!-- Position 2: NAV (Navigation) -->
          <Position Index="2"
            Action="{setSimVar('map_mode_cpt_sel', 2)}"
            Trigger="{value = (getSimVar('map_mode_cpt_sel') == 2)}" />

          <!-- Position 3: ARC -->
          <Position Index="3"
            Action="{setSimVar('map_mode_cpt_sel', 3)}"
            Trigger="{value = (getSimVar('map_mode_cpt_sel') == 3)}" />

          <!-- Position 4: PLAN -->
          <Position Index="4"
            Action="{setSimVar('map_mode_cpt_sel', 4)}"
            Trigger="{value = (getSimVar('map_mode_cpt_sel') == 4)}" />

          <!-- Amber arc indicator behind the knob            
            - Since animation propagates to children elements,
              mark this as Fixed (doesn't rotate with the knob) -->
          <Arc Color="EngravingColor" Radius="45" Angle="180" Thickness="2" Rotation="180" Fixed="True" Layer="20" />

          <!-- 
            Position markers around the knob:
            - Circular array of 5 rectangles
            - 47px radius (just outside the knob)
            - 45° spacing starting at 180° (left center)
          -->
          <CircularArray Radius="47" Space="45" StartAngle="180" ElementsCount="5" RotateElements="true">
            <Rectangle FillColor="EngravingColor" Width="6" Height="2" OutlineThickness="0" Layer="20" Fixed="True" />
          </CircularArray>
        </Selector>

        <!-- MODE LABELS AROUND THE KNOB -->
        <!-- A CircularSeries places different elements in a regular circular pattern -->
        <CircularSeries Radius="60" Space="45" StartAngle="180" RotateElements="False">         
          <Text FillColor="EngravingColor" String="LS" />                         <!-- Position 0 -->
          <Text FillColor="EngravingColor" String="VOR" DeltaX="-5" DeltaY="5" /> <!-- Position 1 -->
          <Text FillColor="EngravingColor" String="NAV" />                        <!-- Position 2 -->
          <Text FillColor="EngravingColor" String="ARC" DeltaX="7" DeltaY="5" />  <!-- Position 3 -->
          <Text FillColor="EngravingColor" String="PLAN" DeltaX="8" />            <!-- Position 4 -->
        </CircularSeries>
      </Default>
    </Entities>
  </Panel>
</AirPanel>

EFIS knob Screenshot
Screenshot of the rendered selector

Documentation

  • Full Tutorial & Reference – Installed with AirPanel (Manuals/ folder) or available on the GitHub repo.
  • XML Schema – Use XSD/AirPanel.xsd in your editor for auto‑completion and validation.

Examples

Check out sample panels in the /Samples directory:

  • Basic Samples - basic panels ranging from a simple 3-position switch to a more complex panel with multiple switches and annunciators
  • A320_Glareshield.pnl - Airbus A320 FCU, EFIS and warning lights in a single panel
  • A320_MCDU.pnl - Airbus A320 MCDU with transparent background to overlay the panel onto the MCDU screen detached from the virtual cockpit
  • G1000_PFD.pnl and G1000_MFD.pnl - Garmin G1000 PFD and MFD units with transparent background
  • SixPack.pnl - Panel with the classic six primary instruments of an aircraft

Acknowledgements

AirPanel would not exist without these great open‑source projects:

  • SFML – Graphics, windowing, input
  • pugixml – Fast XML parsing
  • Dear ImGui – Menus & dialogs
  • Lua – Embedded scripting

License

AirPanel is released under the GPLv3 License. See LICENSE for details.


Have questions or ideas? Open an issue on GitHub.

About

Air Panel is a software for creating 2D aircraft panels for Microsoft Flight Simulator 2020/2024

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors