#! /usr/bin/python # -*- coding: utf-8 -*- """ This file is part of LibreLight. LibreLight is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2 of the License. LibreLight is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with LibreLight. If not, see <http://www.gnu.org/licenses/>. (c) 2012 micha@uxsrv.de """ import random rnd_id = str(random.randint(1000,9000)) rnd_id += " Beta 22.02 " import subprocess rnd_id += subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD']).decode('ascii').strip() try: xtitle = __file__ except: xtitle = "__file__" if "/" in xtitle: xtitle = xtitle.split("/")[-1] import sys sys.stdout.write("\x1b]2;"+str(xtitle)+" "+str(rnd_id)+"\x07") # terminal title import json import time import sys import os import _thread as thread import traceback import tkinter import tkinter as tk from tkinter import font import tkinter.simpledialog import lib.chat as chat import lib.motion as motion from collections import OrderedDict CUES = OrderedDict() groups = OrderedDict() class Modes(): def __init__(self): self.modes = {} self.__cfg = {} self.__cb = None def val(self,mode,value=None): if value is not None: return self.set(mode,value) elif mode in self.modes: return self.modes[mode] def get(self,mode,value=None): return slef.val(mode,value) def __check(self,mode): if mode not in self.modes: self.modes[mode] = 0 self.__cfg[mode] = 0 def cfg(self,mode,data={}): self.__check(mode) if type(data) is dict: for k in data: v = data[k] if v not in self.__cfg: self.__cfg[k] = v return 1 elif type(data) is str: if data in self.__cfg: return self.__cfg[data] def set(self,mode,value): protected = ["BLIND","CLEAR","STONY_FX"] self.__check(mode) out = 0 if mode == "CLEAR": return 1 elif mode == "ESC": for m in self.modes: print("ESC",m) if m == "COPY": PRESETS.clear_copy() if m == "MOVE": PRESETS.clear_move() if m != "BLIND": self.modes[m] = 0 self.callback(m) out = 1 return 1 elif value: for m in self.modes: if m not in protected and mode not in protected and m != mode: if self.modes[m]: self.modes[m]= 0 self.callback(m) if self.modes[mode]: if modes == "MOVE": PRESETS.clear_move() if modes == "COPY": PRESETS.clear_copy() self.modes[mode] = 0 # value else: self.modes[mode] = 1 #value out = 1 else: self.modes[mode] = 0 #value if modes == "COPY": PRESETS.clear_copy() if modes == "MOVE": PRESETS.clear_move() self.callback(mode) return value def set_cb(self,cb): if cb: self.__cb = cb def callback(self,mode): if self.__cb is not None and mode in self.modes: value = self.modes[mode] self.__cb(mode=mode,value=value) modes = Modes() #modes.val("BLIND", 0) #modes.modes["BLIND"] = 0 modes.modes["ESC"] = 0 modes.modes["REC"] = 0 modes.modes["EDIT"] = 0 modes.modes["MOVE"] = 0 modes.modes["FLASH"] = 0 modes.modes["GO"] = 0 modes.modes["DEL"] = 0 modes.modes["STONY_FX"] = 0 modes.modes["SELECT"] = 0 modes.modes["CFG-BTN"] = 0 modes.modes["LABEL"] = 0 def xcb(mode,value=None): print("xcb","MODE CALLBACK",mode,value) if mode == "STONY_FX": print("xcb",modes.val("STONY_FX")) #modes.set_cb(xcb) POS = ["PAN","TILT","MOTION"] COLOR = ["RED","GREEN","BLUE","COLOR"] BEAM = ["GOBO","G-ROT","PRISMA","P-ROT","FOCUS","SPEED"] INT = ["DIM","SHUTTER","STROBE","FUNC"] client = chat.tcp_sender(port=50001) jclient = chat.tcp_sender()#port=50001) def jclient_send(data): jclient.send("\00 "+ json.dumps(data) +"\00 ") class _FadeTime(): def __init__(self): self._value = 2 self._on = 1 def inc(self,value=None): if value is not None: if type(value) is float: self._value += round(value,4) else: self._value += value return self._value def val(self,value=None): if value is not None: if type(value) is float: self._value = round(value,4) else: self._value = value return self._value def on(self): self._on = 1 def off(self): self._on = 0 def _is(self): if self._on: return 1 return 0 FADE = _FadeTime() #2 #0.1 #1.13 fx_move_prm = {"SIZE":20,"SPEED":100,"OFFSET":50,"BASE":"-","START":0} fx_prm = {"SIZE":200,"SPEED":30,"OFFSET":255,"BASE":"-","START":0,"MODE":0,"MO":0,"DIR":1,"WING":2} fx_modes = [":RED",":GREEN",":BLUE",":MAG",":YELLOW",":CYAN"] fx_mo = ["sinus","on","on2","bump","bump2","fade","cosinus"] def build_cmd(dmx,val,args=[],flash=0,xpfx="",attr=""): if not args: args.append(FADE.val()) cmd="" if xpfx: pfx=xpfx elif flash: pfx ="df" else: pfx ="d" if type(val) is float or type(val) is int: cmd += ",{}{}:{:0.4f}".format(pfx,dmx,val) else: cmd += ",{}{}:{}".format(pfx,dmx,val) if flash: cmd += ":0:0"#.format(val) else: for val in args: if type(val) is float or type(val) is int: cmd += ":{:0.4f}".format(val) else: cmd += ":{}".format(val) if attr: cmd += ":"+str(attr) cprint("build_cmd",cmd,color="red") return cmd def update_raw_dmx(data ,value=None,args=[],xfade=0,flash=0,pfx="d",fx=0): if flash: xfade = 0 if not args: # and xfade is not None:# and FADE._is(): args.append(xfade) else: args[0] = xfade cmd = [] jcmd = [] if flash: pfx += "f" for row in data: jxcmd={} if type(value) is float: jxcmd["VALUE"] = value #round(value,3) else: jxcmd["VALUE"] = value jxcmd["args"] = [] if fx: if value is not None: # z.b. flush off xcmd = str(value)+":"+row["FX"].split(":",1)[-1] jxcmd["FX"] = row["FX"].split(":",1)[-1] else: xcmd = row["FX"] jxcmd["FX"] = row["FX"] else: if row["VALUE"] is None: xcmd = "" else: if value is not None: if type(value) is float: xcmd = "{:0.4f}".format(value) else: xcmd = "{}".format(value) else: v=row["VALUE"] xcmd = "{:0.4f}".format(v) cprint([v]) if type(v) is float: jxcmd["VALUE"] = v #round(v,3) else: jxcmd["VALUE"] = v for arg in args: if type(arg) is float: xcmd += ":{:0.4f}".format(arg) jxcmd["args"].append(v)#round(arg,3)) else: xcmd += ":{}".format(arg) jxcmd["args"].append(arg)#round(arg,3)) #print( "pack: FIX",row["FIX"],row["ATTR"], xcmd) #xcmd += ":{}".format(row["ATTR"]) v= xfade #FADE.val() #rxcmd["args"][0] if type( v ) is float: jxcmd["FADE"] = round(v,4) else: jxcmd["FADE"] = v #if ("VALUE" in jxcmd and jxcmd["VALUE"] is not None) or "FX" in jxcmd and jxcmd["FX"]: jcmd.append( jxcmd) cmd.append( xcmd) #if xcmd: # cprint("update_raw_dmx j",jxcmd,color="red") # cprint("update_raw_dmx x",xcmd,color="red") return cmd,jcmd def update_dmx(attr,data,value=None,args=None,flash=0,pfx=""): xfade = 0 if not args: args=[] xfade = FADE.val() args.append(xfade) #global modes #BLIND #print("update_dmx",data) dmx = data["DMX"] dmx = (data["UNIVERS"]*512)+data["DMX"] val = None cmd="" try: if attr == "DIM" and data["ATTRIBUT"][attr]["NR"] < 0: #VDIM #print( "VDIM") for attr in data["ATTRIBUT"]: dmx = (data["UNIVERS"]*512) + data["DMX"] dmx = data["DMX"] if data["ATTRIBUT"][attr]["NR"] < 0: #virtual channels continue dmx += data["ATTRIBUT"][attr]["NR"]-1 mode = "" if "MODE" in data["ATTRIBUT"][attr]: mode = data["ATTRIBUT"][attr]["MODE"] #print(attr) val = data["ATTRIBUT"][attr]["VALUE"] if data["ATTRIBUT"][attr]["MASTER"]: val = val * (data["ATTRIBUT"]["DIM"]["VALUE"] / 255.) if val is not None: #cmd += ",d{}:{:0.4f}".format(dmx,int(val)) if value is not None: val = value if mode == "F": #FADE cmd += build_cmd(dmx,val,args=args,flash=flash,xpfx=pfx,attr=attr) else: cmd += build_cmd(dmx,val,args=[0],flash=flash,xpfx=pfx,attr=attr) #print("cmd",cmd) elif data["ATTRIBUT"][attr]["NR"] > 0: dmx += data["ATTRIBUT"][attr]["NR"]-1 val = data["ATTRIBUT"][attr]["VALUE"] mode = "" if "MODE" in data["ATTRIBUT"][attr]: mode = data["ATTRIBUT"][attr]["MODE"] if data["ATTRIBUT"][attr]["MASTER"]: #if "VDIM" in data["ATTRIBUT"]: if "DIM" in data["ATTRIBUT"] and data["ATTRIBUT"]["DIM"]["NR"] < 0: #VDIM val = val * (data["ATTRIBUT"]["DIM"]["VALUE"] / 255.) if val is not None: #cmd += ",d{}:{}".format(dmx,int(val)) if value is not None: val = value if mode == "F": #FADE cmd += build_cmd(dmx,val,args=args,flash=flash,xpfx=pfx,attr=attr) else: cmd += build_cmd(dmx,val,args=[0],flash=flash,xpfx=pfx,attr=attr) #print("cmd",cmd) if modes.val("BLIND"): cmd="" cprint("update_dmx",cmd,color="red") return cmd except Exception as e: cprint("== cb EXCEPT",e,color="red") cprint("Error on line {}".format(sys.exc_info()[-1].tb_lineno),color="red") cprint(''.join(traceback.format_exception(None, e, e.__traceback__)),color="red") raise e class dummy_event(): def __init__(self): self.num =0 self.type = 4 #press 5 release self.set_value=-1 gcolor = 1 def cprint(*text,color="blue",space=" ",end="\n"): #return 0 #disable print dbg if not gcolor: print(text) return 0 if color == "green": txt = '\033[92m' elif color == "red": txt = '\033[0;31m\033[1m' elif color == "yellow": txt = '\033[93m\033[1m' elif color == "cyan": txt = '\033[96m' else: txt = '\033[94m' for t in text: txt += str(t ) +" " #HEADER = '\033[95m' #OKBLUE = '\033[94m' #OKCYAN = '\033[96m' #OKGREEN = '\033[92m' #WARNING = '\033[93m' #FAIL = '\033[91m' #ENDC = '\033[0m' #BOLD = '\033[1m' #UNDERLINE = '\033[4m' txt += '\033[0m' print(txt,end=end) #return txt cprint("________________________________") class Xevent(): def __init__(self,fix,elem,attr=None,data=None,mode=None): self.fix = fix self.data=data self.attr = attr self.elem = elem self.mode = mode def fx(self,event): cprint("Xevent.fx",self.attr,self.fix,event) jdatas = [] if event.num == 4: cprint("FX:COLOR CHANGE",fx_prm,color="red") txt = "FX:RED" fx_prm["MODE"] += 1 if fx_prm["MODE"] > len(fx_modes): fx_prm["MODE"]=0 txt = "FX:"+fx_modes[fx_prm["MODE"]] master.elem_fx_commands["FX:RED"]["text"] = txt elif event.num == 5: cprint("FX:COLOR CHANGE",fx_prm,color="red") txt = "FX:RED" fx_prm["MODE"] -= 1 if fx_prm["MODE"] < 0: fx_prm["MODE"]= len(fx_modes)-1 txt = "FX:"+fx_modes[fx_prm["MODE"]] master.elem_fx_commands["FX:RED"]["text"] = txt elif event.num == 1: cmd = "" offset = 0 offset_flag=0 start = fx_prm["START"] base = fx_prm["BASE"] #FIXTURES.start_fx(attr) xfixtures = [] # WING's and BLOCK's for fix in FIXTURES.fixtures: xfixtures.append(fix) x=0 if fx_prm["DIR"] < 0: xfixtures = xfixtures[::-1] x=-1 wings = [] if fx_prm["WING"]: l = len(xfixtures) w = l // fx_prm["WING"] teiler = l//w if teiler < 2: teiler = 2 for i in range(teiler): j = i*w wing = xfixtures[j:j+w] if i%2==0: wing = wing[::-1] print("wing",i,"j",j,"w",w,"wing",wing) wings.append(wing) if l > j+w: wing = xfixtures[j+w:] wings.append(wing) else: wings.append(xfixtures) print("FX442 ",xfixtures) print("FX442 ",fx_prm,x) for wing in wings: coffset= offset for fix in wing: data = FIXTURES.fixtures[fix] #print( "ADD FX",fix) for attr in data["ATTRIBUT"]: jdata = {"MODE":"FX"} jdata["FIX"] = fix jdata["DMX"] = FIXTURES.get_dmx(fix,attr) jdata["ATTR"] =attr if attr.endswith("-FINE"): continue csize = fx_prm["SIZE"] cspeed = fx_prm["SPEED"] cstart = fx_prm["START"] cbase = fx_prm["BASE"] #cstart = start coffset= offset #cbase = base fx="" if "SIN" in self.attr: fx = "sinus" elif "FD" in self.attr: fx = "fade" elif "ON2" in self.attr: fx = "on2" elif "ON" in self.attr: fx = "on" elif "BUM2" in self.attr: fx = "bump2" elif "BUM" in self.attr: fx = "bump" elif "COS" in self.attr: fx = "cosinus" if fx: if fx_prm["SPEED"] < 0.1: fx = "off" else: if ":DIM" in self.attr: base="" ffxb= fx_mo[fx_prm["MO"]] if attr == "DIM": if fx_prm["SPEED"] < 0.1: fx = "off" else: fx = ffxb #"fade" elif ":TILT" in self.attr: base="" if attr == "PAN": fx = "off" if attr == "TILT": if fx_prm["SPEED"] < 0.1: fx = "off" else: fx = "sinus" elif ":PAN" in self.attr: base="" if attr == "PAN": if fx_prm["SPEED"] < 0.1: fx = "off" else: fx = "cosinus" if attr == "TILT": fx = "off" elif ":CIR" in self.attr: base="" if attr == "PAN": if fx_prm["SPEED"] < 0.1: fx = "off" else: fx = "cosinus" if attr == "TILT": if fx_prm["SPEED"] < 0.1: fx = "off" else: fx = "sinus" elif ":RED" in self.attr: ffxb= fx_mo[fx_prm["MO"]] ffx= "off" #fx_mo[fx_prm["MO"]] if ":RED" in fx_modes[fx_prm["MODE"]]:# base="-" if attr == "RED": #coffset=0 #cspeed=0 fx=ffx if attr == "GREEN": fx = ffxb# "off" if attr == "BLUE": fx = ffxb#"off" elif ":GREEN" in fx_modes[fx_prm["MODE"]]:#fx_prm["MODE"]:#in self.attr: base="-" if attr == "RED": fx = ffxb#"off" elif ":GREEN" in fx_modes[fx_prm["MODE"]]:#fx_prm["MODE"]:#in self.attr: if attr == "GREEN": fx = ffxb# "off" #cspeed=0 #coffset=0 fx=ffx if attr == "BLUE": fx = ffxb#"off" elif ":BLUE" in fx_modes[fx_prm["MODE"]]:#fx_prm["MODE"]:#self.attr: base="-" if attr == "RED": fx = ffxb# "off" if attr == "GREEN": fx = ffxb# "off" if attr == "BLUE": fx = ffxb# "off" #cspeed=0 #coffset=0 fx=ffx elif ":YELLOW" in fx_modes[fx_prm["MODE"]]:#fx_prm["MODE"]:#self.attr: base="-" if attr == "RED": fx = ffxb# "off" #cspeed=0 #coffset=0 fx=ffx if attr == "GREEN": fx = ffxb# "off" #cspeed=0 #coffset=0 fx=ffx if attr == "BLUE": fx = "off" elif ":CYAN" in fx_modes[fx_prm["MODE"]]:#fx_prm["MODE"]:#self.attr: base="-" if attr == "RED": fx = ffxb# "off" if attr == "GREEN": fx = ffxb# "off" #cspeed=0 #coffset=0 fx=ffx if attr == "BLUE": fx = ffxb# "off" #cspeed=0 #coffset=0 fx=ffx elif ":MAG" in fx_modes[fx_prm["MODE"]]:#fx_prm["MODE"]:#self.attr: base="-" if attr == "RED": fx = ffxb# "off" fx=ffx #cspeed=0 #coffset=0 if attr == "GREEN": fx = ffxb# "off" if attr == "BLUE": fx = ffxb# "off" fx=ffx #cspeed=0 #coffset=0 else: cprint("FX: unbekant",fx_modes[fx_prm["MODE"]],color="red") jdata["TYPE"] = fx jdata["OFFSET"]= coffset jdata["SPEED"] = cspeed jdata["START"] = cstart jdata["BASE"] = cbase if fx: print(jdata) jdatas.append(jdata) if fx: #fx += ":{:0.0f}:{:0.0f}:{:0.0f}:{:0.0f}:{}:".format(fx_prm["SIZE"],fx_prm["SPEED"],start,offset,base) fx += ":{:0.0f}:{:0.0f}:{:0.0f}:{:0.0f}:{}:".format(csize,cspeed,cstart,coffset,cbase) offset_flag=1 #print("ADD FX",fix,attr,fx,data["ATTRIBUT"][attr]["ACTIVE"]) if "FX" not in data["ATTRIBUT"][attr]: data["ATTRIBUT"][attr]["FX"] ="" if data["ATTRIBUT"][attr]["ACTIVE"] and fx: print("++ADD FX",fix,attr,fx) data["ATTRIBUT"][attr]["FX"] = fx #"sinus:40:100:10" cmd+=update_dmx(attr,data,pfx="fx",value=fx)#,flash=FLASH) if fx_prm["OFFSET"] > 0.5 and offset_flag: offset_flag=0 offset += fx_prm["OFFSET"] # add offset on next fixture #print("offset",offset) if cmd and not modes.val("BLIND"): client.send(cmd) jclient_send(jdatas) master.refresh_fix() def command(self,event): if self.mode == "COMMAND": if self.attr == "CLEAR": if event.num == 1: ok = FIXTURES.clear() if ok: master.refresh_fix() modes.val(self.attr,0) elif self.attr.startswith("SZ:"):#SIN": #global fx_prm k = "SIZE" if event.num == 1: pass elif event.num == 2: pass elif event.num == 4: if fx_prm[k] <= 0: fx_prm[k] = 1 fx_prm[k] *=1.2 elif event.num == 5: fx_prm[k] /=1.2 #fx_prm[k] =int(fx_prm[k]) if fx_prm[k] > 4000: fx_prm[k] = 4000 if fx_prm[k] < 0: fx_prm[k] =0 self.data.elem_fx_commands[self.attr]["text"] = "SZ:{:0.0f}".format(fx_prm[k]) elif self.attr.startswith("SP:"):#SIN": #global fx_prm k = "SPEED" if event.num == 1: pass elif event.num == 2: pass elif event.num == 4: if fx_prm[k] <= 0: fx_prm[k] = 1 fx_prm[k] *=1.2 elif event.num == 5: fx_prm[k] /=1.2 #fx_prm[k] =int(fx_prm[k]) if fx_prm[k] > 4000: fx_prm[k] = 4000 if fx_prm[k] < 0: fx_prm[k] =0 if fx_prm[k] < 0.1: self.data.elem_fx_commands[self.attr]["text"] = "SP:off".format(fx_prm[k]) else: self.data.elem_fx_commands[self.attr]["text"] = "SP:{:0.0f}".format(fx_prm[k]) elif self.attr.startswith("ST:"):#SIN": #global fx_prm k = "START" if event.num == 1: pass elif event.num == 2: pass elif event.num == 4: if fx_prm[k] <= 0: fx_prm[k] = 1 fx_prm[k] *=1.2 elif event.num == 5: fx_prm[k] /=1.2 #fx_prm[k] =int(fx_prm[k]) if fx_prm[k] > 4000: fx_prm[k] = 4000 if fx_prm[k] < 0: fx_prm[k] =0 self.data.elem_fx_commands[self.attr]["text"] = "ST:{:0.0f}".format(fx_prm[k]) elif self.attr.startswith("MO:"):# on,sinus,bump #global fx_prm k = "MO" if event.num == 1: pass elif event.num == 2: pass elif event.num == 4: fx_prm[k] -=1 if fx_prm[k] < 0: fx_prm[k] = len(fx_mo)-1 elif event.num == 5: fx_prm[k] +=1 if fx_prm[k] >= len(fx_mo): fx_prm[k] = 0 txt = fx_mo[fx_prm[k]] self.data.elem_fx_commands[self.attr]["text"] = "MO:{}".format(txt) elif self.attr.startswith("DIR:"):#SIN": #global fx_prm k = "DIR" if event.num == 1: pass elif event.num == 2: pass elif event.num == 4: fx_prm[k] = 1 elif event.num == 5: fx_prm[k] =-1 txt = fx_prm[k] self.data.elem_fx_commands[self.attr]["text"] = "DIR:{}".format(fx_prm[k]) elif self.attr.startswith("WING:"):#SIN": #global fx_prm k = "WING" if event.num == 1: pass elif event.num == 2: pass elif event.num == 4: fx_prm[k] += 1 elif event.num == 5: fx_prm[k] -=1 if fx_prm[k] > 10: fx_prm[k] = 10 if fx_prm[k] < 0: fx_prm[k] =0 txt = fx_prm[k] self.data.elem_fx_commands[self.attr]["text"] = "WING:{}".format(fx_prm[k]) elif self.attr.startswith("OF:"):#SIN": #global fx_prm k = "OFFSET" if event.num == 1: pass elif event.num == 2: pass elif event.num == 4: if fx_prm[k] <= 0: fx_prm[k] = 1 fx_prm[k] *=1.2 elif event.num == 5: fx_prm[k] /=1.2 #fx_prm[k] =int(fx_prm[k]) if fx_prm[k] > 1024: fx_prm[k] = 1024 if fx_prm[k] < 0: fx_prm[k] =0 self.data.elem_fx_commands[self.attr]["text"] = "OF:{:0.0f}".format(fx_prm[k]) elif self.attr.startswith("BS:"): k = "BASE" if event.num == 1: fx_prm[k] = "0" elif event.num == 2: pass elif event.num == 4: fx_prm[k] = "+" elif event.num == 5: fx_prm[k] = "-" self.data.elem_fx_commands[self.attr]["text"] = "BS:{}".format(fx_prm[k]) elif self.attr.startswith("FX:"):#SIN": self.fx(event) elif self.attr == "FX OFF": if event.num == 1: FIXTURES.fx_off("all") CONSOLE.fx_off("all") CONSOLE.flash_off("all") master.refresh_fix() return 0 elif self.attr == "FADE": fade = FADE.val() print("EVENT CHANGE FADE",fade) if fade < 0.01: FADE.val(0.01) elif fade > 100.0: fade = 100 if event.num == 4: fade *= 1.1 elif event.num == 5: fade /= 1.1 elif event.num == 1: if FADE._is(): FADE.off()# = 0 self.data.elem_commands[self.attr]["bg"] = "grey" else: FADE.on()# = 1 self.data.elem_commands[self.attr]["bg"] = "green" elif event.num == 2: if fade > 1 and fade < 4: fade = 4 elif fade > 3 and fade < 6: fade = 6 elif fade > 5 and fade < 7: fade = 8 elif fade > 7 and fade < 9: fade = 10 elif fade > 9: fade = 0.01 elif fade < 1: fade = 1.1 fade = round(fade,3) FADE.val(fade) self.data.elem_commands[self.attr]["text"] = "Fade{:0.2f}".format(fade) elif self.attr == "BACKUP": modes.val(self.attr,1) PRESETS.backup_presets() FIXTURES.backup_patch() #time.sleep(1) modes.val(self.attr,0) else: if event.num == 1: print("ELSE",self.attr) modes.val(self.attr,1) return 0 def cb(self,event): cprint("EVENT cb",self.attr,self.mode,event,color='yellow') print(["type",event.type,"num",event.num]) try: change = 0 if "keysym" in dir(event): if "Escape" == event.keysym: ok = FIXTURES.clear() master.refresh_fix() return 0 if self.mode == "COMMAND": self.command(event) elif self.mode == "ROOT": if event.keysym=="Escape": pass elif self.mode == "INPUT": print("INP",self.data.entry.get()) if event.keycode == 36: x=self.data.entry.get() client.send(x) elif self.mode == "INPUT2": print("INP2",self.data.entry2.get()) if event.keycode == 36: x=self.data.entry2.get() client.send(x) elif self.mode == "INPUT3": print("INP3",self.data.entry3.get()) if event.keycode == 36: x=self.data.entry3.get() client.send(x) elif self.mode == "PRESET": nr = self.attr #int(self.attr.split(":")[1])-1 if event.num == 1: if str(event.type) == '4': #4 ButtonPress if modes.val("REC"): self.data.preset_rec(nr) modes.val("REC",0) elif modes.val("DEL"): ok=PRESETS.delete(nr) if ok: modes.val("DEL",0) master.refresh_exec() elif modes.val("COPY"): ok=PRESETS.copy(nr) if ok: modes.val("COPY",0) master.refresh_exec() elif modes.val("MOVE"): ok=PRESETS.move(nr) if ok: modes.val("MOVE",0) master.refresh_exec() elif modes.val("CFG-BTN"): master.btn_cfg(nr) elif modes.val("LABEL"):#else: master.label(nr) elif modes.val("EDIT"): FIXTURES.clear() self.data.preset_select(nr) self.data.preset_go(nr,xfade=0,event=event,val=255) modes.val("EDIT", 0) master.refresh_fix() elif modes.val("SELECT"): self.data.preset_select(nr) else: self.data.preset_go(nr,event=event,val=255) else: self.data.preset_go(nr,xfade=0,event=event,val=0) if event.num == 3: if not modes.val("REC"): self.data.preset_go(nr,xfade=0,event=event,val=255) return 0 elif self.mode == "INPUT": return 0 if self.mode == "ENCODER": cprint("ENC",self.fix,self.attr,self.mode) cprint(self.data) val="" if event.num == 1: val ="click" elif event.num == 4: val ="+" elif event.num == 5: val ="-" if val: FIXTURES.encoder(fix=self.fix,attr=self.attr,xval=val) master.refresh_fix() except Exception as e: cprint("== cb EXCEPT",e,color="red") cprint("Error on line {}".format(sys.exc_info()[-1].tb_lineno),color="red") cprint(''.join(traceback.format_exception(None, e, e.__traceback__)),color="red") def wheel(event,d=None): print("wheel",event,d) import copy class Element(): def __init__(self): self.__data = {} def set(self,key,val): self.__data[key] = val class Base(): def __init__(self): show_name = "GloryCamp2021" #show_name = "JMS" #show_name = "Dimmer" show_name = "DemoShow" self.home = os.environ['HOME'] self.show_path = self.home +"/LibreLight/" if not os.path.isdir(self.show_path): os.mkdir(self.show_path) self.show_path += "/show/" if not os.path.isdir(self.show_path): os.mkdir(self.show_path) self.show_path += "/" +show_name +"/" if not os.path.isdir(self.show_path): os.mkdir(self.show_path) pass def _load(self,filename): xfname = self.show_path+"/"+str(filename)+".sav" print("load",xfname) f = open(xfname,"r") lines = f.readlines() f.close() data = OrderedDict() labels = OrderedDict() for line in lines: key,label,rdata = line.split("\t",2) key = int(key) #print(xfname,"load",key,label) #print(line) jdata = json.loads(rdata,object_pairs_hook=OrderedDict) nrnull = 0 print(jdata) #if "ATTRIBUT" in jdata: # translate old FIXTURES.fixtures start with 0 to 1 # for attr in jdata["ATTRIBUT"]: # row = jdata["ATTRIBUT"][attr] # if type(row) is OrderedDict: # #print(row) # if "VALUE" in row: # v = row["VALUE"] # if type(v) is float: # v = round(v,4) # jdata["ATTRIBUT"][attr]["VALUE"] = round(v,4) # print("preset v",key,label,attr,v) if "ATTRIBUT" in jdata: # translate old FIXTURES.fixtures start with 0 to 1 for attr in jdata["ATTRIBUT"]: pass #if "VALUE" in jdata["ATTRIBUT"][attr]: # v = jdata["ATTRIBUT"][attr]["VALUE"] # if type(v) is float: # jdata["ATTRIBUT"][attr]["VALUE"] = round(v,4) # #print("fix v",attr,v) #if "NR" in jdata["ATTRIBUT"][attr]: # nr = jdata["ATTRIBUT"][attr]["NR"] # if nr == 0: # nrnull = 1 # break if nrnull: print("DMX NR IS NULL",attr,"CHANGE +1") for attr in jdata["ATTRIBUT"]: if "NR" in jdata["ATTRIBUT"][attr]: nr = jdata["ATTRIBUT"][attr]["NR"] if nr >= 0: jdata["ATTRIBUT"][attr]["NR"] +=1 data[key] = jdata labels[key] = label return data,labels def _backup(self,filename,data,labels): #fixture #xfname = "show/"+show_name+"/"+str(filename)+".sav" xfname = self.show_path+"/"+str(filename)+".sav" print("backup",xfname) f = open(xfname,"w") for key in data: line = data[key] #print(line) label = "label" if key in labels: label = labels[key] if label == "Name-"+str(key): label = "" #print(xfname,"load",key,label,len(line)) f.write( "{}\t{}\t{}\n".format( key,label,json.dumps(line) ) ) f.close() class Event(): def __init__(self,name): self.name=name #print("init",self) def event(self,event): print(self.name,event) class scroll(): def __init__(self,canvas): self.canvas=canvas def config(self,event): canvas = self.canvas canvas.configure(scrollregion=canvas.bbox("all"))#,width=400,height=200) def hex_to_rgb(hex): return tuple(int(hex[i:i+2], 16) for i in (0, 2, 4)) class cb(): def __init__(self,win): self.win = win def _callback(self,event): clobj=event.widget ## undermouse=find_withtag(master.CURRENT) undermouse=self.win.find_closest(self.win.CURRENT) print( repr(undermouse)) def callback(self,event): print(__file__,self,"callback",event) cnv = self.win item = cnv.find_closest(cnv.canvasx(event.x), cnv.canvasy(event.y))[0] tags = cnv.gettags(item) #cnv.itemconfigure(self.tag, text=tags[0]) print(tags,item) color = cnv.itemcget(item, "fill") cnv.itemconfig("all", width=1)#filla="green") cnv.itemconfig(item, width=3)#filla="green") print(color) print( hex_to_rgb(color[1:])) class GUI(Base): def __init__(self): super().__init__() self.load() self._XX = 0 self.all_attr =["DIM","PAN","TILT"] self.elem_attr = {} self.fx_commands =["STONY_FX","FX OFF","\n" ,"FX:CIR","FX:PAN","FX:TILT","\n" ,"MSZ:","MSP:","MST:","MOF:","MBS:-","\n" ,"FX:DIM","FX:RED", "MO:on","DIR:1","WING:0","\n" ,"SZ:","SP:","ST:","OF:","BS:-","\n" , "FX:SIN","FX:COS","FX:BUM","FX:BUM2","FX:FD","FX:ON","FX:ON2" ] self.commands =["\n","ESC","CFG-BTN","LABEL","BACKUP","DEL","\n" ,"SELECT","FLASH","GO","FADE","MOVE","\n" ,"BLIND","CLEAR","REC","EDIT","COPY","\n" ] self.elem_fx_commands = {} self.val_fx_commands = {} self.elem_commands = {} self.val_commands = {} self.elem_presets = {} for i in range(8*8*8): if i not in PRESETS.val_presets: name = "Preset:"+str(i+1)+":\nXYZ" #self.presets[i] = [i] PRESETS.val_presets[i] = OrderedDict() # FIX PRESETS.val_presets[i]["CFG"] = OrderedDict() # CONFIG PRESETS.label_presets[i] = "-" modes.set_cb(self.xcb) def button_refresh(self,name,color,color2=None,fg=None): cprint("button_refresh",name,color) #if color == "gold": # color2 = "yellow" if color2 is None: color2 = color if name in self.elem_commands: self.elem_commands[name]["bg"] = color self.elem_commands[name].config(activebackground=color2) if fg: self.elem_commands[name]["fg"] = fg print(dir(self.elem_commands[name])) elif name in self.elem_fx_commands: #todo self.elem_fx_commands[name]["bg"] = color self.elem_fx_commands[name].config(activebackground=color2) if fg: self.elem_fx_commands[name]["fg"] = fg print(dir(self.elem_fx_commands[name])) def btn_cfg(self,nr): txt = PRESETS.btn_cfg(nr) txt = tkinter.simpledialog.askstring("CFG-BTN","GO=GO\nFL=FLASH\nSEL=SELECT\n EXE:"+str(nr+1),initialvalue=txt) if txt: PRESETS.btn_cfg(nr,txt) self.elem_presets[nr]["text"] = PRESETS.get_btn_txt(nr) modes.val("CFG-BTN",0) def label(self,nr): txt = PRESETS.label(nr) txt = tkinter.simpledialog.askstring("LABEL","EXE:"+str(nr+1),initialvalue=txt) if txt: PRESETS.label(nr,txt) self.elem_presets[nr]["text"] = PRESETS.get_btn_txt(nr) modes.val("LABEL", 0) def xcb(self,mode,value=None): cprint("MODE CALLBACK",mode,value,color="green",end="") #cprint(self,"xcb","MODE CALLBACK",mode,value,color="green") if value: cprint("===== ON ======",color="red") self.button_refresh(mode,color="red")#,fg="blue") else: cprint("===== OFF ======",color="red") self.button_refresh(mode,color="lightgrey")#,fg="black") def load(self,fname=""): pass def exit(self): print("__del__",self) PRESETS.backup_presets() #print("********************************************************") FIXTURES.backup_patch() #print("*********del",self,"***********************************************") def refresh_exec(self): cprint("PRESET.refresh_exec()") self._XX +=1 for k in PRESETS.val_presets: label = "" if k not in self.elem_presets: cprint("ERROR",k ,"not in elem_presets continue") continue if k in PRESETS.label_presets: label = PRESETS.label_presets[k] #print([label]) b = self.elem_presets[k] if k in PRESETS.val_presets and len(PRESETS.val_presets[k]) : sdata = PRESETS.val_presets[k] #print("sdata7654",sdata) BTN="go" if "CFG" in sdata:#["BUTTON"] = "GO" if "BUTTON" in sdata["CFG"]: BTN = sdata["CFG"]["BUTTON"] txt=str(k)+":"+str(BTN)+":"+str(len(sdata)-1)+"\n"+label #txt+=str(self._XX) b["text"] = txt b["bg"] = "yellow" b.config(activebackground="yellow") if len(sdata) > 1: fx_color = 0 val_color = 0 for fix in sdata: if fix == "CFG": continue #print( "$$$$",fix,sdata[fix]) for attr in sdata[fix]: if "FX" in sdata[fix][attr]: if sdata[fix][attr]["FX"]: fx_color = 1 if "VALUE" in sdata[fix][attr]: if sdata[fix][attr]["VALUE"] is not None: val_color = 1 b["fg"] = "black" if val_color: b["bg"] = "gold" b.config(activebackground="#ffaa55") if fx_color: b["fg"] = "blue" else: if fx_color: b["bg"] = "cyan" b.config(activebackground="#55d4ff") else: b["bg"] = "grey" b.config(activebackground="#aaaaaa") if "\n" in txt: txt = txt.split("\n")[0] if "SEL" in txt: b["fg"] = "black" b["bg"] = "#5555ff" b.config(activebackground="#6666ff") elif "GO" in txt: b["fg"] = "black" elif "FL" in txt: b["fg"] = "#7f00ff" def refresh_fix(self): for fix in FIXTURES.fixtures: sdata = FIXTURES.fixtures[fix] for attr in sdata["ATTRIBUT"]: if "FINE" in attr: continue v2 = sdata["ATTRIBUT"][attr]["VALUE"] if fix in self.elem_attr: elem = self.elem_attr[fix][attr] #print( attr,v2) elem["text"] = "{} {:0.2f}".format(attr,v2) if sdata["ATTRIBUT"][attr]["ACTIVE"]: elem["bg"] = "yellow" elem.config(activebackground="yellow") else: elem["bg"] = "grey" elem.config(activebackground="grey") if sdata["ATTRIBUT"][attr]["FX"]: elem["fg"] = "blue" else: elem["fg"] = "black" def preset_rec(self,nr): print("------- STORE PRESET") data = FIXTURES.get_active() if modes.val("STONY_FX"): PRESETS.rec(nr,data,"STONY_FX") modes.val("STONY_FX",0) else: PRESETS.rec(nr,data) sdata=data PRESETS.val_presets[nr] = sdata master.refresh_exec() return 1 def preset_select(self,nr): print("SELECT PRESET") sdata = PRESETS.val_presets[nr] cmd = "" for fix in sdata: if fix == "CFG": continue for attr in sdata[fix]: v2 = sdata[fix][attr]["VALUE"] v2_fx = sdata[fix][attr]["FX"] #print( self.data.elem_attr) if fix in self.elem_attr: elem = self.elem_attr[fix][attr] FIXTURES.fixtures[fix]["ATTRIBUT"][attr]["ACTIVE"] = 1 elem["bg"] = "yellow" def preset_go(self,nr,val=None,xfade=None,event=None): if xfade is None and FADE._is(): xfade = FADE.val() print("GO PRESET FADE",nr,val) rdata = PRESETS.get_raw_map(nr) if not rdata: return 0 print("???????") cfg = PRESETS.get_cfg(nr) print("''''''''") #virtcmd = FIXTURES.get_virtual(rdata) if not cfg: cprint("NO CFG",cfg,nr) return 0 xFLASH = 0 value=None cprint("preset_go",nr,cfg) if modes.val("SELECT") or ( "BUTTON" in cfg and cfg["BUTTON"] == "SEL") and val: #FLASH self.preset_select(nr) elif modes.val("FLASH") or ( "BUTTON" in cfg and cfg["BUTTON"] == "FL"): #FLASH xFLASH = 1 xfade = 0 if type(val) is not None and val == 0 : value = "off" if event: if str(event.type) == "ButtonRelease" or event.type == '5' : # 4 fix vor ThinkPad / Debian 11 if xFLASH: value = "off" cprint("preset_go() FLUSH",value,color="red") fcmd = FIXTURES.update_raw(rdata,update=0) self._preset_go(rdata,cfg,fcmd,value,xfade=xfade,xFLASH=xFLASH) elif not val: cprint("preset_go() STOP",value,color="red") elif modes.val("GO") or ( "BUTTON" in cfg and cfg["BUTTON"] in ["go","GO"]): fcmd = FIXTURES.update_raw(rdata) self._preset_go(rdata,cfg,fcmd,value,xfade=xfade,xFLASH=xFLASH) if not (modes.val("FLASH") or ( "BUTTON" in cfg and cfg["BUTTON"] == "FL")): #FLASH self.refresh_exec() self.refresh_fix() else: self.refresh_exec() self.refresh_fix() def _preset_go(self,rdata,cfg,fcmd,value,xfade=None,event=None,xFLASH=0): if xfade is None and FADE._is(): xfade = FADE.val() cprint("PRESETS._preset_go()",len(rdata)) vvcmd,jvvcmd = update_raw_dmx( rdata ,value,[],xfade=xfade ) fxcmd,jfxcmd = update_raw_dmx( rdata ,value,[],xfade=xfade,fx=1) cmd = [] for vcmd,d in [[jvvcmd,"d"],[jfxcmd,"fx"]]: #cprint(vcmd) if xFLASH: d+="f" for i,v in enumerate(fcmd): if xFLASH: vcmd[i]["FLASH"] = 1 #print(i) #print(fcmd) DMX = fcmd[i]["DMX"] if "VALUE" in vcmd[i] and type(vcmd[i]["VALUE"]) is float: vcmd[i]["VALUE"] = round(vcmd[i]["VALUE"],3) if DMX and vcmd[i]: #xcmd = ",{}{}:{}".format(d,DMX,vcmd[i]) vcmd[i]["DMX"] = DMX #cmd.append( xcmd ) if "VIRTUAL" in fcmd[i]: for a in fcmd[i]["VIRTUAL"]: DMX = fcmd[i]["VIRTUAL"][a] if DMX and vcmd[i]: vcmd[i]["DMX"] = DMX #xcmd = ",{}{}:{}".format(d,DMX,vcmd[i]) #cmd.append( xcmd ) if vcmd[i]["VALUE"] is not None or ("FX" in vcmd[i] and vcmd[i]["FX"]): cprint("jvcmd",vcmd[i]) cmd.append(vcmd[i]) if cmd and not modes.val("BLIND"): pass jclient_send(cmd) return 0 #======================= END cmd=[] for vcmd,d in [[vvcmd,"d"],[fxcmd,"fx"]]: if xFLASH: d+="f" for i,v in enumerate(fcmd): DMX = fcmd[i]["DMX"] if DMX and vcmd[i]: xcmd = ",{}{}:{}".format(d,DMX,vcmd[i]) cmd.append( xcmd ) if "VIRTUAL" in fcmd[i]: for a in fcmd[i]["VIRTUAL"]: DMX = fcmd[i]["VIRTUAL"][a] if DMX and vcmd[i]: xcmd = ",{}{}:{}".format(d,DMX,vcmd[i]) cmd.append( xcmd ) cmd = "".join(cmd) #print("cmd",cmd) if cmd and not modes.val("BLIND"): client.send(cmd ) def draw_sub_dim(self,fix,data,c=0,r=0,frame=None): i=0 if frame is None: frame = tk.Frame(root,bg="black") frame.pack(fill=tk.X, side=tk.TOP) if fix not in self.elem_attr: self.elem_attr[fix] = {} for attr in data["ATTRIBUT"]: if attr not in self.all_attr: self.all_attr.append(attr) if attr not in self.elem_attr[fix]: self.elem_attr[fix][attr] = [] if attr.endswith("-FINE"): continue v= data["ATTRIBUT"][attr]["VALUE"] b = tk.Button(frame,bg="lightblue", text=""+str(fix)+" "+data["NAME"],width=4) b.bind("<Button>",Xevent(fix=fix,mode="D-SELECT",elem=b).cb) b.grid(row=r, column=c, sticky=tk.W+tk.E) c+=1 b = tk.Button(frame,bg="grey", text=str(attr)+' '+str(round(v,2)),width=6) self.elem_attr[fix][attr] = b b.bind("<Button>",Xevent(fix=fix,elem=b,attr=attr,mode="ENCODER",data=data).cb) b.grid(row=r, column=c, sticky=tk.W+tk.E) c+=1 if c >=12: c=0 r+=1 return c,r def draw_patch(self,yframe): xframe = tk.Frame(yframe,bg="black") xframe.pack() def yview(event): print("yevent",event) yyy=20.1 xframe.yview_moveto(yyy) i=0 c=0 r=0 for fix in FIXTURES.fixtures: i+=1 data = FIXTURES.fixtures[fix] b = tk.Button(xframe,bg="lightblue", text="FIX:"+str(fix)+" "+data["NAME"],width=20) #b.bind("<Button>",Xevent(fix=fix,elem=b).cb) b.grid(row=r, column=c, sticky=tk.W+tk.E) c+=1 #r+=1 if fix not in self.elem_attr: self.elem_attr[fix] = {} patch = ["DMX","UNIVERS"] for k in patch: v=data[k] b = tk.Button(xframe,bg="grey", text=str(k)+' '+str(v),width=8) #self.elem_attr[fix][attr] = b #b.bind("<Button>",Xevent(fix=fix,elem=b,attr=attr,data=data).cb) b.grid(row=r, column=c, sticky=tk.W+tk.E) c+=1 if c >=8: c=1 r+=1 for attr in data["ATTRIBUT"]: if attr not in self.all_attr: self.all_attr.append(attr) if attr not in self.elem_attr[fix]: self.elem_attr[fix][attr] = [] if attr.endswith("-FINE"): continue v= data["ATTRIBUT"][attr]["VALUE"] b = tk.Button(xframe,bg="grey", text=str(attr)+' '+str(round(v,2)),width=8) #self.elem_attr[fix][attr] = b #b.bind("<Button>",Xevent(fix=fix,elem=b,attr=attr,data=data).cb) b.grid(row=r, column=c, sticky=tk.W+tk.E) c+=1 if c >=8: c=1 r+=1 c=0 r+=1 def draw_fix(self,xframe,yframe=None): r=0 c=0 frame_dim=xframe if yframe: frame_dim=yframe frame_fix=xframe root = frame_dim dim_frame = tk.Frame(root,bg="black") dim_frame.pack(fill=tk.X, side=tk.TOP) root = frame_fix fix_frame = tk.Frame(root,bg="black") fix_frame.pack(fill=tk.X, side=tk.TOP) i=0 c=0 r=0 dim_end=0 for fix in FIXTURES.fixtures: i+=1 data = FIXTURES.fixtures[fix] #print("draw_fix", fix ,data ) if(len(data["ATTRIBUT"].keys()) <= 1): c,r=self.draw_sub_dim(fix,data,c=c,r=r,frame=dim_frame) else: if not dim_end: dim_end=1 c=0 r=0 #self._draw_fix(fix,data,root=fix_frame) frame = fix_frame b = tk.Button(frame,bg="lightblue", text="FIX:"+str(fix)+" "+data["NAME"],width=20) b.bind("<Button>",Xevent(fix=fix,mode="SELECT",elem=b).cb) b.grid(row=r, column=c, sticky=tk.W+tk.E) c+=1 #r+=1 if fix not in self.elem_attr: self.elem_attr[fix] = {} for attr in data["ATTRIBUT"]: if attr.endswith("-FINE"): continue if attr not in self.all_attr: self.all_attr.append(attr) if attr not in self.elem_attr[fix]: self.elem_attr[fix][attr] = ["line1348",fix,attr] v= data["ATTRIBUT"][attr]["VALUE"] b = tk.Button(frame,bg="grey", text=str(attr)+' '+str(round(v,2)),width=8) self.elem_attr[fix][attr] = b b.bind("<Button>",Xevent(fix=fix,elem=b,attr=attr,mode="ENCODER",data=data).cb) b.grid(row=r, column=c, sticky=tk.W+tk.E) c+=1 if c >=8: c=1 r+=1 c=0 r+=1 def draw_enc(self,xframe): root2 = xframe i=0 c=0 r=0 frame = tk.Frame(root2,bg="black") frame.pack( side=tk.TOP,expand=1,fill="both") b = tk.Button(frame,bg="lightblue", text="ENCODER",width=6) b.grid(row=r, column=c, sticky=tk.W+tk.E) c+=1 for attr in self.all_attr: if attr.endswith("-FINE"): continue v=0 b = tk.Button(frame,bg="orange", text=str(attr)+'',width=6) b.bind("<Button>",Xevent(fix=0,elem=b,attr=attr,data=self,mode="ENCODER").cb) b.grid(row=r, column=c, sticky=tk.W+tk.E) c+=1 if c >=8: c=0 r+=1 def draw_fx(self,xframe): frame_fx=xframe i=0 c=0 r=0 frame = tk.Frame(frame_fx,bg="black") frame.pack(fill=tk.X, side=tk.TOP) b = tk.Button(frame,bg="lightblue", text="FX.",width=6) #b.bind("<Button>",Xevent(fix=fix,elem=b).cb) b.grid(row=r, column=c, sticky=tk.W+tk.E) c+=1 for comm in self.fx_commands: if comm == "\n": c=0 r+=1 continue v=0 b = tk.Button(frame,bg="lightgrey", text=str(comm),width=6,height=2) if comm not in self.elem_fx_commands: self.elem_fx_commands[comm] = b self.val_fx_commands[comm] = 0 b.bind("<Button>",Xevent(fix=0,elem=b,attr=comm,data=self,mode="COMMAND").cb) if comm == "BLIND": b["bg"] = "grey" elif comm == "CLEAR": b["bg"] = "grey" elif comm == "STONY_FX": b["bg"] = "grey" elif comm == "FADE": b["bg"] = "green" elif comm == "FX OFF": b["bg"] = "magenta" elif comm[:3] == "FX:": b["text"] = comm #"BS:{}".format(fx_prm["BASE"]) b["bg"] = "#ffbf00" elif comm == "MO:on": b["text"] = comm #"BS:{}".format(fx_prm["BASE"]) b["bg"] = "lightgreen" elif comm == "MO:on": b["text"] = comm #"BS:{}".format(fx_prm["BASE"]) b["bg"] = "lightgreen" elif comm == "SZ:": b["text"] = "SZ:{:0.0f}".format(fx_prm["SIZE"]) b["bg"] = "lightgreen" elif comm == "SP:": b["text"] = "SP:{:0.0f}".format(fx_prm["SPEED"]) b["bg"] = "lightgreen" elif comm == "ST:": b["bg"] = "lightgreen" b["text"] = "ST:{:0.0f}".format(fx_prm["START"]) elif comm == "OF:": b["bg"] = "lightgreen" b["text"] = "OF:{:0.0f}".format(fx_prm["OFFSET"]) elif comm == "BS:-": b["bg"] = "lightgreen" b["text"] = "BS:{}".format(fx_prm["BASE"]) elif comm[0] == "M": b["text"] = comm #"BS:{}".format(fx_prm["BASE"]) b["bg"] = "lightgrey" if comm: b.grid(row=r, column=c, sticky=tk.W+tk.E) c+=1 if c >=5: c=0 r+=1 def draw_command(self,xframe): frame_cmd=xframe i=0 c=0 r=0 frame = tk.Frame(frame_cmd,bg="black") frame.pack(fill=tk.X, side=tk.TOP) b = tk.Button(frame,bg="lightblue", text="COMM.",width=6) #b.bind("<Button>",Xevent(fix=fix,elem=b).cb) b.grid(row=r, column=c, sticky=tk.W+tk.E) #r+=1 c+=1 for comm in self.commands: if comm == "\n": c=0 r+=1 continue v=0 b = tk.Button(frame,bg="lightgrey", text=str(comm),width=6,height=2) if comm not in self.elem_commands: self.elem_commands[comm] = b self.val_commands[comm] = 0 b.bind("<Button>",Xevent(fix=0,elem=b,attr=comm,data=self,mode="COMMAND").cb) if comm == "BLIND": b["bg"] = "grey" if comm == "CLEAR": b["bg"] = "grey" if comm == "STONY_FX": b["bg"] = "grey" if comm == "FADE": b["bg"] = "green" if comm == "FX OFF": b["bg"] = "magenta" if comm == "SZ:": b["text"] = "SZ:{:0.0f}".format(fx_prm["SIZE"]) if comm == "SP:": b["text"] = "SP:{:0.0f}".format(fx_prm["SPEED"]) if comm == "FADE": b["text"] = "FADE:{:0.02f}".format(FADE.val()) if comm == "ST:": b["text"] = "ST:{:0.0f}".format(fx_prm["START"]) if comm == "OF:": b["text"] = "OF:{:0.0f}".format(fx_prm["OFFSET"]) if comm == "BS:": b["text"] = "BS:{}".format(fx_prm["BASE"]) if comm: b.grid(row=r, column=c, sticky=tk.W+tk.E) c+=1 if c >=5: c=0 r+=1 def draw_preset(self,xframe): i=0 c=0 r=0 root = xframe frame = tk.Frame(root,bg="black") frame.pack(fill=tk.X, side=tk.TOP) i=0 for k in PRESETS.val_presets: if i%(8*8)==0 or i ==0: c=0 b = tk.Label(frame,bg="black", text="X" ) b.grid(row=r, column=c, sticky=tk.W+tk.E) r+=1 c=0 b = tk.Button(frame,bg="lightblue", text="EXEC " ) b.grid(row=r, column=c, sticky=tk.W+tk.E) c+=1 b = tk.Button(frame,bg="lightblue", text="PAGE " + str(int(i/(8*8))+1) ) b.grid(row=r, column=c, sticky=tk.W+tk.E) c+=1 b = tk.Button(frame,bg="lightblue", text="<NAME>" ) b.grid(row=r, column=c, sticky=tk.W+tk.E) r+=1 c=0 i+=1 v=0 label = "" #if k in PRESETS.label_presets: # label = PRESETS.label_presets[k] # #print([label]) sdata=PRESETS.val_presets[k] BTN="go" if "CFG" in sdata:#["BUTTON"] = "GO" if "BUTTON" in sdata["CFG"]: BTN = sdata["CFG"]["BUTTON"] txt=str(k+1)+":"+str(BTN)+":"+str(len(sdata)-1)+"\n"+label b = tk.Button(frame,bg="grey", text=txt,width=8,height=2) b.bind("<Button>",Xevent(fix=0,elem=b,attr=k,data=self,mode="PRESET").cb) b.bind("<ButtonRelease>",Xevent(fix=0,elem=b,attr=k,data=self,mode="PRESET").cb) if k not in self.elem_presets: self.elem_presets[k] = b b.grid(row=r, column=c, sticky=tk.W+tk.E) c+=1 if c >=8: c=0 r+=1 self.refresh_exec() def draw_input(self): i=0 c=0 r=0 frame = tk.Frame(root2,bg="black") frame.pack(fill=tk.X, side=tk.TOP) b = tk.Label(frame,bg="black", text="------------------------ ---------------------------------------") b.grid(row=r, column=c, sticky=tk.W+tk.E) r=0 frame = tk.Frame(root2,bg="black") frame.pack(fill=tk.X, side=tk.TOP) b = tk.Label(frame, text="send:") b.grid(row=r, column=c, sticky=tk.W+tk.E) c+=1 b = tk.Entry(frame,bg="grey", text="",width=50) self.entry = b b.bind("<Button>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT").cb) b.bind("<Key>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT").cb) b.grid(row=r, column=c, sticky=tk.W+tk.E) b.insert("end","d0:127,fx241:sinus:50:50:10,fx243:cosinus:50:50:10,d201:127,fx201:sinus:50:300:10") r+=1 b = tk.Entry(frame,bg="grey", text="",width=20) self.entry2 = b b.bind("<Button>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT2").cb) b.bind("<Key>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT2").cb) b.grid(row=r, column=c, sticky=tk.W+tk.E) b.insert("end","d1:0:4") r+=1 b = tk.Entry(frame,bg="grey", text="",width=20) self.entry3 = b b.bind("<Button>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT3").cb) #b.bind("<B1-Motion>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT3").cb) b.bind("<Key>",Xevent(fix=0,elem=b,attr="INPUT",data=self,mode="INPUT3").cb) b.grid(row=r, column=c, sticky=tk.W+tk.E) b.insert("end","fx:alloff:::") def draw_colorpicker(self,xframe): import lib.colorpicker as colp class _CB(): def __init__(self): self.old_color = (0,0,0) def cb(self,event,data): cprint("colorpicker CB") if "color" in data and self.old_color != data["color"] or event.num==2: self.old_color = data["color"] else: return 0 color = data["color"] print("e",event,data) print("e",dir(event))#.keys()) try: print("e.state",event.state) except:pass set_fade = FADE.val() #fade if "color" in data and (event.num == 1 or event.num == 3 or event.num==2 or event.state in [256,1024]): cr=None cg=None cb=None if event.num == 1: set_fade=FADE.val() #fade cr = color[0] cg = color[1] cb = color[2] elif event.num == 3: cr = color[0] cg = color[1] cb = color[2] set_fade=0 elif event.num == 2: cr= "click" cg= "click" cb= "click" elif event.state == 256: cr = color[0] cg = color[1] cb = color[2] set_fade=0 else: set_fade=0 if cr is not None: FIXTURES.encoder(fix=0,attr="RED",xval=cr,xfade=set_fade) if cg is not None: FIXTURES.encoder(fix=0,attr="GREEN",xval=cg,xfade=set_fade) if cb is not None: FIXTURES.encoder(fix=0,attr="BLUE",xval=cb,xfade=set_fade) master.refresh_fix() print("PICK COLOR:",data["color"]) _cb=_CB() colp.colorpicker(xframe,width=600,height=100, xcb=_cb.cb) return 0 canvas=tk.Canvas(xframe,width=600,height=100) canvas["bg"] = "yellow" #"green" canvas.pack() # RGB x=0 y=0 j=0 d = 20 for i in range(0,d+1): fi = int(i*255/d) f = 255-fi if i > d/2: pass#break color = '#%02x%02x%02x' % (f, fi, fi) print( "farbe", i*10, j, f,fi,fi,color) r = canvas.create_rectangle(x, y, x+20, y+20, fill=color) x+=20 def render(self): #Xroot.bind("<Key>",Xevent(fix=0,elem=None,attr="ROOT",data=self,mode="ROOT").cb) self.draw_input() def ScrollFrame(root,width=50,height=100,bd=1): #print("ScrollFrame init",width,height) aframe=tk.Frame(root,relief=tk.GROOVE)#,width=width,height=height,bd=bd) #aframe.place(x=0,y=0) aframe.pack(side="left",fill="both",expand=1) #x=0,y=0) canvas=tk.Canvas(aframe,width=width-24,height=height) canvas["bg"] = "black" #"green" bframe=tk.Frame(canvas)#,width=width,height=height) bframe["bg"] = "blue" scrollbar=tk.Scrollbar(aframe,orient="vertical",command=canvas.yview,width=20) canvas.configure(yscrollcommand=scrollbar.set) scrollbar.pack(side="right",fill="y") canvas.pack(side="left",expand=1,fill="both") canvas.create_window((0,0),window=bframe,anchor='nw') bframe.bind("<Configure>",scroll(canvas).config) canvas.bind("<Button>",Event("XXX").event) canvas.bind("<Key>",Event("XXX").event) canvas.bind("<KeyRelease>",Event("XXX").event) return bframe #frame = ScrollFrame(root) class GUIHandler(): def __init__(self): pass def update(self,fix,attr,args={}): print("GUIHandler.update()",fix,attr,args) for i,k in enumerate(args): v = args[k] #print("GUI-H", i,k,v) class Fixtures(Base): def __init__(self): super().__init__() #self.load() self.fixtures = OrderedDict() self.gui = GUIHandler() def load_patch(self): filename="patch" d,l = self._load(filename) self.fixtures = OrderedDict() for i in l: sdata = d[i] for attr in sdata["ATTRIBUT"]: sdata["ATTRIBUT"][attr]["ACTIVE"] = 0 #print("load",filename,sdata) #if "CFG" not in sdata: # sdata["CFG"] = OrderedDict() self.fixtures[str(i)] = sdata #PRESETS.label_presets = l def backup_patch(self): filename = "patch" data = self.fixtures labels = {} for k in data: labels[k] = k self._backup(filename,data,labels) def fx_off(self,fix=None): if not fix or fix == "all": #self.data.elem_fx_commands[self.attr]["bg"] = "magenta" for fix in self.fixtures: data = self.fixtures[fix] for attr in data["ATTRIBUT"]: data["ATTRIBUT"][attr]["FX"] = "" def get_attr(self,fix,attr): if fix in self.fixtures: data = self.fixtures[fix] if "ATTRIBUT" in data: if attr in data["ATTRIBUT"]: return data["ATTRIBUT"][attr] def get_dmx(self,fix,attr): cprint("get_dmx",[fix,attr]) if fix in self.fixtures: data = self.fixtures[fix] if "DMX" in data: DMX = int(data["DMX"]) else: return -1 if "UNIVERS" in data: DMX += (int(data["UNIVERS"])*512) adata = self.get_attr(fix,attr) #-hier ende 8.2.22 cprint("adata",adata,DMX) if adata: if "NR" in adata: NR = adata["NR"] if NR: DMX+=NR-1 else: return -2 return DMX return -4 return -3 def update_raw(self,rdata,update=1): cprint("update_raw",len(rdata)) cmd = [] for i,d in enumerate(rdata): xcmd = {"DMX":""} #print("fix:",i,d) fix = d["FIX"] attr = d["ATTR"] v2 = d["VALUE"] v2_fx = d["FX"] if fix not in self.fixtures: continue sdata = self.fixtures[fix] #shortcat ATTR = sdata["ATTRIBUT"] sDMX = 0 if sdata["DMX"] > 0: #print( sdata) sDMX = (sdata["UNIVERS"]*512)+sdata["DMX"] #sDMX =sdata["DMX"] #else: # continue if attr not in ATTR: continue #DMX = FIXTURES.get_dmx(fix) if ATTR[attr]["NR"] >= 0: DMX = sDMX+ATTR[attr]["NR"]-1 xcmd["DMX"] = str(DMX) else: if attr == "DIM" and ATTR[attr]["NR"] < 0: xcmd["VIRTUAL"] = {} for a in ATTR: if ATTR[a]["MASTER"]: xcmd["VIRTUAL"][a] = sDMX+ATTR[a]["NR"]-1 #print( "VIRTUAL",xcmd) cmd.append(xcmd) v=ATTR[attr]["VALUE"] if v2 is not None and update: ATTR[attr]["VALUE"] = v2 #self.data.elem_attr[fix][attr]["text"] = str(attr)+' '+str(round(v,2)) text = str(attr)+' '+str(round(v,2)) #self.gui.update(fix,attr,args={"text":text}) #print("END 5454 _=_=_=_=_==_") cprint("update_raw",cmd,color="red") return cmd def encoder(self,fix,attr,xval="",xfade=0): cprint("FIXTURES.encoder",fix,attr,xval,xfade,color="yellow") if attr == "CLEAR": self.clear() return 0 if fix not in self.fixtures: jdata=[{"MODE":"---"}] ii =0 jclient_send(jdata) for fix in self.fixtures: ii+=1 #cprint(fix,attr,xval) data = self.fixtures[fix] if attr in data["ATTRIBUT"]: if xval == "click": self.select(fix,attr,mode="on") elif data["ATTRIBUT"][attr]["ACTIVE"]: if fix: # prevent endless recursion self.encoder(fix,attr,xval,xfade) jdata=[{"MODE":ii}] jclient_send(jdata) return 0 data = self.fixtures[fix] if xval == "click": #cprint(data) return self.select(fix,attr,mode="toggle") v2=data["ATTRIBUT"][attr]["VALUE"] change=0 increment = 4.11 jdata = {"MODE":"ENC"} if xval == "+": v2+= increment jdata["INC"] = increment change=1 elif xval == "-": jdata["INC"] = increment*-1 v2-= increment change=1 elif type(xval) is int or type(xval) is float: v2 = xval change=1 if v2 < 0: v2=0 elif v2 > 256: v2=256 jdata["VALUE"] = round(v2,4) jdata["FIX"] = fix jdata["ATTR"] = attr jdata["DMX"] = FIXTURES.get_dmx(fix,attr) out = {} if change: data["ATTRIBUT"][attr]["ACTIVE"] = 1 data["ATTRIBUT"][attr]["VALUE"] = round(v2,4) jdata["FADE"] = 0 if xfade: jdata["FADE"] = xfade if not modes.val("BLIND"): jdata = [jdata] print(jdata) jclient_send(jdata) return v2 def get_active(self): cprint("get_active",self,"get_active") CFG = OrderedDict() sdata = OrderedDict() sdata["CFG"] = CFG # OrderedDict() sdata["CFG"]["FADE"] = FADE.val() sdata["CFG"]["DEALY"] = 0 #sdata["CFG"]["BUTTON"] = "GO" for fix in self.fixtures: data = self.fixtures[fix] for attr in data["ATTRIBUT"]: if data["ATTRIBUT"][attr]["ACTIVE"]: if fix not in sdata: sdata[fix] = {} if attr not in sdata[fix]: sdata[fix][attr] = OrderedDict() if not modes.val("STONY_FX"): sdata[fix][attr]["VALUE"] = data["ATTRIBUT"][attr]["VALUE"] #sdata[fix][attr]["FADE"] = FADE.val() #fade else: sdata[fix][attr]["VALUE"] = None #data["ATTRIBUT"][attr]["VALUE"] if "FX" not in data["ATTRIBUT"][attr]: data["ATTRIBUT"][attr]["FX"] ="" sdata[fix][attr]["FX"] = data["ATTRIBUT"][attr]["FX"] return sdata def select(self,fix=None,attr=None,mode="on"): cprint("FIXTURES.select()",fix,attr,mode,color="yellow") out = 0 if fix in self.fixtures: data = self.fixtures[fix] if attr in data["ATTRIBUT"]: if mode == "on": if not data["ATTRIBUT"][attr]["ACTIVE"]: data["ATTRIBUT"][attr]["ACTIVE"] = 1 out = 1 elif mode == "off": if data["ATTRIBUT"][attr]["ACTIVE"]: data["ATTRIBUT"][attr]["ACTIVE"] = 0 out = 1 elif mode == "toggle": if data["ATTRIBUT"][attr]["ACTIVE"]: data["ATTRIBUT"][attr]["ACTIVE"] = 0 else: data["ATTRIBUT"][attr]["ACTIVE"] = 1 out = 1 return out def clear(self): out = 0 for fix in self.fixtures: data = self.fixtures[fix] for attr in data["ATTRIBUT"]: if attr.endswith("-FINE"): continue if data["ATTRIBUT"][attr]["ACTIVE"]: out +=1 data["ATTRIBUT"][attr]["ACTIVE"] = 0 return out class Presets(Base): def __init__(self): super().__init__() #self.load() self._last_copy = None self._last_move = None def load_presets(self): filename="presets" d,l = self._load(filename) for i in d: sdata = d[i] if "CFG" not in sdata: sdata["CFG"] = OrderedDict() if "FADE" not in sdata["CFG"]: sdata["CFG"]["FADE"] = 4 if "DELAY" not in sdata["CFG"]: sdata["CFG"]["DELAY"] = 0 if "BUTTON" not in sdata["CFG"]: sdata["CFG"]["BUTTON"] = "GO" self.val_presets = d self.label_presets = l def check_cfg(self,nr=None): cprint("PRESETS.check_cfg()",nr) ok = 0 if nr is not None: ok += self._check_cfg(nr) else: for nr in self.val_presets: ok += self._check_cfg(nr) return ok def _check_cfg(self,nr): #cprint("PRESETS._check_cfg()",nr) ok=0 if nr in self.val_presets: sdata = self.val_presets[nr] if "CFG" not in sdata: sdata["CFG"] = OrderedDict() ok += 1 if "FADE" not in sdata["CFG"]: sdata["CFG"]["FADE"] = 4 ok += 1 if "DELAY" not in sdata["CFG"]: sdata["CFG"]["DELAY"] = 0 ok += 1 if "BUTTON" not in sdata["CFG"]: sdata["CFG"]["BUTTON"] = "GO" ok += 1 if ok: cprint("REPAIR CFG's",nr,sdata["CFG"],color="red") else: cprint("nr not in data ",nr,color="red") return ok def backup_presets(self): filename = "presets" data = self.val_presets labels = self.label_presets self._backup(filename,data,labels) def get_cfg(self,nr): cprint("PRESETS.get_cfg()",nr) self.check_cfg(nr) if nr not in self.val_presets: cprint("get_cfg",self,"error get_cfg no nr:",nr,color="red") return {} if "CFG" in self.val_presets[nr]: return self.val_presets[nr]["CFG"] def get_raw_map(self,nr): print("get_raw_map",nr) if nr not in self.val_presets: self.val_presets[nr] = OrderedDict() self.val_presets[nr]["VALUE"] = 0 self.val_presets[nr]["FX"] = "" sdata = self.val_presets[nr] cmd = "" out = [] dmx=-1 for fix in sdata: if fix == "CFG": #print("CFG",nr,sdata[fix]) continue for attr in sdata[fix]: x = {} #print("RAW",attr) x["FIX"] = fix x["ATTR"] = attr x["VALUE"] = sdata[fix][attr]["VALUE"] x["FX"] = sdata[fix][attr]["FX"] #x["DMX"] = sdata[fix][attr]["NR"] out.append(x) return out def get_btn_txt(self,nr): sdata=self.val_presets[nr] BTN="go" if "CFG" in sdata: if "BUTTON" in sdata["CFG"]: BTN = sdata["CFG"]["BUTTON"] _label = self.label_presets[nr] # = label txt=str(nr+1)+":"+str(BTN)+":"+str(len(sdata)-1)+"\n"+_label print("get_btn_txt",nr,[txt]) return txt def btn_cfg(self,nr,txt=None): if nr not in self.val_presets: return "" if "CFG" not in self.val_presets[nr]: self.val_presets[nr]["CFG"] = OrderedDict() if "BUTTON" not in self.val_presets[nr]["CFG"]: self.val_presets[nr]["CFG"]["BUTTON"] = "" if type(txt) is str: self.val_presets[nr]["CFG"]["BUTTON"] = txt if self.val_presets[nr]["CFG"]["BUTTON"] is None: self.val_presets[nr]["CFG"]["BUTTON"] = "" print("EEE", self.val_presets[nr]["CFG"]["BUTTON"] ) return self.val_presets[nr]["CFG"]["BUTTON"] def label(self,nr,txt=None): if nr not in self.label_presets: return "" if type(txt) is str: self.label_presets[nr] = txt print("set label",nr,[txt]) print("??? ?? set label",nr,[txt]) return self.label_presets[nr] def clear_move(self): cprint("PRESETS.clear_move()",end=" ") self.clear_copy() def clear_copy(self): cprint("PRESETS.clear_copy()",end=" ") if self._last_copy is not None: cprint("=OK=",color="red") self._last_copy = None else: cprint("=NONE=",color="green") def copy(self,nr,overwrite=1): cprint("PRESETS._copy",nr,"last",self._last_copy) if nr: if self._last_copy is not None: ok = self._copy(self._last_copy,nr,overwrite=overwrite) return ok #ok else: self._last_copy = nr cprint("PRESETS.copy START ",color="red") return 0 return 1 # on error reset move def _copy(self,nr_from,nr_to,overwrite=1): cprint("PRESETS._copy",nr_from,"to",nr_to) self.check_cfg(nr_from) if self._last_copy is None: cprint("PRESETS._copy last nr is None") return 0 if nr_from in self.val_presets and nr_to in self.val_presets: fdata = self.val_presets[nr_from] tdata = self.val_presets[nr_to] #cprint(fdata) flabel = self.label_presets[nr_from] tlabel = self.label_presets[nr_to] self.val_presets[nr_to] = copy.deepcopy(fdata) self.label_presets[nr_to] = flabel if not overwrite: #default cprint("overwrite",overwrite) self.val_presets[nr_from] = copy.deepcopy(tdata) self.label_presets[nr_from] = tlabel #self.label_presets[nr_from] = "MOVE" self.clear_copy() cprint("PRESETS.copy OK",color="red") return 1 def move(self,nr): cprint("PRESETS.move",self._last_copy,"to",nr) if nr: last = self._last_copy ok= self.copy(nr,overwrite=0) if ok and last: cprint("PRESETS.move OK",color="red") #self.delete(last) return ok #ok return 0 # on error reset move def delete(self,nr): cprint("PRESETS.delete",nr) ok=0 if nr in self.val_presets: self.val_presets[nr] = OrderedDict() self.label_presets[nr] = "" ok = 1 self.check_cfg(nr) return ok def rec(self,nr,data,arg=""): print("rec",self,"rec()",data,arg) self.check_cfg(nr) self.val_presets[nr] = data return 1 class GUI_grid(): def __init__(self,root,data,title="tilte",width=800): self.data = data self.frame = tk.Frame(root,bg="black",width=width) self.frame.pack(fill=tk.BOTH, side=tk.LEFT) r=0 c=0 i=1 for row in data: self.b = tk.Button(self.frame,bg="lightblue", text=row["text"],width=11,height=4) #self.b.bind("<Button>",Xevent(fix=fix,elem=b).cb) self.b.grid(row=r, column=c, sticky=tk.W+tk.E)#,anchor="w") c+=1 if c % 8 == 0: r+=1 c=0 i+=1 self.frame.pack() class BEvent(): def __init__(self,data,cb): self._data = data self._cb = cb def cb(self,event): #print(self,event) self._cb(event,self._data) class GUI_menu(): def __init__(self,root,data,title="tilte",width=800): global tk self.data = data self.frame = tk.Frame(root,bg="black",width=width) self.frame.pack(fill=tk.BOTH, side=tk.LEFT) r=0 c=0 i=1 self.b = tk.Label(self.frame,bg="lightblue", text="MAIN:MENU",width=10,height=1) self.b.grid(row=r, column=c, sticky=tk.W+tk.E)#,anchor="w") r+=1 for row in data: #print(i) #row = data[i] self.b = tk.Button(self.frame,bg="lightblue", text=row["text"],width=10,height=3) self.b.bind("<Button>",BEvent({"NR":i,"text":row["text"]},self.callback).cb) self.b.grid(row=r, column=c, sticky=tk.W+tk.E)#,anchor="w") r+=1 i+=1 self.frame.pack() def callback(self,event,data={}): print("callback543",self,event,data) window_manager.top(data["text"])# = WindowManager() lf_nr = 0 class GUIWindow(): def __init__(self,title="tilte",master=0,width=100,height=100,left=None,top=None): global lf_nr if master: self.tk = tkinter.Tk() defaultFont = tkinter.font.nametofont("TkDefaultFont") print(defaultFont) defaultFont.configure(family="FreeSans", size=10, weight="bold") #self.tk.option_add("*Font", FontBold) else: self.tk = tkinter.Toplevel() #print(title,self.tk.__doc__) self.tk["bg"] = "black" self.tk.bind("<Button>",self.callback) self.tk.bind("<Key>",self.callback) self.tk.bind("<KeyRelease>",self.callback) self.tk.title(""+str(title)+" "+str(lf_nr)+":"+str(rnd_id)) lf_nr+=1 #self.tk.geometry("270x600+0+65") geo ="{}x{}".format(width,height) if left is not None: geo += "+{}".format(left) if top is not None: geo += "+{}".format(top) #self._event_clear = Xevent(fix=0,elem=None,attr="CLEAR",data=self,mode="ROOT").cb self.tk.geometry(geo) def title(self,title=None): if title is None: return self.tk.title() else: return self.tk.title(title) def show(self): pass def mainloop(self): try: self.tk.mainloop() finally: self.tk.quit() def callback(self,event,data={}):#value=255): print() print() cprint("<GUI>",event,color="yellow") cprint("<GUI>",event.state,data,[event.type],color="yellow") value = 255 if "Release" in str(event.type) or str(event.type) == '5' or str(event.type) == '3': value = 0 if "keysym" in dir(event): if "Escape" == event.keysym: FIXTURES.clear() modes.val("ESC",1) master.refresh_fix() elif event.keysym in "ebfclrms" and value: if "e" == event.keysym: modes.val("EDIT",1) elif "b" == event.keysym: modes.val("BLIND",1) elif "f" == event.keysym: modes.val("FLASH",1) elif "c" == event.keysym: modes.val("CFG-BTN",1) elif "l" == event.keysym: modes.val("LABEL",1) elif "r" == event.keysym: modes.val("REC",1) elif "m" == event.keysym: x=modes.val("MOVE",1) if not x: PRESETS.clear_move() elif "s" == event.keysym: modes.val("SELECT",1) elif event.keysym in ["1","2","3","4","5","6","7","8","9","0"]: nr = int( event.keysym) if nr == 0: nr =10 cprint("F-KEY",value,nr) xfade = 0 if FADE._is(): xfade = 0 master.preset_go(128-1+nr,xfade=xfade,val=value) elif event.keysym in ["F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12"]: nr = int( event.keysym[1])-1 cprint("F-KEY",value,nr) xfade = 0 if FADE._is(): xfade = 0 master.preset_go(65-1+nr,xfade=xfade,val=value) elif "End" == event.keysym: FIXTURES.fx_off("all") CONSOLE.fx_off("all") CONSOLE.flash_off("all") elif "Delete" == event.keysym: #PRESETS.delete(nr) if value: modes.val("DEL",1) class WindowManager(): def __init__(self): self.windows = {} self.nr= 0 self.first="" def new(self,w,name=""): if not self.first: if name: self.first = name else: self.first = str(self.nr) w.tk.attributes('-topmost',True) if name: self.windows[str(name)] = w else: self.windows[str(self.nr)] = w self.nr+=1 #w.show() def mainloop(self): self.windows[self.first].mainloop() def top(self,name): name = str(name) if name in self.windows: self.windows[name].tk.attributes('-topmost',True) self.windows[name].tk.attributes('-topmost',False) else: print(name,"not in self.windows",self.windows.keys()) class Console(): def __init__(self): pass def flash_off(self,fix): client.send("df0:alloff:::,") def fx_off(self,fix): cprint("Console.fx_off()",fix) if not fix or fix == "all": client.send("fx0:alloff:,fxf:alloff:,") client.send("df0:alloff:::,") return 0 window_manager = WindowManager() CONSOLE = Console() PRESETS = Presets() PRESETS.load_presets() FIXTURES = Fixtures() FIXTURES.load_patch() master = GUI() w = GUIWindow("MAIN",master=1,width=100,height=450,left=0,top=65) data = [] #data.append({"text":"COMMAND"}) data.append({"text":"EXEC"}) data.append({"text":"DIMMER"}) data.append({"text":"FIXTURES"}) f = GUI_menu(w.tk,data) window_manager.new(w) name="EXEC" w = GUIWindow(name,master=0,width=800,height=400,left=110,top=65) w1 = ScrollFrame(w.tk,width=800,height=400) #frame_exe = w.tk master.draw_preset(w1)#w.tk) window_manager.new(w,name) name="DIMMER" w = GUIWindow(name,master=0,width=800,height=400,left=110,top=65) w2 = ScrollFrame(w.tk,width=800,height=400) #frame_dim = w1 # w.tk #master.draw_dim(w1.tk) window_manager.new(w,name) name="FIXTURES" w = GUIWindow(name,master=0,width=800,height=400,left=110,top=65) w1 = ScrollFrame(w.tk,width=800,height=400) #frame_fix = w1 #w.tk master.draw_fix(w1,w2)#.tk) window_manager.new(w,name) name="ENCODER" ww = GUIWindow(name,master=0,width=800,height=50,left=110,top=500) Xroot = ww.tk w = None root = tk.Frame(Xroot,bg="black",width="10px") print("print pack",root) root.pack(fill=tk.BOTH,expand=0, side=tk.LEFT) root3 = tk.Frame(Xroot,bg="black",width="20px") root3.pack(fill=tk.BOTH,expand=0, side=tk.LEFT) root2 = tk.Frame(Xroot,bg="black",width="1px") master.draw_enc(root2) root2.pack(fill=tk.BOTH,expand=0, side=tk.LEFT) name = "COMMAND" w = GUIWindow(name,master=0,width=350,height=200,left=920,top=65) master.draw_command(w.tk) window_manager.new(w,name) name="PATCH" w = GUIWindow(name,master=0,width=800,height=400,left=110,top=65) w1 = ScrollFrame(w.tk,width=800,height=400) master.draw_patch(w1) window_manager.new(w,name) name="FX" w = GUIWindow(name,master=0,width=350,height=250,left=920,top=305) #frame_fx = w.tk master.draw_fx(w.tk) window_manager.new(w,name) #LibreLightDesk name="COLORPICKER" w = GUIWindow(name,master=0,width=580,height=100,left=80,top=620) master.draw_colorpicker(w.tk) window_manager.new(w,name) #Xroot = tk.Tk() #Xroot["bg"] = "black" #white #Xroot.title( xtitle+" "+str(rnd_id) ) #Xroot.geometry("1024x800+130+65") master.render() #w = frame_fix #GUIWindow("OLD",master=0,width=800,height=500,left=130,top=65) window_manager.new(w,name) try: #root.mainloop() #tk.mainloop() window_manager.mainloop() finally: master.exit()