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

- old
+ new

@@ -12,12 +12,10 @@ 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_type: action_type) GestureInfo.new(finger, direction, action_type) end def push(gesture_action) super(gesture_action) @@ -28,11 +26,11 @@ private GestureInfo = Struct.new(:finger, :direction, :action_type) def elapsed_time - return 0 if length == 0 + return 0 if length.zero? last.time - first.time end def detect_direction(action_type) case action_type @@ -42,65 +40,67 @@ detect_zoom end end 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 + move = avg_moves + MultiLogger.debug(move: move) + return unless enough_distance?(move) + return move[:x] > 0 ? 'right' : 'left' if move[:x].abs > move[:y].abs + move[:y] > 0 ? 'down' : 'up' end def detect_zoom - diameter = mul_diameter + diameter = avg_attrs(:zoom) + MultiLogger.debug(diameter: diameter) # TODO: change threshold from config files - if diameter > 10 - 'in' - elsif diameter < 0.1 - 'out' - end + return unless enough_diameter?(diameter) + return 'in' if diameter > 1 + 'out' end def detect_finger last.finger end - def sum_moves - move_x = sum_attrs(:move_x) - move_y = sum_attrs(:move_y) - { x: move_x, y: move_y } - end + Distance = Struct.new(:x, :y) - def mul_diameter - mul_attrs(:zoom) + def avg_moves + move_x = sum_attrs(:move_x) / length + move_y = sum_attrs(:move_y) / length + Distance.new(move_x, move_y) end def sum_attrs(attr) send('map') do |gesture_action| gesture_action.send(attr.to_sym.to_s) end.compact.inject(:+) end - def mul_attrs(attr) - send('map') do |gesture_action| - num = gesture_action.send(attr.to_sym.to_s) - # NOTE: ignore 0.0, treat as 1(immutable) - num.zero? ? 1 : num - end.compact.inject(:*) + def avg_attrs(attr) + sum_attrs(attr) / length end def action_end? last_action_name =~ /_END$/ end def last_action_name return false if last.class != GestureAction last.action + end + + def enough_distance?(move) + (move[:x].abs > 20) || (move[:y].abs > 20) + end + + def enough_diameter?(avg_diameter) + delta_diameter = if avg_diameter > 1 + avg_diameter - first.zoom + else + first.zoom - avg_diameter + end + delta_diameter > 0.3 end def enough_actions? (length > 1) && (elapsed_time > 0.1) end