motion-loco 0.1.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.
- checksums.yaml +15 -0
- data/README.md +29 -0
- data/lib/motion-loco.rb +8 -0
- data/lib/motion-loco/controller.rb +21 -0
- data/lib/motion-loco/convenience_methods.rb +17 -0
- data/lib/motion-loco/model.rb +9 -0
- data/lib/motion-loco/observable.rb +167 -0
- data/lib/motion-loco/proc.rb +24 -0
- data/lib/motion-loco/resizable.rb +252 -0
- data/lib/motion-loco/table_view.rb +116 -0
- data/lib/motion-loco/version.rb +3 -0
- data/lib/motion-loco/view_controller.rb +13 -0
- data/lib/motion-loco/views.rb +66 -0
- metadata +101 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MTQxZjRjNTk4MWY0OWMyMGRlOTUzMjk3ODVmMzliODIxZDA5YzczYg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NTIwYTU0ZDdmZDhmNmIyYWZiOWI2NWU3ZThjOTAxYTIxYWQ3OWYyZg==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZDMzYjJkM2RmMmZjZjIwZGVmNmU5MTk4NmJjZWIwMTQ1YTk2YTk0MWRhNjcw
|
10
|
+
ZDFiZjM0ODFiZTIyMzBkOTQ2NTQwYjdmZDQ1NGQyYmM1NTk1YmE1ODM0MDM1
|
11
|
+
MDI3OGVjODFkODI3ZWQ3OTUzYTUzZWMxOTU0NTI5MmM4Mzg1OGY=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ODA5ZDhmZTFhYmU5NDBkNDQxOWExYTYwOWE2NDYzOWQxMTk5ZDgyZGI4MzVi
|
14
|
+
MzNmMTI0NWFlODYxODM5NmM1ZjNjMzA1ZjEyNTIwMzk2ODNkZDFiNDU1ZTJl
|
15
|
+
NmZjNDFkYmNmNWVkYWE0YTI4NTk0MjM1MzdlNTBmNDFmYTZhMjE=
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Loco
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'motion-loco'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install motion-loco
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/lib/motion-loco.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
unless defined?(Motion::Project::Config)
|
2
|
+
raise "This file must be required within a RubyMotion project Rakefile."
|
3
|
+
end
|
4
|
+
|
5
|
+
require 'motion-redgreen'
|
6
|
+
require 'motion-require'
|
7
|
+
|
8
|
+
Motion::Require.all(Dir.glob(File.expand_path('../motion-loco/**/*.rb', __FILE__)))
|
@@ -0,0 +1,21 @@
|
|
1
|
+
motion_require 'observable'
|
2
|
+
|
3
|
+
module Loco
|
4
|
+
|
5
|
+
class Controller
|
6
|
+
include Observable
|
7
|
+
|
8
|
+
def self.instance
|
9
|
+
@instance ||= new
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.method_missing(method, *args, &block)
|
13
|
+
if self.instance.respond_to? method
|
14
|
+
self.instance.send(method, *args)
|
15
|
+
else
|
16
|
+
super
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Loco
|
2
|
+
|
3
|
+
# TODO: Determine if logging should happen based on environment
|
4
|
+
def self.debug(obj)
|
5
|
+
NSLog(obj.inspect.send(:cyan))
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.t(name, *args)
|
9
|
+
if args
|
10
|
+
format = NSBundle.mainBundle.localizedStringForKey(name, value:nil, table:nil)
|
11
|
+
format % args
|
12
|
+
else
|
13
|
+
NSBundle.mainBundle.localizedStringForKey(name, value:nil, table:nil)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
motion_require 'proc'
|
2
|
+
|
3
|
+
module Loco
|
4
|
+
|
5
|
+
module Observable
|
6
|
+
COLLECTION_OPERATIONS = [ NSKeyValueChangeInsertion, NSKeyValueChangeRemoval, NSKeyValueChangeReplacement ]
|
7
|
+
DEFAULT_OPTIONS = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
|
8
|
+
|
9
|
+
# Used to create observable view controllers.
|
10
|
+
def init
|
11
|
+
super
|
12
|
+
initialize_bindings
|
13
|
+
set_properties({})
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
# Create new instance from a hash of properties with values.
|
18
|
+
# @param [Hash] properties
|
19
|
+
def initialize(properties={})
|
20
|
+
super
|
21
|
+
initialize_bindings
|
22
|
+
set_properties(properties)
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
# Used to create observable views.
|
27
|
+
def initWithFrame(frame)
|
28
|
+
super
|
29
|
+
initialize_bindings
|
30
|
+
set_properties({})
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
# Used to create observable table view cells
|
35
|
+
def initWithStyle(style, reuseIdentifier:reuseIdentifier)
|
36
|
+
super
|
37
|
+
initialize_bindings
|
38
|
+
set_properties({})
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
# Change one or many properties from a hash of properties with values.
|
43
|
+
# @param [Hash] properties
|
44
|
+
def set_properties(hash)
|
45
|
+
# Set the initial property values from the given hash
|
46
|
+
hash.each do |key, value|
|
47
|
+
self.send("#{key}=", value)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def method_missing(method, *args, &block)
|
52
|
+
if method.end_with?('_binding=') || method.end_with?('Binding=')
|
53
|
+
method = method.gsub('_binding=', '').gsub('Binding=', '')
|
54
|
+
if args.first.is_a?(String)
|
55
|
+
if args.first =~ /^[A-Z]/
|
56
|
+
split_args = args.first.split('.')
|
57
|
+
target = Kernel.const_get(split_args.slice!(0)).instance
|
58
|
+
key_path = split_args.join('.')
|
59
|
+
else
|
60
|
+
target = self
|
61
|
+
key_path = args.first
|
62
|
+
end
|
63
|
+
else
|
64
|
+
target = args.first.first
|
65
|
+
key_path = args.first.last
|
66
|
+
end
|
67
|
+
self.send("#{method}=", target.valueForKeyPath(key_path))
|
68
|
+
register_observer(target, key_path) do
|
69
|
+
self.send("#{method}=", target.valueForKeyPath(key_path))
|
70
|
+
end
|
71
|
+
else
|
72
|
+
super
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def register_observer(target, key_path, &block)
|
77
|
+
unless observer_is_registered?(target, key_path)
|
78
|
+
target.addObserver(self, forKeyPath:key_path.to_s, options:DEFAULT_OPTIONS, context:nil)
|
79
|
+
end
|
80
|
+
observers_for(target, key_path) << block
|
81
|
+
end
|
82
|
+
|
83
|
+
def remove_observer(target, key_path)
|
84
|
+
target.removeObserver(self, forKeyPath:key_path)
|
85
|
+
observers = observers_for(target, key_path)
|
86
|
+
observers[target].delete(key_path) if observers[target].has_key?(key_path)
|
87
|
+
end
|
88
|
+
|
89
|
+
def remove_all_observers
|
90
|
+
return if @observers.nil?
|
91
|
+
@observers.each do |target, key_paths|
|
92
|
+
key_paths.each_key do |key_path|
|
93
|
+
target.removeObserver(self, forKeyPath:key_path)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
@observers.clear
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
# Create the bindings for the computed properties and observers
|
102
|
+
def initialize_bindings
|
103
|
+
bindings = self.class.send(:get_class_bindings)
|
104
|
+
|
105
|
+
bindings.each do |binding|
|
106
|
+
binding[:proc].observed_properties.each do |key_path|
|
107
|
+
register_observer(self, key_path) do
|
108
|
+
new_value = binding[:proc].call(self)
|
109
|
+
if binding[:name]
|
110
|
+
self.send("#{binding[:name]}=", new_value)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def observeValueForKeyPath(key_path, ofObject:target, change:change, context:context)
|
118
|
+
if observer_is_registered?(target, key_path)
|
119
|
+
@observers[target][key_path].each do |proc|
|
120
|
+
proc.call
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def observer_is_registered?(target, key_path)
|
126
|
+
return @observers && @observers[target] && @observers[target][key_path.to_s]
|
127
|
+
end
|
128
|
+
|
129
|
+
def observers_for(target, key_path)
|
130
|
+
@observers ||= {}
|
131
|
+
@observers[target] ||= {}
|
132
|
+
@observers[target][key_path.to_s] ||= []
|
133
|
+
end
|
134
|
+
|
135
|
+
def dealloc
|
136
|
+
self.remove_all_observers
|
137
|
+
super
|
138
|
+
end
|
139
|
+
|
140
|
+
module ClassMethods
|
141
|
+
def property(name, proc=nil)
|
142
|
+
attr_accessor name
|
143
|
+
unless proc.nil?
|
144
|
+
@class_bindings = get_class_bindings
|
145
|
+
@class_bindings << { name: name, proc: proc }
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def observer(name, proc)
|
150
|
+
@class_bindings = get_class_bindings
|
151
|
+
@class_bindings << { proc: proc }
|
152
|
+
end
|
153
|
+
|
154
|
+
# An array of the model's bindings
|
155
|
+
# @return [Array]
|
156
|
+
def get_class_bindings
|
157
|
+
@class_bindings ||= []
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
def self.included(base)
|
163
|
+
base.extend(ClassMethods)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Loco
|
2
|
+
|
3
|
+
class ::Proc
|
4
|
+
attr_reader :observed_properties
|
5
|
+
def observed_properties
|
6
|
+
@observed_properties ||= []
|
7
|
+
end
|
8
|
+
|
9
|
+
def observes(*properties)
|
10
|
+
properties.each {|property|
|
11
|
+
self.observed_properties << property
|
12
|
+
}
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def property(*properties)
|
17
|
+
properties.each {|property|
|
18
|
+
self.observed_properties << property
|
19
|
+
}
|
20
|
+
self
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,252 @@
|
|
1
|
+
module Loco
|
2
|
+
|
3
|
+
module Resizable
|
4
|
+
attr_accessor :parentView
|
5
|
+
|
6
|
+
# The position of the bottom edge,
|
7
|
+
# relative to the superview's bottom edge.
|
8
|
+
# @return [Integer]
|
9
|
+
attr_accessor :bottom
|
10
|
+
def bottom=(bottom)
|
11
|
+
super
|
12
|
+
refresh_layout
|
13
|
+
end
|
14
|
+
|
15
|
+
# The height of the view.
|
16
|
+
# @return [Integer]
|
17
|
+
attr_accessor :height
|
18
|
+
def height=(height)
|
19
|
+
super
|
20
|
+
refresh_layout
|
21
|
+
end
|
22
|
+
|
23
|
+
# The position of the left edge,
|
24
|
+
# relative to the superview's left edge.
|
25
|
+
# @return [Integer]
|
26
|
+
attr_accessor :left
|
27
|
+
def left=(left)
|
28
|
+
super
|
29
|
+
refresh_layout
|
30
|
+
end
|
31
|
+
|
32
|
+
# The position of the right edge,
|
33
|
+
# relative to the superview's right edge.
|
34
|
+
# @return [Integer]
|
35
|
+
attr_accessor :right
|
36
|
+
def right=(right)
|
37
|
+
super
|
38
|
+
refresh_layout
|
39
|
+
end
|
40
|
+
|
41
|
+
# The position of the top edge,
|
42
|
+
# relative to the superview's top edge.
|
43
|
+
# @return [Integer]
|
44
|
+
attr_accessor :top
|
45
|
+
def top=(top)
|
46
|
+
super
|
47
|
+
refresh_layout
|
48
|
+
end
|
49
|
+
|
50
|
+
# The width of the view.
|
51
|
+
# @return [Integer]
|
52
|
+
attr_accessor :width
|
53
|
+
def width=(width)
|
54
|
+
super
|
55
|
+
refresh_layout
|
56
|
+
end
|
57
|
+
|
58
|
+
# Create new instance from a hash of properties with values.
|
59
|
+
# @param [Object] frame The CGRect or a Hash of properties.
|
60
|
+
def initWithFrame(frame)
|
61
|
+
if frame.is_a? Hash
|
62
|
+
# Set the initial property values from the given hash
|
63
|
+
super(CGRect.new)
|
64
|
+
frame.each do |key, value|
|
65
|
+
self.send("#{key}=", value)
|
66
|
+
end
|
67
|
+
else
|
68
|
+
super(frame)
|
69
|
+
end
|
70
|
+
view_setup
|
71
|
+
self
|
72
|
+
end
|
73
|
+
|
74
|
+
# Refresh the layout based on bottom, left, right, top, and superview.
|
75
|
+
# @param [UIView] superview
|
76
|
+
def refresh_layout(superview=nil)
|
77
|
+
# The view can't be positioned without being added to the superview first.
|
78
|
+
superview ||= self.superview
|
79
|
+
return if superview.nil?
|
80
|
+
|
81
|
+
# Determine the original size, position, and autoresizing mask that should be used.
|
82
|
+
if self.top && self.bottom
|
83
|
+
if self.left && self.right
|
84
|
+
# FW, FH
|
85
|
+
@origin_x = self.left
|
86
|
+
@origin_y = self.top
|
87
|
+
@size_height = superview.bounds.size.height - self.top - self.bottom
|
88
|
+
@size_width = superview.bounds.size.width - self.left - self.right
|
89
|
+
@autoresizing = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight
|
90
|
+
elsif self.left && self.width
|
91
|
+
# FH, FRM
|
92
|
+
@origin_x = self.left
|
93
|
+
@origin_y = self.top
|
94
|
+
@size_height = superview.bounds.size.height - self.top - self.bottom
|
95
|
+
@size_width = self.width
|
96
|
+
@autoresizing = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleRightMargin
|
97
|
+
elsif self.right && self.width
|
98
|
+
# FH, FLM
|
99
|
+
@origin_x = superview.bounds.size.width - self.width - self.right
|
100
|
+
@origin_y = self.top
|
101
|
+
@size_height = superview.bounds.size.height - self.top - self.bottom
|
102
|
+
@size_width = self.width
|
103
|
+
@autoresizing = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin
|
104
|
+
elsif self.width
|
105
|
+
# FH, FLM, FRM
|
106
|
+
@origin_x = (superview.bounds.size.width - self.width) / 2
|
107
|
+
@origin_y = self.top
|
108
|
+
@size_height = superview.bounds.size.height - self.top - self.bottom
|
109
|
+
@size_width = self.width
|
110
|
+
@autoresizing = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin
|
111
|
+
else
|
112
|
+
# Needs More Params
|
113
|
+
NSLog('%@<Loco::View> Not enough params to position and size the view.', self.class)
|
114
|
+
end
|
115
|
+
elsif self.top
|
116
|
+
if self.left && self.right && self.height
|
117
|
+
# FW, FBM
|
118
|
+
@origin_x = self.left
|
119
|
+
@origin_y = self.top
|
120
|
+
@size_height = self.height
|
121
|
+
@size_width = superview.bounds.size.width - self.left - self.right
|
122
|
+
@autoresizing = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin
|
123
|
+
elsif self.left && self.height && self.width
|
124
|
+
# FBM, FRM
|
125
|
+
@origin_x = self.left
|
126
|
+
@origin_y = self.top
|
127
|
+
@size_height = self.height
|
128
|
+
@size_width = self.width
|
129
|
+
@autoresizing = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin
|
130
|
+
elsif self.right && self.height && self.width
|
131
|
+
# FBM, FLM
|
132
|
+
@origin_x = superview.bounds.size.width - self.width - self.right
|
133
|
+
@origin_y = self.top
|
134
|
+
@size_height = self.height
|
135
|
+
@size_width = self.width
|
136
|
+
@autoresizing = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin
|
137
|
+
elsif self.height && self.width
|
138
|
+
# FLM, FRM, FBM
|
139
|
+
@origin_x = (superview.bounds.size.width - self.width) / 2
|
140
|
+
@origin_y = self.top
|
141
|
+
@size_height = self.height
|
142
|
+
@size_width = self.width
|
143
|
+
@autoresizing = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin |UIViewAutoresizingFlexibleBottomMargin
|
144
|
+
else
|
145
|
+
# Needs More Params
|
146
|
+
NSLog('%@<Loco::View> Not enough params to position and size the view.', self.class)
|
147
|
+
end
|
148
|
+
elsif self.bottom
|
149
|
+
if self.left && self.right && self.height
|
150
|
+
# FW, FTM
|
151
|
+
@origin_x = self.left
|
152
|
+
@origin_y = superview.bounds.size.height - self.height - self.bottom
|
153
|
+
@size_height = self.height
|
154
|
+
@size_width = superview.bounds.size.width - self.left - self.right
|
155
|
+
@autoresizing = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin
|
156
|
+
elsif self.left && self.height && self.width
|
157
|
+
# FTM, FRM
|
158
|
+
@origin_x = self.left
|
159
|
+
@origin_y = superview.bounds.size.height - self.height - self.bottom
|
160
|
+
@size_height = self.height
|
161
|
+
@size_width = self.width
|
162
|
+
@autoresizing = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin
|
163
|
+
elsif self.right && self.height && self.width
|
164
|
+
# FTM, FLM
|
165
|
+
@origin_x = superview.bounds.size.width - self.width - self.right
|
166
|
+
@origin_y = superview.bounds.size.height - self.height - self.bottom
|
167
|
+
@size_height = self.height
|
168
|
+
@size_width = self.width
|
169
|
+
@autoresizing = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin
|
170
|
+
elsif self.height && self.width
|
171
|
+
# FLM, FRM, FTM
|
172
|
+
@origin_x = (superview.bounds.size.width - self.width) / 2
|
173
|
+
@origin_y = superview.bounds.size.height - self.height - self.bottom
|
174
|
+
@size_height = self.height
|
175
|
+
@size_width = self.width
|
176
|
+
@autoresizing = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin |UIViewAutoresizingFlexibleTopMargin
|
177
|
+
else
|
178
|
+
# Needs More Params
|
179
|
+
NSLog('%@<Loco::View> Not enough params to position and size the view.', self.class)
|
180
|
+
end
|
181
|
+
elsif self.left && self.right && self.height
|
182
|
+
# FW, FTM, FBM
|
183
|
+
@origin_x = self.left
|
184
|
+
@origin_y = (superview.bounds.size.height - self.height) / 2
|
185
|
+
@size_height = self.height
|
186
|
+
@size_width = superview.bounds.size.width - self.left - self.right
|
187
|
+
@autoresizing = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin
|
188
|
+
elsif self.width && self.height
|
189
|
+
if self.left
|
190
|
+
# FTM, FBM, FRM
|
191
|
+
@origin_x = self.left
|
192
|
+
@origin_y = (superview.bounds.size.height - self.height) / 2
|
193
|
+
@size_height = self.height
|
194
|
+
@size_width = self.width
|
195
|
+
@autoresizing = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin
|
196
|
+
elsif self.right
|
197
|
+
# FTM, FBM, FLM
|
198
|
+
@origin_x = superview.bounds.size.width - self.width - self.right
|
199
|
+
@origin_y = (superview.bounds.size.height - self.height) / 2
|
200
|
+
@size_height = self.height
|
201
|
+
@size_width = self.width
|
202
|
+
@autoresizing = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin
|
203
|
+
else
|
204
|
+
# FTM, FBM, FLM, FRM
|
205
|
+
@origin_x = (superview.bounds.size.width - self.width) / 2
|
206
|
+
@origin_y = (superview.bounds.size.height - self.height) / 2
|
207
|
+
@size_height = self.height
|
208
|
+
@size_width = self.width
|
209
|
+
@autoresizing = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin
|
210
|
+
end
|
211
|
+
else
|
212
|
+
# Needs More Params
|
213
|
+
NSLog('%@<Loco::View> Not enough params to position and size the view.', self.class)
|
214
|
+
end
|
215
|
+
|
216
|
+
# Warn of any possible conflicts
|
217
|
+
if self.top && self.bottom && self.height
|
218
|
+
NSLog('%@<Loco::View> `top`, `bottom`, and `height` may conflict with each other. Only two of the three should be set.', self.class)
|
219
|
+
NSLog('%@<Loco::View> top: %@, bottom: %@, height: %@', self.class, self.top, self.bottom, self.height)
|
220
|
+
end
|
221
|
+
if self.left && self.right && self.width
|
222
|
+
NSLog('%@<Loco::View> `left`, `right`, and `width` may conflict with each other. Only two of the three should be set.', self.class)
|
223
|
+
NSLog('%@<Loco::View> left: %@, right: %@, width: %@', self.class, self.left, self.right, self.width)
|
224
|
+
end
|
225
|
+
|
226
|
+
if @origin_x && @origin_y && @size_width && @size_height && @autoresizing
|
227
|
+
self.frame = [[@origin_x, @origin_y], [@size_width, @size_height]]
|
228
|
+
self.autoresizingMask = @autoresizing
|
229
|
+
end
|
230
|
+
|
231
|
+
# Update the subviews
|
232
|
+
self.subviews.each do |view|
|
233
|
+
view.refresh_layout(self) if view.is_a? Resizable
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def view_setup
|
238
|
+
viewSetup
|
239
|
+
end
|
240
|
+
|
241
|
+
def viewSetup
|
242
|
+
# Override #view_setup or #viewSetup to customize the view
|
243
|
+
end
|
244
|
+
|
245
|
+
# Fires when the superview changes.
|
246
|
+
def willMoveToSuperview(superview)
|
247
|
+
self.parentView = superview
|
248
|
+
refresh_layout(superview)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
motion_require 'observable'
|
2
|
+
motion_require 'resizable'
|
3
|
+
|
4
|
+
module Loco
|
5
|
+
|
6
|
+
class TableViewCell < UITableViewCell
|
7
|
+
include Observable
|
8
|
+
|
9
|
+
property :content
|
10
|
+
|
11
|
+
def initWithStyle(style, reuseIdentifier:reuseIdentifier)
|
12
|
+
if super
|
13
|
+
view_setup # Needed because it's not Loco::Resizable
|
14
|
+
end
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def select
|
19
|
+
Loco.debug("Override #{self.class}#select with the action to take when the row is selected")
|
20
|
+
end
|
21
|
+
|
22
|
+
def view_controller(superview=nil)
|
23
|
+
if superview
|
24
|
+
view_controller = superview.nextResponder
|
25
|
+
else
|
26
|
+
view_controller = self.superview.nextResponder
|
27
|
+
end
|
28
|
+
if view_controller.is_a? UIViewController
|
29
|
+
view_controller
|
30
|
+
elsif view_controller.is_a? UIView
|
31
|
+
self.view_controller(view_controller)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
alias_method :viewController, :view_controller
|
35
|
+
|
36
|
+
def view_setup
|
37
|
+
viewSetup
|
38
|
+
end
|
39
|
+
|
40
|
+
def viewSetup
|
41
|
+
Loco.debug("Override #{self.class}#viewSetup or #{self.class}#view_setup to customize the view")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class TableView < UITableView
|
46
|
+
include Resizable
|
47
|
+
include Observable
|
48
|
+
|
49
|
+
property :content
|
50
|
+
|
51
|
+
def content=(value)
|
52
|
+
@content = value
|
53
|
+
self.reloadData
|
54
|
+
end
|
55
|
+
|
56
|
+
def cell_id
|
57
|
+
@cell_id ||= "CELL_#{self.object_id}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def initWithFrame(frame)
|
61
|
+
super(frame)
|
62
|
+
self.dataSource = self.delegate = self
|
63
|
+
end
|
64
|
+
|
65
|
+
def item_view_class
|
66
|
+
self.class.send(:get_item_view_class)
|
67
|
+
end
|
68
|
+
|
69
|
+
# UITableViewDelegate implementation for returning the number sections in the table view.
|
70
|
+
# @return [Integer]
|
71
|
+
def numberOfSectionsInTableView(tableView)
|
72
|
+
1
|
73
|
+
end
|
74
|
+
|
75
|
+
# UITableViewDelegate implementation for returning the cell at a given indexPath.
|
76
|
+
# @return [Loco::TableViewCell]
|
77
|
+
def tableView(tableView, cellForRowAtIndexPath:indexPath)
|
78
|
+
cell = tableView.dequeueReusableCellWithIdentifier(cell_id)
|
79
|
+
unless cell
|
80
|
+
cell = self.item_view_class.alloc.initWithStyle(UITableViewCellStyleDefault, reuseIdentifier:cell_id)
|
81
|
+
end
|
82
|
+
cell.content = self.content[indexPath.row]
|
83
|
+
cell
|
84
|
+
end
|
85
|
+
|
86
|
+
# UITableViewDelegate implementation for selecting a cell at a given indexPath.
|
87
|
+
def tableView(tableView, didSelectRowAtIndexPath:indexPath)
|
88
|
+
cell = tableView.cellForRowAtIndexPath(indexPath)
|
89
|
+
cell.select
|
90
|
+
end
|
91
|
+
|
92
|
+
# UITableViewDelegate implementation for returning the number of rows in a section.
|
93
|
+
# @return [Integer]
|
94
|
+
def tableView(tableView, numberOfRowsInSection:section)
|
95
|
+
if self.content.is_a? Array
|
96
|
+
self.content.length
|
97
|
+
else
|
98
|
+
0
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class << self
|
103
|
+
|
104
|
+
def item_view_class(view_class)
|
105
|
+
@item_view_class = view_class
|
106
|
+
end
|
107
|
+
alias_method :itemViewClass, :item_view_class
|
108
|
+
|
109
|
+
def get_item_view_class
|
110
|
+
@item_view_class ||= TableViewCell
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
motion_require 'observable'
|
2
|
+
motion_require 'resizable'
|
3
|
+
|
4
|
+
module Loco
|
5
|
+
|
6
|
+
class Button < UIButton
|
7
|
+
include Resizable
|
8
|
+
include Observable
|
9
|
+
end
|
10
|
+
|
11
|
+
class DatePicker < UIDatePicker
|
12
|
+
include Resizable
|
13
|
+
include Observable
|
14
|
+
end
|
15
|
+
|
16
|
+
class ImageView < UIImageView
|
17
|
+
include Resizable
|
18
|
+
include Observable
|
19
|
+
end
|
20
|
+
|
21
|
+
class Label < UILabel
|
22
|
+
include Resizable
|
23
|
+
include Observable
|
24
|
+
end
|
25
|
+
|
26
|
+
class PickerView < UIPickerView
|
27
|
+
include Resizable
|
28
|
+
include Observable
|
29
|
+
end
|
30
|
+
|
31
|
+
class ProgressView < UIProgressView
|
32
|
+
include Resizable
|
33
|
+
include Observable
|
34
|
+
end
|
35
|
+
|
36
|
+
class ScrollView < UIScrollView
|
37
|
+
include Resizable
|
38
|
+
include Observable
|
39
|
+
end
|
40
|
+
|
41
|
+
class Slider < UISlider
|
42
|
+
include Resizable
|
43
|
+
include Observable
|
44
|
+
end
|
45
|
+
|
46
|
+
class TextView < UITextView
|
47
|
+
include Resizable
|
48
|
+
include Observable
|
49
|
+
end
|
50
|
+
|
51
|
+
class Toolbar < UIToolbar
|
52
|
+
include Resizable
|
53
|
+
include Observable
|
54
|
+
end
|
55
|
+
|
56
|
+
class View < UIView
|
57
|
+
include Resizable
|
58
|
+
include Observable
|
59
|
+
end
|
60
|
+
|
61
|
+
class WebView < UIWebView
|
62
|
+
include Resizable
|
63
|
+
include Observable
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: motion-loco
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brian Pattison
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-05-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: motion-redgreen
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: motion-require
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.0.6
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.0.6
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: ! "Library for RubyMotion that includes Ember.js-like bindings, computed
|
56
|
+
properties, and observers.\n Loco also includes a set of
|
57
|
+
views that are easier to position and size."
|
58
|
+
email:
|
59
|
+
- brian@brianpattison.com
|
60
|
+
executables: []
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- README.md
|
65
|
+
- lib/motion-loco/controller.rb
|
66
|
+
- lib/motion-loco/convenience_methods.rb
|
67
|
+
- lib/motion-loco/model.rb
|
68
|
+
- lib/motion-loco/observable.rb
|
69
|
+
- lib/motion-loco/proc.rb
|
70
|
+
- lib/motion-loco/resizable.rb
|
71
|
+
- lib/motion-loco/table_view.rb
|
72
|
+
- lib/motion-loco/version.rb
|
73
|
+
- lib/motion-loco/view_controller.rb
|
74
|
+
- lib/motion-loco/views.rb
|
75
|
+
- lib/motion-loco.rb
|
76
|
+
homepage: https://github.com/brianpattison/motion-loco
|
77
|
+
licenses:
|
78
|
+
- MIT
|
79
|
+
metadata: {}
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ! '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
requirements: []
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 2.0.3
|
97
|
+
signing_key:
|
98
|
+
specification_version: 4
|
99
|
+
summary: Library for RubyMotion that includes Ember.js-like bindings, computed properties,
|
100
|
+
and observers.
|
101
|
+
test_files: []
|