Guido cannot work in python mode

After some gander at Guido repo, seems like all of its Python examples and workarounds had never been released nor tagged for years! :date:

All the Python Mode examples linked by @tabreturn: :star_struck:

Relies on an Interactive.make() overloaded signature w/ 2 args: Interactive.make(this, True): :flushed:

However, that overloaded static method version exists on ‘master’ only, nowhere else! :open_mouth:

So even today, only the Interactive.make() w/ 1 parameter is available. :expressionless:

However, w/o it, we have to close Python Mode completely before each re-run! :scream:

But fret not! Now that Python Mode allows directly access to any Java member, regardless its access permission, we can simply assign None to Interactive.manager before calling Interactive.make(): :crazy_face:

# Workaround for missing overloaded Interactive.make(PApplet, boolean):
print Interactive.manager
Interactive.manager = None 
Interactive.make(this)

It forces Interactive.make() to always instantiate a new Interactive rather than reusing an existing 1, which is unfortunately buggy on Python Mode. :bug:

There are more problems when using Guido on Python Mode though. :zipper_mouth_face:
Interactive.add() doesn’t work on Python classes. :snake:
Instead, we need to create a class which inherits from ActiveElement: :face_with_monocle:

# ActiveElement inheritance replaces Interactive.add(Object):
class SimpleButton(ActiveElement):

W8! There’s 1 more bug! Which was fixed on ‘master’, but it’s unavailable for us: :face_with_head_bandage:

Callback ActiveElement::mousePressed() is invoked 2 times! :calling:

  • 1st as signature ActiveElement::mousePressed() w/ no parameters.
  • 2nd as signature ActiveElement::mousePressed(float, float), which receives mouse’s current coordinates.

As you can see, all empty callbacks were commented on ‘master’ version. :see_no_evil:
But they’re very active on the distributed version we use currently. :space_invader:

Java, due to its native overloading dispatch, can pick which 1 to use. :coffee:
But in Python, we’ve gotta def a callback which accepts all overloaded signatures coming at it! :grimacing:

# *args for both signatures ActiveElement::mousePressed() &
# ActiveElement::mousePressed(float, float):
def mousePressed(self, *args):

And b/c it’s called back twice, we need to check which version it was, so we don’t toggle self.on twice as well: :checkered_flag:

# Only toggles when overloaded callback signature isn't
# ActiveElement::mousePressed():
if args: self.on ^= True
print args, self.on

I believe that’s all for now. As you can see, I’ve fixed the button example, not the slider 1, b/c that’s the 1 I was studying while trying to peruse the Guido source: :upside_down_face:

"""
 Simple Button (Guido)
 ported from Java to Python by fjenett (2014-May-25)
 fix & mod for old Guido by GoToLoop (2019-Mar-30)

 Discourse.Processing.org/t/guido-cannot-work-in-python-mode/9501/10
 GitHub.com/fjenett/Guido/blob/master/examples/mode-python/button/button.pyde
"""

add_library('Guido')

def setup():
    size(400, 400)

    # Workaround for missing overloaded Interactive.make(PApplet, boolean):
    print Interactive.manager
    Interactive.manager = None 
    Interactive.make(this)

    dim = SimpleButton.DIM
    d = (width - dim) / dim
    dd = d << 1

    for y in range(dim, height - d, dd):
        for x in range(dim, width - d, dd):
            SimpleButton(x, y, d, d)


def draw(): clear()


# ActiveElement inheritance replaces Interactive.add(Object):
class SimpleButton(ActiveElement):
    DIM, ON, OFF, OUTLINE = 20, 200, 100, -1

    def __init__(self, x, y, w, h):
        super(SimpleButton, self).__init__(x, y, w, h)
        self.on = False


    # Variant param *args for both sigs ActiveElement::mousePressed() &
    # ActiveElement::mousePressed(float, float):
    def mousePressed(self, *args):
        # Only toggles when overloaded callback signature isn't
        # ActiveElement::mousePressed():
        if args: self.on ^= True
        print args, self.on


    def draw(self):
        stroke(self.OUTLINE) if self.hover else noStroke()
        fill(self.ON if self.on else self.OFF)
        rect(self.x, self.y, self.width, self.height)
2 Likes