Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

Group Class Reference

A Drawing element that consists of a group of shapes. More...

#include <Group.h>

Inheritance diagram for Group:

DrawElement Object Drawing::Contents List of all members.

Public Methods

 Group ()
void add_feature (std::string, Object *)
virtual void move (const Position &)
 Move all constituents rigidly so they center around the new position.

virtual void set_color (color)
 Set the color of all constituents.

virtual bool is_hit (const Position &)
 Return true if any element is covers this position.

virtual void set_selected (bool b)
 Set the selected bit of the group as a whole.

virtual int mutate (const Position &)
 Mutate a group.

virtual void render (SimpleWindow *)
 Draw the group into the canvas.

void add_element (DrawElement *e)
 Add an element to the group.

void remove_element (DrawElement *)
 Remove an element from the group.

DrawElementfind_hit (const Position &)
 Return the constituent that is at this location (if any).

void to_front (DrawElement *)
 Move an element to the front of the group.

void to_back (DrawElement *)
 Move an element to the back of the group.

virtual void set_changed (DrawElement *)
 Informs the group of a change in a constituent.


Private Types

typedef std::list< DrawElement * > Elements

Private Attributes

Elements elements

Static Private Attributes

Group::Factory factory

Detailed Description

A Drawing element that consists of a group of shapes.

A Group can be a visible collection of objects, but the collection of all objects in the drawing is also stored as a Group. Thus, a drawing is represented as heirarchical structure of DrawElements.


Member Typedef Documentation

typedef std::list<DrawElement*> Group::Elements [private]
 


Constructor & Destructor Documentation

Group::Group  
 

00004 : DrawElement(), elements() {}


Member Function Documentation

void Group::add_element DrawElement   e
 

Add an element to the group.

Then recompute center of gravity.

Exceptions:
std::invalid_argument  if e is already in a group.

00068 {
00069   if (e->set_location(this)) {
00070     elements.push_front(e);
00071     set_changed(e);
00072   } else {
00073     throw std::invalid_argument("located elsewhere");
00074   }
00075 }

void Group::add_feature std::string   ,
Object  
[virtual]
 

Reimplemented from Object.

00007 {
00008   if (key == "element") {
00009     if (DrawElement* e = dynamic_cast<DrawElement*>(object)) {
00010       add_element(e);
00011     } else throw unknown_feature("group element must be draw element");
00012   } else Object::add_feature(key,object);
00013 }

DrawElement * Group::find_hit const Position &   
 

Return the constituent that is at this location (if any).

00088 {
00089   Elements::const_iterator begin = elements.begin(), end = elements.end();
00090   for (Elements::const_iterator p = begin; p != end; ++p)
00091     if ((*p)->is_hit(pos)) return *p;
00092   return 0;
00093 }

bool Group::is_hit const Position &    [virtual]
 

Return true if any element is covers this position.

Implements DrawElement.

00030                                       {
00031   Elements::const_iterator begin = elements.begin(), end = elements.end();
00032   for (Elements::const_iterator p = begin; p != end; ++p)
00033     if ((*p)->is_hit(pos)) return true;
00034   return false;
00035 }

void Group::move const Position &    [virtual]
 

Move all constituents rigidly so they center around the new position.

Reimplemented from DrawElement.

00015                                         {
00016   Position delta = new_pos - get_center();
00017   Elements::const_iterator begin = elements.begin(), end = elements.end();
00018   for (Elements::const_iterator p = begin; p != end; ++p)
00019     (*p)->move((*p)->get_center()+delta);
00020   DrawElement::move(new_pos);
00021 }

int Group::mutate const Position &    [virtual]
 

Mutate a group.

If the position indicates a group constituent, move it into the surrounding group. If it indicates an element not in this group, move that element into the group.

Returns :
1 no matter what

Reimplemented from DrawElement.

00044                                      {
00045   Group* inside = get_location();
00046   if (DrawElement *e = find_hit(pos)) {
00047     remove_element(e);
00048     e->set_selected(false); // or inconsistency results
00049     if (inside) inside->add_element(e);
00050   } else if (inside) {
00051     if (DrawElement *e = inside->find_hit(pos)) {
00052       inside->remove_element(e);
00053       add_element(e);
00054       e->set_selected(true);
00055     }
00056   }
00057   return 1;
00058 }

void Group::remove_element DrawElement  
 

Remove an element from the group.

Then recompute center of gravity.

Exceptions:
std::invalid_argument  if e is not already in a group.

00078 {
00079   if (e->reset_location(this)) {
00080     elements.remove(e);
00081     set_changed(e);
00082   } else {
00083     throw std::invalid_argument("not located here");
00084   }
00085 }

void Group::render SimpleWindow   [virtual]
 

Draw the group into the canvas.

Implements DrawElement.

00060                                   {
00061   // paint from back first!
00062   for (Elements::reverse_iterator i = elements.rbegin();
00063        i != elements.rend(); ++i)
00064     (*i)->render(w);
00065 }

void Group::set_changed DrawElement   [virtual]
 

Informs the group of a change in a constituent.

Recomputes center of gravity. If there is a containing group, this group is also informed.

Reimplemented in Drawing::Contents.

00117                                     {
00118   // recompute center (average of elements)
00119   Position sum(0.0,0.0);
00120   Elements::const_iterator begin = elements.begin(), end = elements.end();
00121   for (Elements::const_iterator p = begin; p != end; ++p)
00122     sum = sum + (*p)->get_center();
00123   if (!elements.empty()) sum = sum/elements.size();
00124   // if no elements, don't divide by zero;
00125   // center will be (0.0,0.0) but is irrelevant anyway  
00126   DrawElement::move(sum);
00127 }

void Group::set_color color    [virtual]
 

Set the color of all constituents.

Reimplemented from DrawElement.

00023                              {
00024   Elements::const_iterator begin = elements.begin(), end = elements.end();
00025   for (Elements::const_iterator p = begin; p != end; ++p)
00026     (*p)->set_color(c);
00027   DrawElement::set_color(c);
00028 }

void Group::set_selected bool    b [virtual]
 

Set the selected bit of the group as a whole.

It also sets the selected bits of the constituents so that they render differently.

Reimplemented from DrawElement.

00037                                {
00038   Elements::const_iterator begin = elements.begin(), end = elements.end();
00039   for (Elements::const_iterator p = begin; p != end; ++p)
00040     (*p)->set_selected(b);
00041   DrawElement::set_selected(b);
00042 }

void Group::to_back DrawElement  
 

Move an element to the back of the group.

It will be drawn first.

Exceptions:
std::invalid_argument  if e is not already in a group.

00107 {
00108   if (e->check_location(this)) {
00109     elements.remove(e);
00110     elements.push_back(e);
00111     set_changed(e);
00112   } else {
00113     throw std::invalid_argument("not located here");
00114   }
00115 }

void Group::to_front DrawElement  
 

Move an element to the front of the group.

It will be drawn last.

Exceptions:
std::invalid_argument  if e is not already in a group.

00096 {
00097   if (e->check_location(this)) {
00098     elements.remove(e);
00099     elements.push_front(e);
00100     set_changed(e);
00101   } else {
00102     throw std::invalid_argument("not located here");
00103   }
00104 }


Member Data Documentation

Elements Group::elements [private]
 

Group::Factory Group::factory [static, private]
 


The documentation for this class was generated from the following files:
Generated on Fri Nov 8 10:52:30 2002 for Draw by doxygen1.2.17