* added a little bit of tracing to object destruction, since there

seems to be a problem when quitting the app
* added Undo/Redo commands for numerous operations
	- (un)assigning VectorPaths to Shapes
	- adding new VectorPaths
	- removing VectorPaths
	- adding Shapes
	- transforming Shapes
	- adding Styles
	- changing Style color
* there was a mix up in classes inheriting from SimpleListView,
  RemoveItemList() gives a list of item pointers, not indices
* GradientControl sent the focus notification to the window instead
  of the set BHandler target
* StyleView takes care of transfering the current Style color or
  the focused gradient stop color to the CurrentColor object, so
  the current color of the SwatchGroup is synced
* small improvement to layout of SwatchGroup
* SwatchGroup no longer knows anything about a Style
* fixed syncing the global Selection to the listview selection
  at least for ShapeListView
* implemented cloning Shapes
  - added Transformer::Clone(VectorSource& source) to all Transformers
  - ShapeListView uses this when dropping shapes with shift pressed
* updated NOTES
* added Transformable::matrix_size, so that "6" isn't hardcoded
  everywhere (though it still is at most places)
* added listener interface to TransformBox, this is used by
  the new TransformObjectsCommand, as long as the TransformBox still
  exists, the command modifies the TransformBox transformation instead
  of messing with the objects itself
* fixed hotspot size in TransformBox by using the zoom level of
  the CanvasView
* TransformBox rotates/scales correctly around the visible pivot
* fixed TransformCommand toggling to transformation (the diff was bogus)
* Gradient doesn't trigger unnecessary notifications in SetColor()
* CanvasView doesn't eat keyboard events when the GradientControl or
  one of the ListViews has focus (is a hack currently...)
* fixed bug in PropertyListView when it calls the PropertyChanged()
  hook: because of the notification mechanism, the Properties might
  be toast after the hook returns
* moved all GetProperty() implementations from headers into .cpp files



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18122 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2006-07-12 15:46:01 +00:00
parent 994caa6f7a
commit 61b0e9e314
83 changed files with 1750 additions and 242 deletions
+2
View File
@@ -28,10 +28,12 @@ IconEditorApp::IconEditorApp()
// destructor // destructor
IconEditorApp::~IconEditorApp() IconEditorApp::~IconEditorApp()
{ {
printf("~IconEditorApp() - deleting document\n");
// NOTE: it is important that the GUI has been deleted // NOTE: it is important that the GUI has been deleted
// at this point, so that all the listener/observer // at this point, so that all the listener/observer
// stuff is properly detached // stuff is properly detached
delete fDocument; delete fDocument;
printf("~IconEditorApp() - done\n");
} }
// #pragma mark - // #pragma mark -
+8
View File
@@ -105,6 +105,7 @@ Application Icon-O-Matic :
Selectable.cpp Selectable.cpp
Selection.cpp Selection.cpp
# generic/support # generic/support
Referenceable.cpp
RWLocker.cpp RWLocker.cpp
support.cpp support.cpp
support_ui.cpp support_ui.cpp
@@ -124,18 +125,24 @@ Application Icon-O-Matic :
ShapeContainer.cpp ShapeContainer.cpp
VectorPath.cpp VectorPath.cpp
# shape/commands # shape/commands
AddPathsCommand.cpp
AddPointCommand.cpp AddPointCommand.cpp
AddShapesCommand.cpp
ChangePointCommand.cpp ChangePointCommand.cpp
InsertPointCommand.cpp InsertPointCommand.cpp
MoveShapesCommand.cpp MoveShapesCommand.cpp
MoveTransformersCommand.cpp MoveTransformersCommand.cpp
PathCommand.cpp PathCommand.cpp
RemovePathsCommand.cpp
RemovePointsCommand.cpp RemovePointsCommand.cpp
RemoveShapesCommand.cpp RemoveShapesCommand.cpp
RemoveTransformersCommand.cpp RemoveTransformersCommand.cpp
UnassignPathCommand.cpp
# style # style
AddStylesCommand.cpp
CurrentColor.cpp CurrentColor.cpp
Gradient.cpp Gradient.cpp
SetColorCommand.cpp
SetGradientCommand.cpp SetGradientCommand.cpp
Style.cpp Style.cpp
StyleManager.cpp StyleManager.cpp
@@ -144,6 +151,7 @@ Application Icon-O-Matic :
Transformable.cpp Transformable.cpp
TransformBox.cpp TransformBox.cpp
TransformBoxStates.cpp TransformBoxStates.cpp
TransformObjectsCommand.cpp
TransformCommand.cpp TransformCommand.cpp
TransformShapesBox.cpp TransformShapesBox.cpp
# transformer # transformer
+51 -23
View File
@@ -8,6 +8,7 @@
#include "MainWindow.h" #include "MainWindow.h"
#include <new>
#include <stdio.h> #include <stdio.h>
#include <Menu.h> #include <Menu.h>
@@ -16,6 +17,9 @@
#include <Message.h> #include <Message.h>
#include <ScrollView.h> #include <ScrollView.h>
#include "AddPathsCommand.h"
#include "AddShapesCommand.h"
#include "AddStylesCommand.h"
#include "Document.h" #include "Document.h"
#include "CanvasView.h" #include "CanvasView.h"
#include "CommandStack.h" #include "CommandStack.h"
@@ -47,6 +51,8 @@
#include "StyleManager.h" #include "StyleManager.h"
#include "VectorPath.h" #include "VectorPath.h"
using std::nothrow;
enum { enum {
MSG_UNDO = 'undo', MSG_UNDO = 'undo',
MSG_REDO = 'redo', MSG_REDO = 'redo',
@@ -98,44 +104,62 @@ MainWindow::MessageReceived(BMessage* message)
fDocument->CommandStack()->Redo(); fDocument->CommandStack()->Redo();
break; break;
// TODO: use an AddPathCommand and listen to // TODO: listen to selection in CanvasView to add a manipulator
// selection in CanvasView to add a manipulator
case MSG_NEW_PATH: { case MSG_NEW_PATH: {
VectorPath* path = new VectorPath(); VectorPath* path = new (nothrow) VectorPath();
fDocument->Icon()->Paths()->AddPath(path); 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; break;
} }
case MSG_PATH_SELECTED: { case MSG_PATH_SELECTED: {
VectorPath* path; VectorPath* path;
if (message->FindPointer("path", (void**)&path) == B_OK) { if (message->FindPointer("path", (void**)&path) < B_OK)
PathManipulator* pathManipulator = new PathManipulator(path); path = NULL;
fState->DeleteManipulators();
fState->DeleteManipulators();
if (path) {
PathManipulator* pathManipulator = new (nothrow) PathManipulator(path);
fState->AddManipulator(pathManipulator); fState->AddManipulator(pathManipulator);
} }
break; break;
} }
// TODO: use an AddStyleCommand
case MSG_NEW_STYLE: { case MSG_NEW_STYLE: {
Style* style = new Style(); Style* style = new (nothrow) Style();
style->SetColor((rgb_color){ rand() % 255, if (style) {
rand() % 255, style->SetColor((rgb_color){ rand() % 255,
rand() % 255, rand() % 255,
255 }); rand() % 255,
StyleManager::Default()->AddStyle(style); 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; break;
} }
case MSG_STYLE_SELECTED: { case MSG_STYLE_SELECTED: {
Style* style; Style* style;
if (message->FindPointer("style", (void**)&style) < B_OK) if (message->FindPointer("style", (void**)&style) < B_OK)
style = NULL; style = NULL;
fSwatchGroup->SetCurrentStyle(style);
fStyleView->SetStyle(style); fStyleView->SetStyle(style);
break; break;
} }
// TODO: use an AddShapeCommand
case MSG_NEW_SHAPE: { case MSG_NEW_SHAPE: {
Shape* shape = new Shape(StyleManager::Default()->StyleAt(0)); Shape* shape = new (nothrow) Shape(StyleManager::Default()->StyleAt(0));
fDocument->Icon()->Shapes()->AddShape(shape); 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; break;
} }
case MSG_SHAPE_SELECTED: { case MSG_SHAPE_SELECTED: {
@@ -157,7 +181,7 @@ case MSG_SHAPE_SELECTED: {
} }
if (selectedShapes.CountItems() > 0) { if (selectedShapes.CountItems() > 0) {
TransformShapesBox* transformBox = new TransformShapesBox( TransformShapesBox* transformBox = new (nothrow) TransformShapesBox(
fCanvasView, fCanvasView,
(const Shape**)selectedShapes.Items(), (const Shape**)selectedShapes.Items(),
selectedShapes.CountItems()); selectedShapes.CountItems());
@@ -251,7 +275,7 @@ MainWindow::_Init()
fPathListView->SetPathContainer(fDocument->Icon()->Paths()); fPathListView->SetPathContainer(fDocument->Icon()->Paths());
fPathListView->SetShapeContainer(fDocument->Icon()->Shapes()); fPathListView->SetShapeContainer(fDocument->Icon()->Shapes());
// fPathListView->SetCommandStack(fDocument->CommandStack()); fPathListView->SetCommandStack(fDocument->CommandStack());
fPathListView->SetSelection(fDocument->Selection()); fPathListView->SetSelection(fDocument->Selection());
fStyleListView->SetStyleManager(StyleManager::Default()); fStyleListView->SetStyleManager(StyleManager::Default());
@@ -260,6 +284,7 @@ MainWindow::_Init()
fStyleListView->SetSelection(fDocument->Selection()); fStyleListView->SetSelection(fDocument->Selection());
fStyleView->SetCommandStack(fDocument->CommandStack()); fStyleView->SetCommandStack(fDocument->CommandStack());
fStyleView->SetCurrentColor(CurrentColor::Default());
fShapeListView->SetShapeContainer(fDocument->Icon()->Shapes()); fShapeListView->SetShapeContainer(fDocument->Icon()->Shapes());
fShapeListView->SetCommandStack(fDocument->CommandStack()); fShapeListView->SetCommandStack(fDocument->CommandStack());
@@ -290,11 +315,13 @@ MainWindow::_Init()
fDocument->Icon()->Paths()->AddPath(path); fDocument->Icon()->Paths()->AddPath(path);
Style* style1 = new Style(); Style* style1 = new Style();
style1->SetName("Style White");
style1->SetColor((rgb_color){ 255, 255, 255, 255 }); style1->SetColor((rgb_color){ 255, 255, 255, 255 });
StyleManager::Default()->AddStyle(style1); StyleManager::Default()->AddStyle(style1);
Style* style2 = new Style(); Style* style2 = new Style();
style2->SetName("Style Gradient");
Gradient gradient(true); Gradient gradient(true);
gradient.AddColor((rgb_color){ 255, 211, 6, 255 }, 0.0); gradient.AddColor((rgb_color){ 255, 211, 6, 255 }, 0.0);
gradient.AddColor((rgb_color){ 255, 238, 160, 255 }, 0.5); gradient.AddColor((rgb_color){ 255, 238, 160, 255 }, 0.5);
@@ -320,6 +347,7 @@ MainWindow::_Init()
fDocument->Icon()->Shapes()->AddShape(shape); fDocument->Icon()->Shapes()->AddShape(shape);
Style* style3 = new Style(); Style* style3 = new Style();
style3->SetName("Style Red");
style3->SetColor((rgb_color){ 255, 0, 169,200 }); style3->SetColor((rgb_color){ 255, 0, 169,200 });
StyleManager::Default()->AddStyle(style3); StyleManager::Default()->AddStyle(style3);
@@ -579,13 +607,13 @@ MainWindow::_CreateMenuBar(BRect frame)
editMenu->AddItem(fRedoMI); editMenu->AddItem(fRedoMI);
// Path // Path
fPathMenu->AddItem(new BMenuItem("New", new BMessage(MSG_NEW_PATH))); fPathMenu->AddItem(new BMenuItem("Add", new BMessage(MSG_NEW_PATH)));
// Style // Style
fStyleMenu->AddItem(new BMenuItem("New", new BMessage(MSG_NEW_STYLE))); fStyleMenu->AddItem(new BMenuItem("Add", new BMessage(MSG_NEW_STYLE)));
// Shape // Shape
fShapeMenu->AddItem(new BMenuItem("New", new BMessage(MSG_NEW_SHAPE))); fShapeMenu->AddItem(new BMenuItem("Add", new BMessage(MSG_NEW_SHAPE)));
// Transformer // Transformer
+7 -9
View File
@@ -13,11 +13,10 @@
* "add points" mode is problematic when having multiple manipulators for * "add points" mode is problematic when having multiple manipulators for
different paths showing at the same time... 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 * solve the problem of individual gradient transformation per shape [done]
-> introduce "StyleInstance", a Shape would not reference a Style
directly but via a StyleInstance... this object can have additional
information like the gradient transformation
* IconRenderer should construct a separate StyleManager and append * IconRenderer should construct a separate StyleManager and append
the styles in the order of shapes, also adding styles multiple the styles in the order of shapes, also adding styles multiple
@@ -25,17 +24,16 @@
rendering uses the style index for z ordering) [done] rendering uses the style index for z ordering) [done]
* add more functionality to Transformer/VertexSource interface: * add more functionality to Transformer/VertexSource interface:
- (inverse) Transformation - Cloning [done]
- Cloning
* add more powerful listener interface to Shape * add more powerful listener interface to Shape
(TransformerAdded()/Removed()...) [done] (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 --------- user interface
+6 -2
View File
@@ -25,18 +25,22 @@ Document::Document(const char* name)
fCommandStack(new (nothrow) ::CommandStack()), fCommandStack(new (nothrow) ::CommandStack()),
fSelection(new (nothrow) ::Selection()), fSelection(new (nothrow) ::Selection()),
fName(name),
fRef(NULL) fRef(NULL)
{ {
SetName(name);
} }
// destructor // destructor
Document::~Document() Document::~Document()
{ {
delete fIcon;
delete fCommandStack; delete fCommandStack;
printf("~Document() - fCommandStack deleted\n");
delete fSelection; delete fSelection;
printf("~Document() - fSelection deleted\n");
delete fIcon;
printf("~Document() - fIcon deleted\n");
delete fRef; delete fRef;
printf("~Document() - fRef deleted\n");
} }
// SetName // SetName
+1
View File
@@ -9,6 +9,7 @@
#include "Icon.h" #include "Icon.h"
#include <new> #include <new>
#include <stdio.h>
#include "PathContainer.h" #include "PathContainer.h"
#include "Shape.h" #include "Shape.h"
@@ -15,6 +15,11 @@
#include "Command.h" #include "Command.h"
#include "CommandStack.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" #include "RWLocker.h"
@@ -33,8 +38,12 @@ class EventFilter : public BMessageFilter {
filter_result result = B_DISPATCH_MESSAGE; filter_result result = B_DISPATCH_MESSAGE;
switch (message->what) { switch (message->what) {
case B_KEY_DOWN: { case B_KEY_DOWN: {
if (dynamic_cast<BTextView*>(*target)) if (dynamic_cast<BTextView*>(*target))
break; break;
if (dynamic_cast<SimpleListView*>(*target))
break;
if (dynamic_cast<GradientControl*>(*target))
break;
uint32 key; uint32 key;
uint32 modifiers; uint32 modifiers;
if (message->FindInt32("raw_char", (int32*)&key) >= B_OK if (message->FindInt32("raw_char", (int32*)&key) >= B_OK
@@ -44,8 +53,12 @@ class EventFilter : public BMessageFilter {
break; break;
} }
case B_KEY_UP: { case B_KEY_UP: {
if (dynamic_cast<BTextView*>(*target)) if (dynamic_cast<BTextView*>(*target))
break; break;
if (dynamic_cast<SimpleListView*>(*target))
break;
if (dynamic_cast<GradientControl*>(*target))
break;
uint32 key; uint32 key;
uint32 modifiers; uint32 modifiers;
if (message->FindInt32("raw_char", (int32*)&key) >= B_OK if (message->FindInt32("raw_char", (int32*)&key) >= B_OK
@@ -45,6 +45,9 @@ name_for_id(int32 id)
case PROPERTY_MITER_LIMIT: case PROPERTY_MITER_LIMIT:
name = "Miter Limit"; name = "Miter Limit";
break; break;
case PROPERTY_STROKE_SHORTEN:
name = "Shorten";
break;
case PROPERTY_CLOSED: case PROPERTY_CLOSED:
name = "Closed"; name = "Closed";
@@ -23,6 +23,7 @@ enum {
PROPERTY_CAP_MODE = 'cpmd', PROPERTY_CAP_MODE = 'cpmd',
PROPERTY_JOIN_MODE = 'jnmd', PROPERTY_JOIN_MODE = 'jnmd',
PROPERTY_MITER_LIMIT = 'mtlm', PROPERTY_MITER_LIMIT = 'mtlm',
PROPERTY_STROKE_SHORTEN = 'srtn',
PROPERTY_CLOSED = 'clsd', PROPERTY_CLOSED = 'clsd',
@@ -166,6 +166,13 @@ PropertyObject::FindProperty(uint32 propertyID) const
return NULL; return NULL;
} }
//HasProperty
bool
PropertyObject::HasProperty(Property* property) const
{
return fProperties.HasItem((void*)property);
}
// ContainsSameProperties // ContainsSameProperties
bool bool
PropertyObject::ContainsSameProperties(const PropertyObject& other) const PropertyObject::ContainsSameProperties(const PropertyObject& other) const
@@ -31,6 +31,7 @@ class PropertyObject : public Observable {
int32 CountProperties() const; int32 CountProperties() const;
Property* FindProperty(uint32 propertyID) const; Property* FindProperty(uint32 propertyID) const;
bool HasProperty(Property* property) const;
bool ContainsSameProperties( bool ContainsSameProperties(
const PropertyObject& other) const; const PropertyObject& other) const;
@@ -468,8 +468,13 @@ PropertyListView::UpdateObject(uint32 propertyID)
if (previous && current) { if (previous && current) {
// call hook function // call hook function
PropertyChanged(previous, current); PropertyChanged(previous, current);
// update saved property // update saved property if it is still contained
previous->SetValue(current); // 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);
} }
} }
@@ -144,7 +144,7 @@ BoolValueView::SetEnabled(bool enabled)
} }
} }
// SetToProperty // AdoptProperty
bool bool
BoolValueView::AdoptProperty(Property* property) BoolValueView::AdoptProperty(Property* property)
{ {
@@ -160,3 +160,10 @@ BoolValueView::AdoptProperty(Property* property)
return false; return false;
} }
// GetProperty
Property*
BoolValueView::GetProperty() const
{
return fProperty;
}
@@ -30,8 +30,7 @@ class BoolValueView : public PropertyEditorView {
virtual void SetEnabled(bool enabled); virtual void SetEnabled(bool enabled);
virtual bool AdoptProperty(Property* property); virtual bool AdoptProperty(Property* property);
virtual Property* GetProperty() const virtual Property* GetProperty() const;
{ return fProperty; }
private: private:
void _ToggleValue(); void _ToggleValue();
@@ -116,8 +116,7 @@ ColorValueView::IsFocused() const
return fSwatchView->IsFocus(); return fSwatchView->IsFocus();
} }
// AdoptProperty
// SetToProperty
bool bool
ColorValueView::AdoptProperty(Property* property) ColorValueView::AdoptProperty(Property* property)
{ {
@@ -133,3 +132,13 @@ ColorValueView::AdoptProperty(Property* property)
} }
return false; return false;
} }
// GetProperty
Property*
ColorValueView::GetProperty() const
{
return fProperty;
}
@@ -32,8 +32,7 @@ class ColorValueView : public PropertyEditorView {
virtual bool IsFocused() const; virtual bool IsFocused() const;
virtual bool AdoptProperty(Property* property); virtual bool AdoptProperty(Property* property);
virtual Property* GetProperty() const virtual Property* GetProperty() const;
{ return fProperty; }
protected: protected:
ColorProperty* fProperty; ColorProperty* fProperty;
@@ -65,3 +65,13 @@ FloatValueView::AdoptProperty(Property* property)
} }
return false; return false;
} }
// GetProperty
Property*
FloatValueView::GetProperty() const
{
return fProperty;
}
@@ -26,8 +26,7 @@ class FloatValueView : public TextInputValueView {
virtual void ValueChanged(); virtual void ValueChanged();
virtual bool AdoptProperty(Property* property); virtual bool AdoptProperty(Property* property);
virtual Property* GetProperty() const virtual Property* GetProperty() const;
{ return fProperty; }
private: private:
FloatProperty* fProperty; FloatProperty* fProperty;
@@ -88,6 +88,13 @@ IconValueView::AdoptProperty(Property* property)
return false; return false;
} }
// GetProperty
Property*
IconValueView::GetProperty() const
{
return fProperty;
}
// #pragma mark - // #pragma mark -
// SetIcon // SetIcon
@@ -26,8 +26,7 @@ class IconValueView : public PropertyEditorView {
virtual void SetEnabled(bool enabled); virtual void SetEnabled(bool enabled);
virtual bool AdoptProperty(Property* property); virtual bool AdoptProperty(Property* property);
virtual Property* GetProperty() const virtual Property* GetProperty() const;
{ return fProperty; }
// IconValueView // IconValueView
status_t SetIcon(const unsigned char* bitsFromQuickRes, status_t SetIcon(const unsigned char* bitsFromQuickRes,
@@ -69,3 +69,10 @@ Int64ValueView::AdoptProperty(Property* property)
return false; return false;
} }
// GetProperty
Property*
Int64ValueView::GetProperty() const
{
return fProperty;
}
@@ -26,8 +26,7 @@ class Int64ValueView : public TextInputValueView {
virtual void ValueChanged(); virtual void ValueChanged();
virtual bool AdoptProperty(Property* property); virtual bool AdoptProperty(Property* property);
virtual Property* GetProperty() const virtual Property* GetProperty() const;
{ return fProperty; }
private: private:
Int64Property* fProperty; Int64Property* fProperty;
@@ -66,3 +66,10 @@ IntValueView::AdoptProperty(Property* property)
return false; return false;
} }
// GetProperty
Property*
IntValueView::GetProperty() const
{
return fProperty;
}
@@ -26,8 +26,7 @@ class IntValueView : public TextInputValueView {
virtual void ValueChanged(); virtual void ValueChanged();
virtual bool AdoptProperty(Property* property); virtual bool AdoptProperty(Property* property);
virtual Property* GetProperty() const virtual Property* GetProperty() const;
{ return fProperty; }
private: private:
IntProperty* fProperty; IntProperty* fProperty;
@@ -230,3 +230,10 @@ OptionValueView::AdoptProperty(Property* property)
return false; return false;
} }
// GetProperty
Property*
OptionValueView::GetProperty() const
{
return fProperty;
}
@@ -34,8 +34,7 @@ class OptionValueView : public PropertyEditorView {
virtual void ValueChanged(); virtual void ValueChanged();
virtual bool AdoptProperty(Property* property); virtual bool AdoptProperty(Property* property);
virtual Property* GetProperty() const virtual Property* GetProperty() const;
{ return fProperty; }
private: private:
OptionProperty* fProperty; OptionProperty* fProperty;
@@ -65,3 +65,10 @@ StringValueView::AdoptProperty(Property* property)
} }
return false; return false;
} }
// GetProperty
Property*
StringValueView::GetProperty() const
{
return fProperty;
}
@@ -27,8 +27,7 @@ class StringValueView : public TextInputValueView {
virtual void ValueChanged(); virtual void ValueChanged();
virtual bool AdoptProperty(Property* property); virtual bool AdoptProperty(Property* property);
virtual Property* GetProperty() const virtual Property* GetProperty() const;
{ return fProperty; }
private: private:
StringProperty* fProperty; StringProperty* fProperty;
@@ -0,0 +1,77 @@
/*
* Copyright 2001-2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
* Axel Dörfler, axeld@pinc-software.de
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "Referenceable.h"
#define TRACE 1
#define ICON 1
#if TRACE
#include <debugger.h>
#include <stdio.h>
#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<IconObject*>(this);
//printf("Referenceable::Release() - %s: %ld\n",
// object ? object->Name() : "unkown", fReferenceCount);
// } else
//#endif
if (old == 1) {
#if ICON
IconObject* object = dynamic_cast<IconObject*>(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;
}
@@ -14,36 +14,14 @@
class Referenceable { class Referenceable {
public: public:
Referenceable() Referenceable();
: fReferenceCount(1) virtual ~Referenceable();
{}
virtual ~Referenceable()
{}
inline void Acquire(); void Acquire();
inline bool Release(); bool Release();
private: private:
vint32 fReferenceCount; 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 #endif // REFERENCABLE_H
@@ -87,9 +87,10 @@ GradientControl::MakeFocus(bool focus)
if (focus != IsFocus()) { if (focus != IsFocus()) {
_UpdateCurrentColor(); _UpdateCurrentColor();
Invalidate(); Invalidate();
// keep the window informed when the focus of this object changes if (fTarget) {
if (BWindow* window = Window()) if (BLooper* looper = fTarget->Looper())
window->PostMessage(MSG_GRADIENT_CONTROL_FOCUS_CHANGED); looper->PostMessage(MSG_GRADIENT_CONTROL_FOCUS_CHANGED, fTarget);
}
} }
BView::MakeFocus(focus); BView::MakeFocus(focus);
} }
@@ -125,9 +126,9 @@ GradientControl::MouseDown(BPoint where)
rgb_color color; rgb_color color;
uint8* bits = temp; uint8* bits = temp;
bits += 4 * (uint32)((width - 1) * offset); bits += 4 * (uint32)((width - 1) * offset);
color.red = bits[2]; color.red = bits[0];
color.green = bits[1]; color.green = bits[1];
color.blue = bits[0]; color.blue = bits[2];
color.alpha = bits[3]; color.alpha = bits[3];
fCurrentStepIndex = fGradient->AddColor(color, offset); fCurrentStepIndex = fGradient->AddColor(color, offset);
fDraggingStepIndex = -1; fDraggingStepIndex = -1;
@@ -625,6 +626,7 @@ void
GradientControl::_UpdateCurrentColor() const GradientControl::_UpdateCurrentColor() const
{ {
if (!fMessage || !fTarget || !fTarget->Looper()) if (!fMessage || !fTarget || !fTarget->Looper())
return;
// set the CanvasView current color // set the CanvasView current color
if (color_step* step = fGradient->ColorAt(fCurrentStepIndex)) { if (color_step* step = fGradient->ColorAt(fCurrentStepIndex)) {
BMessage message(*fMessage); BMessage message(*fMessage);
+48 -21
View File
@@ -16,11 +16,15 @@
#include <Mime.h> #include <Mime.h>
#include <Window.h> #include <Window.h>
#include "VectorPath.h" #include "AddPathsCommand.h"
#include "CommandStack.h"
#include "Observer.h" #include "Observer.h"
#include "RemovePathsCommand.h"
#include "Shape.h" #include "Shape.h"
#include "ShapeContainer.h" #include "ShapeContainer.h"
#include "Selection.h" #include "Selection.h"
#include "UnassignPathCommand.h"
#include "VectorPath.h"
static const float kMarkWidth = 14.0; static const float kMarkWidth = 14.0;
static const float kBorderOffset = 3.0; static const float kBorderOffset = 3.0;
@@ -258,9 +262,9 @@ PathListView::SelectionChanged()
PathListItem* item PathListItem* item
= dynamic_cast<PathListItem*>(ItemAt(CurrentSelection(0))); = dynamic_cast<PathListItem*>(ItemAt(CurrentSelection(0)));
if (item && fMessage) { if (fMessage) {
BMessage message(*fMessage); BMessage message(*fMessage);
message.AddPointer("path", (void*)item->path); message.AddPointer("path", item ? (void*)item->path : NULL);
Invoke(&message); Invoke(&message);
} }
@@ -292,23 +296,21 @@ PathListView::MouseDown(BPoint where)
+ kBorderOffset + kMarkWidth + kBorderOffset + kMarkWidth
+ kTextOffset / 2.0; + kTextOffset / 2.0;
VectorPath* path = item->path; VectorPath* path = item->path;
if (itemFrame.Contains(where)) { if (itemFrame.Contains(where) && fCommandStack) {
// add or remove the path to the shape // add or remove the path to the shape
// TODO: code these commands... ::Command* command;
// Command* command; if (fCurrentShape->Paths()->HasPath(path)) {
// if (fCurrentShape->Paths()->HasPath(path)) { command = new UnassignPathCommand(
// command = new RemovePathFromShapeCommand( fCurrentShape, path);
// fCurrentShape, path); } else {
// } else { VectorPath* paths[1];
// command = new AddPathToShapeCommand( paths[0] = path;
// fCurrentShape, path); command = new AddPathsCommand(
// } fCurrentShape->Paths(),
// fCommandStack->Perform(command); paths, 1, false,
if (fCurrentShape->Paths()->HasPath(path)) { fCurrentShape->Paths()->CountPaths());
fCurrentShape->Paths()->RemovePath(path); }
} else { fCommandStack->Perform(command);
fCurrentShape->Paths()->AddPath(path);
}
handled = true; handled = true;
} }
} }
@@ -353,13 +355,31 @@ PathListView::MoveItems(BList& items, int32 toIndex)
void void
PathListView::CopyItems(BList& items, int32 toIndex) PathListView::CopyItems(BList& items, int32 toIndex)
{ {
// TODO: allow to copy path
} }
// RemoveItemList // RemoveItemList
void 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<PathListItem*>(
(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 // CloneItem
@@ -469,6 +489,13 @@ PathListView::SetSelection(Selection* selection)
fSelection = selection; fSelection = selection;
} }
// SetCommandStack
void
PathListView::SetCommandStack(CommandStack* stack)
{
fCommandStack = stack;
}
// SetCurrentShape // SetCurrentShape
void void
PathListView::SetCurrentShape(Shape* shape) PathListView::SetCurrentShape(Shape* shape)
+2 -1
View File
@@ -43,7 +43,7 @@ class PathListView : public SimpleListView,
virtual void MoveItems(BList& items, int32 toIndex); virtual void MoveItems(BList& items, int32 toIndex);
virtual void CopyItems(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; virtual BListItem* CloneItem(int32 atIndex) const;
@@ -55,6 +55,7 @@ class PathListView : public SimpleListView,
void SetPathContainer(PathContainer* container); void SetPathContainer(PathContainer* container);
void SetShapeContainer(ShapeContainer* container); void SetShapeContainer(ShapeContainer* container);
void SetSelection(Selection* selection); void SetSelection(Selection* selection);
void SetCommandStack(CommandStack* stack);
void SetCurrentShape(Shape* shape); void SetCurrentShape(Shape* shape);
Shape* CurrentShape() const Shape* CurrentShape() const
+37 -12
View File
@@ -17,6 +17,7 @@
#include <Mime.h> #include <Mime.h>
#include <Window.h> #include <Window.h>
#include "AddShapesCommand.h"
#include "CommandStack.h" #include "CommandStack.h"
#include "MoveShapesCommand.h" #include "MoveShapesCommand.h"
#include "RemoveShapesCommand.h" #include "RemoveShapesCommand.h"
@@ -117,8 +118,6 @@ ShapeListView::~ShapeListView()
void void
ShapeListView::SelectionChanged() ShapeListView::SelectionChanged()
{ {
// TODO: single selection versus multiple selection
ShapeListItem* item = dynamic_cast<ShapeListItem*>(ItemAt(CurrentSelection(0))); ShapeListItem* item = dynamic_cast<ShapeListItem*>(ItemAt(CurrentSelection(0)));
if (fMessage) { if (fMessage) {
BMessage message(*fMessage); BMessage message(*fMessage);
@@ -130,10 +129,16 @@ ShapeListView::SelectionChanged()
if (!fSelection) if (!fSelection)
return; return;
if (item) if (!item) {
fSelection->Select(item->shape);
else
fSelection->DeselectAll(); fSelection->DeselectAll();
return;
}
for (int32 i = 0;
(item = dynamic_cast<ShapeListItem*>(ItemAt(CurrentSelection(i))));
i++) {
fSelection->Select(item->shape, i > 0);
}
} }
// MessageReceived // MessageReceived
@@ -220,19 +225,41 @@ ShapeListView::MoveItems(BList& items, int32 toIndex)
void void
ShapeListView::CopyItems(BList& items, int32 toIndex) ShapeListView::CopyItems(BList& items, int32 toIndex)
{ {
MoveItems(items, toIndex); if (!fCommandStack || !fShapeContainer)
// TODO: allow copying items return;
int32 count = items.CountItems();
Shape* shapes[count];
for (int32 i = 0; i < count; i++) {
ShapeListItem* item
= dynamic_cast<ShapeListItem*>((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 // RemoveItemList
void void
ShapeListView::RemoveItemList(BList& indexList) ShapeListView::RemoveItemList(BList& items)
{ {
if (!fCommandStack || !fShapeContainer) if (!fCommandStack || !fShapeContainer)
return; return;
int32 count = indexList.CountItems(); int32 count = items.CountItems();
const int32* indices = (int32*)indexList.Items(); int32 indices[count];
for (int32 i = 0; i < count; i++)
indices[i] = IndexOf((SimpleItem*)items.ItemAtFast(i));
RemoveShapesCommand* command RemoveShapesCommand* command
= new (nothrow) RemoveShapesCommand(fShapeContainer, = new (nothrow) RemoveShapesCommand(fShapeContainer,
@@ -264,8 +291,6 @@ ShapeListView::ShapeAdded(Shape* shape, int32 index)
if (!LockLooper()) if (!LockLooper())
return; return;
// NOTE: shapes are always added at the end
// of the list, so the sorting is synced...
_AddShape(shape, index); _AddShape(shape, index);
UnlockLooper(); UnlockLooper();
+1 -1
View File
@@ -39,7 +39,7 @@ class ShapeListView : public SimpleListView,
virtual void MoveItems(BList& items, int32 toIndex); virtual void MoveItems(BList& items, int32 toIndex);
virtual void CopyItems(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; virtual BListItem* CloneItem(int32 atIndex) const;
+1 -1
View File
@@ -347,7 +347,7 @@ StyleListView::CopyItems(BList& items, int32 toIndex)
// RemoveItemList // RemoveItemList
void void
StyleListView::RemoveItemList(BList& indices) StyleListView::RemoveItemList(BList& items)
{ {
// TODO: allow removing items // TODO: allow removing items
} }
+1 -1
View File
@@ -43,7 +43,7 @@ class StyleListView : public SimpleListView,
virtual void MoveItems(BList& items, int32 toIndex); virtual void MoveItems(BList& items, int32 toIndex);
virtual void CopyItems(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; virtual BListItem* CloneItem(int32 atIndex) const;
+72 -1
View File
@@ -16,8 +16,10 @@
#include <PopUpMenu.h> #include <PopUpMenu.h>
#include "CommandStack.h" #include "CommandStack.h"
#include "CurrentColor.h"
#include "Gradient.h" #include "Gradient.h"
#include "GradientControl.h" #include "GradientControl.h"
#include "SetColorCommand.h"
#include "SetGradientCommand.h" #include "SetGradientCommand.h"
#include "Style.h" #include "Style.h"
@@ -37,6 +39,7 @@ enum {
StyleView::StyleView(BRect frame) StyleView::StyleView(BRect frame)
: BView(frame, "style view", B_FOLLOW_LEFT | B_FOLLOW_TOP, 0), : BView(frame, "style view", B_FOLLOW_LEFT | B_FOLLOW_TOP, 0),
fCommandStack(NULL), fCommandStack(NULL),
fCurrentColor(NULL),
fStyle(NULL), fStyle(NULL),
fGradient(NULL) fGradient(NULL)
{ {
@@ -112,6 +115,7 @@ StyleView::StyleView(BRect frame)
StyleView::~StyleView() StyleView::~StyleView()
{ {
SetStyle(NULL); SetStyle(NULL);
SetCurrentColor(NULL);
fGradientControl->Gradient()->RemoveObserver(this); fGradientControl->Gradient()->RemoveObserver(this);
} }
@@ -140,6 +144,10 @@ StyleView::MessageReceived(BMessage* message)
_SetGradientType(type); _SetGradientType(type);
break; break;
} }
case MSG_SET_COLOR:
case MSG_GRADIENT_CONTROL_FOCUS_CHANGED:
_TransferGradientStopColor();
break;
default: default:
BView::MessageReceived(message); BView::MessageReceived(message);
@@ -169,6 +177,8 @@ StyleView::ObjectChanged(const Observable* object)
} else { } else {
*fGradient = *controlGradient; *fGradient = *controlGradient;
} }
// transfer the current gradient color to the current color
_TransferGradientStopColor();
} }
} else if (object == fGradient) { } else if (object == fGradient) {
if (*fGradient != *controlGradient) { if (*fGradient != *controlGradient) {
@@ -177,7 +187,12 @@ StyleView::ObjectChanged(const Observable* object)
} }
} else if (object == fStyle) { } else if (object == fStyle) {
// maybe the gradient was added or removed // maybe the gradient was added or removed
// or the color changed
_SetGradient(fStyle->Gradient()); _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) if (fStyle == style)
return; return;
if (fStyle) if (fStyle) {
fStyle->RemoveObserver(this); fStyle->RemoveObserver(this);
fStyle->Release();
}
fStyle = style; fStyle = style;
Gradient* gradient = NULL; Gradient* gradient = NULL;
if (fStyle) { if (fStyle) {
fStyle->Acquire();
fStyle->AddObserver(this); fStyle->AddObserver(this);
gradient = fStyle->Gradient(); gradient = fStyle->Gradient();
if (fCurrentColor && !gradient)
fCurrentColor->SetColor(fStyle->Color());
} }
_SetGradient(gradient); _SetGradient(gradient);
@@ -211,6 +232,22 @@ StyleView::SetCommandStack(CommandStack* stack)
fCommandStack = 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 - // #pragma mark -
// _SetGradient // _SetGradient
@@ -287,3 +324,37 @@ StyleView::_SetGradientType(int32 type)
{ {
fGradientControl->Gradient()->SetType((gradient_type)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);
}
}
+5
View File
@@ -16,6 +16,7 @@
class BMenu; class BMenu;
class BMenuField; class BMenuField;
class CommandStack; class CommandStack;
class CurrentColor;
class Gradient; class Gradient;
class GradientControl; class GradientControl;
class Style; class Style;
@@ -38,6 +39,7 @@ class StyleView : public BView,
// StyleView // StyleView
void SetStyle(Style* style); void SetStyle(Style* style);
void SetCommandStack(CommandStack* stack); void SetCommandStack(CommandStack* stack);
void SetCurrentColor(CurrentColor* color);
private: private:
void _SetGradient(Gradient* gradient); void _SetGradient(Gradient* gradient);
@@ -45,9 +47,12 @@ class StyleView : public BView,
int32 type) const; int32 type) const;
void _SetStyleType(int32 type); void _SetStyleType(int32 type);
void _SetGradientType(int32 type); void _SetGradientType(int32 type);
void _AdoptCurrentColor(rgb_color color);
void _TransferGradientStopColor();
CommandStack* fCommandStack; CommandStack* fCommandStack;
CurrentColor* fCurrentColor;
Style* fStyle; Style* fStyle;
Gradient* fGradient; Gradient* fGradient;
+7 -31
View File
@@ -19,7 +19,6 @@
#include "ColorSlider.h" #include "ColorSlider.h"
#include "CurrentColor.h" #include "CurrentColor.h"
#include "Group.h" #include "Group.h"
#include "Style.h"
#include "SwatchView.h" #include "SwatchView.h"
enum { enum {
@@ -35,7 +34,6 @@ SwatchGroup::SwatchGroup(BRect frame)
: BView(frame, "style view", B_FOLLOW_NONE, 0), : BView(frame, "style view", B_FOLLOW_NONE, 0),
fCurrentColor(NULL), fCurrentColor(NULL),
fCurrentStyle(NULL),
fIgnoreNotifications(false), fIgnoreNotifications(false),
fColorPickerPanel(NULL), fColorPickerPanel(NULL),
@@ -93,12 +91,15 @@ SwatchGroup::SwatchGroup(BRect frame)
fBottomSwatchViews->ResizeToPreferred(); fBottomSwatchViews->ResizeToPreferred();
fBottomSwatchViews->SetResizingMode(B_FOLLOW_ALL); fBottomSwatchViews->SetResizingMode(B_FOLLOW_ALL);
fTopSwatchViews->MoveTo(30, 4); float paletteHeight = fBottomSwatchViews->Frame().Height()
fBottomSwatchViews->MoveTo(30, fTopSwatchViews->Frame().bottom + 1); + fTopSwatchViews->Frame().Height() + 1;
fTopSwatchViews->MoveTo(paletteHeight + 2, 4);
fBottomSwatchViews->MoveTo(paletteHeight + 2,
fTopSwatchViews->Frame().bottom + 1);
fCurrentColorSV->MoveTo(0, fTopSwatchViews->Frame().top); fCurrentColorSV->MoveTo(0, fTopSwatchViews->Frame().top);
fCurrentColorSV->ResizeTo(28, fBottomSwatchViews->Frame().bottom fCurrentColorSV->ResizeTo(paletteHeight, paletteHeight);
- fTopSwatchViews->Frame().top);
fCurrentColorSV->SetResizingMode(B_FOLLOW_LEFT | B_FOLLOW_TOP); fCurrentColorSV->SetResizingMode(B_FOLLOW_LEFT | B_FOLLOW_TOP);
float width = fTopSwatchViews->Frame().right float width = fTopSwatchViews->Frame().right
@@ -128,7 +129,6 @@ SwatchGroup::SwatchGroup(BRect frame)
SwatchGroup::~SwatchGroup() SwatchGroup::~SwatchGroup()
{ {
SetCurrentColor(NULL); SetCurrentColor(NULL);
SetCurrentStyle(NULL);
} }
// ObjectChanged // ObjectChanged
@@ -147,10 +147,6 @@ SwatchGroup::ObjectChanged(const Observable* object)
_SetColor(h, s, v); _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 - // #pragma mark -
// _SetColor // _SetColor
-3
View File
@@ -20,7 +20,6 @@ class ColorPickerPanel;
class ColorSlider; class ColorSlider;
class CurrentColor; class CurrentColor;
class Group; class Group;
class Style;
class SwatchView; class SwatchView;
class SwatchGroup : public BView, class SwatchGroup : public BView,
@@ -38,7 +37,6 @@ class SwatchGroup : public BView,
// SwatchGroup // SwatchGroup
void SetCurrentColor(CurrentColor* color); void SetCurrentColor(CurrentColor* color);
void SetCurrentStyle(Style* style);
private: private:
void _SetColor(rgb_color color); void _SetColor(rgb_color color);
@@ -53,7 +51,6 @@ class SwatchGroup : public BView,
Group* fBottomSwatchViews; Group* fBottomSwatchViews;
CurrentColor* fCurrentColor; CurrentColor* fCurrentColor;
Style* fCurrentStyle;
bool fIgnoreNotifications; bool fIgnoreNotifications;
ColorPickerPanel* fColorPickerPanel; ColorPickerPanel* fColorPickerPanel;
@@ -195,13 +195,15 @@ TransformerListView::CopyItems(BList& items, int32 toIndex)
// RemoveItemList // RemoveItemList
void void
TransformerListView::RemoveItemList(BList& indexList) TransformerListView::RemoveItemList(BList& items)
{ {
if (!fCommandStack || !fShape) if (!fCommandStack || !fShape)
return; return;
int32 count = indexList.CountItems(); int32 count = items.CountItems();
const int32* indices = (int32*)indexList.Items(); int32 indices[count];
for (int32 i = 0; i < count; i++)
indices[i] = IndexOf((SimpleItem*)items.ItemAtFast(i));
RemoveTransformersCommand* command RemoveTransformersCommand* command
= new (nothrow) RemoveTransformersCommand(fShape, = new (nothrow) RemoveTransformersCommand(fShape,
@@ -33,7 +33,7 @@ class TransformerListView : public SimpleListView,
virtual void MoveItems(BList& items, int32 toIndex); virtual void MoveItems(BList& items, int32 toIndex);
virtual void CopyItems(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; virtual BListItem* CloneItem(int32 atIndex) const;
@@ -38,6 +38,7 @@ PathContainer::PathContainer(bool ownsPaths)
// destructor // destructor
PathContainer::~PathContainer() PathContainer::~PathContainer()
{ {
printf("PathContainer::~PathContainer()\n");
int32 count = fListeners.CountItems(); int32 count = fListeners.CountItems();
if (count > 0) { if (count > 0) {
debugger("~PathContainer() - there are still" debugger("~PathContainer() - there are still"
+11 -1
View File
@@ -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); SetStyle(other.fStyle);
} }
@@ -80,6 +89,7 @@ Shape::Shape(const Shape& other)
// destructor // destructor
Shape::~Shape() Shape::~Shape()
{ {
printf("~Shape()\n");
int32 count = fTransformers.CountItems(); int32 count = fTransformers.CountItems();
for (int32 i = 0; i < count; i++) { for (int32 i = 0; i < count; i++) {
Transformer* t = (Transformer*)fTransformers.ItemAtFast(i); Transformer* t = (Transformer*)fTransformers.ItemAtFast(i);
@@ -888,6 +888,20 @@ VectorPath::RemoveListener(PathListener* listener)
return fListeners.RemoveItem((void*)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 - // #pragma mark -
// _SetPoint // _SetPoint
+3
View File
@@ -142,6 +142,9 @@ class VectorPath : public BArchivable,
bool AddListener(PathListener* listener); bool AddListener(PathListener* listener);
bool RemoveListener(PathListener* listener); bool RemoveListener(PathListener* listener);
int32 CountListeners() const;
PathListener* ListenerAtFast(int32 index) const;
private: private:
BRect _Bounds() const; BRect _Bounds() const;
@@ -0,0 +1,108 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "AddPathsCommand.h"
#include <new>
#include <stdio.h>
#include <string.h>
#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";
}
}
@@ -0,0 +1,43 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#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
@@ -0,0 +1,99 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "AddShapesCommand.h"
#include <new>
#include <stdio.h>
#include <string.h>
#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";
}
@@ -0,0 +1,41 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#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
@@ -0,0 +1,128 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "RemovePathsCommand.h"
#include <new>
#include <stdio.h>
#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<Shape*>(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";
}
@@ -0,0 +1,46 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef REMOVE_PATHS_COMMAND_H
#define REMOVE_PATHS_COMMAND_H
#include <List.h>
#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
@@ -19,7 +19,7 @@ using std::nothrow;
// constructor // constructor
RemoveShapesCommand::RemoveShapesCommand(ShapeContainer* container, RemoveShapesCommand::RemoveShapesCommand(ShapeContainer* container,
const int32* indices, int32* const indices,
int32 count) int32 count)
: Command(), : Command(),
fContainer(container), fContainer(container),
@@ -41,7 +41,7 @@ RemoveShapesCommand::~RemoveShapesCommand()
{ {
if (fShapesRemoved && fShapes) { if (fShapesRemoved && fShapes) {
for (int32 i = 0; i < fCount; i++) for (int32 i = 0; i < fCount; i++)
delete fShapes[i]; fShapes[i]->Release();
} }
delete[] fShapes; delete[] fShapes;
delete[] fIndices; delete[] fIndices;
@@ -18,7 +18,7 @@ class RemoveShapesCommand : public Command {
public: public:
RemoveShapesCommand( RemoveShapesCommand(
ShapeContainer* container, ShapeContainer* container,
const int32* indices, int32* const indices,
int32 count); int32 count);
virtual ~RemoveShapesCommand(); virtual ~RemoveShapesCommand();
@@ -0,0 +1,66 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#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";
}
@@ -0,0 +1,36 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#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
@@ -0,0 +1,99 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "AddStylesCommand.h"
#include <new>
#include <stdio.h>
#include <string.h>
#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";
}
@@ -0,0 +1,41 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#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
+11 -7
View File
@@ -277,10 +277,12 @@ bool
Gradient::SetColor(int32 index, const color_step& color) Gradient::SetColor(int32 index, const color_step& color)
{ {
if (color_step* step = ColorAt(index)) { if (color_step* step = ColorAt(index)) {
step->color = color.color; if (*step != color) {
step->offset = color.offset; step->color = color.color;
Notify(); step->offset = color.offset;
return true; Notify();
return true;
}
} }
return false; return false;
} }
@@ -290,9 +292,11 @@ bool
Gradient::SetColor(int32 index, const rgb_color& color) Gradient::SetColor(int32 index, const rgb_color& color)
{ {
if (color_step* step = ColorAt(index)) { if (color_step* step = ColorAt(index)) {
step->color = color; if ((uint32&)step->color != (uint32&)color) {
Notify(); step->color = color;
return true; Notify();
return true;
}
} }
return false; return false;
} }
@@ -0,0 +1,82 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "SetColorCommand.h"
#include <new>
#include <stdio.h>
#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<const SetColorCommand*>(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;
}
@@ -0,0 +1,38 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef SET_COLOR_COMMAND_H
#define SET_COLOR_COMMAND_H
#include <InterfaceDefs.h>
#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
@@ -40,10 +40,10 @@ ChannelTransform::~ChannelTransform()
// SetTransformation // SetTransformation
void void
ChannelTransform::SetTransformation(BPoint pivot, ChannelTransform::SetTransformation(BPoint pivot,
BPoint translation, BPoint translation,
double rotation, double rotation,
double xScale, double xScale,
double yScale) double yScale)
{ {
if (fTranslation != translation || if (fTranslation != translation ||
fPivot != pivot || fPivot != pivot ||
@@ -23,6 +23,11 @@
#define INSET 8.0 #define INSET 8.0
TransformBoxListener::TransformBoxListener() {}
TransformBoxListener::~TransformBoxListener() {}
// #pragma mark -
// constructor // constructor
TransformBox::TransformBox(StateView* view, BRect box) TransformBox::TransformBox(StateView* view, BRect box)
: ChannelTransform(), : ChannelTransform(),
@@ -68,6 +73,8 @@ TransformBox::TransformBox(StateView* view, BRect box)
// destructor // destructor
TransformBox::~TransformBox() TransformBox::~TransformBox()
{ {
_NotifyDeleted();
delete fCurrentCommand; delete fCurrentCommand;
delete fDragLTState; delete fDragLTState;
@@ -137,8 +144,8 @@ TransformBox::MouseDown(BPoint where)
fCurrentState->SetOrigin(where); fCurrentState->SetOrigin(where);
delete fCurrentCommand; delete fCurrentCommand;
fCurrentCommand = MakeAction(fCurrentState->ActionName(), fCurrentCommand = MakeCommand(fCurrentState->ActionName(),
fCurrentState->ActionNameIndex()); fCurrentState->ActionNameIndex());
} }
return true; return true;
@@ -173,7 +180,7 @@ TransformBox::MouseOver(BPoint where)
{ {
TransformToCanvas(where); TransformToCanvas(where);
_SetState(_DragStateFor(where, 1.0 /*zoom*/)); _SetState(_DragStateFor(where, ZoomLevel()));
fMousePos = where; fMousePos = where;
if (fCurrentState) { if (fCurrentState) {
fCurrentState->UpdateViewCursor(fView, fMousePos); fCurrentState->UpdateViewCursor(fView, fMousePos);
@@ -200,7 +207,7 @@ TransformBox::Bounds()
BPoint rt = fRightTop; BPoint rt = fRightTop;
BPoint lb = fLeftBottom; BPoint lb = fLeftBottom;
BPoint rb = fRightBottom; BPoint rb = fRightBottom;
BPoint c = Pivot(); BPoint c = fPivot;
TransformFromCanvas(lt); TransformFromCanvas(lt);
TransformFromCanvas(rt); TransformFromCanvas(rt);
@@ -301,9 +308,9 @@ TransformBox::Update(bool deep)
Transform(&fPivot); Transform(&fPivot);
} }
// OffsetPivot // OffsetCenter
void void
TransformBox::OffsetPivot(BPoint offset) TransformBox::OffsetCenter(BPoint offset)
{ {
if (offset != BPoint(0.0, 0.0)) { if (offset != BPoint(0.0, 0.0)) {
fPivotOffset += offset; fPivotOffset += offset;
@@ -311,6 +318,13 @@ TransformBox::OffsetPivot(BPoint offset)
} }
} }
// Center
BPoint
TransformBox::Center() const
{
return fPivot;
}
// SetBox // SetBox
void void
TransformBox::SetBox(BRect box) TransformBox::SetBox(BRect box)
@@ -342,7 +356,7 @@ void
TransformBox::NudgeBy(BPoint offset) TransformBox::NudgeBy(BPoint offset)
{ {
if (!fNudging && !fCurrentCommand) { if (!fNudging && !fCurrentCommand) {
fCurrentCommand = MakeAction("Move", 0/*MOVE*/); fCurrentCommand = MakeCommand("Move", 0/*MOVE*/);
fNudging = true; fNudging = true;
} }
if (fNudging) { if (fNudging) {
@@ -370,6 +384,13 @@ TransformBox::TransformToCanvas(BPoint& point) const
{ {
} }
// ZoomLevel
float
TransformBox::ZoomLevel() const
{
return 1.0;
}
// ViewSpaceRotation // ViewSpaceRotation
double double
TransformBox::ViewSpaceRotation() const TransformBox::ViewSpaceRotation() const
@@ -378,6 +399,26 @@ TransformBox::ViewSpaceRotation() const
return LocalRotation(); 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? // TODO: why another version?
// point_line_dist // point_line_dist
float float
@@ -414,7 +455,7 @@ TransformBox::_DragStateFor(BPoint where, float canvasZoom)
// priorities: // priorities:
// transformation center point has highest priority ?!? // transformation center point has highest priority ?!?
if (point_point_distance(where, Pivot()) < inset) if (point_point_distance(where, fPivot) < inset)
state = fOffsetCenterState; state = fOffsetCenterState;
if (!state) { if (!state) {
@@ -581,6 +622,23 @@ TransformBox::_StrokeBWPoint(BView* into, BPoint point, double angle) const
into->StrokeLine(p[3], p[0], B_SOLID_LOW); 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 // _SetState
void void
TransformBox::_SetState(DragState* state) TransformBox::_SetState(DragState* state)
@@ -591,4 +649,3 @@ TransformBox::_SetState(DragState* state)
} }
} }
@@ -9,14 +9,26 @@
#ifndef TRANSFORM_BOX_H #ifndef TRANSFORM_BOX_H
#define TRANSFORM_BOX_H #define TRANSFORM_BOX_H
#include <List.h>
#include "ChannelTransform.h" #include "ChannelTransform.h"
#include "Manipulator.h" #include "Manipulator.h"
class Command; class Command;
class StateView; class StateView;
class DragState; class DragState;
class TransformBox;
class TransformCommand; class TransformCommand;
class TransformBoxListener {
public:
TransformBoxListener();
virtual ~TransformBoxListener();
virtual void TransformBoxDeleted(
const TransformBox* box) = 0;
};
class TransformBox : public ChannelTransform, class TransformBox : public ChannelTransform,
public Manipulator { public Manipulator {
public: public:
@@ -50,7 +62,8 @@ class TransformBox : public ChannelTransform,
// TransformBox // TransformBox
virtual void Update(bool deep = true); virtual void Update(bool deep = true);
void OffsetPivot(BPoint offset); void OffsetCenter(BPoint offset);
BPoint Center() const;
void SetBox(BRect box); void SetBox(BRect box);
BRect Box() const BRect Box() const
{ return fOriginalBox; } { return fOriginalBox; }
@@ -64,22 +77,28 @@ class TransformBox : public ChannelTransform,
virtual void TransformFromCanvas(BPoint& point) const; virtual void TransformFromCanvas(BPoint& point) const;
virtual void TransformToCanvas(BPoint& point) const; virtual void TransformToCanvas(BPoint& point) const;
virtual float ZoomLevel() const;
virtual TransformCommand* MakeAction(const char* actionName, virtual TransformCommand* MakeCommand(const char* actionName,
uint32 nameIndex) const = 0; uint32 nameIndex) = 0;
bool IsRotating() const bool IsRotating() const
{ return fCurrentState == fRotateState; } { return fCurrentState == fRotateState; }
virtual double ViewSpaceRotation() const; virtual double ViewSpaceRotation() const;
// Listener support
bool AddListener(TransformBoxListener* listener);
bool RemoveListener(TransformBoxListener* listener);
private: private:
DragState* _DragStateFor(BPoint canvasWhere, DragState* _DragStateFor(BPoint canvasWhere,
float canvasZoom); float canvasZoom);
void _StrokeBWLine(BView* into, void _StrokeBWLine(BView* into,
BPoint from, BPoint to) const; BPoint from, BPoint to) const;
void _StrokeBWPoint(BView* into, void _StrokeBWPoint(BView* into,
BPoint point, double angle) const; BPoint point,
double angle) const;
BRect fOriginalBox; BRect fOriginalBox;
@@ -100,7 +119,11 @@ class TransformBox : public ChannelTransform,
bool fNudging; bool fNudging;
BList fListeners;
protected: protected:
void _NotifyDeleted() const;
// "static" state objects // "static" state objects
void _SetState(DragState* state); void _SetState(DragState* state);
@@ -509,7 +509,7 @@ RotateBoxState::SetOrigin(BPoint origin)
void void
RotateBoxState::DragTo(BPoint current, uint32 modifiers) 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 (modifiers & B_SHIFT_KEY) {
if (angle < 0.0) if (angle < 0.0)
@@ -521,14 +521,14 @@ RotateBoxState::DragTo(BPoint current, uint32 modifiers)
double newAngle = fOldAngle + angle; double newAngle = fOldAngle + angle;
fParent->RotateBy(newAngle - fParent->LocalRotation()); fParent->RotateBy(fParent->Center(), newAngle - fParent->LocalRotation());
} }
// UpdateViewCursor // UpdateViewCursor
void void
RotateBoxState::UpdateViewCursor(BView* view, BPoint current) const RotateBoxState::UpdateViewCursor(BView* view, BPoint current) const
{ {
BPoint origin(fParent->Pivot()); BPoint origin(fParent->Center());
fParent->TransformToCanvas(origin); fParent->TransformToCanvas(origin);
fParent->TransformToCanvas(current); fParent->TransformToCanvas(current);
BPoint from = origin + BPoint(sinf(22.5 * 180.0 / PI) * 50.0, BPoint from = origin + BPoint(sinf(22.5 * 180.0 / PI) * 50.0,
@@ -587,7 +587,7 @@ void
OffsetCenterState::DragTo(BPoint current, uint32 modifiers) OffsetCenterState::DragTo(BPoint current, uint32 modifiers)
{ {
fParent->InverseTransform(&current); fParent->InverseTransform(&current);
fParent->OffsetPivot(current - fOrigin); fParent->OffsetCenter(current - fOrigin);
fOrigin = current; fOrigin = current;
} }
@@ -90,11 +90,11 @@ TransformCommand::Undo()
{ {
status_t status = InitCheck(); status_t status = InitCheck();
if (status >= B_OK) { if (status >= B_OK) {
_SetTransformation(fOldPivot - fNewPivot, _SetTransformation(fOldPivot,
fOldTranslation - fNewTranslation, fOldTranslation,
fOldRotation - fNewRotation, fOldRotation,
fOldXScale - fNewXScale, fOldXScale,
fOldYScale - fNewYScale); fOldYScale);
} }
return status; return status;
} }
@@ -105,11 +105,11 @@ TransformCommand::Redo()
{ {
status_t status = InitCheck(); status_t status = InitCheck();
if (status >= B_OK) { if (status >= B_OK) {
_SetTransformation(fNewPivot - fOldPivot, _SetTransformation(fNewPivot,
fNewTranslation - fOldTranslation, fNewTranslation,
fNewRotation - fOldRotation, fNewRotation,
fNewXScale - fOldXScale, fNewXScale,
fNewYScale - fOldYScale); fNewYScale);
} }
return status; return status;
} }
@@ -39,7 +39,7 @@ class TransformCommand : public Command {
virtual void GetName(BString& name); virtual void GetName(BString& name);
// TransformCommand // TransformCommand
void SetNewTransformation(BPoint pivot, void SetNewTransformation(BPoint pivot,
BPoint translation, BPoint translation,
double rotation, double rotation,
@@ -0,0 +1,115 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "TransformObjectsCommand.h"
#include <new>
#include <stdio.h>
#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;
}
@@ -0,0 +1,56 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#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
@@ -15,7 +15,7 @@
#include "CanvasView.h" #include "CanvasView.h"
#include "Shape.h" #include "Shape.h"
#include "StateView.h" #include "StateView.h"
//#include "TransformShapesCommand.h" #include "TransformObjectsCommand.h"
using std::nothrow; using std::nothrow;
@@ -116,6 +116,10 @@ TransformShapesBox::ObjectChanged(const Observable* object)
box = box | fShapes[i]->Bounds(); box = box | fShapes[i]->Bounds();
fShapes[i]->StoreTo(&fOriginals[i * 6]); fShapes[i]->StoreTo(&fOriginals[i * 6]);
} }
// any TransformObjectsCommand cannot use the TransformBox
// anymore
_NotifyDeleted();
Reset(); Reset();
SetBox(box); SetBox(box);
@@ -154,6 +158,13 @@ TransformShapesBox::TransformToCanvas(BPoint& point) const
fParentTransform.Transform(&point); fParentTransform.Transform(&point);
} }
// ZoomLevel
float
TransformShapesBox::ZoomLevel() const
{
return fCanvasView->ZoomLevel();
}
// ViewSpaceRotation // ViewSpaceRotation
double double
TransformShapesBox::ViewSpaceRotation() const TransformShapesBox::ViewSpaceRotation() const
@@ -163,19 +174,23 @@ TransformShapesBox::ViewSpaceRotation() const
return t.rotation() * 180.0 / PI; return t.rotation() * 180.0 / PI;
} }
// MakeAction // MakeCommand
TransformCommand* TransformCommand*
TransformShapesBox::MakeAction(const char* actionName, uint32 nameIndex) const TransformShapesBox::MakeCommand(const char* commandName, uint32 nameIndex)
{ {
// return new TransformShapesCommand(fShapes, fCount, const Transformable* objects[fCount];
// for (int32 i = 0; i < fCount; i++)
// Pivot(), objects[i] = fShapes[i];
// Translation(),
// LocalRotation(), return new TransformObjectsCommand(this, objects, fOriginals, fCount,
// LocalXScale(),
// LocalYScale(), Pivot(),
// Translation(),
// actionName, LocalRotation(),
// nameIndex); LocalXScale(),
return NULL; LocalYScale(),
commandName,
nameIndex);
} }
@@ -29,10 +29,11 @@ class TransformShapesBox : public TransformBox {
virtual void TransformFromCanvas(BPoint& point) const; virtual void TransformFromCanvas(BPoint& point) const;
virtual void TransformToCanvas(BPoint& point) const; virtual void TransformToCanvas(BPoint& point) const;
virtual float ZoomLevel() const;
virtual double ViewSpaceRotation() const; virtual double ViewSpaceRotation() const;
virtual TransformCommand* MakeAction(const char* actionName, virtual TransformCommand* MakeCommand(const char* actionName,
uint32 nameIndex) const; uint32 nameIndex);
// TransformShapesBox // TransformShapesBox
Command* Perform(); Command* Perform();
@@ -32,14 +32,14 @@ Transformable::~Transformable()
// StoreTo // StoreTo
void void
Transformable::StoreTo(double matrix[6]) const Transformable::StoreTo(double matrix[matrix_size]) const
{ {
store_to(matrix); store_to(matrix);
} }
// LoadFrom // LoadFrom
void void
Transformable::LoadFrom(double matrix[6]) Transformable::LoadFrom(double matrix[matrix_size])
{ {
// before calling the potentially heavy TransformationChanged() // before calling the potentially heavy TransformationChanged()
// hook function, make sure that the transformation // hook function, make sure that the transformation
@@ -103,7 +103,7 @@ Transformable::Invert()
bool bool
Transformable::IsIdentity() const Transformable::IsIdentity() const
{ {
double m[6]; double m[matrix_size];
store_to(m); store_to(m);
if (m[0] == 1.0 && if (m[0] == 1.0 &&
m[1] == 0.0 && m[1] == 0.0 &&
@@ -119,7 +119,7 @@ Transformable::IsIdentity() const
bool bool
Transformable::IsTranslationOnly() const Transformable::IsTranslationOnly() const
{ {
double m[6]; double m[matrix_size];
store_to(m); store_to(m);
if (m[0] == 1.0 && if (m[0] == 1.0 &&
m[1] == 0.0 && m[1] == 0.0 &&
@@ -133,7 +133,7 @@ Transformable::IsTranslationOnly() const
bool bool
Transformable::IsNotDistorted() const Transformable::IsNotDistorted() const
{ {
double m[6]; double m[matrix_size];
store_to(m); store_to(m);
return (m[0] == m[3]); return (m[0] == m[3]);
} }
@@ -142,7 +142,7 @@ Transformable::IsNotDistorted() const
bool bool
Transformable::IsValid() const Transformable::IsValid() const
{ {
double m[6]; double m[matrix_size];
store_to(m); store_to(m);
return ((m[0] * m[3] - m[1] * m[2]) != 0.0); return ((m[0] * m[3] - m[1] * m[2]) != 0.0);
} }
@@ -151,9 +151,9 @@ Transformable::IsValid() const
bool bool
Transformable::operator==(const Transformable& other) const Transformable::operator==(const Transformable& other) const
{ {
double m1[6]; double m1[matrix_size];
other.store_to(m1); other.store_to(m1);
double m2[6]; double m2[matrix_size];
store_to(m2); store_to(m2);
if (m1[0] == m2[0] && if (m1[0] == m2[0] &&
m1[1] == m2[1] && m1[1] == m2[1] &&
@@ -17,12 +17,16 @@
class Transformable : public agg::trans_affine { class Transformable : public agg::trans_affine {
public: public:
enum {
matrix_size = 6,
};
Transformable(); Transformable();
Transformable(const Transformable& other); Transformable(const Transformable& other);
virtual ~Transformable(); virtual ~Transformable();
void StoreTo(double matrix[6]) const; void StoreTo(double matrix[matrix_size]) const;
void LoadFrom(double matrix[6]); void LoadFrom(double matrix[matrix_size]);
// set to or combine with other matrix // set to or combine with other matrix
void SetTransform(const Transformable& other); void SetTransform(const Transformable& other);
@@ -8,10 +8,14 @@
#include "AffineTransformer.h" #include "AffineTransformer.h"
#include <new>
#include "CommonPropertyIDs.h" #include "CommonPropertyIDs.h"
#include "Property.h" #include "Property.h"
#include "PropertyObject.h" #include "PropertyObject.h"
using std::nothrow;
// constructor // constructor
AffineTransformer::AffineTransformer(VertexSource& source) AffineTransformer::AffineTransformer(VertexSource& source)
: Transformer(source, "Transformation"), : 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 // rewind
void void
AffineTransformer::rewind(unsigned path_id) AffineTransformer::rewind(unsigned path_id)
@@ -25,7 +25,9 @@ class AffineTransformer : public Transformer,
VertexSource& source); VertexSource& source);
virtual ~AffineTransformer(); 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 unsigned vertex(double* x, double* y);
virtual void SetSource(VertexSource& source); virtual void SetSource(VertexSource& source);
@@ -8,11 +8,15 @@
#include "ContourTransformer.h" #include "ContourTransformer.h"
#include <new>
#include "CommonPropertyIDs.h" #include "CommonPropertyIDs.h"
#include "OptionProperty.h" #include "OptionProperty.h"
#include "Property.h" #include "Property.h"
#include "PropertyObject.h" #include "PropertyObject.h"
using std::nothrow;
// constructor // constructor
ContourTransformer::ContourTransformer(VertexSource& source) ContourTransformer::ContourTransformer(VertexSource& source)
: Transformer(source, "Contour"), : 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 // rewind
void void
ContourTransformer::rewind(unsigned path_id) ContourTransformer::rewind(unsigned path_id)
@@ -22,7 +22,9 @@ class ContourTransformer : public Transformer,
VertexSource& source); VertexSource& source);
virtual ~ContourTransformer(); 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 unsigned vertex(double* x, double* y);
virtual void SetSource(VertexSource& source); virtual void SetSource(VertexSource& source);
@@ -8,6 +8,10 @@
#include "PerspectiveTransformer.h" #include "PerspectiveTransformer.h"
#include <new>
using std::nothrow;
// constructor // constructor
PerspectiveTransformer::PerspectiveTransformer(VertexSource& source) PerspectiveTransformer::PerspectiveTransformer(VertexSource& source)
: Transformer(source, "Perspective"), : 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 // rewind
void void
PerspectiveTransformer::rewind(unsigned path_id) PerspectiveTransformer::rewind(unsigned path_id)
@@ -25,8 +25,10 @@ class PerspectiveTransformer : public Transformer,
VertexSource& source); VertexSource& source);
virtual ~PerspectiveTransformer(); virtual ~PerspectiveTransformer();
virtual void rewind(unsigned path_id); virtual Transformer* Clone(VertexSource& source) const;
virtual unsigned vertex(double* x, double* y);
virtual void rewind(unsigned path_id);
virtual unsigned vertex(double* x, double* y);
virtual void SetSource(VertexSource& source); virtual void SetSource(VertexSource& source);
@@ -8,11 +8,15 @@
#include "StrokeTransformer.h" #include "StrokeTransformer.h"
#include <new>
#include "CommonPropertyIDs.h" #include "CommonPropertyIDs.h"
#include "OptionProperty.h" #include "OptionProperty.h"
#include "Property.h" #include "Property.h"
#include "PropertyObject.h" #include "PropertyObject.h"
using std::nothrow;
// constructor // constructor
StrokeTransformer::StrokeTransformer(VertexSource& source) StrokeTransformer::StrokeTransformer(VertexSource& source)
: Transformer(source, "Stroke"), : 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 // rewind
void void
StrokeTransformer::rewind(unsigned path_id) StrokeTransformer::rewind(unsigned path_id)
@@ -98,6 +119,10 @@ StrokeTransformer::MakePropertyObject() const
miter_limit())); miter_limit()));
} }
// shorten
object->AddProperty(new FloatProperty(PROPERTY_STROKE_SHORTEN,
shorten()));
return object; return object;
} }
@@ -137,6 +162,13 @@ StrokeTransformer::SetToPropertyObject(const PropertyObject* object)
Notify(); Notify();
} }
// shorten
float s = object->Value(PROPERTY_STROKE_SHORTEN, (float)shorten());
if (s != shorten()) {
shorten(s);
Notify();
}
return HasPendingNotifications(); return HasPendingNotifications();
} }
@@ -22,8 +22,10 @@ class StrokeTransformer : public Transformer,
VertexSource& source); VertexSource& source);
virtual ~StrokeTransformer(); virtual ~StrokeTransformer();
virtual void rewind(unsigned path_id); virtual Transformer* Clone(VertexSource& source) const;
virtual unsigned vertex(double* x, double* y);
virtual void rewind(unsigned path_id);
virtual unsigned vertex(double* x, double* y);
virtual void SetSource(VertexSource& source); virtual void SetSource(VertexSource& source);
@@ -31,7 +31,9 @@ class Transformer : public VertexSource,
const char* name); const char* name);
virtual ~Transformer(); 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 unsigned vertex(double* x, double* y);
virtual void SetSource(VertexSource& source); virtual void SetSource(VertexSource& source);