_LibreLightDesk.py 78 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327
  1. #! /usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. """
  4. This file is part of LibreLight.
  5. LibreLight is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 2 of the License, or
  8. (at your option) any later version.
  9. LibreLight is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with LibreLight. If not, see <http://www.gnu.org/licenses/>.
  15. (c) 2012 micha.rathfelder@gmail.com
  16. """
  17. import random
  18. rnd_id = str(random.randint(1000,9000))
  19. rnd_id += " Beta 22.01"
  20. try:
  21. xtitle = __file__
  22. except:
  23. xtitle = "__file__"
  24. if "/" in xtitle:
  25. xtitle = xtitle.split("/")[-1]
  26. import sys
  27. sys.stdout.write("\x1b]2;"+str(xtitle)+" "+str(rnd_id)+"\x07") # terminal title
  28. import json
  29. import time
  30. import sys
  31. import _thread as thread
  32. import traceback
  33. import tkinter
  34. import tkinter as tk
  35. from tkinter import font
  36. import tkinter.simpledialog
  37. import lib.chat as chat
  38. import lib.motion as motion
  39. from collections import OrderedDict
  40. show_name = "GloryCamp2021"
  41. #show_name = "JMS"
  42. #show_name = "Dimmer"
  43. CUES = OrderedDict()
  44. groups = OrderedDict()
  45. class Modes():
  46. def __init__(self):
  47. self.modes = {}
  48. self.__cfg = {}
  49. self.__cb = None
  50. def val(self,mode,value=None):
  51. if value is not None:
  52. return self.set(mode,value)
  53. elif mode in self.modes:
  54. return self.modes[mode]
  55. def get(self,mode,value=None):
  56. return slef.val(mode,value)
  57. def __check(self,mode):
  58. if mode not in self.modes:
  59. self.modes[mode] = 0
  60. self.__cfg[mode] = 0
  61. def cfg(self,mode,data={}):
  62. self.__check(mode)
  63. if type(data) is dict:
  64. for k in data:
  65. v = data[k]
  66. if v not in self.__cfg:
  67. self.__cfg[k] = v
  68. return 1
  69. elif type(data) is str:
  70. if data in self.__cfg:
  71. return self.__cfg[data]
  72. def set(self,mode,value):
  73. protected = ["BLIND","CLEAR"]
  74. self.__check(mode)
  75. out = 0
  76. if mode == "CLEAR":
  77. return 1
  78. elif mode == "ESC":
  79. for m in self.modes:
  80. print("ESC",m)
  81. if m == "COPY":
  82. PRESETS.clear_copy()
  83. if m == "MOVE":
  84. PRESETS.clear_move()
  85. if m != "BLIND":
  86. self.modes[m] = 0
  87. self.callback(m)
  88. out = 1
  89. return 1
  90. elif value:
  91. for m in self.modes:
  92. if m not in protected and mode not in protected and m != mode:
  93. if self.modes[m]:
  94. self.modes[m]= 0
  95. self.callback(m)
  96. if self.modes[mode]:
  97. if modes == "MOVE":
  98. PRESETS.clear_move()
  99. if modes == "COPY":
  100. PRESETS.clear_copy()
  101. self.modes[mode] = 0 # value
  102. else:
  103. self.modes[mode] = 1 #value
  104. out = 1
  105. else:
  106. self.modes[mode] = 0 #value
  107. if modes == "COPY":
  108. PRESETS.clear_copy()
  109. if modes == "MOVE":
  110. PRESETS.clear_move()
  111. self.callback(mode)
  112. return value
  113. def set_cb(self,cb):
  114. if cb:
  115. self.__cb = cb
  116. def callback(self,mode):
  117. if self.__cb is not None and mode in self.modes:
  118. value = self.modes[mode]
  119. self.__cb(mode=mode,value=value)
  120. modes = Modes()
  121. #modes.val("BLIND", 0)
  122. #modes.modes["BLIND"] = 0
  123. modes.modes["ESC"] = 0
  124. modes.modes["STORE"] = 0
  125. modes.modes["EDIT"] = 0
  126. modes.modes["MOVE"] = 0
  127. modes.modes["FLASH"] = 0
  128. modes.modes["GO"] = 0
  129. modes.modes["DEL"] = 0
  130. modes.modes["STONY_FX"] = 0
  131. modes.modes["SELECT"] = 0
  132. modes.modes["CFG-BTN"] = 0
  133. modes.modes["LABEL"] = 0
  134. def xcb(mode,value=None):
  135. print("xcb","MODE CALLBACK",mode,value)
  136. #modes.set_cb(xcb)
  137. POS = ["PAN","TILT","MOTION"]
  138. COLOR = ["RED","GREEN","BLUE","COLOR"]
  139. BEAM = ["GOBO","G-ROT","PRISMA","P-ROT","FOCUS","SPEED"]
  140. INT = ["DIM","SHUTTER","STROBE","FUNC"]
  141. client = chat.tcp_sender()
  142. fade = 2 #2 #0.1 #1.13
  143. fade_on = 1
  144. fx_prm = {"SIZE":20,"SPEED":100,"OFFSET":50,"BASE":"-","START":0}
  145. def build_cmd(dmx,val,args=[fade],flash=0,xpfx="",attr=""):
  146. cmd=""
  147. if xpfx:
  148. pfx=xpfx
  149. elif flash:
  150. pfx ="df"
  151. else:
  152. pfx ="d"
  153. if type(val) is float or type(val) is int:
  154. cmd += ",{}{}:{:0.4f}".format(pfx,dmx,val)
  155. else:
  156. cmd += ",{}{}:{}".format(pfx,dmx,val)
  157. if flash:
  158. cmd += ":0:0"#.format(val)
  159. else:
  160. for val in args:
  161. if type(val) is float or type(val) is int:
  162. cmd += ":{:0.4f}".format(val)
  163. else:
  164. cmd += ":{}".format(val)
  165. if attr:
  166. cmd += ":"+str(attr)
  167. return cmd
  168. def update_raw_dmx(data ,value=None,args=[fade],flash=0,pfx="d",fx=0):
  169. cmd = []
  170. if flash:
  171. pfx += "f"
  172. for row in data:
  173. if fx:
  174. if value is not None:
  175. # z.b. flush off
  176. xcmd = str(value)+":"+row["FX"].split(":",1)[-1]
  177. else:
  178. xcmd = row["FX"]
  179. else:
  180. if row["VALUE"] is None:
  181. xcmd = ""
  182. else:
  183. if value is not None:
  184. if type(value) is float:
  185. xcmd = "{:0.4f}".format(value)
  186. else:
  187. xcmd = "{}".format(value)
  188. else:
  189. xcmd = "{:0.4f}".format(row["VALUE"])
  190. for arg in args:
  191. if type(arg) is float:
  192. xcmd += ":{}".format(arg)
  193. else:
  194. xcmd += ":{:0.4f}".format(arg)
  195. #print( "pack: FIX",row["FIX"],row["ATTR"], xcmd)
  196. #xcmd += ":{}".format(row["ATTR"])
  197. cmd.append( xcmd)
  198. return cmd
  199. def update_dmx(attr,data,value=None,args=[fade],flash=0,pfx=""):
  200. #global modes #BLIND
  201. #print("update_dmx",data)
  202. dmx = data["DMX"]
  203. dmx = (data["UNIVERS"]*512)+data["DMX"]
  204. val = None
  205. cmd=""
  206. try:
  207. if attr == "DIM" and data["ATTRIBUT"][attr]["NR"] < 0: #VDIM
  208. #print( "VDIM")
  209. for attr in data["ATTRIBUT"]:
  210. dmx = (data["UNIVERS"]*512) + data["DMX"]
  211. dmx = data["DMX"]
  212. if data["ATTRIBUT"][attr]["NR"] < 0: #virtual channels
  213. continue
  214. dmx += data["ATTRIBUT"][attr]["NR"]-1
  215. mode = ""
  216. if "MODE" in data["ATTRIBUT"][attr]:
  217. mode = data["ATTRIBUT"][attr]["MODE"]
  218. #print(attr)
  219. val = data["ATTRIBUT"][attr]["VALUE"]
  220. if data["ATTRIBUT"][attr]["MASTER"]:
  221. val = val * (data["ATTRIBUT"]["DIM"]["VALUE"] / 255.)
  222. if val is not None:
  223. #cmd += ",d{}:{:0.4f}".format(dmx,int(val))
  224. if value is not None:
  225. val = value
  226. if mode == "F": #FADE
  227. cmd += build_cmd(dmx,val,args=args,flash=flash,xpfx=pfx,attr=attr)
  228. else:
  229. cmd += build_cmd(dmx,val,args=[0],flash=flash,xpfx=pfx,attr=attr)
  230. #print("cmd",cmd)
  231. elif data["ATTRIBUT"][attr]["NR"] > 0:
  232. dmx += data["ATTRIBUT"][attr]["NR"]-1
  233. val = data["ATTRIBUT"][attr]["VALUE"]
  234. mode = ""
  235. if "MODE" in data["ATTRIBUT"][attr]:
  236. mode = data["ATTRIBUT"][attr]["MODE"]
  237. if data["ATTRIBUT"][attr]["MASTER"]:
  238. #if "VDIM" in data["ATTRIBUT"]:
  239. if "DIM" in data["ATTRIBUT"] and data["ATTRIBUT"]["DIM"]["NR"] < 0: #VDIM
  240. val = val * (data["ATTRIBUT"]["DIM"]["VALUE"] / 255.)
  241. if val is not None:
  242. #cmd += ",d{}:{}".format(dmx,int(val))
  243. if value is not None:
  244. val = value
  245. if mode == "F": #FADE
  246. cmd += build_cmd(dmx,val,args=args,flash=flash,xpfx=pfx,attr=attr)
  247. else:
  248. cmd += build_cmd(dmx,val,args=[0],flash=flash,xpfx=pfx,attr=attr)
  249. #print("cmd",cmd)
  250. if modes.val("BLIND"):
  251. cmd=""
  252. return cmd
  253. except Exception as e:
  254. cprint("== cb EXCEPT",e,color="red")
  255. cprint("Error on line {}".format(sys.exc_info()[-1].tb_lineno),color="red")
  256. cprint(''.join(traceback.format_exception(None, e, e.__traceback__)),color="red")
  257. raise e
  258. class dummy_event():
  259. def __init__(self):
  260. self.num =0
  261. self.type = 4 #press 5 release
  262. self.set_value=-1
  263. gcolor = 1
  264. def cprint(*text,color="blue",space=" ",end="\n"):
  265. if not gcolor:
  266. print(text)
  267. return 0
  268. if color == "green":
  269. txt = '\033[92m'
  270. elif color == "red":
  271. txt = '\033[0;31m\033[1m'
  272. elif color == "yellow":
  273. txt = '\033[93m\033[1m'
  274. elif color == "cyan":
  275. txt = '\033[96m'
  276. else:
  277. txt = '\033[94m'
  278. for t in text:
  279. txt += str(t ) +" "
  280. #HEADER = '\033[95m'
  281. #OKBLUE = '\033[94m'
  282. #OKCYAN = '\033[96m'
  283. #OKGREEN = '\033[92m'
  284. #WARNING = '\033[93m'
  285. #FAIL = '\033[91m'
  286. #ENDC = '\033[0m'
  287. #BOLD = '\033[1m'
  288. #UNDERLINE = '\033[4m'
  289. txt += '\033[0m'
  290. print(txt,end=end)
  291. #return txt
  292. cprint("________________________________")
  293. class Xevent():
  294. def __init__(self,fix,elem,attr=None,data=None,mode=None):
  295. self.fix = fix
  296. self.data=data
  297. self.attr = attr
  298. self.elem = elem
  299. self.mode = mode
  300. def fx(self,event):
  301. cprint("Xevent.fx",self.attr,self.fix,event)
  302. if event.num == 1:
  303. cmd = ""
  304. offset = 0
  305. offset_flag=0
  306. start = fx_prm["START"]
  307. base = fx_prm["BASE"]
  308. #FIXTURES.start_fx(attr)
  309. for fix in FIXTURES.fixtures:
  310. data = FIXTURES.fixtures[fix]
  311. #print( "ADD FX",fix)
  312. for attr in data["ATTRIBUT"]:
  313. if attr.endswith("-FINE"):
  314. continue
  315. fx=""
  316. if "SIN" in self.attr:
  317. fx = "sinus"
  318. elif "FD" in self.attr:
  319. fx = "fade"
  320. elif "ON2" in self.attr:
  321. fx = "on2"
  322. elif "ON" in self.attr:
  323. fx = "on"
  324. elif "BUM2" in self.attr:
  325. fx = "bump2"
  326. elif "BUM" in self.attr:
  327. fx = "bump"
  328. elif "COS" in self.attr:
  329. fx = "cosinus"
  330. if fx:
  331. if fx_prm["SPEED"] < 0.1:
  332. fx = "off"
  333. else:
  334. if "DIM" in self.attr:
  335. base=""
  336. if attr == "DIM":
  337. if fx_prm["SPEED"] < 0.1:
  338. fx = "off"
  339. else:
  340. fx = "fade"
  341. elif "TILT" in self.attr:
  342. base=""
  343. if attr == "PAN":
  344. fx = "off"
  345. if attr == "TILT":
  346. if fx_prm["SPEED"] < 0.1:
  347. fx = "off"
  348. else:
  349. fx = "sinus"
  350. elif "PAN" in self.attr:
  351. base=""
  352. if attr == "PAN":
  353. if fx_prm["SPEED"] < 0.1:
  354. fx = "off"
  355. else:
  356. fx = "cosinus"
  357. if attr == "TILT":
  358. fx = "off"
  359. elif "CIR" in self.attr:
  360. base=""
  361. if attr == "PAN":
  362. if fx_prm["SPEED"] < 0.1:
  363. fx = "off"
  364. else:
  365. fx = "cosinus"
  366. if attr == "TILT":
  367. if fx_prm["SPEED"] < 0.1:
  368. fx = "off"
  369. else:
  370. fx = "sinus"
  371. if fx:
  372. fx += ":{:0.0f}:{:0.0f}:{:0.0f}:{:0.0f}:{}:".format(fx_prm["SIZE"],fx_prm["SPEED"],start,offset,base)
  373. offset_flag=1
  374. if "FX" not in data["ATTRIBUT"][attr]:
  375. data["ATTRIBUT"][attr]["FX"] =""
  376. print("ADD FX",fix,attr,fx,data["ATTRIBUT"][attr]["ACTIVE"])
  377. if data["ATTRIBUT"][attr]["ACTIVE"] and fx:
  378. print("++ADD FX",fix,attr,fx)
  379. data["ATTRIBUT"][attr]["FX"] = fx #"sinus:40:100:10"
  380. cmd+=update_dmx(attr,data,pfx="fx",value=fx)#,flash=FLASH)
  381. if fx_prm["OFFSET"] > 0.5 and offset_flag:
  382. offset_flag=0
  383. offset += fx_prm["OFFSET"] # add offset on next fixture
  384. #print("offset",offset)
  385. if cmd and not modes.val("BLIND"):
  386. client.send(cmd)
  387. def command(self,event):
  388. if self.mode == "COMMAND":
  389. if self.attr == "CLEAR":
  390. if event.num == 1:
  391. ok = FIXTURES.clear()
  392. if ok:
  393. master.refresh_fix()
  394. modes.val(self.attr,0)
  395. elif self.attr.startswith("SZ:"):#SIN":
  396. #global fx_prm
  397. k = "SIZE"
  398. if event.num == 1:
  399. pass
  400. elif event.num == 2:
  401. pass
  402. elif event.num == 4:
  403. if fx_prm[k] <= 0:
  404. fx_prm[k] = 1
  405. fx_prm[k] *=1.2
  406. elif event.num == 5:
  407. fx_prm[k] /=1.2
  408. #fx_prm[k] =int(fx_prm[k])
  409. if fx_prm[k] > 4000:
  410. fx_prm[k] = 4000
  411. if fx_prm[k] < 0:
  412. fx_prm[k] =0
  413. self.data.elem_fx_commands[self.attr]["text"] = "SZ:{:0.0f}".format(fx_prm[k])
  414. elif self.attr.startswith("SP:"):#SIN":
  415. #global fx_prm
  416. k = "SPEED"
  417. if event.num == 1:
  418. pass
  419. elif event.num == 2:
  420. pass
  421. elif event.num == 4:
  422. if fx_prm[k] <= 0:
  423. fx_prm[k] = 1
  424. fx_prm[k] *=1.2
  425. elif event.num == 5:
  426. fx_prm[k] /=1.2
  427. #fx_prm[k] =int(fx_prm[k])
  428. if fx_prm[k] > 4000:
  429. fx_prm[k] = 4000
  430. if fx_prm[k] < 0:
  431. fx_prm[k] =0
  432. if fx_prm[k] < 0.1:
  433. self.data.elem_fx_commands[self.attr]["text"] = "SP:off".format(fx_prm[k])
  434. else:
  435. self.data.elem_fx_commands[self.attr]["text"] = "SP:{:0.0f}".format(fx_prm[k])
  436. elif self.attr.startswith("ST:"):#SIN":
  437. #global fx_prm
  438. k = "START"
  439. if event.num == 1:
  440. pass
  441. elif event.num == 2:
  442. pass
  443. elif event.num == 4:
  444. if fx_prm[k] <= 0:
  445. fx_prm[k] = 1
  446. fx_prm[k] *=1.2
  447. elif event.num == 5:
  448. fx_prm[k] /=1.2
  449. #fx_prm[k] =int(fx_prm[k])
  450. if fx_prm[k] > 4000:
  451. fx_prm[k] = 4000
  452. if fx_prm[k] < 0:
  453. fx_prm[k] =0
  454. self.data.elem_fx_commands[self.attr]["text"] = "ST:{:0.0f}".format(fx_prm[k])
  455. elif self.attr.startswith("OF:"):#SIN":
  456. #global fx_prm
  457. k = "OFFSET"
  458. if event.num == 1:
  459. pass
  460. elif event.num == 2:
  461. pass
  462. elif event.num == 4:
  463. if fx_prm[k] <= 0:
  464. fx_prm[k] = 1
  465. fx_prm[k] *=1.2
  466. elif event.num == 5:
  467. fx_prm[k] /=1.2
  468. #fx_prm[k] =int(fx_prm[k])
  469. if fx_prm[k] > 1024:
  470. fx_prm[k] = 1024
  471. if fx_prm[k] < 0:
  472. fx_prm[k] =0
  473. self.data.elem_fx_commands[self.attr]["text"] = "OF:{:0.0f}".format(fx_prm[k])
  474. elif self.attr.startswith("BS:"):
  475. k = "BASE"
  476. if event.num == 1:
  477. fx_prm[k] = "0"
  478. elif event.num == 2:
  479. pass
  480. elif event.num == 4:
  481. fx_prm[k] = "+"
  482. elif event.num == 5:
  483. fx_prm[k] = "-"
  484. self.data.elem_fx_commands[self.attr]["text"] = "BS:{}".format(fx_prm[k])
  485. elif self.attr.startswith("FX:"):#SIN":
  486. self.fx(event)
  487. elif self.attr == "FX OFF":
  488. if event.num == 1:
  489. FIXTURES.fx_off("all")
  490. CONSOLE.fx_off("all")
  491. CONSOLE.flash_off("all")
  492. return 0
  493. elif self.attr == "FADE":
  494. global fade
  495. global fade_on
  496. if fade < 0.01:
  497. fade = 0.01
  498. elif fade > 100.0:
  499. fade = 100
  500. if event.num == 4:
  501. fade *= 1.1
  502. elif event.num == 5:
  503. fade /= 1.1
  504. elif event.num == 1:
  505. if fade_on:
  506. fade_on = 0
  507. self.data.elem_commands[self.attr]["bg"] = "grey"
  508. else:
  509. fade_on = 1
  510. self.data.elem_commands[self.attr]["bg"] = "green"
  511. elif event.num == 2:
  512. if fade > 1 and fade < 4:
  513. fade = 4
  514. elif fade > 3 and fade < 6:
  515. fade = 6
  516. elif fade > 5 and fade < 7:
  517. fade = 8
  518. elif fade > 7 and fade < 9:
  519. fade = 10
  520. elif fade > 9:
  521. fade = 0.01
  522. elif fade < 1:
  523. fade = 1.1
  524. self.data.elem_commands[self.attr]["text"] = "Fade{:0.2f}".format(fade)
  525. elif self.attr == "BACKUP":
  526. modes.val(self.attr,1)
  527. PRESETS.backup_presets()
  528. FIXTURES.backup_patch()
  529. #time.sleep(1)
  530. modes.val(self.attr,0)
  531. else:
  532. if event.num == 1:
  533. print("ELSE",self.attr)
  534. modes.val(self.attr,1)
  535. return 0
  536. def cb(self,event):
  537. cprint("EVENT cb",self.attr,self.mode,event,color='yellow')
  538. print(["type",event.type,"num",event.num])
  539. try:
  540. change = 0
  541. if "keysym" in dir(event):
  542. if "Escape" == event.keysym:
  543. ok = FIXTURES.clear()
  544. master.refresh_fix()
  545. return 0
  546. if self.mode == "COMMAND":
  547. self.command(event)
  548. elif self.mode == "ROOT":
  549. if event.keysym=="Escape":
  550. pass
  551. elif self.mode == "INPUT":
  552. print("INP",self.data.entry.get())
  553. if event.keycode == 36:
  554. x=self.data.entry.get()
  555. client.send(x)
  556. elif self.mode == "INPUT2":
  557. print("INP2",self.data.entry2.get())
  558. if event.keycode == 36:
  559. x=self.data.entry2.get()
  560. client.send(x)
  561. elif self.mode == "INPUT3":
  562. print("INP3",self.data.entry3.get())
  563. if event.keycode == 36:
  564. x=self.data.entry3.get()
  565. client.send(x)
  566. elif self.mode == "PRESET":
  567. nr = self.attr #int(self.attr.split(":")[1])-1
  568. if event.num == 1:
  569. if str(event.type) == '4': #4 ButtonPress
  570. if modes.val("STORE"):
  571. self.data.preset_store(nr)
  572. modes.val("STORE",0)
  573. elif modes.val("DEL"):
  574. ok=PRESETS.delete(nr)
  575. if ok:
  576. modes.val("DEL",0)
  577. elif modes.val("COPY"):
  578. ok=PRESETS.copy(nr)
  579. if ok:
  580. modes.val("COPY",0)
  581. master.refresh_exec()
  582. elif modes.val("MOVE"):
  583. ok=PRESETS.move(nr)
  584. if ok:
  585. modes.val("MOVE",0)
  586. master.refresh_exec()
  587. elif modes.val("CFG-BTN"):
  588. master.btn_cfg(nr)
  589. elif modes.val("LABEL"):#else:
  590. master.label(nr)
  591. elif modes.val("EDIT"):
  592. self.data.preset_select(nr)
  593. self.data.preset_go(nr,xfade=0,event=event,val=255)
  594. modes.val("EDIT", 0)
  595. self.data.elem_commands["ACTIVATE"]["bg"] = "lightgrey"
  596. elif modes.val("SELECT"):
  597. self.data.preset_select(nr)
  598. else:
  599. self.data.preset_go(nr,event=event,val=255)
  600. else:
  601. self.data.preset_go(nr,xfade=0,event=event,val=0)
  602. if event.num == 3:
  603. if not modes.val("STORE"):
  604. self.data.preset_go(nr,xfade=0,event=event,val=255)
  605. return 0
  606. elif self.mode == "INPUT":
  607. return 0
  608. if self.mode == "ENCODER":
  609. cprint("ENC",self.fix,self.attr,self.mode)
  610. cprint(self.data)
  611. val=""
  612. if event.num == 1:
  613. val ="click"
  614. elif event.num == 4:
  615. val ="+"
  616. elif event.num == 5:
  617. val ="-"
  618. if val:
  619. FIXTURES.encoder(fix=self.fix,attr=self.attr,xval=val)
  620. master.refresh_fix()
  621. except Exception as e:
  622. cprint("== cb EXCEPT",e,color="red")
  623. cprint("Error on line {}".format(sys.exc_info()[-1].tb_lineno),color="red")
  624. cprint(''.join(traceback.format_exception(None, e, e.__traceback__)),color="red")
  625. def wheel(event,d=None):
  626. print("wheel",event,d)
  627. import copy
  628. class Element():
  629. def __init__(self):
  630. self.__data = {}
  631. def set(self,key,val):
  632. self.__data[key] = val
  633. class Base():
  634. def __init__(self):
  635. pass
  636. def _load(self,filename):
  637. xfname = "show/"+show_name+"/"+str(filename)+".sav"
  638. print("load",xfname)
  639. f = open(xfname,"r")
  640. lines = f.readlines()
  641. f.close()
  642. data = OrderedDict()
  643. labels = OrderedDict()
  644. for line in lines:
  645. key,label,rdata = line.split("\t",2)
  646. key = int(key)
  647. #print(xfname,"load",key,label)
  648. #print(line)
  649. jdata = json.loads(rdata,object_pairs_hook=OrderedDict)
  650. nrnull = 0
  651. if "ATTRIBUT" in jdata: # translate old FIXTURES.fixtures start with 0 to 1
  652. for attr in jdata["ATTRIBUT"]:
  653. if "NR" in jdata["ATTRIBUT"][attr]:
  654. nr = jdata["ATTRIBUT"][attr]["NR"]
  655. if nr == 0:
  656. nrnull = 1
  657. break
  658. if nrnull:
  659. print("DMX NR IS NULL",attr,"CHANGE +1")
  660. for attr in jdata["ATTRIBUT"]:
  661. if "NR" in jdata["ATTRIBUT"][attr]:
  662. nr = jdata["ATTRIBUT"][attr]["NR"]
  663. if nr >= 0:
  664. jdata["ATTRIBUT"][attr]["NR"] +=1
  665. data[key] = jdata
  666. labels[key] = label
  667. return data,labels
  668. def _backup(self,filename,data,labels):
  669. #fixture
  670. xfname = "show/"+show_name+"/"+str(filename)+".sav"
  671. print("backup",xfname)
  672. f = open(xfname,"w")
  673. for key in data:
  674. line = data[key]
  675. #print(line)
  676. label = "label"
  677. if key in labels:
  678. label = labels[key]
  679. if label == "Name-"+str(key):
  680. label = ""
  681. #print(xfname,"load",key,label,len(line))
  682. f.write( "{}\t{}\t{}\n".format( key,label,json.dumps(line) ) )
  683. f.close()
  684. class Event():
  685. def __init__(self,name):
  686. self.name=name
  687. print("init",self)
  688. def event(self,event):
  689. print(self.name,event)
  690. class scroll():
  691. def __init__(self,canvas):
  692. self.canvas=canvas
  693. def config(self,event):
  694. canvas = self.canvas
  695. canvas.configure(scrollregion=canvas.bbox("all"))#,width=400,height=200)
  696. def hex_to_rgb(hex):
  697. return tuple(int(hex[i:i+2], 16) for i in (0, 2, 4))
  698. class cb():
  699. def __init__(self,win):
  700. self.win = win
  701. def _callback(self,event):
  702. clobj=event.widget
  703. ## undermouse=find_withtag(master.CURRENT)
  704. undermouse=self.win.find_closest(self.win.CURRENT)
  705. print( repr(undermouse))
  706. def callback(self,event):
  707. print(__file__,self,"callback",event)
  708. cnv = self.win
  709. item = cnv.find_closest(cnv.canvasx(event.x), cnv.canvasy(event.y))[0]
  710. tags = cnv.gettags(item)
  711. #cnv.itemconfigure(self.tag, text=tags[0])
  712. print(tags,item)
  713. color = cnv.itemcget(item, "fill")
  714. cnv.itemconfig("all", width=1)#filla="green")
  715. cnv.itemconfig(item, width=3)#filla="green")
  716. print(color)
  717. print( hex_to_rgb(color[1:]))
  718. class GUI(Base):
  719. def __init__(self):
  720. super().__init__()
  721. self.load()
  722. self._XX = 0
  723. self.all_attr =["DIM","PAN","TILT"]
  724. self.elem_attr = {}
  725. self.fx_commands =["STONY_FX","FX OFF","\n"
  726. ,"FX:CIR","FX:PAN","FX:TILT","FX:DIM","\n"
  727. ,"SZ:","SP:","ST:","OF:","BS:-","\n"
  728. , "FX:SIN","FX:COS","FX:BUM","FX:BUM2","FX:FD","FX:ON","FX:ON2" ]
  729. self.commands =["\n","ESC","CFG-BTN","LABEL","BACKUP","\n"
  730. "SELECT","FLASH","GO","FADE","MOVE","DEL","\n"
  731. ,"BLIND","CLEAR","STORE","EDIT","COPY","\n"
  732. ]
  733. self.elem_fx_commands = {}
  734. self.val_fx_commands = {}
  735. self.elem_commands = {}
  736. self.val_commands = {}
  737. self.elem_presets = {}
  738. for i in range(8*8*8):
  739. if i not in PRESETS.val_presets:
  740. name = "Preset:"+str(i+1)+":\nXYZ"
  741. #self.presets[i] = [i]
  742. PRESETS.val_presets[i] = OrderedDict() # FIX
  743. PRESETS.val_presets[i]["CFG"] = OrderedDict() # CONFIG
  744. PRESETS.label_presets[i] = "-"
  745. modes.set_cb(self.xcb)
  746. def button_refresh(self,name,color,fg=None):
  747. cprint("button_refresh",name,color)
  748. if name in self.elem_commands:
  749. self.elem_commands[name]["bg"] = color
  750. self.elem_commands[name].config(activebackground=color)
  751. if fg:
  752. self.elem_commands[name]["fg"] = fg
  753. print(dir(self.elem_commands[name]))
  754. def btn_cfg(self,nr):
  755. txt = PRESETS.btn_cfg(nr)
  756. txt = tkinter.simpledialog.askstring("CFG-BTN","GO,FLASH,TOGGLE,SWOP\n EXE:"+str(nr+1),initialvalue=txt)
  757. if txt:
  758. PRESETS.btn_cfg(nr,txt)
  759. self.elem_presets[nr]["text"] = PRESETS.get_btn_txt(nr)
  760. modes.val("CFG-BTN",0)
  761. def label(self,nr):
  762. txt = PRESETS.label(nr)
  763. txt = tkinter.simpledialog.askstring("LABEL","EXE:"+str(nr+1),initialvalue=txt)
  764. if txt:
  765. PRESETS.label(nr,txt)
  766. self.elem_presets[nr]["text"] = PRESETS.get_btn_txt(nr)
  767. modes.val("LABEL", 0)
  768. def xcb(self,mode,value=None):
  769. cprint("MODE CALLBACK",mode,value,color="green",end="")
  770. #cprint(self,"xcb","MODE CALLBACK",mode,value,color="green")
  771. if value:
  772. cprint("===== ON ======",color="red")
  773. self.button_refresh(mode,color="red")#,fg="blue")
  774. else:
  775. cprint("===== OFF ======",color="red")
  776. self.button_refresh(mode,color="lightgrey")#,fg="black")
  777. def load(self,fname=""):
  778. pass
  779. def exit(self):
  780. print("__del__",self)
  781. PRESETS.backup_presets()
  782. print("********************************************************")
  783. FIXTURES.backup_patch()
  784. print("*********del",self,"***********************************************")
  785. def refresh_exec(self):
  786. cprint("PRESET.refresh_exec()")
  787. self._XX +=1
  788. for k in PRESETS.val_presets:
  789. label = ""
  790. if k not in self.elem_presets:
  791. cprint("ERROR",k ,"not in elem_presets continue")
  792. continue
  793. if k in PRESETS.label_presets:
  794. label = PRESETS.label_presets[k]
  795. #print([label])
  796. b = self.elem_presets[k]
  797. if k in PRESETS.val_presets and len(PRESETS.val_presets[k]) :
  798. sdata = PRESETS.val_presets[k]
  799. BTN="go"
  800. if "CFG" in sdata:#["BUTTON"] = "GO"
  801. if "BUTTON" in sdata["CFG"]:
  802. BTN = sdata["CFG"]["BUTTON"]
  803. txt=str(k)+":"+str(BTN)+":"+str(len(sdata)-1)+"\n"+label
  804. txt+=str(self._XX)
  805. b["text"] = txt
  806. b["bg"] = "yellow"
  807. if len(sdata) > 1:
  808. fx_color = 0
  809. val_color = 0
  810. for fix in sdata:
  811. if fix == "CFG":
  812. continue
  813. #print( "$$$$",fix,sdata[fix])
  814. for attr in sdata[fix]:
  815. if "FX" in sdata[fix][attr]:
  816. if sdata[fix][attr]["FX"]:
  817. fx_color = 1
  818. if "VALUE" in sdata[fix][attr]:
  819. if sdata[fix][attr]["VALUE"] is not None:
  820. val_color = 1
  821. b["fg"] = "black"
  822. if val_color:
  823. b["bg"] = "gold"
  824. if fx_color:
  825. b["fg"] = "blue"
  826. else:
  827. if fx_color:
  828. b["bg"] = "cyan"
  829. else:
  830. b["bg"] = "grey"
  831. if "SEL" in txt:
  832. b["fg"] = "black"
  833. b["bg"] = "blue"
  834. elif "GO" in txt:
  835. b["fg"] = "black"
  836. elif "FL" in txt:
  837. b["fg"] = "red"
  838. def refresh_fix(self):
  839. for fix in FIXTURES.fixtures:
  840. sdata = FIXTURES.fixtures[fix]
  841. for attr in sdata["ATTRIBUT"]:
  842. if "FINE" in attr:
  843. continue
  844. v2 = sdata["ATTRIBUT"][attr]["VALUE"]
  845. if fix in self.elem_attr:
  846. elem = self.elem_attr[fix][attr]
  847. #print( attr,v2)
  848. elem["text"] = "{} {:0.2f}".format(attr,v2)
  849. if sdata["ATTRIBUT"][attr]["ACTIVE"]:
  850. elem["bg"] = "yellow"
  851. elem.config(activebackground="yellow")
  852. else:
  853. elem["bg"] = "grey"
  854. elem.config(activebackground="grey")
  855. if sdata["ATTRIBUT"][attr]["FX"]:
  856. elem["fg"] = "blue"
  857. else:
  858. elem["fg"] = "black"
  859. def preset_store(self,nr):
  860. #TODO refactor
  861. print("------- STORE PRESET")
  862. data = FIXTURES.get_active()
  863. if modes.val("STONY_FX"):
  864. PRESETS.store(nr,data,"STONY_FX")
  865. else:
  866. PRESETS.store(nr,data)
  867. sdata=data
  868. PRESETS.val_presets[nr] = sdata
  869. if len(sdata) > 1:
  870. fx_color = 0
  871. val_color = 0
  872. for fix in sdata:
  873. if fix == "CFG":
  874. continue
  875. #print( "$$$$",fix,sdata[fix])
  876. for attr in sdata[fix]:
  877. if "FX" in sdata[fix][attr]:
  878. if sdata[fix][attr]["FX"]:
  879. fx_color = 1
  880. if "VALUE" in sdata[fix][attr]:
  881. if sdata[fix][attr]["VALUE"] is not None:
  882. val_color = 1
  883. self.elem_presets[nr]["fg"] = "black"
  884. if val_color:
  885. self.elem_presets[nr]["bg"] = "yellow"
  886. if fx_color:
  887. self.elem_presets[nr]["fg"] = "blue"
  888. else:
  889. if fx_color:
  890. self.elem_presets[nr]["bg"] = "cyan"
  891. else:
  892. self.elem_presets[nr]["fg"] = "black"
  893. self.elem_presets[nr]["bg"] = "grey"
  894. #self.elem_presets[nr].option_add("*Font", FontBold)
  895. label = ""
  896. if nr in PRESETS.label_presets:
  897. #print(dir(self.data))
  898. label = PRESETS.label_presets[nr]
  899. BTN="go"
  900. if "CFG" in sdata:#["BUTTON"] = "GO"
  901. if "BUTTON" in sdata["CFG"]:
  902. BTN = sdata["CFG"]["BUTTON"]
  903. txt = str(nr)+":"+str(BTN)+":"+str(len(sdata)-1)+"\n"+label
  904. self.elem_presets[nr]["text"] = txt
  905. #print("GO CFG ",PRESETS.val_presets)
  906. def preset_select(self,nr):
  907. print("SELECT PRESET")
  908. sdata = PRESETS.val_presets[nr]
  909. cmd = ""
  910. for fix in sdata:
  911. if fix == "CFG":
  912. continue
  913. for attr in sdata[fix]:
  914. v2 = sdata[fix][attr]["VALUE"]
  915. v2_fx = sdata[fix][attr]["FX"]
  916. #print( self.data.elem_attr)
  917. if fix in self.elem_attr:
  918. elem = self.elem_attr[fix][attr]
  919. FIXTURES.fixtures[fix]["ATTRIBUT"][attr]["ACTIVE"] = 1
  920. elem["bg"] = "yellow"
  921. def preset_go(self,nr,val=None,xfade=fade,event=None):
  922. print("GO PRESET FADE",nr,val)
  923. rdata = PRESETS.get_raw_map(nr)
  924. cfg = PRESETS.get_cfg(nr)
  925. fcmd = FIXTURES.update_raw(rdata)
  926. #virtcmd = FIXTURES.get_virtual(rdata)
  927. if not cfg:
  928. cprint("NO CFG",cfg,nr)
  929. return 0
  930. xFLASH = 0
  931. value=None
  932. cprint(nr,cfg)
  933. if modes.val("SELECT") or ( "BUTTON" in cfg and cfg["BUTTON"] == "SEL") and val: #FLASH
  934. self.preset_select(nr)
  935. elif modes.val("FLASH") or ( "BUTTON" in cfg and cfg["BUTTON"] == "FL"): #FLASH
  936. xFLASH = 1
  937. xfade = 0
  938. if type(val) is not None and val == 0 :
  939. value = "off"
  940. if event:
  941. if str(event.type) == "ButtonRelease" or event.type == '5' :
  942. # 4 fix vor ThinkPad / Debian 11
  943. if xFLASH:
  944. value = "off"
  945. cprint("preset_go() FLUSH",value,color="red")
  946. self._preset_go(rdata,cfg,fcmd,value,xfade=xfade,xFLASH=xFLASH)
  947. elif not val:
  948. cprint("preset_go() STOP",value,color="red")
  949. elif modes.val("GO") or ( "BUTTON" in cfg and cfg["BUTTON"] in ["go","GO"]):
  950. self._preset_go(rdata,cfg,fcmd,value,xfade=xfade,xFLASH=xFLASH)
  951. self.refresh_exec()
  952. def _preset_go(self,rdata,cfg,fcmd,value,xfade=fade,event=None,xFLASH=0):
  953. cprint("PRESETS._preset_go()",len(rdata))
  954. vvcmd = update_raw_dmx( rdata ,value,[xfade] )
  955. fxcmd = update_raw_dmx( rdata ,value,[xfade],fx=1)
  956. cmd = []
  957. for vcmd,d in [[vvcmd,"d"],[fxcmd,"fx"]]:
  958. if xFLASH:
  959. d+="f"
  960. for i,v in enumerate(fcmd):
  961. DMX = fcmd[i]["DMX"]
  962. if DMX and vcmd[i]:
  963. xcmd = ",{}{}:{}".format(d,DMX,vcmd[i])
  964. cmd.append( xcmd )
  965. if "VIRTUAL" in fcmd[i]:
  966. for a in fcmd[i]["VIRTUAL"]:
  967. DMX = fcmd[i]["VIRTUAL"][a]
  968. if DMX and vcmd[i]:
  969. xcmd = ",{}{}:{}".format(d,DMX,vcmd[i])
  970. cmd.append( xcmd )
  971. cmd = "".join(cmd)
  972. print("cmd",cmd)
  973. if cmd and not modes.val("BLIND"):
  974. client.send(cmd )
  975. def draw_sub_dim(self,fix,data,c=0,r=0,frame=None):
  976. Font = font.Font(family='Helvetica', size=9, weight='normal')
  977. FontBold = font.Font(family='Helvetica', size=10, weight='bold')
  978. i=0
  979. if frame is None:
  980. frame = tk.Frame(root,bg="black")
  981. frame.pack(fill=tk.X, side=tk.TOP)
  982. if fix not in self.elem_attr:
  983. self.elem_attr[fix] = {}
  984. for attr in data["ATTRIBUT"]:
  985. if attr not in self.all_attr:
  986. self.all_attr.append(attr)
  987. if attr not in self.elem_attr[fix]:
  988. self.elem_attr[fix][attr] = []
  989. if attr.endswith("-FINE"):
  990. continue
  991. v= data["ATTRIBUT"][attr]["VALUE"]
  992. b = tk.Button(frame,bg="lightblue",font=FontBold, text=""+str(fix)+" "+data["NAME"],width=4)
  993. b.bind("<Button>",Xevent(fix=fix,mode="D-SELECT",elem=b).cb)
  994. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  995. c+=1
  996. b = tk.Button(frame,bg="grey",font=FontBold, text=str(attr)+' '+str(round(v,2)),width=6)
  997. self.elem_attr[fix][attr] = b
  998. b.bind("<Button>",Xevent(fix=fix,elem=b,attr=attr,mode="ENCODER",data=data).cb)
  999. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1000. c+=1
  1001. if c >=12:
  1002. c=0
  1003. r+=1
  1004. return c,r
  1005. def draw_patch(self,xframe):
  1006. r=0
  1007. c=0
  1008. frame_dim = xframe
  1009. root = frame_dim
  1010. dim_frame = tk.Frame(root,bg="black")
  1011. dim_frame.pack(fill=tk.X, side=tk.TOP)
  1012. root = frame_patch
  1013. fix_frame = tk.Frame(root,bg="black")
  1014. canvas = tk.Canvas(root)
  1015. def yview(event):
  1016. print("yevent",event)
  1017. print(dir(canvas))
  1018. yyy=20.1
  1019. fix_frame.yview_moveto(yyy)
  1020. fix_frame = tk.Frame(root,bg="black")
  1021. fix_frame.pack(fill=tk.X, side=tk.TOP)
  1022. i=0
  1023. c=0
  1024. r=0
  1025. for fix in FIXTURES.fixtures:
  1026. i+=1
  1027. data = FIXTURES.fixtures[fix]
  1028. print( fix ,data )
  1029. if 1:
  1030. frame = fix_frame
  1031. b = tk.Button(frame,bg="lightblue", text="FIX:"+str(fix)+" "+data["NAME"],width=20)
  1032. b.bind("<Button>",Xevent(fix=fix,elem=b).cb)
  1033. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1034. c+=1
  1035. #r+=1
  1036. if fix not in self.elem_attr:
  1037. self.elem_attr[fix] = {}
  1038. patch = ["DMX","UNIVERS"]
  1039. for k in patch:
  1040. v=data[k]
  1041. b = tk.Button(frame,bg="grey", text=str(k)+' '+str(v),width=8)
  1042. #self.elem_attr[fix][attr] = b
  1043. #b.bind("<Button>",Xevent(fix=fix,elem=b,attr=attr,data=data).cb)
  1044. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1045. c+=1
  1046. if c >=8:
  1047. c=1
  1048. r+=1
  1049. for attr in data["ATTRIBUT"]:
  1050. if attr not in self.all_attr:
  1051. self.all_attr.append(attr)
  1052. if attr not in self.elem_attr[fix]:
  1053. self.elem_attr[fix][attr] = []
  1054. if attr.endswith("-FINE"):
  1055. continue
  1056. v= data["ATTRIBUT"][attr]["VALUE"]
  1057. b = tk.Button(frame,bg="grey", text=str(attr)+' '+str(round(v,2)),width=8)
  1058. self.elem_attr[fix][attr] = b
  1059. #b.bind("<Button>",Xevent(fix=fix,elem=b,attr=attr,data=data).cb)
  1060. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1061. c+=1
  1062. if c >=8:
  1063. c=1
  1064. r+=1
  1065. c=0
  1066. r+=1
  1067. def draw_fix(self,xframe):
  1068. r=0
  1069. c=0
  1070. frame_dim=xframe
  1071. frame_fix=xframe
  1072. root = frame_dim
  1073. dim_frame = tk.Frame(root,bg="black")
  1074. dim_frame.pack(fill=tk.X, side=tk.TOP)
  1075. root = frame_fix
  1076. fix_frame = tk.Frame(root,bg="black")
  1077. fix_frame.pack(fill=tk.X, side=tk.TOP)
  1078. Font = font.Font(family='Helvetica', size=9, weight='normal')
  1079. FontBold = font.Font(family='Helvetica', size=10, weight='bold')
  1080. i=0
  1081. c=0
  1082. r=0
  1083. dim_end=0
  1084. for fix in FIXTURES.fixtures:
  1085. i+=1
  1086. data = FIXTURES.fixtures[fix]
  1087. print( fix ,data )
  1088. if(len(data["ATTRIBUT"].keys()) <= 1):
  1089. c,r=self.draw_sub_dim(fix,data,c=c,r=r,frame=dim_frame)
  1090. else:
  1091. if not dim_end:
  1092. dim_end=1
  1093. c=0
  1094. r=0
  1095. #self._draw_fix(fix,data,root=fix_frame)
  1096. frame = fix_frame
  1097. b = tk.Button(frame,bg="lightblue",font=FontBold, text="FIX:"+str(fix)+" "+data["NAME"],width=20)
  1098. b.bind("<Button>",Xevent(fix=fix,mode="SELECT",elem=b).cb)
  1099. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1100. c+=1
  1101. #r+=1
  1102. if fix not in self.elem_attr:
  1103. self.elem_attr[fix] = {}
  1104. for attr in data["ATTRIBUT"]:
  1105. if attr.endswith("-FINE"):
  1106. continue
  1107. if attr not in self.all_attr:
  1108. self.all_attr.append(attr)
  1109. if attr not in self.elem_attr[fix]:
  1110. self.elem_attr[fix][attr] = ["line1348",fix,attr]
  1111. v= data["ATTRIBUT"][attr]["VALUE"]
  1112. b = tk.Button(frame,bg="grey",font=FontBold, text=str(attr)+' '+str(round(v,2)),width=8)
  1113. self.elem_attr[fix][attr] = b
  1114. b.bind("<Button>",Xevent(fix=fix,elem=b,attr=attr,mode="ENCODER",data=data).cb)
  1115. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1116. c+=1
  1117. if c >=8:
  1118. c=1
  1119. r+=1
  1120. c=0
  1121. r+=1
  1122. def draw_enc(self,xframe):
  1123. root2 = xframe
  1124. i=0
  1125. c=0
  1126. r=0
  1127. frame = tk.Frame(root2,bg="black")
  1128. frame.pack( side=tk.TOP,expand=1,fill="both")
  1129. b = tk.Button(frame,bg="lightblue", text="ENCODER",width=6)
  1130. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1131. c+=1
  1132. for attr in self.all_attr:
  1133. if attr.endswith("-FINE"):
  1134. continue
  1135. v=0
  1136. b = tk.Button(frame,bg="orange", text=str(attr)+'',width=6)
  1137. b.bind("<Button>",Xevent(fix=0,elem=b,attr=attr,data=self,mode="ENCODER").cb)
  1138. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1139. c+=1
  1140. if c >=8:
  1141. c=0
  1142. r+=1
  1143. def draw_fx(self,xframe):
  1144. frame_fx=xframe
  1145. i=0
  1146. c=0
  1147. r=0
  1148. frame = tk.Frame(frame_fx,bg="black")
  1149. frame.pack(fill=tk.X, side=tk.TOP)
  1150. b = tk.Button(frame,bg="lightblue", text="FX.",width=6)
  1151. #b.bind("<Button>",Xevent(fix=fix,elem=b).cb)
  1152. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1153. c+=1
  1154. for comm in self.fx_commands:
  1155. if comm == "\n":
  1156. c=0
  1157. r+=1
  1158. continue
  1159. v=0
  1160. b = tk.Button(frame,bg="lightgrey", text=str(comm),width=6,height=2)
  1161. if comm not in self.elem_fx_commands:
  1162. self.elem_fx_commands[comm] = b
  1163. self.val_fx_commands[comm] = 0
  1164. b.bind("<Button>",Xevent(fix=0,elem=b,attr=comm,data=self,mode="COMMAND").cb)
  1165. if comm == "BLIND":
  1166. b["bg"] = "grey"
  1167. if comm == "CLEAR":
  1168. b["bg"] = "grey"
  1169. if comm == "STONY_FX":
  1170. b["bg"] = "grey"
  1171. if comm == "FADE":
  1172. b["bg"] = "green"
  1173. if comm == "FX OFF":
  1174. b["bg"] = "magenta"
  1175. if comm == "SZ:":
  1176. b["text"] = "SZ:{:0.0f}".format(fx_prm["SIZE"])
  1177. if comm == "SP:":
  1178. b["text"] = "SP:{:0.0f}".format(fx_prm["SPEED"])
  1179. if comm == "ST:":
  1180. b["text"] = "ST:{:0.0f}".format(fx_prm["START"])
  1181. if comm == "OF:":
  1182. b["text"] = "OF:{:0.0f}".format(fx_prm["OFFSET"])
  1183. if comm == "BS:":
  1184. b["text"] = "BS:{}".format(fx_prm["BASE"])
  1185. if comm:
  1186. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1187. c+=1
  1188. if c >=5:
  1189. c=0
  1190. r+=1
  1191. def draw_command(self,xframe):
  1192. frame_cmd=xframe
  1193. i=0
  1194. c=0
  1195. r=0
  1196. frame = tk.Frame(frame_cmd,bg="black")
  1197. frame.pack(fill=tk.X, side=tk.TOP)
  1198. b = tk.Button(frame,bg="lightblue", text="COMM.",width=6)
  1199. #b.bind("<Button>",Xevent(fix=fix,elem=b).cb)
  1200. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1201. #r+=1
  1202. c+=1
  1203. for comm in self.commands:
  1204. if comm == "\n":
  1205. c=0
  1206. r+=1
  1207. continue
  1208. v=0
  1209. b = tk.Button(frame,bg="lightgrey", text=str(comm),width=6,height=2)
  1210. if comm not in self.elem_commands:
  1211. self.elem_commands[comm] = b
  1212. self.val_commands[comm] = 0
  1213. b.bind("<Button>",Xevent(fix=0,elem=b,attr=comm,data=self,mode="COMMAND").cb)
  1214. if comm == "BLIND":
  1215. b["bg"] = "grey"
  1216. if comm == "CLEAR":
  1217. b["bg"] = "grey"
  1218. if comm == "STONY_FX":
  1219. b["bg"] = "grey"
  1220. if comm == "FADE":
  1221. b["bg"] = "green"
  1222. if comm == "FX OFF":
  1223. b["bg"] = "magenta"
  1224. if comm == "SZ:":
  1225. b["text"] = "SZ:{:0.0f}".format(fx_prm["SIZE"])
  1226. if comm == "SP:":
  1227. b["text"] = "SP:{:0.0f}".format(fx_prm["SPEED"])
  1228. if comm == "FADE":
  1229. b["text"] = "FADE:{:0.02f}".format(fade)
  1230. if comm == "ST:":
  1231. b["text"] = "ST:{:0.0f}".format(fx_prm["START"])
  1232. if comm == "OF:":
  1233. b["text"] = "OF:{:0.0f}".format(fx_prm["OFFSET"])
  1234. if comm == "BS:":
  1235. b["text"] = "BS:{}".format(fx_prm["BASE"])
  1236. if comm:
  1237. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1238. c+=1
  1239. if c >=5:
  1240. c=0
  1241. r+=1
  1242. def draw_preset(self,xframe):
  1243. i=0
  1244. c=0
  1245. r=0
  1246. root = xframe
  1247. frame = tk.Frame(root,bg="black")
  1248. frame.pack(fill=tk.X, side=tk.TOP)
  1249. i=0
  1250. for k in PRESETS.val_presets:
  1251. if i%(8*8)==0 or i ==0:
  1252. c=0
  1253. b = tk.Label(frame,bg="black", text="X" )
  1254. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1255. r+=1
  1256. c=0
  1257. b = tk.Button(frame,bg="lightblue", text="EXEC " )
  1258. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1259. c+=1
  1260. b = tk.Button(frame,bg="lightblue", text="PAGE " + str(int(i/(8*8))+1) )
  1261. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1262. c+=1
  1263. b = tk.Button(frame,bg="lightblue", text="<NAME>" )
  1264. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1265. r+=1
  1266. c=0
  1267. i+=1
  1268. v=0
  1269. label = ""
  1270. if k in PRESETS.label_presets:
  1271. label = PRESETS.label_presets[k]
  1272. print([label])
  1273. sdata=PRESETS.val_presets[k]
  1274. BTN="go"
  1275. if "CFG" in sdata:#["BUTTON"] = "GO"
  1276. if "BUTTON" in sdata["CFG"]:
  1277. BTN = sdata["CFG"]["BUTTON"]
  1278. txt=str(k+1)+":"+str(BTN)+":"+str(len(sdata)-1)+"\n"+label
  1279. b = tk.Button(frame,bg="grey", text=txt,width=8,height=2)
  1280. b.bind("<Button>",Xevent(fix=0,elem=b,attr=k,data=self,mode="PRESET").cb)
  1281. b.bind("<ButtonRelease>",Xevent(fix=0,elem=b,attr=k,data=self,mode="PRESET").cb)
  1282. if k not in self.elem_presets:
  1283. self.elem_presets[k] = b
  1284. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1285. c+=1
  1286. if c >=8:
  1287. c=0
  1288. r+=1
  1289. self.refresh_exec()
  1290. def draw_input(self):
  1291. i=0
  1292. c=0
  1293. r=0
  1294. frame = tk.Frame(root2,bg="black")
  1295. frame.pack(fill=tk.X, side=tk.TOP)
  1296. b = tk.Label(frame,bg="black", text="------------------------ ---------------------------------------")
  1297. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1298. r=0
  1299. frame = tk.Frame(root2,bg="black")
  1300. frame.pack(fill=tk.X, side=tk.TOP)
  1301. b = tk.Label(frame, text="send:")
  1302. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1303. c+=1
  1304. b = tk.Entry(frame,bg="grey", text="",width=50)
  1305. self.entry = b
  1306. b.bind("<Button>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT").cb)
  1307. b.bind("<Key>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT").cb)
  1308. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1309. b.insert("end","d0:127,fx241:sinus:50:50:10,fx243:cosinus:50:50:10,d201:127,fx201:sinus:50:300:10")
  1310. r+=1
  1311. b = tk.Entry(frame,bg="grey", text="",width=20)
  1312. self.entry2 = b
  1313. b.bind("<Button>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT2").cb)
  1314. b.bind("<Key>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT2").cb)
  1315. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1316. b.insert("end","d1:0:4")
  1317. r+=1
  1318. b = tk.Entry(frame,bg="grey", text="",width=20)
  1319. self.entry3 = b
  1320. b.bind("<Button>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT3").cb)
  1321. #b.bind("<B1-Motion>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT3").cb)
  1322. b.bind("<Key>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT3").cb)
  1323. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  1324. b.insert("end","fx:alloff:::")
  1325. def draw_colorpicker(self,xframe):
  1326. import lib.colorpicker as colp
  1327. class _CB():
  1328. def __init__(self):
  1329. self.old_color = (0,0,0)
  1330. def cb(self,event,data):
  1331. if "color" in data and self.old_color != data["color"]:
  1332. self.old_color = data["color"]
  1333. else:
  1334. return 0
  1335. color = data["color"]
  1336. print("PPPPPPPOOOOOORRR")
  1337. print("e",event,data)
  1338. print("e",dir(event))#.keys())
  1339. try:
  1340. print("e.state",event.state)
  1341. except:pass
  1342. set_fade = fade
  1343. if "color" in data and (event.num == 1 or event.num == 3 or event.num==2 or event.state in [256,1024]):
  1344. cr=None
  1345. cg=None
  1346. cb=None
  1347. if event.num == 1:
  1348. set_fade=fade
  1349. cr = color[0]
  1350. cg = color[1]
  1351. cb = color[2]
  1352. elif event.num == 3:
  1353. cr = color[0]
  1354. cg = color[1]
  1355. cb = color[2]
  1356. set_fade=0
  1357. elif event.num == 2:
  1358. cr= "click"
  1359. cg= "click"
  1360. cb= "click"
  1361. elif event.state == 256:
  1362. cr = color[0]
  1363. cg = color[1]
  1364. cb = color[2]
  1365. set_fade=0
  1366. else:
  1367. set_fade=0
  1368. if cr is not None:
  1369. FIXTURES.encoder(fix=0,attr="RED",xval=cr,xfade=set_fade)
  1370. if cg is not None:
  1371. FIXTURES.encoder(fix=0,attr="GREEN",xval=cg,xfade=set_fade)
  1372. if cb is not None:
  1373. FIXTURES.encoder(fix=0,attr="BLUE",xval=cb,xfade=set_fade)
  1374. master.refresh_fix()
  1375. print("PICK COLOR:",data["color"])
  1376. _cb=_CB()
  1377. colp.colorpicker(xframe,width=600,height=100, xcb=_cb.cb)
  1378. return 0
  1379. canvas=tk.Canvas(xframe,width=600,height=100)
  1380. canvas["bg"] = "yellow" #"green"
  1381. canvas.pack()
  1382. # RGB
  1383. x=0
  1384. y=0
  1385. j=0
  1386. d = 20
  1387. for i in range(0,d+1):
  1388. fi = int(i*255/d)
  1389. f = 255-fi
  1390. if i > d/2:
  1391. pass#break
  1392. color = '#%02x%02x%02x' % (f, fi, fi)
  1393. print( "farbe", i*10, j, f,fi,fi,color)
  1394. r = canvas.create_rectangle(x, y, x+20, y+20, fill=color)
  1395. x+=20
  1396. def render(self):
  1397. #Xroot.bind("<Key>",Xevent(fix=0,elem=None,attr="ROOT",data=self,mode="ROOT").cb)
  1398. self.draw_input()
  1399. def ScrollFrame(root,width=50,height=100,bd=1):
  1400. print("ScrollFrame init",width,height)
  1401. aframe=tk.Frame(root,relief=tk.GROOVE)#,width=width,height=height,bd=bd)
  1402. #aframe.place(x=0,y=0)
  1403. aframe.pack(side="left",fill="both",expand=1) #x=0,y=0)
  1404. canvas=tk.Canvas(aframe,width=width-24,height=height)
  1405. canvas["bg"] = "black" #"green"
  1406. bframe=tk.Frame(canvas)#,width=width,height=height)
  1407. bframe["bg"] = "blue"
  1408. scrollbar=tk.Scrollbar(aframe,orient="vertical",command=canvas.yview,width=20)
  1409. canvas.configure(yscrollcommand=scrollbar.set)
  1410. scrollbar.pack(side="right",fill="y")
  1411. canvas.pack(side="left",expand=1,fill="both")
  1412. canvas.create_window((0,0),window=bframe,anchor='nw')
  1413. bframe.bind("<Configure>",scroll(canvas).config)
  1414. canvas.bind("<Button>",Event("XXX").event)
  1415. canvas.bind("<Key>",Event("XXX").event)
  1416. canvas.bind("<KeyRelease>",Event("XXX").event)
  1417. return bframe
  1418. #frame = ScrollFrame(root)
  1419. class GUIHandler():
  1420. def __init__(self):
  1421. pass
  1422. def update(self,fix,attr,args={}):
  1423. #print("GUIHandler",fix,attr,args)
  1424. for i,k in enumerate(args):
  1425. v = args[k]
  1426. #print("GUI-H", i,k,v)
  1427. class Fixtures(Base):
  1428. def __init__(self):
  1429. super().__init__()
  1430. #self.load()
  1431. self.fixtures = OrderedDict()
  1432. self.gui = GUIHandler()
  1433. def load_patch(self):
  1434. filename="patch"
  1435. d,l = self._load(filename)
  1436. self.fixtures = OrderedDict()
  1437. for i in l:
  1438. sdata = d[i]
  1439. for attr in sdata["ATTRIBUT"]:
  1440. sdata["ATTRIBUT"][attr]["ACTIVE"] = 0
  1441. #print("load",filename,sdata)
  1442. #if "CFG" not in sdata:
  1443. # sdata["CFG"] = OrderedDict()
  1444. self.fixtures[str(i)] = sdata
  1445. #PRESETS.label_presets = l
  1446. def backup_patch(self):
  1447. filename = "patch"
  1448. data = self.fixtures
  1449. labels = {}
  1450. for k in data:
  1451. labels[k] = k
  1452. self._backup(filename,data,labels)
  1453. def fx_off(self,fix=None):
  1454. if not fix or fix == "all":
  1455. #self.data.elem_fx_commands[self.attr]["bg"] = "magenta"
  1456. for fix in self.fixtures:
  1457. data = self.fixtures[fix]
  1458. for attr in data["ATTRIBUT"]:
  1459. data["ATTRIBUT"][attr]["FX"] = ""
  1460. def update_raw(self,rdata):
  1461. #print("update_raw",rdata)
  1462. cmd = []
  1463. for i,d in enumerate(rdata):
  1464. xcmd = {"DMX":""}
  1465. #print("fix:",i,d)
  1466. fix = d["FIX"]
  1467. attr = d["ATTR"]
  1468. v2 = d["VALUE"]
  1469. v2_fx = d["FX"]
  1470. if fix not in self.fixtures:
  1471. continue
  1472. sdata = self.fixtures[fix] #shortcat
  1473. ATTR = sdata["ATTRIBUT"]
  1474. sDMX = 0
  1475. if sdata["DMX"] > 0:
  1476. print( sdata)
  1477. sDMX = (sdata["UNIVERS"]*512)+sdata["DMX"]
  1478. #sDMX =sdata["DMX"]
  1479. if attr not in ATTR:
  1480. continue
  1481. if ATTR[attr]["NR"] >= 0:
  1482. DMX = sDMX+ATTR[attr]["NR"]-1
  1483. xcmd["DMX"] = str(DMX)
  1484. else:
  1485. if attr == "DIM" and ATTR[attr]["NR"] < 0:
  1486. xcmd["VIRTUAL"] = {}
  1487. for a in ATTR:
  1488. if ATTR[a]["MASTER"]:
  1489. xcmd["VIRTUAL"][a] = sDMX+ATTR[a]["NR"]-1
  1490. #print( "VIRTUAL",xcmd)
  1491. cmd.append(xcmd)
  1492. v=ATTR[attr]["VALUE"]
  1493. if v2 is not None:
  1494. ATTR[attr]["VALUE"] = v2
  1495. #self.data.elem_attr[fix][attr]["text"] = str(attr)+' '+str(round(v,2))
  1496. text = str(attr)+' '+str(round(v,2))
  1497. self.gui.update(fix,attr,args={"text":text})
  1498. return cmd
  1499. def encoder(self,fix,attr,xval="",xfade=0):
  1500. cprint("FIXTURES.encoder",fix,attr,xval,xfade,color="yellow")
  1501. if attr == "CLEAR":
  1502. self.clear()
  1503. return 0
  1504. if fix not in self.fixtures:
  1505. for fix in self.fixtures:
  1506. #cprint(fix,attr,xval)
  1507. data = self.fixtures[fix]
  1508. if attr in data["ATTRIBUT"]:
  1509. if xval == "click":
  1510. self.select(fix,attr,mode="on")
  1511. elif data["ATTRIBUT"][attr]["ACTIVE"]:
  1512. if fix: # prevent endless recursion
  1513. self.encoder(fix,attr,xval,xfade)
  1514. return 0
  1515. data = self.fixtures[fix]
  1516. if xval == "click":
  1517. cprint(data)
  1518. return self.select(fix,attr,mode="toggle")
  1519. v2=data["ATTRIBUT"][attr]["VALUE"]
  1520. change=0
  1521. increment = 4.11
  1522. if xval == "+":
  1523. v2+= increment
  1524. v = "+{:0.4f}".format( increment ) #) #4.11"
  1525. change=1
  1526. elif xval == "-":
  1527. v2-= increment
  1528. v = "-{:0.4f}".format( increment ) #) #4.11"
  1529. change=1
  1530. elif type(xval) is int or type(xval) is float:
  1531. v2 = xval
  1532. change=1
  1533. if v2 < 0:
  1534. v2=0
  1535. elif v2 > 256:
  1536. v2=256
  1537. out = {}
  1538. if change:
  1539. data["ATTRIBUT"][attr]["ACTIVE"] = 1
  1540. data["ATTRIBUT"][attr]["VALUE"] = v2
  1541. if xfade:
  1542. cmd=update_dmx(attr=attr,data=data)
  1543. else:
  1544. cmd=update_dmx(attr=attr,data=data,args=[0])
  1545. if cmd and not modes.val("BLIND"):
  1546. client.send(cmd)
  1547. return v2
  1548. def get_active(self):
  1549. print(self,"get_active")
  1550. CFG = OrderedDict()
  1551. sdata = OrderedDict()
  1552. sdata["CFG"] = CFG # OrderedDict()
  1553. sdata["CFG"]["FADE"] = fade
  1554. sdata["CFG"]["DEALY"] = 0
  1555. #sdata["CFG"]["BUTTON"] = "GO"
  1556. for fix in self.fixtures:
  1557. data = self.fixtures[fix]
  1558. for attr in data["ATTRIBUT"]:
  1559. if data["ATTRIBUT"][attr]["ACTIVE"]:
  1560. if fix not in sdata:
  1561. sdata[fix] = {}
  1562. if attr not in sdata[fix]:
  1563. sdata[fix][attr] = OrderedDict()
  1564. if not modes.val("STONY_FX"):
  1565. sdata[fix][attr]["VALUE"] = data["ATTRIBUT"][attr]["VALUE"]
  1566. #sdata[fix][attr]["FADE"] = fade
  1567. else:
  1568. sdata[fix][attr]["VALUE"] = None #data["ATTRIBUT"][attr]["VALUE"]
  1569. if "FX" not in data["ATTRIBUT"][attr]:
  1570. data["ATTRIBUT"][attr]["FX"] =""
  1571. sdata[fix][attr]["FX"] = data["ATTRIBUT"][attr]["FX"]
  1572. return sdata
  1573. def select(self,fix=None,attr=None,mode="on"):
  1574. cprint("FIXTURES.select()",fix,attr,mode,color="yellow")
  1575. out = 0
  1576. if fix in self.fixtures:
  1577. data = self.fixtures[fix]
  1578. if attr in data["ATTRIBUT"]:
  1579. if mode == "on":
  1580. if not data["ATTRIBUT"][attr]["ACTIVE"]:
  1581. data["ATTRIBUT"][attr]["ACTIVE"] = 1
  1582. out = 1
  1583. elif mode == "off":
  1584. if data["ATTRIBUT"][attr]["ACTIVE"]:
  1585. data["ATTRIBUT"][attr]["ACTIVE"] = 0
  1586. out = 1
  1587. elif mode == "toggle":
  1588. if data["ATTRIBUT"][attr]["ACTIVE"]:
  1589. data["ATTRIBUT"][attr]["ACTIVE"] = 0
  1590. else:
  1591. data["ATTRIBUT"][attr]["ACTIVE"] = 1
  1592. out = 1
  1593. return out
  1594. def clear(self):
  1595. out = 0
  1596. for fix in self.fixtures:
  1597. data = self.fixtures[fix]
  1598. for attr in data["ATTRIBUT"]:
  1599. if attr.endswith("-FINE"):
  1600. continue
  1601. if data["ATTRIBUT"][attr]["ACTIVE"]:
  1602. out +=1
  1603. data["ATTRIBUT"][attr]["ACTIVE"] = 0
  1604. return out
  1605. class Presets(Base):
  1606. def __init__(self):
  1607. super().__init__()
  1608. #self.load()
  1609. self._last_copy = None
  1610. self._last_move = None
  1611. def load_presets(self):
  1612. filename="presets"
  1613. d,l = self._load(filename)
  1614. for i in d:
  1615. sdata = d[i]
  1616. if "CFG" not in sdata:
  1617. sdata["CFG"] = OrderedDict()
  1618. if "FADE" not in sdata["CFG"]:
  1619. sdata["CFG"]["FADE"] = 4
  1620. if "DELAY" not in sdata["CFG"]:
  1621. sdata["CFG"]["DELAY"] = 0
  1622. if "BUTTON" not in sdata["CFG"]:
  1623. sdata["CFG"]["BUTTON"] = "GO"
  1624. self.val_presets = d
  1625. self.label_presets = l
  1626. def check_cfg(self,nr=None):
  1627. cprint("PRESETS.check_cfg()",nr)
  1628. ok = 0
  1629. if nr is not None:
  1630. ok += self._check_cfg(nr)
  1631. else:
  1632. for nr in self.val_presets:
  1633. ok += self._check_cfg(nr)
  1634. return ok
  1635. def _check_cfg(self,nr):
  1636. #cprint("PRESETS._check_cfg()",nr)
  1637. ok=0
  1638. if nr in self.val_presets:
  1639. sdata = self.val_presets[nr]
  1640. if "CFG" not in sdata:
  1641. sdata["CFG"] = OrderedDict()
  1642. ok += 1
  1643. if "FADE" not in sdata["CFG"]:
  1644. sdata["CFG"]["FADE"] = 4
  1645. ok += 1
  1646. if "DELAY" not in sdata["CFG"]:
  1647. sdata["CFG"]["DELAY"] = 0
  1648. ok += 1
  1649. if "BUTTON" not in sdata["CFG"]:
  1650. sdata["CFG"]["BUTTON"] = "GO"
  1651. ok += 1
  1652. if ok:
  1653. cprint("REPAIR CFG's",nr,sdata["CFG"],color="red")
  1654. else:
  1655. cprint("nr not in data ",nr,color="red")
  1656. return ok
  1657. def backup_presets(self):
  1658. filename = "presets"
  1659. data = self.val_presets
  1660. labels = self.label_presets
  1661. self._backup(filename,data,labels)
  1662. def get_cfg(self,nr):
  1663. cprint("PRESETS.get_cfg()",nr)
  1664. self.check_cfg(nr)
  1665. if nr not in self.val_presets:
  1666. cprint(self,"error get_cfg no nr:",nr,color="red")
  1667. return {}
  1668. if "CFG" in self.val_presets[nr]:
  1669. return self.val_presets[nr]["CFG"]
  1670. def get_raw_map(self,nr):
  1671. print("get_raw_map",nr)
  1672. if nr not in self.val_presets:
  1673. self.val_presets[nr] = OrderedDict()
  1674. self.val_presets[nr]["VALUE"] = 0
  1675. self.val_presets[nr]["FX"] = ""
  1676. sdata = self.val_presets[nr]
  1677. cmd = ""
  1678. out = []
  1679. dmx=-1
  1680. for fix in sdata:
  1681. if fix == "CFG":
  1682. #print("CFG",nr,sdata[fix])
  1683. continue
  1684. for attr in sdata[fix]:
  1685. x = {}
  1686. #print("RAW",attr)
  1687. x["FIX"] = fix
  1688. x["ATTR"] = attr
  1689. x["VALUE"] = sdata[fix][attr]["VALUE"]
  1690. x["FX"] = sdata[fix][attr]["FX"]
  1691. #x["DMX"] = sdata[fix][attr]["NR"]
  1692. out.append(x)
  1693. return out
  1694. def get_btn_txt(self,nr):
  1695. sdata=self.val_presets[nr]
  1696. BTN="go"
  1697. if "CFG" in sdata:
  1698. if "BUTTON" in sdata["CFG"]:
  1699. BTN = sdata["CFG"]["BUTTON"]
  1700. _label = self.label_presets[nr] # = label
  1701. txt=str(nr+1)+":"+str(BTN)+":"+str(len(sdata)-1)+"\n"+_label
  1702. print("get_btn_txt",nr,[txt])
  1703. return txt
  1704. def btn_cfg(self,nr,txt=None):
  1705. if nr not in self.val_presets:
  1706. return ""
  1707. if "CFG" not in self.val_presets[nr]:
  1708. self.val_presets[nr]["CFG"] = OrderedDict()
  1709. if "BUTTON" not in self.val_presets[nr]["CFG"]:
  1710. self.val_presets[nr]["CFG"]["BUTTON"] = ""
  1711. if type(txt) is str:
  1712. self.val_presets[nr]["CFG"]["BUTTON"] = txt
  1713. if self.val_presets[nr]["CFG"]["BUTTON"] is None:
  1714. self.val_presets[nr]["CFG"]["BUTTON"] = ""
  1715. print("EEE", self.val_presets[nr]["CFG"]["BUTTON"] )
  1716. return self.val_presets[nr]["CFG"]["BUTTON"]
  1717. def label(self,nr,txt=None):
  1718. if nr not in self.label_presets:
  1719. return ""
  1720. if type(txt) is str:
  1721. self.label_presets[nr] = txt
  1722. print("set label",nr,[txt])
  1723. print("??? ?? set label",nr,[txt])
  1724. return self.label_presets[nr]
  1725. def clear_move(self):
  1726. cprint("PRESETS.clear_move()",end=" ")
  1727. self.clear_copy()
  1728. def clear_copy(self):
  1729. cprint("PRESETS.clear_copy()",end=" ")
  1730. if self._last_copy is not None:
  1731. cprint("=OK=",color="red")
  1732. self._last_copy = None
  1733. else:
  1734. cprint("=NONE=",color="green")
  1735. def copy(self,nr):
  1736. cprint("PRESETS._copy",nr,"last",self._last_copy)
  1737. if nr:
  1738. if self._last_copy is not None:
  1739. ok = self._copy(self._last_copy,nr)
  1740. return ok #ok
  1741. else:
  1742. self._last_copy = nr
  1743. cprint("PRESETS.copy START ",color="red")
  1744. return 0
  1745. return 1 # on error reset move
  1746. def _copy(self,nr_from,nr_to):
  1747. cprint("PRESETS._copy",nr_from,"to",nr_to)
  1748. self.check_cfg(nr_from)
  1749. if self._last_copy is None:
  1750. cprint("PRESETS._copy last nr is None")
  1751. return 0
  1752. if nr_from in self.val_presets and nr_to in self.val_presets:
  1753. data = self.val_presets[nr_from]
  1754. cprint(data)
  1755. label = self.label_presets[nr_from]
  1756. self.val_presets[nr_to] = data
  1757. self.label_presets[nr_to] = label
  1758. #self.label_presets[nr_from] = "MOVE"
  1759. self.clear_copy()
  1760. cprint("PRESETS.copy OK",color="red")
  1761. return 1
  1762. def move(self,nr):
  1763. cprint("PRESETS.move",self._last_copy,"to",nr)
  1764. if nr:
  1765. last = self._last_copy
  1766. ok= self.copy(nr)
  1767. if ok and last:
  1768. cprint("PRESETS.move OK",color="red")
  1769. self.delete(last)
  1770. return ok #ok
  1771. return 1 # on error reset move
  1772. def delete(self,nr):
  1773. cprint("PRESETS.delete",nr)
  1774. if nr in self.val_presets:
  1775. self.val_presets[nr] = OrderedDict()
  1776. self.label_presets[nr] = "DEL"
  1777. self.check_cfg(nr)
  1778. def store(self,nr,data,arg=""):
  1779. print(self,"store()",data,arg)
  1780. self.check_cfg(nr)
  1781. self.val_presets[nr] = data
  1782. return 1
  1783. class GUI_grid():
  1784. def __init__(self,root,data,title="tilte",width=800):
  1785. self.data = data
  1786. self.frame = tk.Frame(root,bg="black",width=width)
  1787. self.frame.pack(fill=tk.BOTH, side=tk.LEFT)
  1788. r=0
  1789. c=0
  1790. i=1
  1791. for row in data:
  1792. self.b = tk.Button(self.frame,bg="lightblue", text=row["text"],width=11,height=4)
  1793. #self.b.bind("<Button>",Xevent(fix=fix,elem=b).cb)
  1794. self.b.grid(row=r, column=c, sticky=tk.W+tk.E)#,anchor="w")
  1795. c+=1
  1796. if c % 8 == 0:
  1797. r+=1
  1798. c=0
  1799. i+=1
  1800. self.frame.pack()
  1801. class BEvent():
  1802. def __init__(self,data,cb):
  1803. self._data = data
  1804. self._cb = cb
  1805. def cb(self,event):
  1806. #print(self,event)
  1807. self._cb(event,self._data)
  1808. class GUI_menu():
  1809. def __init__(self,root,data,title="tilte",width=800):
  1810. global tk
  1811. self.data = data
  1812. self.frame = tk.Frame(root,bg="black",width=width)
  1813. self.frame.pack(fill=tk.BOTH, side=tk.LEFT)
  1814. r=0
  1815. c=0
  1816. i=1
  1817. self.b = tk.Label(self.frame,bg="blue", text="MAIN:MENU",width=13,height=1)
  1818. self.b.grid(row=r, column=c, sticky=tk.W+tk.E)#,anchor="w")
  1819. r+=1
  1820. for row in data:
  1821. #print(i)
  1822. #row = data[i]
  1823. self.b = tk.Button(self.frame,bg="lightblue", text=row["text"],width=13,height=3)
  1824. self.b.bind("<Button>",BEvent({"NR":i,"text":row["text"]},self.callback).cb)
  1825. self.b.grid(row=r, column=c, sticky=tk.W+tk.E)#,anchor="w")
  1826. r+=1
  1827. i+=1
  1828. self.frame.pack()
  1829. def callback(self,event,data={}):
  1830. print(self,event,data)
  1831. window_manager.top(data["text"])# = WindowManager()
  1832. lf_nr = 0
  1833. class GUIWindow():
  1834. def __init__(self,title="tilte",master=0,width=100,height=100,left=None,top=None):
  1835. global lf_nr
  1836. if master:
  1837. #Font = font.Font(family='Helvetica', size=9, weight='normal')
  1838. self.tk = tkinter.Tk()#font=Font) #Toplevel()
  1839. #Font = font.Font(family='Helvetica', size=9, weight='normal')
  1840. #FontBold = font.Font(family='Helvetica', size=10, weight='bold')
  1841. #self.tk.default_font.configure(size=9)
  1842. #self.tk.option_add("*Font", FontBold)
  1843. #self.tk.configure(font=Font)
  1844. else:
  1845. self.tk = tkinter.Toplevel()
  1846. self.tk["bg"] = "black"
  1847. self.tk.bind("<Button>",self.callback)
  1848. self.tk.bind("<Key>",self.callback)
  1849. self.tk.bind("<KeyRelease>",self.callback)
  1850. self.tk.title(""+str(title)+" "+str(lf_nr)+":"+str(rnd_id))
  1851. lf_nr+=1
  1852. #self.tk.geometry("270x600+0+65")
  1853. geo ="{}x{}".format(width,height)
  1854. if left is not None:
  1855. geo += "+{}".format(left)
  1856. if top is not None:
  1857. geo += "+{}".format(top)
  1858. #self._event_clear = Xevent(fix=0,elem=None,attr="CLEAR",data=self,mode="ROOT").cb
  1859. self.tk.geometry(geo)
  1860. def title(self,title=None):
  1861. if title is None:
  1862. return self.tk.title()
  1863. else:
  1864. return self.tk.title(title)
  1865. def show(self):
  1866. pass
  1867. #self.frame.pack()
  1868. def mainloop(self):
  1869. self.tk.mainloop()
  1870. def callback(self,event,data={}):#value=255):
  1871. print()
  1872. print()
  1873. print("<GUI>",self,event,event.state,data,[event.type])
  1874. value = 255
  1875. if "Release" in str(event.type) or str(event.type) == '5' or str(event.type) == '3':
  1876. value = 0
  1877. if "keysym" in dir(event):
  1878. if "Escape" == event.keysym:
  1879. FIXTURES.clear()
  1880. modes.val("ESC",1)
  1881. master.refresh_fix()
  1882. elif event.keysym in "ebfclrms" and value:
  1883. if "e" == event.keysym:
  1884. modes.val("EDIT",1)
  1885. elif "b" == event.keysym:
  1886. modes.val("BLIND",1)
  1887. elif "f" == event.keysym:
  1888. modes.val("FLASH",1)
  1889. elif "c" == event.keysym:
  1890. modes.val("CFG-BTN",1)
  1891. elif "l" == event.keysym:
  1892. modes.val("LABEL",1)
  1893. elif "r" == event.keysym:
  1894. modes.val("STORE",1)
  1895. elif "m" == event.keysym:
  1896. x=modes.val("MOVE",1)
  1897. if not x:
  1898. PRESETS.clear_move()
  1899. elif "s" == event.keysym:
  1900. modes.val("SELECT",1)
  1901. elif event.keysym in ["F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12"]:
  1902. nr = int( event.keysym[1])-1
  1903. cprint("F-KEY",value,nr)
  1904. master.preset_go(71-1+nr,xfade=fade,val=value)
  1905. elif "End" == event.keysym:
  1906. FIXTURES.fx_off("all")
  1907. CONSOLE.fx_off("all")
  1908. CONSOLE.flash_off("all")
  1909. elif "Delete" == event.keysym:
  1910. pass
  1911. class WindowManager():
  1912. def __init__(self):
  1913. self.windows = {}
  1914. self.nr= 0
  1915. self.first=""
  1916. def new(self,w,name=""):
  1917. if not self.first:
  1918. if name:
  1919. self.first = name
  1920. else:
  1921. self.first = str(self.nr)
  1922. w.tk.attributes('-topmost',True)
  1923. if name:
  1924. self.windows[str(name)] = w
  1925. else:
  1926. self.windows[str(self.nr)] = w
  1927. self.nr+=1
  1928. #w.show()
  1929. def mainloop(self):
  1930. self.windows[self.first].mainloop()
  1931. def top(self,name):
  1932. name = str(name)
  1933. if name in self.windows:
  1934. self.windows[name].tk.attributes('-topmost',True)
  1935. self.windows[name].tk.attributes('-topmost',False)
  1936. else:
  1937. print(name,"not in self.windows",self.windows.keys())
  1938. class Console():
  1939. def __init__(self):
  1940. pass
  1941. def flash_off(self,fix):
  1942. client.send("df0:alloff:::,")
  1943. def fx_off(self,fix):
  1944. cprint("Console.fx_off()",fix)
  1945. if not fix or fix == "all":
  1946. client.send("fx0:alloff:,fxf:alloff:,")
  1947. client.send("df0:alloff:::,")
  1948. return 0
  1949. window_manager = WindowManager()
  1950. CONSOLE = Console()
  1951. PRESETS = Presets()
  1952. PRESETS.load_presets()
  1953. FIXTURES = Fixtures()
  1954. FIXTURES.load_patch()
  1955. master = GUI()
  1956. w = GUIWindow("MAIN",master=1,width=130,height=450,left=0,top=65)
  1957. data = []
  1958. #data.append({"text":"COMMAND"})
  1959. data.append({"text":"EXEC"})
  1960. data.append({"text":"DIMMER"})
  1961. data.append({"text":"FIXTURES"})
  1962. #data.append({"text":"PRESET"})
  1963. #data.append({"text":"PATCH"})
  1964. #data.append({"text":"ENCODER"})
  1965. f = GUI_menu(w.tk,data)
  1966. window_manager.new(w)
  1967. name="DIMMER"
  1968. w = GUIWindow(name,master=0,width=800,height=400,left=140,top=65)
  1969. w1 = ScrollFrame(w.tk,width=800,height=400)
  1970. #frame_dim = w1 # w.tk
  1971. #master.draw_dim(w1.tk)
  1972. window_manager.new(w,name)
  1973. name="FIXTURES"
  1974. w = GUIWindow(name,master=0,width=800,height=400,left=140,top=65)
  1975. w1 = ScrollFrame(w.tk,width=800,height=400)
  1976. #frame_fix = w1 #w.tk
  1977. master.draw_fix(w1)#.tk)
  1978. window_manager.new(w,name)
  1979. name="ENCODER"
  1980. ww = GUIWindow(name,master=0,width=800,height=50,left=140,top=500)
  1981. Xroot = ww.tk
  1982. #default_font = font.Font(family='Helvetica', size=12, weight='bold')
  1983. Font = font.Font(family='Helvetica', size=9, weight='normal')
  1984. FontBold = font.Font(family='Helvetica', size=10, weight='bold')
  1985. #default_font.configure(size=9)
  1986. Xroot.option_add("*Font", FontBold)
  1987. w = None
  1988. root = tk.Frame(Xroot,bg="black",width="10px")
  1989. root.pack(fill=tk.BOTH,expand=0, side=tk.LEFT)
  1990. root3 = tk.Frame(Xroot,bg="black",width="20px")
  1991. root3.pack(fill=tk.BOTH,expand=0, side=tk.LEFT)
  1992. root2 = tk.Frame(Xroot,bg="black",width="1px")
  1993. master.draw_enc(root2)
  1994. root2.pack(fill=tk.BOTH,expand=0, side=tk.LEFT)
  1995. #w = GUIWindow("GRID",master=0,width=1000,height=200,left=232,top=65)
  1996. #data = []
  1997. #for i in range(10):
  1998. # data.append({"text":"P {:02}".format(i+1)})
  1999. #w = GUI_grid(w.tk,data)
  2000. #window_manager.new(w)
  2001. name = "COMMAND"
  2002. w = GUIWindow(name,master=0,width=350,height=200,left=950,top=65)
  2003. master.draw_command(w.tk)
  2004. window_manager.new(w,name)
  2005. name="EXEC"
  2006. w = GUIWindow(name,master=0,width=800,height=400,left=140,top=65)
  2007. w1 = ScrollFrame(w.tk,width=800,height=400)
  2008. #frame_exe = w.tk
  2009. master.draw_preset(w1)#w.tk)
  2010. window_manager.new(w,name)
  2011. name="PATCH"
  2012. w = GUIWindow(name,master=0,width=800,height=400,left=140,top=65)
  2013. w1 = ScrollFrame(w.tk,width=800,height=400)
  2014. frame_patch = w1 #w.tk
  2015. window_manager.new(w,name)
  2016. name="FX"
  2017. w = GUIWindow(name,master=0,width=350,height=250,left=950,top=305)
  2018. #frame_fx = w.tk
  2019. master.draw_fx(w.tk)
  2020. window_manager.new(w,name)
  2021. #LibreLightDesk
  2022. name="COLERPICKER"
  2023. w = GUIWindow(name,master=0,width=580,height=100,left=80,top=620)
  2024. master.draw_colorpicker(w.tk)
  2025. window_manager.new(w,name)
  2026. #Xroot = tk.Tk()
  2027. #Xroot["bg"] = "black" #white
  2028. #Xroot.title( xtitle+" "+str(rnd_id) )
  2029. #Xroot.geometry("1024x800+130+65")
  2030. master.render()
  2031. #w = frame_fix #GUIWindow("OLD",master=0,width=800,height=500,left=130,top=65)
  2032. window_manager.new(w,name)
  2033. try:
  2034. #root.mainloop()
  2035. #tk.mainloop()
  2036. window_manager.mainloop()
  2037. finally:
  2038. master.exit()