Quellcode durchsuchen

add: colorpicker

micha vor 3 Jahren
Ursprung
Commit
784feba22f
4 geänderte Dateien mit 866 neuen und 697 gelöschten Zeilen
  1. 735 694
      _LibreLightDesk.py
  2. 128 0
      lib/colorpicker.py
  3. 2 2
      show/GloryCamp2021/patch.sav
  4. 1 1
      show/GloryCamp2021/presets.sav

+ 735 - 694
_LibreLightDesk.py

@@ -909,655 +909,281 @@ class scroll():
         canvas = self.canvas
         canvas.configure(scrollregion=canvas.bbox("all"))#,width=400,height=200)
 
-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)
-    return bframe
-#frame = ScrollFrame(root)
-
-class GUIHandler():
-    def __init__(self):
-        pass
-    def update(self,fix,attr,args={}):
-        #print("GUIHandler",fix,attr,args)
-        for i,k in enumerate(args):
-            v = args[k] 
-            #print("GUI-H", i,k,v)
-            
-class Fixtures(Base):
+class GUI(Base):
     def __init__(self):
         super().__init__() 
-        #self.load()
-        self.fixtures = OrderedDict()
-        self.gui = GUIHandler()
+        self.load()
 
+        self.all_attr =["DIM","PAN","TILT"]
+        self.elem_attr = {}
         
-    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
-        #self.PRESETS.label_presets = l
+        self.fx_commands =["STONY_FX","FX OFF","\n"
+                ,"FX:CIR","FX:PAN","FX:TILT","FX:DIM","\n"
+                ,"SZ:","SP:","ST:","OF:","BS:-","\n"
+                , "FX:SIN","FX:COS","FX:BUM","FX:BUM2","FX:FD","FX:ON","FX:ON2" ]
+        self.commands =["\n","BLIND","CLEAR","STORE","EDIT","MOVE","\n","CFG-BTN","LABEL"
+                ,"BACKUP","SET","","","SELECT","ACTIVATE","FLASH","FADE"
+                ]
+        self.elem_fx_commands = {}
+        self.val_fx_commands = {}
+        self.elem_commands = {}
+        self.val_commands = {}
 
-    def backup_patch(self):
-        filename = "patch"
-        data  = self.fixtures
-        labels = {}
-        for k in data:
-            labels[k] = k
-        self._backup(filename,data,labels)
+        self.elem_presets = {}
+        self.PRESETS = Presets()
+        self.PRESETS.load_presets()
+        self.FIXTURES = Fixtures()
+        self.FIXTURES.load_patch()
+        
+        for i in range(8*8):
+            if i not in self.PRESETS.val_presets:
+                name = "Preset:"+str(i+1)+":\nXYZ"
+                #self.presets[i] = [i]
+                self.PRESETS.val_presets[i] = OrderedDict() # FIX 
+                self.PRESETS.val_presets[i]["CFG"] =  OrderedDict() # CONFIG 
+                self.PRESETS.label_presets[i] = "-"
 
-    def update_raw(self,rdata):
-        #print("update_raw",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"]
+  
+    def load(self,fname=""):
+        pass
+    def exit(self):
+        print("__del__",self)
+        self.PRESETS.backup_presets()
+        print("********************************************************")
+        self.FIXTURES.backup_patch()
+        print("*********del",self,"***********************************************")
+    def refresh_gui(self):
+        for fix in self.FIXTURES.fixtures:                            
+            sdata = self.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"
+                    else:
+                        elem["bg"] = "grey"
 
-            if fix not in self.fixtures:
-                continue 
-            sdata = self.fixtures[fix] #shortcat
-            ATTR  = sdata["ATTRIBUT"] 
+    def preset_store(self,nr):
+        print("STORE PRESET")
+        self.val_commands["STORE"] = 0
+        global STORE
+        STORE = 0
+        self.elem_commands["STORE"]["bg"] = "lightgrey"
 
-            sDMX = 0
-            if  sdata["DMX"] > 0:
-                print( sdata)
-                sDMX = (sdata["UNIVERS"]*512)+sdata["DMX"]  
-                #sDMX =sdata["DMX"]  
+        CFG = OrderedDict()
+        if "CFG" in self.PRESETS.val_presets[nr]: #["CFG"] 
+            CFG = self.PRESETS.val_presets[nr]["CFG"] 
+        sdata = {}
+        sdata["CFG"] = CFG # OrderedDict()
+        sdata["CFG"]["FADE"] = fade
+        sdata["CFG"]["DEALY"] = 0
+        #sdata["CFG"]["BUTTON"] = "GO"
+        for fix in self.FIXTURES.fixtures:                            
+            data = self.FIXTURES.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
+                        else:
+                            sdata[fix][attr]["VALUE"] = None #data["ATTRIBUT"][attr]["VALUE"]
 
-            if attr not in ATTR:
-                continue
+                        if "FX" not in data["ATTRIBUT"][attr]: 
+                             data["ATTRIBUT"][attr]["FX"] =""
+                        
+                        sdata[fix][attr]["FX"] = data["ATTRIBUT"][attr]["FX"] 
+    
+        print("sdata",len(sdata))
         
-            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)
-
+        self.PRESETS.val_presets[nr] = sdata
+        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
 
-            cmd.append(xcmd)
+            self.elem_presets[nr]["fg"] = "black"
+            if val_color:
+                self.elem_presets[nr]["bg"] = "yellow"
+                if fx_color:
+                    self.elem_presets[nr]["fg"] = "blue"
+            else:   
+                if fx_color:
+                    self.elem_presets[nr]["bg"] = "cyan"
+        else:
+            self.elem_presets[nr]["fg"] = "black"
+            self.elem_presets[nr]["bg"] = "grey"
+        #self.elem_presets[nr].option_add("*Font", FontBold)
+        label = ""
+        if nr in self.PRESETS.label_presets:
+            #print(dir(self.data))
+            label = self.PRESETS.label_presets[nr]
 
-            v=ATTR[attr]["VALUE"]
-            if v2 is not None:
-                ATTR[attr]["VALUE"] = v2
+        BTN="go"
+        if "CFG" in sdata:#["BUTTON"] = "GO"
+            if "BUTTON" in sdata["CFG"]:
+                BTN = sdata["CFG"]["BUTTON"]
+        txt = str(nr)+":"+str(BTN)+":"+str(len(sdata)-1)+"\n"+label 
+        self.elem_presets[nr]["text"] = txt 
+        #print("GO CFG ",self.PRESETS.val_presets)
+           
 
-            #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})
-        return cmd
+    def preset_select(self,nr):
+        print("SELECT PRESET")
+        sdata = self.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]
+                    #self#encoder(attr=attr,data=data,elem=elem,action="click")
+                    self.FIXTURES.fixtures[fix]["ATTRIBUT"][attr]["ACTIVE"] = 1
+                    elem["bg"] = "yellow"
+    def preset_go(self,nr,xfade=fade,event=None):
+        print("GO PRESET FADE",nr)
 
+        rdata = self.PRESETS.get_raw_map(nr)
+        cfg   = self.PRESETS.get_cfg(nr)
+        fcmd  = self.FIXTURES.update_raw(rdata)
+        #virtcmd  = self.data.FIXTURES.get_virtual(rdata)
 
-class Presets(Base):
-    def __init__(self):
-        super().__init__() 
-        #self.load()
 
-    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 backup_presets(self):
-        filename = "presets"
-        data   = self.val_presets
-        labels = self.label_presets
-        self._backup(filename,data,labels)
-        
-
-    def get_cfg(self,nr):
-        if nr not in self.val_presets:
-            print(self,"error get_cfg no nr:",nr)
-            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
+        xFLASH = 0
+        value=None
+        #xfade = fade
+        if modes.val("FLASH") or ( "BUTTON" in cfg and cfg["BUTTON"] == "SEL"): #FLASH
+            self.preset_select(nr)
+            return 0
+        elif modes.val("FLASH") or ( "BUTTON" in cfg and cfg["BUTTON"] == "FL"): #FLASH
+            xFLASH = 1
+            xfade = 0
+            if event:
+                if str(event.type) == "ButtonRelease" or event.type == '5' :
+                    # 4 fix vor ThinkPad / Debian 11
+                    if xFLASH:
+                        value = "off"
 
-            for attr in sdata[fix]:
-                x = {}
-                #print("RAW",attr)
-                x["FIX"]   = fix
-                x["ATTR"]  = attr
+        vvcmd = update_raw_dmx( rdata ,value,[xfade] ) 
+        fxcmd = update_raw_dmx( rdata ,value,[xfade],fx=1) 
 
-                x["VALUE"] = sdata[fix][attr]["VALUE"]
-                x["FX"]    = sdata[fix][attr]["FX"]
-                #x["DMX"]  = sdata[fix][attr]["NR"] 
+        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 )
 
-                out.append(x)
-        return out
+                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 )
 
-class GUI_grid():
-    def __init__(self,root,data,title="tilte",width=800):
+        cmd = "".join(cmd)
+        print("cmd",cmd) 
+        if cmd and not modes.val("BLIND"):
+            client.send(cmd )
+        
+        self.refresh_gui()
 
-        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:
+        
+    def draw_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)
 
-            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")
+        #b = tk.Button(frame,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] = {}
+            
+        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,elem=b).cb)
+            b.grid(row=r, column=c, sticky=tk.W+tk.E)
             c+=1
-            if c % 8 == 0:
-                r+=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,data=data).cb)
+            b.grid(row=r, column=c, sticky=tk.W+tk.E)
+            c+=1
+            if c >=12:
                 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+=1
+        return c,r
+    def draw_patch(self):
         r=0
         c=0
-        i=1
-        self.b = tk.Label(self.frame,bg="blue", text="MAIN:MENU",width=13,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=13,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(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() #Toplevel()
-        else:
-            self.tk = tkinter.Toplevel()
-        self.tk["bg"] = "black"
-        self.tk.bind("<Button>",self.callback)
-        self.tk.bind("<Key>",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)
+        root = frame_dim
+        dim_frame = tk.Frame(root,bg="black")
+        dim_frame.pack(fill=tk.X, side=tk.TOP)
+        root = frame_patch
 
-        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
-        #self.frame.pack()
-    def mainloop(self):
-        self.tk.mainloop()
-    def callback(self,event,data={}):
-        print("<GUI>",self,event,data)
         
-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())
+        fix_frame = tk.Frame(root,bg="black")
+        canvas = tk.Canvas(root)
+        def yview(event):
+            print("yevent",event)
+            print(dir(canvas))
+            #yview_moveto', 'yview_scroll'
+            yyy=20.1
+            
+            fix_frame.yview_moveto(yyy)
+            #canvas.yview_moveto(yyy)
+            #yyy=20
+            #canvas.yview_scroll(yyy,"units")
+        #def sconfig(event):
+        #    global canvas
+        #    canvas.configure(scrollregion=canvas.bbox("all"),width=400,height=200)
+        #fix_frame.bind("<Configure>",sconfig)
+        #myscrollbar=tk.Scrollbar(root,orient="vertical",command=canvas.yview)
+        #myscrollbar=tk.Scrollbar(root,orient="vertical",command=yview)
+        #myscrollbar.pack(side="right",fill="y") 
+        #canvas.create_window((0, 0), window=fix_frame, anchor="nw")
+        #canvas.pack(fill=tk.X, side=tk.TOP)
 
-window_manager = WindowManager()
-
-w = GUIWindow("MAIN",master=1,width=130,height=450,left=0,top=65)
-data = []
-#data.append({"text":"COMMAND"})
-data.append({"text":"EXEC"})
-data.append({"text":"DIMMER"})
-data.append({"text":"FIXTURES"})
-#data.append({"text":"PRESET"})
-#data.append({"text":"PATCH"})
-#data.append({"text":"ENCODER"})
-f = GUI_menu(w.tk,data)
-window_manager.new(w)
-
-#w = GUIWindow("GRID",master=0,width=1000,height=200,left=232,top=65)
-#data = []
-#for i in range(10):
-#    data.append({"text":"P {:02}".format(i+1)})
-#w = GUI_grid(w.tk,data)
-#window_manager.new(w)
-
-name = "COMMAND"
-w = GUIWindow(name,master=0,width=350,height=200,left=950,top=65)
-frame_cmd = w.tk
-window_manager.new(w,name)
-
-name="EXEC"
-w = GUIWindow(name,master=0,width=800,height=400,left=140,top=65)
-frame_exe = w.tk
-window_manager.new(w,name)
-
-name="DIMMER"
-w = GUIWindow(name,master=0,width=800,height=400,left=140,top=65)
-w1 = ScrollFrame(w.tk,width=800,height=400)
-frame_dim = w1 # w.tk
-window_manager.new(w,name)
-
-name="FIXTURES"
-w = GUIWindow(name,master=0,width=800,height=400,left=140,top=65)
-w1 = ScrollFrame(w.tk,width=800,height=400)
-frame_fix = w1 #w.tk
-window_manager.new(w,name)
-
-name="PATCH"
-w = GUIWindow(name,master=0,width=800,height=400,left=140,top=65)
-w1 = ScrollFrame(w.tk,width=800,height=400)
-frame_patch = w1 #w.tk
-window_manager.new(w,name)
-
-name="FX"
-w = GUIWindow(name,master=0,width=350,height=250,left=950,top=305)
-frame_fx = 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")
-
-name="ENCODER"
-ww = GUIWindow(name,master=0,width=800,height=50,left=140,top=500)
-Xroot = ww.tk
-w = None
-root = tk.Frame(Xroot,bg="black",width="10px")
-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")
-root2.pack(fill=tk.BOTH,expand=0, side=tk.LEFT)
-
-#default_font = font.Font(family='Helvetica', size=12, weight='bold')
-Font = font.Font(family='Helvetica', size=9, weight='normal')
-FontBold = font.Font(family='Helvetica', size=10, weight='bold')
-#default_font.configure(size=9)
-Xroot.option_add("*Font", FontBold)
-
-
-
-#w = frame_fix #GUIWindow("OLD",master=0,width=800,height=500,left=130,top=65)
-window_manager.new(w,name)
-
-class GUI(Base):
-    def __init__(self):
-        super().__init__() 
-        self.load()
-
-        self.all_attr =["DIM","PAN","TILT"]
-        self.elem_attr = {}
-        
-        self.fx_commands =["STONY_FX","FX OFF","\n"
-                ,"FX:CIR","FX:PAN","FX:TILT","FX:DIM","\n"
-                ,"SZ:","SP:","ST:","OF:","BS:-","\n"
-                , "FX:SIN","FX:COS","FX:BUM","FX:BUM2","FX:FD","FX:ON","FX:ON2" ]
-        self.commands =["\n","BLIND","CLEAR","STORE","EDIT","MOVE","\n","CFG-BTN","LABEL"
-                ,"BACKUP","SET","","","SELECT","ACTIVATE","FLASH","FADE"
-                ]
-        self.elem_fx_commands = {}
-        self.val_fx_commands = {}
-        self.elem_commands = {}
-        self.val_commands = {}
-
-        self.elem_presets = {}
-        self.PRESETS = Presets()
-        self.PRESETS.load_presets()
-        self.FIXTURES = Fixtures()
-        self.FIXTURES.load_patch()
-        
-        for i in range(8*8):
-            if i not in self.PRESETS.val_presets:
-                name = "Preset:"+str(i+1)+":\nXYZ"
-                #self.presets[i] = [i]
-                self.PRESETS.val_presets[i] = OrderedDict() # FIX 
-                self.PRESETS.val_presets[i]["CFG"] =  OrderedDict() # CONFIG 
-                self.PRESETS.label_presets[i] = "-"
-
-  
-    def load(self,fname=""):
-        pass
-    def exit(self):
-        print("__del__",self)
-        self.PRESETS.backup_presets()
-        print("********************************************************")
-        self.FIXTURES.backup_patch()
-        print("*********del",self,"***********************************************")
-    def refresh_gui(self):
-        for fix in self.FIXTURES.fixtures:                            
-            sdata = self.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"
-                    else:
-                        elem["bg"] = "grey"
-
-    def preset_store(self,nr):
-        print("STORE PRESET")
-        self.val_commands["STORE"] = 0
-        global STORE
-        STORE = 0
-        self.elem_commands["STORE"]["bg"] = "lightgrey"
-
-        CFG = OrderedDict()
-        if "CFG" in self.PRESETS.val_presets[nr]: #["CFG"] 
-            CFG = self.PRESETS.val_presets[nr]["CFG"] 
-        sdata = {}
-        sdata["CFG"] = CFG # OrderedDict()
-        sdata["CFG"]["FADE"] = fade
-        sdata["CFG"]["DEALY"] = 0
-        #sdata["CFG"]["BUTTON"] = "GO"
-        for fix in self.FIXTURES.fixtures:                            
-            data = self.FIXTURES.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
-                        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"] 
-    
-        print("sdata",len(sdata))
-        
-        self.PRESETS.val_presets[nr] = sdata
-        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
-
-            self.elem_presets[nr]["fg"] = "black"
-            if val_color:
-                self.elem_presets[nr]["bg"] = "yellow"
-                if fx_color:
-                    self.elem_presets[nr]["fg"] = "blue"
-            else:   
-                if fx_color:
-                    self.elem_presets[nr]["bg"] = "cyan"
-        else:
-            self.elem_presets[nr]["fg"] = "black"
-            self.elem_presets[nr]["bg"] = "grey"
-        #self.elem_presets[nr].option_add("*Font", FontBold)
-        label = ""
-        if nr in self.PRESETS.label_presets:
-            #print(dir(self.data))
-            label = self.PRESETS.label_presets[nr]
-
-        BTN="go"
-        if "CFG" in sdata:#["BUTTON"] = "GO"
-            if "BUTTON" in sdata["CFG"]:
-                BTN = sdata["CFG"]["BUTTON"]
-        txt = str(nr)+":"+str(BTN)+":"+str(len(sdata)-1)+"\n"+label 
-        self.elem_presets[nr]["text"] = txt 
-        #print("GO CFG ",self.PRESETS.val_presets)
-           
-
-    def preset_select(self,nr):
-        print("SELECT PRESET")
-        sdata = self.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]
-                    #self#encoder(attr=attr,data=data,elem=elem,action="click")
-                    self.FIXTURES.fixtures[fix]["ATTRIBUT"][attr]["ACTIVE"] = 1
-                    elem["bg"] = "yellow"
-    def preset_go(self,nr,xfade=fade,event=None):
-        print("GO PRESET FADE",nr)
-
-        rdata = self.PRESETS.get_raw_map(nr)
-        cfg   = self.PRESETS.get_cfg(nr)
-        fcmd  = self.FIXTURES.update_raw(rdata)
-        #virtcmd  = self.data.FIXTURES.get_virtual(rdata)
-
-
-        xFLASH = 0
-        value=None
-        #xfade = fade
-        if modes.val("FLASH") or ( "BUTTON" in cfg and cfg["BUTTON"] == "SEL"): #FLASH
-            self.preset_select(nr)
-            return 0
-        elif modes.val("FLASH") or ( "BUTTON" in cfg and cfg["BUTTON"] == "FL"): #FLASH
-            xFLASH = 1
-            xfade = 0
-            if event:
-                if str(event.type) == "ButtonRelease" or event.type == '5' :
-                    # 4 fix vor ThinkPad / Debian 11
-                    if xFLASH:
-                        value = "off"
-
-        vvcmd = update_raw_dmx( rdata ,value,[xfade] ) 
-        fxcmd = update_raw_dmx( rdata ,value,[xfade],fx=1) 
-
-        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 )
-        
-        self.refresh_gui()
-
-        
-    def draw_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)
-
-        #b = tk.Button(frame,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] = {}
-            
-        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,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,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):
-        r=0
-        c=0
-        root = frame_dim
-        dim_frame = tk.Frame(root,bg="black")
-        dim_frame.pack(fill=tk.X, side=tk.TOP)
-        root = frame_patch
-
-        
-        fix_frame = tk.Frame(root,bg="black")
-        canvas = tk.Canvas(root)
-        def yview(event):
-            print("yevent",event)
-            print(dir(canvas))
-            #yview_moveto', 'yview_scroll'
-            yyy=20.1
-            
-            fix_frame.yview_moveto(yyy)
-            #canvas.yview_moveto(yyy)
-            #yyy=20
-            #canvas.yview_scroll(yyy,"units")
-        #def sconfig(event):
-        #    global canvas
-        #    canvas.configure(scrollregion=canvas.bbox("all"),width=400,height=200)
-        #fix_frame.bind("<Configure>",sconfig)
-        #myscrollbar=tk.Scrollbar(root,orient="vertical",command=canvas.yview)
-        #myscrollbar=tk.Scrollbar(root,orient="vertical",command=yview)
-        #myscrollbar.pack(side="right",fill="y") 
-        #canvas.create_window((0, 0), window=fix_frame, anchor="nw")
-        #canvas.pack(fill=tk.X, side=tk.TOP)
-
-        fix_frame = tk.Frame(root,bg="black")
-        fix_frame.pack(fill=tk.X, side=tk.TOP)
-        #fix_frame = canvas
+        fix_frame = tk.Frame(root,bg="black")
+        fix_frame.pack(fill=tk.X, side=tk.TOP)
+        #fix_frame = canvas
 
         #fix_frame.configure(scrollregion=canvas.bbox("all"),width=200,height=200)
         #canvas.configure(yscrollcommand=myscrollbar.set)
@@ -1675,7 +1301,8 @@ class GUI(Base):
                 c=0
                 r+=1
                 
-    def draw_enc(self):
+    def draw_enc(self,xframe):
+        root2 = xframe
         i=0
         c=0
         r=0
@@ -1706,7 +1333,8 @@ class GUI(Base):
             if c >=8:
                 c=0
                 r+=1
-    def draw_fx(self):
+    def draw_fx(self,xframe):
+        frame_fx=xframe
         i=0
         c=0
         r=0
@@ -1765,7 +1393,8 @@ class GUI(Base):
             if c >=5:
                 c=0
                 r+=1
-    def draw_command(self):
+    def draw_command(self,xframe):
+        frame_cmd=xframe
         i=0
         c=0
         r=0
@@ -1826,11 +1455,12 @@ class GUI(Base):
             if c >=5:
                 c=0
                 r+=1
-    def draw_preset(self):
+    def draw_preset(self,xframe):
+
         i=0
         c=0
         r=0
-        root = frame_exe
+        root = xframe
         
         frame = tk.Frame(root,bg="black")
         frame.pack(fill=tk.X, side=tk.TOP)
@@ -1874,83 +1504,494 @@ class GUI(Base):
                                 if sdata[fix][attr]["VALUE"] is not None:
                                     val_color = 1
 
-                    b["fg"] = "black"
-                    if val_color:
-                        b["bg"] = "gold"
-                        if fx_color:
-                            b["fg"] = "blue"
-                    else:   
-                        if fx_color:
-                            b["bg"] = "cyan"
-                else:
-                    b["bg"] = "grey"
-            if "SEL" in txt:
-                b["fg"] = "black"
-                b["bg"] = "blue"
-            elif "GO" in txt:
-                b["fg"] = "black"
-            elif "FL" in txt:
-                b["fg"] = "red"
+                    b["fg"] = "black"
+                    if val_color:
+                        b["bg"] = "gold"
+                        if fx_color:
+                            b["fg"] = "blue"
+                    else:   
+                        if fx_color:
+                            b["bg"] = "cyan"
+                else:
+                    b["bg"] = "grey"
+            if "SEL" in txt:
+                b["fg"] = "black"
+                b["bg"] = "blue"
+            elif "GO" in txt:
+                b["fg"] = "black"
+            elif "FL" in txt:
+                b["fg"] = "red"
+
+            if k not in self.elem_presets:
+                self.elem_presets[k] = b
+                #self.PRESETS.val_presets[preset] = 0
+            b.grid(row=r, column=c, sticky=tk.W+tk.E)
+            c+=1
+            if c >=8:
+                c=0
+                r+=1
+    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("<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
+
+        colp.colorpicker(xframe,width=600,height=100)
+        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_patch()
+        self.draw_fix()
+        #input()
+        #self.draw_enc()
+        #self.draw_command()
+        #self.draw_fx()
+        self.draw_input()
+        #self.draw_preset()
+
+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)
+    return bframe
+#frame = ScrollFrame(root)
+
+class GUIHandler():
+    def __init__(self):
+        pass
+    def update(self,fix,attr,args={}):
+        #print("GUIHandler",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
+        #self.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 update_raw(self,rdata):
+        #print("update_raw",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"]  
+
+            if attr not in ATTR:
+                continue
+        
+            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:
+                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})
+        return cmd
+
+
+class Presets(Base):
+    def __init__(self):
+        super().__init__() 
+        #self.load()
+
+    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 backup_presets(self):
+        filename = "presets"
+        data   = self.val_presets
+        labels = self.label_presets
+        self._backup(filename,data,labels)
+        
+
+    def get_cfg(self,nr):
+        if nr not in self.val_presets:
+            print(self,"error get_cfg no nr:",nr)
+            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
+
+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:
 
-            if k not in self.elem_presets:
-                self.elem_presets[k] = b
-                #self.PRESETS.val_presets[preset] = 0
-            b.grid(row=r, column=c, sticky=tk.W+tk.E)
+            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:
-                c=0
+            if c % 8 == 0:
                 r+=1
-    def draw_input(self):
-        i=0
-        c=0
-        r=0
-        frame = tk.Frame(root2,bg="black")
-        frame.pack(fill=tk.X, side=tk.TOP)
+                c=0
+            i+=1
+        self.frame.pack()
 
-        b = tk.Label(frame,bg="black", text="------------------------ ---------------------------------------")
-        b.grid(row=r, column=c, sticky=tk.W+tk.E)
+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
-        
-        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")
+        c=0
+        i=1
+        self.b = tk.Label(self.frame,bg="blue", text="MAIN:MENU",width=13,height=1)
+        self.b.grid(row=r, column=c, sticky=tk.W+tk.E)#,anchor="w")
         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("<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 render(self):
-        Xroot.bind("<Key>",Xevent(fix=0,elem=None,attr="ROOT",data=self,mode="ROOT").cb)
-        self.draw_patch()
-        self.draw_fix()
-        #input()
-        self.draw_enc()
-        self.draw_command()
-        self.draw_fx()
-        self.draw_input()
-        self.draw_preset()
+        for row in data:
+            #print(i)
+            #row = data[i]
+            self.b = tk.Button(self.frame,bg="lightblue", text=row["text"],width=13,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(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() #Toplevel()
+        else:
+            self.tk = tkinter.Toplevel()
+        self.tk["bg"] = "black"
+        self.tk.bind("<Button>",self.callback)
+        self.tk.bind("<Key>",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.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
+        #self.frame.pack()
+    def mainloop(self):
+        self.tk.mainloop()
+    def callback(self,event,data={}):
+        print("<GUI>",self,event,data)
+        
+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())
+
+window_manager = WindowManager()
+
+master =GUI()
+
+w = GUIWindow("MAIN",master=1,width=130,height=450,left=0,top=65)
+data = []
+#data.append({"text":"COMMAND"})
+data.append({"text":"EXEC"})
+data.append({"text":"DIMMER"})
+data.append({"text":"FIXTURES"})
+#data.append({"text":"PRESET"})
+#data.append({"text":"PATCH"})
+#data.append({"text":"ENCODER"})
+f = GUI_menu(w.tk,data)
+window_manager.new(w)
+
+name="DIMMER"
+w = GUIWindow(name,master=0,width=800,height=400,left=140,top=65)
+w1 = ScrollFrame(w.tk,width=800,height=400)
+frame_dim = w1 # w.tk
+window_manager.new(w,name)
+
+name="FIXTURES"
+w = GUIWindow(name,master=0,width=800,height=400,left=140,top=65)
+w1 = ScrollFrame(w.tk,width=800,height=400)
+frame_fix = w1 #w.tk
+window_manager.new(w,name)
+
+
+name="ENCODER"
+ww = GUIWindow(name,master=0,width=800,height=50,left=140,top=500)
+Xroot = ww.tk
+#default_font = font.Font(family='Helvetica', size=12, weight='bold')
+Font = font.Font(family='Helvetica', size=9, weight='normal')
+FontBold = font.Font(family='Helvetica', size=10, weight='bold')
+#default_font.configure(size=9)
+Xroot.option_add("*Font", FontBold)
+w = None
+root = tk.Frame(Xroot,bg="black",width="10px")
+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)
+
+
+#w = GUIWindow("GRID",master=0,width=1000,height=200,left=232,top=65)
+#data = []
+#for i in range(10):
+#    data.append({"text":"P {:02}".format(i+1)})
+#w = GUI_grid(w.tk,data)
+#window_manager.new(w)
+
+name = "COMMAND"
+w = GUIWindow(name,master=0,width=350,height=200,left=950,top=65)
+master.draw_command(w.tk)
+window_manager.new(w,name)
+
+name="EXEC"
+w = GUIWindow(name,master=0,width=800,height=400,left=140,top=65)
+#frame_exe = w.tk
+master.draw_preset(w.tk)
+window_manager.new(w,name)
+
+name="PATCH"
+w = GUIWindow(name,master=0,width=800,height=400,left=140,top=65)
+w1 = ScrollFrame(w.tk,width=800,height=400)
+frame_patch = w1 #w.tk
+window_manager.new(w,name)
+
+name="FX"
+w = GUIWindow(name,master=0,width=350,height=250,left=950,top=305)
+#frame_fx = w.tk
+master.draw_fx(w.tk)
+window_manager.new(w,name)
+
+#LibreLightDesk
+name="COLERPICKER"
+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:
-    master =GUI()
-    master.render()
 
     #root.mainloop()
     #tk.mainloop()

+ 128 - 0
lib/colorpicker.py

@@ -0,0 +1,128 @@
+
+import tkinter as tk
+
+def r():
+    canvas=tk.Canvas(xframe,width=600,height=100)
+    canvas["bg"] = "yellow" #"green"
+    canvas.pack()
+    # RGB
+    x=0
+    y=0
+    j=0
+    d = 20
+    f = 255 #255-fi
+    e = 5
+    for r in range(0,d+1):
+        fi = int(r*255/d)
+        color = '#%02x%02x%02x' % (f, fi, fi) 
+        print( "farbe", r*10, j, f,fi,fi,color)
+        r = canvas.create_rectangle(x, y, x+20, y+20, fill=color)
+        x+=20
+
+
+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):
+        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:]))
+
+
+def colorpicker(xframe,width=600,height=100):
+    canvas=tk.Canvas(xframe,width=width,height=height)
+    canvas["bg"] = "grey" #"green"
+    callback = cb(canvas)
+    #canvas.bind("<Key>", key)
+    canvas.bind("<Button-1>", callback.callback)
+    canvas.pack()
+
+    x=2
+    y=2
+    d = 3
+    r=0
+    g=1
+    b=1
+    mode = 0
+    count = 0
+    while 1:
+        print("-",[r,g,b],mode)
+        for xx in range(d,0,-1):
+            fi = int(xx*255/d)
+            print(xx,y)
+            print(fi,end=" ")
+            color = '#%02x%02x%02x' % (int(255-r*fi),int(255-g*fi),int(255-b*fi)) 
+            canvas.create_rectangle(x, y, x+20, y+20, fill=color)
+            
+            y+=22
+        color = '#%02x%02x%02x' % (255,255,255) 
+        canvas.create_rectangle(x, y, x+20, y+20, fill=color)
+        print()
+        if count == 1 and mode == 3:
+            print("-------")
+            break
+        y=2
+        x+=22
+        if r >= 1 and g >= 1 and b <= 0:
+            mode = 1
+        elif r <= 0 and g >= 1 and b <= 0:
+            mode = 2
+        elif r <= 0 and g >= 1 and b >= 1:
+            mode = 3
+        elif r <= 0 and g <= 0 and b >= 1:
+            mode = 4
+        elif r >= 1 and g <= 0 and b >= 1:
+            mode = 5
+        elif r >= 1 and g <= 0 and b <= 0:
+            mode = 6
+            count +=1
+
+        s = 0.25 # 1/d #0.25
+        if mode == 1:
+            r -= s#0.25
+        if mode == 2:
+            b += s#0.25
+        if mode == 3:
+            g -= s#0.25
+        if mode == 4:
+            r += s#0.25
+        if mode == 5:
+            b -= s#0.25
+        if mode == 6:
+            g += s#0.25
+
+        if r > 1:
+            r=1
+        if g > 1:
+            g=1
+        if b > 1:
+            b=1
+
+        if r < 0:
+            r=0
+        if g < 0:
+            g=0
+        if b < 0:
+            b=0
+    
+if __name__ == "__main__":
+    xframe = tk.Tk() 
+    xframe.geometry("1600x600")
+    r()
+    colorpicker(xframe)
+    xframe.mainloop()

+ 2 - 2
show/GloryCamp2021/patch.sav

@@ -89,5 +89,5 @@
 125	125	{"DMX": 125, "UNIVERS": 0, "NAME": "D125", "ATTRIBUT": {"DIM": {"NR": 1, "MASTER": "1", "MODE": "F", "VALUE": 106.86, "ACTIVE": 0, "FX": ""}}}
 126	126	{"DMX": 126, "UNIVERS": 0, "NAME": "D126", "ATTRIBUT": {"DIM": {"NR": 1, "MASTER": "1", "MODE": "F", "VALUE": 106.86, "ACTIVE": 0, "FX": ""}}}
 1001	1001	{"DMX": 401, "UNIVERS": 0, "NAME": "IRGB", "ATTRIBUT": {"DIM": {"NR": 1, "MASTER": "1", "MODE": "F", "VALUE": 45.21, "ACTIVE": 0, "FX": ""}, "RED": {"NR": 4, "MASTER": "", "MODE": "F", "VALUE": 256, "ACTIVE": 0, "FX": ""}, "GREEN": {"NR": 5, "MASTER": "", "MODE": "F", "VALUE": 251.89, "ACTIVE": 0, "FX": ""}, "BLUE": {"NR": 6, "MASTER": "", "MODE": "F", "VALUE": 256, "ACTIVE": 0, "FX": ""}}}
-3001	3001	{"DMX": 241, "UNIVERS": 0, "NAME": "MH-BEAM", "ATTRIBUT": {"SHUTTER": {"NR": 6, "MASTER": "", "MODE": "", "VALUE": 217.8300000000003, "ACTIVE": 0, "FX": ""}, "DIM": {"NR": -1, "MASTER": "", "MODE": "F", "VALUE": 256, "ACTIVE": 0, "FX": ""}, "PAN": {"NR": 1, "MASTER": "", "MODE": "F", "VALUE": 139.74000000000004, "ACTIVE": 0, "FX": ""}, "PAN-FINE": {"NR": 2, "MASTER": "", "MODE": "F", "VALUE": 127.0, "ACTIVE": 0, "FX": ""}, "TILT": {"NR": 3, "MASTER": "", "MODE": "F", "VALUE": 53.43000000000002, "ACTIVE": 0, "FX": ""}, "TILT-FINE": {"NR": 4, "MASTER": "", "MODE": "F", "VALUE": 127.0, "ACTIVE": 0, "FX": ""}, "RED": {"NR": 7, "MASTER": "1", "MODE": "F", "VALUE": 256, "ACTIVE": 0, "FX": ""}, "GREEN": {"NR": 8, "MASTER": "1", "MODE": "F", "VALUE": 256, "ACTIVE": 0, "FX": ""}, "BLUE": {"NR": 9, "MASTER": "1", "MODE": "F", "VALUE": 256, "ACTIVE": 0, "FX": ""}}}
-3002	3002	{"DMX": 261, "UNIVERS": 0, "NAME": "MH-BEAM", "ATTRIBUT": {"SHUTTER": {"NR": 6, "MASTER": "", "MODE": "", "VALUE": 213.72000000000028, "ACTIVE": 0, "FX": ""}, "DIM": {"NR": -1, "MASTER": "", "MODE": "F", "VALUE": 256, "ACTIVE": 0, "FX": ""}, "PAN": {"NR": 1, "MASTER": "", "MODE": "F", "VALUE": 147.96000000000006, "ACTIVE": 0, "FX": ""}, "PAN-FINE": {"NR": 2, "MASTER": "", "MODE": "F", "VALUE": 127.0, "ACTIVE": 0, "FX": ""}, "TILT": {"NR": 3, "MASTER": "", "MODE": "F", "VALUE": 36.99000000000002, "ACTIVE": 0, "FX": ""}, "TILT-FINE": {"NR": 4, "MASTER": "", "MODE": "F", "VALUE": 127.0, "ACTIVE": 0, "FX": ""}, "RED": {"NR": 7, "MASTER": "1", "MODE": "F", "VALUE": 256, "ACTIVE": 0, "FX": ""}, "GREEN": {"NR": 8, "MASTER": "1", "MODE": "F", "VALUE": 256, "ACTIVE": 0, "FX": ""}, "BLUE": {"NR": 9, "MASTER": "1", "MODE": "F", "VALUE": 256, "ACTIVE": 0, "FX": ""}}}
+3001	3001	{"DMX": 241, "UNIVERS": 0, "NAME": "MH-BEAM", "ATTRIBUT": {"SHUTTER": {"NR": 6, "MASTER": "", "MODE": "", "VALUE": 8.220000000000002, "ACTIVE": 0, "FX": ""}, "DIM": {"NR": -1, "MASTER": "", "MODE": "F", "VALUE": 256, "ACTIVE": 0, "FX": ""}, "PAN": {"NR": 1, "MASTER": "", "MODE": "F", "VALUE": 98.64, "ACTIVE": 0, "FX": ""}, "PAN-FINE": {"NR": 2, "MASTER": "", "MODE": "F", "VALUE": 127.0, "ACTIVE": 0, "FX": ""}, "TILT": {"NR": 3, "MASTER": "", "MODE": "F", "VALUE": 24.660000000000025, "ACTIVE": 0, "FX": ""}, "TILT-FINE": {"NR": 4, "MASTER": "", "MODE": "F", "VALUE": 127.0, "ACTIVE": 0, "FX": ""}, "RED": {"NR": 7, "MASTER": "1", "MODE": "F", "VALUE": 256, "ACTIVE": 0, "FX": ""}, "GREEN": {"NR": 8, "MASTER": "1", "MODE": "F", "VALUE": 256, "ACTIVE": 0, "FX": ""}, "BLUE": {"NR": 9, "MASTER": "1", "MODE": "F", "VALUE": 256, "ACTIVE": 0, "FX": ""}}}
+3002	3002	{"DMX": 261, "UNIVERS": 0, "NAME": "MH-BEAM", "ATTRIBUT": {"SHUTTER": {"NR": 6, "MASTER": "", "MODE": "", "VALUE": 8.220000000000002, "ACTIVE": 0, "FX": ""}, "DIM": {"NR": -1, "MASTER": "", "MODE": "F", "VALUE": 256, "ACTIVE": 0, "FX": ""}, "PAN": {"NR": 1, "MASTER": "", "MODE": "F", "VALUE": 98.64, "ACTIVE": 0, "FX": ""}, "PAN-FINE": {"NR": 2, "MASTER": "", "MODE": "F", "VALUE": 127.0, "ACTIVE": 0, "FX": ""}, "TILT": {"NR": 3, "MASTER": "", "MODE": "F", "VALUE": 24.660000000000025, "ACTIVE": 0, "FX": ""}, "TILT-FINE": {"NR": 4, "MASTER": "", "MODE": "F", "VALUE": 127.0, "ACTIVE": 0, "FX": ""}, "RED": {"NR": 7, "MASTER": "1", "MODE": "F", "VALUE": 256, "ACTIVE": 0, "FX": ""}, "GREEN": {"NR": 8, "MASTER": "1", "MODE": "F", "VALUE": 256, "ACTIVE": 0, "FX": ""}, "BLUE": {"NR": 9, "MASTER": "1", "MODE": "F", "VALUE": 256, "ACTIVE": 0, "FX": ""}}}

Datei-Diff unterdrückt, da er zu groß ist
+ 1 - 1
show/GloryCamp2021/presets.sav


Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.