Jay McGavren's Journal

2010-08-02

Ruboto On Acid - Multitouch

Ruboto 0.3 added TouchListener to its event handlers. Here’s my experiment with adding multitouch input to the Ruby On Acid demo…

When it starts up (or the factory resets), all attributes are controlled by an ExampleFactory, meaning they’ll randomly be assigned to LoopFactories, SineFactories, RandomWalkFactories, etc. Touch the screen, though, and control of the drawing x/y position will be given to the touchscreen. Touch in a second place, and control of random attributes will go to your second finger: r/g/b channel, opacity, width, or height.

java_import "android.content.pm.ActivityInfo"
java_import "android.content.Context"
java_import "android.graphics.Color"
java_import "android.graphics.Paint"
java_import "android.graphics.Canvas"
java_import "android.graphics.Bitmap"
java_import "android.graphics.RectF"
java_import "org.ruboto.embedded.RubotoView"

$activity.start_ruboto_activity "$acid" do


  handle_create do |bundle|
  end


  setup_content do
    $acid.set_requested_orientation(ActivityInfo::SCREEN_ORIENTATION_PORTRAIT)
    @f = RubyOnAcid::MetaFactory.new
    @f.source_factories << RubyOnAcid::ExampleFactory.new
    @resetter = RubyOnAcid::SkipFactory.new(:odds => 0.999)
    @input_factories = {}
    @input_factories[:touch] = RubyOnAcid::InputFactory.new
    @input_factories[:touch].source_factories << RubyOnAcid::ExampleFactory.new
    @input_factories.values.each {|factory| @f.source_factories << factory}
    reset_assignments
    RubotoView.new($acid)
  end


  handle_draw do |view, canvas|

    @bitmap ||= Bitmap.create_bitmap(view.get_width, view.get_height, Bitmap::Config::ARGB_8888)
    @buffer ||= Canvas.new(@bitmap)

    paint = Paint.new
    paint.color = Color.argb(
      @f.get(:alpha, :min => 50, :max => 255),
      @f.get(:red, :min => 50, :max => 255),
      @f.get(:green, :min => 50, :max => 255),
      @f.get(:blue, :min => 50, :max => 255)
    )
    paint.anti_alias = true
    
    x = @f.get(:x, :max => view.get_width)
    y = @f.get(:y, :max => view.get_height)
    x_radius = @f.get(:x_radius, :min => 5, :max => view.get_width / 2)
    y_radius = @f.get(:y_radius, :min => 5, :max => view.get_width / 2)
    rect = RectF.new(x - x_radius, y - y_radius, x + x_radius, y + y_radius)
    @buffer.draw_oval(rect, paint)
    
    canvas.draw_bitmap(@bitmap, 0, 0, nil)
    
    reset_assignments if @resetter.boolean(:reset)

    view.invalidate
    
  end

  
  def reset_assignments
    @input_factories[:touch].clear_assigned_keys
    @input_factories[:touch].clear_input_values
    @input_factories[:touch].clear_seen_values
    @f.reset_assignments
    @f.assign_factory(:x, @input_factories[:touch])
    @f.assign_factory(:y, @input_factories[:touch])
    @input_factories[:touch].assign_key(:x, :x_0)
    @input_factories[:touch].assign_key(:y, :y_0)
  end
  
  
  handle_touch_event do |event|
    0.upto 10 do |pointer_id|
      index = event.find_pointer_index(pointer_id)
      break if index == -1
      @input_factories[:touch].put("x_#{pointer_id}".to_sym, event.get_x(index))
      @input_factories[:touch].put("y_#{pointer_id}".to_sym, event.get_y(index))
    end
  end
  
end

As before, I’ve created an all-in-one script that inlines the entire Ruby On Acid library. Point your phone here and open the link with Ruboto (0.3.1 or later), give it a moment to load, then choose Execute: acid_multitouch.rb.

comments powered by Disqus