Capturing Unicorn Tears

I ran across a post on the forums where the developer was asking how to call the Action event of a Pushbutton.  The simple answer is use the Push method.  It simulates the user actually pushing the button with the mouse thus causing its Action event to fire (and on Mac OS X the button actually animates the push – I don’t know about Windows or Linux).  The longer, more nuanced answer, is don’t do that!  It’s a bad idea.  Let me explain.

Let’s start off with a typical development experience.  You’ve created your wizbang new utility.  It starts of simple and you have a simple Pushbutton.  You add the Pushbutton to your window, you then add the Action event and you put your super duper code that captures unicorn tears.  You test and it works great to much acclaim.

Version one goes out the door and users ask for more features.  So you add a PagePanel to your Window and move the existing UI to one of the pages.  But, because capturing unicorn tears is THE feature of your app you add a Toolbar to the window and then add a Button to it.  In the Toolbar action event you need to make the same thing happen that the Pushbutton did before.

At this point you can either copy and paste the code from the Pushbutton Action event into the Toolbar Action event and be done with it.  This is bad because if you change something in your process it has to be fixed in two places.  But you’ve read the documentation and know that there is a Push method on the Pushbutton that allows you to simulate the push and fire the Action event.  This is slightly better because you only have one copy of the code.  But it’s still not great.

The better choice is to create a method that does whatever was in the Pushbutton Action event.  Maybe a method called “Handle_Capture_Unicorn_Tears” is a better idea.  Because then it can be called from either the Pushbutton or Toolbar action events.

I know, this seems like a lot of work, but now version two ships and someone asks, “Hey, wouldn’t it be great to have a keyboard shortcut for getting those Unicorn tears?”  And you say, “Yup,” and proceed to add it to the Menubar with its own MenuHandler.  If you had copied the code from action event to action event now you’d have a third place to maintain it.

Have I mentioned yet that this is a bad idea?  So don’t do it.  I’ve had to fix projects like this where code was copied and pasted each time it was used.  All of them slightly different.  Are there reasons for them to be different in this location versus the other location?  Only the unicorns know and they ain’t telling;  it’s very hard to debug apps like this.

But no, you’ve been trying to be a good developer and know that copy/pasting the exact same code in multiple places is a bad idea.  But you did use the Push method and you now try to call that from the MenuHandler.  Except the window that the Pushbutton resides on isn’t even open yet when you try to Free the Unicorns.  Except that in testing you always had that window open when calling the MenuHandler and now users are reporting a Nil Object Exception and are pretty angry.

I’m sure must be a valid reason to use the Push method.  I just haven’t found it yet in fifteen years of coding Xojo applications.  The Push seems to be the lazy way out when putting the code from the Action event into its own method would be just as easy (and preferable).

Push works for Pushbuttons, but there is no equivalent for it in other controls.  Nothing.  Learn how to call the same method from two places.  It’s not that hard.

I’ll mention a forward looking thing based on Xojo for iOS experience.  In the existing framework setting a controls value via code will always fire it’s action event.  For example, if you set the Value of a CheckBox it’s Action event fires.  In iOS, setting the equivalent Switch value via code does NOT fire its ValueChanged event.  This is on purpose and all iOS controls are like this.  I was told by a Xojo engineer that this will come to the desktop and web frameworks too.  Be warned.

Capturing unicorn tears is cool and I encourage to make such a utility.  Be smart about it and be lazy and not just lazy now but lazy for a year from now.  If you ever have a need to call a control event from another location, make a method and call the method from the spots it needs.

What say you my fellow Xojo maniacs?

3 thoughts on “Capturing Unicorn Tears

  1. Absolutely – separation of the function from the UI should be the rule, it’s part of Object Oriented design. I would argue that the only code not to be abstracted from the UI elements is code which affects other UI elements.

    The proposed change there mentioned, that changing values in code will no longer fire events will mean a whole lot of “If bEditInCode = False” tests can be stripped out, so seems a great idea to me.

  2. “In iOS, setting the equivalent Switch value via code does NOT fire its ValueChanged event. This is on purpose and all iOS controls are like this. I was told by a Xojo engineer that this will come to the desktop and web frameworks too. Be warned.”

    Whether a value is changed by code or manually by user interaction, there must be an event firing which allows to react on the new situation. If they simply switch this off in desktop builds, then it will break a lot of code out there. But heck, I’m pretty disillusioned about Xojo’s protection of customer’s investments …

    And for the unicorn: Before starting a real-world project, I’d recommend to get familiar with the terms Encapsulation, Data Abstraction, Polymorphism and Inheritence. (See rblibrary.com for Object Oriented Programming).

    Instead of just adding a unicorn-tears-method to Window1, I would create a unicorn class and include any current and future methods and properties etc in it. When the project grows, it helps a lot to keep things clean.

    • Oh, agreed, but I can’t tell you how many projects I’ve ‘fixed’ that do exactly what I wrote up. So one step at a time.

Comments are closed.