bluepotion 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -0
  3. data/lib/project/alert_dialog/alert_dialog.rb +26 -4
  4. data/lib/project/benchmark.rb +34 -0
  5. data/lib/project/delayed_execution.rb +16 -0
  6. data/lib/project/ext/object.rb +16 -15
  7. data/lib/project/ext/time.rb +42 -0
  8. data/lib/project/ext/view.rb +26 -5
  9. data/lib/project/potion.rb +9 -0
  10. data/lib/project/pro_motion/activities/pm_activity.rb +15 -0
  11. data/lib/project/pro_motion/activities/pm_navigation_activity.rb +8 -1
  12. data/lib/project/pro_motion/activities/pm_single_fragment_activity.rb +1 -1
  13. data/lib/project/pro_motion/adapters/pm_base_adapter.rb +79 -15
  14. data/lib/project/pro_motion/adapters/pm_cursor_adapter.rb +7 -31
  15. data/lib/project/pro_motion/fragments/pm_list_screen.rb +14 -11
  16. data/lib/project/pro_motion/fragments/pm_screen.rb +3 -0
  17. data/lib/project/pro_motion/fragments/pm_screen_module.rb +41 -2
  18. data/lib/project/pro_motion/pm_application.rb +63 -0
  19. data/lib/project/ruby_motion_query/rmq/actions.rb +10 -0
  20. data/lib/project/ruby_motion_query/rmq/base.rb +79 -25
  21. data/lib/project/ruby_motion_query/rmq/config.rb +9 -0
  22. data/lib/project/ruby_motion_query/rmq/event_wrappers/rmq_keyboard_action.rb +12 -0
  23. data/lib/project/ruby_motion_query/rmq/event_wrappers/rmq_number_picker_change.rb +12 -0
  24. data/lib/project/ruby_motion_query/rmq/events.rb +14 -3
  25. data/lib/project/ruby_motion_query/rmq/factory.rb +10 -5
  26. data/lib/project/ruby_motion_query/rmq/selectors.rb +7 -6
  27. data/lib/project/ruby_motion_query/rmq/styles.rb +33 -10
  28. data/lib/project/ruby_motion_query/rmq/subviews.rb +2 -3
  29. data/lib/project/ruby_motion_query/rmq/traverse.rb +44 -6
  30. data/lib/project/ruby_motion_query/rmq_color.rb +2 -1
  31. data/lib/project/ruby_motion_query/rmq_device.rb +6 -0
  32. data/lib/project/ruby_motion_query/rmq_resource.rb +8 -0
  33. data/lib/project/ruby_motion_query/rmq_screen_data.rb +5 -0
  34. data/lib/project/ruby_motion_query/rmq_stylesheet.rb +30 -4
  35. data/lib/project/ruby_motion_query/rmq_validation.rb +3 -3
  36. data/lib/project/ruby_motion_query/rmq_view_data.rb +33 -1
  37. data/lib/project/ruby_motion_query/stylers/rmq_text_view_styler.rb +11 -3
  38. data/lib/project/ruby_motion_query/stylers/rmq_view_styler.rb +37 -3
  39. data/lib/project/version.rb +1 -1
  40. metadata +10 -4
  41. data/lib/project/compatibility/motion_keychain.rb +0 -14
@@ -0,0 +1,9 @@
1
+ class RMQ
2
+ def self.caching_enabled?
3
+ !!@caching_enabled
4
+ end
5
+
6
+ def self.caching_enabled=(value)
7
+ @caching_enabled = value
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ class RMQKeyboardAction
2
+ def initialize(&block)
3
+ @done_callback = block
4
+ end
5
+
6
+ def onEditorAction(view, action_id, key_event)
7
+ if action_id == Potion::EditorInfo::IME_ACTION_DONE
8
+ @done_callback.call if @done_callback
9
+ end
10
+ false
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ class RMQNumberPickerChange
2
+ attr_accessor :change_block
3
+
4
+ def initialize(&block)
5
+ @change_block = block
6
+ end
7
+
8
+ def onValueChange(picker, old_val, new_val)
9
+ @change_block.call(picker, old_val, new_val)
10
+ end
11
+
12
+ end
@@ -5,7 +5,9 @@ class RMQ
5
5
  when :click, :tap, :touch
6
6
  handle_click(view, &block)
7
7
  when :change
8
- handle_change(view, &block)
8
+ handle_change(view, args, &block)
9
+ when :done
10
+ handle_done(view, &block)
9
11
  else
10
12
  raise "[RMQ ERROR] Unrecognized event: #{event}"
11
13
  end
@@ -25,13 +27,22 @@ class RMQ
25
27
  end
26
28
  end
27
29
 
28
- def handle_change(view, &block)
30
+ def handle_change(view, args, &block)
29
31
  # Seek bar change
30
32
  if view.respond_to? :setOnSeekBarChangeListener
31
33
  view.onSeekBarChangeListener = RMQSeekChange.new(args, &block)
32
34
  # Text change
33
- elsif view.respond_to? :addTextChangeListener
35
+ elsif view.respond_to? :addTextChangedListener
34
36
  view.addTextChangedListener(RMQTextChange.new(&block))
37
+ elsif view.respond_to? :setOnValueChangedListener
38
+ view.onValueChangedListener = RMQNumberPickerChange.new(&block)
39
+ end
40
+ end
41
+
42
+ def handle_done(view, &block)
43
+ # Keyboard done button pressed
44
+ if view.respond_to? :setOnEditorActionListener
45
+ view.onEditorActionListener = RMQKeyboardAction.new(&block)
35
46
  end
36
47
  end
37
48
 
@@ -22,11 +22,16 @@ class RMQ
22
22
  #
23
23
  # @return [RMQ]
24
24
  def create_with_selectors(working_selectors, originated_from, working_parent_rmq = nil)
25
- q = RMQ.new
26
- q.originated_from = originated_from
27
- q.parent_rmq = working_parent_rmq
28
- q.selectors = working_selectors
29
- q
25
+ #if working_parent_rmq && (working_parent_rmq.selectors.length == 1)
26
+ #working_parent_rmq.selectors[0].rmq(working_selectors)
27
+ #else
28
+ q = RMQ.new
29
+ q.originated_from = originated_from
30
+
31
+ q.parent_rmq = working_parent_rmq
32
+ q.selectors = working_selectors
33
+ q
34
+ #end
30
35
  end
31
36
 
32
37
  # This is used internally, to get a new rmq instance, just call "rmq" in your view or controller or
@@ -18,18 +18,19 @@ class RMQ
18
18
  # return true unless view.rmq_data.has_tag?
19
19
 
20
20
  new_selectors.each do |selector|
21
- if selector.is_a?(Java::Lang::Integer)
22
- if view.id == selector
21
+ if selector.is_a?(Symbol)
22
+ rd = view.rmq_data
23
+ if (rd.has_style?(selector)) || rd.has_tag?(selector)
23
24
  out = true
24
25
  break
25
26
  end
26
- elsif selector == :tagged
27
- if view.rmq_data.has_tag?
27
+ elsif selector.is_a?(Java::Lang::Integer)
28
+ if view.id == selector
28
29
  out = true
29
30
  break
30
31
  end
31
- elsif selector.is_a?(Symbol)
32
- if (view.rmq_data.has_style?(selector)) || view.rmq_data.has_tag?(selector)
32
+ elsif selector == :tagged
33
+ if view.rmq_data.has_tag?
33
34
  out = true
34
35
  break
35
36
  end
@@ -37,11 +37,24 @@ class RMQ
37
37
 
38
38
  def apply_style(*style_names)
39
39
  if style_names
40
- selected.each do |selected_view|
41
- style_names.each do |style_name|
42
- apply_style_to_view selected_view, style_name
40
+ if style_names.length == 1 && selected.length == 1
41
+ apply_style_to_view selected.first, style_names.first
42
+ else
43
+ selected.each do |selected_view|
44
+ style_names.each do |style_name|
45
+ apply_style_to_view selected_view, style_name
46
+ end
43
47
  end
44
48
  end
49
+
50
+ # TODO, remove this hack once RMA is fixed
51
+ #tproc = proc do |style_name|
52
+ #apply_style_to_view @apply_style_selected_view, style_name
53
+ #end
54
+ #selected.each do |selected_view|
55
+ #@apply_style_selected_view = selected_view
56
+ #style_names.each &tproc
57
+ #end
45
58
  end
46
59
  self
47
60
  end
@@ -49,12 +62,15 @@ class RMQ
49
62
 
50
63
  def apply_style_to_view(view, style_name)
51
64
  #begin
52
- styler = self.styler_for(view)
53
- self.stylesheet.send(style_name, styler)
54
- styler.finalize
55
-
56
- view.rmq_data.styles << style_name unless view.rmq_data.has_style?(style_name)
57
- view.rmq_style_applied
65
+ if sheet = self.stylesheet
66
+ styler = self.styler_for(view)
67
+ sheet.send(style_name, styler)
68
+ styler.finalize
69
+ styler.cleanup
70
+
71
+ view.rmq_data.styles << style_name unless view.rmq_data.has_style?(style_name)
72
+ view.rmq_style_applied
73
+ end
58
74
  #rescue NoMethodError => e
59
75
  #if e.message =~ /.*#{style_name.to_s}.*/
60
76
  #$stderr.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"
@@ -78,7 +94,14 @@ class RMQ
78
94
  out.flatten!.uniq
79
95
  end
80
96
 
81
-
97
+ def reapply_styles
98
+ selected.each do |selected_view|
99
+ selected_view.rmq_data.styles.each do |style_name|
100
+ apply_style_to_view selected_view, style_name
101
+ end
102
+ end
103
+ self
104
+ end
82
105
 
83
106
  end
84
107
 
@@ -30,7 +30,6 @@ class RMQ
30
30
  built = true
31
31
  end
32
32
 
33
- rmq_data.activity = self.activity
34
33
  rmq_data.screen = self.screen
35
34
 
36
35
  subviews_added << new_view
@@ -68,14 +67,14 @@ class RMQ
68
67
  alias :insert :add_subview
69
68
 
70
69
  def tag_all_from_resource_entry_name(view)
71
- view.rmq.find.each do |view|
70
+ @@tag_all_from_resource_entry_name_tproc ||= proc do |view|
72
71
  if ren = view.resource_entry_name
73
72
  view.rmq_data.tag(ren.to_sym)
74
73
  end
75
74
  end
75
+ view.rmq.find.each &@@tag_all_from_resource_entry_name_tproc
76
76
  end
77
77
 
78
-
79
78
  # Removes the selected views from their parent's (superview) subview array
80
79
  #
81
80
  # @example
@@ -28,6 +28,8 @@ class RMQ
28
28
  else
29
29
  RMQ.app.current_screen
30
30
  end
31
+ elsif @originated_from.respond_to?(:dummy_workaround_for_kind_of) # TODO, kind_of? doesn't seem to work, verify. Workaround here
32
+ @originated_from
31
33
  else
32
34
  RMQ.app.current_screen
33
35
  end
@@ -41,7 +43,8 @@ class RMQ
41
43
  if @originated_from.is_a?(Android::App::Activity)
42
44
  @originated_from.root_view
43
45
  else
44
- self.controller.root_view
46
+ c = self.controller
47
+ c.root_view if c
45
48
  end
46
49
  end
47
50
 
@@ -66,8 +69,16 @@ class RMQ
66
69
  end
67
70
  end
68
71
 
72
+ def only_root_view_selected?
73
+ selected.length == 1 && selected[0].rmq_data.is_screen_root_view
74
+ end
75
+
69
76
  def all
70
- wrap(root_view).find
77
+ if only_root_view_selected?
78
+ self.find
79
+ else
80
+ self.wrap(self.root_view).find
81
+ end
71
82
  end
72
83
 
73
84
  def children(*working_selectors)
@@ -91,10 +102,38 @@ class RMQ
91
102
  def find(*working_selectors)
92
103
  normalize_selectors(working_selectors)
93
104
 
94
- #if working_selectors.length == 1 && self.selected.length == 1 && working_selectors.first.is_a?(Java::Lang::Integer)
95
- #return selected_first.findViewById(r(:id, working_selectors.first))
96
- #end
105
+ if RMQ.caching_enabled?
106
+ self_selected = self.selected
107
+ if working_selectors.length == 1 && self_selected.length == 1
108
+ single_selected = self_selected[0]
109
+ #if single_seleced.rmq_data.cache_queries
110
+ single_selector = working_selectors[0]
111
+ #if single_selector.is_a?(Symbol)
112
+ if cached = single_selected.rmq_data.query_cache[single_selector]
113
+ #mp "cached #{single_selector}"
114
+ return cached
115
+ else
116
+ q = filter(uniq: true) do |view|
117
+ sbvws = all_subviews_for(view)
118
+
119
+ if RMQ.is_blank?(working_selectors)
120
+ sbvws
121
+ else
122
+ sbvws.inject([]) do |out, subview|
123
+ out << subview if match(subview, working_selectors)
124
+ out
125
+ end
126
+ end
127
+ end # filter
128
+
129
+ single_selected.rmq_data.query_cache[single_selector] = q
130
+ return q
131
+ end
132
+ #end
133
+ end
134
+ end
97
135
 
136
+ # Repeating this inline for performance, TODO, measure and refactor
98
137
  filter(uniq: true) do |view|
99
138
  sbvws = all_subviews_for(view)
100
139
 
@@ -107,7 +146,6 @@ class RMQ
107
146
  end
108
147
  end
109
148
  end # filter
110
-
111
149
  end
112
150
 
113
151
  def find!(*args) # Do not alias this, strange bugs happen where classes don't have methods
@@ -114,7 +114,8 @@ class RMQColorFactory
114
114
  end
115
115
 
116
116
  def from_rgba(r, g, b, a)
117
- RMQColor.argb(a, r, b, g)
117
+ android_a = a * 255
118
+ RMQColor.argb(android_a, r, g, b)
118
119
  end
119
120
  end
120
121
 
@@ -43,5 +43,11 @@ class RMQDevice
43
43
  #TODO
44
44
  end
45
45
 
46
+ def unique_id
47
+ # This is no simple task... and can sometimes be nil based on device implementation
48
+ # This does seem, however, to be the best answer for now.
49
+ Android::Provider::Settings::Secure.getString(find.app.getContentResolver, "android_id")
50
+ end
51
+
46
52
  end
47
53
  end
@@ -22,5 +22,13 @@ class RMQResource
22
22
  def layout(name)
23
23
  self.find("layout", name)
24
24
  end
25
+
26
+ # the string value all up inside your 'res/values/strings.xml' (or nil)
27
+ def string(name=nil)
28
+ return nil unless name
29
+ resource_id = find(:string, name)
30
+ return nil if resource_id.nil? || resource_id == 0
31
+ PMApplication.current_application.resources.getString(resource_id)
32
+ end
25
33
  end
26
34
  end
@@ -1,3 +1,8 @@
1
1
  class RMQScreenData
2
2
  attr_accessor :stylesheet, :cached_rmq
3
+
4
+ def cleanup
5
+ @cached_rmq = nil
6
+ @stylesheet = nil
7
+ end
3
8
  end
@@ -1,15 +1,41 @@
1
1
  class RMQStylesheet
2
- attr_accessor :controller
3
-
4
- def initialize(controller)
2
+ def initialize(parent_screen)
5
3
  unless RMQStylesheet.application_was_setup
6
4
  RMQStylesheet.application_was_setup = true
7
5
  application_setup
8
6
  end
9
- @controller = controller
7
+ @screen = parent_screen
10
8
  setup
11
9
  end
12
10
 
11
+ # @ deprecated
12
+ def controller=(value)
13
+ @screen = value
14
+ end
15
+ # @ deprecated
16
+ def controller
17
+ @screen
18
+ end
19
+
20
+ def screen
21
+ @screen
22
+ end
23
+
24
+ def find(*working_selectors) # Not calling rmq below for performance reasons (one less method invocation)
25
+ if @screen
26
+ @screen.rmq(working_selectors)
27
+ else
28
+ super
29
+ end
30
+ end
31
+ def rmq(*working_selectors)
32
+ if @screen
33
+ @screen.rmq(working_selectors)
34
+ else
35
+ super
36
+ end
37
+ end
38
+
13
39
  def application_setup
14
40
  # Override to do your overall setup for your applications. This
15
41
  # is where you want to add your custom fonts and colors
@@ -116,8 +116,8 @@ module RubyMotionQuery
116
116
  HASUPPER = '^(?=.*[A-Z]).+$'
117
117
  # Has at least 1 lowercase letter
118
118
  HASLOWER = '^(?=.*[a-z]).+$'
119
- # Has some kind of value not just whitespace (doesn't require data to be stripped)
120
- PRESENCE = '\S+'
119
+ # is just whitespace
120
+ NOT_PRESENCE = '^\s*$' #Needed for android presence madness
121
121
 
122
122
  @@validation_methods = {
123
123
  :email => lambda { |value, opts| value.toString.matches(EMAIL)},
@@ -134,7 +134,7 @@ module RubyMotionQuery
134
134
  :strong_password => lambda { |value, opts| value.toString.matches(STRONGPW)},
135
135
  :has_upper => lambda { |value, opts| value.toString.matches(HASUPPER)},
136
136
  :has_lower => lambda { |value, opts| value.toString.matches(HASLOWER)},
137
- :presence => lambda { |value, opts| value.toString.matches(PRESENCE)},
137
+ :presence => lambda { |value, opts| !value.toString.matches(NOT_PRESENCE)},
138
138
  :length => lambda { |value, opts|
139
139
  opts = {
140
140
  exact_length: nil,
@@ -1,10 +1,42 @@
1
1
  class RMQViewData
2
- attr_accessor :events, :built, :is_screen_root_view, :activity, :screen
2
+ attr_accessor :events, :built, :is_screen_root_view, :screen, :cached_rmq #, :cache_queries
3
3
 
4
4
  def screen_root_view?
5
5
  !@is_screen_root_view.nil?
6
6
  end
7
7
 
8
+ def cleanup
9
+ clear_query_cache
10
+ if @cached_rmq
11
+ @cached_rmq.selectors = nil
12
+ @cached_rmq.parent_rmq = nil
13
+ @cached_rmq = nil
14
+ end
15
+ @events = nil
16
+ @screen = nil
17
+ @_tags = nil
18
+ @_styles = nil
19
+ @_validation_errors = nil
20
+ @validation_errors = nil
21
+ @is_screen_root_view = false
22
+ @built = false
23
+ nil
24
+ end
25
+
26
+ def query_cache
27
+ @_query_cache ||= {}
28
+ end
29
+
30
+ def clear_query_cache
31
+ @query_cache = {}
32
+ end
33
+
34
+ def activity
35
+ if @screen
36
+ @screen.getActivity
37
+ end
38
+ end
39
+
8
40
  # @return [Hash] Array of tag names assigned to to this view
9
41
  def tags
10
42
  @_tags ||= {}