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.
@@ -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()