* Transformers have Name() now

* added TransformerFactory to instantiate the various types via the GUI
* added Transformer menu to main window
* added TransformerListView that shows the Transformers applied to the
  selected Shape
* implemented more powerful listener interface for Shape, used by
  TransformerListView


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18027 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2006-07-04 14:16:03 +00:00
parent 9d9c1564b8
commit bab183a273
26 changed files with 746 additions and 53 deletions

View File

@ -75,6 +75,7 @@ Application Icon-O-Matic :
PathListView.cpp
ShapeListView.cpp
SwatchGroup.cpp
TransformerListView.cpp
# gradient
Gradient.cpp
# shape
@ -101,6 +102,7 @@ Application Icon-O-Matic :
PerspectiveTransformer.cpp
StrokeTransformer.cpp
Transformer.cpp
TransformerFactory.cpp
#
CanvasView.cpp
IconEditorApp.cpp

View File

@ -24,6 +24,8 @@
#include "PathListView.h"
#include "ShapeListView.h"
#include "SwatchGroup.h"
#include "TransformerFactory.h"
#include "TransformerListView.h"
// TODO: just for testing
#include "AffineTransformer.h"
@ -46,11 +48,13 @@ enum {
MSG_NEW_PATH = 'nwvp',
MSG_PATH_SELECTED = 'vpsl',
MSG_SHAPE_SELECTED = 'spsl',
MSG_ADD_TRANSFORMER = 'adtr',
};
// constructor
MainWindow::MainWindow(IconEditorApp* app, Document* document)
: BWindow(BRect(50, 50, 661, 661), "Icon-O-Matic",
: BWindow(BRect(50, 50, 781, 781), "Icon-O-Matic",
B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
B_ASYNCHRONOUS_CONTROLS),
fApp(app),
@ -106,9 +110,28 @@ case MSG_SHAPE_SELECTED: {
if (message->FindPointer("shape", (void**)&shape) < B_OK)
shape = NULL;
fPathListView->SetCurrentShape(shape);
fTransformerListView->SetShape(shape);
break;
}
case MSG_ADD_TRANSFORMER: {
Shape* shape = fPathListView->CurrentShape();
if (!shape)
break;
uint32 type;
if (message->FindInt32("type", (int32*)&type) < B_OK)
break;
Transformer* transformer
= TransformerFactory::TransformerFor(type,
shape->VertexSource());
// TODO: command
if (transformer)
shape->AddTransformer(transformer);
break;
}
default:
BWindow::MessageReceived(message);
}
@ -222,7 +245,7 @@ MainWindow::_Init()
StrokeTransformer* transformer
= new StrokeTransformer(shape->VertexSource());
transformer->width(5.0);
shape->AppendTransformer(transformer);
shape->AddTransformer(transformer);
shape->SetName("Outline");
fDocument->Icon()->Shapes()->AddShape(shape);
@ -239,7 +262,7 @@ MainWindow::_Init()
*transformer2 *= agg::trans_affine_translation(10.0, 6.0);
*transformer2 *= agg::trans_affine_rotation(0.2);
*transformer2 *= agg::trans_affine_scaling(0.8, 0.6);
shape->AppendTransformer(transformer2);
shape->AddTransformer(transformer2);
shape->SetName("Transformed");
fDocument->Icon()->Shapes()->AddShape(shape);
@ -291,6 +314,7 @@ MainWindow::_CreateGUI(BRect bounds)
bounds.bottom = bounds.top + 63;
fIconPreview64 = new IconView(bounds, "icon preview 64");
// path list view
bounds.OffsetBy(bounds.Width() + 6, 0);
bounds.right = bounds.left + 100;
bounds.bottom = fCanvasView->Frame().top - 5.0;
@ -298,10 +322,16 @@ MainWindow::_CreateGUI(BRect bounds)
fPathListView = new PathListView(bounds, "path list view",
new BMessage(MSG_PATH_SELECTED), this);
// shape list view
bounds.OffsetBy(bounds.Width() + 6 + B_V_SCROLL_BAR_WIDTH, 0);
fShapeListView = new ShapeListView(bounds, "shape list view",
new BMessage(MSG_SHAPE_SELECTED), this);
// transformer list view
bounds.OffsetBy(bounds.Width() + 6 + B_V_SCROLL_BAR_WIDTH, 0);
fTransformerListView = new TransformerListView(bounds,
"transformer list view");
bg->AddChild(fSwatchGroup);
bg->AddChild(fIconPreview16);
@ -319,6 +349,11 @@ MainWindow::_CreateGUI(BRect bounds)
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,
0, false, true,
B_NO_BORDER));
bg->AddChild(new BScrollView("transformer list scroll view",
fTransformerListView,
B_FOLLOW_RIGHT | B_FOLLOW_TOP,
0, false, true,
B_NO_BORDER));
bg->AddChild(fCanvasView);
@ -336,12 +371,14 @@ MainWindow::_CreateMenuBar(BRect frame)
BMenu* pathMenu = new BMenu("Path");
BMenu* styleMenu = new BMenu("Style");
BMenu* shapeMenu = new BMenu("Shape");
BMenu* transformerMenu = new BMenu("Transformer");
menuBar->AddItem(fileMenu);
menuBar->AddItem(editMenu);
menuBar->AddItem(pathMenu);
menuBar->AddItem(styleMenu);
menuBar->AddItem(shapeMenu);
menuBar->AddItem(transformerMenu);
// Edit
fUndoMI = new BMenuItem("<nothing to undo>",
@ -358,6 +395,20 @@ MainWindow::_CreateMenuBar(BRect frame)
// Path
pathMenu->AddItem(new BMenuItem("New", new BMessage(MSG_NEW_PATH)));
// Transformer
int32 cookie = 0;
uint32 type;
BString name;
while (TransformerFactory::NextType(&cookie, &type, &name)) {
BMessage* message = new BMessage(MSG_ADD_TRANSFORMER);
message->AddInt32("type", type);
BString label("Add ");
label << name;
transformerMenu->AddItem(new BMenuItem(label.String(), message));
}
transformerMenu->SetTargetForItems(this);
return menuBar;
}

View File

@ -22,6 +22,8 @@ class IconView;
class PathListView;
class ShapeListView;
class SwatchGroup;
class TransformerListView;
class MultipleManipulatorState;
class MainWindow : public BWindow,
@ -59,6 +61,8 @@ class MainWindow : public BWindow,
PathListView* fPathListView;
ShapeListView* fShapeListView;
TransformerListView* fTransformerListView;
// TODO: for testing only...
MultipleManipulatorState* fState;
};

View File

@ -29,7 +29,7 @@
- Cloning
* add more powerful listener interface to Shape
(TransformerAdded()/Removed()...)
(TransformerAdded()/Removed()...) [done]
* implement commands for the newly added editing features
@ -43,7 +43,7 @@
* list of paths used by shape, but it could also be done such that
used paths are marked in the global list when a shape is selected [done]
* list of transformers attached to the selected shape
* list of transformers attached to the selected shape [done]
* area for styles, style is either solid color or gradient
@ -65,3 +65,4 @@
* compound shape single pass rendering [done]
* auto hinting (aligning to pixels) of marked shapes
* level of detail support to hide/show shapes

View File

@ -80,7 +80,7 @@ SimpleItem::DrawBackground(BView *owner, BRect frame, uint32 flags)
color = tint_color(color, 1.06);
// background
if (IsSelected())
color = tint_color(color, B_DARKEN_2_TINT);
color = tint_color(color, (B_DARKEN_1_TINT + B_DARKEN_2_TINT) / 2.0);
owner->SetLowColor(color);
owner->FillRect(frame, B_SOLID_LOW);
}
@ -894,10 +894,23 @@ void
SimpleListView::MakeDragMessage(BMessage* message) const
{
if (message) {
message->AddPointer("list", (void*)dynamic_cast<const DragSortableListView*>(this));
message->AddPointer("list",
(void*)dynamic_cast<const DragSortableListView*>(this));
int32 index;
for (int32 i = 0; (index = CurrentSelection(i)) >= 0; i++)
message->AddInt32("index", index);
}
}
// _MakeEmpty
void
SimpleListView::_MakeEmpty()
{
// NOTE: BListView::MakeEmpty() uses ScrollTo()
// for which the object needs to be attached to
// a BWindow.... :-(
int32 count = CountItems();
for (int32 i = count - 1; i >= 0; i--)
delete RemoveItem(i);
}

View File

@ -184,6 +184,9 @@ class SimpleListView :
BRect itemFrame) const;
virtual void MakeDragMessage(BMessage* message) const;
protected:
void _MakeEmpty();
private:
BMessage* fSelectionChangeMessage;

View File

@ -515,18 +515,6 @@ PathListView::_ItemForPath(VectorPath* path) const
return NULL;
}
// _MakeEmpty
void
PathListView::_MakeEmpty()
{
// NOTE: BListView::MakeEmpty() uses ScrollTo()
// for which the object needs to be attached to
// a BWindow.... :-(
int32 count = CountItems();
for (int32 i = count - 1; i >= 0; i--)
delete RemoveItem(i);
}
// #pragma mark -
// _UpdateMarks

View File

@ -65,7 +65,6 @@ class PathListView : public SimpleListView,
bool _RemovePath(VectorPath* path);
PathListItem* _ItemForPath(VectorPath* path) const;
void _MakeEmpty();
friend class ShapePathListener;
void _UpdateMarks();

View File

@ -371,15 +371,3 @@ ShapeListView::_ItemForShape(Shape* shape) const
return NULL;
}
// _MakeEmpty
void
ShapeListView::_MakeEmpty()
{
// NOTE: BListView::MakeEmpty() uses ScrollTo()
// for which the object needs to be attached to
// a BWindow.... :-(
int32 count = CountItems();
for (int32 i = count - 1; i >= 0; i--)
delete RemoveItem(i);
}

View File

@ -57,7 +57,6 @@ class ShapeListView : public SimpleListView,
bool _RemoveShape(Shape* shape);
ShapeListItem* _ItemForShape(Shape* shape) const;
void _MakeEmpty();
BMessage* fMessage;

View File

@ -0,0 +1,290 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "TransformerListView.h"
#include <new>
#include <stdio.h>
#include <Application.h>
#include <ListItem.h>
#include <Message.h>
#include <Mime.h>
#include <Window.h>
#include "CommandStack.h"
//#include "MoveTransformersCommand.h"
//#include "RemoveTransformersCommand.h"
#include "Transformer.h"
#include "Observer.h"
#include "Selection.h"
using std::nothrow;
class TransformerItem : public SimpleItem {
public:
TransformerItem(Transformer* t)
: SimpleItem(t->Name()),
transformer(t)
{
}
virtual ~TransformerItem()
{
}
Transformer* transformer;
};
// #pragma mark -
enum {
MSG_DRAG_TRANSFORMER = 'drgt',
};
// constructor
TransformerListView::TransformerListView(BRect frame, const char* name,
BMessage* message, BHandler* target)
: SimpleListView(frame, name,
NULL, B_MULTIPLE_SELECTION_LIST),
fMessage(message),
fShape(NULL),
fSelection(NULL),
fCommandStack(NULL)
{
SetDragCommand(MSG_DRAG_TRANSFORMER);
SetTarget(target);
}
// destructor
TransformerListView::~TransformerListView()
{
_MakeEmpty();
delete fMessage;
if (fShape)
fShape->RemoveListener(this);
}
// SelectionChanged
void
TransformerListView::SelectionChanged()
{
// TODO: single selection versus multiple selection
TransformerItem* item
= dynamic_cast<TransformerItem*>(ItemAt(CurrentSelection(0)));
if (fMessage) {
BMessage message(*fMessage);
message.AddPointer("transformer", item ? (void*)item->transformer : NULL);
Invoke(&message);
}
// modify global Selection
if (!fSelection)
return;
if (item)
fSelection->Select(item->transformer);
else
fSelection->DeselectAll();
}
// MakeDragMessage
void
TransformerListView::MakeDragMessage(BMessage* message) const
{
SimpleListView::MakeDragMessage(message);
message->AddPointer("container", fShape);
int32 count = CountItems();
for (int32 i = 0; i < count; i++) {
TransformerItem* item = dynamic_cast<TransformerItem*>(ItemAt(CurrentSelection(i)));
if (item) {
message->AddPointer("transformer", (void*)item->transformer);
} else
break;
}
}
// #pragma mark -
// MoveItems
void
TransformerListView::MoveItems(BList& items, int32 toIndex)
{
// if (!fCommandStack || !fShape)
// return;
//
// int32 count = items.CountItems();
// Transformer** transformers = new (nothrow) Transformer*[count];
// if (!shapes)
// return;
//
// for (int32 i = 0; i < count; i++) {
// TransformerItem* item
// = dynamic_cast<TransformerItem*>((BListItem*)items.ItemAtFast(i));
// transformers[i] = item ? item->transformer : NULL;
// }
//
// MoveTransformersCommand* command
// = new (nothrow) MoveTransformersCommand(fShape,
// transformers, count, toIndex);
// if (!command) {
// delete[] transformers;
// return;
// }
//
// fCommandStack->Perform(command);
}
// CopyItems
void
TransformerListView::CopyItems(BList& items, int32 toIndex)
{
MoveItems(items, toIndex);
// TODO: allow copying items
}
// RemoveItemList
void
TransformerListView::RemoveItemList(BList& indexList)
{
// if (!fCommandStack || !fShape)
// return;
//
// int32 count = indexList.CountItems();
// const int32* indices = (int32*)indexList.Items();
//
// RemoveTransformersCommand* command
// = new (nothrow) RemoveTransformersCommand(fShape,
// indices, count);
// fCommandStack->Perform(command);
}
// CloneItem
BListItem*
TransformerListView::CloneItem(int32 index) const
{
if (TransformerItem* item = dynamic_cast<TransformerItem*>(ItemAt(index))) {
return new TransformerItem(item->transformer);
}
return NULL;
}
// #pragma mark -
// TransformerAdded
void
TransformerListView::TransformerAdded(Transformer* transformer, int32 index)
{
// NOTE: we are in the thread that messed with the
// Shape, so no need to lock the document, when this is
// changed to asynchronous notifications, then it would
// need to be read-locked!
if (!LockLooper())
return;
_AddTransformer(transformer, index);
UnlockLooper();
}
// TransformerRemoved
void
TransformerListView::TransformerRemoved(Transformer* transformer)
{
// NOTE: we are in the thread that messed with the
// Shape, so no need to lock the document, when this is
// changed to asynchronous notifications, then it would
// need to be read-locked!
if (!LockLooper())
return;
_RemoveTransformer(transformer);
UnlockLooper();
}
// #pragma mark -
// SetShape
void
TransformerListView::SetShape(Shape* shape)
{
if (fShape == shape)
return;
// detach from old container
if (fShape)
fShape->RemoveListener(this);
_MakeEmpty();
fShape = shape;
if (!fShape)
return;
fShape->AddListener(this);
int32 count = fShape->CountTransformers();
for (int32 i = 0; i < count; i++)
_AddTransformer(fShape->TransformerAtFast(i), i);
}
// SetSelection
void
TransformerListView::SetSelection(Selection* selection)
{
fSelection = selection;
}
// SetCommandStack
void
TransformerListView::SetCommandStack(CommandStack* stack)
{
fCommandStack = stack;
}
// #pragma mark -
// _AddTransformer
bool
TransformerListView::_AddTransformer(Transformer* transformer, int32 index)
{
if (transformer)
return AddItem(new TransformerItem(transformer), index);
return false;
}
// _RemoveTransformer
bool
TransformerListView::_RemoveTransformer(Transformer* transformer)
{
TransformerItem* item = _ItemForTransformer(transformer);
if (item && RemoveItem(item)) {
delete item;
return true;
}
return false;
}
// _ItemForTransformer
TransformerItem*
TransformerListView::_ItemForTransformer(Transformer* transformer) const
{
for (int32 i = 0;
TransformerItem* item = dynamic_cast<TransformerItem*>(ItemAt(i));
i++) {
if (item->transformer == transformer)
return item;
}
return NULL;
}

View File

@ -0,0 +1,63 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef TRANSFORMER_LIST_VIEW_H
#define TRANSFORMER_LIST_VIEW_H
#include "ListViews.h"
#include "Shape.h"
class CommandStack;
class Transformer;
class TransformerItem;
class Selection;
class TransformerListView : public SimpleListView,
public ShapeListener {
public:
TransformerListView(BRect frame,
const char* name,
BMessage* selectionMessage = NULL,
BHandler* target = NULL);
virtual ~TransformerListView();
// SimpleListView interface
virtual void SelectionChanged();
virtual void MakeDragMessage(BMessage* message) const;
virtual void MoveItems(BList& items, int32 toIndex);
virtual void CopyItems(BList& items, int32 toIndex);
virtual void RemoveItemList(BList& indices);
virtual BListItem* CloneItem(int32 atIndex) const;
// ShapeListener interface
virtual void TransformerAdded(Transformer* transformer,
int32 index);
virtual void TransformerRemoved(Transformer* transformer);
// TransformerListView
void SetShape(Shape* shape);
void SetSelection(Selection* selection);
void SetCommandStack(CommandStack* stack);
private:
bool _AddTransformer(Transformer* transformer, int32 index);
bool _RemoveTransformer(Transformer* transformer);
TransformerItem* _ItemForTransformer(Transformer* transformer) const;
BMessage* fMessage;
Shape* fShape;
Selection* fSelection;
CommandStack* fCommandStack;
};
#endif // TRANSFORMER_LIST_VIEW_H

View File

@ -11,6 +11,18 @@
using std::nothrow;
// constructor
ShapeListener::ShapeListener()
{
}
// destructor
ShapeListener::~ShapeListener()
{
}
// #pragma mark -
// constructor
Shape::Shape(::Style* style)
: Observable(),
@ -148,6 +160,28 @@ Shape::SetStyle(::Style* style)
Notify();
}
// #pragma mark -
// SetName
void
Shape::SetName(const char* name)
{
if (fName == name)
return;
fName = name;
Notify();
}
// Name
const char*
Shape::Name() const
{
return fName.String();
}
// #pragma mark -
// Bounds
BRect
Shape::Bounds(bool updateLast) const
@ -191,37 +225,122 @@ Shape::VertexSource()
return *source;
}
// AppendTransformer
// AddTransformer
bool
Shape::AppendTransformer(Transformer* transformer)
Shape::AddTransformer(Transformer* transformer)
{
return AddTransformer(transformer, CountTransformers());
}
// AddTransformer
bool
Shape::AddTransformer(Transformer* transformer, int32 index)
{
if (!transformer)
return false;
if (!fTransformers.AddItem((void*)transformer))
if (!fTransformers.AddItem((void*)transformer, index))
return false;
Notify();
_NotifyTransformerAdded(transformer, index);
return true;
}
// RemoveTransformer
bool
Shape::RemoveTransformer(Transformer* transformer)
{
if (fTransformers.RemoveItem((void*)transformer)) {
_NotifyTransformerRemoved(transformer);
return true;
}
return false;
}
// #pragma mark -
// SetName
void
Shape::SetName(const char* name)
// CountShapes
int32
Shape::CountTransformers() const
{
if (fName == name)
return;
return fTransformers.CountItems();
}
fName = name;
// HasTransformer
bool
Shape::HasTransformer(Transformer* transformer) const
{
return fTransformers.HasItem((void*)transformer);
}
// IndexOf
int32
Shape::IndexOf(Transformer* transformer) const
{
return fTransformers.IndexOf((void*)transformer);
}
// TransformerAt
Transformer*
Shape::TransformerAt(int32 index) const
{
return (Transformer*)fTransformers.ItemAt(index);
}
// TransformerAtFast
Transformer*
Shape::TransformerAtFast(int32 index) const
{
return (Transformer*)fTransformers.ItemAtFast(index);
}
// #pragma mark -
// AddListener
bool
Shape::AddListener(ShapeListener* listener)
{
if (listener && !fListeners.HasItem((void*)listener))
return fListeners.AddItem((void*)listener);
return false;
}
// RemoveListener
bool
Shape::RemoveListener(ShapeListener* listener)
{
return fListeners.RemoveItem((void*)listener);
}
// #pragma mark -
// _NotifyTransformerAdded
void
Shape::_NotifyTransformerAdded(Transformer* transformer, int32 index) const
{
BList listeners(fListeners);
int32 count = listeners.CountItems();
for (int32 i = 0; i < count; i++) {
ShapeListener* listener
= (ShapeListener*)listeners.ItemAtFast(i);
listener->TransformerAdded(transformer, index);
}
// TODO: merge Observable and ShapeListener interface
Notify();
}
// Name
const char*
Shape::Name() const
// _NotifyTransformerRemoved
void
Shape::_NotifyTransformerRemoved(Transformer* transformer) const
{
return fName.String();
BList listeners(fListeners);
int32 count = listeners.CountItems();
for (int32 i = 0; i < count; i++) {
ShapeListener* listener
= (ShapeListener*)listeners.ItemAtFast(i);
listener->TransformerRemoved(transformer);
}
// TODO: merge Observable and ShapeListener interface
Notify();
}

View File

@ -14,6 +14,17 @@
class Style;
// TODO: merge Observer and ShapeListener interface
class ShapeListener {
public:
ShapeListener();
virtual ~ShapeListener();
virtual void TransformerAdded(Transformer* t,
int32 index) = 0;
virtual void TransformerRemoved(Transformer* t) = 0;
};
class Shape : public Observable,
public Observer, // observing all the paths
public Referenceable,
@ -44,24 +55,44 @@ class Shape : public Observable,
inline ::Style* Style() const
{ return fStyle; }
void SetName(const char* name);
const char* Name() const;
inline BRect LastBounds() const
{ return fLastBounds; }
BRect Bounds(bool updateLast = false) const;
::VertexSource& VertexSource();
bool AppendTransformer(
Transformer* transformer);
void SetName(const char* name);
const char* Name() const;
bool AddTransformer(Transformer* transformer);
bool AddTransformer(Transformer* transformer,
int32 index);
bool RemoveTransformer(Transformer* transformer);
int32 CountTransformers() const;
bool HasTransformer(Transformer* transformer) const;
int32 IndexOf(Transformer* transformer) const;
Transformer* TransformerAt(int32 index) const;
Transformer* TransformerAtFast(int32 index) const;
bool AddListener(ShapeListener* listener);
bool RemoveListener(ShapeListener* listener);
private:
void _NotifyTransformerAdded(Transformer* t,
int32 index) const;
void _NotifyTransformerRemoved(Transformer* t) const;
PathContainer* fPaths;
::Style* fStyle;
PathSource fPathSource;
BList fTransformers;
BList fListeners;
mutable BRect fLastBounds;
BString fName;

View File

@ -42,3 +42,11 @@ AffineTransformer::SetSource(VertexSource& source)
Affine::attach(source);
}
// Name
const char*
AffineTransformer::Name() const
{
return "Transformation";
}

View File

@ -29,6 +29,8 @@ class AffineTransformer : public Transformer,
virtual unsigned vertex(double* x, double* y);
virtual void SetSource(VertexSource& source);
virtual const char* Name() const;
};
#endif // AFFINE_TRANSFORMER_H

View File

@ -42,3 +42,10 @@ ContourTransformer::SetSource(VertexSource& source)
Contour::attach(source);
}
// Name
const char*
ContourTransformer::Name() const
{
return "Contour";
}

View File

@ -26,6 +26,8 @@ class ContourTransformer : public Transformer,
virtual unsigned vertex(double* x, double* y);
virtual void SetSource(VertexSource& source);
virtual const char* Name() const;
};
#endif // CONTOUR_TRANSFORMER_H

View File

@ -42,3 +42,11 @@ PerspectiveTransformer::SetSource(VertexSource& source)
Perspective::attach(source);
}
// Name
const char*
PerspectiveTransformer::Name() const
{
return "Perspective";
}

View File

@ -29,6 +29,8 @@ class PerspectiveTransformer : public Transformer,
virtual unsigned vertex(double* x, double* y);
virtual void SetSource(VertexSource& source);
virtual const char* Name() const;
};
#endif // PERSPECTIVE_TRANSFORMER_H

View File

@ -42,3 +42,11 @@ StrokeTransformer::SetSource(VertexSource& source)
Stroke::attach(source);
}
// Name
const char*
StrokeTransformer::Name() const
{
return "Stroke";
}

View File

@ -26,6 +26,8 @@ class StrokeTransformer : public Transformer,
virtual unsigned vertex(double* x, double* y);
virtual void SetSource(VertexSource& source);
virtual const char* Name() const;
};
#endif // STROKE_TRANSFORMER_H

View File

@ -51,3 +51,12 @@ Transformer::SetSource(VertexSource& source)
{
fSource = source;
}
// #pragma mark -
// SelectedChanged
void
Transformer::SelectedChanged()
{
}

View File

@ -9,6 +9,8 @@
#ifndef TRANSFORMER_H
#define TRANSFORMER_H
#include "Selectable.h"
class VertexSource {
public:
VertexSource();
@ -19,7 +21,8 @@ class VertexSource {
};
class Transformer : public VertexSource {
class Transformer : public VertexSource,
public Selectable {
public:
Transformer(VertexSource& source);
virtual ~Transformer();
@ -29,6 +32,11 @@ class Transformer : public VertexSource {
virtual void SetSource(VertexSource& source);
virtual const char* Name() const = 0;
// Selectable interface
virtual void SelectedChanged();
private:
VertexSource& fSource;
};

View File

@ -0,0 +1,57 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "TransformerFactory.h"
#include "AffineTransformer.h"
#include "ContourTransformer.h"
#include "PerspectiveTransformer.h"
#include "StrokeTransformer.h"
// TransformerFor
Transformer*
TransformerFactory::TransformerFor(uint32 type, VertexSource& source)
{
switch (type) {
case 0:
return new AffineTransformer(source);
case 1:
return new PerspectiveTransformer(source);
case 2:
return new ContourTransformer(source);
case 3:
return new StrokeTransformer(source);
}
return NULL;
}
// NextType
bool
TransformerFactory::NextType(int32* cookie, uint32* type, BString* name)
{
*type = *cookie;
*cookie = *cookie + 1;
switch (*type) {
case 0:
*name = "Transformation";
return true;
case 1:
*name = "Perspective";
return true;
case 2:
*name = "Contour";
return true;
case 3:
*name = "Stroke";
return true;
}
return false;
}

View File

@ -0,0 +1,29 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef TRANSFORMER_FACTORY_H
#define TRANSFORMER_FACTORY_H
#include <String.h>
class Transformer;
class VertexSource;
class TransformerFactory {
public:
static Transformer* TransformerFor(uint32 type,
VertexSource& source);
static bool NextType(int32* cookie,
uint32* type,
BString* name);
};
#endif // TRANSFORMER_FACTORY_H