# # Special, UI avare events API # module UnderOs::UI::Events def on(event, *args, &block) return event.map{|e,b| self.on(e,&b)}[0] || self if event.is_a?(Hash) @_.userInteractionEnabled = true event = add_ui_event_listener(event) UnderOs::Events::Listeners.add(self, event, *args, block) end def off(event) UnderOs::Events::Listeners.remove(self, event) end def emit(*event) if event.is_a?(UIGestureRecognizer) event, r = find_recognizer_from(event.class) event = Event.new(self, event) else event = Event.new(self, *event) end UnderOs::Events::Listeners.kick(self, event, {}) end def on=(hash) on hash end class TouchListeners def self.listeners @listeners ||= Hash.new{ |h,k| h[k] = [] } end def self.add(eventname, view) listeners[eventname] << view end def self.notify(eventname, event) listeners[eventname].each do |view| if eventname == :touchmove # being nice and throttling the touchmove events return if @__working @__working = true end touches = touches_for_view(view, event) view.emit(eventname, touches: touches) if touches.size > 0 @__working = false end end def self.touches_for_view(view, event) frame = view._.frame touches = [] event.allTouches.each do |touch| if point = touch_inside_of(frame, touch) touches << Touch.new(view, point) end end touches end def self.touch_inside_of(frame, touch) point = touch.locationInView(nil) point = nil if point.x < frame.origin.x || point.y < frame.origin.y || point.x > frame.origin.x + frame.size.width || point.y > frame.origin.y + frame.size.height point end class Touch attr_reader :view, :position def initialize(view, position) @view = view @position = position end def pageX position.x end def pageY position.y end def viewX @position.x - view._.frame.origin.x end def viewY @position.y - view._.frame.origin.y end def inspect "#