class RMQ
many hacks in this: we can’t duplicate the iOS implementation because define_singleton_method isn’t implemented in Android
:‘(
Constants
- VERSION
Public Class Methods
# File lib/project/ruby_motion_query/rmq_app.rb, line 6 def self.app PMApplication.current_application end
# File lib/project/ruby_motion_query/rmq/config.rb, line 6 def self.caching_enabled=(value) @caching_enabled = value end
# File lib/project/ruby_motion_query/rmq/config.rb, line 2 def self.caching_enabled? !!@caching_enabled end
# File lib/project/ruby_motion_query/rmq_color.rb, line 5 def self.color(*params) if params.empty? RMQColor else RMQColorFactory.build(params) end end
This is used internally, to get a new rmq instance, just call “rmq” in your view or controller or just create a new one like so: RubyMotionQuery::RMQ.new
@return [RMQ]
# File lib/project/ruby_motion_query/rmq/factory.rb, line 41 def create_with_array_and_selectors(array, working_selectors, local_originated_from, working_parent_rmq = nil) # TODO, convert to opts q = RMQ.new q.originated_from = local_originated_from q.selectors = working_selectors q.parent_rmq = working_parent_rmq q.selected = array # Must be last q end
This is used internally, to get a new rmq instance, just call “rmq” in your view or controller or just create a new one like so: RubyMotionQuery::RMQ.new
@return [RMQ]
# File lib/project/ruby_motion_query/rmq/factory.rb, line 24 def create_with_selectors(working_selectors, originated_from, working_parent_rmq = nil) #if working_parent_rmq && (working_parent_rmq.selectors.length == 1) #working_parent_rmq.selectors[0].rmq(working_selectors) #else q = RMQ.new q.originated_from = originated_from q.parent_rmq = working_parent_rmq q.selectors = working_selectors q #end end
# File lib/project/ruby_motion_query/rmq/debug.rb, line 6 def self.debugging=(flag) @debugging = flag end
# File lib/project/ruby_motion_query/rmq/debug.rb, line 2 def self.debugging? @debugging ||= ENV['rmq_debug'] == 'true' end
# File lib/project/ruby_motion_query/rmq_device.rb, line 6 def self.device RMQDevice end
# File lib/project/ruby_motion_query/rmq_font.rb, line 2 def self.font RMQFont end
@return [RMQImageUtils]
# File lib/project/ruby_motion_query/rmq_image.rb, line 3 def self.image RMQImageUtils end
# File lib/project/ruby_motion_query/rmq/utils.rb, line 8 def is_blank?(o) if o.is_a?(RMQ) RMQ.is_blank?(o.to_a) else o.respond_to?(:empty?) ? o.empty? : !o end end
# File lib/project/ruby_motion_query/rmq/utils.rb, line 4 def is_class?(o) o.class == Java::Lang::Class end
# File lib/project/ruby_motion_query/rmq/utils.rb, line 24 def is_object_weak_ref?(o) false end
# File lib/project/ruby_motion_query/rmq/base.rb, line 2 def initialize @selected_dirty = true $rmq_initialized ||= 0 $rmq_initialized += 1 #mp $rmq_initialized end
@return [RMQResource]
# File lib/project/ruby_motion_query/rmq_resource.rb, line 3 def self.resource RMQResource end
# File lib/project/ruby_motion_query/rmq/utils.rb, line 32 def symbolize(s) s.to_s.gsub(/\s+/,"_").gsub(/\W+/,"").downcase.to_sym end
# File lib/project/ruby_motion_query/rmq/utils.rb, line 16 def weak_ref(o) o end
# File lib/project/ruby_motion_query/rmq/utils.rb, line 20 def weak_ref_to_strong_ref(weak_ref) weak_ref end
# File lib/project/ruby_motion_query/rmq/utils.rb, line 28 def weak_ref_value(o) o end
Public Instance Methods
@return [RMQ]
# File lib/project/ruby_motion_query/rmq/enumerablish.rb, line 6 def <<(value) selected << value if value.is_a?(UIView) self end
@return [RMQ]
@example
rmq(UILabel)[3] or rmq(UILabel)[1..5] or rmq(UILabel)[2,3]
# File lib/project/ruby_motion_query/rmq/enumerablish.rb, line 24 def [](*args) RMQ.create_with_array_and_selectors(Array(selected[*args]), @selectors, @originated_from) end
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 2 def activity # TODO we can get the activity in better ways, and in more # situations if @originated_from.is_a?(PMScreen) @originated_from.activity elsif @originated_from.is_a?(Potion::Activity) @originated_from elsif @originated_from.is_a?(Potion::View) if @originated_from.rmq_data @originated_from.rmq_data.activity else RMQ.app.current_activity end else RMQ.app.current_activity end end
# File lib/project/ruby_motion_query/rmq/subviews.rb, line 2 def add_subview(view_or_class, opts={}) subviews_added = [] selected.each do |selected_view| created = false appended = false built = false tag_xml_layout = false if view_or_class.is_a?(Potion::View) new_view = view_or_class elsif view_or_class.is_a?(Symbol) # Inflate from xml created = true layout = RMQResource.layout(view_or_class) inflater = Potion::LayoutInflater.from(self.activity) new_view = inflater.inflate(layout, nil) tag_xml_layout = true else created = true new_view = view_or_class.new(RMQ.app.context) new_view.setId(Potion::ViewIdGenerator.generate) end rmq_data = new_view.rmq_data unless rmq_data.built rmq_data.built = true # build only once built = true end rmq_data.screen = self.screen subviews_added << new_view unless opts[:do_not_add] #if at_index = opts[:at_index] #selected_view.insertSubview(new_view, atIndex: at_index) #elsif below_view = opts[:below_view] #selected_view.insertSubview(new_view, belowSubview: below_view) #else selected_view.addView(new_view) #end appended = true end if created new_view.rmq_created end new_view.rmq_build if built new_view.rmq_appended if appended if self.stylesheet apply_style_to_view(new_view, opts[:style]) if opts[:style] end tag_all_from_resource_entry_name(new_view) if tag_xml_layout end viewq = RMQ.create_with_array_and_selectors(subviews_added, selectors, @originated_from, self) opts[:block].call viewq if opts[:block] opts[:raw_block].call viewq.get if opts[:raw_block] viewq end
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 76 def all if only_root_view_selected? self.find else self.wrap(self.root_view).find end end
# File lib/project/ruby_motion_query/rmq/base.rb, line 265 def all_subviews_for(view) out = [] return out unless view.is_a?(Potion::ViewGroup) needs_flattening = false (0...view.getChildCount).each_with_index do |i| sbv = view.getChildAt(i) if sbv && view != sbv out << sbv if sbv.is_a?(Potion::ViewGroup) && sbv.getChildCount > 0 needs_flattening = true out << all_subviews_for(sbv) end end end out.flatten! if needs_flattening out end
@return [RMQ] A new rmq instance reducing selected views to those that match selectors provided
@param selectors your selector
@example
rmq(UIImage).and(:some_tag).attr(image: nil)
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 161 def and(*working_selectors) return self unless working_selectors normalize_selectors(working_selectors) self.select do |view| match(view, working_selectors) end end
@return [RMQ] A new rmq instance adding the context to the selected views
@example
rmq(my_view).children.and_self
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 190 def and_self if self.parent_rmq out = self.parent_rmq.selected.dup out << selected out.flatten! RMQ.create_with_array_and_selectors(out, selectors, @context, self) else self end end
# File lib/project/ruby_motion_query/rmq_app.rb, line 2 def app PMApplication.current_application end
# File lib/project/ruby_motion_query/rmq/subviews.rb, line 89 def append(view_or_class, style=nil, opts={}, dummy=nil) # <- dummy is to get around RM bug) opts[:style] = style #opts[:block] = block if block out = self.add_subview(view_or_class, opts) out end
# File lib/project/ruby_motion_query/rmq/subviews.rb, line 96 def append!(view_or_class, style=nil, opts={}) self.append(view_or_class, style, opts).get end
# File lib/project/ruby_motion_query/rmq/styles.rb, line 38 def apply_style(*style_names) if style_names if style_names.length == 1 && selected.length == 1 apply_style_to_view selected.first, style_names.first else selected.each do |selected_view| style_names.each do |style_name| apply_style_to_view selected_view, style_name end end end # TODO, remove this hack once RMA is fixed #tproc = proc do |style_name| #apply_style_to_view @apply_style_selected_view, style_name #end #selected.each do |selected_view| #@apply_style_selected_view = selected_view #style_names.each &tproc #end end self end
# File lib/project/ruby_motion_query/rmq/styles.rb, line 63 def apply_style_to_view(view, style_name) #begin if sheet = self.stylesheet styler = self.styler_for(view) sheet.send(style_name, styler) styler.finalize styler.cleanup view.rmq_data.styles << style_name unless view.rmq_data.has_style?(style_name) view.rmq_style_applied end #rescue NoMethodError => e #if e.message =~ /.*#{style_name.to_s}.*/ #$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" #else #raise e #end #end end
@return [RMQ]
# File lib/project/ruby_motion_query/rmq/actions.rb, line 4 def attr(new_settings) selected.each do |view| new_settings.each do |k,v| view.send "#{k}=", v end end self end
@return [RMQ] The parent rmq instance. This is useful when you want to go down into the tree, then move back up to do more work. Like jQuery’s “end”
@example
rmq(test_view).find(Potion::Button).tag(:foo).back.find(UILabel).tag(:bar)
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 207 def back self.parent_rmq || self end
# File lib/project/ruby_motion_query/rmq/subviews.rb, line 113 def build(view_or_constant, style = nil, opts = {}, &block) opts[:do_not_add] = true opts[:style] = style opts[:block] = block if block add_subview view_or_constant, opts end
# File lib/project/ruby_motion_query/rmq/subviews.rb, line 120 def build!(view_or_constant, style = nil, opts = {}, &block) opts[:raw_block] = block if block build(view_or_constant, style, opts).get end
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 84 def children(*working_selectors) normalize_selectors(working_selectors) filter do |view| sbvws = view.subviews if RMQ.is_blank?(working_selectors) sbvws else sbvws.inject([]) do |out, subview| out << subview if match(subview, working_selectors) out end end end end
# File lib/project/ruby_motion_query/rmq/actions.rb, line 43 def cleanup selected.each { |view| view.cleanup } self end
# File lib/project/ruby_motion_query/rmq/actions.rb, line 48 def clear_cache selected.each { |view| view.rmq_data.clear_query_cache } self end
For each selected view, get the first view that matches the selector(s) by testing the view’s parent and traversing up through its ancestors in the tree
@return [RMQ] Instance selecting the first parent or grandparent or ancestor up the tree of the selected view(s)
@param selectors
@example
rmq.closest(Potion::View).get.setContentOffset([0,0])
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 306 def closest(*working_selectors) normalize_selectors(working_selectors) filter do |view| closest_view(view, working_selectors) end end
# File lib/project/ruby_motion_query/rmq_color.rb, line 13 def color(*params) self.class.color(*params) end
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 38 def controller self.screen || self.activity end
# File lib/project/ruby_motion_query/rmq/enumerablish.rb, line 96 def count length end
# File lib/project/ruby_motion_query/rmq/subviews.rb, line 100 def create(view_or_constant, style = nil, opts = {}, &block) # TODO, refactor so that add_subview uses create, not backwards like it is now opts[:do_not_add] = true opts[:style] = style opts[:block] = block if block add_subview view_or_constant, opts end
# File lib/project/ruby_motion_query/rmq/subviews.rb, line 108 def create!(view_or_constant, style=nil, opts = {}, &block) opts[:raw_block] = block if block create(view_or_constant, style, opts).get end
This is used internally, to get a new rmq instance, just call “rmq” in your view or controller or just create a new one like so: RubyMotionQuery::RMQ.new
@return [RMQ]
# File lib/project/ruby_motion_query/rmq/factory.rb, line 6 def create_blank_rmq RMQ.create_with_array_and_selectors([], self.selectors, @originated_from) end
This is used internally, to get a new rmq instance, just call “rmq” in your view or controller or just create a new one like so: RubyMotionQuery::RMQ.new
@return [RMQ]
# File lib/project/ruby_motion_query/rmq/factory.rb, line 14 def create_rmq_in_originated_from(*working_selectors) RMQ.create_with_selectors(working_selectors, @originated_from) end
# File lib/project/ruby_motion_query/rmq/data.rb, line 2 def data(new_data = :rmq_not_provided) if new_data != :rmq_not_provided selected.each do |view| case view when Potion::EditText then view.text = new_data.to_s.toString when Potion::TextView then view.text = new_data.to_s.toString # TODO, finish end end self else out = selected.map do |view| case view when Potion::EditText then view.text.toString.to_s when Potion::TextView then view.text # TODO, finish end end out = out.first if out.length == 1 out end end
# File lib/project/ruby_motion_query/rmq/data.rb, line 27 def data=(new_data) self.data(new_data) end
@return [RMQ]
# File lib/project/ruby_motion_query/rmq/enumerablish.rb, line 49 def detect(&block) # Unlike enumerable, detect and find are not the same. See find in transverse return self unless block RMQ.create_with_array_and_selectors(selected.select(&block), @selectors, @originated_from) end
# File lib/project/ruby_motion_query/rmq_device.rb, line 2 def device RMQDevice end
@return [RMQ]
# File lib/project/ruby_motion_query/rmq/enumerablish.rb, line 30 def each(&block) return self unless block RMQ.create_with_array_and_selectors(selected.each(&block), @selectors, @originated_from) end
# File lib/project/ruby_motion_query/rmq/enumerablish.rb, line 11 def empty? selected.length == 0 end
# File lib/project/ruby_motion_query/rmq/base.rb, line 254 def extract_views_from_selectors(view_container, working_selectors) unless RMQ.is_blank?(working_selectors) working_selectors.delete_if do |selector| if selector.is_a?(Potion::View) view_container << selector true end end end end
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 51 def filter(opts = {}, &block) out = [] limit = opts[:limit] selected.each do |view| results = yield(view) unless RMQ.is_blank?(results) out << results break if limit && (out.length >= limit) end end out.flatten! out = out.uniq if opts[:uniq] if opts[:return_array] out else RMQ.create_with_array_and_selectors(out, selectors, @originated_from, self) end end
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 102 def find(*working_selectors) normalize_selectors(working_selectors) if RMQ.caching_enabled? self_selected = self.selected if working_selectors.length == 1 && self_selected.length == 1 single_selected = self_selected[0] #if single_seleced.rmq_data.cache_queries single_selector = working_selectors[0] #if single_selector.is_a?(Symbol) if cached = single_selected.rmq_data.query_cache[single_selector] #mp "cached #{single_selector}" return cached else q = filter(uniq: true) do |view| sbvws = all_subviews_for(view) if RMQ.is_blank?(working_selectors) sbvws else sbvws.inject([]) do |out, subview| out << subview if match(subview, working_selectors) out end end end # filter single_selected.rmq_data.query_cache[single_selector] = q return q end #end end end # Repeating this inline for performance, TODO, measure and refactor filter(uniq: true) do |view| sbvws = all_subviews_for(view) if RMQ.is_blank?(working_selectors) sbvws else sbvws.inject([]) do |out, subview| out << subview if match(subview, working_selectors) out end end end # filter end
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 151 def find!(*args) # Do not alias this, strange bugs happen where classes don't have methods self.find(*args).get end
@return [RMQ]
# File lib/project/ruby_motion_query/rmq/enumerablish.rb, line 74 def first # TODO, check if it fails with nil RMQ.create_with_array_and_selectors([selected.first], @selectors, @originated_from) end
# File lib/project/ruby_motion_query/rmq/actions.rb, line 26 def focus unless RMQ.is_blank?(selected) selected.last.requestFocus end self end
# File lib/project/ruby_motion_query/rmq_font.rb, line 6 def font RMQFont end
# File lib/project/ruby_motion_query/rmq/base.rb, line 69 def get sel = self.selected if sel.length == 1 sel.first else sel end end
@return [RMQ]
# File lib/project/ruby_motion_query/rmq/enumerablish.rb, line 55 def grep(&block) return self unless block RMQ.create_with_array_and_selectors(selected.grep(&block), @selectors, @originated_from) end
Check if any of the selected has a given tag @example
rmq(my_view).has_tag?(:your_tag) #false rmq(my_view).tag(:your_tag) rmq(my_view).has_tag?(:your_tag) #true
@return [Boolean] true if any selection views have tag provided
# File lib/project/ruby_motion_query/rmq/tags.rb, line 44 def has_tag? tag out = false selected.each do |view| if view.rmq_data.has_tag?(tag) out = true # This is weird because of RM android bug break end end out end
# File lib/project/ruby_motion_query/rmq/actions.rb, line 33 def hide selected.each { |view| view.setVisibility(Potion::View::INVISIBLE) } self end
@return [RMQImageUtils]
# File lib/project/ruby_motion_query/rmq_image.rb, line 8 def image RMQImageUtils end
@return [RMQ]
# File lib/project/ruby_motion_query/rmq/enumerablish.rb, line 67 def inject(o, &block) return self unless block RMQ.create_with_array_and_selectors(selected.inject(o, &block), @selectors, @originated_from) end
# File lib/project/ruby_motion_query/rmq/base.rb, line 200 def inspect out = "RMQ #{self.object_id}. #{self.count} selected. selectors: #{self.selectors}. .log for more info" out << "\n[#{selected.first.inspect}]" if self.count == 1 out end
@return [RMQ]
# File lib/project/ruby_motion_query/rmq/enumerablish.rb, line 79 def last # TODO, check if it fails with nil RMQ.create_with_array_and_selectors([selected.last], @selectors, @originated_from) end
@return [Integer] number of views selected
# File lib/project/ruby_motion_query/rmq/enumerablish.rb, line 90 def length selected.length end
# File lib/project/ruby_motion_query/rmq/base.rb, line 94 def log(opt = nil) if opt == :tree mp tree_to_s(selected) sleep 0.1 # Hack, TODO, fix async problem return end wide = (opt == :wide) out = "\n id |object id |scr| class | style_name | frame |" out << "\n" unless wide out << " sv id |object id |een| superview | subviews count | tags |" line = " ––––––––––––|------------|–––|–––––––––––––––––––––––|–––––––––––––––––––––––––|–––––––––––––––––––––––––––––––––––––––|\n" out << "\n" out << line.chop if wide out << line selected.each do |view| out << " #{view.id.to_s.ljust(12)}|" out << " #{view.object_id.to_s.ljust(12)}|" out << (view.rmq_data.screen_root_view? ? " √ |" : " |") name = view.short_class_name name = name[(name.length - 21)..name.length] if name.length > 21 out << " #{name.ljust(22)}|" #out << " #{""[0..23].ljust(24)}|" # TODO change to real stylname out << " #{(view.rmq_data.style_name.to_s || '')[0..23].ljust(24)}|" # TODO change to real stylname s = "" #if view.origin #format = '#0.#' s = " {l: #{view.x}" s << ", t: #{view.y}" s << ", w: #{view.width}" s << ", h: #{view.height}}" #end out << s.ljust(36) out << " |" out << "\n" unless wide if view.superview out << " #{view.superview.id.to_s.ljust(12)}|" out << " |" out << " |" out << " #{(view.superview ? view.superview.short_class_name : '')[0..21].ljust(22)}|" end out << " #{view.subviews.length.to_s.ljust(23)} |" #out << " #{view.subviews.length.to_s.rjust(8)} #{view.superview.short_class_name.ljust(20)} #{view.superview.object_id.to_s.rjust(10)}" out << " #{view.rmq_data.tag_names.join(',').ljust(38)}|" out << "\n" out << line unless wide end mp out sleep 0.1 # Hack, TODO, fix async problem end
# File lib/project/ruby_motion_query/rmq/base.rb, line 149 def log_tree self.log :tree end
@return [RMQ]
# File lib/project/ruby_motion_query/rmq/enumerablish.rb, line 36 def map(&block) return self unless block RMQ.create_with_array_and_selectors(selected.map(&block), @selectors, @originated_from) end
# File lib/project/ruby_motion_query/rmq/selectors.rb, line 13 def match(view, new_selectors, dummy=nil) out = false # This method is written strange because the return in this example doesn't actually return (RM bug) # elsif selector == :tagged # return true unless view.rmq_data.has_tag? new_selectors.each do |selector| if selector.is_a?(Symbol) rd = view.rmq_data if (rd.has_style?(selector)) || rd.has_tag?(selector) out = true break end elsif selector.is_a?(Java::Lang::Integer) if view.id == selector out = true break end elsif selector == :tagged if view.rmq_data.has_tag? out = true break end elsif selector.is_a?(Hash) if match_hash(view, selector) out = true break end elsif RMQ.is_class?(selector) if view.is_a?(selector) out = true break end else if view == selector out = true break end end end out end
@return [RMQ] Sibling below the selected view(s) (in the subview array)
@param selectors
@example
rmq(my_view).next.hide rmq(my_view).next(UITextField).focus
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 264 def next(*working_selectors) normalize_selectors(working_selectors) filter do |view| subs = view.superview.subviews location = subs.index(view) if location < subs.length - 1 subs[location + 1] end end end
@return [RMQ] A new rmq instance removing selected views that match selectors provided
@param selectors
@example
# Entire family of labels from siblings on down rmq(my_label).parent.find(UILabel).not(my_label).move(left: 10)
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 177 def not(*working_selectors) return self unless working_selectors normalize_selectors(working_selectors) self.reject do |view| match(view, working_selectors) end end
# File lib/project/ruby_motion_query/rmq/events.rb, line 2 def on(event, args={}, &block) self.selected.each do |view| case event when :click, :tap, :touch handle_click(view, &block) when :change handle_change(view, args, &block) when :done handle_done(view, &block) else raise "[RMQ ERROR] Unrecognized event: #{event}" end end end
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 72 def only_root_view_selected? selected.length == 1 && selected[0].rmq_data.is_screen_root_view end
# File lib/project/ruby_motion_query/rmq/base.rb, line 78 def origin_views if pq = self.parent_rmq pq.selected else root_view end end
# File lib/project/ruby_motion_query/rmq/base.rb, line 38 def originated_from @originated_from end
def finalize mp ‘finalize’ # Never called $rmq_initialized -= 1 mp $rmq_initialized super end
# File lib/project/ruby_motion_query/rmq/base.rb, line 16 def originated_from=(value) if value if value.is_a?(Potion::Activity) @originated_from = value @activity = value elsif value.is_a?(PMScreen) || value.is_a?(PMListScreen) @originated_from = value elsif value.is_a?(Potion::View) @originated_from = value elsif value.is_a?(RMQStylesheet) @originated_from = value.controller else @originated_from = nil #debug.log_detailed('Invalid originated_from', objects: {value: value}) #mp "Invalid originated_from: #{value.inspect}" end else @originated_from = nil end @originated_from end
# File lib/project/ruby_motion_query/rmq/base.rb, line 55 def originated_from_or_its_view if @originated_from.is_a?(Potion::Activity) || @originated_from.is_a?(PMScreen) @originated_from.root_view elsif @originated_from.is_a?(Potion::View) @originated_from end #if @originated_from.is_a?(Potion::Activity) || @originated_from.is_a?(PMScreen) #@originated_from.root_view #else #@originated_from #end end
@return [RMQ] rmq instance selecting the parent of the selected view(s)
@example
rmq(my_view).parent.find(:delete_button).toggle_enabled
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 215 def parent closest(Potion::View) end
# File lib/project/ruby_motion_query/rmq/base.rb, line 42 def parent_rmq @_parent_rmq end
# File lib/project/ruby_motion_query/rmq/base.rb, line 45 def parent_rmq=(value) #debug.assert(value.is_a?(RMQ) || value.nil?, 'Invalid parent_rmq', { value: value }) @_parent_rmq = value end
@return [RMQ] Instance selecting the parents, grandparents, etc, all the way up the tree of the selected view(s)
@param selectors
@example
rmq(my_view).parents.log
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 227 def parents(*working_selectors) normalize_selectors(working_selectors) filter(uniq: true) do |view| superviews = all_superviews_for(view) if RMQ.is_blank?(working_selectors) superviews else superviews.inject([]) do |subview, out| out << subview if match(subview, working_selectors) out end end end end
@return [RMQ] Sibling above the selected view(s) (in the subview array)
@param selectors
@example
rmq(my_view).prev.hid rmq(my_view).prev(UITextField).focus
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 283 def prev(*working_selectors) normalize_selectors(working_selectors) filter do |view| if sv = view.superview subs = sv.subviews location = subs.index(view) if location > 0 subs[location - 1] end end end end
# File lib/project/ruby_motion_query/rmq/styles.rb, line 97 def reapply_styles selected.each do |selected_view| selected_view.rmq_data.styles.each do |style_name| apply_style_to_view selected_view, style_name end end self end
@return [RMQ]
# File lib/project/ruby_motion_query/rmq/enumerablish.rb, line 61 def reject(&block) return self unless block RMQ.create_with_array_and_selectors(selected.reject(&block), @selectors, @originated_from) end
Removes the selected views from their parent’s (superview) subview array
@example
rmq(a_view, another_view).remove
@return [RMQ]
# File lib/project/ruby_motion_query/rmq/subviews.rb, line 84 def remove selected.each { |view| view.parent.removeView(view) } self end
@return [RMQResource]
# File lib/project/ruby_motion_query/rmq_resource.rb, line 8 def resource RMQResource end
# File lib/project/ruby_motion_query/rmq/base.rb, line 50 def root? # TODO broken (selected.length == 1) && (selected.first == @originated_from) end
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 42 def root_view if @originated_from.is_a?(Android::App::Activity) @originated_from.root_view else c = self.controller c.root_view if c end end
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 20 def screen # TODO we can get the screen in better ways, and in more # situations if @originated_from.is_a?(PMScreen) @originated_from elsif @originated_from.is_a?(Potion::View) if @originated_from.rmq_data @originated_from.rmq_data.screen else RMQ.app.current_screen end elsif @originated_from.respond_to?(:dummy_workaround_for_kind_of) # TODO, kind_of? doesn't seem to work, verify. Workaround here @originated_from else RMQ.app.current_screen end end
@return [RMQ]
# File lib/project/ruby_motion_query/rmq/enumerablish.rb, line 43 def select(&block) return self unless block RMQ.create_with_array_and_selectors(selected.select(&block), @selectors, @originated_from) end
# File lib/project/ruby_motion_query/rmq/base.rb, line 212 def selected if @selected_dirty @_selected = [] if RMQ.is_blank?(self.selectors) if orig = originated_from_or_its_view @_selected << orig end #elsif self.selectors.length == 1 and self.selectors.first.is_a?(Java::Lang::Integer) ### Special case where we find by id #@_selected << self.root_view.findViewById(self.selectors.first) else working_selectors = self.selectors.dup extract_views_from_selectors(@_selected, working_selectors) unless RMQ.is_blank?(working_selectors) subviews = all_subviews_for(root_view) #return @_selected subviews.each do |subview| @_selected << subview if match(subview, working_selectors) end end end #@_selected.each do |s| #unless s.is_a?(Potion::View) #mp "bad selected: #{s}" #caller #end #end @selected_dirty = false else @_selected ||= [] end @_selected end
Do not use
# File lib/project/ruby_motion_query/rmq/base.rb, line 207 def selected=(value) @_selected = value @selected_dirty = false end
# File lib/project/ruby_motion_query/rmq/selectors.rb, line 9 def selectors @_selectors end
Do not use
# File lib/project/ruby_motion_query/rmq/selectors.rb, line 3 def selectors=(value) @selected_dirty = true normalize_selectors(value) @_selectors = value end
# File lib/project/ruby_motion_query/rmq/actions.rb, line 13 def send(method, args = nil) selected.each do |view| if view.respond_to?(method) if args view.__send__ method, args else view.__send__ method end end end self end
# File lib/project/ruby_motion_query/rmq/actions.rb, line 38 def show selected.each { |view| view.setVisibility(Potion::View::VISIBLE) } self end
@return [RMQ] Siblings of the selected view(s)
@param selectors
@example
rmq(my_view).siblings.send(:poke)
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 251 def siblings(*working_selectors) normalize_selectors(working_selectors) self.parent.children.not(selected) end
# File lib/project/ruby_motion_query/rmq/enumerablish.rb, line 93 def size length end
# File lib/project/ruby_motion_query/rmq/styles.rb, line 83 def style selected.each do |view| yield(styler_for(view)) end self end
# File lib/project/ruby_motion_query/rmq/styles.rb, line 23 def styler_for(view) context = RMQ.app.context styler = case view when Android::Widget::RelativeLayout then RMQRelativeLayoutStyler.new(view, context) when Android::Widget::LinearLayout then RMQLinearLayoutStyler.new(view, context) when Android::Widget::TextView then RMQTextViewStyler.new(view, context) when Android::Widget::ImageView then RMQImageViewStyler.new(view, context) when Android::Widget::ImageButton then RMQImageButtonStyler.new(view, context) when Android::Widget::Button then RMQButtonStyler.new(view, context) else RMQViewStyler.new(view, context) end styler end
# File lib/project/ruby_motion_query/rmq/styles.rb, line 90 def styles out = selected.map do |view| view.rmq_data.styles end out.flatten!.uniq end
# File lib/project/ruby_motion_query/rmq/styles.rb, line 13 def stylesheet @_stylesheet ||= begin if self.controller && (ss = self.controller.rmq_data.stylesheet) ss elsif (prmq = self.parent_rmq) && prmq.stylesheet prmq.stylesheet end end end
# File lib/project/ruby_motion_query/rmq/styles.rb, line 3 def stylesheet=(value) controller = self.screen || self.activity unless value.is_a?(RMQStylesheet) value = value.new(controller) end @_stylesheet = value controller.rmq_data.stylesheet = value self end
Add tags @example
rmq(my_view).tag(:your_tag) rmq(my_view).clear_tags.tag(:your_new_tag) rmq(my_view).find(UILabel).tag(:selected, :customer)
You can optionally store a value in the tag, which can be super useful in some rare situations @example
rmq(my_view).tag(your_tag: 22) rmq(my_view).tag(your_tag: 22, your_other_tag: 'Hello world')
@return [RMQ]
# File lib/project/ruby_motion_query/rmq/tags.rb, line 15 def tag(*tag_or_tags) selected.each do |view| view.rmq_data.tag(tag_or_tags) end self end
# File lib/project/ruby_motion_query/rmq/subviews.rb, line 69 def tag_all_from_resource_entry_name(view) @@tag_all_from_resource_entry_name_tproc ||= proc do |view| if ren = view.resource_entry_name view.rmq_data.tag(ren.to_sym) end end view.rmq.find.each &@@tag_all_from_resource_entry_name_tproc end
@return [Array]
# File lib/project/ruby_motion_query/rmq/enumerablish.rb, line 85 def to_a selected end
# File lib/project/ruby_motion_query/rmq/base.rb, line 153 def tree_to_s(selected_views, depth = 0) out = "" mp 1 selected_views.each do |view| mp 2 mp view.rmq_data.tags if depth == 0 out << "\n" else mp 3 0.upto(depth - 1) do |i| mp 4 out << (i == (depth - 1) ? " ├" : " │") end end out << '───' mp 5 out << "#{view.id}|#{view.object_id} " out << "SCREEN ROOT/" if view.rmq_data.screen_root_view? out << "#{view.short_class_name[0..21]}" out << " ( :#{view.rmq_data.style_name.to_s[0..23]} )" if view.rmq_data.style_name if view.rmq_data.tag_names.length > 0 mp 6 mp view.rmq_data.tag_names.inspect out << " [ #{view.rmq_data.tag_names.join(',')} ]" end #if view.origin #format = '#0.#' s = " {l: #{view.x}" s << ", t: #{view.y}" s << ", w: #{view.width}" s << ", h: #{view.height}}" out << s #end out << "\n" out << tree_to_s(view.subviews, depth + 1) end out end
# File lib/project/ruby_motion_query/rmq/tags.rb, line 22 def untag(*tag_or_tags) selected.each do |view| view.rmq_data.untag(tag_or_tags) end self end
# File lib/project/ruby_motion_query/rmq/version.rb, line 3 def version VERSION end
# File lib/project/ruby_motion_query/rmq/base.rb, line 86 def wrap(view_one, *views) # These strange params is because of RMA bug views = [views] unless views.is_a?(Potion::ArrayList) # TODO, WTF, RM bug? views.unshift(view_one) views.flatten! views.select!{ |v| v.is_a?(Potion::View) } RMQ.create_with_array_and_selectors(views, views, @originated_from, self) end
Protected Instance Methods
# File lib/project/ruby_motion_query/rmq/traverse.rb, line 317 def closest_view(view, working_selectors) if nr = view.superview if match(nr, working_selectors) nr else closest_view(nr,working_selectors) end else nil end end
Private Instance Methods
# File lib/project/ruby_motion_query/rmq/events.rb, line 30 def handle_change(view, args, &block) # Seek bar change if view.respond_to? :setOnSeekBarChangeListener view.onSeekBarChangeListener = RMQSeekChange.new(args, &block) # Text change elsif view.respond_to? :addTextChangedListener view.addTextChangedListener(RMQTextChange.new(&block)) elsif view.respond_to? :setOnValueChangedListener view.onValueChangedListener = RMQNumberPickerChange.new(&block) end end
# File lib/project/ruby_motion_query/rmq/events.rb, line 20 def handle_click(view, &block) # Click event for ListItems if view.respond_to? :setOnItemClickListener view.onItemClickListener = RMQItemClick.new(&block) # Generic Click else view.onClickListener = RMQClick.new(&block) end end
# File lib/project/ruby_motion_query/rmq/events.rb, line 42 def handle_done(view, &block) # Keyboard done button pressed if view.respond_to? :setOnEditorActionListener view.onEditorActionListener = RMQKeyboardAction.new(&block) end end
# File lib/project/ruby_motion_query/rmq/selectors.rb, line 60 def match_hash(view, hash) # TODO, check speed, and do sub hashes for stuff like origin # it's probably pretty slow hash.each do |k,v| return true if view.respond_to?(k) && (view.send(k) == v) end false end
# File lib/project/ruby_motion_query/rmq/selectors.rb, line 69 def normalize_selectors(a = self.selectors) a.flatten! if a a end