UI with update-Function?



  • I’m working on a small interface which allows me to generate a composition according to a few parameters. The code takes a while to process, so updating in real-time doesn’t work well.

    Is there a way to add an «update»-Button in order to configure the settings first and then update?
    Or does anyone have another idea? (I hope my explanations are clear…)


  • admin

    well, if the Variables is to interactive and your code is to complex, its maybe time to but a different UI around it!!

    import vanilla
    import drawBot
    
    # create a custom controller calss
    class MyController:
        
        def __init__(self):
            # use vanilla to create a window
            self.w = vanilla.Window((400, 400), minSize=(200, 200))
            # add a text box
            self.w.textSizeText = vanilla.TextBox((10, 10, -10, 22), "Text Size:")
            # add a slider
            self.w.textSize = vanilla.Slider((80, 10, -10, 22), value=20, minValue=8, maxValue=100)
            # add a button and set the hit callback to `drawIt`
            self.w.update = vanilla.Button((10, 40, -10, 22), "Update", callback=self.drawIt)
            # add a drawBot preview
            self.w.preview = drawBot.ui.drawView.DrawView((0, 70, 0, 0))
            # open the window
            self.w.open()
        
        def drawIt(self, sender):
            # the callback when ever the button is hit
            # get the font size from the slider
            fontSize = self.w.textSize.get()
            # start a new drawing
            drawBot.newDrawing()
            # add a page
            drawBot.newPage(100, 100)
            # set a font size
            drawBot.fontSize(fontSize)
            # draw some thext
            drawBot.text(f"{fontSize}pt Hello foo bar", (10, 10))
            # get the pdf document
            pdf = drawBot.pdfImage()
            # set the pdf document in the preview
            self.w.preview.setPDFDocument(pdf)
            # clean up
            drawBot.endDrawing() 
    
    # open your controller
    MyController()
    

    this could be added to a .drawBot file which is a package to easily distribute complex code: see https://www.drawbot.com/content/drawBotApp/drawBotPackage.html

    good luck!!


  • admin

    second thought it could be a nice feature for Variable...

    continue here: https://github.com/typemytype/drawbot/issues/383



  • Many thanks, Frederik! Both thoughts are very useful and exactly what I was looking for.

    Now, I don’t manage to link a callback (CheckBox to use color), which is independent of the update Button with the draw function.

    import vanilla
    import drawBot
    from AppKit import NSColor
    
    
    # create a custom controller calss
    class MyController:
        
        def __init__(self):
            # use vanilla to create a window
            self.w = vanilla.Window((800, 800), minSize=(200, 200))
            # add a text box
            self.w.textSizeText = vanilla.TextBox((10, 10, -10, 22), "Text Size:")
            # add a slider
            self.w.textSize = vanilla.Slider((80, 10, -10, 22), value=20, minValue=8, maxValue=50)
            # add a button and set the hit callback to `drawIt`
            self.w.update = vanilla.Button((150, 40, -150, 22), "Update", callback=self.drawIt)
            
            self.w.colors = vanilla.ColorWell((10, 60, -750, -700),color=NSColor.redColor())
            
            self.w.checkBox = vanilla.CheckBox((60, 80, -10, 20), "use color", callback=self.checkBoxCallback, value=True)
            
            # add a drawBot preview
            self.w.preview = drawBot.ui.drawView.DrawView((0, 120, 0, 0))
            self.w.open() # open the window
            
        def checkBoxCallback(self, sender):
            print("check box checked", sender.get()) 
            if self.w.checkBox():
                color = self.w.colors()
            else:
                color = 0
             
        def drawIt(self, sender):
            # the callback when ever the button is hit
            # get the font size from the slider
            fontSize = self.w.textSize.get()
       
            # start a new drawing
            drawBot.newDrawing()
            # add a page
            drawBot.newPage(100, 100)
            # set a font size
            drawBot.fontSize(fontSize)
            # draw some thext
            drawBot.text(f"{fontSize}pt Hello foo bar", (10, 10))
            
            
            fill(color)
            rect(0,50,self.w.textSize.get(), 30)
            
            # get the pdf document
            pdf = drawBot.pdfImage()
            # set the pdf document in the preview
            self.w.preview.setPDFDocument(pdf)
            # clean up
            drawBot.endDrawing() 
    
    # open your controller
    MyController()
    

  • admin

    a lot of issue 🙂

    what is color?
    a vanilla colorWell is not callable, most vanilla controls have .get() to retrieve the data of the control.

    import vanilla
    import drawBot
    from AppKit import NSColor
    
    
    # create a custom controller calss
    class MyController:
        
        def __init__(self):
            # use vanilla to create a window
            self.w = vanilla.Window((800, 800), minSize=(200, 200))
            # add a text box
            self.w.textSizeText = vanilla.TextBox((10, 10, -10, 22), "Text Size:")
            # add a slider
            self.w.textSize = vanilla.Slider((80, 10, -10, 22), value=20, minValue=8, maxValue=50)
            # add a button and set the hit callback to `drawIt`
            self.w.update = vanilla.Button((150, 40, -150, 22), "Update", callback=self.drawIt)
            
            self.w.colors = vanilla.ColorWell((10, 60, -750, -700),color=NSColor.redColor())
            
            self.w.checkBox = vanilla.CheckBox((60, 80, -10, 20), "use color", value=True)
            
            # add a drawBot preview
            self.w.preview = drawBot.ui.drawView.DrawView((0, 120, 0, 0))
            self.w.open() # open the window        
             
        def drawIt(self, sender):
            # the callback when ever the button is hit
            # get the font size from the slider
            fontSize = self.w.textSize.get()
       
            # start a new drawing
            drawBot.newDrawing()
            # add a page
            drawBot.newPage(100, 100)
            # set a font size
            drawBot.fontSize(fontSize)
            # draw some thext
            drawBot.text(f"{fontSize}pt Hello foo bar", (10, 10))
            
           if self.w.checkBox.get():
                color = self.w.colors.get()
            else:
                color = 0
                
            fill(color)
            rect(0,50,self.w.textSize.get(), 30)
            
            # get the pdf document
            pdf = drawBot.pdfImage()
            # set the pdf document in the preview
            self.w.preview.setPDFDocument(pdf)
            # clean up
            drawBot.endDrawing() 
    
    # open your controller
    MyController()
    

  • admin

    an other option:

    use the vanilla argument continuous for input controls like sliders:

    Variable([
        dict(name="foo", ui="Slider", args=dict(continuous=False)),
        dict(name="bar", ui="Slider")    
    ], globals())
    
    print(foo, bar)
    

  • admin

    DrawBot 3.126 has a continuous flag in Variable that adds a Update button

    good luck!