class Rabbit::Gesture::Handler

Constants

DEFAULT_BACK_COLOR
DEFAULT_CURRENT_COLOR
DEFAULT_LINE_COLOR
DEFAULT_LINE_WIDTH
DEFAULT_NEXT_COLOR
DEFAULT_NEXT_WIDTH
MOTION_TO_ANGLE

Attributes

back_color[RW]
current_color[RW]
line_color[RW]
line_width[RW]
next_color[RW]
next_width[RW]

Public Class Methods

new(conf={}) click to toggle source
Calls superclass method
# File lib/rabbit/gesture/handler.rb, line 36
def initialize(conf={})
  super()
  conf ||= {}
  @back_color = conf[:back_color] || DEFAULT_BACK_COLOR
  @line_color = conf[:line_color] || DEFAULT_LINE_COLOR
  @next_color = conf[:next_color] || DEFAULT_NEXT_COLOR
  @current_color = conf[:current_color] || DEFAULT_CURRENT_COLOR
  @line_width = conf[:line_width] || DEFAULT_LINE_WIDTH
  @next_width = conf[:next_width] || DEFAULT_NEXT_WIDTH
  @processor = Processor.new(conf[:threshold],
                             conf[:skew_threshold_angle])
  @actions = []
  @locus = []
end

Public Instance Methods

add_action(sequence, action, &block) click to toggle source
# File lib/rabbit/gesture/handler.rb, line 59
def add_action(sequence, action, &block)
  invalid_motion = sequence.find do |motion|
    not @processor.available_motion?(motion)
  end
  raise InvalidMotionError.new(invalid_motion) if invalid_motion
  @actions << [sequence, action, block]
end
button_motion(x, y, width, height) click to toggle source
# File lib/rabbit/gesture/handler.rb, line 79
def button_motion(x, y, width, height)
  new_x = @base_x + x
  new_y = @base_y + y
  @locus << [new_x, new_y]
  @processor.update_position(new_x, new_y)
end
button_release(x, y, width, height) click to toggle source
# File lib/rabbit/gesture/handler.rb, line 75
def button_release(x, y, width, height)
  perform_action
end
clear_actions() click to toggle source
# File lib/rabbit/gesture/handler.rb, line 55
def clear_actions
  @actions.clear
end
draw(renderer) click to toggle source
# File lib/rabbit/gesture/handler.rb, line 95
def draw(renderer)
  if @back_color.alpha == 1.0 or
      (@back_color.alpha < 1.0 and renderer.alpha_available?)
    size = renderer.size
    args = [true, 0, 0, size.real_width, size.real_height]
    args << @back_color
    renderer.draw_rectangle(*args)
  end

  draw_available_marks(renderer, next_available_motions)

  act, = action
  draw_mark(renderer, act, *@processor.position) if act

  draw_locus(renderer)
end
draw_last_locus(renderer) click to toggle source
# File lib/rabbit/gesture/handler.rb, line 86
def draw_last_locus(renderer)
  if @locus.size >= 2
    x1, y1 = @locus[-2]
    x2, y2 = @locus[-1]
    args = [x1, y1, x2, y2, @line_color, {:line_width => @line_width}]
    renderer.draw_line(*args)
  end
end
draw_locus(renderer) click to toggle source
# File lib/rabbit/gesture/handler.rb, line 112
def draw_locus(renderer)
  return if @locus.empty?
  renderer.draw_lines(@locus, @line_color, {:line_width => @line_width})
end
moved?() click to toggle source
# File lib/rabbit/gesture/handler.rb, line 117
def moved?
  @locus.size >= 2
end
processing?() click to toggle source
# File lib/rabbit/gesture/handler.rb, line 51
def processing?
  @processor.started?
end
start(button, x, y, base_x, base_y) click to toggle source
# File lib/rabbit/gesture/handler.rb, line 67
def start(button, x, y, base_x, base_y)
  @button = button
  @processor.start(x, y)
  @base_x = base_x
  @base_y = base_y
  @locus = [[x, y]]
end

Private Instance Methods

action() click to toggle source
# File lib/rabbit/gesture/handler.rb, line 134
def action
  motions = @processor.motions
  @actions.each do |sequence, act, block|
    return [act, block] if sequence == motions and act.sensitive?
  end
  nil
end
available_motions() click to toggle source
# File lib/rabbit/gesture/handler.rb, line 142
def available_motions
  motions = @processor.motions
  @actions.collect do |sequence, act, block|
    if sequence == motions and act.sensitive?
      [sequence.last, act]
    else
      nil
    end
  end.compact.uniq
end
calc_position_angle(motion) click to toggle source
# File lib/rabbit/gesture/handler.rb, line 237
def calc_position_angle(motion)
  MOTION_TO_ANGLE[motion]
end
calc_position_ratio(motion, inc, dec, inc_skew, dec_skew) click to toggle source
# File lib/rabbit/gesture/handler.rb, line 212
def calc_position_ratio(motion, inc, dec, inc_skew, dec_skew)
  case motion
  when *inc
    1
  when *inc_skew
    1 / Math.sqrt(2)
  when *dec
    -1
  when *dec_skew
    -1 / Math.sqrt(2)
  else
    0
  end
end
draw_action_image(renderer, act, x, y) { || ... } click to toggle source
# File lib/rabbit/gesture/handler.rb, line 176
def draw_action_image(renderer, act, x, y)
  icon = nil
  icon = act.create_icon(Gtk::IconSize::DIALOG) if act
  if icon
    stock, = icon.stock
    icon_size = icon.icon_size
    pixbuf = icon.render_icon_pixbuf(stock, icon_size)
    x -= pixbuf.width / 2.0
    y -= pixbuf.height / 2.0
    renderer.draw_pixbuf(pixbuf, x, y)
  elsif block_given?
    yield
  end
end
draw_available_marks(renderer, infos) click to toggle source
# File lib/rabbit/gesture/handler.rb, line 191
def draw_available_marks(renderer, infos)
  infos.each do |motion, act|
    args = [motion, %w(R), %w(L), %w(UR LR), %w(UL LL)]
    adjust_x = calc_position_ratio(*args)
    args = [motion, %w(D), %w(U), %w(LR LL), %w(UR UL)]
    adjust_y = calc_position_ratio(*args)

    threshold = @processor.threshold
    x, y = @processor.position
    center_x = x + threshold * adjust_x
    center_y = y + threshold * adjust_y
    draw_action_image(renderer, act, center_x, center_y) do
      angle = @processor.skew_threshold_angle
      base_angle = calc_position_angle(motion) - angle
      args = [false, x, y, threshold, base_angle, angle * 2]
      args.concat([@next_color, {:line_width => @next_width}])
      renderer.draw_arc_by_radius(*args)
    end
  end
end
draw_mark(renderer, act, x=nil, y=nil, radius=nil) click to toggle source
# File lib/rabbit/gesture/handler.rb, line 168
def draw_mark(renderer, act, x=nil, y=nil, radius=nil)
  x ||= @processor.position[0]
  y ||= @processor.position[1]
  radius ||= @processor.threshold / 2.0
  renderer.draw_circle_by_radius(true, x, y, radius, @current_color)
  draw_action_image(renderer, act, x, y)
end
make_color(color) click to toggle source
# File lib/rabbit/gesture/handler.rb, line 241
def make_color(color)
  color ||= @back_color
  if color.is_a?(Renderer::Color)
    color
  else
    Renderer::Color.parse(color)
  end
end
match?() click to toggle source
# File lib/rabbit/gesture/handler.rb, line 164
def match?
  not action.nil?
end
next_available_motions() click to toggle source
# File lib/rabbit/gesture/handler.rb, line 153
def next_available_motions
  motions = @processor.motions
  @actions.collect do |sequence, act, block|
    if sequence[0..-2] == motions and act.sensitive?
      [sequence.last, act]
    else
      nil
    end
  end.compact.uniq
end
perform_action() click to toggle source
# File lib/rabbit/gesture/handler.rb, line 122
def perform_action
  act, block = action
  @processor.reset
  @locus.clear
  if act
    act.activate(&block)
    true
  else
    false
  end
end