* implemented MoveTransformersCommand (so Transformers can be

drag sorted now)
* implemented RemoveTransformersCommand
* implemented StyleListView (I promise, this is the last list view :-)
* implemented adding new styles via the Style menu
* implemented selecting the Style of the currently selected Shape


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18072 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2006-07-08 13:04:05 +00:00
parent 9fcdf0e92c
commit 4215c452a4
15 changed files with 1120 additions and 40 deletions
+3
View File
@@ -111,6 +111,7 @@ Application Icon-O-Matic :
IconObjectListView.cpp
PathListView.cpp
ShapeListView.cpp
StyleListView.cpp
SwatchGroup.cpp
TransformerListView.cpp
# shape
@@ -124,9 +125,11 @@ Application Icon-O-Matic :
ChangePointCommand.cpp
InsertPointCommand.cpp
MoveShapesCommand.cpp
MoveTransformersCommand.cpp
PathCommand.cpp
RemovePointsCommand.cpp
RemoveShapesCommand.cpp
RemoveTransformersCommand.cpp
# style
Gradient.cpp
Style.cpp
+45 -1
View File
@@ -25,6 +25,7 @@
#include "PathListView.h"
#include "ScrollView.h"
#include "ShapeListView.h"
#include "StyleListView.h"
#include "SwatchGroup.h"
#include "TransformerFactory.h"
#include "TransformerListView.h"
@@ -49,6 +50,9 @@ enum {
MSG_NEW_PATH = 'nwvp',
MSG_PATH_SELECTED = 'vpsl',
MSG_NEW_STYLE = 'nwst',
MSG_STYLE_SELECTED = 'stsl',
MSG_NEW_SHAPE = 'nwsp',
MSG_SHAPE_SELECTED = 'spsl',
MSG_ADD_TRANSFORMER = 'adtr',
@@ -56,7 +60,7 @@ enum {
// constructor
MainWindow::MainWindow(IconEditorApp* app, Document* document)
: BWindow(BRect(50, 50, 891, 781), "Icon-O-Matic",
: BWindow(BRect(20, 50, 1010, 781), "Icon-O-Matic",
B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
B_ASYNCHRONOUS_CONTROLS),
fApp(app),
@@ -107,11 +111,28 @@ case MSG_PATH_SELECTED: {
}
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);
break;
}
// TODO: use an AddShapeCommand
case MSG_NEW_SHAPE: {
Shape* shape = new Shape(StyleManager::Default()->StyleAt(0));
fDocument->Icon()->Shapes()->AddShape(shape);
break;
}
case MSG_SHAPE_SELECTED: {
Shape* shape;
if (message->FindPointer("shape", (void**)&shape) < B_OK)
shape = NULL;
fPathListView->SetCurrentShape(shape);
fStyleListView->SetCurrentShape(shape);
fTransformerListView->SetShape(shape);
break;
}
@@ -200,13 +221,20 @@ MainWindow::_Init()
fCanvasView->SetIcon(fDocument->Icon());
fPathListView->SetPathContainer(fDocument->Icon()->Paths());
fPathListView->SetShapeContainer(fDocument->Icon()->Shapes());
// fPathListView->SetCommandStack(fDocument->CommandStack());
fPathListView->SetSelection(fDocument->Selection());
fStyleListView->SetStyleManager(StyleManager::Default());
fStyleListView->SetShapeContainer(fDocument->Icon()->Shapes());
// fStyleListView->SetCommandStack(fDocument->CommandStack());
fStyleListView->SetSelection(fDocument->Selection());
fShapeListView->SetShapeContainer(fDocument->Icon()->Shapes());
fShapeListView->SetCommandStack(fDocument->CommandStack());
fShapeListView->SetSelection(fDocument->Selection());
fTransformerListView->SetCommandStack(fDocument->CommandStack());
fTransformerListView->SetSelection(fDocument->Selection());
fPropertyListView->SetCommandStack(fDocument->CommandStack());
@@ -329,6 +357,11 @@ MainWindow::_CreateGUI(BRect bounds)
fPathListView = new PathListView(bounds, "path list view",
new BMessage(MSG_PATH_SELECTED), this);
// style list view
bounds.OffsetBy(bounds.Width() + 6 + B_V_SCROLL_BAR_WIDTH, 0);
fStyleListView = new StyleListView(bounds, "style list view",
new BMessage(MSG_STYLE_SELECTED), this);
// shape list view
bounds.OffsetBy(bounds.Width() + 6 + B_V_SCROLL_BAR_WIDTH, 0);
fShapeListView = new ShapeListView(bounds, "shape list view",
@@ -354,6 +387,11 @@ MainWindow::_CreateGUI(BRect bounds)
B_FOLLOW_LEFT | B_FOLLOW_TOP,
0, false, true,
B_NO_BORDER));
bg->AddChild(new BScrollView("style list scroll view",
fStyleListView,
B_FOLLOW_LEFT | B_FOLLOW_TOP,
0, false, true,
B_NO_BORDER));
bg->AddChild(new BScrollView("shape list scroll view",
fShapeListView,
B_FOLLOW_LEFT | B_FOLLOW_TOP,
@@ -367,6 +405,7 @@ MainWindow::_CreateGUI(BRect bounds)
// scroll view around property list view
bounds.OffsetBy(bounds.Width() + 6 + B_V_SCROLL_BAR_WIDTH, 0);
bounds.right = bg->Bounds().right - 5;
bg->AddChild(new ScrollView(fPropertyListView,
SCROLL_VERTICAL | SCROLL_NO_FRAME,
bounds, "property scroll view",
@@ -414,6 +453,11 @@ MainWindow::_CreateMenuBar(BRect frame)
// Path
pathMenu->AddItem(new BMenuItem("New", new BMessage(MSG_NEW_PATH)));
// Style
styleMenu->AddItem(new BMenuItem("New", new BMessage(MSG_NEW_STYLE)));
// Shape
shapeMenu->AddItem(new BMenuItem("New", new BMessage(MSG_NEW_SHAPE)));
// Transformer
int32 cookie = 0;
+3
View File
@@ -22,6 +22,7 @@ class IconEditorApp;
class IconView;
class PathListView;
class ShapeListView;
class StyleListView;
class SwatchGroup;
class TransformerListView;
@@ -61,6 +62,8 @@ class MainWindow : public BWindow,
IconView* fIconPreview64;
PathListView* fPathListView;
StyleListView* fStyleListView;
ShapeListView* fShapeListView;
TransformerListView* fTransformerListView;
IconObjectListView* fPropertyListView;
@@ -173,6 +173,7 @@ class ShapePathListener : public PathContainerListener,
SetShape(NULL);
}
// PathContainerListener interface
virtual void PathAdded(VectorPath* path)
{
fListView->_SetPathMarked(path, true);
@@ -182,12 +183,14 @@ class ShapePathListener : public PathContainerListener,
fListView->_SetPathMarked(path, false);
}
// ShapeContainerListener interface
virtual void ShapeAdded(Shape* shape, int32 index) {}
virtual void ShapeRemoved(Shape* shape)
{
fListView->SetCurrentShape(NULL);
}
// ShapePathListener
void SetShape(Shape* shape)
{
if (fShape == shape)
+548
View File
@@ -0,0 +1,548 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <[email protected]>
*/
#include "StyleListView.h"
#include <stdio.h>
#include <Application.h>
#include <ListItem.h>
#include <Message.h>
#include <Mime.h>
#include <Window.h>
#include "Style.h"
#include "Observer.h"
#include "Shape.h"
#include "ShapeContainer.h"
#include "Selection.h"
static const float kMarkWidth = 14.0;
static const float kBorderOffset = 3.0;
static const float kTextOffset = 4.0;
class StyleListItem : public SimpleItem,
public Observer {
public:
StyleListItem(Style* s,
StyleListView* listView,
bool markEnabled)
: SimpleItem(""),
style(NULL),
fListView(listView),
fMarkEnabled(markEnabled),
fMarked(false)
{
SetStyle(s);
}
virtual ~StyleListItem()
{
SetStyle(NULL);
}
// SimpleItem interface
virtual void Draw(BView* owner, BRect itemFrame, uint32 flags)
{
SimpleItem::DrawBackground(owner, itemFrame, flags);
// text
owner->SetHighColor(0, 0, 0, 255);
font_height fh;
owner->GetFontHeight(&fh);
BString truncatedString(Text());
owner->TruncateString(&truncatedString, B_TRUNCATE_MIDDLE,
itemFrame.Width()
- kBorderOffset
- kMarkWidth
- kTextOffset
- kBorderOffset);
float height = itemFrame.Height();
float textHeight = fh.ascent + fh.descent;
BPoint pos;
pos.x = itemFrame.left
+ kBorderOffset + kMarkWidth + kTextOffset;
pos.y = itemFrame.top
+ ceilf((height - textHeight) / 2.0 + fh.ascent);
owner->DrawString(truncatedString.String(), pos);
if (!fMarkEnabled)
return;
// mark
BRect markRect = itemFrame;
markRect.left += kBorderOffset;
markRect.right = markRect.left + kMarkWidth;
markRect.top = (markRect.top + markRect.bottom - kMarkWidth) / 2.0;
markRect.bottom = markRect.top + kMarkWidth;
owner->SetHighColor(tint_color(owner->LowColor(), B_DARKEN_1_TINT));
owner->StrokeRect(markRect);
markRect.InsetBy(1, 1);
owner->SetHighColor(tint_color(owner->LowColor(), 1.04));
owner->FillRect(markRect);
if (fMarked) {
markRect.InsetBy(2, 2);
owner->SetHighColor(tint_color(owner->LowColor(),
B_DARKEN_4_TINT));
owner->SetPenSize(2);
owner->StrokeLine(markRect.LeftTop(), markRect.RightBottom());
owner->StrokeLine(markRect.LeftBottom(), markRect.RightTop());
owner->SetPenSize(1);
}
}
// Observer interface
virtual void ObjectChanged(const Observable* object)
{
UpdateText();
}
// StyleListItem
void SetStyle(Style* s)
{
if (s == style)
return;
if (style) {
style->RemoveObserver(this);
style->Release();
}
style = s;
if (style) {
style->Acquire();
style->AddObserver(this);
UpdateText();
}
}
void UpdateText()
{
SetText(style->Name());
Invalidate();
}
void SetMarkEnabled(bool enabled)
{
if (fMarkEnabled == enabled)
return;
fMarkEnabled = enabled;
Invalidate();
}
void SetMarked(bool marked)
{
if (fMarked == marked)
return;
fMarked = marked;
Invalidate();
}
void Invalidate()
{
// :-/
if (fListView->LockLooper()) {
fListView->InvalidateItem(
fListView->IndexOf(this));
fListView->UnlockLooper();
}
}
Style* style;
private:
StyleListView* fListView;
bool fMarkEnabled;
bool fMarked;
};
class ShapeStyleListener : public ShapeListener,
public ShapeContainerListener {
public:
ShapeStyleListener(StyleListView* listView)
: fListView(listView),
fShape(NULL)
{
}
virtual ~ShapeStyleListener()
{
SetShape(NULL);
}
// ShapeListener interface
virtual void TransformerAdded(Transformer* t, int32 index) {}
virtual void TransformerRemoved(Transformer* t) {}
virtual void StyleChanged(Style* oldStyle, Style* newStyle)
{
fListView->_SetStyleMarked(oldStyle, false);
fListView->_SetStyleMarked(newStyle, true);
}
// ShapeContainerListener interface
virtual void ShapeAdded(Shape* shape, int32 index) {}
virtual void ShapeRemoved(Shape* shape)
{
fListView->SetCurrentShape(NULL);
}
// ShapeStyleListener
void SetShape(Shape* shape)
{
if (fShape == shape)
return;
if (fShape)
fShape->RemoveListener(this);
fShape = shape;
if (fShape)
fShape->AddListener(this);
}
Shape* CurrentShape() const
{
return fShape;
}
private:
StyleListView* fListView;
Shape* fShape;
};
// #pragma mark -
// constructor
StyleListView::StyleListView(BRect frame,
const char* name,
BMessage* message, BHandler* target)
: SimpleListView(frame, name,
NULL, B_SINGLE_SELECTION_LIST),
fMessage(message),
fStyleContainer(NULL),
fShapeContainer(NULL),
fSelection(NULL),
fCommandStack(NULL),
fCurrentShape(NULL),
fShapeListener(new ShapeStyleListener(this))
{
SetTarget(target);
}
// destructor
StyleListView::~StyleListView()
{
_MakeEmpty();
delete fMessage;
if (fStyleContainer)
fStyleContainer->RemoveListener(this);
if (fShapeContainer)
fShapeContainer->RemoveListener(fShapeListener);
delete fShapeListener;
}
// SelectionChanged
void
StyleListView::SelectionChanged()
{
// NOTE: single selection list
StyleListItem* item
= dynamic_cast<StyleListItem*>(ItemAt(CurrentSelection(0)));
if (item && fMessage) {
BMessage message(*fMessage);
message.AddPointer("style", (void*)item->style);
Invoke(&message);
}
// modify global Selection
if (!fSelection)
return;
if (item)
fSelection->Select(item->style);
else
fSelection->DeselectAll();
}
// MouseDown
void
StyleListView::MouseDown(BPoint where)
{
if (!fCurrentShape) {
SimpleListView::MouseDown(where);
return;
}
bool handled = false;
int32 index = IndexOf(where);
StyleListItem* item = dynamic_cast<StyleListItem*>(ItemAt(index));
if (item) {
BRect itemFrame(ItemFrame(index));
itemFrame.right = itemFrame.left
+ kBorderOffset + kMarkWidth
+ kTextOffset / 2.0;
Style* style = item->style;
if (itemFrame.Contains(where)) {
// set the style on the shape
// TODO: code this command...
// Command* command = new SetStyleToShapeCommand(
// fCurrentShape, style);
// fCommandStack->Perform(command);
fCurrentShape->SetStyle(style);
handled = true;
}
}
if (!handled)
SimpleListView::MouseDown(where);
}
// MessageReceived
void
StyleListView::MessageReceived(BMessage* message)
{
SimpleListView::MessageReceived(message);
}
// MakeDragMessage
void
StyleListView::MakeDragMessage(BMessage* message) const
{
}
// AcceptDragMessage
bool
StyleListView::AcceptDragMessage(const BMessage* message) const
{
return false;
}
// SetDropTargetRect
void
StyleListView::SetDropTargetRect(const BMessage* message, BPoint where)
{
}
// MoveItems
void
StyleListView::MoveItems(BList& items, int32 toIndex)
{
}
// CopyItems
void
StyleListView::CopyItems(BList& items, int32 toIndex)
{
}
// RemoveItemList
void
StyleListView::RemoveItemList(BList& indices)
{
// TODO: allow removing items
}
// CloneItem
BListItem*
StyleListView::CloneItem(int32 index) const
{
if (StyleListItem* item = dynamic_cast<StyleListItem*>(ItemAt(index))) {
return new StyleListItem(item->style,
const_cast<StyleListView*>(this),
fCurrentShape != NULL);
}
return NULL;
}
// #pragma mark -
// StyleAdded
void
StyleListView::StyleAdded(Style* style)
{
// NOTE: we are in the thread that messed with the
// StyleManager, so no need to lock the
// container, when this is changed to asynchronous
// notifications, then it would need to be read-locked!
if (!LockLooper())
return;
// NOTE: shapes are always added at the end
// of the list, so the sorting is synced...
if (_AddStyle(style))
Select(CountItems() - 1);
UnlockLooper();
}
// StyleRemoved
void
StyleListView::StyleRemoved(Style* style)
{
// NOTE: we are in the thread that messed with the
// StyleManager, so no need to lock the
// container, when this is changed to asynchronous
// notifications, then it would need to be read-locked!
if (!LockLooper())
return;
// NOTE: we're only interested in Style objects
_RemoveStyle(style);
UnlockLooper();
}
// #pragma mark -
// SetStyleManager
void
StyleListView::SetStyleManager(StyleManager* container)
{
if (fStyleContainer == container)
return;
// detach from old container
if (fStyleContainer)
fStyleContainer->RemoveListener(this);
_MakeEmpty();
fStyleContainer = container;
if (!fStyleContainer)
return;
fStyleContainer->AddListener(this);
// sync
// if (!fStyleContainer->ReadLock())
// return;
int32 count = fStyleContainer->CountStyles();
for (int32 i = 0; i < count; i++)
_AddStyle(fStyleContainer->StyleAtFast(i));
// fStyleContainer->ReadUnlock();
}
// SetShapeContainer
void
StyleListView::SetShapeContainer(ShapeContainer* container)
{
if (fShapeContainer == container)
return;
// detach from old container
if (fShapeContainer)
fShapeContainer->RemoveListener(fShapeListener);
fShapeContainer = container;
if (fShapeContainer)
fShapeContainer->AddListener(fShapeListener);
}
// SetSelection
void
StyleListView::SetSelection(Selection* selection)
{
fSelection = selection;
}
// SetCurrentShape
void
StyleListView::SetCurrentShape(Shape* shape)
{
if (fCurrentShape == shape)
return;
fCurrentShape = shape;
fShapeListener->SetShape(shape);
_UpdateMarks();
}
// #pragma mark -
// _AddStyle
bool
StyleListView::_AddStyle(Style* style)
{
if (style)
return AddItem(new StyleListItem(style, this, fCurrentShape != NULL));
return false;
}
// _RemoveStyle
bool
StyleListView::_RemoveStyle(Style* style)
{
StyleListItem* item = _ItemForStyle(style);
if (item && RemoveItem(item)) {
delete item;
return true;
}
return false;
}
// _ItemForStyle
StyleListItem*
StyleListView::_ItemForStyle(Style* style) const
{
for (int32 i = 0;
StyleListItem* item = dynamic_cast<StyleListItem*>(ItemAt(i));
i++) {
if (item->style == style)
return item;
}
return NULL;
}
// #pragma mark -
// _UpdateMarks
void
StyleListView::_UpdateMarks()
{
int32 count = CountItems();
if (fCurrentShape) {
// enable display of marks and mark items whoes
// style is contained in fCurrentShape
for (int32 i = 0; i < count; i++) {
StyleListItem* item = dynamic_cast<StyleListItem*>(ItemAt(i));
if (!item)
continue;
item->SetMarkEnabled(true);
item->SetMarked(fCurrentShape->Style() == item->style);
}
} else {
// disable display of marks
for (int32 i = 0; i < count; i++) {
StyleListItem* item = dynamic_cast<StyleListItem*>(ItemAt(i));
if (!item)
continue;
item->SetMarkEnabled(false);
}
}
Invalidate();
}
// _SetStyleMarked
void
StyleListView::_SetStyleMarked(Style* style, bool marked)
{
if (StyleListItem* item = _ItemForStyle(style)) {
item->SetMarked(marked);
}
}
+87
View File
@@ -0,0 +1,87 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <[email protected]>
*/
#ifndef STYLE_LIST_VIEW_H
#define STYLE_LIST_VIEW_H
#include "ListViews.h"
#include "StyleManager.h"
class CommandStack;
class Selection;
class Shape;
class ShapeContainer;
class ShapeListener;
class Style;
class StyleListItem;
class StyleListView : public SimpleListView,
public StyleManagerListener {
public:
StyleListView(BRect frame,
const char* name,
BMessage* selectionMessage = NULL,
BHandler* target = NULL);
virtual ~StyleListView();
// SimpleListView interface
virtual void SelectionChanged();
virtual void MouseDown(BPoint where);
virtual void MessageReceived(BMessage* message);
virtual void MakeDragMessage(BMessage* message) const;
virtual bool AcceptDragMessage(const BMessage* message) const;
virtual void SetDropTargetRect(const BMessage* message,
BPoint where);
virtual void MoveItems(BList& items, int32 toIndex);
virtual void CopyItems(BList& items, int32 toIndex);
virtual void RemoveItemList(BList& indices);
virtual BListItem* CloneItem(int32 atIndex) const;
// StyleManagerListener interface
virtual void StyleAdded(Style* style);
virtual void StyleRemoved(Style* style);
// StyleListView
void SetStyleManager(StyleManager* container);
void SetShapeContainer(ShapeContainer* container);
void SetSelection(Selection* selection);
void SetCurrentShape(Shape* shape);
Shape* CurrentShape() const
{ return fCurrentShape; }
private:
bool _AddStyle(Style* style);
bool _RemoveStyle(Style* style);
StyleListItem* _ItemForStyle(Style* style) const;
friend class ShapeStyleListener;
void _UpdateMarks();
void _SetStyleMarked(Style* style, bool marked);
BMessage* fMessage;
StyleManager* fStyleContainer;
ShapeContainer* fShapeContainer;
Selection* fSelection;
CommandStack* fCommandStack;
Shape* fCurrentShape;
// the style item will be marked that
// is referenced by this shape
ShapeStyleListener* fShapeListener;
};
#endif // STYLE_LIST_VIEW_H
@@ -18,8 +18,8 @@
#include <Window.h>
#include "CommandStack.h"
//#include "MoveTransformersCommand.h"
//#include "RemoveTransformersCommand.h"
#include "MoveTransformersCommand.h"
#include "RemoveTransformersCommand.h"
#include "Transformer.h"
#include "Observer.h"
#include "Selection.h"
@@ -160,29 +160,29 @@ TransformerListView::MakeDragMessage(BMessage* message) const
void
TransformerListView::MoveItems(BList& items, int32 toIndex)
{
// if (!fCommandStack || !fShape)
// return;
//
// int32 count = items.CountItems();
// Transformer** transformers = new (nothrow) Transformer*[count];
// if (!shapes)
// return;
//
// for (int32 i = 0; i < count; i++) {
// TransformerItem* item
// = dynamic_cast<TransformerItem*>((BListItem*)items.ItemAtFast(i));
// transformers[i] = item ? item->transformer : NULL;
// }
//
// MoveTransformersCommand* command
// = new (nothrow) MoveTransformersCommand(fShape,
// transformers, count, toIndex);
// if (!command) {
// delete[] transformers;
// return;
// }
//
// fCommandStack->Perform(command);
if (!fCommandStack || !fShape)
return;
int32 count = items.CountItems();
Transformer** transformers = new (nothrow) Transformer*[count];
if (!transformers)
return;
for (int32 i = 0; i < count; i++) {
TransformerItem* item
= dynamic_cast<TransformerItem*>((BListItem*)items.ItemAtFast(i));
transformers[i] = item ? item->transformer : NULL;
}
MoveTransformersCommand* command
= new (nothrow) MoveTransformersCommand(fShape,
transformers, count, toIndex);
if (!command) {
delete[] transformers;
return;
}
fCommandStack->Perform(command);
}
// CopyItems
@@ -197,16 +197,16 @@ TransformerListView::CopyItems(BList& items, int32 toIndex)
void
TransformerListView::RemoveItemList(BList& indexList)
{
// if (!fCommandStack || !fShape)
// return;
//
// int32 count = indexList.CountItems();
// const int32* indices = (int32*)indexList.Items();
//
// RemoveTransformersCommand* command
// = new (nothrow) RemoveTransformersCommand(fShape,
// indices, count);
// fCommandStack->Perform(command);
if (!fCommandStack || !fShape)
return;
int32 count = indexList.CountItems();
const int32* indices = (int32*)indexList.Items();
RemoveTransformersCommand* command
= new (nothrow) RemoveTransformersCommand(fShape,
indices, count);
fCommandStack->Perform(command);
}
// CloneItem
@@ -254,6 +254,13 @@ TransformerListView::TransformerRemoved(Transformer* transformer)
UnlockLooper();
}
// StyleChanged
void
TransformerListView::StyleChanged(Style* oldStyle, Style* newStyle)
{
// we don't care
}
// #pragma mark -
// SetShape
@@ -42,16 +42,21 @@ class TransformerListView : public SimpleListView,
int32 index);
virtual void TransformerRemoved(Transformer* transformer);
virtual void StyleChanged(Style* oldStyle, Style* newStyle);
// TransformerListView
void SetShape(Shape* shape);
void SetSelection(Selection* selection);
void SetCommandStack(CommandStack* stack);
private:
bool _AddTransformer(Transformer* transformer, int32 index);
bool _RemoveTransformer(Transformer* transformer);
bool _AddTransformer(
Transformer* transformer, int32 index);
bool _RemoveTransformer(
Transformer* transformer);
TransformerItem* _ItemForTransformer(Transformer* transformer) const;
TransformerItem* _ItemForTransformer(
Transformer* transformer) const;
BMessage* fMessage;
+19 -1
View File
@@ -177,6 +177,8 @@ Shape::InitCheck() const
return fPaths ? B_OK : B_NO_MEMORY;
}
// #pragma mark -
// SetStyle
void
Shape::SetStyle(::Style* style)
@@ -189,6 +191,7 @@ Shape::SetStyle(::Style* style)
fStyle->Release();
}
::Style* oldStyle = fStyle;
fStyle = style;
if (fStyle) {
@@ -196,7 +199,7 @@ Shape::SetStyle(::Style* style)
fStyle->AddObserver(this);
}
_NotifyRerender();
_NotifyStyleChanged(oldStyle, fStyle);
}
// #pragma mark -
@@ -373,6 +376,21 @@ Shape::_NotifyTransformerRemoved(Transformer* transformer) const
_NotifyRerender();
}
// _NotifyStyleChanged
void
Shape::_NotifyStyleChanged(::Style* oldStyle, ::Style* newStyle) const
{
BList listeners(fListeners);
int32 count = listeners.CountItems();
for (int32 i = 0; i < count; i++) {
ShapeListener* listener
= (ShapeListener*)listeners.ItemAtFast(i);
listener->StyleChanged(oldStyle, newStyle);
}
// TODO: merge Observable and ShapeListener interface
_NotifyRerender();
}
// _NotifyRerender
void
Shape::_NotifyRerender() const
+7
View File
@@ -13,6 +13,7 @@
class Style;
// TODO: merge Observer and ShapeListener interface
// ie add "AppearanceChanged(Shape* shape)"
class ShapeListener {
public:
ShapeListener();
@@ -21,6 +22,9 @@ class ShapeListener {
virtual void TransformerAdded(Transformer* t,
int32 index) = 0;
virtual void TransformerRemoved(Transformer* t) = 0;
virtual void StyleChanged(::Style* oldStyle,
::Style* newStyle) = 0;
};
class Shape : public IconObject,
@@ -84,6 +88,9 @@ class Shape : public IconObject,
int32 index) const;
void _NotifyTransformerRemoved(Transformer* t) const;
void _NotifyStyleChanged(::Style* oldStyle,
::Style* newStyle) const;
void _NotifyRerender() const;
PathContainer* fPaths;
@@ -11,6 +11,8 @@
#include "Command.h"
// TODO: make a templated "move items" command?
class Shape;
class ShapeContainer;
@@ -0,0 +1,161 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "MoveTransformersCommand.h"
#include <new>
#include <stdio.h>
#include "Shape.h"
#include "Transformer.h"
using std::nothrow;
// constructor
MoveTransformersCommand::MoveTransformersCommand(Shape* container,
Transformer** transformers,
int32 count,
int32 toIndex)
: Command(),
fContainer(container),
fTransformers(transformers),
fIndices(count > 0 ? new (nothrow) int32[count] : NULL),
fToIndex(toIndex),
fCount(count)
{
if (!fContainer || !fTransformers || !fIndices)
return;
// init original shape indices and
// adjust toIndex compensating for items that
// are removed before that index
int32 itemsBeforeIndex = 0;
for (int32 i = 0; i < fCount; i++) {
fIndices[i] = fContainer->IndexOf(fTransformers[i]);
if (fIndices[i] >= 0 && fIndices[i] < fToIndex)
itemsBeforeIndex++;
}
fToIndex -= itemsBeforeIndex;
}
// destructor
MoveTransformersCommand::~MoveTransformersCommand()
{
delete[] fTransformers;
delete[] fIndices;
}
// InitCheck
status_t
MoveTransformersCommand::InitCheck()
{
if (!fContainer || !fTransformers || !fIndices)
return B_NO_INIT;
// analyse the move, don't return B_OK in case
// the container state does not change...
int32 index = fIndices[0];
// NOTE: fIndices == NULL if fCount < 1
if (index != fToIndex) {
// a change is guaranteed
return B_OK;
}
// the insertion index is the same as the index of the first
// moved item, a change only occures if the indices of the
// moved items is not contiguous
bool isContiguous = true;
for (int32 i = 1; i < fCount; i++) {
if (fIndices[i] != index + 1) {
isContiguous = false;
break;
}
index = fIndices[i];
}
if (isContiguous) {
// the container state will not change because of the move
return B_ERROR;
}
return B_OK;
}
// Perform
status_t
MoveTransformersCommand::Perform()
{
status_t ret = B_OK;
// remove shapes from container
for (int32 i = 0; i < fCount; i++) {
if (fTransformers[i]
&& !fContainer->RemoveTransformer(fTransformers[i])) {
ret = B_ERROR;
break;
}
}
if (ret < B_OK)
return ret;
// add shapes to container at the insertion index
int32 index = fToIndex;
for (int32 i = 0; i < fCount; i++) {
if (fTransformers[i]
&& !fContainer->AddTransformer(fTransformers[i], index++)) {
ret = B_ERROR;
break;
}
}
return ret;
}
// Undo
status_t
MoveTransformersCommand::Undo()
{
status_t ret = B_OK;
// remove shapes from container
for (int32 i = 0; i < fCount; i++) {
if (fTransformers[i]
&& !fContainer->RemoveTransformer(fTransformers[i])) {
ret = B_ERROR;
break;
}
}
if (ret < B_OK)
return ret;
// add shapes to container at remembered indices
for (int32 i = 0; i < fCount; i++) {
if (fTransformers[i]
&& !fContainer->AddTransformer(fTransformers[i], fIndices[i])) {
ret = B_ERROR;
break;
}
}
return ret;
}
// GetName
void
MoveTransformersCommand::GetName(BString& name)
{
// if (fCount > 1)
// name << _GetString(MOVE_TRANSFORMERS, "Move Transformers");
// else
// name << _GetString(MOVE_TRANSFORMER, "Move Transformer");
if (fCount > 1)
name << "Move Transformers";
else
name << "Move Transformer";
}
@@ -0,0 +1,43 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef MOVE_TRANSFORMERS_COMMAND_H
#define MOVE_TRANSFORMERS_COMMAND_H
#include "Command.h"
// TODO: make a templated "move items" command?
class Shape;
class Transformer;
class MoveTransformersCommand : public Command {
public:
MoveTransformersCommand(
Shape* shape,
Transformer** transformers,
int32 count,
int32 toIndex);
virtual ~MoveTransformersCommand();
virtual status_t InitCheck();
virtual status_t Perform();
virtual status_t Undo();
virtual void GetName(BString& name);
private:
Shape* fContainer;
Transformer** fTransformers;
int32* fIndices;
int32 fToIndex;
int32 fCount;
};
#endif // MOVE_TRANSFORMERS_COMMAND_H
@@ -0,0 +1,107 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "RemoveTransformersCommand.h"
#include <new>
#include <stdio.h>
#include <string.h>
#include "ShapeContainer.h"
#include "Shape.h"
using std::nothrow;
// constructor
RemoveTransformersCommand::RemoveTransformersCommand(Shape* container,
const int32* indices,
int32 count)
: Command(),
fContainer(container),
fTransformers(count > 0 ? new (nothrow) Transformer*[count] : NULL),
fIndices(count > 0 ? new (nothrow) int32[count] : NULL),
fCount(count),
fTransformersRemoved(false)
{
if (!fContainer || !fTransformers || !fIndices)
return;
memcpy(fIndices, indices, sizeof(int32) * fCount);
for (int32 i = 0; i < fCount; i++)
fTransformers[i] = fContainer->TransformerAt(fIndices[i]);
}
// destructor
RemoveTransformersCommand::~RemoveTransformersCommand()
{
if (fTransformersRemoved && fTransformers) {
for (int32 i = 0; i < fCount; i++)
delete fTransformers[i];
}
delete[] fTransformers;
delete[] fIndices;
}
// InitCheck
status_t
RemoveTransformersCommand::InitCheck()
{
return fContainer && fTransformers && fIndices ? B_OK : B_NO_INIT;
}
// Perform
status_t
RemoveTransformersCommand::Perform()
{
status_t ret = B_OK;
// remove shapes from container
for (int32 i = 0; i < fCount; i++) {
if (fTransformers[i]
&& !fContainer->RemoveTransformer(fTransformers[i])) {
ret = B_ERROR;
break;
}
}
fTransformersRemoved = true;
return ret;
}
// Undo
status_t
RemoveTransformersCommand::Undo()
{
status_t ret = B_OK;
// add shapes to container at remembered indices
for (int32 i = 0; i < fCount; i++) {
if (fTransformers[i]
&& !fContainer->AddTransformer(fTransformers[i], fIndices[i])) {
ret = B_ERROR;
break;
}
}
fTransformersRemoved = false;
return ret;
}
// GetName
void
RemoveTransformersCommand::GetName(BString& name)
{
// if (fCount > 1)
// name << _GetString(MOVE_TRANSFORMERS, "Move Transformers");
// else
// name << _GetString(MOVE_TRANSFORMER, "Move Transformer");
if (fCount > 1)
name << "Remove Transformers";
else
name << "Remove Transformer";
}
@@ -0,0 +1,42 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef REMOVE_TRANSFORMERS_COMMAND_H
#define REMOVE_TRANSFORMERS_COMMAND_H
#include "Command.h"
class Shape;
class Transformer;
// TODO: make a templated "remove items" command?
class RemoveTransformersCommand : public Command {
public:
RemoveTransformersCommand(
Shape* container,
const int32* indices,
int32 count);
virtual ~RemoveTransformersCommand();
virtual status_t InitCheck();
virtual status_t Perform();
virtual status_t Undo();
virtual void GetName(BString& name);
private:
Shape* fContainer;
Transformer** fTransformers;
int32* fIndices;
int32 fCount;
bool fTransformersRemoved;
};
#endif // REMOVE_TRANSFORMERS_COMMAND_H