# vim: ts=2 sw=2 et tw=72
= Ruby/Evas

== Introduction

Ruby/Evas provides a binding to
((<Evas|URL:http://www.enlightenment.org/pages/evas.html>)).  In
places where this documentation is inspecific, referring to the
original Evas documentation might be a good idea.

== Example

Here is a basic example to get an Evas up and running.

  require 'evas'

  dpy = Display.new
  w, h = dpy.width/2, dpy.height/2

((<Display>)) opens the connection to the X server, and must be
created before an Evas is made.  We also grab the display's width and
height to use when creating our window.

  evas = Evas.new(
    :display => dpy,
    :width => w, :height => h,
    :title => 'Evas Demonstration',
    :fontpath => '/usr/share/fonts/truetype'
  )

The Evas itself and its associated X window are actually created using
((<Evas.new>)).  Throughout Ruby/Evas, I use a hash to specify
arguments in the creation functions.  Some of the arguments are
optional (such as the (({title})) above), while others will raise an
exception if they're not provided (such as the (({display})) above).

  rect = evas.new_rectangle(
    :x => 0, :y => 0,
    :width => w, :height => h
    :layer => -1
  )
  rect.set_color(0, 0, 0, 255)
  rect.show()

An Evas has no default background.  If you don't cover it with
anything, you'll get garbage on the screen.  Here, we created a black
rectangle and put it on a background layer.

  text = evas.new_text(
    :x => 100, :y => 100,
    :fontname => "Verdana_Bold", :fontsize => 10,
    :text => "Evas test succeeded!"
  )
  text.set_color(255, 255, 255, 255)
  text.show()

All ((<EvasObject>))s share some common properties in their
constructor, such as the (({x})) and (({y})) to create the object at.
Others, such as the font-related properties here, are specific to
their object subtype.

  loop {
    evas.handle_x_events
    evas.render
  }

Finally, we let the Evas handle incoming X events and render itself.
((<Evas#handle_x_events>)) blocks while waiting for an X event, so
this loop doesn't waste processor; it only updates the canvas when
necessary.

== Reference

=== Evas

((<Evas>)) represents an actual Evas and its associated X window.

+ Creation

--- Evas.new(argumenthash)
      ((*Required arguments*)): (({:display, :width, :height})) .

      ((*Optional arguments*)): (({:title, :fontpath})).
      * (({title})) is the title set on the X window.  See also:
        ((<Evas#set_window_title>)).
      * (({fontpath})) is the default search path when loading fonts.
        See also: ((<Evas#font_add_path>)).

+ Updating

--- Evas#handle_x_events
      Let the Evas process any pending events from X, allowing it to
      handle things like callbacks on mouse clicks.

--- Evas#render
      Let the Evas render any part of the screen that has changed.

+ Attributes

--- Evas#font_add_path(path)
      Add a path to the list of paths to search for fonts.

--- Evas#set_window_title(title) / Evas#window_title=(title)
      Set the title on the X window associated with this Evas.

+ Subobjects

--- Evas#new_text(arghash)
      Create a new text object on this Evas.  See ((<EOText.new>)) for
      details.

--- Evas#new_rectangle(arghash)
      Create a new rectangle object on this Evas.  See
      ((<EORectangle.new>)) for details.

--- Evas#new_image(arghash)
      Create a new image object on this Evas.  See ((<EOImage.new>)) for
      details.

=== Display

((<Display>)) is a simple wrapper around an Xlib display object.  

--- Display#width
      return the width of the open display.
--- Display#height
      return the width of the open display.
--- Display#xconnection
      return the file descriptor of the X connection.  This is useful
      as a parameter for creating an IO object which will be used in
      ((<Kernel#select>)).

      Example:
        xio = IO.new(dpy.xconnection, "r")
        while not $quit
          if select([xio], nil, nil, 0.5)
            $evas.handle_x_events
          end
          puts "updating..."
          $evas.render
        end
      
      Here, the call to (({select()})) waits up to 0.5 seconds for
      input from X.  If the select succeeds, there are X events
      waiting so we need to call ((<Evas#handle_x_events>)).

      This is useful if you're running some sort of animation, or any
      other process that doesn't wait for X input.

=== EvasObject

((<EvasObject>)) represents an object on the Evas.  It is shared superclass
of the specific objects, such as ((<EOText>)), a object.

Specific objects are created by member functions on the ((<Evas>)), such
as ((<Evas#new_text>)).

+ Creation

--- EvasObject.new(argumenthash)
      EvasObject is never instantiated directly, but the arguments
      available here apply when creating any EvasObject.

      ((*Optional arguments*)): (({:x, :y, :width, :height, :layer})).
      * (({x})) and (({y})) specify the initial coordinates of the
        object.  See also: ((<EvasObject#move>)).
      * (({width})) and (({height})) specify the width and height of the
        object.  This is required for objects like a
        ((<rectangle|EORectangle>)).  See also: ((<EvasObject#resize>)).
      * (({layer})) is used for the stacking order of objects.  A lower
        number means a lower layer.  See also: ((<EvasObject#set_layer>)).

+ Attributes

--- EvasObject#move(x, y)
      Move this object to (x, y).

--- EvasObject#resize(width, height)
      Resize this object to (({width})) by (({height})).

--- EvasObject#set_layer(layer) / EvasObject#layer=(layer)
      (({layer})) is used for the stacking order of objects.  A lower
      number means a lower layer.

--- EvasObject#set_color(red, green, blue, alpha)
      Set the color of this object.  Color values range from 0 (none) to
      255 (full).  (({alpha})) ranges from 0 (fully transparent) to 255
      (opaque).

--- EvasObject#set_alpha(alpha) / EvasObject#alpha=(alpha)
      Set just the transparency of this object.(({alpha})) ranges from 0
      (fully transparent) to 255 (opaque).

+ Methods

--- EvasObject#show()
      Shows this object on the screen.  An object won't appear until it
      is shown.

--- EvasObject#hide()
      Hides this object from the Evas.

--- EvasObject#del()
      Deletes this object from the Evas.  Using an object after it has
      been deleted will probably cause segfaults (FIXME: should it raise
      an exception?  It'd add a tiny bit of overhead to check on every
      call...).

--- EvasObject#onevent
      Connects a handler to an event on this object.  The possible event
      types are:
      * (({EvasObject::EVENT_MOUSE_DOWN}))
      * (({EvasObject::EVENT_MOUSE_UP}))
      * (({EvasObject::EVENT_MOUSE_IN}))
      * (({EvasObject::EVENT_MOUSE_OUT}))
      * (({EvasObject::EVENT_MOUSE_MOVE}))
      ((<EvasObject#onevent>)) has one required argument, the event
      type, and also either a block or a ((<Proc>)).

      The provided block is passed three arguments: the button (not
      valid for some events) and the x, y coordinate of the mouse.

      Example:
        rect.onevent(EvasObject::EVENT_MOUSE_DOWN) do |button, x, y|
          $quit = true if button == 3
        end

      This could be equivalently written as:
      
        def mousedown(button, x, y)
          $quit = true if button == 3
        end

        rect.onevent(EvasObject::EVENT_MOUSE_DOWN, method('mousedown').to_proc)

      or

        rect.onevent(EvasObject::EVENT_MOUSE_DOWN, proc {|b,x,y| mousedown(b,x,y)} )


=== EORectangle

((<EORectangle>)) represents an Evas rectangle object.  Rectangles are
also the only objects usable as clip objects (see
((<EvasObject#set_clip>))).

((<EORectangle>))s are never created directly, and instead are created
through ((<Evas#new_rectangle>)).

+ Creation

--- EORectangle.new(argumenthash)
      See ((<EvasObject.new>)) for possible arguments.

      Note that unless you explicitly set a width and height, this
      rectangle will not be visible.

=== EOText

((<EOText>)) represents an Evas text object.

((<EOText>))s are never created directly, and instead are created
through ((<Evas#new_text>)).

+ Creation

--- EOText.new(argumenthash)
      ((*Required arguments*)): (({:fontname, :fontsize, :text})).
      * (({fontname})) and (({fontsize})) specify the font name and size
        to be used on this text object.  The font name must be the
        filename of a font in your font path (see
        ((<Evas#font_add_path>))).
      * (({text})) is the initial text to show.

      See also ((<EvasObject.new>)) for possible arguments.

+ Attributes

--- EOText#set_text(text) / EOText#text=(text)
      Sets the text displayed in this object.

=== EOImage

((<EOImage>)) represents an Evas image object.  ((<EOImages>))s are
never created directly, and instead are created through
((<Evas#new_image>)).

+ Creation

--- EOImage.new(argumenthash)
      ((*Required arguments*)): (({:path})).
      * (({path})) is the full path to the image file.
      ((*Optional arguments*)): (({:fill_x, :fill_y, :fill_width, :fill_height})).
      * (({:fill_x})), etc., call ((<EOImage#set_fill>)).

      See also ((<EvasObject.new>)) for possible arguments.

+ Attributes

--- EOImage#set_fill(x, y, w, h)
      This sets how large the image will be stretched to fit the image
      object.  This is not the same as the width and height of the
      object.

      Example:

        im = $evas.new_image(
          :x => 0, :y => 0, :width => 100, :height => 100,
          :path => '/path/to/some/image/file.png'
        )
        im.set_fill(0, 0, 50, 50)

      Here, the image will be tiled twice across the 100x100 region.
      Typically, you want to call set_fill with the same size as the
      object.

