* 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
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 -
+8
View File
@@ -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
+51 -23
View File
@@ -8,6 +8,7 @@
#include "MainWindow.h"
#include <new>
#include <stdio.h>
#include <Menu.h>
@@ -16,6 +17,9 @@
#include <Message.h>
#include <ScrollView.h>
#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
+7 -9
View File
@@ -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
+6 -2
View File
@@ -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
+1
View File
@@ -9,6 +9,7 @@
#include "Icon.h"
#include <new>
#include <stdio.h>
#include "PathContainer.h"
#include "Shape.h"
@@ -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<BTextView*>(*target))
break;
if (dynamic_cast<BTextView*>(*target))
break;
if (dynamic_cast<SimpleListView*>(*target))
break;
if (dynamic_cast<GradientControl*>(*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<BTextView*>(*target))
break;
if (dynamic_cast<BTextView*>(*target))
break;
if (dynamic_cast<SimpleListView*>(*target))
break;
if (dynamic_cast<GradientControl*>(*target))
break;
uint32 key;
uint32 modifiers;
if (message->FindInt32("raw_char", (int32*)&key) >= B_OK
@@ -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";
@@ -23,6 +23,7 @@ enum {
PROPERTY_CAP_MODE = 'cpmd',
PROPERTY_JOIN_MODE = 'jnmd',
PROPERTY_MITER_LIMIT = 'mtlm',
PROPERTY_STROKE_SHORTEN = 'srtn',
PROPERTY_CLOSED = 'clsd',
@@ -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
@@ -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;
@@ -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);
}
}
@@ -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;
}
@@ -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();
@@ -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;
}
@@ -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;
@@ -65,3 +65,13 @@ FloatValueView::AdoptProperty(Property* property)
}
return false;
}
// GetProperty
Property*
FloatValueView::GetProperty() const
{
return fProperty;
}
@@ -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;
@@ -88,6 +88,13 @@ IconValueView::AdoptProperty(Property* property)
return false;
}
// GetProperty
Property*
IconValueView::GetProperty() const
{
return fProperty;
}
// #pragma mark -
// SetIcon
@@ -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,
@@ -69,3 +69,10 @@ Int64ValueView::AdoptProperty(Property* property)
return false;
}
// GetProperty
Property*
Int64ValueView::GetProperty() const
{
return fProperty;
}
@@ -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;
@@ -66,3 +66,10 @@ IntValueView::AdoptProperty(Property* property)
return false;
}
// GetProperty
Property*
IntValueView::GetProperty() const
{
return fProperty;
}
@@ -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;
@@ -230,3 +230,10 @@ OptionValueView::AdoptProperty(Property* property)
return false;
}
// GetProperty
Property*
OptionValueView::GetProperty() const
{
return fProperty;
}
@@ -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;
@@ -65,3 +65,10 @@ StringValueView::AdoptProperty(Property* property)
}
return false;
}
// GetProperty
Property*
StringValueView::GetProperty() const
{
return fProperty;
}
@@ -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;
@@ -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 {
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
@@ -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);
+48 -21
View File
@@ -16,11 +16,15 @@
#include <Mime.h>
#include <Window.h>
#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<PathListItem*>(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<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
@@ -469,6 +489,13 @@ PathListView::SetSelection(Selection* selection)
fSelection = selection;
}
// SetCommandStack
void
PathListView::SetCommandStack(CommandStack* stack)
{
fCommandStack = stack;
}
// SetCurrentShape
void
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 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
+37 -12
View File
@@ -17,6 +17,7 @@
#include <Mime.h>
#include <Window.h>
#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<ShapeListItem*>(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<ShapeListItem*>(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<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
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();
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -347,7 +347,7 @@ StyleListView::CopyItems(BList& items, int32 toIndex)
// RemoveItemList
void
StyleListView::RemoveItemList(BList& indices)
StyleListView::RemoveItemList(BList& 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 CopyItems(BList& items, int32 toIndex);
virtual void RemoveItemList(BList& indices);
virtual void RemoveItemList(BList& items);
virtual BListItem* CloneItem(int32 atIndex) const;
+72 -1
View File
@@ -16,8 +16,10 @@
#include <PopUpMenu.h>
#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);
}
}
+5
View File
@@ -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;
+7 -31
View File
@@ -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
-3
View File
@@ -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;
@@ -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,
@@ -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;
@@ -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"
+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);
}
@@ -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);
@@ -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
+3
View File
@@ -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;
@@ -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
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;
@@ -18,7 +18,7 @@ class RemoveShapesCommand : public Command {
public:
RemoveShapesCommand(
ShapeContainer* container,
const int32* indices,
int32* const indices,
int32 count);
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)
{
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;
}
@@ -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
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 ||
@@ -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)
}
}
@@ -9,14 +9,26 @@
#ifndef TRANSFORM_BOX_H
#define TRANSFORM_BOX_H
#include <List.h>
#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);
@@ -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(&current);
fParent->OffsetPivot(current - fOrigin);
fParent->OffsetCenter(current - fOrigin);
fOrigin = current;
}
@@ -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;
}
@@ -39,7 +39,7 @@ class TransformCommand : public Command {
virtual void GetName(BString& name);
// TransformCommand
// TransformCommand
void SetNewTransformation(BPoint pivot,
BPoint translation,
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 "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);
}
@@ -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();
@@ -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] &&
@@ -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);
@@ -8,10 +8,14 @@
#include "AffineTransformer.h"
#include <new>
#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)
@@ -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);
@@ -8,11 +8,15 @@
#include "ContourTransformer.h"
#include <new>
#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)
@@ -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);
@@ -8,6 +8,10 @@
#include "PerspectiveTransformer.h"
#include <new>
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)
@@ -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);
@@ -8,11 +8,15 @@
#include "StrokeTransformer.h"
#include <new>
#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();
}
@@ -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);
@@ -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);