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.
Files changed (88) hide show
  1. data/Gemfile +1 -1
  2. data/Gemfile.lock +3 -3
  3. data/README.md +1172 -319
  4. data/Rakefile +8 -1
  5. data/app/app_delegate.rb +1 -1
  6. data/app/controllers/appearance_controller.rb +13 -0
  7. data/app/controllers/landscape_only_controller.rb +1 -1
  8. data/app/controllers/{first_controller.rb → main_controller.rb} +4 -3
  9. data/app/controllers/motion_layout_controller.rb +22 -0
  10. data/app/styles/appearance.rb +24 -0
  11. data/app/styles/main_styles.rb +8 -6
  12. data/app/views/custom_view.rb +1 -0
  13. data/lib/teacup/calculations.rb +2 -2
  14. data/lib/teacup/{z_core_extensions → core_extensions}/ca_layer.rb +0 -0
  15. data/lib/teacup/core_extensions/view_getters.rb +61 -0
  16. data/lib/teacup/handler.rb +14 -14
  17. data/lib/teacup/layout.rb +94 -17
  18. data/lib/teacup/stylesheet.rb +61 -26
  19. data/lib/teacup/stylesheet_extensions/transform.rb +88 -0
  20. data/lib/teacup/teacup_controller.rb +122 -0
  21. data/lib/teacup/teacup_util.rb +12 -7
  22. data/lib/teacup/teacup_view.rb +329 -0
  23. data/lib/teacup/version.rb +1 -1
  24. data/lib/teacup-ios/appearance.rb +96 -0
  25. data/lib/teacup-ios/core_extensions/teacup_handlers.rb +183 -0
  26. data/lib/teacup-ios/core_extensions/ui_view.rb +30 -0
  27. data/lib/teacup-ios/core_extensions/ui_view_controller.rb +110 -0
  28. data/lib/{dummy.rb → teacup-ios/dummy.rb} +2 -6
  29. data/lib/teacup-ios/handler.rb +23 -0
  30. data/lib/{teacup → teacup-ios}/style.rb +9 -10
  31. data/lib/teacup-ios/stylesheet_extensions/autoresize.rb +169 -0
  32. data/lib/{teacup/stylesheet_extensions/geometry.rb → teacup-ios/stylesheet_extensions/device.rb} +0 -0
  33. data/lib/teacup-osx/core_extensions/ns_view.rb +39 -0
  34. data/lib/teacup-osx/core_extensions/ns_view_controller.rb +21 -0
  35. data/lib/teacup-osx/core_extensions/ns_window.rb +39 -0
  36. data/lib/teacup-osx/core_extensions/ns_window_controller.rb +29 -0
  37. data/lib/{teacup/z_core_extensions/z_handlers.rb → teacup-osx/core_extensions/teacup_handlers.rb} +30 -47
  38. data/lib/teacup-osx/dummy.rb +80 -0
  39. data/lib/teacup-osx/handler.rb +16 -0
  40. data/lib/teacup-osx/style.rb +83 -0
  41. data/lib/teacup-osx/style_extensions/autoresize.rb +169 -0
  42. data/lib/teacup.rb +12 -11
  43. data/samples/Tweets/Gemfile +4 -0
  44. data/samples/Tweets/Gemfile.lock +16 -0
  45. data/samples/Tweets/README +7 -0
  46. data/samples/Tweets/Rakefile +9 -0
  47. data/samples/Tweets/app/app_delegate.rb +18 -0
  48. data/samples/Tweets/app/data_parser.rb +10 -0
  49. data/samples/Tweets/app/json_parser.rb +12 -0
  50. data/samples/Tweets/app/main_window.rb +99 -0
  51. data/samples/Tweets/app/menu.rb +108 -0
  52. data/samples/Tweets/app/stylesheet.rb +21 -0
  53. data/samples/Tweets/app/tweet.rb +11 -0
  54. data/samples/Tweets/resources/Credits.rtf +29 -0
  55. data/samples/Tweets/spec/main_spec.rb +9 -0
  56. data/samples/teacup-osx/.gitignore +1 -0
  57. data/samples/teacup-osx/Gemfile +4 -0
  58. data/samples/teacup-osx/Gemfile.lock +16 -0
  59. data/samples/teacup-osx/Rakefile +9 -0
  60. data/samples/teacup-osx/app/app_delegate.rb +23 -0
  61. data/samples/teacup-osx/app/controller.rb +11 -0
  62. data/samples/teacup-osx/app/menu.rb +108 -0
  63. data/samples/teacup-osx/app/window.rb +12 -0
  64. data/samples/teacup-osx/resources/Credits.rtf +29 -0
  65. data/samples/teacup-osx/resources/teacup.png +0 -0
  66. data/samples/teacup-osx/spec/main_spec.rb +9 -0
  67. data/spec/ios/appearance_spec.rb +18 -0
  68. data/spec/{calculations_spec.rb → ios/calculations_spec.rb} +0 -0
  69. data/spec/{constraints_spec.rb → ios/constraints_spec.rb} +0 -0
  70. data/spec/{custom_class_spec.rb → ios/custom_class_spec.rb} +0 -0
  71. data/spec/{gradient_spec.rb → ios/gradient_spec.rb} +1 -1
  72. data/spec/ios/layout_module_spec.rb +54 -0
  73. data/spec/ios/layout_spec.rb +50 -0
  74. data/spec/{main_spec.rb → ios/main_spec.rb} +52 -13
  75. data/spec/ios/motion_layout_spec.rb +44 -0
  76. data/spec/{present_modal_spec.rb → ios/present_modal_spec.rb} +0 -0
  77. data/spec/{style_spec.rb → ios/style_spec.rb} +1 -1
  78. data/spec/ios/stylesheet_extensions/autoresize_spec.rb +50 -0
  79. data/spec/{stylesheet_spec.rb → ios/stylesheet_spec.rb} +12 -0
  80. data/spec/{ui_view_getters_spec.rb → ios/ui_view_getters_spec.rb} +0 -0
  81. data/spec/{uiswitch_spec.rb → ios/uiswitch_spec.rb} +0 -0
  82. data/spec/{view_spec.rb → ios/view_spec.rb} +23 -2
  83. metadata +85 -35
  84. data/lib/teacup/stylesheet_extensions/autoresize.rb +0 -39
  85. data/lib/teacup/stylesheet_extensions/rotation.rb +0 -37
  86. data/lib/teacup/z_core_extensions/ui_view.rb +0 -262
  87. data/lib/teacup/z_core_extensions/ui_view_controller.rb +0 -263
  88. 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
- if orientation
53
- Overrides[orientation].each do |orientation_key|
54
- if override = self[orientation_key]
55
- # override is first, so it takes precedence
56
- if override.is_a? Hash
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 importing. before merging, these will go
72
- # through the same process that we just finished on the local style
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
@@ -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