Module: Teacup::Layout
- Included in:
- CustomTeacupClass, NSView, NSViewController, NSWindow, NSWindowController, UIView, UIViewController
- Defined in:
- lib/teacup/layout.rb
Overview
Teacup::Layout defines a layout and subview function that can be used to declare and configure the layout of views and the view hierarchy in your application.
This module is included into UIView and UIViewController directly so these functions are available in the places you need them.
In order to use layout() in a UIViewController most effectively you will want to define a stylesheet method that returns a stylesheet.
Class Method Summary collapse
Instance Method Summary collapse
-
#auto(layout_view = top_level_view, layout_subviews = {}, &layout_block) ⇒ Object
Calling this method uses Nick Quaranto’s motion-layout gem to provide ASCII art style access to autolayout.
-
#layout(view_or_class, *teacup_settings, &block) ⇒ Object
Alter the layout of a view.
-
#stylesheet ⇒ Object
Returns a stylesheet to use to style the contents of this controller’s view.
-
#stylesheet=(val) ⇒ Object
Assign a Stylesheet or Stylesheet name (Symbol).
-
#subview(class_or_instance, *args, &block) ⇒ Object
Add a new subview to the view heirarchy.
- #top_level_view ⇒ Object
Class Method Details
.included(base) ⇒ Object
40 41 42 |
# File 'lib/teacup/layout.rb', line 40 def self.included(base) base.extend LayoutClass end |
Instance Method Details
#auto(layout_view = top_level_view, layout_subviews = {}, &layout_block) ⇒ Object
Calling this method uses Nick Quaranto’s motion-layout gem to provide ASCII art style access to autolayout. It assigns all the subviews by stylename, and assigns ‘self.view` as the target view. Beyond that, it’s up to you to implement the layout methods:
auto do
metrics 'margin' => 20
vertical "|-[top]-margin-[bottom]-|"
horizontal "|-margin-[top]-margin-|"
horizontal "|-margin-[bottom]-margin-|"
end
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/teacup/layout.rb', line 251 def auto(layout_view=top_level_view, layout_subviews={}, &layout_block) raise "gem install 'motion-layout'" unless defined? Motion::Layout Teacup.get_styled_subviews(top_level_view).each do |view| if ! layout_subviews[view.stylename.to_s] layout_subviews[view.stylename.to_s] = view end end Motion::Layout.new do |layout| layout.view layout_view layout.subviews layout_subviews layout.instance_eval(&layout_block) end end |
#layout(view_or_class, *teacup_settings, &block) ⇒ Object
Alter the layout of a view
For example, to alter the width and height of a carousel:
Or to layout the carousel in the default style:
You can also use this method with #subview, for example to add a new image to a carousel:
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/teacup/layout.rb', line 129 def layout(view_or_class, *teacup_settings, &block) view = Teacup.to_instance(view_or_class) # prevents the calling of restyle! until we return to this method should_restyle = Teacup.should_restyle_and_block teacup_style = Style.new teacup_settings.each do |setting| case setting when Symbol, String view.stylename = setting when Hash # override settings, but apply them to teacup_style so that it remains # a Teacup::Style object Teacup::merge_defaults(setting, teacup_style, teacup_style) when Enumerable view.style_classes = setting when nil # skip. this is so that helper methods that accept arguments like # stylename can pass those on to this method without having to # introspect the values (just set the default value to `nil`) # # long story short: tests will fail `nil` is not ignore here else raise "The argument #{setting.inspect} is not supported in Teacup::Layout::layout()" end end Teacup.apply_hash view, teacup_style.build(view) # assign the 'teacup_next_responder', which is queried for a stylesheet if # one is not explicitly assigned to the view if view.is_a? Layout view.teacup_next_responder = self end if block_given? superview_chain << view begin # yield will not work if this is defined in the context of the # UIViewController `layout` class method. instance_exec(view, &block) rescue NoMethodError => e NSLog("Exception executing layout(#{view.inspect}) in #{self.inspect} (stylesheet=#{stylesheet})") raise e end superview_chain.pop end if should_restyle Teacup.should_restyle! view.restyle! end view end |
#stylesheet ⇒ Object
Returns a stylesheet to use to style the contents of this controller’s view. You can also assign a stylesheet to #stylesheet=, which will in turn call restyle!.
This method will be queried each time restyle! is called, and also implicitly whenever Teacup needs to draw your layout (currently only at view load time).
81 82 83 84 85 86 87 |
# File 'lib/teacup/layout.rb', line 81 def stylesheet if @stylesheet.is_a? Symbol @stylesheet = Teacup::Stylesheet[@stylesheet] end @stylesheet || self.class.stylesheet end |
#stylesheet=(val) ⇒ Object
Assign a Stylesheet or Stylesheet name (Symbol)
57 58 59 |
# File 'lib/teacup/layout.rb', line 57 def stylesheet= val @stylesheet = val end |
#subview(class_or_instance, *args, &block) ⇒ Object
Add a new subview to the view heirarchy.
By default the subview will be added at the top level of the view heirarchy, though if this function is executed within a block passed to #layout or #subview, then this view will be added as a subview of the instance being layed out by the block.
This is particularly useful when coupled with the UIViewController.heirarchy function that allows you to declare your view heirarchy.
For example, to specify that a controller should contain some labels:
If you need to add a new image at runtime, you can also do that:
226 227 228 229 230 231 232 233 234 |
# File 'lib/teacup/layout.rb', line 226 def subview(class_or_instance, *args, &block) instance = Teacup.to_instance(class_or_instance) (superview_chain.last || top_level_view).addSubview(instance) layout(instance, *args, &block) instance end |
#top_level_view ⇒ Object
267 268 269 |
# File 'lib/teacup/layout.rb', line 267 def top_level_view raise "No default view has been defined for #{self.class}. Implement `top_level_view`." end |