lib/fusuma/action_stack.rb in fusuma-0.1.8 vs lib/fusuma/action_stack.rb in fusuma-0.1.9

- old
+ new

@@ -5,60 +5,82 @@ super(*args) end # return { finger:, direction:, action: } or nil def gesture_info - return unless enough_actions? - MultiLogger.debug(enough_actions?: enough_actions?) - direction = detect_direction - finger = detect_finger - action = detect_action + return unless enough_actions? && enough_time_passed? + action_type = detect_action_type + direction = detect_direction(action_type) + return if direction.nil? + @last_triggered_time = last.time + finger = detect_finger clear - MultiLogger.debug(finger: finger, direction: direction, action: action) - GestureInfo.new(finger, direction, action) + MultiLogger.debug(finger: finger, direction: direction, + action_type: action_type) + GestureInfo.new(finger, direction, action_type) end def push(gesture_action) super(gesture_action) clear if action_end? end alias << push private - GestureInfo = Struct.new(:finger, :direction, :action) - Direction = Struct.new(:move, :pinch) + GestureInfo = Struct.new(:finger, :direction, :action_type) - def detect_direction - direction_hash = sum_direction - move = detect_move(direction_hash) - pinch = detect_pinch(direction_hash) - Direction.new(move, pinch) + def elapsed_time + return 0 if length == 0 + last.time - first.time end - def detect_move(direction_hash) - if direction_hash[:move][:x].abs > direction_hash[:move][:y].abs - return direction_hash[:move][:x] > 0 ? 'right' : 'left' + def detect_direction(action_type) + case action_type + when 'swipe' + detect_move + when 'pinch' + detect_zoom end - direction_hash[:move][:y] > 0 ? 'down' : 'up' end - def detect_pinch(direction_hash) - direction_hash[:pinch] > 1 ? 'in' : 'out' + def detect_move + moves = sum_moves + return nil if moves[:x].zero? && moves[:y].zero? + # MultiLogger.debug(moves: moves) + return nil if (moves[:x].abs < 200) && (moves[:y].abs < 200) + if moves[:x].abs > moves[:y].abs + return moves[:x] > 0 ? 'right' : 'left' + else + moves[:y] > 0 ? 'down' : 'up' + end end + def detect_zoom + diameter = mul_diameter + # TODO: change threshold from config files + if diameter > 10 + 'in' + elsif diameter < 0.1 + 'out' + end + end + def detect_finger last.finger end - def sum_direction + def sum_moves move_x = sum_attrs(:move_x) move_y = sum_attrs(:move_y) - pinch = mul_attrs(:pinch) - { move: { x: move_x, y: move_y }, pinch: pinch } + { x: move_x, y: move_y } end + def mul_diameter + mul_attrs(:zoom) + end + def sum_attrs(attr) send('map') do |gesture_action| gesture_action.send(attr.to_sym.to_s) end.compact.inject(:+) end @@ -79,13 +101,21 @@ return false if last.class != GestureAction last.action end def enough_actions? - length > 7 # TODO: should be detected by move per time + (length > 1) && (elapsed_time > 0.1) end - def detect_action + def enough_time_passed? + (last.time - last_triggerd_time) > 0.5 + end + + def last_triggerd_time + @last_triggered_time || 0 + end + + def detect_action_type first.action =~ /GESTURE_(.*?)_/ Regexp.last_match(1).downcase end end end