#! /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 . (c) 2012 micha@uxsrv.de """ import random rnd_id = str(random.randint(1000,9000)) rnd_id += " Beta 22.05 " import subprocess try: rnd_id += subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD']).decode('ascii').strip() except: rnd_id += " no git" 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 space_font = None 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): #like jquery 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 self.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","REC-FX"] self.__check(mode) 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) return 1 if value: for m in self.modes: if m not in protected and mode not in protected and m != mode: cprint("-#-# clear mode",mode,m,value,color="red") if self.modes[m]: self.modes[m]= 0 self.callback(m) if self.modes[mode] and value == 1: if modes == "MOVE": PRESETS.clear_move() if modes == "COPY": PRESETS.clear_copy() self.modes[mode] = 0 # value else: self.modes[mode] = value #1 #value 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["REC-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 == "REC-FX": print("xcb",modes.val("REC-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) import zlib def jclient_send(data): t_start = time.time() jtxt = data jdatas = [] for jdata in data: if "DMX" in jdata: try: if int(jdata["DMX"]) >= 1: # ignore DMX lower one jdatas.append(jdata) else: cprint("jclient_send, ignore DMX ",jdata["DMX"],color="red") except Exception as e: cprint("jclient_send, Exception DMX ",color="red") cprint("",jdata,color="red") cprint("-----",color="red") jtxt = jdatas jtxt = json.dumps(jtxt) jtxt = jtxt.encode() #jtxt = zlib.compress(jtxt) jclient.send(b"\00 "+ jtxt +b"\00 ") print(round((time.time()-t_start)*1000,4),"milis") cprint(round(time.time(),4),color="yellow") class ValueBuffer(): def __init__(self,_min=0,_max=255): self._value = 2 self._on = 1 self._min=_min self._max=_max def check(self): if self._value < self._min: self._value = self._min elif self._value > self._max: self._value = self._max def inc(self,value=None): if value is not None: if type(value) is float: self._value += round(value,4) else: self._value += value self.check() 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 self.check() 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 = ValueBuffer() #2 #0.1 #1.13 FADE_move = ValueBuffer() #2 #0.1 #1.13 FADE_move.val(4) fx_prm_move = {"SIZE":40,"SPEED":8,"OFFSET":100,"BASE":"0","START":0,"MODE":0,"MO":0,"DIR":1,"INVERT":0,"WING":2,"WIDTH":100} fx_prm = {"SIZE":255,"SPEED":10,"OFFSET":100,"BASE":"-","START":0,"MODE":0,"MO":0,"DIR":1,"INVERT":1,"SHUFFLE":0,"WING":2,"WIDTH":25} fx_modes = ["RED","GREEN","BLUE","MAG","YELLOW","CYAN"] fx_mo = ["fade","on","rnd","ramp","ramp2","cosinus","sinus"] class FX_handler(): def __init__(): pass def reshape_preset(data ,value=None,xfade=0,flash=0,ptfade=0): f=0 #fade out = [] for row in data: cprint("reshape_preset",row) line = {} if type(value) is float: line["VALUE"] = value #round(value,3) else: line["VALUE"] = value if value is not None: line["FX"] = row["FX"].split(":",1)[-1] else: line["FX"] = row["FX"] if row["FX2"]: line["FX2"] = row["FX2"] if row["VALUE"] is not None: if value is None: v=row["VALUE"] if type(v) is float: line["VALUE"] = v #round(v,3) else: line["VALUE"] = v if row["ATTR"] in ["PAN","TILT"]: f = ptfade for a in ["DIM","ZOOM","FOCUS","RED","GREEN","BLUE","WHITE","AMBER","IRIS","BLADE"]: #FADE ATTRIBUTES if a in row["ATTR"]: f = xfade break if flash: xfade = 0 if type( f ) is float: line["FADE"] = round(f,4) else: line["FADE"] = f if 0: cprint("reshape_preset j",line,color="red") cprint("reshape_preset",line) out.append(line) return out 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_fx(): """ global input event Handeler for short cut's ... etc """ 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 = [] fx2 = {} 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:\n"+fx_modes[fx_prm["MODE"]] master.fx.elem["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:\n"+fx_modes[fx_prm["MODE"]] master.fx.elem["FX:RED"]["text"] = txt elif event.num == 1: offset = 0 offset_move = 0 start = fx_prm["START"] base = fx_prm["BASE"] xfixtures = [] fix_active =FIXTURES.get_active() for fix in fix_active: if fix == "CFG": continue xfixtures.append(fix) x=0 if not xfixtures: cprint("470 fx() ... init no fixture selected",color="red") return 0 wings = [] l = len(xfixtures) if fx_prm["WING"] and l > 1: 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) for wing in wings: if fx_prm["SHUFFLE"]: wing = wing[:] random.shuffle(wing) wlen = len(wing) coffset= 0 # 1024/wlen * (offset/255) coffset_move=0 for fix in wing: data = FIXTURES.fixtures[fix] for attr in data["ATTRIBUT"]: jdata = {"MODE":"FX"} jdata["VALUE"] = None jdata["FIX"] = fix jdata["DMX"] = FIXTURES.get_dmx(fix,attr) jdata["ATTR"] =attr if attr.endswith("-FINE"): continue if attr in ["PAN","TILT"]: csize = fx_prm_move["SIZE"] cspeed = fx_prm_move["SPEED"] cstart = fx_prm_move["START"] cbase = fx_prm_move["BASE"] width = fx_prm_move["WIDTH"] invert = fx_prm_move["INVERT"] coffset_move= round(offset_move,1) else: csize = fx_prm["SIZE"] cspeed = fx_prm["SPEED"] cstart = fx_prm["START"] cbase = fx_prm["BASE"] width = fx_prm["WIDTH"] invert = fx_prm["INVERT"] coffset= round(offset,1) fx="" if "SIN" in self.attr: fx = "sinus" elif "FD" in self.attr: fx = "fade" elif "RND" in self.attr: fx = "rnd" elif "ON" in self.attr: fx = "on" elif "RAMP2" in self.attr: fx = "bump2" fx = "ramp2" elif "RAMP" in self.attr: fx = "ramp" elif "COS" in self.attr: fx = "cosinus" if fx: if attr in ["PAN","TILT"]: cprint("SKIP FX attr:{} fix:{} " .format(attr,fix) ) continue if fx: if fx_prm["SPEED"] < 0: fx = "off" else: if ":DIM" in self.attr: base="" ffxb=fx_mo[fx_prm["MO"]] #ffxb= "cosinus" if attr == "DIM": if fx_prm["SPEED"] < 0: 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: fx = "off" else: fx = "sinus" elif ":PAN" in self.attr: base="" if attr == "PAN": if fx_prm_move["SPEED"] < 0: fx = "off" else: fx = "cosinus" if attr == "TILT": fx = "off" elif ":CIR" in self.attr: base="" if attr == "PAN": if fx_prm_move["SPEED"] < 0: fx = "off" else: fx = "cosinus" if attr == "TILT": if fx_prm["SPEED"] < 0: 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": 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" 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" fx=ffx elif "YELLOW" in fx_modes[fx_prm["MODE"]]:#fx_prm["MODE"]:#self.attr: base="-" if attr == "RED": fx = ffxb# "off" fx=ffx if attr == "GREEN": fx = ffxb# "off" 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" fx=ffx if attr == "BLUE": fx = ffxb# "off" fx=ffx elif "MAG" in fx_modes[fx_prm["MODE"]]:#fx_prm["MODE"]:#self.attr: base="-" if attr == "RED": fx = ffxb# "off" fx=ffx if attr == "GREEN": fx = ffxb# "off" if attr == "BLUE": fx = ffxb# "off" fx=ffx else: cprint("FX: unbekant",fx_modes[fx_prm["MODE"]],color="red") fxtype = fx fxtype = fx if "FX" not in data["ATTRIBUT"][attr]: data["ATTRIBUT"][attr]["FX"] ="" if "FX2" not in data["ATTRIBUT"][attr]: data["ATTRIBUT"][attr]["FX2"] ={} if data["ATTRIBUT"][attr]["ACTIVE"] and fxtype: #print("++ADD FX",fix,attr,fx) #data["ATTRIBUT"][attr]["FX"] = fx #"sinus:40:100:10" fjdata = {} if cspeed < 0.1: fjdata["TYPE"] = "off" else: fjdata["TYPE"] = fxtype fjdata["SIZE"] = round(csize,2) fjdata["SPEED"] = round(cspeed,2) fjdata["WIDTH"] = int(width) fjdata["START"] = cstart if attr in ["PAN","TILT"]: fjdata["OFFSET"]= round(coffset_move,2) else: fjdata["OFFSET"]= round(coffset,2) fjdata["INVERT"]= int(invert) fjdata["BASE"] = cbase jdata["FX2"] = fjdata data["ATTRIBUT"][attr]["FX2"] = fjdata jdatas.append(jdata) if fx_prm_move["OFFSET"] > 0.5: # and aoffset_move = (100/wlen) * (fx_prm_move["OFFSET"]/100) if fx_prm_move["DIR"] <= 0: offset_move -= aoffset_move else: offset_move += aoffset_move offset_move = round(offset_move,2) if fx_prm["OFFSET"] > 0.5: # and aoffset = (100/wlen) * (fx_prm["OFFSET"]/100) if fx_prm["DIR"] <= 0: offset -= aoffset else: offset += aoffset offset = round(offset,2) if jdatas and not modes.val("BLIND"): jclient_send(jdatas) master.refresh_fix() def command(self,event,mode=""): cprint("fx_command",self.mode) if self.mode == "FX": prm = fx_prm ct = self.data.fx if self.mode == "FX-MOVE": prm = fx_prm_move ct = self.data.fx_moves if 1: if self.attr.startswith("SIZE:"):#SIN": #global fx_prm k = "SIZE" if event.num == 1: prm[k] =30 elif event.num == 3: prm[k] =100 elif event.num == 4: if prm[k] <= 0: prm[k] = 1 prm[k] +=5 elif event.num == 5: prm[k] -=5 #prm[k] =int(prm[k]) if prm[k] > 4000: prm[k] = 4000 if prm[k] < 0: prm[k] =0 if prm[k] == 6: #bug prm[k] =5 ct.elem[self.attr]["text"] = "SIZE:\n{:0.0f}".format(prm[k]) cprint(prm) elif self.attr.startswith("SPEED:"):#SIN": #global prm k = "SPEED" if event.num == 1: prm[k] = 6 elif event.num == 3: prm[k] = 60 elif event.num == 4: if prm[k] <= 0: prm[k] = 0.06 elif prm[k] < 5: prm[k] *=1.2 else: prm[k] +=5 #1.1 elif event.num == 5: if prm[k] <= 5: prm[k] *=0.8 else: prm[k] -= 5 #1.1 #prm[k] =int(prm[k]) if prm[k] > 4000: prm[k] = 4000 if prm[k] < 0.05: prm[k] =0 if prm[k] > 5 and prm[k] < 10: #bug prm[k] =5 if prm[k] < 0: ct.elem[self.attr]["text"] = "SPEED:\noff".format(prm[k]) else: ct.elem[self.attr]["text"] = "SPEED:\n{:0.02f}".format(prm[k]) cprint(prm) elif self.attr.startswith("START:"):#SIN": #global prm k = "START" if event.num == 1: pass elif event.num == 2: pass elif event.num == 4: if prm[k] <= 0: prm[k] = 1 prm[k] += 5 #1.1 elif event.num == 5: prm[k] -= 5 #1.1 #prm[k] =int(prm[k]) if prm[k] > 4000: prm[k] = 4000 if prm[k] < 5: prm[k] =0 if prm[k] == 6: #bug prm[k] =5 ct.elem[self.attr]["text"] = "START:\n{:0.0f}".format(prm[k]) cprint(prm) elif self.attr.startswith("WIDTH:"):#SIN": #global prm k = "WIDTH" if event.num == 1: prm[k] = 25 elif event.num == 2: prm[k] = 50 elif event.num == 3: prm[k] = 100 elif event.num == 4: if prm[k] <= 0: prm[k] = 1 elif prm[k] == 50: prm[k] = 100 elif prm[k] == 5: prm[k] = 25 elif prm[k] == 25: prm[k] = 50 else: prm[k] += 5 #*=1.1 elif event.num == 5: if prm[k] == 10: prm[k] = 5 elif prm[k] == 25: prm[k] = 10 elif prm[k] == 50: prm[k] = 25 elif prm[k] == 100: prm[k] = 50 #else: # prm[k] -=5 #/=1.1 #prm[k] =int(prm[k]) if prm[k] < 0: prm[k] = 0 if prm[k] > 100: prm[k] = 100 if prm[k] == 6: #bug prm[k] =5 if prm[k] > 25 and prm[k] < 50: #bug prm[k] =50 if prm[k] > 50 and prm[k] < 100: #bug prm[k] =100 ct.elem[self.attr]["text"] = "WIDTH:\n{:0.0f}".format(prm[k]) cprint(prm) elif self.attr.startswith("DIR:"):#SIN": #global prm k = "DIR" if event.num == 1: prm[k] = 1 elif event.num == 3: prm[k] = -1 elif event.num == 4: prm[k] = 1 elif event.num == 5: prm[k] =-1 txt = prm[k] ct.elem[self.attr]["text"] = "DIR:\n{}".format(prm[k]) cprint(prm) elif self.attr.startswith("SHUFFLE:"):#SIN": #global prm k = "SHUFFLE" if event.num == 1: prm[k] = 0 elif event.num == 3: prm[k] = 1 elif event.num == 4: prm[k] = 1 elif event.num == 5: prm[k] =0 if prm[k] == 6: #bug ? prm[k] =5 ct.elem[self.attr]["text"] = k+":\n{}".format(prm[k]) cprint(prm) elif self.attr.startswith("INVERT:"):#SIN": #global prm k = "INVERT" if event.num == 1: prm[k] = 0 elif event.num == 3: prm[k] = 1 elif event.num == 4: prm[k] = 1 elif event.num == 5: prm[k] =0 if prm[k] == 6: #bug ? prm[k] =5 ct.elem[self.attr]["text"] = k+":\n{}".format(prm[k]) cprint(prm) elif self.attr.startswith("WING:"):#SIN": #global prm k = "WING" if event.num == 1: prm[k] = 1 elif event.num == 3: prm[k] = 2 elif event.num == 4: prm[k] += 1 elif event.num == 5: prm[k] -=1 if prm[k] > 100: prm[k] = 100 if prm[k] < 1: prm[k] =1 txt = prm[k] ct.elem[self.attr]["text"] = "WING:\n{}".format(prm[k]) cprint(prm) elif self.attr.startswith("OFFSET:"):#SIN": #global prm k = "OFFSET" if event.num == 1: prm[k] = 50 elif event.num == 2: prm[k] *= 2 elif event.num == 3: prm[k] = 100 elif event.num == 4: if prm[k] <= 0: prm[k] = 1 prm[k] +=5 #*=1.1 elif event.num == 5: prm[k] -=5 #/=1.1 #prm[k] =int(prm[k]) #if prm[k] > 512: # prm[k] = 512 if prm[k] < 5: prm[k] =0 if prm[k] == 6: #bug prm[k] =5 ct.elem[self.attr]["text"] = "OFFSET:\n{:0.0f}".format(prm[k]) cprint(prm) elif self.attr.startswith("BASE:"): k = "BASE" if event.num == 1: prm[k] = "-" elif event.num == 3: prm[k] = "0" elif event.num == 4: prm[k] = "+" elif event.num == 5: prm[k] = "0" ct.elem[self.attr]["text"] = "BASE:\n{}".format(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 #if event.num == 1: elif self.attr == "REC-FX": print("ELSE",self.attr) modes.val(self.attr,1) return 0 def cb(self,event): cprint("EVENT_fx cb",self.attr,self.mode,event,color='yellow') print(["type",event.type,"num",event.num]) try: change = 0 if self.mode.startswith("FX"): self.command(event) return 0 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") return 1 class Xevent(): """ global input event Handeler for short cut's ... etc """ 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 setup(self,event): cprint("xevent.SETUP",[self.mode,self.attr],color="red") if self.mode == "SETUP": if self.attr == "BACKUP\nSHOW": self.elem["bg"] = "orange" self.elem["text"] = "SAVING..." self.elem["bg"] = "red" tkinter.Tk.update_idletasks(gui_menu_gui.tk) #self.elem["fg"] = "orange" self.elem.config(activebackground="orange") modes.val(self.attr,1) PRESETS.backup_presets() FIXTURES.backup_patch() #time.sleep(1) #modes.val(self.attr,0) self.elem["bg"] = "lightgrey" #self.elem["fg"] = "lightgrey" self.elem.config(activebackground="lightgrey") elif self.attr == "LOAD\nSHOW": name = "LOAD-SHOW" base = Base() line1 = "PATH: "+base.show_path1 +base.show_name line2 = "DATE: "+ time.strftime("%Y-%m-%d %X", time.localtime(time.time())) cb = LOAD_SHOW_AND_RESTAT #(j).cb pw = PopupList(name,cb=cb) frame = pw.sframe(line1=line1,line2=line2) r = _load_show_list(frame,cb=cb) self.elem["bg"] = "red" self.elem.config(activebackground="red") #w.tk.attributes('-topmost',False) else: r=tkinter.messagebox.showwarning(message="{}\nnot implemented".format(self.attr.replace("\n"," ")),parent=None) return 1 def live(self,event): if self.mode == "LIVE": if "FADE" in self.attr: if self.attr == "FADE": ct = FADE if "PAN/TILT" in self.attr: ct = FADE_move fade = ct.val() print("EVENT CHANGE FADE",[self.attr]) print("EVENT CHANGE FADE",fade,self.attr) if fade < 0.01: ct.val(0.01) elif fade > 100.0: pass #fade = 100 if event.num == 4: fade *= 1.1 elif event.num == 5: fade /= 1.1 elif event.num == 1: if ct._is(): ct.off()# = 0 self.data.commands.elem[self.attr]["bg"] = "grey" self.elem.config(activebackground="grey") else: ct.on()# = 1 self.data.commands.elem[self.attr]["bg"] = "green" self.elem.config(activebackground="lightgreen") 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 = ct.val(fade) if self.attr == "FADE": self.data.commands.elem[self.attr]["text"] = "FADE:{:0.2f}".format(fade) if "PAN/TILT" in self.attr: self.data.commands.elem[self.attr]["text"] = "PAN\TILT\nFADE:{:0.2f}".format(fade) 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 == "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 encoder(self,event): global _shift_key if self.mode == "ENCODER": cprint("Xevent","ENC",self.fix,self.attr,self.mode) cprint("SHIFT_KEY",_shift_key,"??????????") #cprint(self.data) val="" if event.num == 1: val ="click" elif event.num == 4: val ="++" if _shift_key: val = "+" elif event.num == 5: val ="--" if _shift_key: val = "-" print("SHIFT",val,_shift_key) if val: if self.attr == "DIM" and self.fix == 0 and val == "click": pass else: FIXTURES.encoder(fix=self.fix,attr=self.attr,xval=val) master.refresh_fix() 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 == "SETUP": self.setup(event) elif self.mode == "COMMAND": self.command(event) elif self.mode == "LIVE": self.live(event) elif self.mode == "ENCODER": self.encoder(event) elif self.mode == "FX": cprint("Xevent CALLING FX WRONG EVENT OBJECT !!",color="red") 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) # keep MOVE on 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,button="go") 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,ptfade=0,event=event,val=255) return 0 elif self.mode == "INPUT": return 0 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") return 1 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): self._init() def _init(self): show_name = "GloryCamp2021" #show_name = "JMS" show_name = "DemoShow" #show_name = "Dimmer" self.home = os.environ['HOME'] self.show_path0 = self.home +"/LibreLight/" self.show_path = self.show_path0 self.show_path1 = self.show_path0 + "/show/" try: f = open(self.show_path+"init.txt","r") for line in f.readlines(): #cprint(line) if not line.startswith("#"): show_name = line.strip() show_name = show_name.replace(".","") show_name = show_name.replace("\\","") show_name = show_name.replace("/","") self.show_name = show_name except Exception as e: cprint("show name exception",color="red") self._check() def _set(self,fname): ok= os.path.isdir(self.show_path1+"/"+fname) ini = self.show_path0+"init.txt" print("SET SHOW NAME",fname,ok,ini) if ok: #self.show_name = fname f = open( ini ,"a") f.write(fname+"\n") f.close() return 1 def _check(self): 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 += "/" +self.show_name +"/" if not os.path.isdir(self.show_path): os.mkdir(self.show_path) pass def _list(self): #self._check() show_list = list(os.listdir( self.show_path1 )) out = [] for fname in show_list: #print(fname) ctime = os.path.getmtime(self.show_path1+fname) ctime = time.strftime("%Y-%m-%d %X", time.localtime(ctime)) #1650748726.6604707)) try: mtime = os.path.getmtime(self.show_path1+fname+"/patch.sav") mtime = time.strftime("%Y-%m-%d %X", time.localtime(mtime)) #1650748726.6604707)) except: mtime = 0 if mtime: out.append([fname,mtime])#,ctime]) from operator import itemgetter out=sorted(out, key=itemgetter(1)) out.reverse() return out def _load(self,filename): #self._init() #self._check() 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): #self._init() #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 MiniButton: def __init__(self,root,width=72,height=38,text="button"): self.text=text self.rb = tk.Frame(root, highlightbackground = "lightgrey", highlightthickness = 1, bd=0) self.bb = tk.Canvas(self.rb, highlightbackground = "black", highlightthickness = 1, bd=1,relief=tk.RAISED) self.bb.configure(width=width, height=height) def _label(self,text="1\n2\n3\n"): z = 0 self.bb.delete("label") for t in text.split("\n"): self.l = self.bb.create_text(37,z*10+9,text=t,anchor="c",tag="label") z+=1 def configure(self,**args): if "text" in args: self.text = args["text"] self._label(self.text) if "bg" in args: #print(dir(self.bb)) self.bb.configure(bg=args["bg"]) def config(self,**args): self.configure(**args) def bind(self,etype="