Example

The following example demonstrates the implementation of a new triangle Actor type.

Figure A.1. Behaviour

Behaviour

Source code

File: triangle_actor.h

#ifndef CLUTTER_TUTORIAL_TRIANGLE_ACTOR_H
#define CLUTTER_TUTORIAL_TRIANGLE_ACTOR_H

#include <cluttermm.h>

namespace Tutorial
{

class Triangle : public Clutter::Actor
{
public:
  static Glib::RefPtr<Triangle> create();
  static Glib::RefPtr<Triangle> create(const Clutter::Color& color);

  virtual ~Triangle();

  void set_color(const Clutter::Color& color);
  Clutter::Color get_color() const;

protected:
  Triangle();
  explicit Triangle(const Clutter::Color& color);

  virtual void on_paint();
  virtual void pick_vfunc(const Clutter::Color& color);

private:
  Clutter::Color color_;

  void do_triangle_paint(const Clutter::Color& color);
};

} // namespace Tutorial

#endif /* !CLUTTER_TUTORIAL_TRIANGLE_ACTOR */

File: triangle_actor.cc

#include "triangle_actor.h"
#include <cogl/cogl.h>

namespace Tutorial
{

Glib::RefPtr<Triangle> Triangle::create()
{
  return Glib::RefPtr<Triangle>(new Triangle());
}

Glib::RefPtr<Triangle> Triangle::create(const Clutter::Color& color)
{
  return Glib::RefPtr<Triangle>(new Triangle(color));
}

Triangle::Triangle()
:
  color_ (0xFF, 0xFF, 0xFF, 0xFF)
{}

Triangle::Triangle(const Clutter::Color& color)
:
  color_ (color)
{}

Triangle::~Triangle()
{}

void Triangle::do_triangle_paint(const Clutter::Color& color)
{
  const Clutter::Geometry geom = get_geometry();

  cogl_push_matrix();
  cogl_color(color.gobj());

  ClutterFixed coords[6];

  // Paint a triangle.  The parent paint call will have translated us into
  // position so paint from 0, 0.
  coords[0] = CLUTTER_INT_TO_FIXED(0);
  coords[1] = CLUTTER_INT_TO_FIXED(0);

  coords[2] = CLUTTER_INT_TO_FIXED(0);
  coords[3] = CLUTTER_INT_TO_FIXED(geom.get_height());

  coords[4] = CLUTTER_INT_TO_FIXED(geom.get_width());
  coords[5] = coords[3];

  cogl_path_polygon(coords, G_N_ELEMENTS(coords) / 2);
  cogl_path_fill();

  cogl_pop_matrix();
}

void Triangle::on_paint()
{
  // Paint the triangle with the actor's color:
  Clutter::Color color(color_);
  color.set_alpha( get_opacity() );
  do_triangle_paint(color);
}

void Triangle::pick_vfunc(const Clutter::Color& color)
{
  // Paint the triangle with the pick color, offscreen.
  // This is used by Clutter to detect the actor under the cursor 
  // by identifying the unique color under the cursor.
  do_triangle_paint(color);
}

/**
 * Tutorial::Triangle::get_color:
 *
 * @returns the color of the triangle.
 */
Clutter::Color Triangle::get_color() const
{
  return color_;
}

/**
 * Tutorial::Triangle::set_color:
 * @color: a Clutter::Color
 *
 * Sets the color of the triangle.
 */
void Triangle::set_color(const Clutter::Color& color)
{
  color_ = color;
  set_opacity(color_.get_alpha());

  if(is_visible())
    queue_redraw();
}

} // namespace Tutorial

File: main.cc

#include "triangle_actor.h"
#include <cluttermm.h>

int main(int argc, char** argv)
{
  Clutter::init(&argc, &argv);

  // Get the stage and set its size and color:
  Glib::RefPtr<Clutter::Stage> stage = Clutter::Stage::get_default();
  stage->set_size(200, 200);
  stage->set_color(Clutter::Color(0x00, 0x00, 0x00, 0xFF)); // black

  // Add our custom actor to the stage:
  Glib::RefPtr<Tutorial::Triangle> actor =
    Tutorial::Triangle::create(Clutter::Color(0xFF, 0xFF, 0xFF, 0x99));
  actor->set_size(100, 100);
  actor->set_position(20, 20);
  stage->add_actor(actor);
  actor->show();

  // Show the stage:
  stage->show();

  // Start the main loop, so we can respond to events:
  Clutter::main();

  return 0;
}