changeset 818:bf728997bfde

start the observable between editchoice and the editor Ignore-this: 23094325e4b13df6a7b5d3b1325d509d
author drewp@bigasterisk.com
date Sat, 12 Jan 2013 20:51:20 +0000
parents 6885c2fa9369
children 87150923dcaa
files bin/subcomposer
diffstat 1 files changed, 79 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/bin/subcomposer	Thu Nov 01 04:00:16 2012 +0000
+++ b/bin/subcomposer	Sat Jan 12 20:51:20 2013 +0000
@@ -15,22 +15,54 @@
 from light9.rdfdb import clientsession
 from light9.tkdnd import initTkdnd, dragSourceRegister, dropTargetRegister
 
+class _NoNewVal(object):
+    pass
+
+class Observable(object):
+    """
+    like knockout's observable. Hopefully this can be replaced by a
+    better python one
+    """
+    def __init__(self, val):
+        self.val = val
+        self.subscribers = set()
+
+    def __call__(self, newVal=_NoNewVal):
+        if newVal is _NoNewVal:
+            return self.val
+        self.val = newVal
+        for s in self.subscribers:
+            s(newVal)
+
+    def subscribe(self, cb, callNow=True):
+        """cb is called with new values, and also right now with the
+        current value unless you opt out"""
+        self.subscribers.add(cb)
+        if callNow:
+            cb(self.val)
+
+class Local(object):
+    """placeholder for the local uri that EditChoice does not
+    manage. Set resourceObservable to Local to indicate that you're
+    unlinked"""
+
 class EditChoice(tk.Frame):
     """
+    Observable <-> linker UI
+
     widget for tying some UI to a shared resource for editing, or
     unlinking it (which means associating it with a local resource
     that's not named or shared). This object does not own the choice
     of resource; the caller does.
     """
-    def __init__(self, parent, getResource, onSetResource, onSetLocal):
-        want to pass an observable uri value and an observable isLocal for 2way sync
+    def __init__(self, parent, graph, resourceObservable):
         """
-        getResource is called to get the URI of the currently 
+        getResource is called to get the URI of the currently
         """
-        self.frame = tk.Frame(parent)
-        self.subSelection.pack(side='top')
-        tk.Label(self.subSelection, text="Editing:").pack(side='left')
-        self.currentSubFrame = tk.Frame(self.subSelection)
+        self.frame = tk.Frame(parent, relief='raised',border=8)
+        self.frame.pack(side='top')
+        tk.Label(self.frame, text="Editing:").pack(side='left')
+        self.currentSubFrame = tk.Frame(self.frame)
         self.currentSubFrame.pack(side='left')
 
         self.subIcon = tk.Label(self.currentSubFrame, text="sub1",
@@ -38,19 +70,37 @@
                                 relief='raised', padx=10, pady=10)
         self.subIcon.pack()
 
+        self.resourceObservable = resourceObservable
+        resourceObservable.subscribe(self.uriChanged)
+
         dragSourceRegister(self.subIcon, 'copy', 'text/uri-list',
-                           lambda: self.currentSub.uri)
-        def onEv(*args):
-            print "ev", args
+                           self.resourceObservable)
+        def onEv(ev):
+            self.resourceObservable(ev.data)
             return "link"
         self.onEv = onEv
-          
-        dropTargetRegister(self, onDrop=onEv,
-                           hoverStyle=dict(background="#555500", bd=3, relief='groove'))
+
+        # it would be nice if I didn't receive my own drags here
+        dropTargetRegister(self.subIcon, typeList=["*"], onDrop=onEv,
+                           hoverStyle=dict(background="#555500", bd=3,
+                                           relief='groove'))
 
         tk.Label(self.currentSubFrame, text="local data (drag sub here)").pack()
-        tk.Button(text="unlink", command=self.switchToLocalSub)
-    
+        b=tk.Button(text="unlink", command=self.switchToLocalSub)
+        b.pack()
+
+
+    def uriChanged(self, newUri):
+        print "chg", newUri
+        # i guess i show the label and icon for this
+        if newUri is Local:
+            self.subIcon.config(text="(local)")
+        else:
+            self.subIcon.config(text=newUri)
+
+    def switchToLocalSub(self):
+        self.resourceObservable(Local)
+
 
 class Subcomposer(tk.Frame):
     """
@@ -58,6 +108,8 @@
     editing. If we don't have a currentSub, then we're actually
     editing a session-local sub called <session> l9:currentSub <sessionLocalSub>
 
+    Contains an EditChoice widget
+
     UI actions:
     - drag a sub uri on here to make it the one we're editing
 
@@ -77,7 +129,7 @@
       although maybe that will be stupid. If you change the name
       before anyone knows about this uri, we could update the current
       sub's uri to a slug of the new label.
-    
+
     - rename this sub: not available if you're on a local sub. Sets
       the label of a named sub. Might update the uri of the named sub
       if it's new enough that no one else would have that uri. Not
@@ -96,8 +148,14 @@
         self.levelbox = Levelbox(self, graph)
         self.levelbox.pack(side='top')
 
-        EditChoice(self).frame.pack(side='top')
-        
+        currentUri = Observable("http://curr")
+
+        def pc(val):
+            print "change viewed sub to", val
+        currentUri.subscribe(pc)
+
+        EditChoice(self, self.graph, currentUri).frame.pack(side='top')
+
         def alltozero():
             for lev in self.levelbox.levels:
                 lev.setlevel(0)
@@ -139,9 +197,9 @@
             out[lev.channelnum] = lev.currentlevel
         if not out:
             return []
-        
+
         return [out.get(i, 0) for i in range(max(out.keys()) + 1)]
-     
+
     def sendupdate(self):
         dmxclient.outputlevels(self.toDmxLevels(), twisted=True)
 
@@ -153,7 +211,7 @@
         self.cmd = cmd
         self.entry = tk.Entry(self)
         self.entry.pack(side='left', expand=True, fill='x')
-        
+
         self.entry.bind("<Return>", self.action)
         tk.Button(self, text=verb, command=self.action).pack(side='left')