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