Files @ 1b0266dd233a
Branch filter:

Location: light9/light8/uihelpers.py - annotation

drewp
picking and dragging works pretty well (no ctrl yet)
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
"""all the tiny tk helper functions"""

from __future__ import nested_scopes
from Tkinter import *
from Tix import *
from types import StringType

windowlocations = {
    'sub' : '425x738+00+00',
    'console' : '168x24+848+000',
    'leveldisplay' : '144x340+870+400',
    'cuefader' : '314x212+546+741',
    'effect' : '24x24+0963+338',
    'stage' : '823x683+37+030',
    'scenes' : '504x198+462+12',
}

def make_frame(parent):
    f = Frame(parent, bd=0, bg='black')
    f.pack(side='left')
    return f

def bindkeys(root,key, func):
    root.bind(key, func)
    for w in root.winfo_children():
        w.bind(key, func)


def toplevel_savegeometry(tl,name):
    try:
        geo = tl.geometry()
        if not geo.startswith("1x1"):
            f=open(".light9-window-geometry-%s" % name.replace(' ','_'),'w')
            f.write(tl.geometry())
        # else the window never got mapped
    except:
        # it's ok if there's no saved geometry
        pass

    # this would get called repeatedly for each child of the window (i
    # dont know why) so we unbind after the first Destroy event
    tl.unbind("<Destroy>",tl._toplevelat_funcid)

def toplevelat(name, existingtoplevel=None):
    tl = existingtoplevel or Toplevel()
    tl.title(name)

    try:
        f=open(".light9-window-geometry-%s" % name.replace(' ','_'))
        windowlocations[name]=f.read() # file has no newline
    except:
        # it's ok if there's no saved geometry
        pass

    if name in windowlocations:
        tl.geometry(windowlocations[name])

    tl._toplevelat_funcid=tl.bind("<Destroy>",lambda ev,tl=tl,name=name: toplevel_savegeometry(tl,name))

    return tl

def toggle_slider(s):
    if s.get() == 0:
        s.set(100)
    else:
        s.set(0)

# for lambda callbacks    
def printout(t):
    print t

def printevent(ev):
    for k in dir(ev):
        if not k.startswith('__'):
            print k,getattr(ev,k)
    print ""
    
def eventtoparent(ev,sequence):
    "passes an event to the parent, screws up TixComboBoxes"

    wid_class = str(ev.widget.__class__)
    if wid_class == 'Tix.ComboBox' or wid_class == 'Tix.TixSubWidget':
        return

    evdict={}
    for x in ['state', 'time', 'y', 'x', 'serial']:
        evdict[x]=getattr(ev,x)
#    evdict['button']=ev.num
    par=ev.widget.winfo_parent()
    if par!=".":
        ev.widget.nametowidget(par).event_generate(sequence,**evdict)
    #else the event made it all the way to the top, unhandled

def colorlabel(label):
    """color a label based on its own text"""
    txt=label['text'] or "0"
    lev=float(txt)/100
    low=(80,80,180)
    high=(255,55,050)
    out = [int(l+lev*(h-l)) for h,l in zip(high,low)]
    col="#%02X%02X%02X" % tuple(out)
    label.config(bg=col)

# TODO: get everyone to use this
def colorfade(low, high, percent):
    '''not foolproof.  make sure 0 < percent < 1'''
    out = [int(l+percent*(h-l)) for h,l in zip(high,low)]
    col="#%02X%02X%02X" % tuple(out)
    return col

def colortotuple(anytkobj, colorname):
    'pass any tk object and a color name, like "yellow"'
    rgb = anytkobj.winfo_rgb(colorname)
    return [v / 256 for v in rgb]

class Togglebutton(Button):
    """works like a single radiobutton, but it's a button so the
    label's on the button face, not to the side. the optional command
    callback is called on button set, not on unset. takes a variable
    just like a checkbutton"""
    def __init__(self,parent,variable=None,command=None,downcolor='red',**kw):

        self.oldcommand = command
        Button.__init__(self,parent,command=self.invoke,**kw)

        self._origbkg = self.cget('bg')
        self.downcolor = downcolor

        self._variable = variable
        if self._variable:
            self._variable.trace('w',self._varchanged)
            self._setstate(self._variable.get())
        else:
            self._setstate(0)

        self.bind("<Return>",self.invoke)
        self.bind("<1>",self.invoke)
        self.bind("<space>",self.invoke)

    def _varchanged(self,*args):
        self._setstate(self._variable.get())
        
    def invoke(self,*ev):
        if self._variable:
            self._variable.set(not self.state)
        else:
            self._setstate(not self.state)
        
        if self.oldcommand and self.state: # call command only when state goes to 1
            self.oldcommand()
        return "break"

    def _setstate(self,newstate):
        self.state = newstate
        if newstate: # set
            self.config(bg=self.downcolor,relief='sunken')
        else: # unset
            self.config(bg=self._origbkg,relief='raised')
        return "break"


class FancyDoubleVar(DoubleVar):
    def __init__(self,master=None):
        DoubleVar.__init__(self,master)
        self.callbacklist = {} # cbname : mode
        self.namedtraces = {} # name : cbname
    def trace_variable(self,mode,callback):
        """Define a trace callback for the variable.

        MODE is one of "r", "w", "u" for read, write, undefine.
        CALLBACK must be a function which is called when
        the variable is read, written or undefined.

        Return the name of the callback.
        """
        cbname = self._master._register(callback)
        self._tk.call("trace", "variable", self._name, mode, cbname)
        
        # we build a list of the trace callbacks (the py functrions and the tcl functionnames)
        self.callbacklist[cbname] = mode
#        print "added trace:",callback,cbname
        
        return cbname
    trace=trace_variable
    def disable_traces(self):
        for cb,mode in self.callbacklist.items():
#            DoubleVar.trace_vdelete(self,v[0],k)
            self._tk.call("trace", "vdelete", self._name, mode,cb)
            # but no master delete!
            
    def recreate_traces(self):
        for cb,mode in self.callbacklist.items():
#            self.trace_variable(v[0],v[1])
            self._tk.call("trace", "variable", self._name, mode,cb)

    def trace_named(self, name, callback):
        if name in self.namedtraces:
            print "FancyDoubleVar: already had a trace named %s - replacing it" % name
            self.delete_named(name)

        cbname = self.trace_variable('w',callback) # this will register in self.callbacklist too
        
        self.namedtraces[name] = cbname
        return cbname
        
    def delete_named(self, name):
        if name in self.namedtraces:

            cbname = self.namedtraces[name]
            
            self.trace_vdelete('w',cbname)
	    #self._tk.call("trace","vdelete",self._name,'w',cbname)
            print "FancyDoubleVar: successfully deleted trace named %s" % name
        else:
            print "FancyDoubleVar: attempted to delete named %s which wasn't set to any function" % name

def get_selection(listbox):
    'Given a listbox, returns first selection as integer'
    selection = int(listbox.curselection()[0]) # blech
    return selection

if __name__=='__main__':
    root=Tk()
    root.tk_focusFollowsMouse()
    iv=IntVar()
    def cb():
        print "cb!"
    t = Togglebutton(root,text="testbutton",command=cb,variable=iv)
    t.pack()
    Entry(root,textvariable=iv).pack()
    root.mainloop()