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.
@@ -61,5 +61,25 @@ module RubyMotionQuery
61
61
  self
62
62
  end
63
63
 
64
+ def enable
65
+ selected.each { |view| view.enabled = true }
66
+ self
67
+ end
68
+
69
+ def disable
70
+ selected.each { |view| view.enabled = false }
71
+ self
72
+ end
73
+
74
+ def enable_interaction
75
+ selected.each { |view| view.userInteractionEnabled = true }
76
+ self
77
+ end
78
+
79
+ def disable_interaction
80
+ selected.each { |view| view.userInteractionEnabled = false }
81
+ self
82
+ end
83
+
64
84
  end
65
85
  end
@@ -1,39 +1,42 @@
1
1
  module RubyMotionQuery
2
2
  class RMQ
3
3
 
4
+ # Animate
5
+ #
4
6
  # @return [RMQ]
5
7
  def animate(opts = {})
8
+ animations_callback = (opts[:animations] || opts[:changes])
9
+ after_callback = (opts[:completion] || opts[:after])
10
+ return self unless animations_callback
11
+
12
+
6
13
  working_selected = self.selected
7
- @_rmq = self # @ for rm bug
14
+ self_rmq = self
8
15
 
9
- animations_lambda = if (animations_callback = (opts.delete(:animations) || opts.delete(:changes)))
10
- -> do
11
- working_selected.each do |view|
12
- animations_callback.call(@_rmq.create_rmq_in_context(view))
13
- end
16
+ working_selected.each do |view|
17
+ view_rmq = self_rmq.wrap(view)
18
+
19
+ animations_lambda = -> do
20
+ animations_callback.call(view_rmq)
14
21
  end
15
- else
16
- nil
17
- end
18
22
 
19
- return self unless animations_lambda
23
+ after_lambda = if after_callback
24
+ ->(did_finish) {
25
+ after_callback.call(did_finish, view_rmq)
26
+ }
27
+ else
28
+ nil
29
+ end
20
30
 
21
- after_lambda = if (after_callback = (opts.delete(:completion) || opts.delete(:after)))
22
- -> (did_finish) {
23
- after_callback.call(did_finish, @_rmq)
24
- }
25
- else
26
- nil
31
+ UIView.animateWithDuration(
32
+ opts[:duration] || 0.3,
33
+ delay: opts[:delay] || 0,
34
+ options: opts[:options] || UIViewAnimationOptionCurveEaseInOut,
35
+ animations: animations_lambda,
36
+ completion: after_lambda
37
+ )
27
38
  end
28
39
 
29
- UIView.animateWithDuration(
30
- opts.delete(:duration) || 0.3,
31
- delay: opts.delete(:delay) || 0,
32
- options: (opts.delete(:options) || UIViewAnimationOptionCurveEaseInOut),
33
- animations: animations_lambda,
34
- completion: after_lambda
35
- )
36
-
37
40
  self
38
41
  end
39
42
 
@@ -86,34 +89,38 @@ module RubyMotionQuery
86
89
  def throb(opts = {})
87
90
  opts.merge!({
88
91
  duration: 0.4,
89
- animations: -> (cq) {
92
+ animations: ->(cq) {
90
93
  cq.style {|st| st.scale = 1.0}
91
94
  }
92
95
  })
93
96
 
94
- @rmq.animate(
97
+ out = @rmq.animate(
95
98
  duration: 0.1,
96
- animations: -> (q) {
99
+ animations: ->(q) {
97
100
  q.style {|st| st.scale = 1.1}
98
101
  },
99
- completion: -> (did_finish, q) {
100
- q.animate(opts)
102
+ completion: ->(did_finish, completion_rmq) {
103
+ if did_finish
104
+ completion_rmq.animate(opts)
105
+ end
101
106
  }
102
107
  )
108
+ out
103
109
  end
104
110
 
111
+ # @return [RMQ]
105
112
  def drop_and_spin(opts = {})
106
113
  remove_view = opts[:remove_view]
107
114
  opts.merge!({
108
115
  duration: 0.4 + (rand(8) / 10),
109
116
  options: UIViewAnimationOptionCurveEaseIn|UIViewAnimationOptionBeginFromCurrentState,
110
- animations: -> (cq) {
117
+ animations: ->(cq) {
111
118
  cq.style do |st|
112
119
  st.top = @rmq.device.height + st.height
113
120
  st.rotation = 180 + rand(50)
114
121
  end
115
122
  },
116
- completion: -> (did_finish, q) {
123
+ completion: ->(did_finish, q) {
117
124
  if did_finish
118
125
  q.style do |st|
119
126
  st.rotation = 0
@@ -26,7 +26,7 @@ module RubyMotionQuery
26
26
 
27
27
  # @return [Symbol] Environment the app is running it
28
28
  def environment
29
- RUBYMOTION_ENV.to_sym
29
+ @_environment ||= RUBYMOTION_ENV.to_sym
30
30
  end
31
31
 
32
32
  # @return [Boolean] true if the app is running in the :release environment
@@ -69,6 +69,26 @@ module RubyMotionQuery
69
69
  def document_path
70
70
  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true)[0]
71
71
  end
72
+
73
+ # Returns the current view controller in the app. If the current controller is a tab or
74
+ # navigation controller, then it gets the current tab or topmost controller in the nav.
75
+ #
76
+ # This mostly works... mostly. As there really isn't a "current view_controller"
77
+ #
78
+ # @return [UIViewController]
79
+ def current_view_controller(root_view_controller = nil)
80
+ if root_view_controller || ((window = RMQ.app.window) && (root_view_controller = window.rootViewController))
81
+ case root_view_controller
82
+ when UINavigationController
83
+ root_view_controller.visibleViewController
84
+ when UITabBarController
85
+ current_view_controller(root_view_controller.selectedViewController)
86
+ else
87
+ root_view_controller
88
+ end
89
+ end
90
+ end
91
+
72
92
  end
73
93
  end
74
94
  end
@@ -16,12 +16,36 @@ module RubyMotionQuery
16
16
  # controller that the view is currently in or to the current screen's
17
17
  # controller
18
18
  class RMQ
19
- attr_accessor :context
20
19
 
21
20
  def initialize
22
21
  @selected_dirty = true
23
22
  end
24
23
 
24
+ # This is mostly used internally
25
+ #
26
+ # If rmq was called in a view, context will be that view. If it was called
27
+ # in a UIViewController, it will be that controller. If it is called in another
28
+ # object, it will be current controller's rmq instance and thus context will be
29
+ # that controller
30
+ def context=(value)
31
+ if value
32
+ if value.is_a?(UIViewController)
33
+ @context = RubyMotionQuery::RMQ.weak_ref(value)
34
+ elsif value.is_a?(UIView)
35
+ @context = value
36
+ #else
37
+ #debug.log_detailed('Invalid context', objects: {value: value})
38
+ end
39
+ else
40
+ @context = nil
41
+ end
42
+ @context
43
+ end
44
+
45
+ def context
46
+ @context
47
+ end
48
+
25
49
  # Do not use
26
50
  def selected=(value)
27
51
  @_selected = value
@@ -90,6 +114,7 @@ module RubyMotionQuery
90
114
  @_parent_rmq
91
115
  end
92
116
  def parent_rmq=(value)
117
+ #debug.assert(value.is_a?(RMQ) || value.nil?, 'Invalid parent_rmq', { value: value })
93
118
  @_parent_rmq = value
94
119
  end
95
120
 
@@ -100,7 +125,7 @@ module RubyMotionQuery
100
125
  if pq = self.parent_rmq
101
126
  pq.selected
102
127
  else
103
- [self.view_controller.view]
128
+ [self.weak_view_controller.view]
104
129
  end
105
130
  end
106
131
 
@@ -284,19 +309,6 @@ module RubyMotionQuery
284
309
  out
285
310
  end
286
311
 
287
- class << self
288
- attr_accessor :cache_controller_rmqs
289
- @cache_controller_rmqs = true
290
-
291
- def debugging?
292
- @debugging ||= ENV['rmq_debug'] == 'true'
293
- end
294
-
295
- def debugging=(flag)
296
- @debugging = flag
297
- end
298
- end
299
-
300
312
  protected
301
313
  def extract_views_from_selectors(view_container, working_selectors)
302
314
  unless RMQ.is_blank?(working_selectors)
@@ -43,9 +43,19 @@ module RubyMotionQuery
43
43
  RMQ.is_blank?(@_tags)
44
44
  end
45
45
  end
46
+
47
+ def view_controller=(value)
48
+ #RubyMotionQuery::RMQ.debug.assert(value.is_a?(UIViewController), 'Invalid controller in ViewData', { controller: value })
49
+
50
+ @_view_controller = RubyMotionQuery::RMQ.weak_ref(value)
51
+ end
52
+
53
+ def view_controller
54
+ @_view_controller
55
+ end
46
56
  end
47
57
 
48
58
  class ControllerData
49
- attr_accessor :stylesheet, :rmq
59
+ attr_accessor :stylesheet, :cached_rmq
50
60
  end
51
61
  end
@@ -0,0 +1,92 @@
1
+ module RubyMotionQuery
2
+ class RMQ
3
+ def self.debug
4
+ Debug
5
+ end
6
+
7
+ def self.debugging?
8
+ @debugging ||= ENV['rmq_debug'] == 'true'
9
+ end
10
+
11
+ def self.debugging=(flag)
12
+ @debugging = flag
13
+ end
14
+
15
+ # @return [Debug]
16
+ def debug
17
+ Debug
18
+ end
19
+ end
20
+
21
+ # Notes:
22
+ #
23
+ # rake debug=1 NSZombieEnabled=YES
24
+ #
25
+ # rake debug=1 NSZombieEnabled=YES MallocStackLogging=1
26
+ # /usr/bin/malloc_history 89032 0x9508da0
27
+ # /usr/bin/malloc_history 47706 0x937e5c0 | grep "rb_scope__.+?__"
28
+ class Debug
29
+ class << self
30
+ # Warning, this is very slow
31
+ def log_detailed(label, params = {})
32
+ return unless RMQ.app.development? || RMQ.app.test?
33
+
34
+ objects = params[:objects]
35
+ skip_first_caller = params[:skip_first_caller]
36
+
37
+ if block_given? && !objects
38
+ objects = yield
39
+ end
40
+
41
+ callers = caller
42
+ callers = callers.drop(1) if skip_first_caller
43
+
44
+ out = %(
45
+
46
+ ------------------------------------------------
47
+ Deep log - #{label}
48
+ At: #{Time.now.to_s}
49
+
50
+ Callers:
51
+ #{callers.join("\n - ")}
52
+
53
+ Objects:
54
+ #{objects.map{|k, v| "#{k.to_s}: #{v.inspect}" }.join("\n\n")}
55
+ ------------------------------------------------
56
+
57
+ ).gsub(/^ +/, '')
58
+
59
+ NSLog out
60
+ label
61
+ end
62
+
63
+ # Warning, this is very slow to output log, checking truthy however is
64
+ # basically as performant as an if statement
65
+ #
66
+ # @example
67
+ #
68
+ # # foo and bar are objects we want to inspect
69
+ # rmq.debug.assert(1==2, 'Bad stuff happened', {
70
+ # foo: foo,
71
+ # bar: bar
72
+ # })
73
+ def assert(truthy, label = nil, objects = nil)
74
+ if (RMQ.app.development? || RMQ.app.test?) && !truthy
75
+ label ||= 'Assert failed'
76
+ if block_given? && !objects
77
+ objects = yield
78
+ end
79
+ log_detailed label, objects: objects, skip_first_caller: true
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+
87
+ #class UIViewController
88
+ #def dealloc
89
+ #puts "dealloc controller #{self.object_id}"
90
+ #super
91
+ #end
92
+ #end
@@ -1,38 +1,49 @@
1
1
  module RubyMotionQuery
2
2
  class RMQ
3
- # TODO question, should there be a rmq pool to reuse?
4
-
3
+ # This is used internally, to get a new rmq instance, just call "rmq" in your view or controller or
4
+ # just create a new one like so: RubyMotionQuery::RMQ.new
5
+ #
5
6
  # @return [RMQ]
6
7
  def create_blank_rmq
7
8
  RMQ.create_with_array_and_selectors([], self.selectors, @context)
8
9
  end
9
10
 
11
+ # This is used internally, to get a new rmq instance, just call "rmq" in your view or controller or
12
+ # just create a new one like so: RubyMotionQuery::RMQ.new
13
+ #
10
14
  # @return [RMQ]
11
- def create_rmq_in_context(*selectors)
12
- RMQ.create_with_selectors(selectors, @context)
15
+ def create_rmq_in_context(*working_selectors)
16
+ RMQ.create_with_selectors(working_selectors, @context)
13
17
  end
14
18
 
15
19
  class << self
16
20
 
21
+ # This is used internally, to get a new rmq instance, just call "rmq" in your view or controller or
22
+ # just create a new one like so: RubyMotionQuery::RMQ.new
23
+ #
17
24
  # @return [RMQ]
18
- def create_with_selectors(selectors, context, parent_rmq = nil)
19
- RMQ.new.tap do |o|
20
- o.context = context
21
- o.parent_rmq = parent_rmq
22
- o.selectors = selectors
23
- end
25
+ def create_with_selectors(working_selectors, current_context, working_parent_rmq = nil)
26
+ q = RMQ.new
27
+ q.context = current_context
28
+ q.parent_rmq = working_parent_rmq
29
+ q.selectors = working_selectors
30
+ q
24
31
  end
25
32
 
33
+ # This is used internally, to get a new rmq instance, just call "rmq" in your view or controller or
34
+ # just create a new one like so: RubyMotionQuery::RMQ.new
35
+ #
26
36
  # @return [RMQ]
27
- def create_with_array_and_selectors(array, selectors, context, parent_rmq = nil) # TODO, convert to opts
28
- RMQ.new.tap do |o|
29
- o.context = context
30
- o.selectors = selectors
31
- o.parent_rmq = parent_rmq
32
- o.selected = array # Must be last
33
- end
37
+ def create_with_array_and_selectors(array, working_selectors, current_context, working_parent_rmq = nil) # TODO, convert to opts
38
+ q = RMQ.new
39
+ q.context = current_context
40
+ q.selectors = working_selectors
41
+ q.parent_rmq = working_parent_rmq
42
+ q.selected = array # Must be last
43
+ q
34
44
  end
35
45
 
36
46
  end
37
47
  end
48
+
38
49
  end
@@ -65,12 +65,12 @@ module RubyMotionQuery
65
65
  scale = UIScreen.mainScreen.scale
66
66
  if use_content_size
67
67
  UIGraphicsBeginImageContextWithOptions(view.contentSize, false, scale)
68
- context = UIGraphicsGetCurrentContext()
68
+ graphics_context = UIGraphicsGetCurrentContext()
69
69
  view.subviews.each do |subview|
70
- CGContextSaveGState(context)
71
- CGContextTranslateCTM(context, subview.frame.origin.x, subview.frame.origin.y)
72
- subview.layer.renderInContext(context)
73
- CGContextRestoreGState(context)
70
+ CGContextSaveGState(graphics_context)
71
+ CGContextTranslateCTM(graphics_context, subview.frame.origin.x, subview.frame.origin.y)
72
+ subview.layer.renderInContext(graphics_context)
73
+ CGContextRestoreGState(graphics_context)
74
74
  end
75
75
  image = UIGraphicsGetImageFromCurrentImageContext()
76
76
  UIGraphicsEndImageContext()