Editor2.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  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 time
  18. import tkinter
  19. import sys
  20. import _thread as thread
  21. import tkinter as tk
  22. from tkinter import font
  23. import lib.chat as chat
  24. root = tk.Tk()
  25. root["bg"] = "red"
  26. #default_font = font.Font(family='Helvetica', size=12, weight='bold')
  27. default_font = font.Font(family='Helvetica', size=10, weight='normal')
  28. #default_font.configure(size=9)
  29. root.option_add("*Font", default_font)
  30. from collections import OrderedDict
  31. CUES = OrderedDict()
  32. groups = OrderedDict()
  33. BLIND = 0
  34. STORE = 0
  35. POS = ["PAN","TILT","MOTION"]
  36. COLOR = ["RED","GREEN","BLUE","COLOR"]
  37. BEAM = ["GOBO","G-ROT","PRISMA","P-ROT","FOCUS","SPEED"]
  38. INT = ["DIM","SHUTTER","STROBE","FUNC"]
  39. client = chat.tcp_sender()
  40. class Xevent():
  41. def __init__(self,elem,attr=None,data=None,mode=None):
  42. self.data=data
  43. self.attr = attr
  44. self.elem = elem
  45. self.mode = mode
  46. def encoder(self,attr,data,elem,action=""):
  47. if action == "click":
  48. if self.data["ATTRIBUT"][attr]["ACTIVE"]:
  49. self.data["ATTRIBUT"][attr]["ACTIVE"] = 0
  50. self.elem["bg"] = "grey"
  51. else:
  52. self.data["ATTRIBUT"][attr]["ACTIVE"] = 1
  53. self.elem["bg"] = "yellow"
  54. return 1
  55. v=data["ATTRIBUT"][attr]["VALUE"]
  56. change=0
  57. if action == "+":
  58. v+= 4.11
  59. change=1
  60. elif action == "-":
  61. v-= 4.11
  62. change=1
  63. if v < 0:
  64. v=0
  65. elif v > 256:
  66. v=256
  67. if change:
  68. data["ATTRIBUT"][attr]["ACTIVE"] = 1
  69. elem["bg"] = "yellow"
  70. data["ATTRIBUT"][attr]["VALUE"] = v
  71. elem["text"] = str(attr)+' '+str(round(v,2))
  72. self.update_dmx(attr=attr,data=data)
  73. def update_dmx(self,attr,data):
  74. global BLIND
  75. dmx = data["DMX"]
  76. val = None
  77. if attr == "VDIM":
  78. for attr in data["ATTRIBUT"]:
  79. dmx = data["DMX"]
  80. if data["ATTRIBUT"][attr]["NR"] < 0:
  81. continue
  82. dmx += data["ATTRIBUT"][attr]["NR"]
  83. #print(attr)
  84. val = data["ATTRIBUT"][attr]["VALUE"]
  85. if data["ATTRIBUT"][attr]["MASTER"]:
  86. val = val * (data["ATTRIBUT"]["VDIM"]["VALUE"] / 255.)
  87. if val is not None:
  88. cmd = "d{}:{}".format(dmx,int(val))
  89. #print("cmd",cmd)
  90. if not BLIND:
  91. client.send(cmd )
  92. else:
  93. pass#print("BLIND ! cmd",cmd)
  94. elif data["ATTRIBUT"][attr]["NR"] >= 0:
  95. dmx += data["ATTRIBUT"][attr]["NR"]
  96. val = data["ATTRIBUT"][attr]["VALUE"]
  97. if data["ATTRIBUT"][attr]["MASTER"]:
  98. if "VDIM" in data["ATTRIBUT"]:
  99. val = val * (data["ATTRIBUT"]["VDIM"]["VALUE"] / 255.)
  100. if val is not None:
  101. cmd = "d{}:{}".format(dmx,int(val))
  102. #print("cmd",cmd)
  103. if not BLIND:
  104. client.send(cmd )
  105. else:
  106. pass#print("BLIND ! cmd",cmd)
  107. def cb(self,event):
  108. #print("cb",self,event,data)
  109. print("cb",self.attr,self.mode,event)
  110. #print(self.obj.keys())
  111. try:
  112. #v = self.data["ATTRIBUT"][self.attr]
  113. change = 0
  114. if self.mode == "COMMAND":
  115. global STORE
  116. global BLIND
  117. if self.attr == "CLEAR":
  118. if event.num == 1:
  119. if STORE:
  120. self.data.val_commands["STORE"] = 0
  121. STORE = 0
  122. self.data.elem_commands["STORE"]["bg"] = "white"
  123. else:
  124. for fix in self.data.fixtures:
  125. print( "clr",fix)
  126. data = self.data.fixtures[fix]
  127. #print("elm",self.data.elem_attr[fix])
  128. for attr in data["ATTRIBUT"]:
  129. if attr.endswith("-FINE"):
  130. continue
  131. self.data.elem_attr[fix][attr]["bg"] = "grey"
  132. data["ATTRIBUT"][attr]["ACTIVE"] = 0
  133. #print(data["ATTRIBUT"])
  134. if self.attr == "BLIND":
  135. if event.num == 1:
  136. if self.data.val_commands[self.attr]:
  137. self.data.val_commands[self.attr] = 0
  138. BLIND = 0
  139. self.data.elem_commands[self.attr]["bg"] = "white"
  140. else:
  141. self.data.val_commands[self.attr] = 1
  142. BLIND = 1
  143. self.data.elem_commands[self.attr]["bg"] = "red"
  144. print("BLIND",self.data.val_commands)
  145. if self.attr == "STORE":
  146. if event.num == 1:
  147. if self.data.val_commands[self.attr]:
  148. self.data.val_commands[self.attr] = 0
  149. STORE = 0
  150. self.data.elem_commands[self.attr]["bg"] = "white"
  151. else:
  152. self.data.val_commands[self.attr] = 1
  153. STORE = 1
  154. self.data.elem_commands[self.attr]["bg"] = "red"
  155. print("BLIND",self.data.val_commands)
  156. return 0
  157. if self.mode == "ENCODER":
  158. #if self.attr == "VDIM":
  159. # self.attr = "DIM"
  160. for fix in self.data.fixtures:
  161. data = self.data.fixtures[fix]
  162. for attr in data["ATTRIBUT"]:
  163. if attr.endswith("-FINE"):
  164. continue
  165. elem = self.data.elem_attr[fix][attr]
  166. if self.attr != attr:
  167. continue
  168. if event.num == 1:
  169. #self.encoder(attr=attr,data=data,elem=elem,action="click")
  170. data["ATTRIBUT"][attr]["ACTIVE"] = 1
  171. elem["bg"] = "yellow"
  172. if not data["ATTRIBUT"][attr]["ACTIVE"]:
  173. continue
  174. if event.num == 4:
  175. self.encoder(attr=attr,data=data,elem=elem,action="+")
  176. #if attr == "DIM":
  177. # self.encoder(attr="VDIM",data=data,elem=elem,action="+")
  178. elif event.num == 5:
  179. self.encoder(attr=attr,data=data,elem=elem,action="-")
  180. #if attr == "DIM":
  181. # self.encoder(attr="VDIM",data=data,elem=elem,action="-")
  182. return 0
  183. if event.num == 1:
  184. self.encoder(attr=self.attr,data=self.data,elem=self.elem,action="click")
  185. elif event.num == 4:
  186. self.encoder(attr=self.attr,data=self.data,elem=self.elem,action="+")
  187. elif event.num == 5:
  188. self.encoder(attr=self.attr,data=self.data,elem=self.elem,action="-")
  189. except Exception as e:
  190. print("== cb EXCEPT",e)
  191. print("Error on line {}".format(sys.exc_info()[-1].tb_lineno))
  192. #print(self.elem["text"],self.attr,self.data)
  193. def wheel(event,d=None):
  194. print("wheel",event,d)
  195. import copy
  196. class Master():
  197. def __init__(self):
  198. self.load()
  199. self.all_attr =[]
  200. self.elem_attr = {}
  201. self.commands =["BLIND","CLEAR","STORE"]
  202. self.elem_commands = {}
  203. self.val_commands = {}
  204. self.presets = OrderedDict()
  205. self.elem_presets = {}
  206. for i in range(8*6):
  207. self.presets["Preset"+str(i)] = [1]
  208. def load(self):
  209. fixture = OrderedDict()
  210. DATA = OrderedDict()
  211. DATA["DIM"] = {"NR": 0, "MASTER": "1", "MODE": "F", "VALUE": 0.0,"ACTIVE":0}
  212. DATA["RED"] = {"NR": 3, "MASTER": "", "MODE": "F", "VALUE": 255.0,"ACTIVE":0}
  213. DATA["GREEN"] = {"NR": 4, "MASTER": "", "MODE": "F", "VALUE": 255.0,"ACTIVE":0}
  214. DATA["BLUE"] = {"NR": 5, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  215. fix = {"DMX": 20, "UNIVERS": 2, "NAME": "IRGB", "ATTRIBUT": DATA}
  216. DATA = OrderedDict()
  217. DATA["VDIM"] = {"NR": -1, "MASTER": "", "MODE": "F", "VALUE": 0.0,"ACTIVE":0}
  218. DATA["RED"] = {"NR": 2, "MASTER": "1", "MODE": "F", "VALUE": 255.0,"ACTIVE":0}
  219. DATA["GREEN"] = {"NR": 1, "MASTER": "1", "MODE": "F", "VALUE": 255.0,"ACTIVE":0}
  220. DATA["BLUE"] = {"NR": 0, "MASTER": "1", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  221. fix3 = {"DMX": 20, "UNIVERS": 2, "NAME": "V+RGB", "ATTRIBUT": DATA}
  222. DATA = OrderedDict()
  223. DATA["DIM-FINE"] = {"NR": 8, "MASTER": "", "MODE": "F", "VALUE": 5.0,"ACTIVE":0}
  224. DATA["VDIM"] = {"NR": -1, "MASTER": "", "MODE": "F", "VALUE": 0.0,"ACTIVE":0}
  225. DATA["PAN"] = {"NR": 0, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  226. DATA["PAN-FINE"] = {"NR": 1, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  227. DATA["TILT"] = {"NR": 2, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  228. DATA["TILT-FINE"] = {"NR": 3, "MASTER": "", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  229. DATA["RED"] = {"NR": 6, "MASTER": "1", "MODE": "F", "VALUE": 255.0,"ACTIVE":0}
  230. DATA["GREEN"] = {"NR": 7, "MASTER": "1", "MODE": "F", "VALUE": 255.0,"ACTIVE":0}
  231. DATA["BLUE"] = {"NR": 8, "MASTER": "1", "MODE": "F", "VALUE": 127.0,"ACTIVE":0}
  232. fixTMH = {"DMX": 20, "UNIVERS": 2, "NAME": "MH-BEAM", "ATTRIBUT": DATA}
  233. fi = copy.deepcopy(fixTMH)
  234. fi["DMX"] = 241
  235. fixture["2001"] = fi
  236. fi = copy.deepcopy(fixTMH)
  237. fi["DMX"] = 461
  238. fixture["2002"] = fi
  239. fi = copy.deepcopy(fix3)
  240. fi["DMX"] = 441
  241. fixture["2003"] = fi
  242. fi = copy.deepcopy(fix3)
  243. fi["DMX"] = 461
  244. fixture["2005"] = fi
  245. fi = copy.deepcopy(fix)
  246. fi["DMX"] = 401
  247. fixture["1001"] = fi
  248. fi = copy.deepcopy(fix)
  249. fi["DMX"] = 421
  250. fi["ATTRIBUT"]["BLUE"]["VALUE"] = 22
  251. fixture["1002"] = fi
  252. fi = copy.deepcopy(fix)
  253. fi["DMX"] = 441
  254. fi["ATTRIBUT"]["BLUE"]["VALUE"] = 22
  255. fixture["1003"] = fi
  256. self.fixtures = fixture
  257. self.preset = OrderedDict()
  258. #["IRIS OPEN", {"74": {"IRIS": 0.0, "_activ": 1, "_selection_nr": 1}}],
  259. for i in range(60):
  260. self.preset["NAME"] = "PRESET "+str(i+1)
  261. DATA = OrderedDict()
  262. DATA["2001"] = {"VDIM":200,"RED":2}
  263. DATA["2002"] = {"VDIM":100,"RED":2}
  264. DATA["2003"] = {"VDIM":50,"RED":2}
  265. self.preset["DATA"] = DATA
  266. def draw_fix(self,fix,data):
  267. i=0
  268. c=0
  269. r=0
  270. frame = tk.Frame(root,bg="black")
  271. frame.pack(fill=tk.X, side=tk.TOP)
  272. b = tk.Button(frame,bg="lightblue", text="FIX:"+str(fix)+" "+data["NAME"],width=20)
  273. b.bind("<Button>",Xevent(elem=b).cb)
  274. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  275. c+=1
  276. #r+=1
  277. if fix not in self.elem_attr:
  278. self.elem_attr[fix] = {}
  279. for attr in data["ATTRIBUT"]:
  280. if attr not in self.all_attr:
  281. self.all_attr.append(attr)
  282. if attr not in self.elem_attr[fix]:
  283. self.elem_attr[fix][attr] = []
  284. if attr.endswith("-FINE"):
  285. continue
  286. v= data["ATTRIBUT"][attr]["VALUE"]
  287. b = tk.Button(frame,bg="grey", text=str(attr)+' '+str(round(v,2)),width=10)
  288. self.elem_attr[fix][attr] = b
  289. b.bind("<Button>",Xevent(elem=b,attr=attr,data=data).cb)
  290. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  291. c+=1
  292. if c >=8:
  293. c=0
  294. r+=1
  295. def draw_enc(self):
  296. i=0
  297. c=0
  298. r=0
  299. frame = tk.Frame(root,bg="black")
  300. frame.pack(fill=tk.X, side=tk.TOP)
  301. b = tk.Label(frame,bg="black", text="--------------------------------------- ---------------------------------------")
  302. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  303. r=0
  304. frame = tk.Frame(root,bg="black")
  305. frame.pack(fill=tk.X, side=tk.TOP)
  306. b = tk.Button(frame,bg="lightblue", text="ENCODER")
  307. #b.bind("<Button>",Xevent(elem=b).cb)
  308. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  309. r+=1
  310. for attr in self.all_attr:
  311. if attr.endswith("-FINE"):
  312. continue
  313. v=0
  314. b = tk.Button(frame,bg="orange", text=str(attr)+'',width=10)
  315. b.bind("<Button>",Xevent(elem=b,attr=attr,data=self,mode="ENCODER").cb)
  316. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  317. c+=1
  318. if c >=8:
  319. c=0
  320. r+=1
  321. def draw_command(self):
  322. i=0
  323. c=0
  324. r=0
  325. frame = tk.Frame(root,bg="black")
  326. frame.pack(fill=tk.X, side=tk.TOP)
  327. b = tk.Label(frame,bg="black", text="--------------------------------------- ---------------------------------------")
  328. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  329. r=0
  330. frame = tk.Frame(root,bg="black")
  331. frame.pack(fill=tk.X, side=tk.TOP)
  332. b = tk.Button(frame,bg="lightblue", text="COMMANDS")
  333. #b.bind("<Button>",Xevent(elem=b).cb)
  334. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  335. r+=1
  336. for comm in self.commands:
  337. v=0
  338. b = tk.Button(frame,bg="white", text=str(comm),width=10)
  339. if comm not in self.elem_commands:
  340. self.elem_commands[comm] = b
  341. self.val_commands[comm] = 0
  342. b.bind("<Button>",Xevent(elem=b,attr=comm,data=self,mode="COMMAND").cb)
  343. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  344. c+=1
  345. if c >=8:
  346. c=0
  347. r+=1
  348. def draw_preset(self):
  349. i=0
  350. c=0
  351. r=0
  352. frame = tk.Frame(root,bg="black")
  353. frame.pack(fill=tk.X, side=tk.TOP)
  354. b = tk.Label(frame, text="--------------------------------------- ---------------------------------------")
  355. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  356. r=0
  357. frame = tk.Frame(root,bg="black")
  358. frame.pack(fill=tk.X, side=tk.TOP)
  359. b = tk.Button(frame,bg="lightblue", text="PRESET")
  360. #b.bind("<Button>",Xevent(elem=b).cb)
  361. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  362. r+=1
  363. for k in self.presets:
  364. v=0
  365. b = tk.Button(frame,bg="white", text=str(k),height=2)
  366. b.bind("<Button>",Xevent(elem=b,attr=k,data=self,mode="COMMAND").cb)
  367. b.grid(row=r, column=c, sticky=tk.W+tk.E)
  368. c+=1
  369. if c >=8:
  370. c=0
  371. r+=1
  372. def render(self):
  373. for fix in self.fixtures:
  374. data = self.fixtures[fix]
  375. print( fix)
  376. self.draw_fix(fix,data)
  377. self.draw_enc()
  378. self.draw_command()
  379. self.draw_preset()
  380. master =Master()
  381. master.render()
  382. root.mainloop()