API - draw inverted text mask

Help creating logic scripts for Air Manager Instruments

Moderators: russ, Ralph

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

API - draw inverted text mask

#1 Post by Detlef »

Hi all,

I am currently trying to generate an annunciator panel for the Saab 340B and I want to mimic the old-style non-perfect look of the annunciator lamps. They shine through not perfectly red or yellow in one color but actually for example the red text has some yellow dots in it. I can do that with Skinman (great program!) but only if I draw each of the 40 annunc lights separately.

I like to program that in Lua, but for that I would need a way to write black text on a transparent canvas and then invert that as a mask, so that the text color becomes the alpha channel and the text background is black. Is that possible? - I am not sure I make myself understandable :)

Thank you
Detlef

Oh and when did I say last, that I am totally fascinated by now, by what you can do with programming instruments in Airmanager? So now I said it.

User avatar
Sling
Posts: 5237
Joined: Mon Sep 11, 2017 2:37 pm
Contact:

Re: API - draw inverted text mask

#2 Post by Sling »

I don’t think that’s possible with canvas but you don’t need to draw each one. You just need the text mask, a background of the unlit state and one annunciator of each colour.

User avatar
Keith Baxter
Posts: 4674
Joined: Wed Dec 20, 2017 11:00 am
Location: Botswana

Re: API - draw inverted text mask

#3 Post by Keith Baxter »

Hi,

You can do something like this in canvas. You will need to play around with the the gradient and opacity.

Note 8 digit hex code is supported. The 7th and 8 digit being the opacity. This is useful when you want to change the opacity of just one color in the gradient.

Code: Select all

digm_52blkC            ="font:digital-7-mono.ttf;           size:52px; color: #202020; halign:center; valign:center;"
digm_52witC            ="font:digital-7-mono.ttf;           size:52px; color: yellow; halign:center; valign:center;"
digm_50witC            ="font:digital-7-mono.ttf;           size:51px; color: red; halign:center; valign:center;"
my_canvas=canvas_add(0,0,500,500)
bat_lit=0

canvas_draw(my_canvas, function()
 _rect(100,210,300,80)
 _fill("#000000")
 _rect(100,210,300,80)
 _fill_gradient_box(120,225,260,50,10,40,"#333333","#00000033")
 _txt("BATTERY",digm_52blkC,250,250)
 
 _rect(460,460,40,40)
 _fill("blue")
end)

function annunciator()
canvas_draw(my_canvas, function()
 _rect(100,210,300,80)
 _fill("#000000")

 _rect(100,210,300,80)
 _fill_gradient_box(120,225,260,50,10,40,"#333333","#00000033")
 _txt("BATTERY",digm_52blkC,250,250)
 _txt("BATTERY",digm_52witC,250,250,bat_lit)
 _txt("BATTERY",digm_50witC,250,250,bat_lit)
 
 _rect(460,460,40,40)
 _fill("blue")
end)
end
function callback_pressed()
   bat_lit=bat_lit+1
   if bat_lit>1 then bat_lit =0 end
   
   annunciator()
end

button_id = button_add(nil,nil, 460,460,40,40,callback_pressed)

Keith
AMD RYZEN 9 5950X CPU, Corsair H80I cooler, ASUS TUF GAMING B550-PLUS AMD Ryzen Mother Board,  32Gb ram Corsair Vengeance 3000Mh, MSI GTX960 4G graphics card 

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

Re: API - draw inverted text mask

#4 Post by Detlef »

Hi Keith,

thank you for the example code! I tried it. Pretty amazing what you can do with those parameters. For now I think I go with the text masks like Tony suggested.

Thank you
Detlef

User avatar
Keith Baxter
Posts: 4674
Joined: Wed Dec 20, 2017 11:00 am
Location: Botswana

Re: API - draw inverted text mask

#5 Post by Keith Baxter »

Detlef wrote: Wed Apr 28, 2021 8:47 am Hi Keith,

thank you for the example code! I tried it. Pretty amazing what you can do with those parameters. For now I think I go with the text masks like Tony suggested.

Thank you
Detlef
Joe did this with just three images. He used photoshop I think.
He was sharing his screen last night. I am sure he will assist if you ask him.
ann.png
Keith
AMD RYZEN 9 5950X CPU, Corsair H80I cooler, ASUS TUF GAMING B550-PLUS AMD Ryzen Mother Board,  32Gb ram Corsair Vengeance 3000Mh, MSI GTX960 4G graphics card 

JackZ
Posts: 2262
Joined: Mon Feb 22, 2016 1:02 pm

Re: API - draw inverted text mask

#6 Post by JackZ »

Hi.
Though I understand the power of canvas draw(), I don’t think that it is to be used for every purpose.

I made recently a quite complicated Annunciator panel in Skinman with only one background image for the unlit state and individual images for the lit state of each annunciator. Much more flexibility over the final result, and easy to code, just have to play with visible().
TBH I am not talking about the annunciator logic itself which was a nightmare, involving binary operations and intercommunication between instruments and gauges, since it has to trigger the MASTER WARNING buttons as well.
It even has a test button, that required to keep the current state of each annunciator before lighting them up.
And dual brightness. More than 1100 lines of code for this very instrument only.
377A6781-540C-4079-960F-F6F4691499D9.jpeg
18265D16-8FE5-43BD-AC82-E4C39C9AB9D8.jpeg
annum tests2.JPG
Annums.JPG
Jacques
Last edited by JackZ on Wed Apr 28, 2021 11:08 am, edited 2 times in total.
My YouTube Chanel on the A320 (Real SOPs by an Airline Pilot IRL):
https://www.youtube.com/playlist?list=P ... 0Q6SBASRqJ

User avatar
Keith Baxter
Posts: 4674
Joined: Wed Dec 20, 2017 11:00 am
Location: Botswana

Re: API - draw inverted text mask

#7 Post by Keith Baxter »

JackZ wrote: Wed Apr 28, 2021 10:42 am Hi.
Though I understand the power of canvas draw(), I don’t think that it is to be used for every purpose.
100's Jacques,

I also do as you say for annunciators.

However with a slight differance. I use _fill_img() in a canvas and control the visibility via opacity. OR

You can also have all the lit "my_image.png" in a table so that they are not ALL loaded.

Code: Select all

lit_ann_table={"my_image1","my_image2","my_image3","my_image4"......
off_ann_table={"","","",""......
Example..
By changing the state from "off" to "lit", you only load those images that are lit.


No image loaded off state

Code: Select all

state="off"
_rect(0,0,40,20)
_fill_img(state.._ann_table[2],0,0,40,20)

Lit image loaded lit state

Code: Select all

state="lit"
_rect(0,0,40,20)
_fill_img(state.._ann_table[2],0,0,40,20
Keith
AMD RYZEN 9 5950X CPU, Corsair H80I cooler, ASUS TUF GAMING B550-PLUS AMD Ryzen Mother Board,  32Gb ram Corsair Vengeance 3000Mh, MSI GTX960 4G graphics card 

User avatar
Sling
Posts: 5237
Joined: Mon Sep 11, 2017 2:37 pm
Contact:

Re: API - draw inverted text mask

#8 Post by Sling »

@Keith Baxter

I’ve just finished up my caravan panels so been doing a bit of flying behind that annunciator panel.

As others have said the graphics and the basic code for turning the lights on and off even with a lamp test and dimming is easy enough. It’s all the logic behind it that takes some time to perfect. I think I’m there now with my caravan. In addition to the lights themselves I also added extra custom logic on top of whats modelled in the sim to get it to behave like the real one. Even got warning horns for VMO and fuel select warnings in there. I’ll do a video at some point I’m sure.

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

Re: API - draw inverted text mask

#9 Post by Detlef »

Jaques and all,

wow! Your panels look really good. I agree with you, I had to use normal img_add function instead of canvas functions here. I simple could not fill the same canvas twice. I wanted (1) a background image from a file and (2) a text mask from a file. Well, I am getting there, work ongoing.
try1.PNG
I also used arrays, with a non number index here because the Saab shows them that way:

Code: Select all

local ImgBackground = img_add_fullscreen("cwp-empty.png")
local gTextStyleLamp = "font:arimo_regular.ttf; size:25"
gLamp = {}

gAmber = string.format("#%02X%02X%02X", 255, 155, 19)
gRed = string.format("#%02X%02X%02X", 255, 0, 0)

L_RED = "bg-red.png"
L_AMBER = "bg-amber.png"
L_OFF = "no-text.png"

local gDim = {}
gDim.x_start = 61
gDim.y_start = 53
gDim.frame_width = 150
gDim.frame_height = 75
gDim.x_step = 150
gDim.y_step = 78

local gColumn = {}
  gColumn.A = 1
  gColumn.B = 2
  gColumn.C = 3
  gColumn.D = 4

for k=0, 39 do
  x = k % 4 * gDim.x_step + gDim.x_start
  y = math.floor(k/4) * gDim.y_step + gDim.y_start
  img_add("frame.png", x, y, gDim.frame_width, gDim.frame_height)
end


function AddLamp(index, file, color)
-- index e.g. "A1", "D2", .. "C10" ..
  local w
  gLamp[index] = {}
  local w = gLamp[index]
  
  if resource_info(file) == nil then
    print("Error: Cannot open " .. file)
    return
  end
  
  if resource_info(color) == nil then
    print("Error: Cannot open " .. color)
    return
  end
  
  local column = gColumn[string.sub(index, 1, 1)]-1  -- starts with 0
  local line = tonumber(string.sub(index, 2, 3)) - 1 -- start with 0
  local x = gDim.x_start + 7 + (column * gDim.x_step)
  local y = gDim.y_start + 6 + (line * gDim.y_step)
  w.width = 132
  w.height = 58

  w.id_off = img_add(L_OFF, x, y, w. width, w.height)
  visible(w.id_off, false)
  
  w.id_on_bg = img_add(color, x, y, w.width, w.height, "visible:false")
  w.id_on_text = img_add(file, x, y, w.width, w.height, "visible:false")
  visible(w.id_on_bg, true)
  visible(w.id_on_text, true)
end

AddLamp("A1", "a1-leng-fire.png", L_RED)
AddLamp("D1", "d1-reng-fire.png", L_RED)
AddLamp("A2", "a2-leng-oilpress.png", L_RED)
AddLamp("C2", "c2-cabin-press.png", L_RED)
AddLamp("D2", "d2-reng-oilpress.png", L_RED)
AddLamp("B3", "double-bar.png", L_RED)
AddLamp("C3", "c3-prop-brake.png", L_RED)
AddLamp("A4", "double-bar.png", L_RED)
AddLamp("B4", "b4-auto-trim.png", L_RED)
AddLamp("C4", "c4-config.png", L_RED)
AddLamp("D4", "double-bar.png", L_RED)
AddLamp("A5", "a5-auto-coarsen.png", L_AMBER)
AddLamp("B5", "double-bar.png", L_AMBER)
AddLamp("C5", "c5-pitch-trim.png", L_AMBER)
AddLamp("D5", "d5-rudder-limit.png", L_AMBER)
AddLamp("B6", "b6-fuel.png", L_AMBER)
AddLamp("C6", "c6-elec.png", L_AMBER)
AddLamp("A7", "a7-ice-prot.png", L_AMBER)
AddLamp("B7", "b7-engine.png", L_AMBER)
AddLamp("D7", "d7-air-cond.png", L_AMBER)
AddLamp("A8", "a8-park-brkon.png", L_AMBER)
AddLamp("B8", "b8-hydr.png", L_AMBER)
AddLamp("C8", "c8-emer-ltsunarmed.png", L_AMBER)
AddLamp("D8", "d8-oxygen.png", L_AMBER)
AddLamp("A9", "a9-askid-inop.png", L_AMBER)
AddLamp("B9", "b9-avionics.png", L_AMBER)
AddLamp("D9", "d9-doors.png", L_AMBER)
AddLamp("A10", "a10-lstall-fail.png", L_AMBER)
AddLamp("B10", "b10-gust-lock.png", L_AMBER)
AddLamp("C10", "c10-pusher-system.png", L_AMBER)
AddLamp("D10", "d10-rstall-fail.png", L_AMBER)


function SwitchLampOn(index, to_on)
  local w = gLamp[index]
  visible(w.id_off, not to_on)
  visible(w.id_on_bg, to_on)
  visible(w.id_on_text, to_on)
end


-- SwitchLampOn("A2", true)
-- SwitchLampOn("C2", true)
-- SwitchLampOn("B3", true)


JackZ
Posts: 2262
Joined: Mon Feb 22, 2016 1:02 pm

Re: API - draw inverted text mask

#10 Post by JackZ »

@Detlef Nice idea, I like your addressing of each lamp by indexes, that should save a lot of code.

Good work!

Jacques
My YouTube Chanel on the A320 (Real SOPs by an Airline Pilot IRL):
https://www.youtube.com/playlist?list=P ... 0Q6SBASRqJ

Post Reply