teacup 1.3.4 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +1 -1
- data/Gemfile.lock +3 -3
- data/README.md +1172 -319
- data/Rakefile +8 -1
- data/app/app_delegate.rb +1 -1
- data/app/controllers/appearance_controller.rb +13 -0
- data/app/controllers/landscape_only_controller.rb +1 -1
- data/app/controllers/{first_controller.rb → main_controller.rb} +4 -3
- data/app/controllers/motion_layout_controller.rb +22 -0
- data/app/styles/appearance.rb +24 -0
- data/app/styles/main_styles.rb +8 -6
- data/app/views/custom_view.rb +1 -0
- data/lib/teacup/calculations.rb +2 -2
- data/lib/teacup/{z_core_extensions → core_extensions}/ca_layer.rb +0 -0
- data/lib/teacup/core_extensions/view_getters.rb +61 -0
- data/lib/teacup/handler.rb +14 -14
- data/lib/teacup/layout.rb +94 -17
- data/lib/teacup/stylesheet.rb +61 -26
- data/lib/teacup/stylesheet_extensions/transform.rb +88 -0
- data/lib/teacup/teacup_controller.rb +122 -0
- data/lib/teacup/teacup_util.rb +12 -7
- data/lib/teacup/teacup_view.rb +329 -0
- data/lib/teacup/version.rb +1 -1
- data/lib/teacup-ios/appearance.rb +96 -0
- data/lib/teacup-ios/core_extensions/teacup_handlers.rb +183 -0
- data/lib/teacup-ios/core_extensions/ui_view.rb +30 -0
- data/lib/teacup-ios/core_extensions/ui_view_controller.rb +110 -0
- data/lib/{dummy.rb → teacup-ios/dummy.rb} +2 -6
- data/lib/teacup-ios/handler.rb +23 -0
- data/lib/{teacup → teacup-ios}/style.rb +9 -10
- data/lib/teacup-ios/stylesheet_extensions/autoresize.rb +169 -0
- data/lib/{teacup/stylesheet_extensions/geometry.rb → teacup-ios/stylesheet_extensions/device.rb} +0 -0
- data/lib/teacup-osx/core_extensions/ns_view.rb +39 -0
- data/lib/teacup-osx/core_extensions/ns_view_controller.rb +21 -0
- data/lib/teacup-osx/core_extensions/ns_window.rb +39 -0
- data/lib/teacup-osx/core_extensions/ns_window_controller.rb +29 -0
- data/lib/{teacup/z_core_extensions/z_handlers.rb → teacup-osx/core_extensions/teacup_handlers.rb} +30 -47
- data/lib/teacup-osx/dummy.rb +80 -0
- data/lib/teacup-osx/handler.rb +16 -0
- data/lib/teacup-osx/style.rb +83 -0
- data/lib/teacup-osx/style_extensions/autoresize.rb +169 -0
- data/lib/teacup.rb +12 -11
- data/samples/Tweets/Gemfile +4 -0
- data/samples/Tweets/Gemfile.lock +16 -0
- data/samples/Tweets/README +7 -0
- data/samples/Tweets/Rakefile +9 -0
- data/samples/Tweets/app/app_delegate.rb +18 -0
- data/samples/Tweets/app/data_parser.rb +10 -0
- data/samples/Tweets/app/json_parser.rb +12 -0
- data/samples/Tweets/app/main_window.rb +99 -0
- data/samples/Tweets/app/menu.rb +108 -0
- data/samples/Tweets/app/stylesheet.rb +21 -0
- data/samples/Tweets/app/tweet.rb +11 -0
- data/samples/Tweets/resources/Credits.rtf +29 -0
- data/samples/Tweets/spec/main_spec.rb +9 -0
- data/samples/teacup-osx/.gitignore +1 -0
- data/samples/teacup-osx/Gemfile +4 -0
- data/samples/teacup-osx/Gemfile.lock +16 -0
- data/samples/teacup-osx/Rakefile +9 -0
- data/samples/teacup-osx/app/app_delegate.rb +23 -0
- data/samples/teacup-osx/app/controller.rb +11 -0
- data/samples/teacup-osx/app/menu.rb +108 -0
- data/samples/teacup-osx/app/window.rb +12 -0
- data/samples/teacup-osx/resources/Credits.rtf +29 -0
- data/samples/teacup-osx/resources/teacup.png +0 -0
- data/samples/teacup-osx/spec/main_spec.rb +9 -0
- data/spec/ios/appearance_spec.rb +18 -0
- data/spec/{calculations_spec.rb → ios/calculations_spec.rb} +0 -0
- data/spec/{constraints_spec.rb → ios/constraints_spec.rb} +0 -0
- data/spec/{custom_class_spec.rb → ios/custom_class_spec.rb} +0 -0
- data/spec/{gradient_spec.rb → ios/gradient_spec.rb} +1 -1
- data/spec/ios/layout_module_spec.rb +54 -0
- data/spec/ios/layout_spec.rb +50 -0
- data/spec/{main_spec.rb → ios/main_spec.rb} +52 -13
- data/spec/ios/motion_layout_spec.rb +44 -0
- data/spec/{present_modal_spec.rb → ios/present_modal_spec.rb} +0 -0
- data/spec/{style_spec.rb → ios/style_spec.rb} +1 -1
- data/spec/ios/stylesheet_extensions/autoresize_spec.rb +50 -0
- data/spec/{stylesheet_spec.rb → ios/stylesheet_spec.rb} +12 -0
- data/spec/{ui_view_getters_spec.rb → ios/ui_view_getters_spec.rb} +0 -0
- data/spec/{uiswitch_spec.rb → ios/uiswitch_spec.rb} +0 -0
- data/spec/{view_spec.rb → ios/view_spec.rb} +23 -2
- metadata +85 -35
- data/lib/teacup/stylesheet_extensions/autoresize.rb +0 -39
- data/lib/teacup/stylesheet_extensions/rotation.rb +0 -37
- data/lib/teacup/z_core_extensions/ui_view.rb +0 -262
- data/lib/teacup/z_core_extensions/ui_view_controller.rb +0 -263
- data/lib/teacup/z_core_extensions/ui_view_getters.rb +0 -58
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
##|
|
|
2
|
+
##| UIView.frame
|
|
3
|
+
##|
|
|
4
|
+
Teacup.handler UIView, :left, :x do |target, x|
|
|
5
|
+
f = target.frame
|
|
6
|
+
f.origin.x = Teacup::calculate(target, :width, x)
|
|
7
|
+
target.frame = f
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
Teacup.handler UIView, :right do |target, r|
|
|
11
|
+
f = target.frame
|
|
12
|
+
f.origin.x = Teacup::calculate(target, :width, r) - f.size.width
|
|
13
|
+
target.frame = f
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
Teacup.handler UIView, :center_x, :middle_x do |target, x|
|
|
17
|
+
c = target.center
|
|
18
|
+
c.x = Teacup::calculate(target, :width, x)
|
|
19
|
+
target.center = c
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
Teacup.handler UIView, :top, :y do |target, y|
|
|
23
|
+
f = target.frame
|
|
24
|
+
f.origin.y = Teacup::calculate(target, :height, y)
|
|
25
|
+
target.frame = f
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
Teacup.handler UIView, :bottom do |target, b|
|
|
29
|
+
f = target.frame
|
|
30
|
+
f.origin.y = Teacup::calculate(target, :height, b) - f.size.height
|
|
31
|
+
target.frame = f
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
Teacup.handler UIView, :center_y, :middle_y do |target, y|
|
|
35
|
+
c = target.center
|
|
36
|
+
c.y = Teacup::calculate(target, :height, y)
|
|
37
|
+
target.center = c
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
Teacup.handler UIView, :width do |target, w|
|
|
41
|
+
f = target.frame
|
|
42
|
+
f.size.width = Teacup::calculate(target, :width, w)
|
|
43
|
+
target.frame = f
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
Teacup.handler UIView, :height do |target, h|
|
|
47
|
+
f = target.frame
|
|
48
|
+
f.size.height = Teacup::calculate(target, :height, h)
|
|
49
|
+
target.frame = f
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
Teacup.handler UIView, :size do |target, size|
|
|
53
|
+
f = target.frame
|
|
54
|
+
size_x = Teacup::calculate(target, :width, size[0])
|
|
55
|
+
size_y = Teacup::calculate(target, :height, size[1])
|
|
56
|
+
f.size = [size_x, size_y]
|
|
57
|
+
target.frame = f
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
Teacup.handler UIView, :origin do |target, origin|
|
|
61
|
+
f = target.frame
|
|
62
|
+
origin_x = Teacup::calculate(target, :width, origin[0])
|
|
63
|
+
origin_y = Teacup::calculate(target, :height, origin[1])
|
|
64
|
+
f.origin = [origin_x, origin_y]
|
|
65
|
+
target.frame = f
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
Teacup.handler UIView, :center do |target, center|
|
|
69
|
+
center_x = Teacup::calculate(target, :width, center[0])
|
|
70
|
+
center_y = Teacup::calculate(target, :height, center[1])
|
|
71
|
+
target.center = [center_x, center_y]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
Teacup.handler UIView, :size do |target, size|
|
|
75
|
+
# odd... if I changed these to .is_a?, weird errors happen. Use ===
|
|
76
|
+
if Symbol === size && size == :full
|
|
77
|
+
if target.superview
|
|
78
|
+
size = target.superview.bounds.size
|
|
79
|
+
else
|
|
80
|
+
size = target.frame.size
|
|
81
|
+
end
|
|
82
|
+
elsif Array === size
|
|
83
|
+
size = [Teacup::calculate(target, :width, size[0]), Teacup::calculate(target, :height, size[1])]
|
|
84
|
+
end
|
|
85
|
+
f = target.frame
|
|
86
|
+
f.size = size
|
|
87
|
+
target.frame = f
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
Teacup.handler UIView, :frame do |target, frame|
|
|
91
|
+
# odd... if I changed these to .is_a?, weird errors happen. Use ===
|
|
92
|
+
if Symbol === frame && frame == :full
|
|
93
|
+
if target.superview
|
|
94
|
+
frame = target.superview.bounds
|
|
95
|
+
else
|
|
96
|
+
frame = target.frame
|
|
97
|
+
end
|
|
98
|
+
elsif Array === frame && frame.length == 4
|
|
99
|
+
frame = [
|
|
100
|
+
[Teacup::calculate(target, :width, frame[0]), Teacup::calculate(target, :height, frame[1])],
|
|
101
|
+
[Teacup::calculate(target, :width, frame[2]), Teacup::calculate(target, :height, frame[3])]
|
|
102
|
+
]
|
|
103
|
+
elsif (Array === frame && frame.length == 2) || CGRect === frame
|
|
104
|
+
frame = [
|
|
105
|
+
[Teacup::calculate(target, :width, frame[0][0]), Teacup::calculate(target, :height, frame[0][1])],
|
|
106
|
+
[Teacup::calculate(target, :width, frame[1][0]), Teacup::calculate(target, :height, frame[1][1])]
|
|
107
|
+
]
|
|
108
|
+
end
|
|
109
|
+
target.frame = frame
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
Teacup.handler UIView, :gradient do |target, gradient|
|
|
113
|
+
gradient_layer = target.instance_variable_get(:@teacup_gradient_layer) || begin
|
|
114
|
+
gradient_layer = CAGradientLayer.layer
|
|
115
|
+
gradient_layer.frame = target.bounds
|
|
116
|
+
target.layer.insertSublayer(gradient_layer, atIndex:0)
|
|
117
|
+
gradient_layer
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
gradient.each do |key, value|
|
|
121
|
+
case key.to_s
|
|
122
|
+
when 'colors'
|
|
123
|
+
colors = [value].flatten.collect { |color| color.is_a?(UIColor) ? color.CGColor : color }
|
|
124
|
+
gradient_layer.colors = colors
|
|
125
|
+
else
|
|
126
|
+
gradient_layer.send("#{key}=", value)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
target.instance_variable_set(:@teacup_gradient_layer, gradient_layer)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
##|
|
|
134
|
+
##| UIButton
|
|
135
|
+
##|
|
|
136
|
+
Teacup.handler UIButton, :title do |target, title|
|
|
137
|
+
target.setTitle(title, forState: UIControlStateNormal)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
Teacup.handler UIButton, :image do |target, image|
|
|
142
|
+
target.setImage(image, forState: UIControlStateNormal)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
Teacup.handler UIButton, :backgroundImage do |target, background_image|
|
|
147
|
+
target.setBackgroundImage(background_image, forState: UIControlStateNormal)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
Teacup.handler UIButton, :titleColor do |target, color|
|
|
152
|
+
target.setTitleColor(color, forState: UIControlStateNormal)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
Teacup.handler UIButton, :titleFont, :font do |target, font|
|
|
157
|
+
target.titleLabel.font = font
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
##|
|
|
162
|
+
##| UINavigationBar
|
|
163
|
+
##|
|
|
164
|
+
Teacup.handler UINavigationBar, :backgroundImage do |styles|
|
|
165
|
+
if styles.is_a?(UIImage)
|
|
166
|
+
styles = { portrait: styles }
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
styles.each do |metric, image|
|
|
170
|
+
case metric
|
|
171
|
+
when UIBarMetricsDefault, :portrait
|
|
172
|
+
self.setBackgroundImage(image && image.uiimage, forBarMetrics:UIBarMetricsDefault)
|
|
173
|
+
when UIBarMetricsLandscapePhone, :landscape
|
|
174
|
+
self.setBackgroundImage(image && image.uiimage, forBarMetrics:UIBarMetricsLandscapePhone)
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# this handler lyooks redundant, but without it Teacup would treat `attrs` as a
|
|
180
|
+
# stylable-property (the 'nested styling' feature)
|
|
181
|
+
Teacup.handler UINavigationBar, :titleTextAttributes do |view, attrs|
|
|
182
|
+
view.titleTextAttributes = attrs
|
|
183
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Teacup's UIView extensions defines some utility functions for UIView that
|
|
2
|
+
# enable a lot of the magic for Teacup::Layout.
|
|
3
|
+
#
|
|
4
|
+
# Users of teacup should be able to ignore the contents of this file for
|
|
5
|
+
# the most part.
|
|
6
|
+
class UIView
|
|
7
|
+
include Teacup::Layout
|
|
8
|
+
include Teacup::View
|
|
9
|
+
|
|
10
|
+
def teacup_animation(options)
|
|
11
|
+
UIView.beginAnimations(nil, context: nil)
|
|
12
|
+
UIView.setAnimationDuration(options[:duration]) if options.key?(:duration)
|
|
13
|
+
UIView.setAnimationCurve(options[:curve]) if options.key?(:curve)
|
|
14
|
+
UIView.setAnimationDelay(options[:delay]) if options.key?(:delay)
|
|
15
|
+
yield
|
|
16
|
+
UIView.commitAnimations
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def style(properties)
|
|
20
|
+
super
|
|
21
|
+
|
|
22
|
+
self.setNeedsDisplay
|
|
23
|
+
self.setNeedsLayout
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def top_level_view
|
|
27
|
+
self
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
class UIViewController
|
|
2
|
+
include Teacup::Layout
|
|
3
|
+
include Teacup::Controller
|
|
4
|
+
|
|
5
|
+
def viewDidLoad
|
|
6
|
+
teacupDidLoad
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# This method *used* to be useful for the `shouldAutorotateToOrientation`
|
|
10
|
+
# method, but the iOS 6 update deprecates that method. Instead, use the
|
|
11
|
+
# `supportedInterfaceOrientations` and return `autorotateMask`.
|
|
12
|
+
def autorotateToOrientation(orientation)
|
|
13
|
+
if view.stylesheet and view.stylesheet.is_a?(Teacup::Stylesheet) and view.stylename
|
|
14
|
+
properties = view.stylesheet.query(view.stylename, self, orientation)
|
|
15
|
+
|
|
16
|
+
# check for orientation-specific properties
|
|
17
|
+
case orientation
|
|
18
|
+
when UIInterfaceOrientationPortrait
|
|
19
|
+
# portrait is "on" by default, must be turned off explicitly
|
|
20
|
+
if properties.supports?(:portrait) == nil and properties.supports?(:upside_up) == nil
|
|
21
|
+
return true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
return (properties.supports?(:portrait) or properties.supports?(:upside_up))
|
|
25
|
+
when UIInterfaceOrientationPortraitUpsideDown
|
|
26
|
+
if UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPhone
|
|
27
|
+
# iphone must have an explicit upside-down style, otherwise this returns
|
|
28
|
+
# false
|
|
29
|
+
return properties.supports?(:upside_down)
|
|
30
|
+
else
|
|
31
|
+
# ipad can just have a portrait style
|
|
32
|
+
return (properties.supports?(:portrait) or properties.supports?(:upside_down))
|
|
33
|
+
end
|
|
34
|
+
when UIInterfaceOrientationLandscapeLeft
|
|
35
|
+
return (properties.supports?(:landscape) or properties.supports?(:landscape_left))
|
|
36
|
+
when UIInterfaceOrientationLandscapeRight
|
|
37
|
+
return (properties.supports?(:landscape) or properties.supports?(:landscape_right))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
return false
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# returns the system default
|
|
44
|
+
if device == UIUserInterfaceIdiomPhone
|
|
45
|
+
return orientation != UIInterfaceOrientationPortraitUpsideDown
|
|
46
|
+
else
|
|
47
|
+
return true
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# You can use this method in `supportedInterfaceOrientations`, and it will
|
|
52
|
+
# query the stylesheet for the supported orientations, based on what
|
|
53
|
+
# orientations are defined. At a minimum, to opt-in to this feature, you'll
|
|
54
|
+
# need to define styles like `style :root, landscape: true`
|
|
55
|
+
def autorotateMask
|
|
56
|
+
device = UIDevice.currentDevice.userInterfaceIdiom
|
|
57
|
+
if view.stylesheet and view.stylesheet.is_a?(Teacup::Stylesheet) and view.stylename
|
|
58
|
+
properties = view.stylesheet.query(view.stylename, self, orientation)
|
|
59
|
+
|
|
60
|
+
orientations = 0
|
|
61
|
+
if properties.supports?(:portrait) or properties.supports?(:upside_up)
|
|
62
|
+
orientations |= UIInterfaceOrientationPortrait
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
if device == UIUserInterfaceIdiomPhone
|
|
66
|
+
# :portrait does not imply upside_down on the iphone
|
|
67
|
+
if properties.supports?(:upside_down)
|
|
68
|
+
orientations |= UIInterfaceOrientationPortraitUpsideDown
|
|
69
|
+
end
|
|
70
|
+
else
|
|
71
|
+
# but does on the ipad
|
|
72
|
+
if properties.supports?(:portrait) or properties.supports?(:upside_down)
|
|
73
|
+
orientations |= UIInterfaceOrientationPortraitUpsideDown
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
if properties.supports?(:landscape) or properties.supports?(:landscape_left)
|
|
78
|
+
orientations |= UIInterfaceOrientationLandscapeLeft
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
if properties.supports?(:landscape) or properties.supports?(:landscape_right)
|
|
82
|
+
orientations |= UIInterfaceOrientationLandscapeRight
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
if orientations == 0
|
|
86
|
+
orientations |= UIInterfaceOrientationPortrait
|
|
87
|
+
end
|
|
88
|
+
return orientations
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# returns the system default
|
|
92
|
+
if device == UIUserInterfaceIdiomPhone
|
|
93
|
+
return UIInterfaceOrientationMaskAllButUpsideDown
|
|
94
|
+
else
|
|
95
|
+
return UIInterfaceOrientationMaskAll
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# restyles the view! be careful about putting styles in your stylesheet that
|
|
100
|
+
# you change in your controller. anything that might change over time should
|
|
101
|
+
# be applied in your controller using `style`
|
|
102
|
+
def willAnimateRotationToInterfaceOrientation(orientation, duration:duration)
|
|
103
|
+
view.restyle!(orientation)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def top_level_view
|
|
107
|
+
view
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
end
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
class TeacupDummy
|
|
2
|
-
def anyMethodName
|
|
3
|
-
@anyobject.type = nil
|
|
4
|
-
end
|
|
5
|
-
end
|
|
6
|
-
|
|
7
1
|
class DummyView < UIView
|
|
8
2
|
private
|
|
9
3
|
def dummy
|
|
@@ -11,6 +5,8 @@ private
|
|
|
11
5
|
setOpaque(nil)
|
|
12
6
|
setClipsToBounds(nil)
|
|
13
7
|
setUserInteractionEnabled(nil)
|
|
8
|
+
UIView.appearanceWhenContainedIn(UIView, nil)
|
|
9
|
+
UIView.appearance
|
|
14
10
|
end
|
|
15
11
|
end
|
|
16
12
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Teacup
|
|
2
|
+
module_function
|
|
3
|
+
|
|
4
|
+
def apply_method(target, assign, setter, value)
|
|
5
|
+
if assign and target.respond_to?(assign)
|
|
6
|
+
NSLog "Setting #{key} = #{value.inspect}" if target.respond_to? :debug and target.debug
|
|
7
|
+
target.send(assign, value)
|
|
8
|
+
elsif target.respondsToSelector(setter)
|
|
9
|
+
NSLog "Calling target.#{setter}(#{value.inspect})" if target.respond_to? :debug and target.debug
|
|
10
|
+
target.send(setter, value)
|
|
11
|
+
elsif target.is_a?(self.AppearanceClass)
|
|
12
|
+
NSLog "Calling target.#{setter}(#{value.inspect})" if target.respond_to? :debug and target.debug
|
|
13
|
+
target.send(setter, value)
|
|
14
|
+
else
|
|
15
|
+
NSLog "TEACUP WARNING: Can't apply #{setter.inspect}#{assign and " or " + assign.inspect or ""} to #{target.inspect}"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def AppearanceClass
|
|
20
|
+
@appearance_klass ||= UIView.appearance.class
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
@@ -49,13 +49,11 @@ module Teacup
|
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
# first, move orientation settings into properties "base" level.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
Teacup::merge_defaults override, properties, properties
|
|
58
|
-
end
|
|
52
|
+
Overrides[orientation].each do |orientation_key|
|
|
53
|
+
if override = self[orientation_key]
|
|
54
|
+
# override is first, so it takes precedence
|
|
55
|
+
if override.is_a? Hash
|
|
56
|
+
Teacup::merge_defaults override, properties, properties
|
|
59
57
|
end
|
|
60
58
|
end
|
|
61
59
|
end
|
|
@@ -68,8 +66,9 @@ module Teacup
|
|
|
68
66
|
properties.delete(orientation_key)
|
|
69
67
|
end
|
|
70
68
|
|
|
71
|
-
# now we can merge extends, and
|
|
72
|
-
# through the same process that we just finished on the
|
|
69
|
+
# now we can merge extends, and imported_stylesheets. before merging,
|
|
70
|
+
# these will go through the same process that we just finished on the
|
|
71
|
+
# local style
|
|
73
72
|
if stylesheet && stylesheet.is_a?(Teacup::Stylesheet)
|
|
74
73
|
stylesheet.imported_stylesheets.reverse.each do |stylesheet|
|
|
75
74
|
imported_properties = stylesheet.query(self.stylename, target, rotation_orientation, seen)
|
|
@@ -104,7 +103,7 @@ module Teacup
|
|
|
104
103
|
end
|
|
105
104
|
end
|
|
106
105
|
|
|
107
|
-
properties
|
|
106
|
+
return properties
|
|
108
107
|
end
|
|
109
108
|
|
|
110
109
|
end
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Example:
|
|
2
|
+
# Teacup::Stylesheet.new :main do
|
|
3
|
+
# style :root,
|
|
4
|
+
# # stays centered and grows in height
|
|
5
|
+
# autoresizingMask: autoresize.flexible_left | autoresize.flexible_right | autoresize.flexible_height
|
|
6
|
+
# # same, in block form
|
|
7
|
+
# autoresizingMask: autoresize { flexible_left | flexible_right | flexible_height }
|
|
8
|
+
# end
|
|
9
|
+
module Teacup
|
|
10
|
+
class Stylesheet
|
|
11
|
+
|
|
12
|
+
def autoresize &block
|
|
13
|
+
@@autoresize ||= Autoresize.new
|
|
14
|
+
if block
|
|
15
|
+
return @@autoresize.instance_exec &block
|
|
16
|
+
else
|
|
17
|
+
return @@autoresize
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
##|
|
|
22
|
+
##| DEPRECATED
|
|
23
|
+
##|
|
|
24
|
+
|
|
25
|
+
def flexible_left
|
|
26
|
+
NSLog("The Stylesheet method `flexible_left` is deprecated, use `autoresize.flexible_left` instead")
|
|
27
|
+
UIViewAutoresizingFlexibleLeftMargin
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def flexible_width
|
|
31
|
+
NSLog("The Stylesheet method `flexible_width` is deprecated, use `autoresize.flexible_width` instead")
|
|
32
|
+
UIViewAutoresizingFlexibleWidth
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def flexible_right
|
|
36
|
+
NSLog("The Stylesheet method `flexible_right` is deprecated, use `autoresize.flexible_right` instead")
|
|
37
|
+
UIViewAutoresizingFlexibleRightMargin
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def flexible_top
|
|
41
|
+
NSLog("The Stylesheet method `flexible_top` is deprecated, use `autoresize.flexible_top` instead")
|
|
42
|
+
UIViewAutoresizingFlexibleTopMargin
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def flexible_height
|
|
46
|
+
NSLog("The Stylesheet method `flexible_height` is deprecated, use `autoresize.flexible_height` instead")
|
|
47
|
+
UIViewAutoresizingFlexibleHeight
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def flexible_bottom
|
|
51
|
+
NSLog("The Stylesheet method `flexible_bottom` is deprecated, use `autoresize.flexible_bottom` instead")
|
|
52
|
+
UIViewAutoresizingFlexibleBottomMargin
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
class Autoresize
|
|
58
|
+
|
|
59
|
+
def none
|
|
60
|
+
UIViewAutoresizingNone
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
##|
|
|
64
|
+
##| FLEXIBLE
|
|
65
|
+
##|
|
|
66
|
+
|
|
67
|
+
def flexible_left
|
|
68
|
+
UIViewAutoresizingFlexibleLeftMargin
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def flexible_width
|
|
72
|
+
UIViewAutoresizingFlexibleWidth
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def flexible_right
|
|
76
|
+
UIViewAutoresizingFlexibleRightMargin
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def flexible_top
|
|
80
|
+
UIViewAutoresizingFlexibleTopMargin
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def flexible_height
|
|
84
|
+
UIViewAutoresizingFlexibleHeight
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def flexible_bottom
|
|
88
|
+
UIViewAutoresizingFlexibleBottomMargin
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
##|
|
|
92
|
+
##| FILL
|
|
93
|
+
##|
|
|
94
|
+
|
|
95
|
+
def fill
|
|
96
|
+
flexible_width | flexible_height
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def fill_top
|
|
100
|
+
flexible_width | flexible_bottom
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def fill_bottom
|
|
104
|
+
flexible_width | flexible_top
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def fill_left
|
|
108
|
+
flexible_height | flexible_right
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def fill_right
|
|
112
|
+
flexible_height | flexible_left
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
##|
|
|
116
|
+
##| FIXED
|
|
117
|
+
##|
|
|
118
|
+
|
|
119
|
+
def fixed_top_left
|
|
120
|
+
flexible_right | flexible_bottom
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def fixed_top_middle
|
|
124
|
+
flexible_left | flexible_right | flexible_bottom
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def fixed_top_right
|
|
128
|
+
flexible_left | flexible_bottom
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def fixed_middle_left
|
|
132
|
+
flexible_top | flexible_bottom | flexible_right
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def fixed_middle
|
|
136
|
+
flexible_top | flexible_bottom | flexible_left | flexible_right
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def fixed_middle_right
|
|
140
|
+
flexible_top | flexible_bottom | flexible_left
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def fixed_bottom_left
|
|
144
|
+
flexible_right | flexible_top
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def fixed_bottom_middle
|
|
148
|
+
flexible_left | flexible_right | flexible_top
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def fixed_bottom_right
|
|
152
|
+
flexible_left | flexible_top
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
##|
|
|
156
|
+
##| FLOAT
|
|
157
|
+
##|
|
|
158
|
+
|
|
159
|
+
def float_horizontal
|
|
160
|
+
flexible_left | flexible_right
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def float_vertical
|
|
164
|
+
flexible_top | flexible_bottom
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
end
|
data/lib/{teacup/stylesheet_extensions/geometry.rb → teacup-ios/stylesheet_extensions/device.rb}
RENAMED
|
File without changes
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Teacup's NSView extensions defines some utility functions for NSView that
|
|
2
|
+
# enable a lot of the magic for Teacup::Layout.
|
|
3
|
+
#
|
|
4
|
+
# Users of teacup should be able to ignore the contents of this file for
|
|
5
|
+
# the most part.
|
|
6
|
+
class NSView
|
|
7
|
+
include Teacup::Layout
|
|
8
|
+
include Teacup::View
|
|
9
|
+
|
|
10
|
+
class << NSView
|
|
11
|
+
attr :teacup_is_animating
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def teacup_animation(options)
|
|
15
|
+
NSAnimationContext.beginGrouping
|
|
16
|
+
NSAnimationContext.currentContext.setDuration(options[:duration]) if options.key?(:duration)
|
|
17
|
+
NSAnimationContext.currentContext.setTimingFunction(options[:timing]) if options.key?(:timing)
|
|
18
|
+
NSView.teacup_is_animating = true
|
|
19
|
+
yield
|
|
20
|
+
NSView.teacup_is_animating = false
|
|
21
|
+
NSAnimationContext.endGrouping
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def apply_style_properties(properties)
|
|
25
|
+
Teacup.apply_hash((NSView.teacup_is_animating ? self.animator : self), properties)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def style(properties)
|
|
29
|
+
super
|
|
30
|
+
|
|
31
|
+
self.setNeedsDisplay(true)
|
|
32
|
+
self.setNeedsLayout(true)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def top_level_view
|
|
36
|
+
self
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
class NSViewController
|
|
2
|
+
include Teacup::Layout
|
|
3
|
+
include Teacup::Controller
|
|
4
|
+
|
|
5
|
+
alias _teacup_loadview loadView
|
|
6
|
+
def loadView
|
|
7
|
+
if nibName and nibBundle
|
|
8
|
+
_teacup_loadview
|
|
9
|
+
else
|
|
10
|
+
self.view = NSView.new
|
|
11
|
+
self.view.autoresizingMask = NSViewWidthSizable|NSViewHeightSizable
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
teacupDidLoad
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def top_level_view
|
|
18
|
+
view
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Teacup's NSWindow extensions defines some utility functions for NSWindow that
|
|
2
|
+
# enable a lot of the magic for Teacup::Layout.
|
|
3
|
+
#
|
|
4
|
+
# Users of teacup should be able to ignore the contents of this file for the
|
|
5
|
+
# most part.
|
|
6
|
+
class NSWindow
|
|
7
|
+
include Teacup::Layout
|
|
8
|
+
include Teacup::View
|
|
9
|
+
|
|
10
|
+
class << NSWindow
|
|
11
|
+
attr :teacup_is_animating
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def teacup_animation(options)
|
|
15
|
+
NSAnimationContext.beginGrouping
|
|
16
|
+
NSAnimationContext.currentContext.setDuration(options[:duration]) if options.key?(:duration)
|
|
17
|
+
NSAnimationContext.currentContext.setTimingFunction(options[:timing]) if options.key?(:timing)
|
|
18
|
+
NSWindow.teacup_is_animating = true
|
|
19
|
+
yield
|
|
20
|
+
NSWindow.teacup_is_animating = false
|
|
21
|
+
NSAnimationContext.endGrouping
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def apply_style_properties(properties)
|
|
25
|
+
Teacup.apply_hash((NSWindow.teacup_is_animating ? self.animator : self), properties)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def style(properties)
|
|
29
|
+
super
|
|
30
|
+
|
|
31
|
+
self.setNeedsDisplay(true)
|
|
32
|
+
self.setNeedsLayout(true)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def top_level_view
|
|
36
|
+
contentView
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|