Cider 7

edited August 2013 in General Posts: 1,255


With the impending release of iOS 7, it was time to give Cider a makeover, and since some parts of the control structure were more than a little awkward, it seemed like time to pitch out baby, bath water, & all and just start over.

The Cider 7 controls are more or less done, and I'm now reworking the editor to use these new controls. Expect it all to hit a forum near you in the next few days.

In some ways, this version of Cider has fewer controls than previous releases, but this time the controls have been remodeled to look and behave much more like the native iOS controls in UIKit. Some of the controls also evince different behaviors. For example, in the image above the first group of controls are all Button controls, with only a style parameter bringing different behavior. You can see other example of these style changes in SegmntedControl and TextField. There are other examples not shown here.

The code structure of Cider 7 is also somewhat different, and is designed to be a compromise between UIKit and the old Cider, with a lean toward "whatever is easiest." For example, the previous version of Cider used four coordinates to define the bounding rect of each control. Cider 7 uses position and size, both Vec2, in a way similar to UIKit. However, Cider 7 still let's you define multipart objects like SegmentedControls with semicolon delimited strings -- because it's easy and compact.

There are a lot more variables for colors and other style elements in Cider 7, so you'll find fewer instances of variables pressed into double duty, but you will have to learn new variable names. In general, style elements now follow the names used in UIKit (hilightedTextColor, etc). The default font of all objects has been changed to HelveticaNeue Light (with occasional use of Ultra Light).

One thing you won't currently find is the Picker control from UIKit. Not because it's not possible, but because I don't like it. Though Picker has been significantly cleaned up for iOS 7, it's still a screen space hog. It also falsely implies the size of the list in it's curve. In most instances, I replace Picker with the DropList control shown above, which now has support for both short and lengthy lists.

In Cider 7 for first release

This base class (which would be called Rect if that wasn't taken) returns with a compliment of routines for drawing, styling, and dealing with the geometry of rectangles. Now based on Vec2 position and size.

This base class for controls is now chock full of more variables and constants to help bring consistency to child controls. Though not of great use on its own, you can use it to provide grouping to other controls. In the image above, the white area are Control objects.

Text labels. Nothing to see here. In fact, the Control class can pretty much do this job on its own.

Replaces the old TextButton class. Default style is the frameless sharp edged button introduced for iOS 7 (and yeah, I know slightly rounded corners are back in the latest beta). Styles can give you differences in color and shape, like info buttons, detail buttons, and a highly non-UIKit standard (but fun) round button.

Replaces the older MultiButton control from Cider 1.6 with something that looks and behaves much more like UIKit's UISegmentedControl. The styles here allow this control to also be used in search bars and steppers.

Cleaned up, restyled, and sporting style options that for the most part line up with UIKit examples. Supports icons as endpoints for when you want to get fancy.

The humble light switch returns in iOS7 style. Note that text and sizing are now handled differently on this control with an external label instead of text on the switch detail.

And now, batting in place of Picker... the DropList has what I think is smooth behavior that doesn't destroy your screen layout, plus it scrolls both directions to support lengthy lists. There are some considerations with this control, particularly around draw order and the keyboard. More later.

The old multi-line TextBox is stripped back to a single line here, but styling lets it mimic several UIKit text options. And no, I still haven't made actual editing of text any nicer.

Though it's drawn off in the corner in the image above, this is generally used as a centered "pop up" element. Easy to use with the old semicolon-delimited list, though like other list controls you can manage the contents yourself if you're willing to put in a little work.

A way to group a sub-set of control types in a "settings panel."

Just think of it as another, non-standard Switch that I could bear to kill.

Another non-standard control, but one that's good at packing lots of info into a small space.

And... that's it for the first release. I'm still working on tab bars and navigation bars, so they'll be back soon.

Dials, Doughnuts, and other "display only" elements from Cider 1.6 are taking a hike to a different library.

So... thanks for reading. Any questions?



  • IgnatzIgnatz Mod
    Posts: 5,396

    ^:)^ wow

  • SimeonSimeon Admin Mod
    Posts: 5,782

    Incredible work, @Mark. I also don't like the iOS 7 (or 6) picker control and prefer your version.

  • Posts: 391

    @Mark, this is awesome! I love the ActionSheet and can't wait to use it to replace my popups! In 1.6 I had to make my own popups using multiple textButtons and it took me a while to get it to work correctly since the controls were created in a for loop and the variables used for the popups were based off of index and value of the table of controls I was iterating through. Ended up having to create a global table to store the popup controls otherwise my popup always used the values of the last control in the loop. I can see the ActionSheet making this much easier. Great work!

  • Jmv38Jmv38 Mod
    Posts: 3,297

    Very nice!

  • Posts: 2,820

    Wow! Now that's what I call usable.

  • Posts: 372

    That is Awesome!!!

  • Posts: 437

    Now we can make apps with iOS7 look appeal :)

  • Jmv38Jmv38 Mod
    Posts: 3,297


  • IgnatzIgnatz Mod
    Posts: 5,396

    @Jmv38 - stop drooling 8-}

  • BriarfoxBriarfox Mod
    Posts: 1,542

    @mark looks amazing. Looks like it time to scrap my ui and completly move to cider :)

  • Posts: 666

    Nice job, Mark. Looks like you went with Vec2's, so I'm pretty glad to see that!

  • Jmv38Jmv38 Mod
    Posts: 3,297

    Any ETA on the code?

  • edited August 2013 Posts: 1,255

    Ok, Cider7 "first draft" is up

    CiderControls 7

    Cider7 interface designer

    Why did it take so long between the last post and this one. Well, I rewrote the library... three times. And it all comes down to coordinates.

    Previous Cider users will remember that the root of all controls (if not all evil) was the Frame, whose init looked like this.

    function Frame:init(left, bottom, right, top)
        self.left = left
        self.right = right
        self.bottom = bottom = top

    But that structure, which mimicked older frameworks, was at odds with both the way Ccodea lays out Rects and with the way iOS' UIKit lays out controls. Meaning Cider both chaffed against Codea on one level, and wasn't a good first step toward learning UIKit.

    So when I rewrote the library for Cider7, I went to the base and changed Frame to this

    function Frame:init(pos, size)
        self.pos = pos
        self.size = size

    Where both pos and size were vec2. Internally, this worked well. It made for cleaner code within CiderControls and was a decent (eh, sorta) bridge to the heavily structure-based UIKit. So, there you go.

    Then I tried using it... and I hated it. The problem was that, with few exceptions, I found myself building vec2s for no other purpose than to pass then along. There are some activities that naturally involve the generation and manipulation of vectors but in my experience, and in my trials of the alpha library, that just wasn't true of interface design.

    So the ripping and tearing began, and when it stopped, this is where we landed.

    function Frame:init(x, y, w, h)
        self.x = x
        self.y = y
        self.w = w
        self.h = h

    Elegant? Hardly, but it does make a Frame the structural equivalent of Codea's Rect. If it helps, just think of Frame as a vec4, without the z.

    To support other approaches, Frame is now festooned with convenience methods. You can address frame.x though frame:left() or see what frame.y + frame.h add up to by calling frame:top(). You can also change the location using frame:setPosition(pos), which accepts a vec2, and return a vec2 with frame:position(). In general, I've gone a little further down the road toward Apple's insistence on getters and setters, but not very far.

    It's a compromise library, and I don't expect anyone to love it. However, because I can approach problems pretty much however I'm thinking of them at the moment, it is a fairly easy library to live with.

    And I'm doing something else for the first time: I'm writing documentation. Expect to see that soon.

    This is the first time anyone other than me has seen this code, so expect issues. Let me know where you run into problems, have questions, or just have a better way of doing things. I'd particularly like some suggestions on better ways to deal with modal objects like action sheets and color selectors.


  • BriarfoxBriarfox Mod
    Posts: 1,542

    @mark looks awesome!

  • Posts: 2,054

    @Mark, those look great! Is there any reason that this is locked to Portrait only?

  • edited August 2013 Posts: 1,255

    @JakAttak no reason other than I didn't do the math for landscape.

    The controls will work either way, it's just the designer that's currently locked down.

  • edited August 2013 Posts: 1,255

    Oh, one other thing that's changed in the editor. Previously, controls were sized by dragging the corners. The new version, in fitting with the change in underlying objects, takes a different approach.


    I like the new approach which uses an X and Y box for precise placement, along with an H or W box for sizing along one axis. It's much easier to line up components than before, and to see the effect of sizing on controls. You can stll jab your finger down anywhere in the middle of a control and drag it around freely, the new controls just lend precision.

    Movie coming soon.

  • BriarfoxBriarfox Mod
    Posts: 1,542

    @Mark you guys and your portrait mode! :P

  • Posts: 226

    @Mark, =D>

  • edited August 2013 Posts: 1,255

    Two new controls on the way. First, the TabBar returns in iOS 7ish form


    This uses a format similar to other Cider7 controls. To define this example bar...

        tabs = TabBar("Play;Record;Speak;Add", 0, 500, WIDTH, 80)
        tabs:setIcon(1, "Cargo Bot:Play Solution Icon")
        tabs:setIcon(2, "Cargo Bot:Record Solution Icon")
        tabs:setIcon(3, "Small World:Dialog Icon")
        tabs:setIcon(4, "Space Art:Star")

    Since the TabBar uses tint() to set colors, it works best with icons that are white on a transparent background.

    The next control is a new one: ListView. The ListView presents a scrolling list with the contents of a table.


    ListView looks much like any other control, but also takes a data table as one of its parameters.

        data = {}
        data[1] = {["first"]="Aaron", ["last"]="Aardvark", 
        ["city"]="Ankorage", ["state"]="AK"}
        data[2] = {["first"]="Barbara", ["last"]="Bongo", 
        ["city"]="Baltimore", ["state"]="MA"}
        data[3] = {["first"]="Calvin", ["last"]="Cool", 
        ["city"]="Caron City", ["state"]="NV"}
        data[4] = {["first"]="Donald", ["last"]="Dandruff", 
        ["city"]="Denver", ["state"]="CO"}
        data[5] = {["first"]="Elton", ["last"]="Englebert", 
        ["city"]="Elysium", ["state"]="LEO"}
        data[6] = {["first"]="Finly", ["last"]="Fergle", 
        ["city"]="Fort Worth", ["state"]="TX"}
        lv = ListView("first;last;city;state", 0, 100, WIDTH, 400, data)
        lv.header[1] = "State"
        lv:setColumnAlignment(2, LEFT)
        lv:setColumnAlignment(1, LEFT)
        lv:setColumnWidth(1, 90)
        lv:setColumnWidth(2, 180)

    In the example the first few lines are used to define an example table called "data," but really just about any table should work (warning: tables that contain tables will not display properly -- think of the ListView like a shallow copy). Data is then used in the init for the ListView. The column names in the ListView init define the order in which items will appear in the table. If you don't care, just enter an empty string. Once the ListView is defined, you can change the header text, set column alignment, and change the default column width.

    Note that ListView doesn't actually lose the left most pixel, that was just me cropping the image. Oh, and people of Anchorage, I apologize for the typo in the example.

  • Posts: 666

    Glad you added a ListView, that and a decent textbox are the two major pains for user created controls.

    In Cider2 I did an editable DataGrid - could you consider extending your ListView to allow an editable data grid? All I did was replace the Label with a TextBox when the user touched the cell.

  • Posts: 1,255

    It's a good idea. I'd probably derive the DataGrid control from the ListView and keep the ListView as a simple, row-oriented control.

    And yeah, I keep meaning to work on that TextBox, but... it's a lot to bite off.

  • Posts: 666

    I rewrote the text box 3 times before I got one that I was acceptably happy with for performance. But the code was ABBYSMAL to support.

  • Posts: 1,255

    Cider Controls 7 Release 2
    Includes TabBar and ListView

  • Posts: 2,820

    Woohoo! Great job.

  • Posts: 63

    @Mark question on your drop down list in cider 7, when I start and create one inside cider and add the text directly to the control list and then run it, it works the list drops down and can be scrolled, but when I created a new app so to speak and include the cider controls the drop down list does not drop it just scrolls through the data on the single line. Any ideas where I am going wrong.

  • Posts: 1,255

    @Jazmal Can you show me the init for the DropList?

    One quick note for everyone: I made an elementary slip-up and left some print statements in the code that I had been using as debugs. Do a quick search and cut those lines to improve performance.

    I'll have it cleaned up in the next release.

  • Posts: 355

    nice man, very nice

  • Posts: 63

    dpl1 = DropList('List', 10, 790, 600, 40, test_Clicked)
    dpl1.background = color(255, 255, 255, 255)
    dpl1.highlightColor = color(0, 0, 0, 0)
    dpl1.highlightedTextColor = color(0, 50, 255, 255)

    I think that's what your after @Mark

  • Posts: 63

    @Mark I only found 2 print statements 1 in each file.

  • Posts: 1,255

    Try something like...

    dpl1 = DropList('Item 1;Item 2;Item 3;Item 4', 10, 790, 600, 40, test_Clicked)
  • Posts: 63

    @Mark tried your solution and it worked, messed around with mine with different data and it worked so tried various other stuff and found if I had the drop box not so wide it works. Thanks for your help in this matter. Keep Cider going .......

    Mark did you mention about some documentation for your wonderful Cider ......

    Again thanks for all your hard work making this a handy little app.
    I still say this should be included with Codea samples.

  • Posts: 63

    Also I have found that the line drop down equal the amount of lines in the init part . Any way to alter this so you can set the amount of lines to show.

  • Posts: 1,255

    @Jazmal Changing the value maxHeight should allow you to clip the control. So, for example, if you have a DropList called dpl1 with a dozen items in it, you should be able to use dpl1.maxHeight = 160 to restrict the size of the list to about four items at a time (using the default itemHeight). You'll get the top and bottom dots to show that the list can be scrolled. You can also fiddle with itemHeight, but getting it to look and feel right can be difficult with reduced font / itemHeight sizes.

    Let me know if this works out for you.

  • Posts: 63

    @Mark have tried your maxHeight but nothing changes, I have even went into the cider controls and changed it in there but still nothing changes. I tried to change the h value in the open function and then the box changed size but the top was off the top screen so I could not scroll back up.
    Will still be trying to go through this more over the weekend if I can get some time to thing.

  • Posts: 1,595

    @Mark wow this looks brilliant, I like how the controls are implemented and the way they're initialised as well, it looks professional too!

  • edited August 2013 Posts: 1,255

    @Jazmal Sorry, I should have made this neater. Right now it's a two step process as in this example.

        dropList2 = DropList("Washington;Adams;Jefferson;Madison;Monroe;"..
        "Adams;Jackson;Van Buren;Harrison;Tyler;Polk;Taylor;Fillmore;"..
        500, 550, 180, 40, callback)
        dropList2.maxHeight = 200
  • Posts: 63

    @Mark your a wonderful person and your solution worked perfectly and I can adjust the drop of the box to suit the display. Thanks again.

  • edited August 2013 Posts: 59

    What is Cider?

  • Posts: 63

    Cider is an app that let's you design a graphic user interface, create buttons , lists, icons and then create the code to each item. Cider 7 is the latest version by @Mark.

    Try it and see. No harm in doing that

  • Posts: 63

    Just in case anyone needs to know how to clear a drop box before re populating it with new data.
    dpl1.itemText = {}

  • added this thread to the Wiki.

  • BriarfoxBriarfox Mod
    Posts: 1,542

    @Mark How would you go about setting all buttons with the same settings? I do not like having all the settings code for each button and would like to have one set of settings that apply to each button.

    I was thinking that one way to do this may be to create a table with all created button names. Then a style table with the style for a button. Create a function that loops through the button name table and creates a string with the style settings then loadstring.

    What are your thoughts?

  • Posts: 1,255

    Well, naturally you can have a table of buttons and iterate. Or you could build a group object that held multiple controls and give it a method that set all the parameters in those controls at once.

    In fact, a group object wouldn't be a bad idea.

  • BriarfoxBriarfox Mod
    edited October 2013 Posts: 1,542

    I'd love to pass a table of params to the buttons :) I'm just trying to save time instead of having to re type in code. Just need one set of params :)

  • BriarfoxBriarfox Mod
    Posts: 1,542

    @Mark I've been using transtale to fine to my controls. I build them off 0,0 then use translate to move them. This works well for buttons, however this method does not seem to work on styled text fields. Translate moves the textbox but the title text is not moved, not is the input text. The textbox stays blank and the carriage moves without showing text. If translate is not used then it seems to work fine.

  • BriarfoxBriarfox Mod
    Posts: 1,542

    @Mark It does not appear that texbox uses selected or enabled. It appears to be inherited from Control but i do not see either being set in textbox. Selected is always nil and enabled = false does not disable the control.

    I'm trying to setup tab control for textboxes but I can't figure out how to get the current selected texbox. I can get past the enabled manually.

  • Posts: 1,255

    @Briarfox. I think I can say with some confidence that textfields are a mess. I've been building some apps, and in the process I've made some changes to the library as I've run into bugs and issues. The use of terms like visible, selected, and selectedText should now be more consistent, and there are a couple of new controls including a calendar and some scrolling menus. I'll get it up this week.

  • BriarfoxBriarfox Mod
    Posts: 1,542

    @Mark Thanks. I ended up getting it working, just had to make a few tweaks. I'll hold off on my project until you have a new version of Cider out, that is unless it's relativly unchanged with current params?

  • BriarfoxBriarfox Mod
    Posts: 1,542

    @Mark the translate issue is do to clip() and I'm not sure how to get around it.

Sign In or Register to comment.