Module: Teacup
- Defined in:
- lib/teacup/handler.rb,
lib/teacup/layout.rb,
lib/teacup/restyle.rb,
lib/teacup/version.rb,
lib/teacup-ios/style.rb,
lib/teacup-osx/style.rb,
lib/teacup/constraint.rb,
lib/teacup/stylesheet.rb,
lib/teacup-ios/handler.rb,
lib/teacup-osx/handler.rb,
lib/teacup/teacup_util.rb,
lib/teacup/teacup_view.rb,
lib/teacup/calculations.rb,
lib/teacup-ios/appearance.rb,
lib/teacup/merge_defaults.rb,
lib/teacup/teacup_controller.rb,
lib/teacup/core_extensions/view_getters.rb,
lib/teacup-osx/style_extensions/autoresize.rb,
lib/teacup/stylesheet_extensions/transform.rb,
lib/teacup-ios/stylesheet_extensions/device.rb,
lib/teacup/stylesheet_extensions/constraints.rb,
lib/teacup-ios/table_view/table_view_delegate.rb,
lib/teacup-ios/stylesheet_extensions/autoresize.rb
Overview
Example:
Teacup::Stylesheet.new :main do
style :root,
# stays centered and grows in height
autoresizingMask: autoresize.flexible_left | autoresize.flexible_right | autoresize.flexible_height
# same, in block form
autoresizingMask: autoresize { flexible_left | flexible_right | flexible_height }
end
Defined Under Namespace
Modules: Controller, ControllerClass, Layout, LayoutClass, TableViewDelegate, View
Classes: Appearance, Autoresize, Constraint, Style, Stylesheet, TransformLayer, TransformView
Constant Summary
collapse
- Priorities =
Some properties need to be assigned before others (size in particular, so that ‘:center_x` can work properly). This hash makes sure the lower priority styles (default priority is 0) get applied before higher ones.
{
frame: 1,
sizeToFit: 2,
size: 2,
width: 2,
height: 2,
center: 3, center_x: 3,
center_y: 3,
}
- VERSION =
'2.2.2'
Class Method Summary
collapse
-
.alias(klass, aliases) ⇒ Object
-
.AppearanceClass ⇒ Object
-
.apply(target, key, value, klass = nil) ⇒ Object
Applies a single style to a target.
-
.apply_hash(target, properties, klass = nil) ⇒ Object
applies a Hash of styles, and converts the frame styles (origin, size, top, left, width, height) into one frame property.
-
.apply_method(target, assign, setter, value) ⇒ Object
-
.calculate(view, dimension, amount) ⇒ Object
-
.convert_constraints(constraints) ⇒ Object
-
.dont_restyle? ⇒ Boolean
-
.handler(klass, *stylenames, &block) ⇒ Object
-
.handlers ⇒ Object
-
.merge_constraints(left, right) ⇒ Object
constraints are a special case because when we merge an array of constraints we need to make sure not to add more than one constraint for a given attribute.
-
.merge_defaults(left, right, target = {}) ⇒ Object
-
.merge_defaults!(left, right) ⇒ Object
modifies left by passing it in as the ‘target`.
-
.should_restyle!(&block) ⇒ Object
-
.should_restyle? ⇒ Boolean
-
.should_restyle_and_block ⇒ Object
-
.to_instance(class_or_instance) ⇒ Object
Class Method Details
.alias(klass, aliases) ⇒ Object
119
120
121
122
123
124
125
126
|
# File 'lib/teacup/handler.rb', line 119
def alias klass, aliases
aliases.each do |style_alias, style_name|
Teacup.handlers[klass][style_alias] = proc { |view, value|
Teacup.apply view, style_name, value
}
end
self
end
|
.AppearanceClass ⇒ Object
19
20
21
|
# File 'lib/teacup-ios/handler.rb', line 19
def AppearanceClass
@appearance_klass ||= UIView.appearance.class
end
|
.apply(target, key, value, klass = nil) ⇒ Object
Applies a single style to a target. Delegates to a teacup handler if one is found.
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
# File 'lib/teacup/handler.rb', line 60
def apply(target, key, value, klass=nil)
if value.is_a? Proc
if value.arity == 1
value = value.call(target)
else
value = target.instance_exec(&value)
end
end
klass ||= target.class
handled = false
klass.ancestors.each do |ancestor|
if Teacup.handlers[ancestor].has_key? key
NSLog "#{ancestor.name} is handling #{key} = #{value.inspect}" if target.respond_to? :debug and target.debug
if Teacup.handlers[ancestor][key].arity == 1
target.instance_exec(value, &Teacup.handlers[ancestor][key])
else
Teacup.handlers[ancestor][key].call(target, value)
end
handled = true
break
end
end
return if handled
if value.is_a? Hash
return Teacup.apply_hash target.send(key), value
end
if key =~ /^set[A-Z]/
assign = nil
setter = key.to_s + ':'
else
assign = key.to_s + '='
setter = 'set' + key.to_s.sub(/^./) {|c| c.capitalize} + ':'
end
Teacup.apply_method(target, assign, setter, value)
end
|
.apply_hash(target, properties, klass = nil) ⇒ Object
applies a Hash of styles, and converts the frame styles (origin, size, top, left, width, height) into one frame property.
For UIAppearance support, the class of the UIView class that is being modified can be passed in
48
49
50
51
52
53
54
55
56
|
# File 'lib/teacup/handler.rb', line 48
def apply_hash(target, properties, klass=nil)
properties.sort do |a, b|
priority_a = Priorities[a[0]]
priority_b = Priorities[b[0]]
priority_a <=> priority_b
end.each do |key, value|
Teacup.apply target, key, value, klass
end
end
|
.apply_method(target, assign, setter, value) ⇒ Object
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# File 'lib/teacup-ios/handler.rb', line 4
def apply_method(target, assign, setter, value)
if assign and target.respond_to?(assign)
NSLog "Setting #{setter} = #{value.inspect}" if target.respond_to? :debug and target.debug
target.send(assign, value)
elsif target.respondsToSelector(setter)
NSLog "Calling target.#{setter}(#{value.inspect})" if target.respond_to? :debug and target.debug
target.send(setter, value)
elsif target.is_a?(self.AppearanceClass)
NSLog "Calling target.#{setter}(#{value.inspect})" if target.respond_to? :debug and target.debug
target.send(setter, value)
else
NSLog "TEACUP WARNING: Can't apply #{setter.inspect}#{assign and " or " + assign.inspect or ""} to #{target.inspect}"
end
end
|
.calculate(view, dimension, amount) ⇒ Object
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
# File 'lib/teacup/calculations.rb', line 3
def calculate(view, dimension, amount)
if amount.is_a? Proc
view.instance_exec(&amount)
elsif amount.is_a?(String) && amount.include?('%')
location = amount.index '%'
offset = amount.slice(location+1, amount.size).gsub(' ', '').to_f
percent = amount.slice(0, location).to_f / 100.0
case dimension
when :width
(view.superview.frame.size.width * percent + offset).round
when :height
(view.superview.frame.size.height * percent + offset).round
else
raise "Unknown dimension #{dimension}"
end
else
amount
end
end
|
.convert_constraints(constraints) ⇒ Object
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
# File 'lib/teacup/merge_defaults.rb', line 61
def convert_constraints(constraints)
if constraints.is_a? Array
constraints.map do |constraint|
convert_constraints(constraint)
end
elsif constraints.is_a? Hash
constraints.map do |sym, relative_to|
convert_constraints(Teacup::Constraint.from_sym(sym, relative_to))
end
elsif constraints.is_a?(Symbol)
Teacup::Constraint.from_sym(constraints)
elsif constraints.is_a?(Teacup::Constraint)
constraints
else
raise "Unsupported constraint: #{constraints.inspect}"
end
end
|
.dont_restyle? ⇒ Boolean
4
5
6
|
# File 'lib/teacup/restyle.rb', line 4
def dont_restyle?
@dont_restyle ||= nil
end
|
.handler(klass, *stylenames, &block) ⇒ Object
108
109
110
111
112
113
114
115
116
117
|
# File 'lib/teacup/handler.rb', line 108
def handler klass, *stylenames, &block
if stylenames.length == 0
raise TypeError.new "No style names assigned in Teacup[#{klass.inspect}]##handler"
else
stylenames.each do |stylename|
Teacup.handlers[klass][stylename] = block
end
end
self
end
|
.handlers ⇒ Object
104
105
106
|
# File 'lib/teacup/handler.rb', line 104
def handlers
@teacup_handlers ||= Hash.new{ |hash,klass| hash[klass] = {} }
end
|
.merge_constraints(left, right) ⇒ Object
constraints are a special case because when we merge an array of constraints we need to make sure not to add more than one constraint for a given attribute
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
# File 'lib/teacup/merge_defaults.rb', line 41
def merge_constraints(left, right)
return right unless left
left = left.map do |constraint|
convert_constraints(constraint)
end.flatten
right = right.map do |constraint|
convert_constraints(constraint)
end.flatten
constrained_attributes = left.map do |constraint|
constraint.attribute
end
additional_constraints = right.reject do |constraint|
constrained_attributes.include?(constraint.attribute)
end
left + additional_constraints
end
|
.merge_defaults(left, right, target = {}) ⇒ Object
Merges two Hashes. This is similar to ‘Hash#merge`, except the values will be merged recursively (aka deep merge) when both values for a key are Hashes, and values for the left argument are preferred over values on the right.
If you pass in a third argument, it will be acted upon directly instead of creating a new Hash. Usually used with ‘merge_defaults!`, which merges values from `right` into `left`.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
# File 'lib/teacup/merge_defaults.rb', line 12
def merge_defaults(left, right, target={})
if target != left
left.each do |key, value|
if target.has_key? key and value.is_a?(Hash) and target[key].is_a?(Hash)
target[key] = Teacup::merge_defaults(target[key], value)
else
if value.is_a?(Hash)
value = Teacup::merge_defaults!({}, value)
end
target[key] = value
end
end
end
right.each do |key, value|
if not target.has_key? key
target[key] = value
elsif value.is_a?(Hash) and left[key].is_a?(Hash)
target[key] = Teacup::merge_defaults(left[key], value, (left==target ? left[key] : {}))
elsif key == :constraints
left[key] = merge_constraints(left[key], value)
end
end
target
end
|
.merge_defaults!(left, right) ⇒ Object
modifies left by passing it in as the ‘target`.
80
81
82
|
# File 'lib/teacup/merge_defaults.rb', line 80
def merge_defaults!(left, right)
Teacup::merge_defaults(left, right, left)
end
|
.should_restyle!(&block) ⇒ Object
18
19
20
21
22
23
24
25
26
27
|
# File 'lib/teacup/restyle.rb', line 18
def should_restyle! &block
if block
_dont_restyle = dont_restyle?
@dont_restyle = nil
yield
@dont_restyle = _dont_restyle
else
@dont_restyle = nil
end
end
|
.should_restyle? ⇒ Boolean
8
9
10
|
# File 'lib/teacup/restyle.rb', line 8
def should_restyle?
return ! self.dont_restyle?
end
|
.should_restyle_and_block ⇒ Object
12
13
14
15
16
|
# File 'lib/teacup/restyle.rb', line 12
def should_restyle_and_block
should_restyle = self.should_restyle?
@dont_restyle = true
return should_restyle
end
|
.to_instance(class_or_instance) ⇒ Object
4
5
6
7
8
9
10
|
# File 'lib/teacup/teacup_util.rb', line 4
def to_instance(class_or_instance)
if class_or_instance.is_a? Class
return class_or_instance.new
else
return class_or_instance
end
end
|