ruby_motion_query 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YTE0YTM0NWIzY2ZmNDIwMTgxNDgzMDMwZDM0MzAxNzJhZmJiN2EyMg==
4
+ ZjFmZTc0N2Y5NDViYjkyNGI3MjQ0MmFhZmQxNmQ3NzRiMzY3YzRkNQ==
5
5
  data.tar.gz: !binary |-
6
- NjM1Zjg4OGRjM2U0YTgyNDFkMWQ2NzZlNjg0MWFjMmQxZTIxYTliZQ==
6
+ ZjU1NWJhMmE3MmZkNGRjNDIyYzJjNjE0YTdmOGNlYzcxNDE3MTMzMQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- YjI4MTM1NTUzZGJkMTg4MGY0NWE0YzgwMDFmMjI5ZGM5YTBhNWFhNDNjYzI4
10
- ZGY5NzNiNTFhYTgyMzM1MThmYTgwNDA3NDE4NmM4Y2Y1YzhmMmFhNGMxNGQz
11
- OWI3N2NlZWNlYTlmYzk5NmY1OTYzODQwZjMwYmMzMWE3M2QyMmE=
9
+ ZDA4NThmZjhhYjhlM2ViZjBiYzI4NzFlYjg0NzdlYTllMGQyNzE3Y2ZiZGQ1
10
+ YjE3M2JmNzc0ZmRhMzVhYWIxYzg5ZjdhMGEyYzFiYTg2ZmQyM2E5YzlhNDNl
11
+ MGYxNDUyOTE5NDJkODljYjc3MmMwYTI1ZDZjNzgwNGI2NDhiMmI=
12
12
  data.tar.gz: !binary |-
13
- YmU4MTYyMjdiNGJkZjdmZDY2OTVjNDlhMGExOGIyMjljYWJhNGJjYmRjNDBh
14
- YjUzMGIxZmIyMjdlODY4Yzg4N2JjN2MyNDQ1NDAzYWQxMTNkZTVjMmY5Njll
15
- NzQwZGZlNDBiODJkMTVjN2UwMmY4ZWE4Zjg3NjMwMmRmM2FmNjQ=
13
+ YWNkY2Q3YjgyYTJhM2EzZmYxNTcyMzI5MTM2NzU5OGFjNGVlY2U5NDg1YzM2
14
+ MmI5ZDc4Y2ZkNGE1YTUwNDA1MzA5OTdkODFhZjVkZGNlZmYzZWM2ZjU1OGQ1
15
+ NmJmZWQ2OTFiZjllMDA4YjA0YmQ4ZTUzNDI0NGE0ODU3ZjU3MWY=
data/README.md CHANGED
@@ -1,14 +1,17 @@
1
1
  ![RQM logo](http://ir_wp.s3.amazonaws.com/wp-content/uploads/sites/9/2013/07/rmq_logo.png)
2
2
 
3
- RubyMotionQuery - RMQ - A small, light, muggle, nonpolluting, jQuery-like library for [RubyMotion](http://rubymotion.com).
3
+ # RubyMotionQuery - RMQ
4
+ A light, muggle, nonpolluting, jQuery-like library for [RubyMotion](http://rubymotion.com).
4
5
 
5
- #### The [RMQ Introductory Guide and other info][1] is a great place to start.
6
+ **The [RMQ Introductory Guide and other info][1] is a great place to start.**
6
7
 
8
+ [![Dependency Status](https://gemnasium.com/infinitered/rmq.png)](https://gemnasium.com/infinitered/rmq)
9
+ [![Build Status](https://travis-ci.org/infinitered/rmq.png?branch=master)](https://travis-ci.org/infinitered/rmq)
7
10
 
8
- ----------
9
11
 
12
+ ## General
10
13
 
11
- #### Some of the very cool features:
14
+ ### Some of the very cool features:
12
15
  - **selecting** (*querying*) views
13
16
  - **traversal** through view hierarchy (moving around the tree)
14
17
  - tagging
@@ -21,30 +24,21 @@ RubyMotionQuery - RMQ - A small, light, muggle, nonpolluting, jQuery-like librar
21
24
  - app
22
25
  - device
23
26
 
24
- #### Other wrapper libraries
25
- There are a lot of great wrappers out there such as Teacup and Sugarcube. I've used these and I enjoy them. However, many of the wrappers heavily pollute the standard classes, which is great if you like that sort of thing. RMQ is designed to have minimal pollution, to be very simple and high performance (it will be when it's done). RMQ shouldn't conflict with anything.
26
-
27
- RMQ **doesn't require any** other wrapper or gem.
28
-
29
- > If you preferred jQuery over Prototype, you'll love RMQ.
30
-
31
- Some of the code in RMQ came from BubbleWrap and Sugarcube. Not too much but some did. I thank you BubbleWrap and Sugarcube teams for your work.
32
-
33
27
  ----------
34
28
 
35
- ### * Alpha * Warning *
29
+ **Tested only on iOS only, not OS X (nor is there any OS X specific code)**
36
30
 
37
- This is in the **alpha** stage right now, it works well and we've used some of RMQ in production apps, but it **needs** more **testing**, **performance** optimizations, **documentation**, and the **TODOs** to be finished.
31
+ ----------
38
32
 
39
- RDocs are not done. I'd appreciate help on these. This readme isn't up to the quality I'd like either. I figure it's better to get it out to the community sooner rather than wait for it to be more finished. My ideal is jQuery quality docs in addition to basic RDoc reference.
33
+ ### Other wrapper libraries
34
+ There are a lot of great wrappers out there such as Teacup and Sugarcube. I've used these and I enjoy them. However, many of the wrappers heavily pollute the standard classes, which is great if you like that sort of thing. RMQ is designed to have minimal pollution, to be very simple and high performance (it will be when it's done). RMQ shouldn't conflict with anything.
40
35
 
41
- Nothing is optimized for speed yet. Well, that isn't true, somethings are.
36
+ RMQ **doesn't require any** other wrapper or gem.
42
37
 
43
- Memory leaks may exist.
38
+ > If you preferred jQuery over Prototype, you'll love RMQ.
44
39
 
45
- Tested only on iOS, not OS X (nor is there any OS X specific code)
40
+ Some of the code in RMQ came from BubbleWrap and Sugarcube. Not too much but some did. I thank you BubbleWrap and Sugarcube teams for your work.
46
41
 
47
- ----------
48
42
 
49
43
  ## Installation
50
44
 
@@ -58,7 +52,6 @@ or add it to your `Gemfile`:
58
52
  - `gem 'ruby_motion_query'`
59
53
 
60
54
 
61
-
62
55
  ## Usage
63
56
 
64
57
  ### Example App
@@ -159,6 +152,8 @@ rmq(UILabel).get
159
152
  - find
160
153
  - children
161
154
  - siblings
155
+ - next
156
+ - prev
162
157
  - closest
163
158
  - parent
164
159
  - parents
@@ -303,6 +298,7 @@ rmq(my_view).hide
303
298
  rmq(my_view).show
304
299
  rmq(my_view).toggle
305
300
  rmq(my_view).toggle_enabled
301
+ rmq(my_text_field).focus # or .become_first_responder
306
302
  ```
307
303
 
308
304
  ### Subviews
@@ -311,10 +307,19 @@ rmq(my_view).toggle_enabled
311
307
  rmq.append(UILabel) # Creates a UILabel in the current controller
312
308
  rmq.append(UILabel, :my_label_style)
313
309
  rmq.append(UILabel.alloc.initWithFrame([[0,0],[10,10]]), :my_label_style)
314
- rmq(my_view).append(UIButton) # A custom button
310
+
311
+ rmq(my_view).append(UIButton)
315
312
  rmq(my_view).remove
316
313
  rmq(my_vuew).children.remove
317
- rmq(UIView).append(UIButton, :delete_me)
314
+
315
+ rmq(UIView).append(UIButton, :delete_me) # A custom button for all views
316
+
317
+ rmq.unshift(UILabel) # Adds to index 0 of the subviews
318
+ rmq.unshift(UILabel, :my_style)
319
+ rmq.insert(UILabel, at_index: 2)
320
+ rmq.insert(UILabel, at_index: 2, style: :my_style)
321
+ rmq.insert(UILabel, below_view: some_view_of_mine)
322
+ rmq.insert(UILabel, below_view: some_view_of_mine, style: :my_style)
318
323
 
319
324
  rmq(my_view).parent # .superview works too
320
325
  rmq(my_view).parents # all parents up the tree, up to the root
@@ -1,5 +1,7 @@
1
1
  module RubyMotionQuery
2
2
  class RMQ
3
+
4
+ # @return [RMQ]
3
5
  def attr(new_settings)
4
6
  selected.each do |view|
5
7
  new_settings.each do |k,v|
@@ -9,6 +11,7 @@ module RubyMotionQuery
9
11
  self
10
12
  end
11
13
 
14
+ # @return [RMQ]
12
15
  def send(method, args = nil)
13
16
  selected.each do |view|
14
17
  if args
@@ -20,21 +23,39 @@ module RubyMotionQuery
20
23
  self
21
24
  end
22
25
 
26
+ # Sets the last selected view as the first responder
27
+ #
28
+ # @return [RMQ]
29
+ #
30
+ # @example
31
+ # rmq(my_view).next(UITextField).focus
32
+ def focus
33
+ unless RMQ.is_blank?(selected)
34
+ selected.last.becomeFirstResponder
35
+ end
36
+ self
37
+ end
38
+ alias :become_first_responder :focus
39
+
40
+ # @return [RMQ]
23
41
  def hide
24
42
  selected.each { |view| view.hidden = true }
25
43
  self
26
44
  end
27
45
 
46
+ # @return [RMQ]
28
47
  def show
29
48
  selected.each { |view| view.hidden = false }
30
49
  self
31
50
  end
32
51
 
52
+ # @return [RMQ]
33
53
  def toggle
34
54
  selected.each { |view| view.hidden = !view.hidden? }
35
55
  self
36
56
  end
37
57
 
58
+ # @return [RMQ]
38
59
  def toggle_enabled
39
60
  selected.each { |view| view.enabled = !view.enabled? }
40
61
  self
@@ -1,5 +1,7 @@
1
1
  module RubyMotionQuery
2
2
  class RMQ
3
+
4
+ # @return [RMQ]
3
5
  def animate(opts = {})
4
6
  working_selected = self.selected
5
7
  @_rmq = self # @ for rm bug
@@ -35,6 +37,7 @@ module RubyMotionQuery
35
37
  self
36
38
  end
37
39
 
40
+ # @return [Animations]
38
41
  def animations
39
42
  @_animations ||= Animations.new(self)
40
43
  end
@@ -45,6 +48,7 @@ module RubyMotionQuery
45
48
  @rmq = rmq
46
49
  end
47
50
 
51
+ # @return [RMQ]
48
52
  def fade_in(opts = {})
49
53
  @rmq.each do |view|
50
54
  view.layer.opacity = 0.0
@@ -58,6 +62,7 @@ module RubyMotionQuery
58
62
  @rmq.animate(opts)
59
63
  end
60
64
 
65
+ # @return [RMQ]
61
66
  def fade_out(opts = {})
62
67
  opts[:animations] = lambda do |rmq|
63
68
  rmq.get.layer.opacity = 0.0
@@ -77,6 +82,7 @@ module RubyMotionQuery
77
82
  @rmq.animate(opts)
78
83
  end
79
84
 
85
+ # @return [RMQ]
80
86
  def throb
81
87
  @rmq.animate(
82
88
  duration: 0.1,
@@ -94,22 +100,27 @@ module RubyMotionQuery
94
100
  )
95
101
  end
96
102
 
103
+ # @return [RMQ]
97
104
  def blink
98
105
  self.fade_out(duration: 0.2, after: lambda {|did_finish, rmq| rmq.animations.fade_in(duration: 0.2)})
99
106
  end
100
107
 
108
+ # @return [RMQ]
101
109
  def start_spinner(style = UIActivityIndicatorViewStyleGray)
102
110
  spinner = Animations.window_spinner(style)
103
111
  spinner.startAnimating
104
112
  @rmq.create_rmq_in_context(spinner)
105
113
  end
106
114
 
115
+ # @return [RMQ]
107
116
  def stop_spinner
108
117
  spinner = Animations.window_spinner
109
118
  spinner.stopAnimating
110
119
  @rmq.create_rmq_in_context(spinner)
111
120
  end
112
121
 
122
+ protected
123
+
113
124
  def self.window_spinner(style = UIActivityIndicatorViewStyleGray)
114
125
  @_window_spinner ||= begin
115
126
  window = RMQ.app.window
@@ -1,68 +1,71 @@
1
1
  module RubyMotionQuery
2
2
  class RMQ
3
+ # @return [App]
3
4
  def app
4
5
  App
5
6
  end
6
7
 
8
+ # @return [App]
7
9
  def self.app
8
10
  App
9
11
  end
10
-
11
- # TODO This is a bit wierd and may not work, need to think on this
12
- # It's also confusing use of rmq which assumes a controller and subviews
13
- #def window_rmq
14
- #RMQ.create_with_selectors([App.window], self.context)
15
- #end
16
-
17
- #def self.window_rmq
18
- #RMQ.create_with_selectors([App.window], App.window)
19
- #end
20
12
  end
21
13
 
22
14
  class App
23
15
  class << self
24
16
 
17
+ # @return [UIWindow]
25
18
  def window
26
19
  UIApplication.sharedApplication.keyWindow || UIApplication.sharedApplication.windows[0]
27
20
  end
28
21
 
22
+ # @return [UIApplicationDelegate]
29
23
  def delegate
30
24
  UIApplication.sharedApplication.delegate
31
25
  end
32
26
 
27
+ # @return [Symbol] Environment the app is running it
33
28
  def environment
34
29
  RUBYMOTION_ENV.to_sym
35
30
  end
36
31
 
32
+ # @return [Boolean] true if the app is running in the :release environment
37
33
  def release?
38
34
  environment == :release
39
35
  end
40
36
  alias :production? :release?
41
37
 
38
+ # @return [Boolean] true if the app is running in the :test environment
42
39
  def test?
43
40
  environment == :test
44
41
  end
45
42
 
43
+ # @return [Boolean] true if the app is running in the :development environment
46
44
  def development?
47
45
  environment == :development
48
46
  end
49
47
 
48
+ # @return [String] Version
50
49
  def version
51
50
  NSBundle.mainBundle.infoDictionary['CFBundleVersion']
52
51
  end
53
52
 
53
+ # @return [String] Name of app
54
54
  def name
55
55
  NSBundle.mainBundle.objectForInfoDictionaryKey 'CFBundleDisplayName'
56
56
  end
57
57
 
58
+ # @return [String] Identifier of app
58
59
  def identifier
59
60
  NSBundle.mainBundle.bundleIdentifier
60
61
  end
61
62
 
63
+ # @return [String] Full path of the resources folder
62
64
  def resource_path
63
65
  NSBundle.mainBundle.resourcePath
64
66
  end
65
67
 
68
+ # @return [String] Full path of the document folder
66
69
  def document_path
67
70
  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true)[0]
68
71
  end
@@ -1,4 +1,20 @@
1
1
  module RubyMotionQuery
2
+
3
+ # The main class for RubyMotionQuery
4
+ #
5
+ # What's an rmq instance?
6
+ # - an rmq instance is an array-like object containing UIViews
7
+ # - rmq() never returns nil. If nothing is selected, it's an empty [ ] array-like
8
+ # object
9
+ # - an rmq object always (almost always) returns either itself or a new
10
+ # rmq object. This is how chaining works. You do not need to worry if
11
+ # an rmq is blank or not, everything always works without throwing a
12
+ # nil exception
13
+ # - jQuery uses the DOM, what is rmq using for the "DOM"? It uses the
14
+ # controller it was called in. The "DOM" is the controller's subview
15
+ # tree. If you call rmq inside a view, it will attach to the
16
+ # controller that the view is currently in or to the current screen's
17
+ # controller
2
18
  class RMQ
3
19
  attr_accessor :context, :parent_rmq
4
20
 
@@ -6,10 +22,17 @@ module RubyMotionQuery
6
22
  @selected_dirty = true
7
23
  end
8
24
 
25
+ # Do not use
9
26
  def selected=(value)
10
27
  @_selected = value
11
28
  @selected_dirty = false
12
29
  end
30
+
31
+ # The UIViews currently selected
32
+ #
33
+ # Use {#get} instead to get the actual UIView objects
34
+ #
35
+ # @return [Array]
13
36
  def selected
14
37
  if @selected_dirty
15
38
  @_selected = []
@@ -39,6 +62,8 @@ module RubyMotionQuery
39
62
  end
40
63
 
41
64
  # The view(s) this rmq was derived from
65
+ #
66
+ # @return [Array]
42
67
  def origin_views
43
68
  if @parent_rmq
44
69
  @parent_rmq.selected
@@ -51,7 +76,15 @@ module RubyMotionQuery
51
76
  # Normally used to get the only view in selected.
52
77
  #
53
78
  # @example
54
- # rmq(foo).parent.get.some_method_on_parent
79
+ # # returns my_view
80
+ # rmq(my_view).get
81
+ #
82
+ # # returns an array
83
+ # rmq(UILabel).get
84
+ #
85
+ # rmq(foo).parent.get.some_method_on_parent
86
+ #
87
+ # @return [UIView or Array]
55
88
  def get
56
89
  sel = self.selected
57
90
  if sel.length == 1
@@ -61,10 +94,21 @@ module RubyMotionQuery
61
94
  end
62
95
  end
63
96
 
97
+ # Is this rmq a root instance?
98
+ #
99
+ # Which means it only has 1 selected view, and that view
100
+ # is the view you called rmq in. Which is a tad confusing, but if you call *just* rmq inside a
101
+ # view, then only that view will be *selected* and this rmq will be *root*. If you call rmq
102
+ # inside a controller, only controller.view will be selected and the rma instance will be a root.
64
103
  def root?
65
104
  (selected.length == 1) && (selected.first == @context)
66
105
  end
67
106
 
107
+ # The context is where rmq was created (not the selectors).
108
+ #
109
+ # Normally you are inside a controller or a UIView when you execute the rmq method.
110
+ #
111
+ # @return [UIView] the controller's view or the view you are in when calling rmq
68
112
  def context_or_context_view
69
113
  if @context.is_a?(UIViewController)
70
114
  @context.view
@@ -73,45 +117,50 @@ module RubyMotionQuery
73
117
  end
74
118
  end
75
119
 
76
- def extract_views_from_selectors(view_container, working_selectors)
77
- unless RMQ.is_blank?(working_selectors)
78
- working_selectors.each do |selector|
79
- if selector.is_a?(UIView)
80
- view_container << working_selectors.delete(selector)
81
- end
82
- end
83
- end
84
- [view_container, working_selectors]
85
- end
86
-
87
- def all_subviews_for(view)
88
- # TODO maybe cache this, and invalidate cache properly
89
- out = []
90
- if view.subviews
91
- view.subviews.each do |subview|
92
- out << subview
93
- out << all_subviews_for(subview)
94
- end
95
- out.flatten!
96
- end
97
-
98
- out
99
- end
100
-
101
- def all_superviews_for(view, out = [])
102
- if (nr = view.nextResponder) && nr.is_a?(UIView)
103
- out << nr
104
- all_superviews_for(nr, out)
105
- end
106
- out
107
- end
108
-
120
+ # Changed inspect to be useful
121
+ #
122
+ # @return [String]
123
+ #
124
+ # @example
125
+ # (main)> rmq.all
126
+ # => RMQ 172658240. 26 selected. selectors: []. .log for more info
109
127
  def inspect
110
128
  out = "RMQ #{self.object_id}. #{self.count} selected. selectors: #{self.selectors.to_s}. .log for more info"
111
129
  out << "\n[#{selected.first}]" if self.count == 1
112
130
  out
113
131
  end
114
132
 
133
+ # Super useful in the console. log outputs to the console a table of the selected views
134
+ #
135
+ # @param :wide outputs wide format (really wide, but awesome: rmq.all.log :wide)
136
+ #
137
+ # @return [String]
138
+ #
139
+ # @example
140
+ # (main)> rmq(UIImageView).log
141
+ #
142
+ # object_id | class | style_name | frame |
143
+ # sv id | superview | subviews count | tags |
144
+ # - - - - - - | - - - - - - - - - - - | - - - - - - - - - - - - | - - - - - - - - - - - - - - - - |
145
+ # 168150976 | UIImageView | logo | {l: 60, t: 10, w: 200, h: 95.5} |
146
+ # 168128784 | UIView | 0 | |
147
+ # - - - - - - | - - - - - - - - - - - | - - - - - - - - - - - - | - - - - - - - - - - - - - - - - |
148
+ # 168180640 | UIImageView | | {l: 1, t: 1, w: 148, h: 19} |
149
+ # 168173616 | UIRoundedRectButton | 0 | |
150
+ # - - - - - - | - - - - - - - - - - - | - - - - - - - - - - - - | - - - - - - - - - - - - - - - - |
151
+ # 168204336 | UIImageView | | {l: 1, t: 0, w: 77, h: 27} |
152
+ # 168201952 | _UISwitchInternalView | 0 | |
153
+ # - - - - - - | - - - - - - - - - - - | - - - - - - - - - - - - | - - - - - - - - - - - - - - - - |
154
+ # 172600352 | UIImageView | | {l: -2, t: 0, w: 79, h: 27} |
155
+ # 168204512 | UIView | 0 | |
156
+ # - - - - - - | - - - - - - - - - - - | - - - - - - - - - - - - | - - - - - - - - - - - - - - - - |
157
+ # 168205504 | UIImageView | | {l: -2, t: 0, w: 131, h: 27} |
158
+ # 168204512 | UIView | 0 | |
159
+ # - - - - - - | - - - - - - - - - - - | - - - - - - - - - - - - | - - - - - - - - - - - - - - - - |
160
+ # 168205600 | UIImageView | | {l: 49, t: 0, w: 29, h: 27} |
161
+ # 168204512 | UIView | 0 | |
162
+ # - - - - - - | - - - - - - - - - - - | - - - - - - - - - - - - | - - - - - - - - - - - - - - - - |
163
+ # RMQ 278442176. 6 selected. selectors: [UIImageView]#
115
164
  def log(opt = nil)
116
165
  wide = (opt == :wide)
117
166
  out = "\n object_id | class | style_name | frame |"
@@ -157,5 +206,40 @@ module RubyMotionQuery
157
206
  attr_accessor :cache_controller_rmqs
158
207
  @cache_controller_rmqs = true
159
208
  end
209
+
210
+ protected
211
+ def extract_views_from_selectors(view_container, working_selectors)
212
+ unless RMQ.is_blank?(working_selectors)
213
+ working_selectors.each do |selector|
214
+ if selector.is_a?(UIView)
215
+ view_container << working_selectors.delete(selector)
216
+ end
217
+ end
218
+ end
219
+ [view_container, working_selectors]
220
+ end
221
+
222
+ def all_subviews_for(view)
223
+ # TODO maybe cache this, and invalidate cache properly
224
+ out = []
225
+ if view.subviews
226
+ view.subviews.each do |subview|
227
+ out << subview
228
+ out << all_subviews_for(subview)
229
+ end
230
+ out.flatten!
231
+ end
232
+
233
+ out
234
+ end
235
+
236
+ def all_superviews_for(view, out = [])
237
+ if (nr = view.nextResponder) && nr.is_a?(UIView)
238
+ out << nr
239
+ all_superviews_for(nr, out)
240
+ end
241
+ out
242
+ end
243
+
160
244
  end
161
245
  end