diff --git a/src/apps/icon-o-matic/IconEditorApp.cpp b/src/apps/icon-o-matic/IconEditorApp.cpp index 548f8049a3..23384825cf 100644 --- a/src/apps/icon-o-matic/IconEditorApp.cpp +++ b/src/apps/icon-o-matic/IconEditorApp.cpp @@ -28,10 +28,12 @@ IconEditorApp::IconEditorApp() // destructor IconEditorApp::~IconEditorApp() { +printf("~IconEditorApp() - deleting document\n"); // NOTE: it is important that the GUI has been deleted // at this point, so that all the listener/observer // stuff is properly detached delete fDocument; +printf("~IconEditorApp() - done\n"); } // #pragma mark - diff --git a/src/apps/icon-o-matic/Jamfile b/src/apps/icon-o-matic/Jamfile index 8513ca5dd8..2636299573 100644 --- a/src/apps/icon-o-matic/Jamfile +++ b/src/apps/icon-o-matic/Jamfile @@ -105,6 +105,7 @@ Application Icon-O-Matic : Selectable.cpp Selection.cpp # generic/support + Referenceable.cpp RWLocker.cpp support.cpp support_ui.cpp @@ -124,18 +125,24 @@ Application Icon-O-Matic : ShapeContainer.cpp VectorPath.cpp # shape/commands + AddPathsCommand.cpp AddPointCommand.cpp + AddShapesCommand.cpp ChangePointCommand.cpp InsertPointCommand.cpp MoveShapesCommand.cpp MoveTransformersCommand.cpp PathCommand.cpp + RemovePathsCommand.cpp RemovePointsCommand.cpp RemoveShapesCommand.cpp RemoveTransformersCommand.cpp + UnassignPathCommand.cpp # style + AddStylesCommand.cpp CurrentColor.cpp Gradient.cpp + SetColorCommand.cpp SetGradientCommand.cpp Style.cpp StyleManager.cpp @@ -144,6 +151,7 @@ Application Icon-O-Matic : Transformable.cpp TransformBox.cpp TransformBoxStates.cpp + TransformObjectsCommand.cpp TransformCommand.cpp TransformShapesBox.cpp # transformer diff --git a/src/apps/icon-o-matic/MainWindow.cpp b/src/apps/icon-o-matic/MainWindow.cpp index 6c19e18cc7..32868f2904 100644 --- a/src/apps/icon-o-matic/MainWindow.cpp +++ b/src/apps/icon-o-matic/MainWindow.cpp @@ -8,6 +8,7 @@ #include "MainWindow.h" +#include #include #include @@ -16,6 +17,9 @@ #include #include +#include "AddPathsCommand.h" +#include "AddShapesCommand.h" +#include "AddStylesCommand.h" #include "Document.h" #include "CanvasView.h" #include "CommandStack.h" @@ -47,6 +51,8 @@ #include "StyleManager.h" #include "VectorPath.h" +using std::nothrow; + enum { MSG_UNDO = 'undo', MSG_REDO = 'redo', @@ -98,44 +104,62 @@ MainWindow::MessageReceived(BMessage* message) fDocument->CommandStack()->Redo(); break; -// TODO: use an AddPathCommand and listen to -// selection in CanvasView to add a manipulator +// TODO: listen to selection in CanvasView to add a manipulator case MSG_NEW_PATH: { - VectorPath* path = new VectorPath(); - fDocument->Icon()->Paths()->AddPath(path); + VectorPath* path = new (nothrow) VectorPath(); + VectorPath* paths[1]; + paths[0] = path; + PathContainer* container = fDocument->Icon()->Paths(); + AddPathsCommand* command = new (nothrow) AddPathsCommand( + container, paths, 1, true, + container->CountPaths()); + fDocument->CommandStack()->Perform(command); break; } case MSG_PATH_SELECTED: { VectorPath* path; - if (message->FindPointer("path", (void**)&path) == B_OK) { - PathManipulator* pathManipulator = new PathManipulator(path); - fState->DeleteManipulators(); + if (message->FindPointer("path", (void**)&path) < B_OK) + path = NULL; + + fState->DeleteManipulators(); + if (path) { + PathManipulator* pathManipulator = new (nothrow) PathManipulator(path); fState->AddManipulator(pathManipulator); } break; } -// TODO: use an AddStyleCommand case MSG_NEW_STYLE: { - Style* style = new Style(); - style->SetColor((rgb_color){ rand() % 255, - rand() % 255, - rand() % 255, - 255 }); - StyleManager::Default()->AddStyle(style); + Style* style = new (nothrow) Style(); + if (style) { + style->SetColor((rgb_color){ rand() % 255, + rand() % 255, + rand() % 255, + 255 }); + Style* styles[1]; + styles[0] = style; + StyleManager* container = StyleManager::Default(); + AddStylesCommand* command = new (nothrow) AddStylesCommand( + container, styles, 1, + container->CountStyles()); + fDocument->CommandStack()->Perform(command); + } break; } case MSG_STYLE_SELECTED: { Style* style; if (message->FindPointer("style", (void**)&style) < B_OK) style = NULL; - fSwatchGroup->SetCurrentStyle(style); fStyleView->SetStyle(style); break; } -// TODO: use an AddShapeCommand case MSG_NEW_SHAPE: { - Shape* shape = new Shape(StyleManager::Default()->StyleAt(0)); - fDocument->Icon()->Shapes()->AddShape(shape); + Shape* shape = new (nothrow) Shape(StyleManager::Default()->StyleAt(0)); + Shape* shapes[1]; + shapes[0] = shape; + AddShapesCommand* command = new (nothrow) AddShapesCommand( + fDocument->Icon()->Shapes(), shapes, 1, + fDocument->Icon()->Shapes()->CountShapes()); + fDocument->CommandStack()->Perform(command); break; } case MSG_SHAPE_SELECTED: { @@ -157,7 +181,7 @@ case MSG_SHAPE_SELECTED: { } if (selectedShapes.CountItems() > 0) { - TransformShapesBox* transformBox = new TransformShapesBox( + TransformShapesBox* transformBox = new (nothrow) TransformShapesBox( fCanvasView, (const Shape**)selectedShapes.Items(), selectedShapes.CountItems()); @@ -251,7 +275,7 @@ MainWindow::_Init() fPathListView->SetPathContainer(fDocument->Icon()->Paths()); fPathListView->SetShapeContainer(fDocument->Icon()->Shapes()); -// fPathListView->SetCommandStack(fDocument->CommandStack()); + fPathListView->SetCommandStack(fDocument->CommandStack()); fPathListView->SetSelection(fDocument->Selection()); fStyleListView->SetStyleManager(StyleManager::Default()); @@ -260,6 +284,7 @@ MainWindow::_Init() fStyleListView->SetSelection(fDocument->Selection()); fStyleView->SetCommandStack(fDocument->CommandStack()); + fStyleView->SetCurrentColor(CurrentColor::Default()); fShapeListView->SetShapeContainer(fDocument->Icon()->Shapes()); fShapeListView->SetCommandStack(fDocument->CommandStack()); @@ -290,11 +315,13 @@ MainWindow::_Init() fDocument->Icon()->Paths()->AddPath(path); Style* style1 = new Style(); + style1->SetName("Style White"); style1->SetColor((rgb_color){ 255, 255, 255, 255 }); StyleManager::Default()->AddStyle(style1); Style* style2 = new Style(); + style2->SetName("Style Gradient"); Gradient gradient(true); gradient.AddColor((rgb_color){ 255, 211, 6, 255 }, 0.0); gradient.AddColor((rgb_color){ 255, 238, 160, 255 }, 0.5); @@ -320,6 +347,7 @@ MainWindow::_Init() fDocument->Icon()->Shapes()->AddShape(shape); Style* style3 = new Style(); + style3->SetName("Style Red"); style3->SetColor((rgb_color){ 255, 0, 169,200 }); StyleManager::Default()->AddStyle(style3); @@ -579,13 +607,13 @@ MainWindow::_CreateMenuBar(BRect frame) editMenu->AddItem(fRedoMI); // Path - fPathMenu->AddItem(new BMenuItem("New", new BMessage(MSG_NEW_PATH))); + fPathMenu->AddItem(new BMenuItem("Add", new BMessage(MSG_NEW_PATH))); // Style - fStyleMenu->AddItem(new BMenuItem("New", new BMessage(MSG_NEW_STYLE))); + fStyleMenu->AddItem(new BMenuItem("Add", new BMessage(MSG_NEW_STYLE))); // Shape - fShapeMenu->AddItem(new BMenuItem("New", new BMessage(MSG_NEW_SHAPE))); + fShapeMenu->AddItem(new BMenuItem("Add", new BMessage(MSG_NEW_SHAPE))); // Transformer diff --git a/src/apps/icon-o-matic/NOTES b/src/apps/icon-o-matic/NOTES index fb531693d1..fbca9d983e 100644 --- a/src/apps/icon-o-matic/NOTES +++ b/src/apps/icon-o-matic/NOTES @@ -13,11 +13,10 @@ * "add points" mode is problematic when having multiple manipulators for different paths showing at the same time... + -> "add points" only available when one path is selected, otherwise + "select points" is used -* solve the problem of individual gradient transformation per shape - -> introduce "StyleInstance", a Shape would not reference a Style - directly but via a StyleInstance... this object can have additional - information like the gradient transformation +* solve the problem of individual gradient transformation per shape [done] * IconRenderer should construct a separate StyleManager and append the styles in the order of shapes, also adding styles multiple @@ -25,17 +24,16 @@ rendering uses the style index for z ordering) [done] * add more functionality to Transformer/VertexSource interface: - - (inverse) Transformation - - Cloning + - Cloning [done] * add more powerful listener interface to Shape (TransformerAdded()/Removed()...) [done] -* implement commands for the newly added editing features +* implement commands for the newly added editing features [done] -* built-in transformation for Gradient and Shape? +* built-in transformation for Gradient and Shape? [done for Shape] -* Transformation manipulator +* Transformation manipulator [done] --------- user interface diff --git a/src/apps/icon-o-matic/document/Document.cpp b/src/apps/icon-o-matic/document/Document.cpp index 5e38fff098..34cd39636d 100644 --- a/src/apps/icon-o-matic/document/Document.cpp +++ b/src/apps/icon-o-matic/document/Document.cpp @@ -25,18 +25,22 @@ Document::Document(const char* name) fCommandStack(new (nothrow) ::CommandStack()), fSelection(new (nothrow) ::Selection()), + fName(name), fRef(NULL) { - SetName(name); } // destructor Document::~Document() { - delete fIcon; delete fCommandStack; +printf("~Document() - fCommandStack deleted\n"); delete fSelection; +printf("~Document() - fSelection deleted\n"); + delete fIcon; +printf("~Document() - fIcon deleted\n"); delete fRef; +printf("~Document() - fRef deleted\n"); } // SetName diff --git a/src/apps/icon-o-matic/document/Icon.cpp b/src/apps/icon-o-matic/document/Icon.cpp index 4b6a42b033..2477469a84 100644 --- a/src/apps/icon-o-matic/document/Icon.cpp +++ b/src/apps/icon-o-matic/document/Icon.cpp @@ -9,6 +9,7 @@ #include "Icon.h" #include +#include #include "PathContainer.h" #include "Shape.h" diff --git a/src/apps/icon-o-matic/generic/gui/stateview/StateView.cpp b/src/apps/icon-o-matic/generic/gui/stateview/StateView.cpp index e339d94b8d..1350014408 100644 --- a/src/apps/icon-o-matic/generic/gui/stateview/StateView.cpp +++ b/src/apps/icon-o-matic/generic/gui/stateview/StateView.cpp @@ -15,6 +15,11 @@ #include "Command.h" #include "CommandStack.h" +// TODO: hack - somehow figure out of catching +// key events for a given control is ok +#include "GradientControl.h" +#include "ListViews.h" +// #include "RWLocker.h" @@ -33,8 +38,12 @@ class EventFilter : public BMessageFilter { filter_result result = B_DISPATCH_MESSAGE; switch (message->what) { case B_KEY_DOWN: { - if (dynamic_cast(*target)) - break; +if (dynamic_cast(*target)) + break; +if (dynamic_cast(*target)) + break; +if (dynamic_cast(*target)) + break; uint32 key; uint32 modifiers; if (message->FindInt32("raw_char", (int32*)&key) >= B_OK @@ -44,8 +53,12 @@ class EventFilter : public BMessageFilter { break; } case B_KEY_UP: { - if (dynamic_cast(*target)) - break; +if (dynamic_cast(*target)) + break; +if (dynamic_cast(*target)) + break; +if (dynamic_cast(*target)) + break; uint32 key; uint32 modifiers; if (message->FindInt32("raw_char", (int32*)&key) >= B_OK diff --git a/src/apps/icon-o-matic/generic/property/CommonPropertyIDs.cpp b/src/apps/icon-o-matic/generic/property/CommonPropertyIDs.cpp index e3587b1629..2a7ffc054e 100644 --- a/src/apps/icon-o-matic/generic/property/CommonPropertyIDs.cpp +++ b/src/apps/icon-o-matic/generic/property/CommonPropertyIDs.cpp @@ -45,6 +45,9 @@ name_for_id(int32 id) case PROPERTY_MITER_LIMIT: name = "Miter Limit"; break; + case PROPERTY_STROKE_SHORTEN: + name = "Shorten"; + break; case PROPERTY_CLOSED: name = "Closed"; diff --git a/src/apps/icon-o-matic/generic/property/CommonPropertyIDs.h b/src/apps/icon-o-matic/generic/property/CommonPropertyIDs.h index 7465d21ef3..51d355d630 100644 --- a/src/apps/icon-o-matic/generic/property/CommonPropertyIDs.h +++ b/src/apps/icon-o-matic/generic/property/CommonPropertyIDs.h @@ -23,6 +23,7 @@ enum { PROPERTY_CAP_MODE = 'cpmd', PROPERTY_JOIN_MODE = 'jnmd', PROPERTY_MITER_LIMIT = 'mtlm', + PROPERTY_STROKE_SHORTEN = 'srtn', PROPERTY_CLOSED = 'clsd', diff --git a/src/apps/icon-o-matic/generic/property/PropertyObject.cpp b/src/apps/icon-o-matic/generic/property/PropertyObject.cpp index 9c2e23914b..98467acb32 100644 --- a/src/apps/icon-o-matic/generic/property/PropertyObject.cpp +++ b/src/apps/icon-o-matic/generic/property/PropertyObject.cpp @@ -166,6 +166,13 @@ PropertyObject::FindProperty(uint32 propertyID) const return NULL; } +//HasProperty +bool +PropertyObject::HasProperty(Property* property) const +{ + return fProperties.HasItem((void*)property); +} + // ContainsSameProperties bool PropertyObject::ContainsSameProperties(const PropertyObject& other) const diff --git a/src/apps/icon-o-matic/generic/property/PropertyObject.h b/src/apps/icon-o-matic/generic/property/PropertyObject.h index 312243ec4e..549148823c 100644 --- a/src/apps/icon-o-matic/generic/property/PropertyObject.h +++ b/src/apps/icon-o-matic/generic/property/PropertyObject.h @@ -31,6 +31,7 @@ class PropertyObject : public Observable { int32 CountProperties() const; Property* FindProperty(uint32 propertyID) const; + bool HasProperty(Property* property) const; bool ContainsSameProperties( const PropertyObject& other) const; diff --git a/src/apps/icon-o-matic/generic/property/view/PropertyListView.cpp b/src/apps/icon-o-matic/generic/property/view/PropertyListView.cpp index 51f7d6fb97..71af685324 100644 --- a/src/apps/icon-o-matic/generic/property/view/PropertyListView.cpp +++ b/src/apps/icon-o-matic/generic/property/view/PropertyListView.cpp @@ -468,8 +468,13 @@ PropertyListView::UpdateObject(uint32 propertyID) if (previous && current) { // call hook function PropertyChanged(previous, current); - // update saved property - previous->SetValue(current); + // update saved property if it is still contained + // in the saved properties (if not, the notification + // mechanism has caused to update the properties + // and "previous" and "current" are toast) + if (fSavedProperties->HasProperty(previous) + && fPropertyObject->HasProperty(current)) + previous->SetValue(current); } } diff --git a/src/apps/icon-o-matic/generic/property/view/specific_properties/BoolValueView.cpp b/src/apps/icon-o-matic/generic/property/view/specific_properties/BoolValueView.cpp index 75b798353a..67961aa37b 100644 --- a/src/apps/icon-o-matic/generic/property/view/specific_properties/BoolValueView.cpp +++ b/src/apps/icon-o-matic/generic/property/view/specific_properties/BoolValueView.cpp @@ -144,7 +144,7 @@ BoolValueView::SetEnabled(bool enabled) } } -// SetToProperty +// AdoptProperty bool BoolValueView::AdoptProperty(Property* property) { @@ -160,3 +160,10 @@ BoolValueView::AdoptProperty(Property* property) return false; } +// GetProperty +Property* +BoolValueView::GetProperty() const +{ + return fProperty; +} + diff --git a/src/apps/icon-o-matic/generic/property/view/specific_properties/BoolValueView.h b/src/apps/icon-o-matic/generic/property/view/specific_properties/BoolValueView.h index 5ef9767190..313375cc1d 100644 --- a/src/apps/icon-o-matic/generic/property/view/specific_properties/BoolValueView.h +++ b/src/apps/icon-o-matic/generic/property/view/specific_properties/BoolValueView.h @@ -30,8 +30,7 @@ class BoolValueView : public PropertyEditorView { virtual void SetEnabled(bool enabled); virtual bool AdoptProperty(Property* property); - virtual Property* GetProperty() const - { return fProperty; } + virtual Property* GetProperty() const; private: void _ToggleValue(); diff --git a/src/apps/icon-o-matic/generic/property/view/specific_properties/ColorValueView.cpp b/src/apps/icon-o-matic/generic/property/view/specific_properties/ColorValueView.cpp index 66fda1d72f..240a5f81c8 100644 --- a/src/apps/icon-o-matic/generic/property/view/specific_properties/ColorValueView.cpp +++ b/src/apps/icon-o-matic/generic/property/view/specific_properties/ColorValueView.cpp @@ -116,8 +116,7 @@ ColorValueView::IsFocused() const return fSwatchView->IsFocus(); } - -// SetToProperty +// AdoptProperty bool ColorValueView::AdoptProperty(Property* property) { @@ -133,3 +132,13 @@ ColorValueView::AdoptProperty(Property* property) } return false; } + +// GetProperty +Property* +ColorValueView::GetProperty() const +{ + return fProperty; +} + + + diff --git a/src/apps/icon-o-matic/generic/property/view/specific_properties/ColorValueView.h b/src/apps/icon-o-matic/generic/property/view/specific_properties/ColorValueView.h index 63d8778243..e7684d1e93 100644 --- a/src/apps/icon-o-matic/generic/property/view/specific_properties/ColorValueView.h +++ b/src/apps/icon-o-matic/generic/property/view/specific_properties/ColorValueView.h @@ -32,8 +32,7 @@ class ColorValueView : public PropertyEditorView { virtual bool IsFocused() const; virtual bool AdoptProperty(Property* property); - virtual Property* GetProperty() const - { return fProperty; } + virtual Property* GetProperty() const; protected: ColorProperty* fProperty; diff --git a/src/apps/icon-o-matic/generic/property/view/specific_properties/FloatValueView.cpp b/src/apps/icon-o-matic/generic/property/view/specific_properties/FloatValueView.cpp index ef2b6b67c0..8d8763f9c3 100644 --- a/src/apps/icon-o-matic/generic/property/view/specific_properties/FloatValueView.cpp +++ b/src/apps/icon-o-matic/generic/property/view/specific_properties/FloatValueView.cpp @@ -65,3 +65,13 @@ FloatValueView::AdoptProperty(Property* property) } return false; } + +// GetProperty +Property* +FloatValueView::GetProperty() const +{ + return fProperty; +} + + + diff --git a/src/apps/icon-o-matic/generic/property/view/specific_properties/FloatValueView.h b/src/apps/icon-o-matic/generic/property/view/specific_properties/FloatValueView.h index 481433436c..a16ee0b2d3 100644 --- a/src/apps/icon-o-matic/generic/property/view/specific_properties/FloatValueView.h +++ b/src/apps/icon-o-matic/generic/property/view/specific_properties/FloatValueView.h @@ -26,8 +26,7 @@ class FloatValueView : public TextInputValueView { virtual void ValueChanged(); virtual bool AdoptProperty(Property* property); - virtual Property* GetProperty() const - { return fProperty; } + virtual Property* GetProperty() const; private: FloatProperty* fProperty; diff --git a/src/apps/icon-o-matic/generic/property/view/specific_properties/IconValueView.cpp b/src/apps/icon-o-matic/generic/property/view/specific_properties/IconValueView.cpp index a07abef665..e67ce8c921 100644 --- a/src/apps/icon-o-matic/generic/property/view/specific_properties/IconValueView.cpp +++ b/src/apps/icon-o-matic/generic/property/view/specific_properties/IconValueView.cpp @@ -88,6 +88,13 @@ IconValueView::AdoptProperty(Property* property) return false; } +// GetProperty +Property* +IconValueView::GetProperty() const +{ + return fProperty; +} + // #pragma mark - // SetIcon diff --git a/src/apps/icon-o-matic/generic/property/view/specific_properties/IconValueView.h b/src/apps/icon-o-matic/generic/property/view/specific_properties/IconValueView.h index b97d898f05..5f4cdb98e6 100644 --- a/src/apps/icon-o-matic/generic/property/view/specific_properties/IconValueView.h +++ b/src/apps/icon-o-matic/generic/property/view/specific_properties/IconValueView.h @@ -26,8 +26,7 @@ class IconValueView : public PropertyEditorView { virtual void SetEnabled(bool enabled); virtual bool AdoptProperty(Property* property); - virtual Property* GetProperty() const - { return fProperty; } + virtual Property* GetProperty() const; // IconValueView status_t SetIcon(const unsigned char* bitsFromQuickRes, diff --git a/src/apps/icon-o-matic/generic/property/view/specific_properties/Int64ValueView.cpp b/src/apps/icon-o-matic/generic/property/view/specific_properties/Int64ValueView.cpp index c6d8e3ee1f..85c411b86b 100644 --- a/src/apps/icon-o-matic/generic/property/view/specific_properties/Int64ValueView.cpp +++ b/src/apps/icon-o-matic/generic/property/view/specific_properties/Int64ValueView.cpp @@ -69,3 +69,10 @@ Int64ValueView::AdoptProperty(Property* property) return false; } +// GetProperty +Property* +Int64ValueView::GetProperty() const +{ + return fProperty; +} + diff --git a/src/apps/icon-o-matic/generic/property/view/specific_properties/Int64ValueView.h b/src/apps/icon-o-matic/generic/property/view/specific_properties/Int64ValueView.h index 44dd3457ac..6eec85e7d7 100644 --- a/src/apps/icon-o-matic/generic/property/view/specific_properties/Int64ValueView.h +++ b/src/apps/icon-o-matic/generic/property/view/specific_properties/Int64ValueView.h @@ -26,8 +26,7 @@ class Int64ValueView : public TextInputValueView { virtual void ValueChanged(); virtual bool AdoptProperty(Property* property); - virtual Property* GetProperty() const - { return fProperty; } + virtual Property* GetProperty() const; private: Int64Property* fProperty; diff --git a/src/apps/icon-o-matic/generic/property/view/specific_properties/IntValueView.cpp b/src/apps/icon-o-matic/generic/property/view/specific_properties/IntValueView.cpp index 6c6de21c33..de49e08b51 100644 --- a/src/apps/icon-o-matic/generic/property/view/specific_properties/IntValueView.cpp +++ b/src/apps/icon-o-matic/generic/property/view/specific_properties/IntValueView.cpp @@ -66,3 +66,10 @@ IntValueView::AdoptProperty(Property* property) return false; } +// GetProperty +Property* +IntValueView::GetProperty() const +{ + return fProperty; +} + diff --git a/src/apps/icon-o-matic/generic/property/view/specific_properties/IntValueView.h b/src/apps/icon-o-matic/generic/property/view/specific_properties/IntValueView.h index 5257d75c1f..f9a4b8e730 100644 --- a/src/apps/icon-o-matic/generic/property/view/specific_properties/IntValueView.h +++ b/src/apps/icon-o-matic/generic/property/view/specific_properties/IntValueView.h @@ -26,8 +26,7 @@ class IntValueView : public TextInputValueView { virtual void ValueChanged(); virtual bool AdoptProperty(Property* property); - virtual Property* GetProperty() const - { return fProperty; } + virtual Property* GetProperty() const; private: IntProperty* fProperty; diff --git a/src/apps/icon-o-matic/generic/property/view/specific_properties/OptionValueView.cpp b/src/apps/icon-o-matic/generic/property/view/specific_properties/OptionValueView.cpp index 0abea905fa..0e6626229a 100644 --- a/src/apps/icon-o-matic/generic/property/view/specific_properties/OptionValueView.cpp +++ b/src/apps/icon-o-matic/generic/property/view/specific_properties/OptionValueView.cpp @@ -230,3 +230,10 @@ OptionValueView::AdoptProperty(Property* property) return false; } +// GetProperty +Property* +OptionValueView::GetProperty() const +{ + return fProperty; +} + diff --git a/src/apps/icon-o-matic/generic/property/view/specific_properties/OptionValueView.h b/src/apps/icon-o-matic/generic/property/view/specific_properties/OptionValueView.h index c9b12c3fea..5cbc068a8e 100644 --- a/src/apps/icon-o-matic/generic/property/view/specific_properties/OptionValueView.h +++ b/src/apps/icon-o-matic/generic/property/view/specific_properties/OptionValueView.h @@ -34,8 +34,7 @@ class OptionValueView : public PropertyEditorView { virtual void ValueChanged(); virtual bool AdoptProperty(Property* property); - virtual Property* GetProperty() const - { return fProperty; } + virtual Property* GetProperty() const; private: OptionProperty* fProperty; diff --git a/src/apps/icon-o-matic/generic/property/view/specific_properties/StringValueView.cpp b/src/apps/icon-o-matic/generic/property/view/specific_properties/StringValueView.cpp index cc3dfba6d0..204716d520 100644 --- a/src/apps/icon-o-matic/generic/property/view/specific_properties/StringValueView.cpp +++ b/src/apps/icon-o-matic/generic/property/view/specific_properties/StringValueView.cpp @@ -65,3 +65,10 @@ StringValueView::AdoptProperty(Property* property) } return false; } + +// GetProperty +Property* +StringValueView::GetProperty() const +{ + return fProperty; +} diff --git a/src/apps/icon-o-matic/generic/property/view/specific_properties/StringValueView.h b/src/apps/icon-o-matic/generic/property/view/specific_properties/StringValueView.h index fb85bf1f41..c36b286760 100644 --- a/src/apps/icon-o-matic/generic/property/view/specific_properties/StringValueView.h +++ b/src/apps/icon-o-matic/generic/property/view/specific_properties/StringValueView.h @@ -27,8 +27,7 @@ class StringValueView : public TextInputValueView { virtual void ValueChanged(); virtual bool AdoptProperty(Property* property); - virtual Property* GetProperty() const - { return fProperty; } + virtual Property* GetProperty() const; private: StringProperty* fProperty; diff --git a/src/apps/icon-o-matic/generic/support/Referenceable.cpp b/src/apps/icon-o-matic/generic/support/Referenceable.cpp new file mode 100644 index 0000000000..3db27219da --- /dev/null +++ b/src/apps/icon-o-matic/generic/support/Referenceable.cpp @@ -0,0 +1,77 @@ +/* + * Copyright 2001-2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * DarkWyrm + * Axel Dörfler, axeld@pinc-software.de + * Stephan Aßmus + */ + +#include "Referenceable.h" + +#define TRACE 1 +#define ICON 1 + +#if TRACE +#include +#include + +#if ICON +#include "IconObject.h" +#endif +#endif + +// constructor +Referenceable::Referenceable() + : fReferenceCount(1) +{ +} + +// destructor +Referenceable::~Referenceable() +{ +} + +// Acquire +void +Referenceable::Acquire() +{ + atomic_add(&fReferenceCount, 1); +} + +// Release +bool +Referenceable::Release() +{ +#if TRACE + int32 old = atomic_add(&fReferenceCount, -1); +//#if ICON +// if (old > 1) { +//IconObject* object = dynamic_cast(this); +//printf("Referenceable::Release() - %s: %ld\n", +// object ? object->Name() : "unkown", fReferenceCount); +// } else +//#endif + if (old == 1) { +#if ICON +IconObject* object = dynamic_cast(this); +printf("Referenceable::Release() - deleting %s\n", + object ? object->Name() : "unkown"); +#else +printf("Referenceable::Release() - deleting\n"); +#endif + delete this; + return true; + } else if (old < 1) + debugger("Referenceable::Release() - already deleted"); +#else + if (atomic_add(&fReferenceCount, -1) == 1) { + delete this; + return true; + } +#endif + + return false; +} + diff --git a/src/apps/icon-o-matic/generic/support/Referenceable.h b/src/apps/icon-o-matic/generic/support/Referenceable.h index 26aa0955c5..00cdf55438 100644 --- a/src/apps/icon-o-matic/generic/support/Referenceable.h +++ b/src/apps/icon-o-matic/generic/support/Referenceable.h @@ -14,36 +14,14 @@ class Referenceable { public: - Referenceable() - : fReferenceCount(1) - {} - virtual ~Referenceable() - {} + Referenceable(); + virtual ~Referenceable(); - inline void Acquire(); - inline bool Release(); + void Acquire(); + bool Release(); private: vint32 fReferenceCount; }; -// Acquire -inline void -Referenceable::Acquire() -{ - atomic_add(&fReferenceCount, 1); -} - -// Release -inline bool -Referenceable::Release() -{ - if (atomic_add(&fReferenceCount, -1) == 1) { - delete this; - return true; - } - - return false; -} - #endif // REFERENCABLE_H diff --git a/src/apps/icon-o-matic/gui/GradientControl.cpp b/src/apps/icon-o-matic/gui/GradientControl.cpp index c286f72348..32ac8d4f05 100644 --- a/src/apps/icon-o-matic/gui/GradientControl.cpp +++ b/src/apps/icon-o-matic/gui/GradientControl.cpp @@ -87,9 +87,10 @@ GradientControl::MakeFocus(bool focus) if (focus != IsFocus()) { _UpdateCurrentColor(); Invalidate(); - // keep the window informed when the focus of this object changes - if (BWindow* window = Window()) - window->PostMessage(MSG_GRADIENT_CONTROL_FOCUS_CHANGED); + if (fTarget) { + if (BLooper* looper = fTarget->Looper()) + looper->PostMessage(MSG_GRADIENT_CONTROL_FOCUS_CHANGED, fTarget); + } } BView::MakeFocus(focus); } @@ -125,9 +126,9 @@ GradientControl::MouseDown(BPoint where) rgb_color color; uint8* bits = temp; bits += 4 * (uint32)((width - 1) * offset); - color.red = bits[2]; + color.red = bits[0]; color.green = bits[1]; - color.blue = bits[0]; + color.blue = bits[2]; color.alpha = bits[3]; fCurrentStepIndex = fGradient->AddColor(color, offset); fDraggingStepIndex = -1; @@ -625,6 +626,7 @@ void GradientControl::_UpdateCurrentColor() const { if (!fMessage || !fTarget || !fTarget->Looper()) + return; // set the CanvasView current color if (color_step* step = fGradient->ColorAt(fCurrentStepIndex)) { BMessage message(*fMessage); diff --git a/src/apps/icon-o-matic/gui/PathListView.cpp b/src/apps/icon-o-matic/gui/PathListView.cpp index fe60c543b6..1f5edb554d 100644 --- a/src/apps/icon-o-matic/gui/PathListView.cpp +++ b/src/apps/icon-o-matic/gui/PathListView.cpp @@ -16,11 +16,15 @@ #include #include -#include "VectorPath.h" +#include "AddPathsCommand.h" +#include "CommandStack.h" #include "Observer.h" +#include "RemovePathsCommand.h" #include "Shape.h" #include "ShapeContainer.h" #include "Selection.h" +#include "UnassignPathCommand.h" +#include "VectorPath.h" static const float kMarkWidth = 14.0; static const float kBorderOffset = 3.0; @@ -258,9 +262,9 @@ PathListView::SelectionChanged() PathListItem* item = dynamic_cast(ItemAt(CurrentSelection(0))); - if (item && fMessage) { + if (fMessage) { BMessage message(*fMessage); - message.AddPointer("path", (void*)item->path); + message.AddPointer("path", item ? (void*)item->path : NULL); Invoke(&message); } @@ -292,23 +296,21 @@ PathListView::MouseDown(BPoint where) + kBorderOffset + kMarkWidth + kTextOffset / 2.0; VectorPath* path = item->path; - if (itemFrame.Contains(where)) { + if (itemFrame.Contains(where) && fCommandStack) { // add or remove the path to the shape -// TODO: code these commands... -// Command* command; -// if (fCurrentShape->Paths()->HasPath(path)) { -// command = new RemovePathFromShapeCommand( -// fCurrentShape, path); -// } else { -// command = new AddPathToShapeCommand( -// fCurrentShape, path); -// } -// fCommandStack->Perform(command); -if (fCurrentShape->Paths()->HasPath(path)) { - fCurrentShape->Paths()->RemovePath(path); -} else { - fCurrentShape->Paths()->AddPath(path); -} + ::Command* command; + if (fCurrentShape->Paths()->HasPath(path)) { + command = new UnassignPathCommand( + fCurrentShape, path); + } else { + VectorPath* paths[1]; + paths[0] = path; + command = new AddPathsCommand( + fCurrentShape->Paths(), + paths, 1, false, + fCurrentShape->Paths()->CountPaths()); + } + fCommandStack->Perform(command); handled = true; } } @@ -353,13 +355,31 @@ PathListView::MoveItems(BList& items, int32 toIndex) void PathListView::CopyItems(BList& items, int32 toIndex) { + // TODO: allow to copy path } // RemoveItemList void -PathListView::RemoveItemList(BList& indices) +PathListView::RemoveItemList(BList& items) { - // TODO: allow removing items + if (!fCommandStack || !fPathContainer) + return; + + int32 count = items.CountItems(); + VectorPath* paths[count]; + for (int32 i = 0; i < count; i++) { + PathListItem* item = dynamic_cast( + (SimpleItem*)items.ItemAtFast(i)); + if (item) + paths[i] = item->path; + else + paths[i] = NULL; + } + + RemovePathsCommand* command + = new (nothrow) RemovePathsCommand(fPathContainer, + paths, count); + fCommandStack->Perform(command); } // CloneItem @@ -469,6 +489,13 @@ PathListView::SetSelection(Selection* selection) fSelection = selection; } +// SetCommandStack +void +PathListView::SetCommandStack(CommandStack* stack) +{ + fCommandStack = stack; +} + // SetCurrentShape void PathListView::SetCurrentShape(Shape* shape) diff --git a/src/apps/icon-o-matic/gui/PathListView.h b/src/apps/icon-o-matic/gui/PathListView.h index e21c757ed0..3aa91ceebc 100644 --- a/src/apps/icon-o-matic/gui/PathListView.h +++ b/src/apps/icon-o-matic/gui/PathListView.h @@ -43,7 +43,7 @@ class PathListView : public SimpleListView, virtual void MoveItems(BList& items, int32 toIndex); virtual void CopyItems(BList& items, int32 toIndex); - virtual void RemoveItemList(BList& indices); + virtual void RemoveItemList(BList& items); virtual BListItem* CloneItem(int32 atIndex) const; @@ -55,6 +55,7 @@ class PathListView : public SimpleListView, void SetPathContainer(PathContainer* container); void SetShapeContainer(ShapeContainer* container); void SetSelection(Selection* selection); + void SetCommandStack(CommandStack* stack); void SetCurrentShape(Shape* shape); Shape* CurrentShape() const diff --git a/src/apps/icon-o-matic/gui/ShapeListView.cpp b/src/apps/icon-o-matic/gui/ShapeListView.cpp index f5cab0e9c1..68359704b4 100644 --- a/src/apps/icon-o-matic/gui/ShapeListView.cpp +++ b/src/apps/icon-o-matic/gui/ShapeListView.cpp @@ -17,6 +17,7 @@ #include #include +#include "AddShapesCommand.h" #include "CommandStack.h" #include "MoveShapesCommand.h" #include "RemoveShapesCommand.h" @@ -117,8 +118,6 @@ ShapeListView::~ShapeListView() void ShapeListView::SelectionChanged() { - // TODO: single selection versus multiple selection - ShapeListItem* item = dynamic_cast(ItemAt(CurrentSelection(0))); if (fMessage) { BMessage message(*fMessage); @@ -130,10 +129,16 @@ ShapeListView::SelectionChanged() if (!fSelection) return; - if (item) - fSelection->Select(item->shape); - else + if (!item) { fSelection->DeselectAll(); + return; + } + + for (int32 i = 0; + (item = dynamic_cast(ItemAt(CurrentSelection(i)))); + i++) { + fSelection->Select(item->shape, i > 0); + } } // MessageReceived @@ -220,19 +225,41 @@ ShapeListView::MoveItems(BList& items, int32 toIndex) void ShapeListView::CopyItems(BList& items, int32 toIndex) { - MoveItems(items, toIndex); - // TODO: allow copying items + if (!fCommandStack || !fShapeContainer) + return; + + int32 count = items.CountItems(); + Shape* shapes[count]; + + for (int32 i = 0; i < count; i++) { + ShapeListItem* item + = dynamic_cast((BListItem*)items.ItemAtFast(i)); + shapes[i] = item ? new (nothrow) Shape(*item->shape) : NULL; + } + + AddShapesCommand* command + = new (nothrow) AddShapesCommand(fShapeContainer, + shapes, count, toIndex); + if (!command) { + for (int32 i = 0; i < count; i++) + delete shapes[i]; + return; + } + + fCommandStack->Perform(command); } // RemoveItemList void -ShapeListView::RemoveItemList(BList& indexList) +ShapeListView::RemoveItemList(BList& items) { if (!fCommandStack || !fShapeContainer) return; - int32 count = indexList.CountItems(); - const int32* indices = (int32*)indexList.Items(); + int32 count = items.CountItems(); + int32 indices[count]; + for (int32 i = 0; i < count; i++) + indices[i] = IndexOf((SimpleItem*)items.ItemAtFast(i)); RemoveShapesCommand* command = new (nothrow) RemoveShapesCommand(fShapeContainer, @@ -264,8 +291,6 @@ ShapeListView::ShapeAdded(Shape* shape, int32 index) if (!LockLooper()) return; - // NOTE: shapes are always added at the end - // of the list, so the sorting is synced... _AddShape(shape, index); UnlockLooper(); diff --git a/src/apps/icon-o-matic/gui/ShapeListView.h b/src/apps/icon-o-matic/gui/ShapeListView.h index cef7e76bed..649eeef7c6 100644 --- a/src/apps/icon-o-matic/gui/ShapeListView.h +++ b/src/apps/icon-o-matic/gui/ShapeListView.h @@ -39,7 +39,7 @@ class ShapeListView : public SimpleListView, virtual void MoveItems(BList& items, int32 toIndex); virtual void CopyItems(BList& items, int32 toIndex); - virtual void RemoveItemList(BList& indices); + virtual void RemoveItemList(BList& items); virtual BListItem* CloneItem(int32 atIndex) const; diff --git a/src/apps/icon-o-matic/gui/StyleListView.cpp b/src/apps/icon-o-matic/gui/StyleListView.cpp index 5d70096086..978aa6cbc7 100644 --- a/src/apps/icon-o-matic/gui/StyleListView.cpp +++ b/src/apps/icon-o-matic/gui/StyleListView.cpp @@ -347,7 +347,7 @@ StyleListView::CopyItems(BList& items, int32 toIndex) // RemoveItemList void -StyleListView::RemoveItemList(BList& indices) +StyleListView::RemoveItemList(BList& items) { // TODO: allow removing items } diff --git a/src/apps/icon-o-matic/gui/StyleListView.h b/src/apps/icon-o-matic/gui/StyleListView.h index 74d705290f..e01add6055 100644 --- a/src/apps/icon-o-matic/gui/StyleListView.h +++ b/src/apps/icon-o-matic/gui/StyleListView.h @@ -43,7 +43,7 @@ class StyleListView : public SimpleListView, virtual void MoveItems(BList& items, int32 toIndex); virtual void CopyItems(BList& items, int32 toIndex); - virtual void RemoveItemList(BList& indices); + virtual void RemoveItemList(BList& items); virtual BListItem* CloneItem(int32 atIndex) const; diff --git a/src/apps/icon-o-matic/gui/StyleView.cpp b/src/apps/icon-o-matic/gui/StyleView.cpp index bd0d270b9c..57d5237d1f 100644 --- a/src/apps/icon-o-matic/gui/StyleView.cpp +++ b/src/apps/icon-o-matic/gui/StyleView.cpp @@ -16,8 +16,10 @@ #include #include "CommandStack.h" +#include "CurrentColor.h" #include "Gradient.h" #include "GradientControl.h" +#include "SetColorCommand.h" #include "SetGradientCommand.h" #include "Style.h" @@ -37,6 +39,7 @@ enum { StyleView::StyleView(BRect frame) : BView(frame, "style view", B_FOLLOW_LEFT | B_FOLLOW_TOP, 0), fCommandStack(NULL), + fCurrentColor(NULL), fStyle(NULL), fGradient(NULL) { @@ -112,6 +115,7 @@ StyleView::StyleView(BRect frame) StyleView::~StyleView() { SetStyle(NULL); + SetCurrentColor(NULL); fGradientControl->Gradient()->RemoveObserver(this); } @@ -140,6 +144,10 @@ StyleView::MessageReceived(BMessage* message) _SetGradientType(type); break; } + case MSG_SET_COLOR: + case MSG_GRADIENT_CONTROL_FOCUS_CHANGED: + _TransferGradientStopColor(); + break; default: BView::MessageReceived(message); @@ -169,6 +177,8 @@ StyleView::ObjectChanged(const Observable* object) } else { *fGradient = *controlGradient; } + // transfer the current gradient color to the current color + _TransferGradientStopColor(); } } else if (object == fGradient) { if (*fGradient != *controlGradient) { @@ -177,7 +187,12 @@ StyleView::ObjectChanged(const Observable* object) } } else if (object == fStyle) { // maybe the gradient was added or removed + // or the color changed _SetGradient(fStyle->Gradient()); + if (fCurrentColor && !fStyle->Gradient()) + fCurrentColor->SetColor(fStyle->Color()); + } else if (object == fCurrentColor) { + _AdoptCurrentColor(fCurrentColor->Color()); } } @@ -190,15 +205,21 @@ StyleView::SetStyle(Style* style) if (fStyle == style) return; - if (fStyle) + if (fStyle) { fStyle->RemoveObserver(this); + fStyle->Release(); + } fStyle = style; Gradient* gradient = NULL; if (fStyle) { + fStyle->Acquire(); fStyle->AddObserver(this); gradient = fStyle->Gradient(); + + if (fCurrentColor && !gradient) + fCurrentColor->SetColor(fStyle->Color()); } _SetGradient(gradient); @@ -211,6 +232,22 @@ StyleView::SetCommandStack(CommandStack* stack) fCommandStack = stack; } +// SetCurrentColor +void +StyleView::SetCurrentColor(CurrentColor* color) +{ + if (fCurrentColor == color) + return; + + if (fCurrentColor) + fCurrentColor->RemoveObserver(this); + + fCurrentColor = color; + + if (fCurrentColor) + fCurrentColor->AddObserver(this); +} + // #pragma mark - // _SetGradient @@ -287,3 +324,37 @@ StyleView::_SetGradientType(int32 type) { fGradientControl->Gradient()->SetType((gradient_type)type); } + +// _AdoptCurrentColor +void +StyleView::_AdoptCurrentColor(rgb_color color) +{ + if (!fStyle) + return; + + if (fGradient) { + // set the focused gradient color stop + if (fGradientControl->IsFocus()) { + fGradientControl->SetCurrentStop(color); + } + } else { + if (fCommandStack) { + fCommandStack->Perform( + new (nothrow) SetColorCommand(fStyle, color)); + } else { + fStyle->SetColor(color); + } + } +} + +// _TransferGradientStopColor +void +StyleView::_TransferGradientStopColor() +{ + if (fCurrentColor && fGradientControl->IsFocus()) { + rgb_color color; + if (fGradientControl->GetCurrentStop(&color)) + fCurrentColor->SetColor(color); + } +} + diff --git a/src/apps/icon-o-matic/gui/StyleView.h b/src/apps/icon-o-matic/gui/StyleView.h index 1d02353c31..6d353cc810 100644 --- a/src/apps/icon-o-matic/gui/StyleView.h +++ b/src/apps/icon-o-matic/gui/StyleView.h @@ -16,6 +16,7 @@ class BMenu; class BMenuField; class CommandStack; +class CurrentColor; class Gradient; class GradientControl; class Style; @@ -38,6 +39,7 @@ class StyleView : public BView, // StyleView void SetStyle(Style* style); void SetCommandStack(CommandStack* stack); + void SetCurrentColor(CurrentColor* color); private: void _SetGradient(Gradient* gradient); @@ -45,9 +47,12 @@ class StyleView : public BView, int32 type) const; void _SetStyleType(int32 type); void _SetGradientType(int32 type); + void _AdoptCurrentColor(rgb_color color); + void _TransferGradientStopColor(); CommandStack* fCommandStack; + CurrentColor* fCurrentColor; Style* fStyle; Gradient* fGradient; diff --git a/src/apps/icon-o-matic/gui/SwatchGroup.cpp b/src/apps/icon-o-matic/gui/SwatchGroup.cpp index 9fa180546f..77d6f9b4ae 100644 --- a/src/apps/icon-o-matic/gui/SwatchGroup.cpp +++ b/src/apps/icon-o-matic/gui/SwatchGroup.cpp @@ -19,7 +19,6 @@ #include "ColorSlider.h" #include "CurrentColor.h" #include "Group.h" -#include "Style.h" #include "SwatchView.h" enum { @@ -35,7 +34,6 @@ SwatchGroup::SwatchGroup(BRect frame) : BView(frame, "style view", B_FOLLOW_NONE, 0), fCurrentColor(NULL), - fCurrentStyle(NULL), fIgnoreNotifications(false), fColorPickerPanel(NULL), @@ -93,12 +91,15 @@ SwatchGroup::SwatchGroup(BRect frame) fBottomSwatchViews->ResizeToPreferred(); fBottomSwatchViews->SetResizingMode(B_FOLLOW_ALL); - fTopSwatchViews->MoveTo(30, 4); - fBottomSwatchViews->MoveTo(30, fTopSwatchViews->Frame().bottom + 1); + float paletteHeight = fBottomSwatchViews->Frame().Height() + + fTopSwatchViews->Frame().Height() + 1; + + fTopSwatchViews->MoveTo(paletteHeight + 2, 4); + fBottomSwatchViews->MoveTo(paletteHeight + 2, + fTopSwatchViews->Frame().bottom + 1); fCurrentColorSV->MoveTo(0, fTopSwatchViews->Frame().top); - fCurrentColorSV->ResizeTo(28, fBottomSwatchViews->Frame().bottom - - fTopSwatchViews->Frame().top); + fCurrentColorSV->ResizeTo(paletteHeight, paletteHeight); fCurrentColorSV->SetResizingMode(B_FOLLOW_LEFT | B_FOLLOW_TOP); float width = fTopSwatchViews->Frame().right @@ -128,7 +129,6 @@ SwatchGroup::SwatchGroup(BRect frame) SwatchGroup::~SwatchGroup() { SetCurrentColor(NULL); - SetCurrentStyle(NULL); } // ObjectChanged @@ -147,10 +147,6 @@ SwatchGroup::ObjectChanged(const Observable* object) _SetColor(h, s, v); } - - if (fCurrentStyle && !fCurrentStyle->Gradient()) { - fCurrentStyle->SetColor(color); - } } } @@ -264,26 +260,6 @@ SwatchGroup::SetCurrentColor(CurrentColor* color) } } -// SetCurrentStyle -void -SwatchGroup::SetCurrentStyle(Style* style) -{ - if (fCurrentStyle == style) - return; - - if (fCurrentStyle) - fCurrentStyle->Release(); - - fCurrentStyle = style; - - if (fCurrentStyle) { - fCurrentStyle->Acquire(); - - if (fCurrentColor && !fCurrentStyle->Gradient()) - fCurrentColor->SetColor(fCurrentStyle->Color()); - } -} - // #pragma mark - // _SetColor diff --git a/src/apps/icon-o-matic/gui/SwatchGroup.h b/src/apps/icon-o-matic/gui/SwatchGroup.h index bdeaf7bf1e..b8a28612dc 100644 --- a/src/apps/icon-o-matic/gui/SwatchGroup.h +++ b/src/apps/icon-o-matic/gui/SwatchGroup.h @@ -20,7 +20,6 @@ class ColorPickerPanel; class ColorSlider; class CurrentColor; class Group; -class Style; class SwatchView; class SwatchGroup : public BView, @@ -38,7 +37,6 @@ class SwatchGroup : public BView, // SwatchGroup void SetCurrentColor(CurrentColor* color); - void SetCurrentStyle(Style* style); private: void _SetColor(rgb_color color); @@ -53,7 +51,6 @@ class SwatchGroup : public BView, Group* fBottomSwatchViews; CurrentColor* fCurrentColor; - Style* fCurrentStyle; bool fIgnoreNotifications; ColorPickerPanel* fColorPickerPanel; diff --git a/src/apps/icon-o-matic/gui/TransformerListView.cpp b/src/apps/icon-o-matic/gui/TransformerListView.cpp index 903f9c8efe..3d1174fd79 100644 --- a/src/apps/icon-o-matic/gui/TransformerListView.cpp +++ b/src/apps/icon-o-matic/gui/TransformerListView.cpp @@ -195,13 +195,15 @@ TransformerListView::CopyItems(BList& items, int32 toIndex) // RemoveItemList void -TransformerListView::RemoveItemList(BList& indexList) +TransformerListView::RemoveItemList(BList& items) { if (!fCommandStack || !fShape) return; - int32 count = indexList.CountItems(); - const int32* indices = (int32*)indexList.Items(); + int32 count = items.CountItems(); + int32 indices[count]; + for (int32 i = 0; i < count; i++) + indices[i] = IndexOf((SimpleItem*)items.ItemAtFast(i)); RemoveTransformersCommand* command = new (nothrow) RemoveTransformersCommand(fShape, diff --git a/src/apps/icon-o-matic/gui/TransformerListView.h b/src/apps/icon-o-matic/gui/TransformerListView.h index 87018a94fc..0117a9f99e 100644 --- a/src/apps/icon-o-matic/gui/TransformerListView.h +++ b/src/apps/icon-o-matic/gui/TransformerListView.h @@ -33,7 +33,7 @@ class TransformerListView : public SimpleListView, virtual void MoveItems(BList& items, int32 toIndex); virtual void CopyItems(BList& items, int32 toIndex); - virtual void RemoveItemList(BList& indices); + virtual void RemoveItemList(BList& items); virtual BListItem* CloneItem(int32 atIndex) const; diff --git a/src/apps/icon-o-matic/shape/PathContainer.cpp b/src/apps/icon-o-matic/shape/PathContainer.cpp index c5ae4934c3..4648f0d6d0 100644 --- a/src/apps/icon-o-matic/shape/PathContainer.cpp +++ b/src/apps/icon-o-matic/shape/PathContainer.cpp @@ -38,6 +38,7 @@ PathContainer::PathContainer(bool ownsPaths) // destructor PathContainer::~PathContainer() { +printf("PathContainer::~PathContainer()\n"); int32 count = fListeners.CountItems(); if (count > 0) { debugger("~PathContainer() - there are still" diff --git a/src/apps/icon-o-matic/shape/Shape.cpp b/src/apps/icon-o-matic/shape/Shape.cpp index ad0fae5306..9138b6c8c5 100644 --- a/src/apps/icon-o-matic/shape/Shape.cpp +++ b/src/apps/icon-o-matic/shape/Shape.cpp @@ -72,7 +72,16 @@ Shape::Shape(const Shape& other) } } } - // TODO: clone vertex transformers + // clone vertex transformers + int32 count = other.CountTransformers(); + for (int32 i = 0; i < count; i++) { + Transformer* original = other.TransformerAtFast(i); + Transformer* cloned = original->Clone(fPathSource); + if (!AddTransformer(cloned)) { + delete cloned; + break; + } + } SetStyle(other.fStyle); } @@ -80,6 +89,7 @@ Shape::Shape(const Shape& other) // destructor Shape::~Shape() { +printf("~Shape()\n"); int32 count = fTransformers.CountItems(); for (int32 i = 0; i < count; i++) { Transformer* t = (Transformer*)fTransformers.ItemAtFast(i); diff --git a/src/apps/icon-o-matic/shape/VectorPath.cpp b/src/apps/icon-o-matic/shape/VectorPath.cpp index f15b2e70a3..e17ee3fc1c 100644 --- a/src/apps/icon-o-matic/shape/VectorPath.cpp +++ b/src/apps/icon-o-matic/shape/VectorPath.cpp @@ -888,6 +888,20 @@ VectorPath::RemoveListener(PathListener* listener) return fListeners.RemoveItem((void*)listener); } +// CountListeners +int32 +VectorPath::CountListeners() const +{ + return fListeners.CountItems(); +} + +// ListenerAtFast +PathListener* +VectorPath::ListenerAtFast(int32 index) const +{ + return (PathListener*)fListeners.ItemAtFast(index); +} + // #pragma mark - // _SetPoint diff --git a/src/apps/icon-o-matic/shape/VectorPath.h b/src/apps/icon-o-matic/shape/VectorPath.h index b0a363f0ad..f19a6eb687 100644 --- a/src/apps/icon-o-matic/shape/VectorPath.h +++ b/src/apps/icon-o-matic/shape/VectorPath.h @@ -142,6 +142,9 @@ class VectorPath : public BArchivable, bool AddListener(PathListener* listener); bool RemoveListener(PathListener* listener); + int32 CountListeners() const; + PathListener* ListenerAtFast(int32 index) const; + private: BRect _Bounds() const; diff --git a/src/apps/icon-o-matic/shape/commands/AddPathsCommand.cpp b/src/apps/icon-o-matic/shape/commands/AddPathsCommand.cpp new file mode 100644 index 0000000000..e2a1439726 --- /dev/null +++ b/src/apps/icon-o-matic/shape/commands/AddPathsCommand.cpp @@ -0,0 +1,108 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "AddPathsCommand.h" + +#include +#include +#include + +#include "PathContainer.h" +#include "VectorPath.h" + +using std::nothrow; + +// constructor +AddPathsCommand::AddPathsCommand(PathContainer* container, + VectorPath** const paths, + int32 count, + bool ownsPaths, + int32 index) + : Command(), + fContainer(container), + fPaths(paths && count > 0 ? new (nothrow) VectorPath*[count] : NULL), + fCount(count), + fOwnsPaths(ownsPaths), + fIndex(index), + fPathsAdded(false) +{ + if (!fContainer || !fPaths) + return; + + memcpy(fPaths, paths, sizeof(VectorPath*) * fCount); +} + +// destructor +AddPathsCommand::~AddPathsCommand() +{ + if (fOwnsPaths && !fPathsAdded && fPaths) { + for (int32 i = 0; i < fCount; i++) + fPaths[i]->Release(); + } + delete[] fPaths; +} + +// InitCheck +status_t +AddPathsCommand::InitCheck() +{ + return fContainer && fPaths ? B_OK : B_NO_INIT; +} + +// Perform +status_t +AddPathsCommand::Perform() +{ + status_t ret = B_OK; + + // add shapes to container + int32 index = fIndex; + for (int32 i = 0; i < fCount; i++) { + if (fPaths[i] && !fContainer->AddPath(fPaths[i]/*, index*/)) { + ret = B_ERROR; + // roll back + for (int32 j = i - 1; j >= 0; j--) + fContainer->RemovePath(fPaths[j]); + break; + } + index++; + } + fPathsAdded = true; + + return ret; +} + +// Undo +status_t +AddPathsCommand::Undo() +{ + // remove shapes from container + for (int32 i = 0; i < fCount; i++) { + fContainer->RemovePath(fPaths[i]); + } + fPathsAdded = false; + + return B_OK; +} + +// GetName +void +AddPathsCommand::GetName(BString& name) +{ + if (fOwnsPaths) { + if (fCount > 1) + name << "Add Paths"; + else + name << "Add Path"; + } else { + if (fCount > 1) + name << "Assign Paths"; + else + name << "Assign Path"; + } +} diff --git a/src/apps/icon-o-matic/shape/commands/AddPathsCommand.h b/src/apps/icon-o-matic/shape/commands/AddPathsCommand.h new file mode 100644 index 0000000000..e7d3956fd1 --- /dev/null +++ b/src/apps/icon-o-matic/shape/commands/AddPathsCommand.h @@ -0,0 +1,43 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef ADD_PATHS_COMMAND_H +#define ADD_PATHS_COMMAND_H + +#include "Command.h" + +class VectorPath; +class PathContainer; + +class AddPathsCommand : public Command { + public: + AddPathsCommand( + PathContainer* container, + VectorPath** const paths, + int32 count, + bool ownsPaths, + int32 index); + virtual ~AddPathsCommand(); + + virtual status_t InitCheck(); + + virtual status_t Perform(); + virtual status_t Undo(); + + virtual void GetName(BString& name); + + private: + PathContainer* fContainer; + VectorPath** fPaths; + int32 fCount; + bool fOwnsPaths; + int32 fIndex; + bool fPathsAdded; +}; + +#endif // ADD_PATHS_COMMAND_H diff --git a/src/apps/icon-o-matic/shape/commands/AddShapesCommand.cpp b/src/apps/icon-o-matic/shape/commands/AddShapesCommand.cpp new file mode 100644 index 0000000000..9484ddbca4 --- /dev/null +++ b/src/apps/icon-o-matic/shape/commands/AddShapesCommand.cpp @@ -0,0 +1,99 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "AddShapesCommand.h" + +#include +#include +#include + +#include "ShapeContainer.h" +#include "Shape.h" + +using std::nothrow; + +// constructor +AddShapesCommand::AddShapesCommand(ShapeContainer* container, + Shape** const shapes, + int32 count, + int32 index) + : Command(), + fContainer(container), + fShapes(shapes && count > 0 ? new (nothrow) Shape*[count] : NULL), + fCount(count), + fIndex(index), + fShapesAdded(false) +{ + if (!fContainer || !fShapes) + return; + + memcpy(fShapes, shapes, sizeof(Shape*) * fCount); +} + +// destructor +AddShapesCommand::~AddShapesCommand() +{ + if (!fShapesAdded && fShapes) { + for (int32 i = 0; i < fCount; i++) + fShapes[i]->Release(); + } + delete[] fShapes; +} + +// InitCheck +status_t +AddShapesCommand::InitCheck() +{ + return fContainer && fShapes ? B_OK : B_NO_INIT; +} + +// Perform +status_t +AddShapesCommand::Perform() +{ + status_t ret = B_OK; + + // add shapes to container + int32 index = fIndex; + for (int32 i = 0; i < fCount; i++) { + if (fShapes[i] && !fContainer->AddShape(fShapes[i], index)) { + ret = B_ERROR; + // roll back + for (int32 j = i - 1; j >= 0; j--) + fContainer->RemoveShape(fShapes[j]); + break; + } + index++; + } + fShapesAdded = true; + + return ret; +} + +// Undo +status_t +AddShapesCommand::Undo() +{ + // remove shapes from container + for (int32 i = 0; i < fCount; i++) { + fContainer->RemoveShape(fShapes[i]); + } + fShapesAdded = false; + + return B_OK; +} + +// GetName +void +AddShapesCommand::GetName(BString& name) +{ + if (fCount > 1) + name << "Add Shapes"; + else + name << "Add Shape"; +} diff --git a/src/apps/icon-o-matic/shape/commands/AddShapesCommand.h b/src/apps/icon-o-matic/shape/commands/AddShapesCommand.h new file mode 100644 index 0000000000..d3fb8d871e --- /dev/null +++ b/src/apps/icon-o-matic/shape/commands/AddShapesCommand.h @@ -0,0 +1,41 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef ADD_SHAPES_COMMAND_H +#define ADD_SHAPES_COMMAND_H + +#include "Command.h" + +class Shape; +class ShapeContainer; + +class AddShapesCommand : public Command { + public: + AddShapesCommand( + ShapeContainer* container, + Shape** const shapes, + int32 count, + int32 index); + virtual ~AddShapesCommand(); + + virtual status_t InitCheck(); + + virtual status_t Perform(); + virtual status_t Undo(); + + virtual void GetName(BString& name); + + private: + ShapeContainer* fContainer; + Shape** fShapes; + int32 fCount; + int32 fIndex; + bool fShapesAdded; +}; + +#endif // ADD_SHAPES_COMMAND_H diff --git a/src/apps/icon-o-matic/shape/commands/RemovePathsCommand.cpp b/src/apps/icon-o-matic/shape/commands/RemovePathsCommand.cpp new file mode 100644 index 0000000000..d2e086b1e1 --- /dev/null +++ b/src/apps/icon-o-matic/shape/commands/RemovePathsCommand.cpp @@ -0,0 +1,128 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "RemovePathsCommand.h" + +#include +#include + +#include "PathContainer.h" +#include "Shape.h" +#include "VectorPath.h" + +using std::nothrow; + +// constructor +RemovePathsCommand::RemovePathsCommand(PathContainer* container, + VectorPath** const paths, + int32 count) + : Command(), + fContainer(container), + fInfos(paths && count > 0 ? new (nothrow) PathInfo[count] : NULL), + fCount(count), + fPathsRemoved(false) +{ + if (!fContainer || !fInfos) + return; + + for (int32 i = 0; i < fCount; i++) { + fInfos[i].path = paths[i]; + fInfos[i].index = 0;//fContainer->IndexOf(paths[i]); + if (paths[i]) { + int32 listenerCount = paths[i]->CountListeners(); + for (int32 j = 0; j < listenerCount; j++) { + Shape* shape = dynamic_cast(paths[i]->ListenerAtFast(j)); + if (shape) + fInfos[i].shapes.AddItem((void*)shape); + } + } + } +} + +// destructor +RemovePathsCommand::~RemovePathsCommand() +{ + if (fPathsRemoved && fInfos) { + for (int32 i = 0; i < fCount; i++) { + if (fInfos[i].path) + fInfos[i].path->Release(); + } + } + delete[] fInfos; +} + +// InitCheck +status_t +RemovePathsCommand::InitCheck() +{ + return fContainer && fInfos ? B_OK : B_NO_INIT; +} + +// Perform +status_t +RemovePathsCommand::Perform() +{ + // remove paths from container and shapes that reference them + for (int32 i = 0; i < fCount; i++) { + if (!fInfos[i].path) + continue; + fContainer->RemovePath(fInfos[i].path); + int32 shapeCount = fInfos[i].shapes.CountItems(); + for (int32 j = 0; j < shapeCount; j++) { + Shape* shape = (Shape*)fInfos[i].shapes.ItemAtFast(j); + shape->Paths()->RemovePath(fInfos[i].path); + } + } + fPathsRemoved = true; + + return B_OK; +} + +// Undo +status_t +RemovePathsCommand::Undo() +{ + status_t ret = B_OK; + + // add paths to container and shapes which previously referenced them + for (int32 i = 0; i < fCount; i++) { + if (!fInfos[i].path) + continue; + if (!fContainer->AddPath(fInfos[i].path/*, fInfos[i].index*/)) { + // roll back + ret = B_ERROR; + for (int32 j = i - 1; j >= 0; j--) { + fContainer->RemovePath(fInfos[j].path); + int32 shapeCount = fInfos[j].shapes.CountItems(); + for (int32 k = 0; k < shapeCount; k++) { + Shape* shape = (Shape*)fInfos[j].shapes.ItemAtFast(k); + shape->Paths()->RemovePath(fInfos[j].path); + } + } + break; + } + int32 shapeCount = fInfos[i].shapes.CountItems(); + for (int32 j = 0; j < shapeCount; j++) { + Shape* shape = (Shape*)fInfos[i].shapes.ItemAtFast(j); + shape->Paths()->AddPath(fInfos[i].path); + } + } + fPathsRemoved = false; + + return ret; +} + +// GetName +void +RemovePathsCommand::GetName(BString& name) +{ + if (fCount > 1) + name << "Remove Paths"; + else + name << "Remove Path"; +} diff --git a/src/apps/icon-o-matic/shape/commands/RemovePathsCommand.h b/src/apps/icon-o-matic/shape/commands/RemovePathsCommand.h new file mode 100644 index 0000000000..ecbd49c79a --- /dev/null +++ b/src/apps/icon-o-matic/shape/commands/RemovePathsCommand.h @@ -0,0 +1,46 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef REMOVE_PATHS_COMMAND_H +#define REMOVE_PATHS_COMMAND_H + +#include + +#include "Command.h" + +class VectorPath; +class PathContainer; + +class RemovePathsCommand : public Command { + public: + RemovePathsCommand( + PathContainer* container, + VectorPath** const paths, + int32 count); + virtual ~RemovePathsCommand(); + + virtual status_t InitCheck(); + + virtual status_t Perform(); + virtual status_t Undo(); + + virtual void GetName(BString& name); + + private: + PathContainer* fContainer; + struct PathInfo { + VectorPath* path; + int32 index; + BList shapes; + }; + PathInfo* fInfos; + int32 fCount; + bool fPathsRemoved; +}; + +#endif // REMOVE_PATHS_COMMAND_H diff --git a/src/apps/icon-o-matic/shape/commands/RemoveShapesCommand.cpp b/src/apps/icon-o-matic/shape/commands/RemoveShapesCommand.cpp index 6f86fc3c4a..fc54a89ef4 100644 --- a/src/apps/icon-o-matic/shape/commands/RemoveShapesCommand.cpp +++ b/src/apps/icon-o-matic/shape/commands/RemoveShapesCommand.cpp @@ -19,7 +19,7 @@ using std::nothrow; // constructor RemoveShapesCommand::RemoveShapesCommand(ShapeContainer* container, - const int32* indices, + int32* const indices, int32 count) : Command(), fContainer(container), @@ -41,7 +41,7 @@ RemoveShapesCommand::~RemoveShapesCommand() { if (fShapesRemoved && fShapes) { for (int32 i = 0; i < fCount; i++) - delete fShapes[i]; + fShapes[i]->Release(); } delete[] fShapes; delete[] fIndices; diff --git a/src/apps/icon-o-matic/shape/commands/RemoveShapesCommand.h b/src/apps/icon-o-matic/shape/commands/RemoveShapesCommand.h index 8ed56dbcc0..1d74fc1f30 100644 --- a/src/apps/icon-o-matic/shape/commands/RemoveShapesCommand.h +++ b/src/apps/icon-o-matic/shape/commands/RemoveShapesCommand.h @@ -18,7 +18,7 @@ class RemoveShapesCommand : public Command { public: RemoveShapesCommand( ShapeContainer* container, - const int32* indices, + int32* const indices, int32 count); virtual ~RemoveShapesCommand(); diff --git a/src/apps/icon-o-matic/shape/commands/UnassignPathCommand.cpp b/src/apps/icon-o-matic/shape/commands/UnassignPathCommand.cpp new file mode 100644 index 0000000000..3a3085db53 --- /dev/null +++ b/src/apps/icon-o-matic/shape/commands/UnassignPathCommand.cpp @@ -0,0 +1,66 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "UnassignPathCommand.h" + +#include "PathContainer.h" +#include "Shape.h" +#include "VectorPath.h" + +// constructor +UnassignPathCommand::UnassignPathCommand(Shape* shape, + VectorPath* path) + : Command(), + fShape(shape), + fPath(path), + fPathRemoved(false) +{ +} + +// destructor +UnassignPathCommand::~UnassignPathCommand() +{ + if (fPathRemoved && fPath) + fPath->Release(); +} + +// InitCheck +status_t +UnassignPathCommand::InitCheck() +{ + return fShape && fPath ? B_OK : B_NO_INIT; +} + +// Perform +status_t +UnassignPathCommand::Perform() +{ + // remove path from shape + fShape->Paths()->RemovePath(fPath); + fPathRemoved = true; + + return B_OK; +} + +// Undo +status_t +UnassignPathCommand::Undo() +{ + // add path to shape + fShape->Paths()->AddPath(fPath); + fPathRemoved = false; + + return B_OK; +} + +// GetName +void +UnassignPathCommand::GetName(BString& name) +{ + name << "Unassign Path"; +} diff --git a/src/apps/icon-o-matic/shape/commands/UnassignPathCommand.h b/src/apps/icon-o-matic/shape/commands/UnassignPathCommand.h new file mode 100644 index 0000000000..52bc37968d --- /dev/null +++ b/src/apps/icon-o-matic/shape/commands/UnassignPathCommand.h @@ -0,0 +1,36 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef UNASSIGN_PATH_COMMAND_H +#define UNASSIGN_PATH_COMMAND_H + +#include "Command.h" + +class Shape; +class VectorPath; + +class UnassignPathCommand : public Command { + public: + UnassignPathCommand(Shape* shape, + VectorPath* path); + virtual ~UnassignPathCommand(); + + virtual status_t InitCheck(); + + virtual status_t Perform(); + virtual status_t Undo(); + + virtual void GetName(BString& name); + + private: + Shape* fShape; + VectorPath* fPath; + bool fPathRemoved; +}; + +#endif // UNASSIGN_PATH_COMMAND_H diff --git a/src/apps/icon-o-matic/style/AddStylesCommand.cpp b/src/apps/icon-o-matic/style/AddStylesCommand.cpp new file mode 100644 index 0000000000..8b384560f6 --- /dev/null +++ b/src/apps/icon-o-matic/style/AddStylesCommand.cpp @@ -0,0 +1,99 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "AddStylesCommand.h" + +#include +#include +#include + +#include "StyleManager.h" +#include "Style.h" + +using std::nothrow; + +// constructor +AddStylesCommand::AddStylesCommand(StyleManager* container, + Style** const styles, + int32 count, + int32 index) + : Command(), + fContainer(container), + fStyles(styles && count > 0 ? new (nothrow) Style*[count] : NULL), + fCount(count), + fIndex(index), + fStylesAdded(false) +{ + if (!fContainer || !fStyles) + return; + + memcpy(fStyles, styles, sizeof(Style*) * fCount); +} + +// destructor +AddStylesCommand::~AddStylesCommand() +{ + if (!fStylesAdded && fStyles) { + for (int32 i = 0; i < fCount; i++) + fStyles[i]->Release(); + } + delete[] fStyles; +} + +// InitCheck +status_t +AddStylesCommand::InitCheck() +{ + return fContainer && fStyles ? B_OK : B_NO_INIT; +} + +// Perform +status_t +AddStylesCommand::Perform() +{ + status_t ret = B_OK; + + // add shapes to container + int32 index = fIndex; + for (int32 i = 0; i < fCount; i++) { + if (fStyles[i] && !fContainer->AddStyle(fStyles[i]/*, index*/)) { + ret = B_ERROR; + // roll back + for (int32 j = i - 1; j >= 0; j--) + fContainer->RemoveStyle(fStyles[j]); + break; + } + index++; + } + fStylesAdded = true; + + return ret; +} + +// Undo +status_t +AddStylesCommand::Undo() +{ + // remove shapes from container + for (int32 i = 0; i < fCount; i++) { + fContainer->RemoveStyle(fStyles[i]); + } + fStylesAdded = false; + + return B_OK; +} + +// GetName +void +AddStylesCommand::GetName(BString& name) +{ + if (fCount > 1) + name << "Add Styles"; + else + name << "Add Style"; +} diff --git a/src/apps/icon-o-matic/style/AddStylesCommand.h b/src/apps/icon-o-matic/style/AddStylesCommand.h new file mode 100644 index 0000000000..3f43e39fc6 --- /dev/null +++ b/src/apps/icon-o-matic/style/AddStylesCommand.h @@ -0,0 +1,41 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef ADD_STYLES_COMMAND_H +#define ADD_STYLES_COMMAND_H + +#include "Command.h" + +class Style; +class StyleManager; + +class AddStylesCommand : public Command { + public: + AddStylesCommand( + StyleManager* container, + Style** const styles, + int32 count, + int32 index); + virtual ~AddStylesCommand(); + + virtual status_t InitCheck(); + + virtual status_t Perform(); + virtual status_t Undo(); + + virtual void GetName(BString& name); + + private: + StyleManager* fContainer; + Style** fStyles; + int32 fCount; + int32 fIndex; + bool fStylesAdded; +}; + +#endif // ADD_STYLES_COMMAND_H diff --git a/src/apps/icon-o-matic/style/Gradient.cpp b/src/apps/icon-o-matic/style/Gradient.cpp index 8539c7b474..fc6ae02138 100644 --- a/src/apps/icon-o-matic/style/Gradient.cpp +++ b/src/apps/icon-o-matic/style/Gradient.cpp @@ -277,10 +277,12 @@ bool Gradient::SetColor(int32 index, const color_step& color) { if (color_step* step = ColorAt(index)) { - step->color = color.color; - step->offset = color.offset; - Notify(); - return true; + if (*step != color) { + step->color = color.color; + step->offset = color.offset; + Notify(); + return true; + } } return false; } @@ -290,9 +292,11 @@ bool Gradient::SetColor(int32 index, const rgb_color& color) { if (color_step* step = ColorAt(index)) { - step->color = color; - Notify(); - return true; + if ((uint32&)step->color != (uint32&)color) { + step->color = color; + Notify(); + return true; + } } return false; } diff --git a/src/apps/icon-o-matic/style/SetColorCommand.cpp b/src/apps/icon-o-matic/style/SetColorCommand.cpp new file mode 100644 index 0000000000..2311e5b0f7 --- /dev/null +++ b/src/apps/icon-o-matic/style/SetColorCommand.cpp @@ -0,0 +1,82 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "SetColorCommand.h" + +#include +#include + +#include "Gradient.h" +#include "Style.h" + +using std::nothrow; + +// constructor +SetColorCommand::SetColorCommand(Style* style, + const rgb_color& color) + : Command(), + fStyle(style), + fColor(color) +{ +} + +// destructor +SetColorCommand::~SetColorCommand() +{ +} + +// InitCheck +status_t +SetColorCommand::InitCheck() +{ + return fStyle ? B_OK : B_NO_INIT; +} + +// Perform +status_t +SetColorCommand::Perform() +{ + // toggle the color + rgb_color previous = fStyle->Color(); + fStyle->SetColor(fColor); + fColor = previous; + + return B_OK; +} + +// Undo +status_t +SetColorCommand::Undo() +{ + return Perform(); +} + +// GetName +void +SetColorCommand::GetName(BString& name) +{ + name << "Change Color"; +} + +// CombineWithNext +bool +SetColorCommand::CombineWithNext(const Command* command) +{ + const SetColorCommand* next + = dynamic_cast(command); + + if (next && next->fTimeStamp - fTimeStamp < 1000000) { + fTimeStamp = next->fTimeStamp; + // NOTE: next was already performed, but + // when undoing, we want to use our + // remembered color + return true; + } + return false; +} + diff --git a/src/apps/icon-o-matic/style/SetColorCommand.h b/src/apps/icon-o-matic/style/SetColorCommand.h new file mode 100644 index 0000000000..4cf4d3e98b --- /dev/null +++ b/src/apps/icon-o-matic/style/SetColorCommand.h @@ -0,0 +1,38 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef SET_COLOR_COMMAND_H +#define SET_COLOR_COMMAND_H + +#include + +#include "Command.h" + +class Style; + +class SetColorCommand : public Command { + public: + SetColorCommand(Style* style, + const rgb_color& color); + virtual ~SetColorCommand(); + + virtual status_t InitCheck(); + + virtual status_t Perform(); + virtual status_t Undo(); + + virtual void GetName(BString& name); + + virtual bool CombineWithNext(const Command* next); + + private: + Style* fStyle; + rgb_color fColor; +}; + +#endif // SET_COLOR_COMMAND_H diff --git a/src/apps/icon-o-matic/transformable/ChannelTransform.cpp b/src/apps/icon-o-matic/transformable/ChannelTransform.cpp index d03480c513..c242bf13e9 100644 --- a/src/apps/icon-o-matic/transformable/ChannelTransform.cpp +++ b/src/apps/icon-o-matic/transformable/ChannelTransform.cpp @@ -40,10 +40,10 @@ ChannelTransform::~ChannelTransform() // SetTransformation void ChannelTransform::SetTransformation(BPoint pivot, - BPoint translation, - double rotation, - double xScale, - double yScale) + BPoint translation, + double rotation, + double xScale, + double yScale) { if (fTranslation != translation || fPivot != pivot || diff --git a/src/apps/icon-o-matic/transformable/TransformBox.cpp b/src/apps/icon-o-matic/transformable/TransformBox.cpp index 4f05edb5f5..8f04e4faf6 100644 --- a/src/apps/icon-o-matic/transformable/TransformBox.cpp +++ b/src/apps/icon-o-matic/transformable/TransformBox.cpp @@ -23,6 +23,11 @@ #define INSET 8.0 +TransformBoxListener::TransformBoxListener() {} +TransformBoxListener::~TransformBoxListener() {} + +// #pragma mark - + // constructor TransformBox::TransformBox(StateView* view, BRect box) : ChannelTransform(), @@ -68,6 +73,8 @@ TransformBox::TransformBox(StateView* view, BRect box) // destructor TransformBox::~TransformBox() { + _NotifyDeleted(); + delete fCurrentCommand; delete fDragLTState; @@ -137,8 +144,8 @@ TransformBox::MouseDown(BPoint where) fCurrentState->SetOrigin(where); delete fCurrentCommand; - fCurrentCommand = MakeAction(fCurrentState->ActionName(), - fCurrentState->ActionNameIndex()); + fCurrentCommand = MakeCommand(fCurrentState->ActionName(), + fCurrentState->ActionNameIndex()); } return true; @@ -173,7 +180,7 @@ TransformBox::MouseOver(BPoint where) { TransformToCanvas(where); - _SetState(_DragStateFor(where, 1.0 /*zoom*/)); + _SetState(_DragStateFor(where, ZoomLevel())); fMousePos = where; if (fCurrentState) { fCurrentState->UpdateViewCursor(fView, fMousePos); @@ -200,7 +207,7 @@ TransformBox::Bounds() BPoint rt = fRightTop; BPoint lb = fLeftBottom; BPoint rb = fRightBottom; - BPoint c = Pivot(); + BPoint c = fPivot; TransformFromCanvas(lt); TransformFromCanvas(rt); @@ -301,9 +308,9 @@ TransformBox::Update(bool deep) Transform(&fPivot); } -// OffsetPivot +// OffsetCenter void -TransformBox::OffsetPivot(BPoint offset) +TransformBox::OffsetCenter(BPoint offset) { if (offset != BPoint(0.0, 0.0)) { fPivotOffset += offset; @@ -311,6 +318,13 @@ TransformBox::OffsetPivot(BPoint offset) } } +// Center +BPoint +TransformBox::Center() const +{ + return fPivot; +} + // SetBox void TransformBox::SetBox(BRect box) @@ -342,7 +356,7 @@ void TransformBox::NudgeBy(BPoint offset) { if (!fNudging && !fCurrentCommand) { - fCurrentCommand = MakeAction("Move", 0/*MOVE*/); + fCurrentCommand = MakeCommand("Move", 0/*MOVE*/); fNudging = true; } if (fNudging) { @@ -370,6 +384,13 @@ TransformBox::TransformToCanvas(BPoint& point) const { } +// ZoomLevel +float +TransformBox::ZoomLevel() const +{ + return 1.0; +} + // ViewSpaceRotation double TransformBox::ViewSpaceRotation() const @@ -378,6 +399,26 @@ TransformBox::ViewSpaceRotation() const return LocalRotation(); } +// #pragma mark - + +// AddListener +bool +TransformBox::AddListener(TransformBoxListener* listener) +{ + if (listener && !fListeners.HasItem((void*)listener)) + return fListeners.AddItem((void*)listener); + return false; +} + +// RemoveListener +bool +TransformBox::RemoveListener(TransformBoxListener* listener) +{ + return fListeners.RemoveItem((void*)listener); +} + +// #pragma mark - + // TODO: why another version? // point_line_dist float @@ -414,7 +455,7 @@ TransformBox::_DragStateFor(BPoint where, float canvasZoom) // priorities: // transformation center point has highest priority ?!? - if (point_point_distance(where, Pivot()) < inset) + if (point_point_distance(where, fPivot) < inset) state = fOffsetCenterState; if (!state) { @@ -581,6 +622,23 @@ TransformBox::_StrokeBWPoint(BView* into, BPoint point, double angle) const into->StrokeLine(p[3], p[0], B_SOLID_LOW); } +// #pragma mark - + +// _NotifyDeleted +void +TransformBox::_NotifyDeleted() const +{ + BList listeners(fListeners); + int32 count = listeners.CountItems(); + for (int32 i = 0; i < count; i++) { + TransformBoxListener* listener + = (TransformBoxListener*)listeners.ItemAtFast(i); + listener->TransformBoxDeleted(this); + } +} + +// #pragma mark - + // _SetState void TransformBox::_SetState(DragState* state) @@ -591,4 +649,3 @@ TransformBox::_SetState(DragState* state) } } - diff --git a/src/apps/icon-o-matic/transformable/TransformBox.h b/src/apps/icon-o-matic/transformable/TransformBox.h index 0bdc85dfe3..f46976e8b7 100644 --- a/src/apps/icon-o-matic/transformable/TransformBox.h +++ b/src/apps/icon-o-matic/transformable/TransformBox.h @@ -9,14 +9,26 @@ #ifndef TRANSFORM_BOX_H #define TRANSFORM_BOX_H +#include + #include "ChannelTransform.h" #include "Manipulator.h" class Command; class StateView; class DragState; +class TransformBox; class TransformCommand; +class TransformBoxListener { + public: + TransformBoxListener(); + virtual ~TransformBoxListener(); + + virtual void TransformBoxDeleted( + const TransformBox* box) = 0; +}; + class TransformBox : public ChannelTransform, public Manipulator { public: @@ -50,7 +62,8 @@ class TransformBox : public ChannelTransform, // TransformBox virtual void Update(bool deep = true); - void OffsetPivot(BPoint offset); + void OffsetCenter(BPoint offset); + BPoint Center() const; void SetBox(BRect box); BRect Box() const { return fOriginalBox; } @@ -64,22 +77,28 @@ class TransformBox : public ChannelTransform, virtual void TransformFromCanvas(BPoint& point) const; virtual void TransformToCanvas(BPoint& point) const; + virtual float ZoomLevel() const; - virtual TransformCommand* MakeAction(const char* actionName, - uint32 nameIndex) const = 0; + virtual TransformCommand* MakeCommand(const char* actionName, + uint32 nameIndex) = 0; bool IsRotating() const { return fCurrentState == fRotateState; } virtual double ViewSpaceRotation() const; + // Listener support + bool AddListener(TransformBoxListener* listener); + bool RemoveListener(TransformBoxListener* listener); + private: DragState* _DragStateFor(BPoint canvasWhere, float canvasZoom); void _StrokeBWLine(BView* into, BPoint from, BPoint to) const; void _StrokeBWPoint(BView* into, - BPoint point, double angle) const; + BPoint point, + double angle) const; BRect fOriginalBox; @@ -100,7 +119,11 @@ class TransformBox : public ChannelTransform, bool fNudging; + BList fListeners; + protected: + void _NotifyDeleted() const; + // "static" state objects void _SetState(DragState* state); diff --git a/src/apps/icon-o-matic/transformable/TransformBoxStates.cpp b/src/apps/icon-o-matic/transformable/TransformBoxStates.cpp index 24e32c74e6..1ce9b718ee 100644 --- a/src/apps/icon-o-matic/transformable/TransformBoxStates.cpp +++ b/src/apps/icon-o-matic/transformable/TransformBoxStates.cpp @@ -509,7 +509,7 @@ RotateBoxState::SetOrigin(BPoint origin) void RotateBoxState::DragTo(BPoint current, uint32 modifiers) { - double angle = calc_angle(fParent->Pivot(), fOrigin, current); + double angle = calc_angle(fParent->Center(), fOrigin, current); if (modifiers & B_SHIFT_KEY) { if (angle < 0.0) @@ -521,14 +521,14 @@ RotateBoxState::DragTo(BPoint current, uint32 modifiers) double newAngle = fOldAngle + angle; - fParent->RotateBy(newAngle - fParent->LocalRotation()); + fParent->RotateBy(fParent->Center(), newAngle - fParent->LocalRotation()); } // UpdateViewCursor void RotateBoxState::UpdateViewCursor(BView* view, BPoint current) const { - BPoint origin(fParent->Pivot()); + BPoint origin(fParent->Center()); fParent->TransformToCanvas(origin); fParent->TransformToCanvas(current); BPoint from = origin + BPoint(sinf(22.5 * 180.0 / PI) * 50.0, @@ -587,7 +587,7 @@ void OffsetCenterState::DragTo(BPoint current, uint32 modifiers) { fParent->InverseTransform(¤t); - fParent->OffsetPivot(current - fOrigin); + fParent->OffsetCenter(current - fOrigin); fOrigin = current; } diff --git a/src/apps/icon-o-matic/transformable/TransformCommand.cpp b/src/apps/icon-o-matic/transformable/TransformCommand.cpp index 0348c76ff9..d2a518bedb 100644 --- a/src/apps/icon-o-matic/transformable/TransformCommand.cpp +++ b/src/apps/icon-o-matic/transformable/TransformCommand.cpp @@ -90,11 +90,11 @@ TransformCommand::Undo() { status_t status = InitCheck(); if (status >= B_OK) { - _SetTransformation(fOldPivot - fNewPivot, - fOldTranslation - fNewTranslation, - fOldRotation - fNewRotation, - fOldXScale - fNewXScale, - fOldYScale - fNewYScale); + _SetTransformation(fOldPivot, + fOldTranslation, + fOldRotation, + fOldXScale, + fOldYScale); } return status; } @@ -105,11 +105,11 @@ TransformCommand::Redo() { status_t status = InitCheck(); if (status >= B_OK) { - _SetTransformation(fNewPivot - fOldPivot, - fNewTranslation - fOldTranslation, - fNewRotation - fOldRotation, - fNewXScale - fOldXScale, - fNewYScale - fOldYScale); + _SetTransformation(fNewPivot, + fNewTranslation, + fNewRotation, + fNewXScale, + fNewYScale); } return status; } diff --git a/src/apps/icon-o-matic/transformable/TransformCommand.h b/src/apps/icon-o-matic/transformable/TransformCommand.h index db1ec84105..6ed18f65e9 100644 --- a/src/apps/icon-o-matic/transformable/TransformCommand.h +++ b/src/apps/icon-o-matic/transformable/TransformCommand.h @@ -39,7 +39,7 @@ class TransformCommand : public Command { virtual void GetName(BString& name); - // TransformCommand + // TransformCommand void SetNewTransformation(BPoint pivot, BPoint translation, double rotation, diff --git a/src/apps/icon-o-matic/transformable/TransformObjectsCommand.cpp b/src/apps/icon-o-matic/transformable/TransformObjectsCommand.cpp new file mode 100644 index 0000000000..7841c045d4 --- /dev/null +++ b/src/apps/icon-o-matic/transformable/TransformObjectsCommand.cpp @@ -0,0 +1,115 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "TransformObjectsCommand.h" + +#include +#include + +#include "ChannelTransform.h" + +// constructor +TransformObjectsCommand::TransformObjectsCommand( + TransformBox* box, + const Transformable** objects, + const double* originals, + int32 count, + + BPoint pivot, + BPoint translation, + double rotation, + double xScale, + double yScale, + + const char* name, + int32 nameIndex) + : TransformCommand(pivot, + translation, + rotation, + xScale, + yScale, + name, + nameIndex), + fTransformBox(box), + fObjects(objects && count > 0 ? + new (nothrow) Transformable*[count] : NULL), + fOriginals(originals && count > 0 ? + new (nothrow) double[ + count * Transformable::matrix_size] : NULL), + fCount(count) +{ + if (!fObjects || !fOriginals) + return; + + memcpy(fObjects, objects, fCount * sizeof(Transformable*)); + memcpy(fOriginals, originals, + fCount * Transformable::matrix_size * sizeof(double)); + + if (fTransformBox) + fTransformBox->AddListener(this); +} + +// destructor +TransformObjectsCommand::~TransformObjectsCommand() +{ + if (fTransformBox) + fTransformBox->RemoveListener(this); + + delete[] fObjects; + delete[] fOriginals; +} + +// InitCheck +status_t +TransformObjectsCommand::InitCheck() +{ + return fObjects && fOriginals ? TransformCommand::InitCheck() + : B_NO_INIT; +} + +// #pragma mark - + +// TransformBoxDeleted +void +TransformObjectsCommand::TransformBoxDeleted( + const TransformBox* box) +{ + if (fTransformBox == box) + fTransformBox = NULL; +} + +// #pragma mark - + +// _SetTransformation +status_t +TransformObjectsCommand::_SetTransformation( + BPoint pivot, BPoint translation, + double rotation, + double xScale, double yScale) const +{ + if (fTransformBox) { + fTransformBox->SetTransformation(pivot, translation, + rotation, xScale, yScale); + return B_OK; + } + + + ChannelTransform transform; + transform.SetTransformation(pivot, translation, + rotation, xScale, yScale); + // restore original transformations + int32 matrixSize = Transformable::matrix_size; + for (int32 i = 0; i < fCount; i++) { + if (fObjects[i]) { + fObjects[i]->LoadFrom(&fOriginals[i * matrixSize]); + fObjects[i]->Multiply(transform); + } + } + return B_OK; +} + diff --git a/src/apps/icon-o-matic/transformable/TransformObjectsCommand.h b/src/apps/icon-o-matic/transformable/TransformObjectsCommand.h new file mode 100644 index 0000000000..cb84f6d3c0 --- /dev/null +++ b/src/apps/icon-o-matic/transformable/TransformObjectsCommand.h @@ -0,0 +1,56 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef TRANSFORM_OBJECTS_COMMAND_H +#define TRANSFORM_OBJECTS_COMMAND_H + +#include "TransformBox.h" +#include "TransformCommand.h" + +class Transformable; + +class TransformObjectsCommand : public TransformCommand, + public TransformBoxListener { + public: + TransformObjectsCommand( + TransformBox* box, + const Transformable** objects, + const double* originals, + int32 count, + + BPoint pivot, + BPoint translation, + double rotation, + double xScale, + double yScale, + + const char* name, + int32 nameIndex); + virtual ~TransformObjectsCommand(); + + // Command interface + virtual status_t InitCheck(); + + // TransformBoxListener interface + virtual void TransformBoxDeleted( + const TransformBox* box); + protected: + // TransformCommand interface + virtual status_t _SetTransformation(BPoint pivotDiff, + BPoint translationDiff, + double rotationDiff, + double xScaleDiff, + double yScaleDiff) const; + + TransformBox* fTransformBox; + Transformable** fObjects; + double* fOriginals; + int32 fCount; +}; + +#endif // TRANSFORM_OBJECTS_COMMAND_H diff --git a/src/apps/icon-o-matic/transformable/TransformShapesBox.cpp b/src/apps/icon-o-matic/transformable/TransformShapesBox.cpp index 2a3bffd628..637c6cf487 100644 --- a/src/apps/icon-o-matic/transformable/TransformShapesBox.cpp +++ b/src/apps/icon-o-matic/transformable/TransformShapesBox.cpp @@ -15,7 +15,7 @@ #include "CanvasView.h" #include "Shape.h" #include "StateView.h" -//#include "TransformShapesCommand.h" +#include "TransformObjectsCommand.h" using std::nothrow; @@ -116,6 +116,10 @@ TransformShapesBox::ObjectChanged(const Observable* object) box = box | fShapes[i]->Bounds(); fShapes[i]->StoreTo(&fOriginals[i * 6]); } + // any TransformObjectsCommand cannot use the TransformBox + // anymore + _NotifyDeleted(); + Reset(); SetBox(box); @@ -154,6 +158,13 @@ TransformShapesBox::TransformToCanvas(BPoint& point) const fParentTransform.Transform(&point); } +// ZoomLevel +float +TransformShapesBox::ZoomLevel() const +{ + return fCanvasView->ZoomLevel(); +} + // ViewSpaceRotation double TransformShapesBox::ViewSpaceRotation() const @@ -163,19 +174,23 @@ TransformShapesBox::ViewSpaceRotation() const return t.rotation() * 180.0 / PI; } -// MakeAction +// MakeCommand TransformCommand* -TransformShapesBox::MakeAction(const char* actionName, uint32 nameIndex) const +TransformShapesBox::MakeCommand(const char* commandName, uint32 nameIndex) { -// return new TransformShapesCommand(fShapes, fCount, -// -// Pivot(), -// Translation(), -// LocalRotation(), -// LocalXScale(), -// LocalYScale(), -// -// actionName, -// nameIndex); - return NULL; + const Transformable* objects[fCount]; + for (int32 i = 0; i < fCount; i++) + objects[i] = fShapes[i]; + + return new TransformObjectsCommand(this, objects, fOriginals, fCount, + + Pivot(), + Translation(), + LocalRotation(), + LocalXScale(), + LocalYScale(), + + commandName, + nameIndex); } + diff --git a/src/apps/icon-o-matic/transformable/TransformShapesBox.h b/src/apps/icon-o-matic/transformable/TransformShapesBox.h index d1775563f9..9eaf5b51b5 100644 --- a/src/apps/icon-o-matic/transformable/TransformShapesBox.h +++ b/src/apps/icon-o-matic/transformable/TransformShapesBox.h @@ -29,10 +29,11 @@ class TransformShapesBox : public TransformBox { virtual void TransformFromCanvas(BPoint& point) const; virtual void TransformToCanvas(BPoint& point) const; + virtual float ZoomLevel() const; virtual double ViewSpaceRotation() const; - virtual TransformCommand* MakeAction(const char* actionName, - uint32 nameIndex) const; + virtual TransformCommand* MakeCommand(const char* actionName, + uint32 nameIndex); // TransformShapesBox Command* Perform(); diff --git a/src/apps/icon-o-matic/transformable/Transformable.cpp b/src/apps/icon-o-matic/transformable/Transformable.cpp index e8e5d55833..fb75a29021 100644 --- a/src/apps/icon-o-matic/transformable/Transformable.cpp +++ b/src/apps/icon-o-matic/transformable/Transformable.cpp @@ -32,14 +32,14 @@ Transformable::~Transformable() // StoreTo void -Transformable::StoreTo(double matrix[6]) const +Transformable::StoreTo(double matrix[matrix_size]) const { store_to(matrix); } // LoadFrom void -Transformable::LoadFrom(double matrix[6]) +Transformable::LoadFrom(double matrix[matrix_size]) { // before calling the potentially heavy TransformationChanged() // hook function, make sure that the transformation @@ -103,7 +103,7 @@ Transformable::Invert() bool Transformable::IsIdentity() const { - double m[6]; + double m[matrix_size]; store_to(m); if (m[0] == 1.0 && m[1] == 0.0 && @@ -119,7 +119,7 @@ Transformable::IsIdentity() const bool Transformable::IsTranslationOnly() const { - double m[6]; + double m[matrix_size]; store_to(m); if (m[0] == 1.0 && m[1] == 0.0 && @@ -133,7 +133,7 @@ Transformable::IsTranslationOnly() const bool Transformable::IsNotDistorted() const { - double m[6]; + double m[matrix_size]; store_to(m); return (m[0] == m[3]); } @@ -142,7 +142,7 @@ Transformable::IsNotDistorted() const bool Transformable::IsValid() const { - double m[6]; + double m[matrix_size]; store_to(m); return ((m[0] * m[3] - m[1] * m[2]) != 0.0); } @@ -151,9 +151,9 @@ Transformable::IsValid() const bool Transformable::operator==(const Transformable& other) const { - double m1[6]; + double m1[matrix_size]; other.store_to(m1); - double m2[6]; + double m2[matrix_size]; store_to(m2); if (m1[0] == m2[0] && m1[1] == m2[1] && diff --git a/src/apps/icon-o-matic/transformable/Transformable.h b/src/apps/icon-o-matic/transformable/Transformable.h index 2924e689f2..7468a9622c 100644 --- a/src/apps/icon-o-matic/transformable/Transformable.h +++ b/src/apps/icon-o-matic/transformable/Transformable.h @@ -17,12 +17,16 @@ class Transformable : public agg::trans_affine { public: + enum { + matrix_size = 6, + }; + Transformable(); Transformable(const Transformable& other); virtual ~Transformable(); - void StoreTo(double matrix[6]) const; - void LoadFrom(double matrix[6]); + void StoreTo(double matrix[matrix_size]) const; + void LoadFrom(double matrix[matrix_size]); // set to or combine with other matrix void SetTransform(const Transformable& other); diff --git a/src/apps/icon-o-matic/transformer/AffineTransformer.cpp b/src/apps/icon-o-matic/transformer/AffineTransformer.cpp index d27df4351f..956804fa66 100644 --- a/src/apps/icon-o-matic/transformer/AffineTransformer.cpp +++ b/src/apps/icon-o-matic/transformer/AffineTransformer.cpp @@ -8,10 +8,14 @@ #include "AffineTransformer.h" +#include + #include "CommonPropertyIDs.h" #include "Property.h" #include "PropertyObject.h" +using std::nothrow; + // constructor AffineTransformer::AffineTransformer(VertexSource& source) : Transformer(source, "Transformation"), @@ -24,6 +28,16 @@ AffineTransformer::~AffineTransformer() { } +// Clone +Transformer* +AffineTransformer::Clone(VertexSource& source) const +{ + AffineTransformer* clone = new (nothrow) AffineTransformer(source); + if (clone) + clone->multiply(*this); + return clone; +} + // rewind void AffineTransformer::rewind(unsigned path_id) diff --git a/src/apps/icon-o-matic/transformer/AffineTransformer.h b/src/apps/icon-o-matic/transformer/AffineTransformer.h index 79d082c4cd..be77a351fa 100644 --- a/src/apps/icon-o-matic/transformer/AffineTransformer.h +++ b/src/apps/icon-o-matic/transformer/AffineTransformer.h @@ -25,7 +25,9 @@ class AffineTransformer : public Transformer, VertexSource& source); virtual ~AffineTransformer(); - virtual void rewind(unsigned path_id); + virtual Transformer* Clone(VertexSource& source) const; + + virtual void rewind(unsigned path_id); virtual unsigned vertex(double* x, double* y); virtual void SetSource(VertexSource& source); diff --git a/src/apps/icon-o-matic/transformer/ContourTransformer.cpp b/src/apps/icon-o-matic/transformer/ContourTransformer.cpp index 3764c0feb3..7bdc5e18de 100644 --- a/src/apps/icon-o-matic/transformer/ContourTransformer.cpp +++ b/src/apps/icon-o-matic/transformer/ContourTransformer.cpp @@ -8,11 +8,15 @@ #include "ContourTransformer.h" +#include + #include "CommonPropertyIDs.h" #include "OptionProperty.h" #include "Property.h" #include "PropertyObject.h" +using std::nothrow; + // constructor ContourTransformer::ContourTransformer(VertexSource& source) : Transformer(source, "Contour"), @@ -26,6 +30,22 @@ ContourTransformer::~ContourTransformer() { } +// Clone +Transformer* +ContourTransformer::Clone(VertexSource& source) const +{ + ContourTransformer* clone = new (nothrow) ContourTransformer(source); + if (clone) { + clone->line_join(line_join()); + clone->inner_join(inner_join()); + clone->width(width()); + clone->miter_limit(miter_limit()); + clone->inner_miter_limit(inner_miter_limit()); + clone->auto_detect_orientation(auto_detect_orientation()); + } + return clone; +} + // rewind void ContourTransformer::rewind(unsigned path_id) diff --git a/src/apps/icon-o-matic/transformer/ContourTransformer.h b/src/apps/icon-o-matic/transformer/ContourTransformer.h index 4b6bfd515c..6d385799c1 100644 --- a/src/apps/icon-o-matic/transformer/ContourTransformer.h +++ b/src/apps/icon-o-matic/transformer/ContourTransformer.h @@ -22,7 +22,9 @@ class ContourTransformer : public Transformer, VertexSource& source); virtual ~ContourTransformer(); - virtual void rewind(unsigned path_id); + virtual Transformer* Clone(VertexSource& source) const; + + virtual void rewind(unsigned path_id); virtual unsigned vertex(double* x, double* y); virtual void SetSource(VertexSource& source); diff --git a/src/apps/icon-o-matic/transformer/PerspectiveTransformer.cpp b/src/apps/icon-o-matic/transformer/PerspectiveTransformer.cpp index 535b10f38b..79a8dd3aca 100644 --- a/src/apps/icon-o-matic/transformer/PerspectiveTransformer.cpp +++ b/src/apps/icon-o-matic/transformer/PerspectiveTransformer.cpp @@ -8,6 +8,10 @@ #include "PerspectiveTransformer.h" +#include + +using std::nothrow; + // constructor PerspectiveTransformer::PerspectiveTransformer(VertexSource& source) : Transformer(source, "Perspective"), @@ -20,6 +24,19 @@ PerspectiveTransformer::~PerspectiveTransformer() { } +// Clone +Transformer* +PerspectiveTransformer::Clone(VertexSource& source) const +{ + PerspectiveTransformer* clone + = new (nothrow) PerspectiveTransformer(source); + if (clone) { +// TODO: upgrade AGG +// clone->multiply(*this); + } + return clone; +} + // rewind void PerspectiveTransformer::rewind(unsigned path_id) diff --git a/src/apps/icon-o-matic/transformer/PerspectiveTransformer.h b/src/apps/icon-o-matic/transformer/PerspectiveTransformer.h index e5a25895c9..6f74cb9566 100644 --- a/src/apps/icon-o-matic/transformer/PerspectiveTransformer.h +++ b/src/apps/icon-o-matic/transformer/PerspectiveTransformer.h @@ -25,8 +25,10 @@ class PerspectiveTransformer : public Transformer, VertexSource& source); virtual ~PerspectiveTransformer(); - virtual void rewind(unsigned path_id); - virtual unsigned vertex(double* x, double* y); + virtual Transformer* Clone(VertexSource& source) const; + + virtual void rewind(unsigned path_id); + virtual unsigned vertex(double* x, double* y); virtual void SetSource(VertexSource& source); diff --git a/src/apps/icon-o-matic/transformer/StrokeTransformer.cpp b/src/apps/icon-o-matic/transformer/StrokeTransformer.cpp index 7adc140516..345db11877 100644 --- a/src/apps/icon-o-matic/transformer/StrokeTransformer.cpp +++ b/src/apps/icon-o-matic/transformer/StrokeTransformer.cpp @@ -8,11 +8,15 @@ #include "StrokeTransformer.h" +#include + #include "CommonPropertyIDs.h" #include "OptionProperty.h" #include "Property.h" #include "PropertyObject.h" +using std::nothrow; + // constructor StrokeTransformer::StrokeTransformer(VertexSource& source) : Transformer(source, "Stroke"), @@ -25,6 +29,23 @@ StrokeTransformer::~StrokeTransformer() { } +// Clone +Transformer* +StrokeTransformer::Clone(VertexSource& source) const +{ + StrokeTransformer* clone = new (nothrow) StrokeTransformer(source); + if (clone) { + clone->line_cap(line_cap()); + clone->line_join(line_join()); + clone->inner_join(inner_join()); + clone->width(width()); + clone->miter_limit(miter_limit()); + clone->inner_miter_limit(inner_miter_limit()); + clone->shorten(shorten()); + } + return clone; +} + // rewind void StrokeTransformer::rewind(unsigned path_id) @@ -98,6 +119,10 @@ StrokeTransformer::MakePropertyObject() const miter_limit())); } + // shorten + object->AddProperty(new FloatProperty(PROPERTY_STROKE_SHORTEN, + shorten())); + return object; } @@ -137,6 +162,13 @@ StrokeTransformer::SetToPropertyObject(const PropertyObject* object) Notify(); } + // shorten + float s = object->Value(PROPERTY_STROKE_SHORTEN, (float)shorten()); + if (s != shorten()) { + shorten(s); + Notify(); + } + return HasPendingNotifications(); } diff --git a/src/apps/icon-o-matic/transformer/StrokeTransformer.h b/src/apps/icon-o-matic/transformer/StrokeTransformer.h index dc949e0919..f46a85526f 100644 --- a/src/apps/icon-o-matic/transformer/StrokeTransformer.h +++ b/src/apps/icon-o-matic/transformer/StrokeTransformer.h @@ -22,8 +22,10 @@ class StrokeTransformer : public Transformer, VertexSource& source); virtual ~StrokeTransformer(); - virtual void rewind(unsigned path_id); - virtual unsigned vertex(double* x, double* y); + virtual Transformer* Clone(VertexSource& source) const; + + virtual void rewind(unsigned path_id); + virtual unsigned vertex(double* x, double* y); virtual void SetSource(VertexSource& source); diff --git a/src/apps/icon-o-matic/transformer/Transformer.h b/src/apps/icon-o-matic/transformer/Transformer.h index 6631e8b562..26c1fbb65a 100644 --- a/src/apps/icon-o-matic/transformer/Transformer.h +++ b/src/apps/icon-o-matic/transformer/Transformer.h @@ -31,7 +31,9 @@ class Transformer : public VertexSource, const char* name); virtual ~Transformer(); - virtual void rewind(unsigned path_id); + virtual Transformer* Clone(VertexSource& source) const = 0; + + virtual void rewind(unsigned path_id); virtual unsigned vertex(double* x, double* y); virtual void SetSource(VertexSource& source);