Editor2.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  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 json
  18. import time
  19. import sys
  20. import _thread as thread
  21. import tkinter
  22. import tkinter as tk
  23. from tkinter import font
  24. import lib.chat as chat
  25. import lib.motion as motion
  26. root = tk.Tk()
  27. root["bg"] = "grey" #white
  28. root.title( __file__)
  29. #default_font = font.Font(family='Helvetica', size=12, weight='bold')
  30. Font = font.Font(family='Helvetica', size=10, weight='normal')
  31. FontBold = font.Font(family='Helvetica', size=10, weight='bold')
  32. #default_font.configure(size=9)
  33. root.option_add("*Font", Font)
  34. from collections import OrderedDict
  35. CUES = OrderedDict()
  36. groups = OrderedDict()
  37. BLIND = 0
  38. STORE = 0
  39. POS = ["PAN","TILT","MOTION"]
  40. COLOR = ["RED","GREEN","BLUE","COLOR"]
  41. BEAM = ["GOBO","G-ROT","PRISMA","P-ROT","FOCUS","SPEED"]
  42. INT = ["DIM","SHUTTER","STROBE","FUNC"]
  43. client = chat.tcp_sender()
  44. def update_dmx(attr,data):
  45. global BLIND
  46. dmx = data["DMX"]
  47. val = None
  48. if attr == "VDIM":
  49. for attr in data["ATTRIBUT"]:
  50. dmx = data["DMX"]
  51. if data["ATTRIBUT"][attr]["NR"] < 0:
  52. continue
  53. dmx += data["ATTRIBUT"][attr]["NR"]
  54. #print(attr)
  55. val = data["ATTRIBUT"][attr]["VALUE"]
  56. if data["ATTRIBUT"][attr]["MASTER"]:
  57. val = val * (data["ATTRIBUT"]["VDIM"]["VALUE"] / 255.)
  58. if val is not None:
  59. cmd = "d{}:{}".format(dmx,int(val))
  60. #print("cmd",cmd)
  61. if not BLIND:
  62. client.send(cmd )
  63. else:
  64. pass#print("BLIND ! cmd",cmd)
  65. elif data["ATTRIBUT"][attr]["NR"] >= 0:
  66. dmx += data["ATTRIBUT"][attr]["NR"]
  67. val = data["ATTRIBUT"][attr]["VALUE"]
  68. if data["ATTRIBUT"][attr]["MASTER"]:
  69. if "VDIM" in data["ATTRIBUT"]:
  70. val = val * (data["ATTRIBUT"]["VDIM"]["VALUE"] / 255.)
  71. if val is not None:
  72. cmd = "d{}:{}".format(dmx,int(val))
  73. #print("cmd",cmd)
  74. if not BLIND:
  75. client.send(cmd )
  76. else:
  77. pass#print("BLIND ! cmd",cmd)
  78. class Worker():
  79. def __init__(self):
  80. self.fade = OrderedDict()
  81. self.timer = time.time()
  82. def loop(self):
  83. while 1:
  84. self.next()
  85. def next(self):
  86. if self.timer+(1/30.) < time.time():
  87. try:
  88. lock.acquire()
  89. #if self.timer+1 < time.time():
  90. self.timer = time.time()
  91. #print("next")
  92. for fix in self.fade:
  93. for attr in self.fade[fix]:
  94. if 1:#len(self.fade[])>=2:
  95. fd=self.fade[fix][attr][0]
  96. x=fd.next()
  97. if x:
  98. x=fd.value
  99. #print("fade",x)
  100. data=self.fade[fix][attr][1]
  101. try:
  102. data["ATTRIBUT"][attr]["VALUE"] = x
  103. update_dmx(attr,data)
  104. except Exception as e:
  105. print("next EXCEPTION",e)
  106. finally:
  107. #lock.acquire()
  108. lock.release()
  109. else:
  110. time.sleep(0.1)
  111. def fade_dmx(self,fix,attr,data,v,v2,ft=None):
  112. if ft is None:
  113. ft = 4
  114. #print("fade_dmx",fix,attr,v,v2)
  115. try:
  116. lock.acquire()
  117. if fix not in self.fade:
  118. self.fade[fix] = OrderedDict()
  119. if attr not in self.fade[fix]:
  120. self.fade[fix][attr] = OrderedDict()
  121. self.fade[fix][attr] = [motion.FadeFast(v,v2,ft),data]
  122. finally:
  123. #lock.acquire()
  124. lock.release()
  125. worker = Worker()
  126. lock = thread.allocate_lock()
  127. thread.start_new_thread(worker.loop,())
  128. class Xevent():
  129. def __init__(self,fix,elem,attr=None,data=None,mode=None):
  130. self.data=data
  131. self.attr = attr
  132. self.elem = elem
  133. self.mode = mode
  134. def encoder(self,fix,attr,data,elem,action=""):
  135. if action == "click":
  136. if self.data["ATTRIBUT"][attr]["ACTIVE"]:
  137. self.data["ATTRIBUT"][attr]["ACTIVE"] = 0
  138. self.elem["bg"] = "grey"
  139. else:
  140. self.data["ATTRIBUT"][attr]["ACTIVE"] = 1
  141. self.elem["bg"] = "yellow"
  142. return 1
  143. v=data["ATTRIBUT"][attr]["VALUE"]
  144. change=0
  145. if action == "+":
  146. v+= 4.11
  147. change=1
  148. elif action == "-":
  149. v-= 4.11
  150. change=1
  151. if v < 0:
  152. v=0
  153. elif v > 256:
  154. v=256
  155. if change:
  156. data["ATTRIBUT"][attr]["ACTIVE"] = 1
  157. elem["bg"] = "yellow"
  158. v2 = v
  159. v = data["ATTRIBUT"][attr]["VALUE"]
  160. data["ATTRIBUT"][attr]["VALUE"] = v2
  161. elem["text"] = str(attr)+' '+str(round(v2,2))
  162. worker.fade_dmx(fix,attr,data,v,v2,ft=0)
  163. #update_dmx(attr=attr,data=data)
  164. def cb(self,event):
  165. #print("cb",self,event,data)
  166. print("cb",self.attr,self.mode,event)
  167. #print(self.obj.keys())
  168. try:
  169. #v = self.data["ATTRIBUT"][self.attr]
  170. global STORE
  171. global BLIND
  172. change = 0
  173. if self.mode == "COMMAND":
  174. if self.attr == "CLEAR":
  175. if event.num == 1:
  176. if STORE:
  177. self.data.val_commands["STORE"] = 0
  178. STORE = 0
  179. self.data.elem_commands["STORE"]["bg"] = "lightgrey"
  180. else:
  181. for fix in self.data.fixtures:
  182. print( "clr",fix)
  183. data = self.data.fixtures[fix]
  184. #print("elm",self.data.elem_attr[fix])
  185. for attr in data["ATTRIBUT"]:
  186. if attr.endswith("-FINE"):
  187. continue
  188. self.data.elem_attr[fix][attr]["bg"] = "grey"
  189. data["ATTRIBUT"][attr]["ACTIVE"] = 0
  190. #print(data["ATTRIBUT"])
  191. elif self.attr == "BLIND":
  192. if event.num == 1:
  193. if self.data.val_commands[self.attr]:
  194. self.data.val_commands[self.attr] = 0
  195. BLIND = 0
  196. self.data.elem_commands[self.attr]["bg"] = "lightgrey"
  197. else:
  198. self.data.val_commands[self.attr] = 1
  199. BLIND = 1
  200. self.data.elem_commands[self.attr]["bg"] = "red"
  201. print("BLIND",self.data.val_commands)
  202. elif self.attr == "STORE":
  203. if event.num == 1:
  204. if self.data.val_commands[self.attr]:
  205. self.data.val_commands[self.attr] = 0
  206. STORE = 0
  207. self.data.elem_commands[self.attr]["bg"] = "lightgrey"
  208. else:
  209. self.data.val_commands[self.attr] = 1
  210. STORE = 1
  211. self.data.elem_commands[self.attr]["bg"] = "red"
  212. print("BLIND",self.data.val_commands)
  213. elif self.attr == "BACKUP":
  214. self.data.backup_presets()
  215. return 0
  216. elif self.mode == "PRESET":
  217. nr = self.attr #int(self.attr.split(":")[1])-1
  218. if event.num == 1:
  219. if STORE:
  220. print("STORE PRESET")
  221. sdata = {}
  222. for fix in self.data.fixtures:
  223. data = self.data.fixtures[fix]
  224. for attr in data["ATTRIBUT"]:
  225. if data["ATTRIBUT"][attr]["ACTIVE"]:
  226. if fix not in sdata:
  227. sdata[fix] = {}
  228. if attr not in sdata[fix]:
  229. sdata[fix][attr] = data["ATTRIBUT"][attr]["VALUE"]
  230. print(sdata)
  231. self.data.val_presets[nr] = sdata
  232. self.data.elem_presets[nr]["bg"] = "yellow"
  233. #self.data.elem_presets[nr].option_add("*Font", FontBold)
  234. self.data.elem_presets[nr]["text"] = "Preset:"+str(nr)+":\n"+str(len(sdata))
  235. print(self.data.val_presets)
  236. self.data.val_commands["STORE"] = 0
  237. STORE = 0
  238. self.data.elem_commands["STORE"]["bg"] = "lightgrey"
  239. else:
  240. print("GO PRESET")
  241. if nr not in self.data.val_presets:
  242. self.data.val_presets[nr] = OrderedDict()
  243. sdata = self.data.val_presets[nr]
  244. for fix in sdata:
  245. for attr in sdata[fix]:
  246. v2 = sdata[fix][attr]
  247. #print(fix,attr,v)
  248. if fix in self.data.fixtures:
  249. #print("==",self.data.fixtures[fix]["ATTRIBUT"])
  250. if attr in self.data.fixtures[fix]["ATTRIBUT"]:
  251. data = self.data.fixtures[fix]
  252. v=self.data.fixtures[fix]["ATTRIBUT"][attr]["VALUE"]
  253. self.data.fixtures[fix]["ATTRIBUT"][attr]["VALUE"] = v2
  254. self.data.elem_attr[fix][attr]["text"] = str(attr)+' '+str(round(v,2))
  255. #update_dmx(attr,data)
  256. worker.fade_dmx(fix,attr,data,v,v2)
  257. print(sdata)
  258. if event.num == 3:
  259. if not STORE:
  260. print("GO PRESET 3")
  261. if nr not in self.data.val_presets:
  262. self.data.val_presets[nr] = OrderedDict()
  263. sdata = self.data.val_presets[nr]
  264. for fix in sdata:
  265. for attr in sdata[fix]:
  266. v2 = sdata[fix][attr]
  267. #print(fix,attr,v)
  268. if fix in self.data.fixtures:
  269. #print("==",self.data.fixtures[fix]["ATTRIBUT"])
  270. if attr in self.data.fixtures[fix]["ATTRIBUT"]:
  271. data = self.data.fixtures[fix]
  272. v=self.data.fixtures[fix]["ATTRIBUT"][attr]["VALUE"]
  273. #self.data.fixtures[fix]["ATTRIBUT"][attr]["VALUE"] = v
  274. #print(str(attr)+' '+str(round(v,2)))
  275. #self.data.elem_attr[fix][attr]["text"] = str(attr)+' '+str(round(v,2))
  276. #update_dmx(attr,data)
  277. print("go",fix,attr,v,v2)
  278. worker.fade_dmx(fix,attr,data,v,v2,ft=0)
  279. return 0
  280. elif self.mode == "INPUT":
  281. return 0
  282. if self.mode == "ENCODER":
  283. #if self.attr == "VDIM":
  284. # self.attr = "DIM"
  285. for fix in self.data.fixtures:
  286. data = self.data.fixtures[fix]
  287. for attr in data["ATTRIBUT"]:
  288. if attr.endswith("-FINE"):
  289. continue
  290. elem = self.data.elem_attr[fix][attr]
  291. if self.attr != attr:
  292. continue
  293. if event.num == 1:
  294. #self.encoder(attr=attr,data=data,elem=elem,action="click")
  295. data["ATTRIBUT"][attr]["ACTIVE"] = 1
  296. elem["bg"] = "yellow"
  297. if not data["ATTRIBUT"][attr]["ACTIVE"]:
  298. continue
  299. if event.num == 4:
  300. self.encoder(fix=fix,attr=attr,data=data,elem=elem,action="+")
  301. #if attr == "DIM":
  302. # self.encoder(attr="VDIM",data=data,elem=elem,action="+")
  303. elif event.num == 5:
  304. self.encoder(fix=fix,attr=attr,data=data,elem=elem,action="-")
  305. #if attr == "DIM":
  306. # self.encoder(attr="VDIM",data=data,elem=elem,action="-")
  307. return 0
  308. if event.num == 1:
  309. self.encoder(fix=fix,attr=self.attr,data=self.data,elem=self.elem,action="click")
  310. elif event.num == 4:
  311. self.encoder(fix=fix,attr=self.attr,data=self.data,elem=self.elem,action="+")
  312. elif event.num == 5:
  313. self.encoder(fix=fix,attr=self.attr,data=self.data,elem=self.elem,action="-")
  314. except Exception as e:
  315. print("== cb EXCEPT",e)
  316. print("Error on line {}".format(sys.exc_info()[-1].tb_lineno))
  317. #print(self.elem["text"],self.attr,self.data)
  318. def wheel(event,d=None):
  319. print("wheel",event,d)
  320. import copy
  321. class Master():
  322. def __init__(self):
  323. self.load()
  324. self.all_attr =["DIM","VDIM","PAN","TILT"]
  325. self.elem_attr = {}
  326. self.commands =["BLIND","CLEAR","STORE","EDIT","","","","BACKUP","SET","","SELECT","ACTIVATE","","","",]
  327. self.elem_commands = {}
  328. self.val_commands = {}
  329. self.presets = OrderedDict()
  330. self.elem_presets = {}
  331. self.val_presets = OrderedDict()
  332. x=self.load_presets()
  333. for i in range(8*6):
  334. if i not in self.presets:
  335. name = "Preset:"+str(i+1)+":\nXYZ"
  336. self.presets[i] = [i]
  337. self.val_presets[i] = OrderedDict()
  338. def load(self):
  339. fixture = OrderedDict()
  340. DATA = OrderedDict()
  341. DATA["DIM"] = {"NR": 0, "MASTER": "1", "MODE": "F", "VALUE": 0.0,"ACTIVE":0}
  342. DATA["RED"] = {"NR": 3, "MASTER": "", "MODE": "F", "VALUE": 255.0,"ACTIVE":0}
  343. DATA["GREEN"] = {"NR": 4, "MASTER": "", "MODE": "F", "VALUE": 255.0,"ACTIVE":0}
  344. DATA["BLUE"] = {"NR": 5, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  345. fix = {"DMX": 20, "UNIVERS": 2, "NAME": "IRGB", "ATTRIBUT": DATA}
  346. DATA = OrderedDict()
  347. DATA["VDIM"] = {"NR": -1, "MASTER": "", "MODE": "F", "VALUE": 0.0,"ACTIVE":0}
  348. DATA["RED"] = {"NR": 2, "MASTER": "1", "MODE": "F", "VALUE": 255.0,"ACTIVE":0}
  349. DATA["GREEN"] = {"NR": 1, "MASTER": "1", "MODE": "F", "VALUE": 255.0,"ACTIVE":0}
  350. DATA["BLUE"] = {"NR": 0, "MASTER": "1", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  351. fix3 = {"DMX": 20, "UNIVERS": 2, "NAME": "V+RGB", "ATTRIBUT": DATA}
  352. DATA = OrderedDict()
  353. DATA["DIM-FINE"] = {"NR": 8, "MASTER": "", "MODE": "F", "VALUE": 5.0,"ACTIVE":0}
  354. DATA["VDIM"] = {"NR": -1, "MASTER": "", "MODE": "F", "VALUE": 0.0,"ACTIVE":0}
  355. DATA["PAN"] = {"NR": 0, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  356. DATA["PAN-FINE"] = {"NR": 1, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  357. DATA["TILT"] = {"NR": 2, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  358. DATA["TILT-FINE"] = {"NR": 3, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  359. DATA["RED"] = {"NR": 6, "MASTER": "1", "MODE": "F", "VALUE": 255.0,"ACTIVE":0}
  360. DATA["GREEN"] = {"NR": 7, "MASTER": "1", "MODE": "F", "VALUE": 255.0,"ACTIVE":0}
  361. DATA["BLUE"] = {"NR": 8, "MASTER": "1", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  362. fixTMH = {"DMX": 20, "UNIVERS": 2, "NAME": "MH-BEAM", "ATTRIBUT": DATA}
  363. fi = copy.deepcopy(fixTMH)
  364. fi["DMX"] = 241
  365. fixture["2001"] = fi
  366. fi = copy.deepcopy(fixTMH)
  367. fi["DMX"] = 461
  368. fixture["2002"] = fi
  369. fi = copy.deepcopy(fix3)
  370. fi["DMX"] = 441
  371. fixture["2003"] = fi
  372. fi = copy.deepcopy(fix3)
  373. fi["DMX"] = 461
  374. fixture["2005"] = fi
  375. fi = copy.deepcopy(fix)
  376. fi["DMX"] = 401
  377. fixture["1001"] = fi
  378. fi = copy.deepcopy(fix)
  379. fi["DMX"] = 421
  380. fi["ATTRIBUT"]["BLUE"]["VALUE"] = 22
  381. fixture["1002"] = fi
  382. fi = copy.deepcopy(fix)
  383. fi["DMX"] = 441
  384. fi["ATTRIBUT"]["BLUE"]["VALUE"] = 22
  385. fixture["1003"] = fi
  386. self.fixtures = fixture
  387. def load_presets(self):
  388. print("load_presets")
  389. f = open("preset.px","r")
  390. lines = f.readlines()
  391. f.close()
  392. self.val_presets = OrderedDict()
  393. self.presets = OrderedDict()
  394. for line in lines:
  395. key,data = line.split("\t",1)
  396. key = int(key)
  397. print("load_presets",key)
  398. data = json.loads(data)
  399. self.val_presets[key] = data
  400. self.presets[key] = 0
  401. return self.val_presets
  402. def backup_presets(self):
  403. print("backup_presets")
  404. f = open("preset.px","w")
  405. for key in self.val_presets:
  406. preset = self.val_presets[key]
  407. f.write(str(key)+"\t"+json.dumps(preset)+"\n")
  408. f.close()
  409. def draw_fix(self,fix,data):
  410. i=0
  411. c=0
  412. r=0
  413. frame = tk.Frame(root,bg="black")
  414. frame.pack(fill=tk.X, side=tk.TOP)
  415. b = tk.Button(frame,bg="lightblue", text="FIX:"+str(fix)+" "+data["NAME"],width=20)
  416. b.bind("<Button>",Xevent(fix=fix,elem=b).cb)
  417. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  418. c+=1
  419. #r+=1
  420. if fix not in self.elem_attr:
  421. self.elem_attr[fix] = {}
  422. for attr in data["ATTRIBUT"]:
  423. if attr not in self.all_attr:
  424. self.all_attr.append(attr)
  425. if attr not in self.elem_attr[fix]:
  426. self.elem_attr[fix][attr] = []
  427. if attr.endswith("-FINE"):
  428. continue
  429. v= data["ATTRIBUT"][attr]["VALUE"]
  430. b = tk.Button(frame,bg="grey", text=str(attr)+' '+str(round(v,2)),width=10)
  431. self.elem_attr[fix][attr] = b
  432. b.bind("<Button>",Xevent(fix=fix,elem=b,attr=attr,data=data).cb)
  433. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  434. c+=1
  435. if c >=8:
  436. c=0
  437. r+=1
  438. def draw_enc(self):
  439. i=0
  440. c=0
  441. r=0
  442. frame = tk.Frame(root,bg="black")
  443. frame.pack(fill=tk.X, side=tk.TOP)
  444. b = tk.Label(frame,bg="black", text="--------------------------------------- ---------------------------------------")
  445. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  446. r=0
  447. frame = tk.Frame(root,bg="black")
  448. frame.pack(fill=tk.X, side=tk.TOP)
  449. b = tk.Button(frame,bg="lightblue", text="ENCODER",width=10)
  450. #b.bind("<Button>",Xevent(fix=fix,elem=b).cb)
  451. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  452. #r+=1
  453. c+=1
  454. for attr in self.all_attr:
  455. if attr.endswith("-FINE"):
  456. continue
  457. v=0
  458. b = tk.Button(frame,bg="orange", text=str(attr)+'',width=10)
  459. b.bind("<Button>",Xevent(fix=0,elem=b,attr=attr,data=self,mode="ENCODER").cb)
  460. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  461. c+=1
  462. if c >=8:
  463. c=0
  464. r+=1
  465. def draw_command(self):
  466. i=0
  467. c=0
  468. r=0
  469. frame = tk.Frame(root,bg="black")
  470. frame.pack(fill=tk.X, side=tk.TOP)
  471. b = tk.Label(frame,bg="black", text="--------------------------------------- ---------------------------------------")
  472. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  473. r=0
  474. frame = tk.Frame(root,bg="black")
  475. frame.pack(fill=tk.X, side=tk.TOP)
  476. b = tk.Button(frame,bg="lightblue", text="COMMANDS",width=10)
  477. #b.bind("<Button>",Xevent(fix=fix,elem=b).cb)
  478. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  479. #r+=1
  480. c+=1
  481. for comm in self.commands:
  482. v=0
  483. b = tk.Button(frame,bg="lightgrey", text=str(comm),width=10)
  484. if comm not in self.elem_commands:
  485. self.elem_commands[comm] = b
  486. self.val_commands[comm] = 0
  487. b.bind("<Button>",Xevent(fix=0,elem=b,attr=comm,data=self,mode="COMMAND").cb)
  488. if comm:
  489. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  490. c+=1
  491. if c >=8:
  492. c=0
  493. r+=1
  494. def draw_preset(self):
  495. i=0
  496. c=0
  497. r=0
  498. frame = tk.Frame(root,bg="black")
  499. frame.pack(fill=tk.X, side=tk.TOP)
  500. b = tk.Label(frame,bg="black", text="--------------------------------------- ---------------------------------------")
  501. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  502. r=0
  503. frame = tk.Frame(root,bg="black")
  504. frame.pack(fill=tk.X, side=tk.TOP)
  505. b = tk.Button(frame,bg="lightblue", text="PRESET")
  506. #b.bind("<Button>",Xevent(elem=b).cb)
  507. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  508. r+=1
  509. for k in self.presets:
  510. v=0
  511. b = tk.Button(frame,bg="grey", text="Preset:"+str(k),width=8,height=2)
  512. b.bind("<Button>",Xevent(fix=0,elem=b,attr=k,data=self,mode="PRESET").cb)
  513. if k in self.val_presets and len(self.val_presets[k]) :
  514. b["bg"] = "yellow"
  515. if k not in self.elem_presets:
  516. self.elem_presets[k] = b
  517. #self.val_presets[preset] = 0
  518. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  519. c+=1
  520. if c >=8:
  521. c=0
  522. r+=1
  523. def draw_input(self):
  524. i=0
  525. c=0
  526. r=0
  527. frame = tk.Frame(root,bg="black")
  528. frame.pack(fill=tk.X, side=tk.TOP)
  529. b = tk.Label(frame,bg="black", text="--------------------------------------- ---------------------------------------")
  530. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  531. r=0
  532. frame = tk.Frame(root,bg="black")
  533. frame.pack(fill=tk.X, side=tk.TOP)
  534. b = tk.Label(frame, text="send:")
  535. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  536. c+=1
  537. b = tk.Entry(frame,bg="grey", text="",width=39)
  538. b.bind("<Button>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT").cb)
  539. b.bind("<Key>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT").cb)
  540. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  541. def render(self):
  542. for fix in self.fixtures:
  543. data = self.fixtures[fix]
  544. print( fix)
  545. self.draw_fix(fix,data)
  546. self.draw_enc()
  547. self.draw_command()
  548. self.draw_input()
  549. self.draw_preset()
  550. master =Master()
  551. master.render()
  552. root.mainloop()