THE Button library you want for codea

Hi all.
For a long time i’ve been writing and sharing button libraries for Codea. I am still not completely satisfyed with my production. I’d like to make (potentially with your help too) a button library that would be ‘the’ definite one that we need.
So i need you help for specifying it.
In my opinion, it should:

  • be very easy to use.
  • code should be integrable in a tab of the project.
  • it should use a callback mechanism / or an event mechanism to trigger action.
  • buttons should have rounded corners, 2 colors (one when waiting, one when touched), a border.
  • should there be a shadow?
  • should the code be the smallest possible?
  • should the buttons come with a user friendly editor? Then how to save the edited properties?
  • buttons should react to tap, press… anything else?
  • should be really fast (for games fps) and the lightest possible on memory.
  • documentation should be included. How to invoque it?
  • i would like this library to be so good that TLL eventually integrates it into Codea.
  • what else?
  • automatic simple layout: left, right, top, bottom (from @yojimbo2000).
  • make buttons appearance fully customizable. (from @andymac3d).
  • buttons should be easily groupable, triggerable and made active. (from @andymac3d).
  • abstracting away the UI design from the main functional code (from @andymac3d).
    Please let me know you opinions!
    Thanks.

What about Cider Controls 7? I haven’t used it myself, but it seems to have some of the features you mention. Is the idea of the library that your proposing that it just focus on the buttons (rather than sliders and other UI elements that Cider Controls covers)?

@Yojimbo2000 thanks for the remark.
I know about Cider7, it is a very nice lib in some aspects. I tried to use but, for me, there were several pifalls:

  • it was expensive on fps.
  • i didnt find it really practical to use (my feeling, i fully respect the great work of Mark).
  • the callback mechanism needed to be cleaned up (when i used it).
    Making excellent buttons is already a tricky task, i fear that trying to embrace too much too early will drift from the goal.
    Btw, you are not using Cider either. Why? You dont need any button lib and prefer to rewrite your own each time?

It’s true, Cider is usually too much for what I need and I do end up writing button classes over and over for some reason… @-)

Personally I think if you start to add an editor, a file format that you save/ load etc, then it starts to get further away from being very simple and light.

Usually, I find there’s some predefined area of the screen where I want the buttons to be, and I just want the buttons I define to automatically line up in a row, either horizontally or vertically, and reposition themselves if the orientation changes.

But then I’ve never written particularly button heavy apps, like RPGs and so on.

@Jmv38. I think you’re right. A definitive way of defining a UI in Codea is well overdue and a simple ‘standard’ method of defining buttons is the minimal requirement.

A couple of additional things relating to Buttons:

  • I think the concept of button ‘appearance’ (i.e. what they look like) - should be fully customisable. I think a default rounded (or Apple standard UIKit one) is a good start - but for games etc… people will want to re-skin this for their own purposes.

  • You should be able to easily setup ‘collections’ of buttons (with independent callbacks) to allow multiple buttons (i.e. a menu) to be easily groupable, triggerable and made active.

My personal view is the development of a more expansive UI system (call it ‘son of Cider’ for want of a better word) that allows Codea users to easily design a UI layout in a drag and drop way (using some bundled tool) that then gets exported to a UI definition file. The definition file gets referenced in a Codea project and its methods/callbacks are then exposed to the user - all relatively transparent and painless.

This is pretty much how QT does its UI stuff (although far more complicated) - but also Pythonista (on the iPad) does this via a .pyui file which is exported from a bundled (and easy to use) UI design tool.

Simplicity and a ‘one size fits all’ strategy for this is very hard to achieve - at least abstracting away the UI design from the main functional code is a good start IMHO.

How does that sound?

@yojimbo2000 Good summary. this translate in adding to the spec:

  • automatic layout: left, right, top, bottom (from @yojimbo2000)

@andymac3d thanks for your insight. Very useful, as usual.
I think i should add to the spec:

  • make buttons appearance fully customizable.
  • buttons should be easily groupable, triggerable and made active.
  • abstracting away the UI design from the main functional code.
    this is probably extremely important, since decoupling functionnalities is the key for code that feels right. Thanks for pointing this out.

No probs @Jmv38 - glad to help.

I guess the beauty of such a UI framework is that once written, you can add extra functionality (or UI ‘widgets’) as you go along and don’t have to write everything in one go. Buttons first and then other things later etc…

As I mentioned, Its worth having a look at how Pythonista implements its UI decoupling as it seems to strike a good compromise between usability and power. It’s UI interface designer is really quite fun! :smiley:

@andymac3d i have pythonista and i know about this interface designer. There are 2 noticeable things, imo:

  • the format to save the ui data: it is a text file, in json i think. Could be a tab in codea, with a table defining the buttons.
  • the editor: it looks preatty much like cider editor. Not sure yet to like it. But i will check again.

@Jvm38 - I already have a well specced out and complete scene (screen) manager . widget manager library that does pretty much everything you need, including all the callbacks / notification events etc. I use lua tables to define the UI widgets and the look and feel of each widget is defined by a entry in a “style” table so that styles can be reused and it keeps the actual UI definition quite small.

My plan is eventually allow the UI and styles to be defined as JSON files so they can be synced via dropbox and reused - replaced as required.

It just need’s documenting, a bit of refactoring to clean up / standardise the code and a couple of the more complex widgets finishing off (I add widgets as I need them for my own projects), I was going to release it to the forum eventually - so if your interested PM me and I can share off the code and maybe we work on it together.

Make an optional delay before the buttons “pop up” again able to be pressed. Also, make a few options for how to display time remaining until it’s usable and such.

EDIT: the word I was looking for was Cooldown; and while I’m on it why not Heatup, where if you hold the button for too long it locks (and maybe then goes into a cooldown). Maybe add some triangle, oval, polygon/abstract buttons?

thanks for your suggestions

I’m a noob when it comes to coding, I made this button class code for my games controls but I’m not sure if I made any mistakes because I not sure how to use or “activate” the code . I tried to but nothing happened (and I was using the variables I made while I was trying to). Could you please help and edit the code for me so it works, my button could be a nice addition to your button library after it’s code is perfected. By the way, my code uses sprites as the button’s “skin” and the reason why nothing happens when you press the button is because I haven’t decided to add that in yet. I’ll probably make the sprite look darker when your finger is touching the button too. Here’s the code… I haven’t got the code copied I’ll post another comment with the code =))

Code :

Controls = class()

function Controls:init(ControlsSide)

    -- Codea does not automatically call this method
    -- ControlsSide means the side of the screen that my controls are on
    -- the x and y for the rect

self.body.x = x
self.body.y = y

    if ControlsSide == left then x = 0 y = 30
        elseif ControlsSide == right then x = 694 y = 724
end

function Controls:draw(ButtonType)
    -- Codea does not automatically call this method
    -- ButtonType is the variable that  determines the "type" of button for my controls
    -- rect(0,0,80,80) is equal to sprite("Project:(left, right, etc.) button", 40,40)
    -- using the info above ^^^ I did the math for the x and y for my custom sprites

    if ButtonType == left then sprite("Project:left button",x + 75,y + 40) 
        elseif ButtonType == up then sprite("Project:up button",x + 165,y + 80)
            elseif ButtonType == action then sprite("Project:action button",x + 165,y + 40)
                elseif ButtonType == right then sprite("Project:right button",x + 330,y + 40)
            tint(255, 255, 255, 148)
end

function Controls:Touched(touch)
    -- Codea does not automatically call this method

    if touchData.state==ENDED then
        --see if we touched the button

        if math.abs(touch.x - x) <= 80 and math.abs(touch.y - y) <= 80 and ButtonType == left then DoSomething()
                elseif ButtonType == up then DoSomething()
                    elseif ButtonType == action then DoSomething()
                        elseif ButtonType == right then DoSomething()
                end
            end
        end
    end
end

It’s not drawing the button because your draw function is empty.

If you don’t understand the code you are using, I suggest you practise some more on simpler examples first.

For some reason when I pasted the code it looked weird and wasn’t right so I changed my comment so most of the code is copyable. I don’t know how to make the rest of it copyable. And thanks for your tutorials @Ignatz I was only able to make that code because of them.

@GameCoder Whenever you post code, put 3 ~'s on a line before and after your code. I added them to your code above.

fabulous and practical

@TechDojo did you finish refactoring your scene manager? If you’re willing to share it, would you be able to PM me a code link?

@Jmv38 I was wondering if you had made any progress with this.

I recently started making a WebDAV client in Codea, so started using Cider 7 for the interface. Of course, as I was going along, I kept on having to make little changes to the library (maybe it is inevitable that every library gets forked at some stage?)

My thoughts are that it should:

  1. Use named parameters. eg

    Button{text = "Don't press me", style = "warning", 
      callback = function() 
         --do something awful 
      end}
    

    I find that particularly when you have various subclasses taking slightly varying parameters, it can get really tricky remembering which subclasses take which parameters, especially if flicking back and forth between dependencies. Named parameters allow way more flexibility when you’re constructing the button.

  2. Have a shallow parent-child hierarchy (ie a kind of windowing). eg connected elements belong to a parent (a frame or window, which isn’t necessarily visible). A single draw or touched call to the parent will call all of the children, in the correct order, ie you want the background to be drawn first, but checked for touch last. I think that the childrens’ positions should be defined relative to the parent, because of point 3:

  3. Automatically support orientation change. As discussed in the thread above, the easiest way to do this is if the parent is set to snap, eg to the centre of the screen, the top right corner etc. Perhaps the simplest way to do this is to have predefined areas representing zones of the screen, zone.left_half, zone.bottom_third, zone.centre, etc (similar to the way that window-snapping can be set up in Windows7 aero, or on the Mac using something like BetterTouchTool/ BetterSnapTool)

  4. Support scrolling within a frame/window. Perhaps just vertically, eg for lists of files etc?

  5. In terms of saving/ loading interfaces, the class could store the initial table of parameters passed to it (ie it’s start state), and write this with json.encode/ json.decode. Or save it to a tab as Lua code (like the Cider interface builder does).

  6. In terms of performance/ FPS, as far as possible store images of each element, drawing them with mesh/ sprite, and only drawing to the image when the button state changes (or perhaps even caching an image of each possible button state at initiation). This wouldn’t be possible for dynamically changing buttons (eg user text entry fields).

  7. Be openly developed on GitHub so that people can contribute with pull requests etc.

Of course, by this stage it is perhaps not the “light” library you were asking for! I still think though that with clever use of class inheritance/ isomorphism, you can pack a lot of flexibility in to not too enormous a library

hi @yojimbo2000 thanks for the follow up. I’ll read your suggestion carefully later.
To answer your question about my progress: :-(.
I came to the point i wanted to use a real ‘lego bricks’ philosophy. This lead me to the composite pattern. Then i got stuck with designing a generic composite pattern, because i want a smooth update() function that 1/ is easy to understand, 2/ doesnt mind of the order of components 3/ has two-way communication skills and 4/ is easy tu use. And i just cant find the good way to wrap this up into a nice class… The version i posted before is not good.
[edit] i’ve read your suggestions above: very good points, thanks.