ruby_motion_query 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -37,6 +37,58 @@ module RubyMotionQuery
37
37
  self
38
38
  end
39
39
 
40
+ def distribute(type = :vertical, params = {})
41
+ return 0 if selected.length == 0
42
+
43
+ margins = params[:margins]
44
+ margin = params[:margin] || 0
45
+ current_end = nil
46
+
47
+ selected.each_with_index do |view, i|
48
+ st = self.styler_for(view)
49
+ next if st.height == 0
50
+
51
+ view_margin = if (margins && margins[i])
52
+ margins[i]
53
+ else
54
+ margin
55
+ end
56
+
57
+ current_end = (st.top - view_margin) unless current_end
58
+
59
+ if type == :horizontal
60
+ st.left = current_end + view_margin
61
+ current_end = st.right
62
+ else
63
+ st.top = current_end + view_margin
64
+ current_end = st.bottom
65
+ end
66
+
67
+ end
68
+
69
+ self
70
+ end
71
+
72
+ def resize_to_fit_subviews
73
+ selected.each do |view|
74
+ st = self.styler_for(view)
75
+
76
+ w = 0
77
+ h = 0
78
+
79
+ view.subviews.each do |subview|
80
+ sub_st = self.styler_for(subview)
81
+ w = [sub_st.right, w].max
82
+ h = [sub_st.bottom, h].max
83
+ end
84
+
85
+ st.width = w if st.width < w
86
+ st.height = h if st.height < h
87
+ end
88
+
89
+ self
90
+ end
91
+
40
92
  # @return [Array] or [CGSize]
41
93
  def location_in_root_view
42
94
  self.location_in(self.root_view)
@@ -16,7 +16,6 @@ module RubyMotionQuery
16
16
  @_selectors
17
17
  end
18
18
 
19
-
20
19
  protected
21
20
 
22
21
  def match_context(new_selectors)
@@ -1,21 +1,21 @@
1
1
  module RubyMotionQuery
2
2
  module Stylers
3
3
 
4
- class UILabelStyler < UIViewStyler
5
- def text=(value) ; @view.text = value ; end
4
+ class UILabelStyler < UIViewStyler
5
+ def text=(value) ; @view.setText value ; end
6
6
  def text ; @view.text ; end
7
7
 
8
- def font=(value) ; @view.font = value ; end
8
+ def font=(value) ; @view.setFont value ; end
9
9
  def font ; @view.font ; end
10
10
 
11
- def color=(value) ; @view.textColor = value ; end
11
+ def color=(value) ; @view.setTextColor value ; end
12
12
  def color ; @view.textColor ; end
13
13
 
14
- def number_of_lines=(value)
14
+ def number_of_lines=(value)
15
15
  value = 0 if value == :unlimited
16
- @view.numberOfLines = value
16
+ @view.setNumberOfLines(value)
17
17
  end
18
- def number_of_lines
18
+ def number_of_lines
19
19
  if @view.numberOfLines == 0
20
20
  :unlimited
21
21
  else
@@ -23,10 +23,10 @@ module RubyMotionQuery
23
23
  end
24
24
  end
25
25
 
26
- def text_alignment=(value)
27
- @view.textAlignment = TEXT_ALIGNMENTS[value] || value
26
+ def text_alignment=(value)
27
+ @view.setTextAlignment(TEXT_ALIGNMENTS[value] || value)
28
28
  end
29
- def text_alignment
29
+ def text_alignment
30
30
  @view.textAlignment
31
31
  end
32
32
 
@@ -2,7 +2,7 @@ module RubyMotionQuery
2
2
  module Stylers
3
3
 
4
4
  # When you create a styler, always inherit UIViewStyler
5
- class UIViewStyler
5
+ class UIViewStyler
6
6
  def initialize(view)
7
7
  @view = view
8
8
  end
@@ -20,7 +20,7 @@ module RubyMotionQuery
20
20
  end
21
21
 
22
22
  def superview
23
- @view.superview || rmq(@view).view_controller.view || rmq.window
23
+ @view.superview || rmq(@view).root_view || rmq.window
24
24
  end
25
25
  alias :parent :superview
26
26
 
@@ -49,6 +49,8 @@ module RubyMotionQuery
49
49
  f.size.height =h[:h] || h[:height] || f.size.height
50
50
 
51
51
  @view.frame = f
52
+ else
53
+ @view.frame = value
52
54
  end
53
55
  end
54
56
  def frame
@@ -68,7 +70,7 @@ module RubyMotionQuery
68
70
  value = [
69
71
  [h[:l], h[:t]],
70
72
  [
71
- sbounds.size.width - h[:l] - h[:r],
73
+ sbounds.size.width - h[:l] - h[:r],
72
74
  sbounds.size.height - h[:t] - h[:b]
73
75
  ]]
74
76
 
@@ -169,7 +171,7 @@ module RubyMotionQuery
169
171
  def center_y=(value)
170
172
  c = @view.center
171
173
  c.y = value
172
- @view.center = c
174
+ @view.setCenter c
173
175
  end
174
176
  def center_y
175
177
  @view.center.y
@@ -181,7 +183,7 @@ module RubyMotionQuery
181
183
  case option
182
184
  when :horizontal
183
185
  # Not using parent.center.x here for orientation
184
- self.center_x = parent.bounds.size.width / 2
186
+ self.center_x = parent.bounds.size.width / 2
185
187
  when :vertical
186
188
  self.center_y = parent.bounds.size.height / 2
187
189
  else
@@ -191,39 +193,39 @@ module RubyMotionQuery
191
193
  end
192
194
 
193
195
  def background_color=(value)
194
- @view.backgroundColor = value
196
+ @view.setBackgroundColor value
195
197
  end
196
198
  def background_color
197
199
  @view.backgroundColor
198
200
  end
199
-
201
+
200
202
  def background_image=(value)
201
- @view.backgroundColor = UIColor.colorWithPatternImage(value)
203
+ @view.setBackgroundColor UIColor.colorWithPatternImage(value)
202
204
  end
203
205
 
204
206
  def z_position=(index)
205
- @view.layer.zPosition = index
207
+ @view.layer.setZPosition index
206
208
  end
207
209
  def z_position
208
210
  @view.layer.zPosition
209
211
  end
210
212
 
211
213
  def opaque=(value)
212
- @view.layer.opaque = value
214
+ @view.layer.setOpaque value
213
215
  end
214
216
  def opaque
215
- @view.layer.opaque
217
+ @view.layer.isOpaque
216
218
  end
217
219
 
218
220
  def hidden=(value)
219
- @view.hidden = value
221
+ @view.setHidden value
220
222
  end
221
223
  def hidden
222
- @view.hidden
224
+ @view.isHidden
223
225
  end
224
226
 
225
227
  def enabled=(value)
226
- @view.enabled = value
228
+ @view.setEnabled value
227
229
  end
228
230
  def enabled
229
231
  @view.enabled
@@ -246,17 +248,24 @@ module RubyMotionQuery
246
248
  end
247
249
 
248
250
  def rotation=(new_angle)
249
- radians = new_angle * Math::PI / 180
251
+ radians = new_angle * Math::PI / 180
250
252
  @view.transform = CGAffineTransformMakeRotation(radians)
251
253
  end
252
254
 
253
255
  def content_mode=(value)
254
- @view.contentMode = value
256
+ @view.setContentMode value
255
257
  end
256
258
  def content_mode
257
259
  @view.contentMode
258
260
  end
259
261
 
262
+ def clips_to_bounds=(value)
263
+ @view.setClipsToBounds value
264
+ end
265
+ def clips_to_bounds
266
+ @view.clipsToBounds
267
+ end
268
+
260
269
  end
261
270
  end
262
271
  end
@@ -3,7 +3,8 @@ module RubyMotionQuery
3
3
 
4
4
  # @return [RMQ]
5
5
  def stylesheet=(value)
6
- controller = view_controller
6
+ controller = self.weak_view_controller
7
+
7
8
  unless value.is_a?(RubyMotionQuery::Stylesheet)
8
9
  value = value.new(controller)
9
10
  end
@@ -16,7 +17,7 @@ module RubyMotionQuery
16
17
  def stylesheet
17
18
  @_stylesheet ||= begin
18
19
 
19
- if self.view_controller && (ss = self.view_controller.rmq_data.stylesheet)
20
+ if self.weak_view_controller && (ss = self.weak_view_controller.rmq_data.stylesheet)
20
21
  ss
21
22
  elsif (prmq = self.parent_rmq) && prmq.stylesheet
22
23
  prmq.stylesheet
@@ -88,11 +89,11 @@ module RubyMotionQuery
88
89
 
89
90
  def apply_style_to_view(view, style_name)
90
91
  begin
91
- stylesheet.__send__(style_name, styler_for(view))
92
+ stylesheet.public_send(style_name, styler_for(view))
92
93
  view.rmq_data.style_name = style_name
93
94
  rescue NoMethodError => e
94
95
  if e.message =~ /.*#{style_name.to_s}.*/
95
- puts "\n[RMQ ERROR] style_name :#{style_name} doesn't exist for a #{view.class.name}. Add 'def #{style_name}(sv)' to #{stylesheet.class.name} class\n\n"
96
+ puts "\n[RMQ ERROR] style_name :#{style_name} doesn't exist for a #{view.class.name}. Add 'def #{style_name}(st)' to #{stylesheet.class.name} class\n\n"
96
97
  else
97
98
  raise e
98
99
  end
@@ -105,7 +106,7 @@ module RubyMotionQuery
105
106
  attr_reader :controller
106
107
 
107
108
  def initialize(controller)
108
- @controller = WeakRef.new(controller)
109
+ @controller = RubyMotionQuery::RMQ.weak_ref(controller)
109
110
 
110
111
  unless Stylesheet.application_was_setup
111
112
  Stylesheet.application_was_setup = true
@@ -179,10 +180,36 @@ module RubyMotionQuery
179
180
  device.screen.applicationFrame.size
180
181
  end
181
182
 
183
+ def screen_width
184
+ screen_size.width
185
+ end
186
+
187
+ def screen_height
188
+ screen_size.height
189
+ end
190
+
182
191
  def screen_size
183
192
  device.screen.bounds.size
184
193
  end
185
194
 
195
+ def content_width
196
+ content_size.width
197
+ end
198
+
199
+ def content_height
200
+ content_size.height
201
+ end
202
+
203
+ # Content size of the controller's rootview, if it is a
204
+ # UIScrollView, UICollectionView, UITableView, etc
205
+ def content_size
206
+ if @controller.view.respond_to?(:contentSize)
207
+ @controller.view.contentSize
208
+ else
209
+ CGSizeZero
210
+ end
211
+ end
212
+
186
213
  def image
187
214
  RMQ.image
188
215
  end
@@ -15,6 +15,8 @@ module RubyMotionQuery
15
15
 
16
16
  selected.each do |selected_view|
17
17
  created = false
18
+ appended = false
19
+
18
20
 
19
21
  if view_or_constant.is_a?(UIView)
20
22
  new_view = view_or_constant
@@ -23,6 +25,8 @@ module RubyMotionQuery
23
25
  new_view = create_view(view_or_constant, opts)
24
26
  end
25
27
 
28
+ new_view.rmq_data.view_controller = self.weak_view_controller
29
+
26
30
  subviews_added << new_view
27
31
 
28
32
  unless opts[:do_not_add]
@@ -33,13 +37,20 @@ module RubyMotionQuery
33
37
  else
34
38
  selected_view.addSubview(new_view)
35
39
  end
40
+
41
+ appended = true
36
42
  end
37
43
 
38
44
  if self.stylesheet
39
45
  apply_style_to_view(new_view, style) if style
40
46
  end
41
47
 
42
- new_view.rmq_did_create(self.wrap(new_view)) if created
48
+ if created
49
+ new_view.rmq_did_create(self.wrap(new_view))
50
+ new_view.rmq_created
51
+ end
52
+ new_view.rmq_build
53
+ new_view.rmq_appended if appended
43
54
  end
44
55
 
45
56
  RMQ.create_with_array_and_selectors(subviews_added, selectors, @context, self)
@@ -86,6 +97,24 @@ module RubyMotionQuery
86
97
  add_subview view_or_constant, opts
87
98
  end
88
99
 
100
+ # Build a view, similar to create and append, but only inits an existing view. Usefull
101
+ # in collectionview cells for example
102
+ #
103
+ # @example
104
+ # # In your collectionview
105
+ # rmq.build(cell) unless cell.reused
106
+ #
107
+ # # Then in your cell
108
+ #
109
+ # def rmq_build
110
+ # rmq.append(UIView, :foo)
111
+ # end
112
+ def build(view, style = nil, opts = {})
113
+ opts[:do_not_add] = true
114
+ opts[:style] = style
115
+ add_subview view, opts
116
+ end
117
+
89
118
  protected
90
119
 
91
120
  def create_view(klass, opts)
@@ -36,7 +36,7 @@ module RubyMotionQuery
36
36
  # @example
37
37
  # rmq.all.log
38
38
  def all
39
- self.view_controller.rmq.find
39
+ self.weak_view_controller.rmq.find
40
40
  end
41
41
 
42
42
  # @return [RMQ] A new rmq instance reducing selected views to those that match selectors provided
@@ -86,11 +86,12 @@ module RubyMotionQuery
86
86
  end
87
87
  alias :add_self :and_self
88
88
 
89
- # @return [RMQ] The parent rmq instance
89
+ # @return [RMQ] The parent rmq instance. This is useful when you want to go down
90
+ # into the tree, then move back up to do more work. Like jQuery's "end"
90
91
  #
91
92
  # @example
92
- # rmq(test_view).find(UIImageView).tag(:foo).end.find(UILabel).tag(:bar)
93
- def end
93
+ # rmq(test_view).find(UIImageView).tag(:foo).back.find(UILabel).tag(:bar)
94
+ def back
94
95
  self.parent_rmq || self
95
96
  end
96
97
 
@@ -244,32 +245,79 @@ module RubyMotionQuery
244
245
  end
245
246
  end
246
247
 
248
+ # This returns a weak ref to the controller. The controller may be destroyed and you will still have a pointer to it.
249
+ # Be mindful of that.
250
+ #
251
+ # When you call rmq within a controller or view, a new instance of RMQ is created with the selectors you may or may
252
+ # not have supplied. That instance will determine what view_controller it should use for stuff like traversing,
253
+ # stylesheet, etc.
254
+ #
255
+ # * rmq method called in a controller: that controller is used
256
+ #
257
+ # * rmq method called in a view and that view is within the subview tree of a controller: that controller is used
258
+ #
259
+ #
260
+ # * rmq method called in a view and that view is NOT within any subview tree of any controller (common in a UITableViewCell
261
+ # for example). In this case it will use the view's controller or the "current controller". Generally
262
+ # that is what is desired, however there are some situations where another controller should be used. In that
263
+ # situation create your own rmq instance and assign the controller you'd rather use
264
+ #
265
+ # * if an rmq instance was created from another rmq instance, it will attempt to the parent_rmq's controller, if it exists
266
+ #
247
267
  # @return [UIViewController] Controller of this rmq instance
248
268
  #
249
269
  # @example
250
- # rmq.view_controller
270
+ # rmq(my_view).view_controller
251
271
  def view_controller
252
- @_view_controller ||= begin
272
+ RMQ.weak_ref_to_strong_ref(self.weak_view_controller)
273
+ end
274
+
275
+ # Mostly used internally
276
+ # See #view_controller
277
+ def weak_view_controller
278
+ if @_view_controller
279
+ @_view_controller
280
+ else
253
281
  if @context.is_a?(UIViewController)
254
- WeakRef.new(@context)
255
- else
256
- if vc = RMQ.controller_for_view(@context)
257
- WeakRef.new(vc)
258
- end
282
+ @context
283
+ else # view
284
+ vc = RMQ.controller_for_view(@context) ||
285
+ (self.parent_rmq && self.parent_rmq.weak_view_controller) ||
286
+ RMQ.app.current_view_controller
287
+
288
+ #debug.assert(vc.is_a?(UIViewController), 'Invalid controller in weak_view_controller') do
289
+ #{
290
+ #vc: vc,
291
+ #context: @context,
292
+ #parent_rmq: self.parent_rmq,
293
+ #current_view_controller: RMQ.app.current_view_controller
294
+ #}
295
+ #end
296
+
297
+ self.view_controller = vc
298
+ @context.rmq_data.view_controller = @_view_controller if @context
299
+
300
+ @_view_controller
259
301
  end
260
302
  end
261
303
  end
304
+ def view_controller=(value)
305
+ @_view_controller = RubyMotionQuery::RMQ.weak_ref(value)
306
+ end
307
+ def weak_view_controller=(value)
308
+ @_view_controller = value
309
+ end
262
310
 
263
311
  # @return [UIView] Root view of this rmq instance's controller
264
312
  #
265
313
  # @example
266
314
  # rmq.root_view
267
315
  def root_view
268
- vc = self.view_controller
316
+ vc = self.weak_view_controller
269
317
  if RMQ.is_blank?(vc)
270
318
  self.context_or_context_view
271
319
  else
272
- self.view_controller.view
320
+ vc.view
273
321
  end
274
322
  end
275
323