ruby_motion_query 0.4.1 → 0.5.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.
@@ -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