teacup v0.3

http://github.com/rubymotion/teacup

This release was focused on fixing some bugs related to how styles are merged, but don't worry, there are a couple exciting new features here, too!

teacup is a DSL that grew out of the #rubymotion channel on irc.freenode.net. It is, along with BubbleWrap, a community project. If you have an idea for it, open an issue, or join us in #teacuprb and see if the idea gains traction. Or better yet, open a pull request!

Teaser: also announcing sweettea today, which brings the features that we are announcing for teacup and makes them alive. Anyone who wondered why sugarcube was written the way it was might "get it" today :-)

New features

Handlers

With the introduction of "Teacup.handler", it is now easy to add your own style shortcuts and aliases. For instance, if you want to alias title: for the UIButton#setTitle(forState:) method, you should write a handler for it. teacup declares a module method Teacup##handler that accepts a class, a style name and a block. When that stylename is applied to an instance of your class (or subclass), the view and value are passed into the block. An example is much clearer:

Teacup.handler UIButton, :title do |view, title|
  view.setTitle(title, forState: UIControlStateNormal)
end

If you ever want to call these programmatically, it's pretty easy:

Teacup.apply my_button_view, :title, "New Title"
Teacup.apply_hash my_button_view, title: => "New Title",
                                  color: :black

Tags are for Xcode

In much the same way that you can find a subview by tag, you can find a subview or subviews by style name.

def MyController < UIViewController
  stylesheet :main

  layout :root do
    subview(UIScrollView, :scrolly) do
      subview(UIButton, :fire_zee_missiles)
    end
  end

  def layoutDidLoad
    self.view.viewWithStylename(:fire_zee_missiles).addTarget(self, action: :fire!, forControlEvents:UIControlEventTouchUpInside)
    # plural works, too:
    self.view.viewsWithStylename(:input)
  end

end

These methods are added to UIView, and they are too long for my taste...

So now we're ready for...

Announcing sweettea!

You could go out and start building your own system of styles, but we already have a reference point with Xcode. When you drag on in UILabel, it comes out with a lot of default values that are not applied when you instantiate one programmatically.

Here are the defaults:

uilabel in xcode

Here is what this looks like in sweettea, using handlers that it adds to teacup.

style :UILabel,
  font: :system.uifont(17),
  numberOfLines: 1,
  minimumFontSize: 10,
  autoshrink: true,
  baseline: :alignbaselines,
  lineBreakMode: :tailtruncation,
  alignment: :left,
  color: :black,
  backgroundColor: :clear

That's nice and terse, reminds us of the Xcode properties, but best of all, you can import the :sweettea stylesheet, and use these styles in your stylesheets!

Teacup::Stylesheet.new :main do
  import :sweettea

  style :header, extends: :UILabel,
    origin: [20, 20],
    size:   [280, 27]

end

And because sweettea is an offshoot of sugarcube, it provides the shortcut to viewWithStylename that I promised.

self.view[:fire_zee_missiles]

This is a very new gem, only UILabel is "done", and it's not even well tested. But if you like it, help me add the Xcode-styled UIKit objects to it, and it will hopefully become an integral part of your toolkit!

sugarcube v0.3

To celebrate all this madness, sugarcube is gaining some factory methods.

These can really be used anywhere, they are not particular to teacup, so they got added to sugarcube rather than sweettea. Doesn't matter much, since sugarcube is required by sweettea.

layout :root do
  subview(UITableview.plain, :mytable) do
    subview(UIButton.rounded, :round_button)
    subview(UIButton.custom, :image_button)
  end
end

fun stuff over, back to teacup

Bug fixes

Merging styles is a MESSY business! We tried a couple ways of fixing the precedence bugs, and finally settled on a special Hash subclass that queries its parent Stylesheet for extends: and imports. It also handles orientation and class styles. Great refactor, thoroughly tested, so have it.

Want to know more?

See the teacup README for more.

Big Thanks! to all the rubymotion developers. We have an amazing group here, and it's been really fun working with some of you on teacup (a smile and a nod to Conrad Irwin and Mark Villacampa). Conrad has promised to "take over" for the next release, so I'm gonna go silent until I hear what he has planned! RubyMotion FTW!