class ImportShardsGUI(TkWindow):

    def __init__(self, path):
        self.selectedComponent = None
        self.uid = 1
        self.functions = glomfrompath(path)
        super(ImportShardsGUI, self).__init__()

    def setupWindow(self):
        items = []
        lookup = {} # This is a bit of a nasty hack really ... :-)
                    # Why is this a hack ?
                    # Oh it's viewed here as a hack because it's a closure
        self.window.title("Shard Builder")

        self.addframe = Tkinter.Frame(self.window, borderwidth=2, relief=Tkinter.GROOVE)
        self.addframe.grid(row=0, column=0, sticky=Tkinter.N+Tkinter.E+Tkinter.W+Tkinter.S, padx=4, pady=4)
        
        # called when item selected from function list
        def menuCallback(index, text):
            self.click_menuChoice(self.getname(text), self.functions[text])
        
        items = list(self.functions.keys())
        
        self.choosebutton = ScrollingMenu(self.addframe, items,
                                          command = menuCallback)
        self.choosebutton.grid(row=0, column=0, columnspan=2, sticky=Tkinter.N)

        self.argPanel = None
        self.argCanvas = Tkinter.Canvas(self.addframe, relief=Tkinter.SUNKEN, borderwidth=2)
        self.argCanvas.grid(row=1, column=0, sticky=Tkinter.N+Tkinter.S+Tkinter.E+Tkinter.W)
        self.argCanvasWID = self.argCanvas.create_window(0,0, anchor=Tkinter.NW)
        self.argCanvasScroll = Tkinter.Scrollbar(self.addframe, orient=Tkinter.VERTICAL)
        self.argCanvasScroll.grid(row=1, column=1, sticky=Tkinter.N+Tkinter.S+Tkinter.E)
        self.argCanvasScroll['command'] = self.argCanvas.yview
        self.argCanvas['yscrollcommand'] = self.argCanvasScroll.set
        
        self.click_menuChoice(self.getname(items[0]), self.functions[items[0]])

        self.addbutton = Tkinter.Button(self.addframe, text="ADD Shard", command=self.click_addComponent)
        self.addbutton.grid(row=2, column=0, columnspan=2, sticky=Tkinter.S)
        self.addframe.rowconfigure(1, weight=1)
        self.addframe.columnconfigure(0, weight=1)
        
        # just adds component same atm.
        self.inlinebutton = Tkinter.Button(self.addframe, text="ADD Inline Shard", command=self.click_addInline)
        self.inlinebutton.grid(row=3, column=0, columnspan=2, sticky=Tkinter.S)

        self.window.rowconfigure(0, weight=1)
        self.window.columnconfigure(0, weight=1)

        self.window.protocol("WM_DELETE_WINDOW", self.handleCloseWindowRequest )


    def main(self):
        while not self.isDestroyed():
            while self.dataReady("control"):
                msg = self.recv("control")
                if isinstance(msg, producerFinished) or isinstance(msg, shutdownMicroprocess):
                    self.send(msg, "signal")
                    self.window.destroy()
                    
            self.tkupdate()
            yield 1

    def handleCloseWindowRequest(self):
        self.send( shutdownMicroprocess(self), "signal")
        self.window.destroy()
    
    def getname(self, fname):
        return fname.split(':')[1].lstrip()

    def click_addComponent(self):
        node, name = self.argPanel.getDef()
        self.send(("ADD", node, name),"outbox")
    
    def click_addInline(self):
        node, name = self.argPanel.getInlineDef()
        self.send(("ADD", node, name),"outbox")
    
    def click_menuChoice(self, fname, fcode):
        if self.argPanel != None:
            self.argPanel.destroy()
        
        self.argPanel = ImportShardPanel(self.argCanvas, fname, fcode)
        self.argPanel.update_idletasks()
        self.argCanvas.itemconfigure(self.argCanvasWID, window=self.argPanel)
        self.argCanvas['scrollregion'] = self.argCanvas.bbox("all")
class ImportShardsGUI(TkWindow):
    """
    A dialogue box component. Initialised with a path, it will extract the code
    of all the functions in any .py files it finds in the tree. These will be
    listed in a drop down menu. Selecting one will display its code.
    Two 'add' options are given: as an inline shard, or as a complete function.
    The inline option sends out just the body of the function as a shardGen
    object, otherwise the code for the function definition will be included.
    """
    def __init__(self, path):
        self.selectedComponent = None
        self.uid = 1
        self.functions = glomfrompath(path)
        super(ImportShardsGUI, self).__init__()

    def setupWindow(self):
        self.window.title("Shard Builder")

        self.addframe = Tkinter.Frame(self.window,
                                      borderwidth=2,
                                      relief=Tkinter.GROOVE)
        self.addframe.grid(row=0,
                           column=0,
                           sticky=Tkinter.N + Tkinter.E + Tkinter.W +
                           Tkinter.S,
                           padx=4,
                           pady=4)

        def menuCallback(index, text):
            self.click_menuChoice(self.getname(text), self.functions[text])

        items = list(self.functions.keys())

        self.choosebutton = ScrollingMenu(self.addframe,
                                          items,
                                          command=menuCallback)
        self.choosebutton.grid(row=0, column=0, columnspan=2, sticky=Tkinter.N)

        self.argPanel = None
        self.argCanvas = Tkinter.Canvas(self.addframe,
                                        relief=Tkinter.SUNKEN,
                                        borderwidth=2)
        self.argCanvas.grid(row=1,
                            column=0,
                            sticky=Tkinter.N + Tkinter.S + Tkinter.E +
                            Tkinter.W)
        self.argCanvasWID = self.argCanvas.create_window(0,
                                                         0,
                                                         anchor=Tkinter.NW)
        self.argCanvasScroll = Tkinter.Scrollbar(self.addframe,
                                                 orient=Tkinter.VERTICAL)
        self.argCanvasScroll.grid(row=1,
                                  column=1,
                                  sticky=Tkinter.N + Tkinter.S + Tkinter.E)
        self.argCanvasScroll['command'] = self.argCanvas.yview
        self.argCanvas['yscrollcommand'] = self.argCanvasScroll.set

        if self.functions:
            self.click_menuChoice(self.getname(items[0]),
                                  self.functions[items[0]])

        self.addbutton = Tkinter.Button(self.addframe,
                                        text="ADD Shard",
                                        command=self.click_addComponent)
        self.addbutton.grid(row=2, column=0, columnspan=2, sticky=Tkinter.S)
        self.addframe.rowconfigure(1, weight=1)
        self.addframe.columnconfigure(0, weight=1)

        # just adds component same atm.
        self.inlinebutton = Tkinter.Button(self.addframe,
                                           text="ADD Inline Shard",
                                           command=self.click_addInline)
        self.inlinebutton.grid(row=3, column=0, columnspan=2, sticky=Tkinter.S)

        self.window.rowconfigure(0, weight=1)
        self.window.columnconfigure(0, weight=1)

        self.window.protocol("WM_DELETE_WINDOW", self.handleCloseWindowRequest)

    def main(self):
        while not self.isDestroyed():
            while self.dataReady("control"):
                msg = self.recv("control")
                if isinstance(msg, producerFinished) or isinstance(
                        msg, shutdownMicroprocess):
                    self.send(msg, "signal")
                    self.window.destroy()

            self.tkupdate()
            yield 1

    def handleCloseWindowRequest(self):
        self.send(shutdownMicroprocess(self), "signal")
        self.window.destroy()

    def getname(self, fname):
        return fname.split(':')[1].lstrip()

    def click_addComponent(self):
        node, name = self.argPanel.getDef()
        self.send(("ADD", node, name), "outbox")

    def click_addInline(self):
        node, name = self.argPanel.getInlineDef()
        self.send(("ADD", node, name), "outbox")

    def click_menuChoice(self, fname, fcode):
        if self.argPanel != None:
            self.argPanel.destroy()

        self.argPanel = ImportShardPanel(self.argCanvas, fname, fcode)
        self.argPanel.update_idletasks()
        self.argCanvas.itemconfigure(self.argCanvasWID, window=self.argPanel)
        self.argCanvas['scrollregion'] = self.argCanvas.bbox("all")
Exemple #3
0
class BuilderControlsGUI(TkWindow):

    def __init__(self, classes):
        self.selectedComponent = None
        self.uid = 1
        self.classes = classes
        super(BuilderControlsGUI, self).__init__()

    def setupWindow(self):
        items = []
        lookup = {} # This is a bit of a nasty hack really ... :-)
                    # Why is this a hack ?
        self.window.title("Pipeline Builder")

        self.addframe = Tkinter.Frame(self.window, borderwidth=2, relief=Tkinter.GROOVE)
        self.addframe.grid(row=0, column=0, sticky=Tkinter.N+Tkinter.E+Tkinter.W+Tkinter.S, padx=4, pady=4)
        
        def menuCallback(index, text):
            self.click_menuChoice(lookup[text])

        print (self.classes[0])
        for theclass in self.classes:
            lookup[ theclass['module']+"."+theclass['class'] ] = theclass
            items.append(theclass['module']+"."+theclass['class'])

        self.choosebutton = ScrollingMenu(self.addframe, items,
                                          command = menuCallback)
        self.choosebutton.grid(row=0, column=0, columnspan=2, sticky=Tkinter.N)

        self.argPanel = None
        self.argCanvas = Tkinter.Canvas(self.addframe, relief=Tkinter.SUNKEN, borderwidth=2)
        self.argCanvas.grid(row=1, column=0, sticky=Tkinter.N+Tkinter.S+Tkinter.E+Tkinter.W)
        self.argCanvasWID = self.argCanvas.create_window(0,0, anchor=Tkinter.NW)
        self.argCanvasScroll = Tkinter.Scrollbar(self.addframe, orient=Tkinter.VERTICAL)
        self.argCanvasScroll.grid(row=1, column=1, sticky=Tkinter.N+Tkinter.S+Tkinter.E)
        self.argCanvasScroll['command'] = self.argCanvas.yview
        self.argCanvas['yscrollcommand'] = self.argCanvasScroll.set
        
        self.click_menuChoice(self.classes[1])

        self.addbutton = Tkinter.Button(self.addframe, text="ADD Component", command=self.click_addComponent )
        self.addbutton.grid(row=2, column=0, columnspan=2, sticky=Tkinter.S)
        self.addframe.rowconfigure(1, weight=1)
        self.addframe.columnconfigure(0, weight=1)
        
        self.remframe = Tkinter.Frame(self.window, borderwidth=2, relief=Tkinter.GROOVE)
        self.remframe.grid(row=1, column=0, columnspan=2, sticky=Tkinter.S+Tkinter.E+Tkinter.W, padx=4, pady=4)

        self.selectedlabel = Tkinter.Label(self.remframe, text="<no component selected>")
        self.selectedlabel.grid(row=0, column=0, sticky=Tkinter.S)
        
        self.delbutton = Tkinter.Button(self.remframe, text="REMOVE Component", command=self.click_removeComponent )
        self.delbutton.grid(row=1, column=0, sticky=Tkinter.S)
        self.delbutton.config(state=Tkinter.DISABLED)

        self.window.rowconfigure(0, weight=1)
        self.window.columnconfigure(0, weight=1)

        self.window.protocol("WM_DELETE_WINDOW", self.handleCloseWindowRequest )


    def main(self):

        while not self.isDestroyed():

            if self.dataReady("inbox"):
                data = self.recv("inbox")
                if data[0].upper() == "SELECT":
                    if data[1].upper() == "NODE":
                        self.componentSelected(data[2])
                                        
            while self.dataReady("control"):
                msg = self.recv("control")
                if isinstance(msg, producerFinished) or isinstance(msg, shutdownMicroprocess):
                    self.send(msg, "signal")
                    self.window.destroy()
                    
            self.tkupdate()
            yield 1

    def handleCloseWindowRequest(self):
        self.send( shutdownMicroprocess(self), "signal")
        self.window.destroy()


    def makeUID(self):
        uid = self.uid
        self.uid += 1
        return uid
        
    def componentSelected(self, component):
        self.selectedComponent = component
        if component == None:
            self.delbutton.config(state=Tkinter.DISABLED)
            self.selectedlabel["text"] = "<no component selected>"
        else:
            self.delbutton.config(state=Tkinter.NORMAL)
            self.selectedlabel["text"] = repr(component[0])


    def click_addComponent(self):
        # add to the pipeline and wire it in
        
        c = self.argPanel.getDef()
        c["id"] = ( c['name'], repr(self.makeUID()) )
        msg = ("ADD", c['id'], c['name'], c, self.selectedComponent)
        self.send( msg, "outbox")
        

    def click_removeComponent(self):
        if self.selectedComponent:
            self.send( ("DEL", self.selectedComponent), "outbox")


    def click_chooseComponent(self):
        pass

    def click_menuChoice(self, theclass):
        if self.argPanel != None:
            self.argPanel.destroy()
        
        self.argPanel = ArgumentsPanel(self.argCanvas, theclass)
        self.argPanel.update_idletasks()
        self.argCanvas.itemconfigure(self.argCanvasWID, window=self.argPanel)
        self.argCanvas['scrollregion'] = self.argCanvas.bbox("all")
class ImportShardsGUI(TkWindow):
    """
    A dialogue box component. Initialised with a path, it will extract the code
    of all the functions in any .py files it finds in the tree. These will be
    listed in a drop down menu. Selecting one will display its code.
    Two 'add' options are given: as an inline shard, or as a complete function.
    The inline option sends out just the body of the function as a shardGen
    object, otherwise the code for the function definition will be included.
    """
    
    
    def __init__(self, path):
        self.selectedComponent = None
        self.uid = 1
        self.functions = glomfrompath(path)
        super(ImportShardsGUI, self).__init__()

    def setupWindow(self):
        self.window.title("Shard Builder")

        self.addframe = Tkinter.Frame(self.window, borderwidth=2, relief=Tkinter.GROOVE)
        self.addframe.grid(row=0, column=0, sticky=Tkinter.N+Tkinter.E+Tkinter.W+Tkinter.S, padx=4, pady=4)
        
        def menuCallback(index, text):
            self.click_menuChoice(self.getname(text), self.functions[text])
        
        items = list(self.functions.keys())
        
        self.choosebutton = ScrollingMenu(self.addframe, items,
                                          command = menuCallback)
        self.choosebutton.grid(row=0, column=0, columnspan=2, sticky=Tkinter.N)

        self.argPanel = None
        self.argCanvas = Tkinter.Canvas(self.addframe, relief=Tkinter.SUNKEN, borderwidth=2)
        self.argCanvas.grid(row=1, column=0, sticky=Tkinter.N+Tkinter.S+Tkinter.E+Tkinter.W)
        self.argCanvasWID = self.argCanvas.create_window(0,0, anchor=Tkinter.NW)
        self.argCanvasScroll = Tkinter.Scrollbar(self.addframe, orient=Tkinter.VERTICAL)
        self.argCanvasScroll.grid(row=1, column=1, sticky=Tkinter.N+Tkinter.S+Tkinter.E)
        self.argCanvasScroll['command'] = self.argCanvas.yview
        self.argCanvas['yscrollcommand'] = self.argCanvasScroll.set
        
        if self.functions:
            self.click_menuChoice(self.getname(items[0]), self.functions[items[0]])

        self.addbutton = Tkinter.Button(self.addframe, text="ADD Shard", command=self.click_addComponent)
        self.addbutton.grid(row=2, column=0, columnspan=2, sticky=Tkinter.S)
        self.addframe.rowconfigure(1, weight=1)
        self.addframe.columnconfigure(0, weight=1)
        
        # just adds component same atm.
        self.inlinebutton = Tkinter.Button(self.addframe, text="ADD Inline Shard", command=self.click_addInline)
        self.inlinebutton.grid(row=3, column=0, columnspan=2, sticky=Tkinter.S)

        self.window.rowconfigure(0, weight=1)
        self.window.columnconfigure(0, weight=1)

        self.window.protocol("WM_DELETE_WINDOW", self.handleCloseWindowRequest )


    def main(self):
        while not self.isDestroyed():
            while self.dataReady("control"):
                msg = self.recv("control")
                if isinstance(msg, producerFinished) or isinstance(msg, shutdownMicroprocess):
                    self.send(msg, "signal")
                    self.window.destroy()
                    
            self.tkupdate()
            yield 1

    def handleCloseWindowRequest(self):
        self.send(shutdownMicroprocess(self), "signal")
        self.window.destroy()
    
    def getname(self, fname):
        return fname.split(':')[1].lstrip()

    def click_addComponent(self):
        node, name = self.argPanel.getDef()
        self.send(("ADD", node, name),"outbox")
    
    def click_addInline(self):
        node, name = self.argPanel.getInlineDef()
        self.send(("ADD", node, name),"outbox")
    
    def click_menuChoice(self, fname, fcode):
        if self.argPanel != None:
            self.argPanel.destroy()
        
        self.argPanel = ImportShardPanel(self.argCanvas, fname, fcode)
        self.argPanel.update_idletasks()
        self.argCanvas.itemconfigure(self.argCanvasWID, window=self.argPanel)
        self.argCanvas['scrollregion'] = self.argCanvas.bbox("all")
class ConnectorShardsGUI(TkWindow):

    def __init__(self, classes):
        self.selectedComponent = None
        self.uid = 1
        self.classes = classes
        super(ConnectorShardsGUI, self).__init__()

    def setupWindow(self):
        self.window.title("Connector Shards")

        self.addframe = Tkinter.Frame(self.window, borderwidth=2, relief=Tkinter.GROOVE)
        self.addframe.grid(row=0, column=0, sticky=Tkinter.N+Tkinter.E+Tkinter.W+Tkinter.S, padx=4, pady=4)
        
        def menuCallback(index, text):
            self.click_menuChoice(shardGen(lookup[text]))
        
        lookup = {}
        for theclass in self.classes:
            lookup[theclass.__name__] = theclass
        
        items = list(lookup.keys())
        self.choosebutton = ScrollingMenu(self.addframe, items,
                                          command = menuCallback)
        self.choosebutton.grid(row=0, column=0, columnspan=2, sticky=Tkinter.N)

        self.argPanel = None
        self.argCanvas = Tkinter.Canvas(self.addframe, relief=Tkinter.SUNKEN, borderwidth=2)
        self.argCanvas.grid(row=1, column=0, sticky=Tkinter.N+Tkinter.S+Tkinter.E+Tkinter.W)
        self.argCanvasWID = self.argCanvas.create_window(0,0, anchor=Tkinter.NW)
        self.argCanvasScroll = Tkinter.Scrollbar(self.addframe, orient=Tkinter.VERTICAL)
        self.argCanvasScroll.grid(row=1, column=1, sticky=Tkinter.N+Tkinter.S+Tkinter.E)
        self.argCanvasScroll['command'] = self.argCanvas.yview
        self.argCanvas['yscrollcommand'] = self.argCanvasScroll.set
        
        self.click_menuChoice(shardGen(lookup[items[0]]))

        self.addbutton = Tkinter.Button(self.addframe, text="ADD Shard", command=self.click_addComponent )
        self.addbutton.grid(row=2, column=0, columnspan=2, sticky=Tkinter.S)
        self.addframe.rowconfigure(1, weight=1)
        self.addframe.columnconfigure(0, weight=1)
        
        self.updatebutton = Tkinter.Button(self.addframe, text="Update Shard", command=self.click_update)
        self.updatebutton.grid(row=3, column=0, columnspan=2, sticky=Tkinter.S)

        self.window.rowconfigure(0, weight=1)
        self.window.columnconfigure(0, weight=1)

        self.window.protocol("WM_DELETE_WINDOW", self.handleCloseWindowRequest )


    def main(self):
        while not self.isDestroyed():
            if self.dataReady("inbox"):
                data = self.recv("inbox")
                if data[0].upper() == "SELECT":
                    if data[1].upper() == "NODE":
                        self.componentSelected(data[2])
                                        
            while self.dataReady("control"):
                msg = self.recv("control")
                if isinstance(msg, producerFinished) or isinstance(msg, shutdownMicroprocess):
                    self.send(msg, "signal")
                    self.window.destroy()
                    
            self.tkupdate()
            yield 1

    def handleCloseWindowRequest(self):
        self.send( shutdownMicroprocess(self), "signal")
        self.window.destroy()
        
    def componentSelected(self, component):
        self.selectedComponent = component
        self.click_menuChoice(component)
    
    def click_update(self):
        self.argPanel.update()
    
    def click_addComponent(self):
        node, name = self.argPanel.getDef()
        self.send(("ADD", node, name),"outbox")

    def click_menuChoice(self, shgen):
        if self.argPanel != None:
            self.argPanel.destroy()
        
        self.argPanel = ConnectorShardPanel(self.argCanvas, shgen)
        self.argPanel.update_idletasks()
        self.argCanvas.itemconfigure(self.argCanvasWID, window=self.argPanel)
        self.argCanvas['scrollregion'] = self.argCanvas.bbox("all")
        self.argPanel.focus_force() #doesn't work :(
Exemple #6
0
class BuilderControlsGUI(TkWindow):
    def __init__(self, classes):
        self.selectedComponent = None
        self.uid = 1
        self.classes = classes
        super(BuilderControlsGUI, self).__init__()

    def setupWindow(self):
        items = []
        lookup = {}  # This is a bit of a nasty hack really ... :-)
        # Why is this a hack ?
        self.window.title("Pipeline Builder")

        self.addframe = Tkinter.Frame(self.window,
                                      borderwidth=2,
                                      relief=Tkinter.GROOVE)
        self.addframe.grid(row=0,
                           column=0,
                           sticky=Tkinter.N + Tkinter.E + Tkinter.W +
                           Tkinter.S,
                           padx=4,
                           pady=4)

        def menuCallback(index, text):
            self.click_menuChoice(lookup[text])

        print(self.classes[0])
        for theclass in self.classes:
            lookup[theclass['module'] + "." + theclass['class']] = theclass
            items.append(theclass['module'] + "." + theclass['class'])

        self.choosebutton = ScrollingMenu(self.addframe,
                                          items,
                                          command=menuCallback)
        self.choosebutton.grid(row=0, column=0, columnspan=2, sticky=Tkinter.N)

        self.argPanel = None
        self.argCanvas = Tkinter.Canvas(self.addframe,
                                        relief=Tkinter.SUNKEN,
                                        borderwidth=2)
        self.argCanvas.grid(row=1,
                            column=0,
                            sticky=Tkinter.N + Tkinter.S + Tkinter.E +
                            Tkinter.W)
        self.argCanvasWID = self.argCanvas.create_window(0,
                                                         0,
                                                         anchor=Tkinter.NW)
        self.argCanvasScroll = Tkinter.Scrollbar(self.addframe,
                                                 orient=Tkinter.VERTICAL)
        self.argCanvasScroll.grid(row=1,
                                  column=1,
                                  sticky=Tkinter.N + Tkinter.S + Tkinter.E)
        self.argCanvasScroll['command'] = self.argCanvas.yview
        self.argCanvas['yscrollcommand'] = self.argCanvasScroll.set

        self.click_menuChoice(self.classes[1])

        self.addbutton = Tkinter.Button(self.addframe,
                                        text="ADD Component",
                                        command=self.click_addComponent)
        self.addbutton.grid(row=2, column=0, columnspan=2, sticky=Tkinter.S)
        self.addframe.rowconfigure(1, weight=1)
        self.addframe.columnconfigure(0, weight=1)

        self.remframe = Tkinter.Frame(self.window,
                                      borderwidth=2,
                                      relief=Tkinter.GROOVE)
        self.remframe.grid(row=1,
                           column=0,
                           columnspan=2,
                           sticky=Tkinter.S + Tkinter.E + Tkinter.W,
                           padx=4,
                           pady=4)

        self.selectedlabel = Tkinter.Label(self.remframe,
                                           text="<no component selected>")
        self.selectedlabel.grid(row=0, column=0, sticky=Tkinter.S)

        self.delbutton = Tkinter.Button(self.remframe,
                                        text="REMOVE Component",
                                        command=self.click_removeComponent)
        self.delbutton.grid(row=1, column=0, sticky=Tkinter.S)
        self.delbutton.config(state=Tkinter.DISABLED)

        self.window.rowconfigure(0, weight=1)
        self.window.columnconfigure(0, weight=1)

        self.window.protocol("WM_DELETE_WINDOW", self.handleCloseWindowRequest)

    def main(self):

        while not self.isDestroyed():

            if self.dataReady("inbox"):
                data = self.recv("inbox")
                if data[0].upper() == "SELECT":
                    if data[1].upper() == "NODE":
                        self.componentSelected(data[2])

            while self.dataReady("control"):
                msg = self.recv("control")
                if isinstance(msg, producerFinished) or isinstance(
                        msg, shutdownMicroprocess):
                    self.send(msg, "signal")
                    self.window.destroy()

            self.tkupdate()
            yield 1

    def handleCloseWindowRequest(self):
        self.send(shutdownMicroprocess(self), "signal")
        self.window.destroy()

    def makeUID(self):
        uid = self.uid
        self.uid += 1
        return uid

    def componentSelected(self, component):
        self.selectedComponent = component
        if component == None:
            self.delbutton.config(state=Tkinter.DISABLED)
            self.selectedlabel["text"] = "<no component selected>"
        else:
            self.delbutton.config(state=Tkinter.NORMAL)
            self.selectedlabel["text"] = repr(component[0])

    def click_addComponent(self):
        # add to the pipeline and wire it in

        c = self.argPanel.getDef()
        c["id"] = (c['name'], repr(self.makeUID()))
        msg = ("ADD", c['id'], c['name'], c, self.selectedComponent)
        self.send(msg, "outbox")

    def click_removeComponent(self):
        if self.selectedComponent:
            self.send(("DEL", self.selectedComponent), "outbox")

    def click_chooseComponent(self):
        pass

    def click_menuChoice(self, theclass):
        if self.argPanel != None:
            self.argPanel.destroy()

        self.argPanel = ArgumentsPanel(self.argCanvas, theclass)
        self.argPanel.update_idletasks()
        self.argCanvas.itemconfigure(self.argCanvasWID, window=self.argPanel)
        self.argCanvas['scrollregion'] = self.argCanvas.bbox("all")
class ConnectorShardsGUI(TkWindow):
    """
    Dialogue box that displays the list of classes it is given in a drop down
    menu. Information each class are shown when selected, see
    ConnectorShardPanel for details. Used by the ShardComposeGUI to
    display and configure the shard connector classes available.
    Sending a ['SELECT', 'NODE', <shardGen object>] message to its inbox
    will cause that object's details to be displayed.
    
    TODO: update menu button field on SELECT
    """

    def __init__(self, classes):
        self.selectedComponent = None
        self.uid = 1
        self.classes = classes
        super(ConnectorShardsGUI, self).__init__()

    def setupWindow(self):
        self.window.title("Connector Shards")

        self.addframe = Tkinter.Frame(self.window, borderwidth=2, relief=Tkinter.GROOVE)
        self.addframe.grid(row=0, column=0, sticky=Tkinter.N+Tkinter.E+Tkinter.W+Tkinter.S, padx=4, pady=4)
        
        def menuCallback(index, text):
            self.click_menuChoice(shardGen(lookup[text]))
        
        lookup = {}
        for theclass in self.classes:
            lookup[theclass.__name__] = theclass
        
        items = list(lookup.keys())
        self.choosebutton = ScrollingMenu(self.addframe, items,
                                          command = menuCallback)
        self.choosebutton.grid(row=0, column=0, columnspan=2, sticky=Tkinter.N)

        self.argPanel = None
        self.argCanvas = Tkinter.Canvas(self.addframe, relief=Tkinter.SUNKEN, borderwidth=2)
        self.argCanvas.grid(row=1, column=0, sticky=Tkinter.N+Tkinter.S+Tkinter.E+Tkinter.W)
        self.argCanvasWID = self.argCanvas.create_window(0,0, anchor=Tkinter.NW)
        self.argCanvasScroll = Tkinter.Scrollbar(self.addframe, orient=Tkinter.VERTICAL)
        self.argCanvasScroll.grid(row=1, column=1, sticky=Tkinter.N+Tkinter.S+Tkinter.E)
        self.argCanvasScroll['command'] = self.argCanvas.yview
        self.argCanvas['yscrollcommand'] = self.argCanvasScroll.set
        
        self.click_menuChoice(shardGen(lookup[items[0]]))

        self.addbutton = Tkinter.Button(self.addframe, text="ADD Shard", command=self.click_addComponent )
        self.addbutton.grid(row=2, column=0, columnspan=2, sticky=Tkinter.S)
        self.addframe.rowconfigure(1, weight=1)
        self.addframe.columnconfigure(0, weight=1)
        
        self.updatebutton = Tkinter.Button(self.addframe, text="Update Shard", command=self.click_update)
        self.updatebutton.grid(row=3, column=0, columnspan=2, sticky=Tkinter.S)

        self.window.rowconfigure(0, weight=1)
        self.window.columnconfigure(0, weight=1)

        self.window.protocol("WM_DELETE_WINDOW", self.handleCloseWindowRequest )


    def main(self):
        while not self.isDestroyed():
            if self.dataReady("inbox"):
                data = self.recv("inbox")
                if data[0].upper() == "SELECT":
                    if data[1].upper() == "NODE":
                        self.componentSelected(data[2])
                                        
            while self.dataReady("control"):
                msg = self.recv("control")
                if isinstance(msg, producerFinished) or isinstance(msg, shutdownMicroprocess):
                    self.send(msg, "signal")
                    self.window.destroy()
                    
            self.tkupdate()
            yield 1

    def handleCloseWindowRequest(self):
        self.send( shutdownMicroprocess(self), "signal")
        self.window.destroy()
        
    def componentSelected(self, component):
        self.selectedComponent = component
        self.click_menuChoice(component)
    
    def click_update(self):
        self.argPanel.update()
    
    def click_addComponent(self):
        node, name = self.argPanel.getDef()
        self.send(("ADD", node, name),"outbox")

    def click_menuChoice(self, shgen):
        if self.argPanel != None:
            self.argPanel.destroy()
        
        self.argPanel = ConnectorShardPanel(self.argCanvas, shgen)
        self.argPanel.update_idletasks()
        self.argCanvas.itemconfigure(self.argCanvasWID, window=self.argPanel)
        self.argCanvas['scrollregion'] = self.argCanvas.bbox("all")
        self.argPanel.focus_force() #doesn't work :(