ruby_motion_query 0.5.8 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,79 +1,41 @@
1
1
  ![RMQ logo](https://raw.github.com/infinitered/rmq/master/resources/logo@2x.png?raw=true)
2
2
 
3
- # RubyMotionQuery - RMQ
3
+ # RMQ - RubyMotion Front-end Library
4
4
 
5
5
  [![Dependency Status](https://gemnasium.com/infinitered/rmq.png)](https://gemnasium.com/infinitered/rmq)
6
6
  [![Build Status](https://travis-ci.org/infinitered/rmq.png?branch=master)](https://travis-ci.org/infinitered/rmq)
7
7
  [![Gem Version](https://badge.fury.io/rb/ruby_motion_query.png)](http://badge.fury.io/rb/ruby_motion_query)
8
8
  [![Crusher.io optimized](http://www.crusher.io/repo/infinitered/rmq/badge)](http://www.crusher.io/repo/infinitered/rmq)
9
9
 
10
- A fast, non-polluting, chaining, front-end library. It’s like jQuery for [RubyMotion](http://rubymotion.com). Templates, stylesheets, events, animations, etc.
10
+ A fast, non-polluting, chaining, front-end library. It’s like jQuery for [RubyMotion](http://rubymotion.com) plus templates, stylesheets, events, animations, etc.
11
11
 
12
- **The [RMQ website][1] is a great place to start.**
12
+ One of RMQ's goal is to have the best [documentation][1] of any RubyMotion UI library.
13
13
 
14
- Also this 6 minute **[intro video](https://www.youtube.com/watch?v=2ihGjCI2DYE)**
14
+ ## v0.6.0
15
15
 
16
- And this 36 minute video: **[Creating an Image Browser app in RubyMotion and RubyMotionQuery](http://infinitered.com/2013/12/26/creating-an-image-browser-app-in-rubymotion-and-rubymotionquery-rmq/)**
17
-
18
- ----------
19
-
20
- ## General
21
-
22
- ### Some of the very cool features:
23
- - events and gestures
24
- - view factory
25
- - stylesheets
26
- - actions
27
- - position
28
- - selecting (_querying views_)
29
- - templates
30
- - traversal through view hierarchy (moving around the tree)
31
- - animations
32
- - tagging
33
- - colors
34
- - fonts
35
- - image utilities
36
- - app
37
- - device
38
-
39
- [![features](https://ir_wp.s3.amazonaws.com/wp-content/uploads/sites/11/2014/03/rmq_parts-300x231.png)](https://ir_wp.s3.amazonaws.com/wp-content/uploads/sites/11/2014/03/rmq_parts.png)
16
+ <br />
40
17
 
41
18
  ----------
42
19
 
43
- **RMQ only works in iOS, not OS X**
20
+ ## Read the [RMQ Documentation][1] here
44
21
 
45
22
  ----------
46
23
 
47
- ### Other wrapper libraries
48
- 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.
49
-
50
- RMQ **doesn't require any** other wrapper or gem.
51
-
52
- > If you preferred jQuery over Prototype, you'll love RMQ.
53
-
54
- 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.
24
+ <br />
55
25
 
56
26
  ## Quick Start
57
27
 
58
28
  ```
59
29
  gem install ruby_motion_query
60
- rmq create my_app
61
- cd my_app
30
+ # Update your gem file to use RMQ-Edge
31
+ gem 'ruby_motion_query', :git => 'git@github.com:infinitered/rmq.git'
62
32
  bundle
63
33
  rake
64
34
  ```
65
35
 
66
- Or, if you use **rbenv**:
67
-
68
- ```
69
- gem install ruby_motion_query
70
- rbenv rehash
71
- rmq create my_app
72
- cd my_app
73
- bundle
74
- rake
75
- ```
36
+ rbenv rehash after gem install if you use rbenv
76
37
 
38
+ <br />
77
39
 
78
40
  ## Installation
79
41
 
@@ -98,1458 +60,42 @@ for **bleeding edge**, add this to your `Gemfile`:
98
60
  - `gem 'ruby_motion_query', :git => 'git@github.com:infinitered/rmq.git'`
99
61
 
100
62
 
101
- ## Deprecation
102
-
103
- - **UIView#rmq_did_create(self_in_rmq)** - *Use rmq_build instead*
104
-
105
- <br />
106
-
107
- ## Usage
108
-
109
- ----
110
-
111
-
112
- <br />
113
-
114
- ### Example App
115
-
116
- ----
117
-
118
- *Clone this repo and run the example app to see an example of use.*
119
-
120
- git clone git@github.com:infinitered/rmq.git
121
- cd rmq
122
- rake
123
-
124
- The example app works in any orientation, on both iPhone and iPad. Notice how the benchmark popup is done with RMQ, then think about how you'd do that without it.
125
-
126
-
127
-
128
- <br />
129
-
130
- ### What's an rmq instance?
131
-
132
- ----
133
-
134
- - an rmq instance is an array-like object containing UIViews
135
- - rmq() never returns nil. If nothing is selected, it's an empty [ ] array-like
136
- object
137
- - an rmq object always (almost always) returns either itself or a new
138
- rmq object. This is how chaining works. You do not need to worry if
139
- an rmq is blank or not, everything always works without throwing a
140
- nil exception
141
- - jQuery uses the DOM, what is rmq using for the "DOM"? It uses the
142
- controller it was called in. The "DOM" is the controller's subview
143
- tree. If you call rmq inside a view, it will attach to the
144
- controller that the view is currently in or to the current screen's
145
- controller
146
-
147
-
148
- <br />
149
-
150
- ### Basic syntax
151
-
152
- ----
153
-
154
- The main command is `rmq` and you use it everywhere. You can rename this by aliasing the methods in `ext.rb`.
155
-
156
- ```ruby
157
- # Like jQuery you wrap your objects or selectors in a rmq(), here are some examples
158
- rmq(my_view).show
159
- rmq(UILabel).hide
160
-
161
- # You can use zero or more selectors, all these are valid
162
- rmq(my_view, UILabel).hide
163
- rmq(:a_tag, :a_style_name, UIImageView).hide
164
- rmq(hidden: true).show
165
-
166
- # If you use a set of selectors, they are an "or", to do an "and" use .and
167
- rmq(UIImageView).and(hidden: true).show
168
- ```
169
-
170
- **rmq by itself is the rmq instance of the current UIViewController if you're inside a UIViewController**.
171
-
172
- If you're inside a UIView you've created, `rmq.closest(UIControl)` is the same as `rmq(self).closest(UIControl)`.
173
-
174
- #### rmq is always an array-like object (enumerablish), never nil, etc:
175
-
176
- Because of this, you **never have to check** if your selectors return anything before calling actions or other methods on your rmq object.
177
-
178
- ```ruby
179
- # This will hide any UILabel in the controller, if any exist. If not, nothing happens
180
- rmq(UILabel).hide
181
-
182
- # Because of this, you can create chains without worry of exceptions
183
- rmq(:this_tag_does_not_exist).show.apply_style(:my_style_name).on(:touch_down){puts 'score!'}
184
- ```
185
-
186
- #### Almost all methods of an rmq object return either itself or another rmq object, so you can chain:
187
- ```ruby
188
- rmq.append(UILabel, :label_style).on(:tap){|sender,event| sender.hide}
189
-
190
- # or
191
-
192
- rmq.closest(AddEntry).find(:delete_button).hide
193
- rmq(AddEntry).find(UILabel).blink
194
-
195
- ```
196
-
197
- If you want the actual inner object(s), use **.get**
198
-
199
- ```ruby
200
- # returns my_view
201
- rmq(my_view).get
202
-
203
- # returns an array
204
- rmq(UILabel).get
205
- ```
206
-
207
-
208
- <br />
209
-
210
- ### Command-line Tool and Generators
211
-
212
- ----
213
-
214
-
215
-
216
- Like Rails, RMQ provides a command-line tool, mostly for generating files. **Create a new app**:
217
-
218
- ```
219
- > rmq create my_app
220
- ```
221
-
222
- To get all the commands available just do:
223
-
224
- ```
225
- > rmq
226
- ```
227
-
228
- To generate **controllers, models, views**, etc, do the following:
229
-
230
- ```
231
- > rmq create model foo
232
- > rmq create controller bar
233
- > rmq create view foo_bar
234
- > rmq create shared some_class_used_app_wide
235
- > rmq create lib some_class_used_by_multiple_apps
236
-
237
- > rmq create collection_view_controller foos
238
- > rmq create table_view_controller bars
239
-
240
- > rmq create view my_view dry_run
241
- ```
242
-
243
- I recomend you play around with it, do this:
244
-
245
- ```
246
- > cd
247
- > cd Desktop
248
- > rmq create test_rmq_app
249
- > cd test_rmq_app
250
- > rmq create table_view_controller people
251
- > rmq create view group
252
- > bundle
253
- > rake
254
- ```
255
-
256
-
257
- <br />
258
-
259
- ### Selectors
260
-
261
- ----
262
-
263
- - Constant
264
- - :a_tag
265
- - :a_style_name
266
- - my_view_instance
267
- - text: 'you can select via attributes also'
268
- - :another_tag, UILabel, text: 'an array' <- this is an "or", use .and for and
269
-
270
- The more common use is to select any view or views you have assigned to variables, then perform actions on them. For example:
271
-
272
- ```ruby
273
- view_1 = UIView.alloc.initWithFrame([[10,10],[100, 10]])
274
- view_2 = UIView.alloc.initWithFrame([[10,20],[100, 10]])
275
- @view_3 = rmq.append(UIView, :some_style).get
276
-
277
- rmq(view_1).layout(l: 20, t: 40, w: 80, h: 20)
278
-
279
- rmq(view_1, view_2, @view_3).hide
280
- a = [view_1, view_2, @view_3]
281
-
282
- rmq(a).distribute(:vertical, margin: 10)
283
-
284
- rmq(a).on(:tap) do |sender|
285
- puts 'Tapped'
286
- end
287
- ```
288
-
289
-
290
- <br />
291
-
292
- ### Subviews - appending, creating, etc
293
-
294
- ----
295
-
296
- * **build**: takes an existing view, applies the style if it exists, then calls rmq_build method
297
- * **create**: creates the view when given the class, or uses an existing view you pass it, then does a [build]
298
- * **append**: [create] + appends the view to the end of the subview tree or to then end of the children of a view (if called on an rmq object with that view in it)
299
- * **prepend**: Same as [append], but inserts the view to beginning of the subview tree (overall or view's children)
300
- * **insert**: Same as [append], but inserts the view at the index of the subview tree (overall or view's children)
301
-
302
- ```ruby
303
- rmq.append(UILabel) # Creates a UILabel in the current controller
304
- rmq.append(UILabel, :my_label_style)
305
- rmq.append(UILabel.alloc.initWithFrame([[0,0],[10,10]]), :my_label_style)
306
-
307
- rmq(my_view).append(UIButton)
308
- rmq(my_view).remove
309
- rmq(my_vuew).children.remove
310
-
311
- rmq(UIView).append(UIButton, :delete_me) # A custom button for all views
312
-
313
- rmq.unshift(UILabel) # Adds to index 0 of the subviews
314
- rmq.unshift(UILabel, :my_style)
315
- rmq.insert(UILabel, at_index: 2)
316
- rmq.insert(UILabel, at_index: 2, style: :my_style)
317
- rmq.insert(UILabel, below_view: some_view_of_mine)
318
- rmq.insert(UILabel, below_view: some_view_of_mine, style: :my_style)
319
-
320
- rmq(my_view).parent # .superview works too
321
- rmq(my_view).parents # all parents up the tree, up to the root
322
- rmq(my_view).children
323
- rmq(my_view).find # children, grandchildren, etc
324
- rmq.root_view
325
- rmq.view_controller
326
- ```
327
-
328
- Often when appending a subview, you assign the view to a instance variable, like so:
329
-
330
- ```ruby
331
- @name = rmq.append(UILabel, :name).get
332
- ```
333
-
334
- The **.get** returns the actual view. Without it you'll get a reference to an rmq instance, which is how
335
- chaining works.
336
-
337
- This is such a common pattern, an RMQ user (https://github.com/shreeve) created append!, which I've included into RMQ.
338
- The ! version of append or create returns the view directly:
339
-
340
- ```ruby
341
- @name = rmq.append!(UILabel, :name)
342
- # Or the even shorter:
343
- @name = rmq.append! UILabel, :name
344
- ```
345
-
346
-
347
-
348
-
349
- #### Create a view
350
- If you want to create a view but not add it to the subviews of any other view, you can
351
- use #create. It's basically #append without the actual appending.
352
- This is very handy for stuff like table cells:
353
-
354
- ```ruby
355
- # In your controller that is a delegate for a UITableView
356
- def tableView(table_view, cellForRowAtIndexPath: index_path)
357
- cell = table_view.dequeueReusableCellWithIdentifier(CELL_IDENTIFIER) || begin
358
- rmq.create(StoreCell, :store_cell, reuse_identifier: CELL_IDENTIFIER).get
359
-
360
- # If you want to change the style of the cell, you can do something like this:
361
- # rmq.create(StoreCell, :store_cell, reuse_identifier: CELL_IDENTIFIER, cell_style: UITableViewCellStyleSubtitle).get
362
- end
363
- end
364
-
365
- # Your cell
366
- class StoreCell < UITableViewCell
367
- def rmq_build
368
- q = rmq(self.contentView)
369
- q.append(UILabel, :title_label) # <- this works even though this object isn't in a controller
370
-
371
- # Use built in views, this assumes you're using the UITableViewCellStyleSubtitle style for the cell
372
- q.build(self.textLabel, :cell_label)
373
- q.build(self.imageView, :cell_image)
374
- q.build(self.detailTextLabel, :cell_label_detail)
375
- end
376
- end
377
- ```
378
-
379
-
380
- <br />
381
-
382
- ### Traversing
383
-
384
- ----
385
-
386
- Moving around the subview tree.
387
-
388
- Used often:
389
-
390
- - view_controller
391
- - root_view # View of the view_controller
392
-
393
- The rest of traversing isn't used too often, but when you need it, it's super handy. The most common methods used are:
394
-
395
- - window # Window of the root_view
396
- - all
397
- - closest
398
- - find
399
-
400
- These are less common:
401
-
402
- - and
403
- - not
404
- - and_self
405
- - back - _rmq(test_view).find(UIImageView).tag(:foo).back.find(UILabel).tag(:bar)_
406
- - children
407
- - siblings
408
- - next
409
- - prev
410
- - parent
411
- - parents
412
- - filter
413
-
414
-
415
- <br />
416
-
417
- ### Enumerablish
418
-
419
- ----
420
-
421
- A rmq object is like an enumerable, but each method returns a rmq object instead of a enumerable. For example, these methods:
422
-
423
- - each
424
- - map
425
- - select
426
- - grep
427
- - detect
428
- - inject
429
- - first
430
- - last
431
- - []
432
- - <<
433
- - *etc*
434
-
435
- all return another rmq instance, so you can chain.
436
-
437
- You can also do **rmq.length** and **rmq[0]** like an array
438
-
439
- **.to_a** gives you an actual array, so will **.get** (this is preferred)
440
-
441
-
442
-
443
- <br />
444
-
445
- ### Layout/Frame System & Position
446
-
447
- ----
448
-
449
-
450
- ```
451
- Options for layout, move, and frame:
452
-
453
- :full
454
- :left :l :from_right :fr
455
- :top :t :from_right :fb
456
- :width :w
457
- :height :h
458
-
459
- Options for nudge:
460
-
461
- :left :l
462
- :right :r
463
- :up :u
464
- :down :d
465
-
466
- Values for each option can be:
467
-
468
- signed int
469
- float
470
- ```
471
-
472
- ```ruby
473
- # In a style
474
- def some_style(st)
475
- st.frame = {l: 20, t: 20, w: 100, h: 50}
476
- end
477
-
478
-
479
- # Layout, move, or resize selected views
480
- rmq(your_view).layout(left: 20, top: 20, width: 100, height: 50)
481
- rmq(your_view).layout(l: 20)
482
- rmq(your_view).layout(left: 20)
483
- rmq(your_view).layout(l: 20, t: 20, w: 100, h: 50)
484
- rmq(your_view).layout(left: 20, top: 20, width: 100, height: 50)
485
-
486
- rmq(your_view).move(left: 20) # alias for layout
487
- rmq(your_view).move(l: 30, t: 50) # alias for layout
488
- rmq(your_view).resize(width: 100, height: 50) # alias for layout
489
-
490
- # Nudge pushes them in a direction
491
- rmq(your_view).nudge(d: 20)
492
- rmq(your_view).nudge(down: 20)
493
- rmq(your_view).nudge(l: 20, r: 20, u: 100, d: 50)
494
- rmq(your_view).nudge(left: 20, right: 20, up: 100, down: 50)
495
-
496
- # Distribute
497
- rmq(UIButton).distribute
498
- rmq(UIButton).distribute(:vertical)
499
- rmq(UIButton).distribute(:horizontal)
500
- rmq(UIButton).distribute(:vertical, margin: 20)
501
- rmq(my_view, my_other_view, third_view).distribute(:vertical, margin: 10)
502
- rmq(UIButton).distribute(:vertical, margins: [5,5,10,5,10,5,10,20])
503
- ```
504
-
505
-
506
- <br />
507
-
508
- ### Events and Gestures
509
-
510
- ----
511
-
512
- #### On / Off
513
-
514
- To add an event, use .on, to remove it it, use .off
515
-
516
- ```ruby
517
- # Simple example
518
- rmq(UIView).on(:tap){|sender| rmq(sender).hide}
519
-
520
- # Adding an Event during creation
521
- view_q = rmq.append(UIView).on(:tap) do |sender, event|
522
- # do something here
523
- end
524
-
525
- # removing an Event
526
- view_q.off(:tap)
527
-
528
- # or you remove them all
529
- view_q.off
530
-
531
- # like everything in RMQ, this works on all items selected
532
- rmq(UIView).off(:tap)
533
- ```
534
-
535
- #### RubyMotionQuery::Event
536
-
537
- In RMQ events and gestures are normalized with the same API. For example removing events or gestures is foo.off, and the appropriate thing happens.
538
-
539
- If you see Event, just remember that's either an event or gesture. I decided to call them Events
540
-
541
- ##### Type of events and gestures
542
-
543
- ```ruby
544
- # Events on controls
545
- :touch
546
- :touch_up
547
- :touch_down
548
- :touch_start
549
- :touch_stop
550
- :change
551
-
552
- :touch_down_repeat
553
- :touch_drag_inside
554
- :touch_drag_outside
555
- :touch_drag_enter
556
- :touch_drag_exit
557
- :touch_up_inside
558
- :touch_up_outside
559
- :touch_cancel
560
-
561
- :value_changed
562
-
563
- :editing_did_begin
564
- :editing_changed
565
- :editing_did_change
566
- :editing_did_end
567
- :editing_did_endonexit
568
-
569
- :all_touch
570
- :all_editing
571
-
572
- :application
573
- :system
574
- :all
575
-
576
- # Gestures
577
- :tap
578
- :pinch
579
- :rotate
580
- :swipe
581
- :swipe_up
582
- :swipe_down
583
- :swipe_left
584
- :swipe_right
585
- :pan
586
- :long_press
587
- ```
588
-
589
- ##### Interesting methods of an RubyMotionQuery::Event:
590
- ```ruby
591
- foo.sender
592
- foo.event
593
-
594
- foo.gesture?
595
- foo.recognizer
596
- foo.gesture
597
-
598
- foo.location
599
- foo.location_in
600
-
601
- foo.sdk_event_or_recognizer
602
- ```
603
-
604
- TODO, need many examples here
605
-
606
- #### RubyMotionQuery::Events
607
-
608
- The internal store of events in a UIView. It's rmq.events, you won't use it too often
609
-
610
-
611
- <br />
612
-
613
- ### Tags
614
-
615
- ----
616
-
617
- ```ruby
618
- # Add tags
619
- rmq(my_view).tag(:your_tag)
620
- rmq(my_view).clear_tags.tag(:your_new_tag)
621
-
622
- rmq(my_view).find(UILabel).tag(:selected, :customer)
623
-
624
- # You can optionally store a value in the tag, which can be super useful in some rare situations
625
- rmq(my_view).tag(your_tag: 22)
626
- rmq(my_view).tag(your_tag: 22, your_other_tag: 'Hello world')
627
-
628
-
629
- # You can use a tag or tags as selecors
630
- rmq(:selected).hide
631
- rmq(:your_tag).and(:selected).hide
632
-
633
- # Get tags for a view
634
- your_view.rmq_data.tags
635
- # Also
636
- your_view.rmq_data.has_tag?(:foo)
637
- your_view.rmq_data.tag_names
638
- ```
639
-
640
-
641
- <br />
642
-
643
- ### Actions
644
-
645
- ----
646
-
647
- ```ruby
648
- rmq(UILabel).attr(text: 'Foo bar')
649
- rmq(UILabel).send(:some_method, args)
650
- rmq(my_view).hide
651
- rmq(my_view).show
652
- rmq(my_view).toggle
653
- rmq(my_view).toggle_enabled
654
- rmq(my_text_field).focus # or .become_first_responder
655
- ```
656
-
657
-
658
- <br />
659
-
660
- ### Animate
661
-
662
- ----
663
-
664
- The most basic:
665
-
666
- ```ruby
667
- rmq.animate do |q|
668
- rmq(UIButton).nudge r: 40
669
- end
670
- ```
671
-
672
- Some more options, this time it is animating a selected view:
673
-
674
- ```ruby
675
- rmq(my_view).animate(
676
- duration: 0.3,
677
- animations: lambda{|q|
678
- q.move left: 20
679
- }
680
- )
681
- ```
682
-
683
- ```ruby
684
- # As an example, this is the implementation of .animations.throb
685
- rmq(selectors).animate(
686
- duration: 0.1,
687
- animations: -> (q) {
688
- q.style {|st| st.scale = 1.1}
689
- },
690
- completion: -> (did_finish, q) {
691
- q.animate(
692
- duration: 0.4,
693
- animations: -> (cq) {
694
- cq.style {|st| st.scale = 1.0}
695
- }
696
- )
697
- }
698
- )
699
-
700
- # You can pass any options that animateWithDuration allows: options: YOUR_OPTIONS
701
- ```
702
-
703
-
704
- <br />
705
-
706
- ### Animations
707
-
708
- ----
709
-
710
- See animate above.
711
-
712
- #### Current animations included:
713
-
714
- ```ruby
715
- rmq(my_view).animations.fade_in
716
- rmq(my_view).animations.fade_in(duration: 0.8)
717
- rmq(my_view).animations.fade_out
718
- rmq(my_view).animations.fade_out(duration: 0.8)
719
-
720
- rmq(my_view).animations.blink
721
- rmq(my_view).animations.throb
722
- rmq(my_view).animations.sink_and_throb
723
- rmq(my_view).animations.land_and_sink_and_throb
724
- rmq(my_view).animations.drop_and_spin
725
-
726
- rmq.animations.start_spinner
727
- rmq.animations.stop_spinner
728
- ```
729
-
730
-
731
- <br />
732
-
733
- ### Color
734
-
735
- ----
736
-
737
- ```ruby
738
- rmq.color.red
739
- rmq.color.from_hex('#ffffff')
740
- rmq.color.from_hex('ffffff')
741
- rmq.color.from_rgba(128, 128, 128, 0.5)
742
-
743
- # Add a new standard color
744
- rmq.color.add_named :pitch_black, '#000000'
745
- # Or
746
- rmq.color.add_named :pitch_black, rmq.color.black
747
-
748
- # In a stylesheet you don't need the rmq
749
- color.pitch_black
750
- color.red
751
- ```
752
-
753
- <br />
754
-
755
- ### Font
756
-
757
- ----
758
-
759
- ```ruby
760
- rmq.font.system(12)
761
- rmq.font_with_name('Helvetica', 18)
762
- rmq.font.family_list # useful in console
763
- rmq.font.for_family('Helvetica') # useful in console
764
-
765
- # Add a new standard font
766
- font_family = 'Helvetica Neue'
767
- font.add_named :large, font_family, 36
768
- font.add_named :medium, font_family, 24
769
- font.add_named :small, font_family, 18
770
-
771
- # then use them like so
772
- rmq.font.large
773
- rmq.font.small
774
-
775
- # In a stylesheet you don't need the rmq
776
- font.medium
777
- font.system(14)
778
- ```
779
-
780
-
781
63
  <br />
782
64
 
783
- ### Images
784
-
785
- ----
786
-
787
-
788
- RMQ provides various features for dealing with images.
789
-
790
- If you want to load an image from your **/resources** folder (_which is where they should be_), you can either load it and cache it (**imageNamed**) or load it and not cache it (**NSBundle.mainBundle.pathForResource**):
791
-
792
- ```ruby
793
- rmq.image.resource('foo') # /resources/foo@2x.png
794
- rmq.image.resource('foo', cached: false)
795
- # In a stylesheet
796
- st.background_image = image.resource('foo')
797
- ```
798
-
799
- **Capped images**
800
-
801
- Sometimes when you apply a background_image to a view you want the image to stretch to the size of the view without stretching the corners of the image, for example if you're making a rounded button. The SDK has a nice feature for this, called UIImage#resizableImageWithCapInsets. It stretches the center of your image, but not the corners.
802
-
803
- Let's say you want to create this, like we did in [Temple](http://app.temple.cx/):
804
-
805
- ![Bar](https://ir_wp.s3.amazonaws.com/wp-content/uploads/sites/18/2014/03/bar.png)
806
-
807
- The red bar grows horizontally. But it has rounded caps. So we created this image ![Cap image](https://ir_wp.s3.amazonaws.com/wp-content/uploads/sites/18/2014/03/bar_poor@2x.png), which is the caps, plus one pixel to stretch. Here it is blown up and I dimmed the 4 caps:
808
-
809
- ![Cap image](https://ir_wp.s3.amazonaws.com/wp-content/uploads/sites/18/2014/03/blown_up.png)
810
-
811
- Basically just the center line of it stretches, the other 4 quadrants do not. RMQ makes this very easy. You create a UIImageView, then in the style (or anywhere) you set the image like so:
812
-
813
- ```ruby
814
- rmq.append(UIImageView, :your_style)
815
- # Then in your style
816
- st.image = image.resource_resizable('your_image', top: 4, left: 4, right: 4, bottom: 4)
817
- ```
818
-
819
- The top, left, etc, tell which parts of the image not to stretch. You can now resize your view and it will look great.
820
-
821
- **Snapshot of a view**
822
-
823
- Lastly you can get an image of a view, meaning a "screenshot" of it:
824
-
825
- ```ruby
826
- my_image_view.image = rmq.image.from_view(some_view)
827
- ```
828
-
829
- **Other examples**
830
-
831
- ```ruby
832
- RubyMotionQuery::ImageUtils.resource('logo')
833
- rmq.image.resource('logo')
834
- rmq.image.resource('subfolder/foo')
835
- rmq.image.resource_for_device('logo') # will look for 4inch or 3.5inch
836
- rmq.image.resource('logo', cached: false)
837
-
838
- rmq.image.resource_resizable('foo', left: 10, top: 10, right: 10, bottom: 10)
839
-
840
- rmq.image.from_view(my_view)
841
-
842
- # In a stylesheet you don't need the rmq
843
- image.resource('logo')
844
- ```
845
-
846
-
847
- <br />
848
-
849
- ### App
850
-
851
- ----
852
-
853
- ```ruby
854
- RubyMotionQuery::App.window
855
- rmq.app.window
856
- rmq.app.delegate
857
- rmq.app.environment
858
- rmq.app.release? # .production? also
859
- rmq.app.test?
860
- rmq.app.development?
861
- rmq.app.version
862
- rmq.app.name
863
- rmq.app.identifier
864
- rmq.app.resource_path
865
- rmq.app.document_path
866
- ```
867
-
868
-
869
- <br />
870
-
871
- ### Device
872
-
873
- ----
874
-
875
- ```ruby
876
- RubyMotionQuery::Device.screen
877
- rmq.device.screen
878
- rmq.device.width # screen width
879
- rmq.device.height # screen height
880
- rmq.device.ipad?
881
- rmq.device.iphone?
882
- rmq.device.four_inch?
883
- rmq.device.retina?
884
-
885
- # return values are :unknown, :portrait, :portrait_upside_down, :landscape_left,
886
- # :landscape_right, :face_up, :face_down
887
- rmq.device.orientation
888
- rmq.device.landscape?
889
- rmq.device.portrait?
890
- ```
891
-
892
-
893
- <br />
894
-
895
- ### Format
896
-
897
- ----
898
-
899
- A performant way to format numbers and dates.
900
-
901
- ```ruby
902
- rmq.format.number(1232, '#,##0.##')
903
- rmq.format.date(Time.now, 'EEE, MMM d, ''yy')
904
- rmq.format.numeric_formatter(your_format_here) # returns cached numeric formatter
905
- rmq.format.date_formatter(your_format_here) # returns cached date formatter
906
- ```
907
- See <http://www.unicode.org/reports/tr35/tr35-19.html#Date_Format_Patterns> for more information about date format strings.
908
-
909
-
910
- <br />
911
-
912
- ### Utils
913
-
914
- ----
915
-
916
- These are mostly used internally by rmq.
917
-
918
- ```ruby
919
- RubyMotionQuery::RMQ.is_class?(foo)
920
- RubyMotionQuery::RMQ.is_blank?(foo)
921
- RubyMotionQuery::RMQ.controller_for_view(view)
922
- RubyMotionQuery::RMQ.view_to_s(view)
923
- RubyMotionQuery::RMQ.weak_ref(foo)
924
- ```
925
-
926
-
927
- <br />
928
-
929
- ### Pollution
930
-
931
- ----
932
-
933
- The following are the only pollution in RMQ
934
-
935
- - UIView
936
- - rmq
937
- - rmq_data
938
- - UIViewController
939
- - rmq
940
- - rmq_data
941
- - Object
942
- - rmq
943
-
944
-
945
- <br />
946
-
947
- ### Console Fun
948
-
949
- ----
950
-
951
- ```ruby
952
- rmq.log :tree
953
- rmq.all.log
954
- rmq.all.log :wide
955
- rmq(UIView).show
956
- rmq(UILabel).animations.blink
957
- rmq(UIButton).nudge l: 10
958
- ```
959
-
960
-
961
- <br />
962
-
963
- ### A recommended project structure
964
-
965
- ----
966
-
967
- - app
968
- - controllers
969
- - your_controller.rb
970
- - your_other_controller.rb
971
- - models
972
- - shared
973
- - stylers
974
- - ui_view_styler.rb
975
- - ui_button_styler.rb
976
- - etc
977
- - stylesheets
978
- - application_stylesheet.rb (inherit from RubyMotionQuery::Stylesheet)
979
- - your_stylesheet.rb (inherit from ApplicationStylesheet)
980
- - your_other_stylesheet.rb (inherit from ApplicationStylesheet)
981
- - your_view_stylesheet.rb (module, included an any controller's stylesheet that needs it)
982
- - views
983
- - lib
984
- - resource
985
- - spec
986
- - controllers
987
- - lib
988
- - models
989
- - shared
990
- - stylers
991
- - views
992
-
993
-
994
- <br />
995
-
996
- ### Debugging
997
-
998
- ----
999
-
1000
- Adding rmq_debug=true to rake turns on some debugging features that are too slow or verbose to include in a normal build. It's great for normal use in the simulator, but you'll want to leave it off if you're measuring performance.
1001
- ```
1002
- rake rmq_debug=true
1003
- ```
1004
-
1005
- Use this to add your optional debugging code
1006
- ```ruby
1007
- rmq.debugging?
1008
- => true
1009
- ```
1010
-
1011
- ```ruby
1012
- rmq.log :tree
1013
- rmq.all.log
1014
- rmq.all.log :wide
1015
-
1016
- rmq(Section).log :tree
1017
- # 163792144 is the ID a button
1018
- rmq(163792144).style{|st| st.background_color = rmq.color.blue}
1019
-
1020
- rmq(Section).children.and_self.log :wide
1021
-
1022
- rmq(UILabel).animations.blink
1023
-
1024
- # Show subview index and thus zorder of Section within Section's parent
1025
- rmq(Section).parent.children.log
1026
- ```
1027
-
1028
-
1029
- <br />
1030
-
1031
- ### Styles and stylesheets
1032
-
1033
- ----
1034
-
1035
- A very lightweight style system, designed for a low memory footprint, fast startup, and fast operation. Most everything is done at compile-time, as it's all just ruby code. Low magic.
1036
-
1037
- **You don't have to use this system, you can use Teacup instead**, or whatever you like. RMQ works great without using the style system.
1038
-
1039
- #### Example controller
1040
-
1041
- ```ruby
1042
- class MainController < UIViewController
1043
-
1044
- def viewDidLoad
1045
- super
1046
-
1047
- rmq.stylesheet = MainStyleSheet # Each controller has its own stylesheet
1048
- view.rmq.apply_style :root_view
1049
-
1050
- @title_label = rmq.append(UILabel, :title_label).get
1051
-
1052
- image_view = rmq.append(UIImageView).get
1053
- # Apply style anywhere
1054
- image_view.apply_style(:logo)
1055
-
1056
- rmq.append(UIButton, :make_labels_blink).on(:tap) do |sender|
1057
- rmq(UILabel).animations.blink
1058
- end
1059
-
1060
- rmq.append(UIButton.buttonWithType(UIButtonTypeRoundedRect), :make_buttons_throb).on(:tap) do |sender|
1061
- rmq(UIButton).animations.throb
1062
- end
1063
-
1064
- rmq.append(UIView, :section).tap do |section|
1065
- section.append(UILabel, :section_title)
1066
-
1067
- section.append(UILabel, :section_enabled_title)
1068
-
1069
- section.append(UISwitch, :section_enabled).on(:change) do |sender|
1070
- style = sender.isOn ? :section_button_enabled : :section_button_disabled
1071
- buttons = sender.rmq.parent.find(UIButton).apply_style(style)
1072
- end
1073
-
1074
- section.append(UIButton, :start_spinner).on(:tap) do |sender|
1075
- rmq.animations.start_spinner
1076
- end
1077
-
1078
- section.append(UIButton, :stop_spinner).on(:tap) do |sender|
1079
- rmq.animations.stop_spinner
1080
- end
1081
- end
1082
-
1083
- end
1084
- end
1085
- ```
1086
-
1087
- #### Example stylesheet
1088
-
1089
- ```ruby
1090
- class ApplicationStylesheet < RubyMotionQuery::Stylesheet
1091
- PADDING = 10
1092
-
1093
- def application_setup
1094
- font_family = 'Helvetica Neue'
1095
- font.add_named :large, font_family, 36
1096
- font.add_named :medium, font_family, 24
1097
- font.add_named :small, font_family, 18
1098
-
1099
- color.add_named :translucent_black, color.from_rgba(0, 0, 0, 0.4)
1100
- color.add_named :battleship_gray, '#7F7F7F'
1101
- end
1102
-
1103
- def label(st)
1104
- st.background_color = color.clear
1105
- end
1106
-
1107
- end
1108
-
1109
- class MainStylesheet < ApplicationStylesheet
1110
- def setup
1111
- # Add stylesheet specific setup stuff here.
1112
- # Add application specific setup stuff in application_stylesheet.rb
1113
- end
1114
-
1115
- def root_view(st)
1116
- st.background_color = color.white
1117
- end
1118
-
1119
- def logo(st)
1120
- st.frame = {t: 10, w: 200, h: 96}
1121
- st.centered = :horizontal
1122
- st.image = image.resource('logo')
1123
- end
1124
-
1125
- def title_label(st)
1126
- label st # stack styles
1127
- st.frame = {l: PADDING, t: 120, w: 200, h: 20}
1128
- st.text = 'Test label'
1129
- st.color = color.from_rgba(34, 132, 198, 1.0)
1130
- st.font = font.medium
1131
- end
1132
-
1133
- def make_labels_blink(st)
1134
- st.frame = {t: 120, w: 150, h: 20}
1135
- st.from_right = PADDING
1136
-
1137
- # ipad? (and landscape?, etc) is just a convenience methods for
1138
- # rmq.device.ipad?
1139
-
1140
- # Here is a complete example of different formatting for orientations
1141
- # and devices
1142
- # if ipad?
1143
- # if landscape?
1144
- # st.frame = {l: 20, t: 120, w: 150, h: four_inch? ? 20 : 30}
1145
- # else
1146
- # st.frame = {l: 90, t: 120, w: 150, h: four_inch? ? 25 : 35}
1147
- # end
1148
- # else
1149
- # if landscape?
1150
- # st.frame = {l: 20, t: 20, w: 150, h: four_inch? ? 22 : 32}
1151
- # else
1152
- # st.frame = {l: 90, t: 20, w: 150, h: four_inch? ? 30 : 40}
1153
- # end
1154
- # end
1155
-
1156
- # If you don't want something to be reapplied during orientation
1157
- # changes (assuming you're reapplying during orientation changes
1158
- # in your controller, it's not automatic)
1159
- unless st.view_has_been_styled?
1160
- st.text = 'Blink labels'
1161
- st.font = font.system(10)
1162
- st.color = color.white
1163
- st.background_color = color.from_hex('ed1160')
1164
- end
1165
- end
1166
-
1167
- def make_buttons_throb(st)
1168
- st.frame = {t: 150, w: 150, h: 20}
1169
- st.from_right = PADDING
1170
- st.text = 'Throb buttons'
1171
- st.color = color.black
1172
- end
1173
-
1174
- def section(st)
1175
- st.frame = {from_bottom: PADDING, w: 270, h: 110}
1176
-
1177
- if landscape? && iphone?
1178
- st.left = PADDING
1179
- else
1180
- st.centered = :horizontal
1181
- end
1182
-
1183
- st.z_position = 1
1184
- st.background_color = color.battleship_gray
1185
- end
1186
-
1187
- def section_label(st)
1188
- label st
1189
- st.color = color.white
1190
- end
1191
-
1192
- def section_title(st)
1193
- section_label st
1194
- st.frame = {l: PADDING, t: PADDING, w: 150, h: 20}
1195
- st.text = 'Section title'
1196
- end
1197
-
1198
- def section_enabled(st)
1199
- label st
1200
- st.frame = {l: PADDING, t: 30}
1201
- st.on = true
1202
- end
1203
-
1204
- def section_enabled_title(st)
1205
- section_label st
1206
- st.frame = {l: 93, t: 34, w: 150, h: 20}
1207
- st.text = 'Enabled'
1208
- end
1209
-
1210
- def section_buttons(st)
1211
- st.frame = {l: PADDING, t: 64, w: 120, h: 40}
1212
- st.background_color = color.black
1213
- section_button_enabled st
1214
- end
1215
-
1216
- def start_spinner(st)
1217
- section_buttons st
1218
- st.text = 'Start spinner'
1219
- end
1220
-
1221
- def stop_spinner(st)
1222
- section_buttons st
1223
- st.from_right = PADDING
1224
- st.text = 'Stop spinner'
1225
- end
1226
-
1227
- def section_button_disabled(st)
1228
- st.enabled = false
1229
- st.color = color.dark_gray
1230
- end
1231
-
1232
- def section_button_enabled(st)
1233
- st.enabled = true
1234
- st.color = color.white
1235
- end
1236
-
1237
- def animate_move(st)
1238
- st.scale = 1.0
1239
- st.frame = {t: 180, w: 150, h: 20}
1240
- st.from_right = PADDING
1241
- st.text = 'Animate move and scale'
1242
- st.font = font.system(10)
1243
- st.color = color.white
1244
- st.background_color = color.from_hex('ed1160')
1245
- st.z_position = 99
1246
- st.color = color.white
1247
- end
1248
-
1249
- def overlay(st)
1250
- st.frame = :full
1251
- st.background_color = color.translucent_black
1252
- st.hidden = true
1253
- st.z_position = 99
1254
- end
1255
-
1256
- def benchmarks_results_wrapper(st)
1257
- st.hidden = true
1258
- st.frame = {w: app_width - 20, h: 120}
1259
- st.centered = :both
1260
- st.background_color = color.white
1261
- st.z_position = 100
1262
- end
1263
-
1264
- def benchmarks_results_label(st)
1265
- label st
1266
- st.padded = {l: 10, t: 10, b:10, r: 10}
1267
- st.text_alignment = :left
1268
- st.color = color.black
1269
- st.font = font.system(10)
1270
-
1271
- # If the styler doesn't have the method, you can add it or
1272
- # just use st.view to get the actual object
1273
- st.view.numberOfLines = 0
1274
- st.view.lineBreakMode = NSLineBreakByWordWrapping
1275
- end
1276
-
1277
- def run_benchmarks(st)
1278
- st.frame = {l: PADDING, t: 150, w: 130, h: 20}
1279
- st.text = 'Run benchmarks'
1280
- st.font = font.system(11)
1281
- st.color = color.white
1282
- st.enabled = true
1283
- st.background_color = color.from_hex('faa619')
1284
- end
1285
-
1286
- def run_benchmarks_disabled(st)
1287
- st.enabled = false
1288
- st.color = color.from_hex('de8714')
1289
- end
1290
-
1291
- def benchmark(st)
1292
- st.hidden = false
1293
- st.text = 'foo'
1294
- st.color = color.white
1295
- st.left = 10
1296
- end
1297
-
1298
- end
1299
- ```
1300
-
1301
- #### Stylers
1302
-
1303
- A styler wraps around a view, augmenting it with styling power and sugar.
1304
-
1305
- Each UIView subclass can have its own styler (many exist in RMQ, but not all *yet*). There is a UIViewStyler class they all inherit from, and a UIControlStyler controls inherit from. Much of the code is in UIViewStyler.
1306
-
1307
- When you create a "style method", it will be passed the view, wrapped in a styler. You can get the view using st.view.
1308
-
1309
- ##### UIViewStyler
1310
- Here is a silly example, showing you a bunch of methods the UIViewStyler gives you:
1311
-
1312
- ```ruby
1313
- def ui_view_kitchen_sink(st)
1314
- st.frame = {l: 1, t: 2, w: 3, h: 4}
1315
- st.frame = {left: 1, top: 2, width: 3, height: 4}
1316
- st.frame = {from_right: 1, from_bottom: 2, width: 3, height: 4}
1317
- st.frame = {fr: 1, fb: 2, w: 3, h: 4}
1318
- st.left = 20
1319
- st.top = 30
1320
- st.width = 40
1321
- st.height = 50
1322
- st.right = 100
1323
- st.bottom = 110
1324
- st.from_right = 10
1325
- st.from_bottom = 12
1326
- st.padded = {l: 1, t: 2, r: 3, b: 4}
1327
- st.padded = {left: 1, top: 2, right: 3, bottom: 4}
1328
- st.center = st.superview.center
1329
- st.center_x = 50
1330
- st.center_y = 60
1331
- st.centered = :horizontal
1332
- st.centered = :vertical
1333
- st.centered = :both
1334
-
1335
- st.enabled = true
1336
- st.hidden = false
1337
- st.z_position = 66
1338
- st.opaque = false
1339
- st.clips_to_bounds = false
1340
- st.hidden = true
1341
- st.content_mode = UIViewContentModeBottomLeft
1342
-
1343
- st.background_color = color.red
1344
- # TODO test background_image
1345
-
1346
- st.scale = 1.5
1347
- st.rotation = 45
1348
- st.tint_color = color.blue
1349
- st.layer.cornerRadius = 5
1350
- end
1351
- ```
1352
-
1353
- ##### UIControlStyler
1354
- Nothing yet
1355
-
1356
- ##### UILabelStyler
1357
-
1358
- ```ruby
1359
- def ui_label_kitchen_sink(st)
1360
- st.text = 'rmq is awesome'
1361
- st.font = font.system(12)
1362
- st.color = color.black
1363
- st.text_alignment = :center
1364
-
1365
- st.resize_to_fit_text
1366
- st.size_to_fit
1367
- end
1368
- ```
1369
-
1370
- ##### UIButtonStyler
1371
-
1372
- ```ruby
1373
- def ui_button_kitchen_sink(st)
1374
- st.text = 'foo'
1375
- st.font = font.system(12)
1376
- st.color = color.red
1377
- st.image_normal = image.resource('logo')
1378
- st.image_highlighted = image.resource('logo')
1379
- end
1380
- ```
1381
-
1382
- ##### UIImageViewStyler
1383
-
1384
- ```ruby
1385
- def u_image_view_kitchen_sink(st)
1386
- st.image = image.resource('logo')
1387
- end
1388
- ```
1389
-
1390
- ##### UIScrollViewStyler
1391
-
1392
- ```ruby
1393
- def ui_scroll_view_kitchen_sink(st)
1394
- st.paging = true
1395
- end
1396
- ```
1397
-
1398
- ##### UISwitchStyler
1399
-
1400
- ```ruby
1401
- def ui_switch_kitchen_sink(st)
1402
- st.on = true
1403
- end
1404
- ```
1405
-
1406
- **There should be a styler for each UIView type. And each one should wrap all common methods and attributes, plus add functionality for common operations. This will come in future versions**
1407
-
1408
- #### Add your own stylers
1409
-
1410
- In the example app, look in **/app/stylers**, you can just copy that whole folder to start. Then add methods to the appropriate class.
1411
-
1412
- Here is an example of adding a method to all stylers:
1413
- ```ruby
1414
- module RubyMotionQuery
1415
- module Stylers
1416
- class UIViewStyler
1417
-
1418
- def border_width=(value)
1419
- @view.layer.borderWidth = value
1420
- end
1421
- def border_width
1422
- @view.layer.borderWidth
1423
- end
1424
-
1425
- end
1426
- end
1427
- end
1428
- ```
1429
-
1430
- You can also include all of your custom stylers in one file, which works well if you don't have a lot.
1431
-
1432
-
1433
- <br />
1434
-
1435
- ### Creating your own views
1436
-
1437
- ----
1438
-
1439
- RMQ calls 3 methods when you create, append, or build a view using rmq. rmq_build is the one you most want to use
1440
- ```ruby
1441
- def rmq_build
1442
- end
1443
-
1444
- def rmq_created
1445
- end
1446
-
1447
- def rmq_appended
1448
- end
1449
- ```
1450
- If you append a view like so:
1451
- ```ruby
1452
- rmq.append(UILabel)
1453
- ```
1454
- The 3 methods will be called in this order:
1455
- - rmq_created
1456
- - rmq_appended
1457
- - rmq_build
1458
-
1459
- In the following example an instance of YourView is created, :your_style is applied
1460
- then rmq_build is called on the instance that was just created. In that
1461
- order.
1462
-
1463
- ```ruby
1464
- # Your view
1465
- class YourView < UIView
1466
- def rmq_build
1467
- rmq(self).tap do |q|
1468
- q.append(UILabel, :section_title)
1469
- q.append(UIButton, :buy_button).on(:tap) do |sender|
1470
- # do something
1471
- end
1472
- end
1473
- end
1474
- end
1475
-
1476
- # In your controller
1477
- rmq.append(YourView, :your_style)
1478
- ```
1479
-
1480
-
1481
- <br />
1482
-
1483
- ### Future features
1484
-
1485
- ----
1486
-
1487
- Current roadmap:
1488
-
1489
- - v0.6 new frame system: I’ve already designed this, I just have to implement it and use it in the real world and tweak. This is going to be very cool. It adds to the existing frame system. It doesn’t replace constraints, but rather gives you almost all the features you need without the complexity of constraints.
1490
- - v0.6.5 templates and stylers all finished
1491
- - v0.6.7 performance improvements
1492
- - v0.7 first rmq plugin and any base features needed to support plugins (I don’t think there will be any base features needed)
1493
- - v0.8 binding system
1494
- - ?
1495
- - ?
1496
- - v1.0
1497
-
1498
- Random future features that I plan on adding
1499
-
1500
- - rmq.push_sub_controller(my_controller) and rmq.pop_sub_controller and rmq.pop_this_controller
1501
- - add borders to UIView styler: st.borders = {l: {w: 2, color: color.black}, r: {w: 2, color: color.black}}
1502
- - add templates for: nav controller, tab controller, table controller, collection controller
1503
- - add from_right, from_bottom, and centered to both st.frame and to move
1504
- - add binding that combines KVO and events to bind an attribute of one object to the attribute of selected view(s), keeping both in sync, like so: rmq.append(UITextField).bind(@person, attr: :name, to: :text)
1505
- - rmq.log to wrap nslog to allow you to turn off logging (or does NSLog already have this feature?)
1506
- - add selectors for UITextField
1507
- - add string to height utility, given the font and the width
1508
- - add block to wrap useful for a variety of things, but here is solid example: rmq.append(UIButton).tag(:foo).wrap{|view| view.titleLabel}.tag(:foo_title)
1509
- - add def rmq_build_with_properties(props = {}). Perhaps remove rmq_created and rmq_appended, not sure if those are useful or not
1510
- - add easy way to do alerts and actionsheets
1511
- - add rmq.help with basic help for when you're in repl
65
+ ### License
1512
66
 
67
+ RMQ is available under the MIT license. See the [LICENSE](https://github.com/infinitered/rmq/blob/master/LICENSE) file for more info.
1513
68
 
1514
69
 
1515
70
  <br />
1516
71
 
1517
- ### Contact
1518
-
1519
- ----
1520
-
1521
- created by **Todd Werth** ([http://toddwerth.com](http://toddwerth.com))
72
+ ### Created by Todd Werth ([http://toddwerth.com](http://toddwerth.com))
1522
73
 
1523
74
  - [@twerth](http://twitter.com/twerth)
1524
75
  - [todd@infinitered.com](mailto:todd@infinitered.com)
1525
76
  - [github](https://github.com/twerth)
1526
77
 
1527
- with help from the team at **InfiniteRed** ([http://infinitered.com](http://infinitered.com))
1528
-
1529
- - [@infinite_red](http://twitter.com/infinite_red)
1530
- - [github](https://github.com/infinitered)
1531
-
1532
-
1533
78
 
1534
79
  <br />
1535
80
 
1536
- ### License
1537
-
1538
- ----
1539
-
1540
- RMQ is available under the MIT license. See the LICENSE file for more info.
1541
-
81
+ ### [Contributors](https://github.com/infinitered/rmq/graphs/contributors)
1542
82
 
1543
83
  <br />
1544
84
 
1545
85
  ### Contributing
1546
86
 
1547
- ----
1548
-
1549
87
  1. Fork it
1550
88
  2. Create your feature branch (`git checkout -b my-new-feature`)
1551
89
  3. Commit your changes (`git commit -am 'Add some feature'`)
1552
90
  4. Push to the branch (`git push origin my-new-feature`)
1553
91
  5. Create new Pull Request
1554
92
 
1555
- [1]: http://infinitered.com/rmq
93
+ <br />
94
+
95
+ ----------
96
+
97
+ ## Read the [RMQ Documentation][1] here
98
+
99
+ ----------
100
+
101
+ [1]: http://rubymotionquery.com