From bab183a27305174861a27a136599b863d22318c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Tue, 4 Jul 2006 14:16:03 +0000 Subject: [PATCH] * 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 --- src/apps/icon-o-matic/Jamfile | 2 + src/apps/icon-o-matic/MainWindow.cpp | 57 +++- src/apps/icon-o-matic/MainWindow.h | 4 + src/apps/icon-o-matic/NOTES | 5 +- .../icon-o-matic/generic/gui/ListViews.cpp | 17 +- src/apps/icon-o-matic/generic/gui/ListViews.h | 3 + src/apps/icon-o-matic/gui/PathListView.cpp | 12 - src/apps/icon-o-matic/gui/PathListView.h | 1 - src/apps/icon-o-matic/gui/ShapeListView.cpp | 12 - src/apps/icon-o-matic/gui/ShapeListView.h | 1 - .../icon-o-matic/gui/TransformerListView.cpp | 290 ++++++++++++++++++ .../icon-o-matic/gui/TransformerListView.h | 63 ++++ src/apps/icon-o-matic/shape/Shape.cpp | 149 ++++++++- src/apps/icon-o-matic/shape/Shape.h | 39 ++- .../transformer/AffineTransformer.cpp | 8 + .../transformer/AffineTransformer.h | 2 + .../transformer/ContourTransformer.cpp | 7 + .../transformer/ContourTransformer.h | 2 + .../transformer/PerspectiveTransformer.cpp | 8 + .../transformer/PerspectiveTransformer.h | 2 + .../transformer/StrokeTransformer.cpp | 8 + .../transformer/StrokeTransformer.h | 2 + .../icon-o-matic/transformer/Transformer.cpp | 9 + .../icon-o-matic/transformer/Transformer.h | 10 +- .../transformer/TransformerFactory.cpp | 57 ++++ .../transformer/TransformerFactory.h | 29 ++ 26 files changed, 746 insertions(+), 53 deletions(-) create mode 100644 src/apps/icon-o-matic/gui/TransformerListView.cpp create mode 100644 src/apps/icon-o-matic/gui/TransformerListView.h create mode 100644 src/apps/icon-o-matic/transformer/TransformerFactory.cpp create mode 100644 src/apps/icon-o-matic/transformer/TransformerFactory.h diff --git a/src/apps/icon-o-matic/Jamfile b/src/apps/icon-o-matic/Jamfile index 4e29ea1a1a..fc7860b937 100644 --- a/src/apps/icon-o-matic/Jamfile +++ b/src/apps/icon-o-matic/Jamfile @@ -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 diff --git a/src/apps/icon-o-matic/MainWindow.cpp b/src/apps/icon-o-matic/MainWindow.cpp index a88dae3854..1035f1c322 100644 --- a/src/apps/icon-o-matic/MainWindow.cpp +++ b/src/apps/icon-o-matic/MainWindow.cpp @@ -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("", @@ -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; } diff --git a/src/apps/icon-o-matic/MainWindow.h b/src/apps/icon-o-matic/MainWindow.h index fad4a1c912..6b4090e46f 100644 --- a/src/apps/icon-o-matic/MainWindow.h +++ b/src/apps/icon-o-matic/MainWindow.h @@ -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; }; diff --git a/src/apps/icon-o-matic/NOTES b/src/apps/icon-o-matic/NOTES index 5383a612ff..a5c55ebd5b 100644 --- a/src/apps/icon-o-matic/NOTES +++ b/src/apps/icon-o-matic/NOTES @@ -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 diff --git a/src/apps/icon-o-matic/generic/gui/ListViews.cpp b/src/apps/icon-o-matic/generic/gui/ListViews.cpp index 52324a94fd..a4cf4f00bd 100644 --- a/src/apps/icon-o-matic/generic/gui/ListViews.cpp +++ b/src/apps/icon-o-matic/generic/gui/ListViews.cpp @@ -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(this)); + message->AddPointer("list", + (void*)dynamic_cast(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); +} + diff --git a/src/apps/icon-o-matic/generic/gui/ListViews.h b/src/apps/icon-o-matic/generic/gui/ListViews.h index df1aff3b59..c41b9f7005 100644 --- a/src/apps/icon-o-matic/generic/gui/ListViews.h +++ b/src/apps/icon-o-matic/generic/gui/ListViews.h @@ -184,6 +184,9 @@ class SimpleListView : BRect itemFrame) const; virtual void MakeDragMessage(BMessage* message) const; + protected: + void _MakeEmpty(); + private: BMessage* fSelectionChangeMessage; diff --git a/src/apps/icon-o-matic/gui/PathListView.cpp b/src/apps/icon-o-matic/gui/PathListView.cpp index 1e59347371..0e64660229 100644 --- a/src/apps/icon-o-matic/gui/PathListView.cpp +++ b/src/apps/icon-o-matic/gui/PathListView.cpp @@ -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 diff --git a/src/apps/icon-o-matic/gui/PathListView.h b/src/apps/icon-o-matic/gui/PathListView.h index 3ddbbfe8a7..e21c757ed0 100644 --- a/src/apps/icon-o-matic/gui/PathListView.h +++ b/src/apps/icon-o-matic/gui/PathListView.h @@ -65,7 +65,6 @@ class PathListView : public SimpleListView, bool _RemovePath(VectorPath* path); PathListItem* _ItemForPath(VectorPath* path) const; - void _MakeEmpty(); friend class ShapePathListener; void _UpdateMarks(); diff --git a/src/apps/icon-o-matic/gui/ShapeListView.cpp b/src/apps/icon-o-matic/gui/ShapeListView.cpp index ceec56ffb8..f5cab0e9c1 100644 --- a/src/apps/icon-o-matic/gui/ShapeListView.cpp +++ b/src/apps/icon-o-matic/gui/ShapeListView.cpp @@ -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); -} - diff --git a/src/apps/icon-o-matic/gui/ShapeListView.h b/src/apps/icon-o-matic/gui/ShapeListView.h index 1550075726..cef7e76bed 100644 --- a/src/apps/icon-o-matic/gui/ShapeListView.h +++ b/src/apps/icon-o-matic/gui/ShapeListView.h @@ -57,7 +57,6 @@ class ShapeListView : public SimpleListView, bool _RemoveShape(Shape* shape); ShapeListItem* _ItemForShape(Shape* shape) const; - void _MakeEmpty(); BMessage* fMessage; diff --git a/src/apps/icon-o-matic/gui/TransformerListView.cpp b/src/apps/icon-o-matic/gui/TransformerListView.cpp new file mode 100644 index 0000000000..2a45c6b1a0 --- /dev/null +++ b/src/apps/icon-o-matic/gui/TransformerListView.cpp @@ -0,0 +1,290 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "TransformerListView.h" + +#include +#include + +#include +#include +#include +#include +#include + +#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(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(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((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(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(ItemAt(i)); + i++) { + if (item->transformer == transformer) + return item; + } + return NULL; +} + + diff --git a/src/apps/icon-o-matic/gui/TransformerListView.h b/src/apps/icon-o-matic/gui/TransformerListView.h new file mode 100644 index 0000000000..3139bf8832 --- /dev/null +++ b/src/apps/icon-o-matic/gui/TransformerListView.h @@ -0,0 +1,63 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#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 diff --git a/src/apps/icon-o-matic/shape/Shape.cpp b/src/apps/icon-o-matic/shape/Shape.cpp index 614388eb7f..6d992693f0 100644 --- a/src/apps/icon-o-matic/shape/Shape.cpp +++ b/src/apps/icon-o-matic/shape/Shape.cpp @@ -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(); } - diff --git a/src/apps/icon-o-matic/shape/Shape.h b/src/apps/icon-o-matic/shape/Shape.h index 72b2585b0b..fec382d61e 100644 --- a/src/apps/icon-o-matic/shape/Shape.h +++ b/src/apps/icon-o-matic/shape/Shape.h @@ -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; diff --git a/src/apps/icon-o-matic/transformer/AffineTransformer.cpp b/src/apps/icon-o-matic/transformer/AffineTransformer.cpp index 1dce4a0536..fb132285fb 100644 --- a/src/apps/icon-o-matic/transformer/AffineTransformer.cpp +++ b/src/apps/icon-o-matic/transformer/AffineTransformer.cpp @@ -42,3 +42,11 @@ AffineTransformer::SetSource(VertexSource& source) Affine::attach(source); } +// Name +const char* +AffineTransformer::Name() const +{ + return "Transformation"; +} + + diff --git a/src/apps/icon-o-matic/transformer/AffineTransformer.h b/src/apps/icon-o-matic/transformer/AffineTransformer.h index a6f1dee87b..097cc954c3 100644 --- a/src/apps/icon-o-matic/transformer/AffineTransformer.h +++ b/src/apps/icon-o-matic/transformer/AffineTransformer.h @@ -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 diff --git a/src/apps/icon-o-matic/transformer/ContourTransformer.cpp b/src/apps/icon-o-matic/transformer/ContourTransformer.cpp index b184b641a1..418e7c7e12 100644 --- a/src/apps/icon-o-matic/transformer/ContourTransformer.cpp +++ b/src/apps/icon-o-matic/transformer/ContourTransformer.cpp @@ -42,3 +42,10 @@ ContourTransformer::SetSource(VertexSource& source) Contour::attach(source); } +// Name +const char* +ContourTransformer::Name() const +{ + return "Contour"; +} + diff --git a/src/apps/icon-o-matic/transformer/ContourTransformer.h b/src/apps/icon-o-matic/transformer/ContourTransformer.h index 3f40ac7a4b..ac0f2dfb02 100644 --- a/src/apps/icon-o-matic/transformer/ContourTransformer.h +++ b/src/apps/icon-o-matic/transformer/ContourTransformer.h @@ -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 diff --git a/src/apps/icon-o-matic/transformer/PerspectiveTransformer.cpp b/src/apps/icon-o-matic/transformer/PerspectiveTransformer.cpp index bcd5878059..8eead11630 100644 --- a/src/apps/icon-o-matic/transformer/PerspectiveTransformer.cpp +++ b/src/apps/icon-o-matic/transformer/PerspectiveTransformer.cpp @@ -42,3 +42,11 @@ PerspectiveTransformer::SetSource(VertexSource& source) Perspective::attach(source); } +// Name +const char* +PerspectiveTransformer::Name() const +{ + return "Perspective"; +} + + diff --git a/src/apps/icon-o-matic/transformer/PerspectiveTransformer.h b/src/apps/icon-o-matic/transformer/PerspectiveTransformer.h index 1d19508990..8c4a602cd3 100644 --- a/src/apps/icon-o-matic/transformer/PerspectiveTransformer.h +++ b/src/apps/icon-o-matic/transformer/PerspectiveTransformer.h @@ -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 diff --git a/src/apps/icon-o-matic/transformer/StrokeTransformer.cpp b/src/apps/icon-o-matic/transformer/StrokeTransformer.cpp index a5205545b7..2f98ef2a2d 100644 --- a/src/apps/icon-o-matic/transformer/StrokeTransformer.cpp +++ b/src/apps/icon-o-matic/transformer/StrokeTransformer.cpp @@ -42,3 +42,11 @@ StrokeTransformer::SetSource(VertexSource& source) Stroke::attach(source); } +// Name +const char* +StrokeTransformer::Name() const +{ + return "Stroke"; +} + + diff --git a/src/apps/icon-o-matic/transformer/StrokeTransformer.h b/src/apps/icon-o-matic/transformer/StrokeTransformer.h index 21f5fcf7d6..0f324aa698 100644 --- a/src/apps/icon-o-matic/transformer/StrokeTransformer.h +++ b/src/apps/icon-o-matic/transformer/StrokeTransformer.h @@ -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 diff --git a/src/apps/icon-o-matic/transformer/Transformer.cpp b/src/apps/icon-o-matic/transformer/Transformer.cpp index 8829ef5ec9..cbbfba1c18 100644 --- a/src/apps/icon-o-matic/transformer/Transformer.cpp +++ b/src/apps/icon-o-matic/transformer/Transformer.cpp @@ -51,3 +51,12 @@ Transformer::SetSource(VertexSource& source) { fSource = source; } + +// #pragma mark - + +// SelectedChanged +void +Transformer::SelectedChanged() +{ +} + diff --git a/src/apps/icon-o-matic/transformer/Transformer.h b/src/apps/icon-o-matic/transformer/Transformer.h index b6b905481b..82dbbd88b0 100644 --- a/src/apps/icon-o-matic/transformer/Transformer.h +++ b/src/apps/icon-o-matic/transformer/Transformer.h @@ -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; }; diff --git a/src/apps/icon-o-matic/transformer/TransformerFactory.cpp b/src/apps/icon-o-matic/transformer/TransformerFactory.cpp new file mode 100644 index 0000000000..9b3b202baf --- /dev/null +++ b/src/apps/icon-o-matic/transformer/TransformerFactory.cpp @@ -0,0 +1,57 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#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; +} diff --git a/src/apps/icon-o-matic/transformer/TransformerFactory.h b/src/apps/icon-o-matic/transformer/TransformerFactory.h new file mode 100644 index 0000000000..070681cf4e --- /dev/null +++ b/src/apps/icon-o-matic/transformer/TransformerFactory.h @@ -0,0 +1,29 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef TRANSFORMER_FACTORY_H +#define TRANSFORMER_FACTORY_H + +#include + +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