New to SODA? Try this WYSIWYG!

SODA is a super great UI library for Codea, made by @yojimbo2000. It’s really something. But it can be hard to get started with.

For the new and/or curious, I’d like to share SODA Designer. With it you can:

  • Interactively design a SODA button, using WYSIWYG controls to customize size, position, color, text color, label, and corner radius.
  • Load a custom background, so that you can design your button against the actual art it will go with.
  • Best of all, once you’ve tweaked your button just how you like it, you can make it into actual code.
  • After you press the save button, inside the project itself you’ll find a tab containing the code that creates that exact same button. Then you can simply copy and paste it into your own projects.

SODA can make even the simplest UI design look slick and professional. You really have to check out what it can do.

You owe it to yourself, to Codea, and to the world. :slight_smile:

(In case it isn’t obvious, this project needs SODA as a dependency to work at all. You can get SODA here, free: https://github.com/Utsira/Soda )


--# Main
--SODA Designer

function setup()
    displayMode(OVERLAY)
    --SODA:
    profiler.init(true)
    Soda.setup()
    --/SODA
    backgroundSprite = readImage("Cargo Bot:Game Area")
    guineaPig = Soda.Button{ title = "placeholder" }
    parameter.text("ButtonTitle", "type in any text", update)
    parameter.number("ButtonWidth", 0.0, 1.0, 0.25, update)
    parameter.number("ButtonHeight", 0.0, 1.0, 0.12, update)
    parameter.number("ButtonX", 0, 1, 0.5, update)
    parameter.number("ButtonY", 0, 1, 0.5, update)
    parameter.color("FillColor", color(208, 125, 136, 156), update)
    parameter.color("TitleColor", color(155, 31, 154, 255), update)
    parameter.number("CornerRadius", 0.0, 50.0, 12.0, update)
    parameter.boolean("Shadow", true, update)
    parameter.text("BackgroundFilename", "Cargo Bot:Game Area", updateBackground)
    parameter.action("save settings to project tab", saveSettingsToTab)
    print("Scroll up parameter list to see more options")
    if newButton ~= nil then
        newButton()
    end
end

function updateBackground()
    if BackgroundFilename ~= "" then
        backgroundSprite = readImage(BackgroundFilename)
    else
        backgroundSprite = nil
    end
end

function update()
    guineaPig.kill = true
    guineaPig = Soda.Button{
		title = ButtonTitle,       
		h = ButtonHeight, w = ButtonWidth, x = ButtonX, y = ButtonY,
		style =  {
			shape = { fill = FillColor, strokeWidth = 1 },
			text = { fill = TitleColor}
		},
		shadow = Shadow,
		shapeArgs = { radius = CornerRadius }
	}
end

function saveSettingsToTab(name, position)
    local dataString = 
    "function newButton()"..
        "\
\\tnewButton = Soda.Button{"..
            "\
\\t\\ttitle = \""..ButtonTitle.."\","..
    "       \
\\t\\th = "..ButtonHeight..", w = "..ButtonWidth..", x = "..ButtonX..", y = "..ButtonY..","..
            "\
\\t\\tstyle =  {"..
                "\
\\t\\t\\tshape = { fill = color"..tostring(FillColor)..", strokeWidth = 1 },"..
                "\
\\t\\t\\ttext = { fill = color"..tostring(TitleColor).."}"..
            "\
\\t\\t},"..
            "\
\\t\\tshadow = "..tostring(Shadow)..","..
            "\
\\t\\tshapeArgs = { radius = "..CornerRadius.." }"..
        "\
\\t}"..   
        "\
\\t--background filename used: "..BackgroundFilename..
    "\
end"
    saveProjectTab("SavedValues",dataString)
    print("Settings saved to tab \"SavedValues\"")
end

function draw()
    --SODA
    pushMatrix()
    Soda.camera()
    drawing()
    popMatrix()
    profiler.draw()
    --/SODA
end

function drawing(breakPoint)
    --SODA
    --in order for gaussian blur to work, do all your drawing here
    if backgroundSprite == nil then
        background(51, 52, 62, 255)
    else
        sprite(backgroundSprite, WIDTH / 2, HEIGHT / 2, WIDTH, HEIGHT)
    end
    Soda.draw(breakPoint)
    --/SODA
end

function touched(touch)
    --SODA
   if Soda.touched(touch) then return end
    --/SODA
end


--MISC SODA STUFF
--user inputs:

function keyboard(key)
    Soda.keyboard(key)
end

function orientationChanged(ori)
    Soda.orientationChanged(ori)
end

--measure performance:

profiler={}

function profiler.init(quiet)    
    profiler.del=0
    profiler.c=0
    profiler.fps=0
    profiler.mem=0
    if not quiet then
        parameter.watch("profiler.fps")
        parameter.watch("profiler.mem")
    end
end

function profiler.draw()
    profiler.del = profiler.del +  DeltaTime
    profiler.c = profiler.c + 1
    if profiler.c==10 then
        profiler.fps=profiler.c/profiler.del
        profiler.del=0
        profiler.c=0
        profiler.mem=collectgarbage("count", 2)
    end
end

Slick! Some suggestions

  • Is the flicker intentional? It seems to do so when I tweak parameters.
  • Multiline strings can be surrounded with [[ like so:
[[
Hello,
World!
]]
  • Multiple variables can be inserted into a string with string.format, is cleaner and faster then multiple concatenations.
  • Maybe you could skip parameters altogether and use Soda as your UI for Soda Designer?

It’s a great piece of code, and it packs a lot of functionality in enough lines to fit in a post. It’ll definitely be useful for people getting started with Soda. If you don’t like my suggestions, feel free to ignore them. I won’t take it personally :).

[I deleted this post because I originally wrote it on mobile and the bullets didn’t format correctly. The whole thing is re-posted below, with proper bullets.]

For markdown lists, you have to put an extra newline before them (fixed my suggestion comment).

...

- 
- 

Since you know so much about Soda, why don’t you help @yojimbo2000 and contribute to to the main Soda repo?

@em2 have you tried doing that from mobile? I did what you say, but on mobile it didn’t work for me.

I literally cut and pasted the same text into this thread from the desktop and it did the formatting correctly.

I mean it, really:

  • I posted the original text from mobile, doing the Markdown formatting by hand.
  • It just showed up as asterisks no matter what I did.
  • I went to the desktop and clicked “edit” to get into the post I’d just made.
  • I coped the text with Command-C.
  • I started a new post.
  • I pasted the text with Command-V.
  • The list automatically formatted itself correctly from the exact same text.

Regarding adding to the repo, I guess I’ve assumed that @yojimbo2000 would request that I add stuff to the repo if he thought it was good enough.

I love your suggestions @em2! I do have answers for many of them though.

  • The flicker happens because I’m killing the button and re-creating it after every adjustment.
  • This is a total kludge I had to do because directly modifying the existing button caused all kinds of weird bugs, as I reported in that other thread.
  • I don’t like it, but the tool still does everything it needs to, so I “shipped it”!
  • I knew about the brackets for multiple lines, but I didn’t know about string.format, I should check that out.
  • I laid the concatenated strings out that weird way for a reason. If you look at the generated code, the concatenation layout mirrors all its tabs and new-lines. This is because SODA configuration parameters, and specifically the style parameters, have a lot of tables and sub-tables, and unless I lay things out visually I get lost in all the brackets.
  • My main concern in my visual layout is to keep separate tables on their own line, so I can see really easily where one ends and the other begins.
  • Using SODA as the UI for SODA Designer is a great idea, and I’d totally do it if the project was an end in itself. It’s actually just a helper tool I wrote for myself to help me compose the UI in a different project. That project is my main focus right now.
  • If you want to try your hand at a SODA-based version of SODA Designer, I totally recommend checking out my other SODA helper called SodaSpec. SODA Designer is nice and visual but it only makes buttons. SodaSpec has no UI but it can make almost all of the components SODA is capable of.

Thanks for your comments!

[Apropos of nothing, on these forums Markdown doesn’t seem to work from mobile devices. Go figure.]

If you have changes to make [to the repo], just fork it and submit a pull request. Then @yojimbo2000 can decide if he wants your changes in the original. You’ve done a lot of great work.
Regarding the bullet lists on mobile, I guess at best performance is patchy because it only works sometimes for me. Maybe you could add that to the bugs section?