demo.lua 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. --debug interception for remote train control
  2. local debug_state = false
  3. if debug_state then
  4. if event.channel=="touch" and event.msg.send_train then digiline_send("send_train","") return end
  5. end
  6. --some basic settings
  7. local occupied = "^[colorize:#34ebd5" --colour of occupied sections
  8. local offset_x = 0.0 --positioning track icons
  9. local offset_y = -0.4 --positioning track icons
  10. local icon_h = 0.8 --track icon sizes
  11. local icon_w = 1 --track icon sizes
  12. local bg = {['W']=12.4,['H']=6} --background size
  13. --[[shorthand for the icons
  14. diag_u = "switchpanel_diag.png"
  15. diag_d = "switchpanel_diag.png^[transformFX"
  16. sw_u_cr = "switchpanel_switch_CR.png"
  17. sw_u_st = "switchpanel_switch_ST.png"
  18. sw_u_rev_cr = "switchpanel_switch_CR.png^[transformFX"
  19. sw_u_rev_st = "switchpanel_switch_ST.png^[transformFX"
  20. sw_d_cr = "switchpanel_switch_CR.png^[transformFY"
  21. sw_d_st = "switchpanel_switch_ST.png^[transformFY"
  22. sw_d_rev_cr = "switchpanel_switch_CR.png^[transformR180"
  23. sw_d_rev_st = "switchpanel_switch_ST.png^[transformR180"
  24. swd_u_st = "switchpanel_switch_diag_ST.png"
  25. swd_u_cr = "switchpanel_switch_diag_CR.png"
  26. swd_u_rev_st = "switchpanel_switch_diag_ST.png^[transformFX"
  27. swd_u_rev_cr = "switchpanel_switch_diag_CR.png^[transformFX"
  28. swd_d_st = "switchpanel_switch_diag_ST.png^[transformFY"
  29. swd_d_cr = "switchpanel_switch_diag_CR.png^[transformFY"
  30. swd_d_rev_cr = "switchpanel_switch_diag_CR.png^[transformR180"
  31. swd_d_rev_st = "switchpanel_switch_diag_ST.png^[transformR180"
  32. cnr_u = "switchpanel_corner.png"
  33. cnr_d = "switchpanel_corner.png^[transformFY"
  34. cnr_u_rev = "switchpanel_corner.png^[transformR180"
  35. cnr_d_rev = "switchpanel_corner.png^[transformFX"
  36. ]]--
  37. --function to assemble rotatable icon strings
  38. local ico = function(variant,rotation,state)
  39. local parts = {
  40. ['sw'] = "switch_",
  41. ['swd'] = "switch_diag_",
  42. ['diag'] = "diag",
  43. ['cnr'] = "corner",
  44. ['u'] = "",
  45. ['d'] = "^[transformFY",
  46. ['u_rev'] = "^[transformFX",
  47. ['d_rev'] = "^[transformR180",
  48. }
  49. if state == nil then state = "" end
  50. return string.format("switchpanel_%s%s.png%s",parts[variant],state,parts[rotation])
  51. end
  52. -- static icons
  53. local lin = "switchpanel_line.png"
  54. local eol = "switchpanel_eol.png"
  55. local eol_rev = eol.."^[transformFX"
  56. local background = "switchpanel_background.png"
  57. local blank = ""
  58. --utility functions
  59. local tableLength = function(T)
  60. local count = 0
  61. for _ in pairs(T) do count = count + 1 end
  62. return count
  63. end
  64. local update = false
  65. local maps = {
  66. [1] = {
  67. ['header'] = {
  68. {command="addlabel",label="<--- WEST",X=icon_w*1,Y=0},
  69. {command="addlabel",label="EAST --->",X=icon_w*7,Y=0},
  70. {command="addlabel",label="MAIN STATION",X=bg.W/3,Y=0}
  71. },
  72. ['base_map'] = {
  73. {blank, blank, ico("cnr","u",nil), lin,lin, ico("cnr","u_rev",nil), },
  74. {blank, {"main_sw3"}, lin, lin,lin, lin, {"main_sw5"}, },
  75. {{"main_sw1"}, lin, lin, lin,lin, lin, lin, {"main_sw7"}} ,
  76. {blank, ico("cnr","u",nil), lin, lin,lin, lin, lin, {"main_sw8"}} ,
  77. {{"main_sw2"}, {"main_sw4"}, lin, lin,lin, lin, {"main_sw6"}, },
  78. {blank, blank, ico("cnr","d",nil), lin,lin, ico("cnr","d_rev",nil), },
  79. },
  80. ['labels'] = {
  81. {blank, blank, blank, "Platform 1"},
  82. {blank, "SW3", blank, "Platform 2",blank,blank,{"SW5","under"}},
  83. {"SW1", blank, blank, "Platform 3",blank,blank,blank,{"SW7","under"}},
  84. {blank, blank, blank, "Platform 4",blank,blank,blank,"SW8"},
  85. {"SW2", "SW4", blank, "Platform 5",blank,blank,"SW6"},
  86. {blank, blank, blank, "Platform 6"}
  87. },
  88. ['sections'] = {
  89. {blank, blank, "417397", {"417397"}, "417397", "619097",},
  90. {blank, "344217", "201022", {"201022"}, "201022", "201022", "619097",},
  91. {{"186996"}, "186996", "498166", {"498166"}, "498166", "498166", "498166", "657546"},
  92. {blank, "767660", "767660", {"767660"}, "767660", "767660", "767660", "170582"},
  93. {{"012237"}, "012237", "857538", {"857538"}, "857538", "857538", "142366",},
  94. {blank, blank, "078069", {"078069"}, "078069", "078069",},
  95. },
  96. ['points'] = {
  97. ['main_sw1'] = {['button_pos'] = {['x']=0.5,['y']=5.4},['pos']={['x']=433,['y']=2,['z']=-84},['icon'] = {"sw","u"}},
  98. ['main_sw2'] = {['button_pos'] = {['x']=0.5,['y']=6.4},['pos']={['x']=435,['y']=2,['z']=-87},['icon'] = {"swd","u"}},
  99. ['main_sw3'] = {['button_pos'] = {['x']=0.5,['y']=7.4},['pos']={['x']=443,['y']=2,['z']=-68},['icon'] = {"swd","u"}},
  100. ['main_sw4'] = {['button_pos'] = {['x']=3.5,['y']=5.4},['pos']={['x']=441,['y']=2,['z']=-84},['icon'] = {"sw","d"}},
  101. ['main_sw5'] = {['button_pos'] = {['x']=3.5,['y']=6.4},['pos']={['x']=485,['y']=2,['z']=-66},['icon'] = {"swd","u_rev"}},
  102. ['main_sw6'] = {['button_pos'] = {['x']=3.5,['y']=7.4},['pos']={['x']=485,['y']=2,['z']=-81},['icon'] = {"swd","d_rev"}},
  103. ['main_sw7'] = {['button_pos'] = {['x']=7.5,['y']=5.4},['pos']={['x']=497,['y']=2,['z']=-72},['icon'] = {"sw","u_rev"}},
  104. ['main_sw8'] = {['button_pos'] = {['x']=7.5,['y']=6.4},['pos']={['x']=497,['y']=2,['z']=-75},['icon'] = {"sw","d_rev"}},
  105. }
  106. },
  107. [2] = {
  108. ['header'] = {
  109. {command="addlabel",label="<--- SOUTH",X=icon_w*1,Y=0},
  110. {command="addlabel",label="NORTH --->",X=icon_w*7,Y=0},
  111. {command="addlabel",label="Main<->Testfield",X=bg.W/3,Y=0},
  112. {command="addlabel",label="Icefields Passing Loop",X=bg.W/3,Y=0.25},
  113. {command="addlabel",label="Cliffside Passing Loop",X=bg.W/3,Y=1.75},
  114. },
  115. ['base_map'] = {
  116. {blank, ico("cnr","u",nil), lin, lin, {"tf_2"},lin},
  117. {{"tf_1"}, lin, lin, ico("cnr","d_rev",nil)},
  118. {blank,ico("cnr","u",nil),lin,lin,{"tf_4"},lin},
  119. {{"tf_3"},lin,lin,ico("cnr","d_rev",nil)}
  120. },
  121. ['labels'] = {
  122. {blank},
  123. {blank}
  124. },
  125. ['sections'] = {
  126. {blank, "272990", {"272990"}, "272990","851349", {"851349"}},
  127. {"986637", {"986637"}, "948558", "948558"},
  128. {blank,"903385",{"903385"},"903385","903385",{"481617"}},
  129. {{"851349"},{"614460"},"614460","614460"}
  130. },
  131. ['points'] = {
  132. ['tf_1'] = {['pos'] = {['x']=620,['y']=2,['z']=-66},['icon'] = {"swd","u"}},
  133. ['tf_2'] = {['pos'] = {['x']=679,['y']=2,['z']=-8},['icon'] = {"sw","d_rev"}},
  134. ['tf_3'] = {['pos'] = {['x']=926,['y']=2,['z']=150},['icon'] = {"sw","u"}},
  135. ['tf_4'] = {['pos'] = {['x']=960,['y']=2,['z']=189},['icon'] = {"sw","d_rev"}},
  136. }
  137. }
  138. }
  139. --quick access to relevant map
  140. local c_map = maps[S.active_map or 1]
  141. --shorthand function to assemble the switch icon in current state
  142. local pt = function(turnout)
  143. -- local id = c_map.points[turnout]
  144. local id = turnout
  145. if debug_state then print(id) end
  146. local state = getstate(id.pos)
  147. state = string.upper(state)
  148. local locked = ""
  149. if has_route_lock then -- check if function is available
  150. if has_route_lock(id.pos) then
  151. locked = "^[colorize:#FF0000"
  152. end
  153. end
  154. return ico(id.icon[1],id.icon[2],state)..locked
  155. end
  156. if event.channel=="touch" then
  157. local msg = event.msg
  158. if type(c_map)=="table" then
  159. if c_map.points then
  160. for k,_ in pairs(msg) do
  161. if c_map.points[k] then
  162. local c_state = getstate(c_map.points[k]['pos'])
  163. local n_state = ""
  164. if c_state == "st" then
  165. n_state = "cr"
  166. else
  167. n_state = "st"
  168. end
  169. setstate(c_map.points[k]['pos'],n_state)
  170. end
  171. end
  172. end
  173. end
  174. update = true
  175. end
  176. --manual update by punching ops panel or luacontroller clock
  177. if event.punch or (event.channel=="display" and event.msg=="update")then
  178. update = true
  179. end
  180. if update == true then
  181. ----reset base layers
  182. local display = {
  183. {command="clear"},
  184. {command="addimage",texture_name=background,X=0,Y=0,W=bg.W,H=bg.H},
  185. {command="addbutton",name="update",label="Manual Refresh",X=7.5,Y=7.4,W=2.5,H=1},
  186. }
  187. if type(c_map)== "table" then
  188. --establish controls
  189. if c_map.points then
  190. for k,v in pairs(c_map.points) do
  191. if v.button_pos then
  192. if not v.display_name then v.display_name = k end
  193. table.insert(display,{command="addbutton",name=k,label=v.display_name,X=v.button_pos.x,Y=v.button_pos.y,W=2,H=1,})
  194. end
  195. end
  196. end
  197. --define complete map
  198. if c_map.base_map then
  199. for y,row in ipairs(c_map.base_map) do
  200. for x,v in ipairs(row) do
  201. if type(v)== "table" then v = pt(c_map.points[v[1]]) end
  202. if v ~= blank then
  203. if c_map.sections ~= nil then
  204. local show_ids = false
  205. local section = c_map.sections[y][x]
  206. if type(section) == "table" then
  207. section = section[1]
  208. show_ids = true
  209. end
  210. local sect_occ = section_occupancy(section)
  211. if type(sect_occ) == "table" and (sect_occ[1] ~= nil) then
  212. v = v..occupied
  213. if show_ids == true then
  214. table.insert(display,{
  215. command="addlabel",
  216. label=table.concat(sect_occ,", "),
  217. X=(icon_w*x)+offset_x,Y=(icon_h*y)+offset_y+0.3
  218. })
  219. end
  220. end
  221. end
  222. table.insert(display,{
  223. command="addimage",
  224. texture_name=v,
  225. X=(icon_w*x)+offset_x,Y=(icon_h*y)+offset_y,
  226. W=1.2*icon_w,H=icon_h
  227. })
  228. end
  229. end
  230. end
  231. end
  232. --add labels
  233. if c_map.labels then
  234. for y,row in ipairs(c_map.labels) do
  235. for x,v in ipairs(row) do
  236. if v ~= blank and v ~= nil then
  237. local pos = {['x'] = (icon_w*x)+offset_x, ['y'] = (icon_h*y)+offset_y-0.1}
  238. local label = ""
  239. if type(v) == "table" then
  240. label = v[1]
  241. if v[2] == "under" then pos.y = pos.y+0.5 end
  242. else
  243. label = v
  244. end
  245. table.insert(display,{
  246. command="addlabel",
  247. label=label,
  248. X=pos.x,Y=pos.y
  249. })
  250. end
  251. end
  252. end
  253. end
  254. --add headers/labels/graphics
  255. if c_map.header then
  256. for _,v in ipairs(c_map.header) do
  257. table.insert(display,v)
  258. end
  259. end
  260. else
  261. table.insert(display,{command="addlabel",label="Map "..tostring(S.active_map).." Not Defined Yet",X=1,Y=1})
  262. end
  263. --add debug train controls if enabled
  264. if debug_state then
  265. table.insert(display,{command="addbutton",name="send_train",label="Send Train",X=7.5,Y=7.5,W=2,H=1})
  266. end
  267. --draw
  268. digiline_send("touch",display)
  269. end