* fixed memory leaks and display bugs
* VectorPath objects were released one two many times by the Shape PathContainers (they don't acquire when a path is added, the Shape does that for them) the PathContainer of the Icon needs to release though, as it "owns" the paths * put the Selection class used by PathManipulator into the PathManipulator namespace, since the compiler seemed to use the wrong destructor (the one from the generic Selection class) * uses a better mechanism to track and render changed parts of icon git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17903 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -21,7 +21,9 @@ CanvasView::CanvasView(BRect frame)
|
|||||||
: StateView(frame, "canvas view", B_FOLLOW_ALL,
|
: StateView(frame, "canvas view", B_FOLLOW_ALL,
|
||||||
B_WILL_DRAW | B_FRAME_EVENTS),
|
B_WILL_DRAW | B_FRAME_EVENTS),
|
||||||
fBitmap(new BBitmap(BRect(0, 0, 63, 63), 0, B_RGB32)),
|
fBitmap(new BBitmap(BRect(0, 0, 63, 63), 0, B_RGB32)),
|
||||||
|
fIcon(NULL),
|
||||||
fRenderer(new IconRenderer(fBitmap)),
|
fRenderer(new IconRenderer(fBitmap)),
|
||||||
|
fDirtyIconArea(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN),
|
||||||
|
|
||||||
fCanvasOrigin(50.0, 50.0),
|
fCanvasOrigin(50.0, 50.0),
|
||||||
fZoomLevel(8.0),
|
fZoomLevel(8.0),
|
||||||
@@ -37,6 +39,7 @@ CanvasView::CanvasView(BRect frame)
|
|||||||
// destructor
|
// destructor
|
||||||
CanvasView::~CanvasView()
|
CanvasView::~CanvasView()
|
||||||
{
|
{
|
||||||
|
SetIcon(NULL);
|
||||||
delete fRenderer;
|
delete fRenderer;
|
||||||
delete fBitmap;
|
delete fBitmap;
|
||||||
|
|
||||||
@@ -101,13 +104,40 @@ CanvasView::Draw(BRect updateRect)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
// AreaInvalidated
|
||||||
|
void
|
||||||
|
CanvasView::AreaInvalidated(const BRect& area)
|
||||||
|
{
|
||||||
|
if (fDirtyIconArea.Contains(area))
|
||||||
|
return;
|
||||||
|
|
||||||
|
fDirtyIconArea = fDirtyIconArea | area;
|
||||||
|
|
||||||
|
BRect viewArea(area);
|
||||||
|
ConvertFromCanvas(&viewArea);
|
||||||
|
Invalidate(viewArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
// SetIcon
|
// SetIcon
|
||||||
void
|
void
|
||||||
CanvasView::SetIcon(Icon* icon)
|
CanvasView::SetIcon(Icon* icon)
|
||||||
{
|
{
|
||||||
|
if (fIcon == icon)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fIcon)
|
||||||
|
fIcon->RemoveListener(this);
|
||||||
|
|
||||||
|
fIcon = icon;
|
||||||
fRenderer->SetIcon(icon);
|
fRenderer->SetIcon(icon);
|
||||||
|
|
||||||
|
if (fIcon)
|
||||||
|
fIcon->AddListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConvertFromCanvas
|
// ConvertFromCanvas
|
||||||
@@ -234,9 +264,10 @@ CanvasView::_FreeBackBitmap()
|
|||||||
void
|
void
|
||||||
CanvasView::_DrawInto(BView* view, BRect updateRect)
|
CanvasView::_DrawInto(BView* view, BRect updateRect)
|
||||||
{
|
{
|
||||||
// TODO: don't render here, use some
|
if (fDirtyIconArea.IsValid()) {
|
||||||
// listener technique on the shapes instead...
|
fRenderer->Render(fDirtyIconArea);
|
||||||
fRenderer->Render();
|
fDirtyIconArea.Set(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN);
|
||||||
|
}
|
||||||
|
|
||||||
// icon
|
// icon
|
||||||
BRect canvas(_CanvasRect());
|
BRect canvas(_CanvasRect());
|
||||||
|
|||||||
@@ -9,13 +9,14 @@
|
|||||||
#ifndef CANVAS_VIEW_H
|
#ifndef CANVAS_VIEW_H
|
||||||
#define CANVAS_VIEW_H
|
#define CANVAS_VIEW_H
|
||||||
|
|
||||||
|
#include "Icon.h"
|
||||||
#include "StateView.h"
|
#include "StateView.h"
|
||||||
|
|
||||||
class BBitmap;
|
class BBitmap;
|
||||||
class Icon;
|
|
||||||
class IconRenderer;
|
class IconRenderer;
|
||||||
|
|
||||||
class CanvasView : public StateView {
|
class CanvasView : public StateView,
|
||||||
|
public IconListener {
|
||||||
public:
|
public:
|
||||||
CanvasView(BRect frame);
|
CanvasView(BRect frame);
|
||||||
virtual ~CanvasView();
|
virtual ~CanvasView();
|
||||||
@@ -25,6 +26,9 @@ class CanvasView : public StateView {
|
|||||||
virtual void FrameResized(float width, float height);
|
virtual void FrameResized(float width, float height);
|
||||||
virtual void Draw(BRect updateRect);
|
virtual void Draw(BRect updateRect);
|
||||||
|
|
||||||
|
// IconListener interface
|
||||||
|
virtual void AreaInvalidated(const BRect& area);
|
||||||
|
|
||||||
// CanvasView
|
// CanvasView
|
||||||
void SetIcon(Icon* icon);
|
void SetIcon(Icon* icon);
|
||||||
|
|
||||||
@@ -52,7 +56,9 @@ class CanvasView : public StateView {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
BBitmap* fBitmap;
|
BBitmap* fBitmap;
|
||||||
|
Icon* fIcon;
|
||||||
IconRenderer* fRenderer;
|
IconRenderer* fRenderer;
|
||||||
|
BRect fDirtyIconArea;
|
||||||
|
|
||||||
BPoint fCanvasOrigin;
|
BPoint fCanvasOrigin;
|
||||||
float fZoomLevel;
|
float fZoomLevel;
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ IconEditorApp::IconEditorApp()
|
|||||||
// destructor
|
// destructor
|
||||||
IconEditorApp::~IconEditorApp()
|
IconEditorApp::~IconEditorApp()
|
||||||
{
|
{
|
||||||
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ MainWindow::MainWindow(IconEditorApp* app, Document* document)
|
|||||||
// destructor
|
// destructor
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
{
|
{
|
||||||
|
delete fState;
|
||||||
}
|
}
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
@@ -139,6 +140,7 @@ MainWindow::_Init()
|
|||||||
|
|
||||||
PathManipulator* pathManipulator = new PathManipulator(path);
|
PathManipulator* pathManipulator = new PathManipulator(path);
|
||||||
state->AddManipulator(pathManipulator);
|
state->AddManipulator(pathManipulator);
|
||||||
|
fState = state;
|
||||||
// ----
|
// ----
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
class CanvasView;
|
class CanvasView;
|
||||||
class Document;
|
class Document;
|
||||||
class IconEditorApp;
|
class IconEditorApp;
|
||||||
|
class ViewState;
|
||||||
|
|
||||||
class MainWindow : public BWindow {
|
class MainWindow : public BWindow {
|
||||||
public:
|
public:
|
||||||
@@ -33,6 +34,8 @@ class MainWindow : public BWindow {
|
|||||||
Document* fDocument;
|
Document* fDocument;
|
||||||
|
|
||||||
CanvasView* fCanvasView;
|
CanvasView* fCanvasView;
|
||||||
|
// TODO: for testing only...
|
||||||
|
ViewState* fState;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAIN_WINDOW_H
|
#endif // MAIN_WINDOW_H
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ Document::Document(const char* name)
|
|||||||
// destructor
|
// destructor
|
||||||
Document::~Document()
|
Document::~Document()
|
||||||
{
|
{
|
||||||
|
delete fIcon;
|
||||||
delete fCommandStack;
|
delete fCommandStack;
|
||||||
delete fSelection;
|
delete fSelection;
|
||||||
delete fRef;
|
delete fRef;
|
||||||
|
|||||||
@@ -11,21 +11,101 @@
|
|||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
#include "PathContainer.h"
|
#include "PathContainer.h"
|
||||||
#include "ShapeContainer.h"
|
#include "Shape.h"
|
||||||
|
|
||||||
using std::nothrow;
|
using std::nothrow;
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
Icon::Icon()
|
IconListener::IconListener()
|
||||||
: fPaths(new (nothrow) PathContainer()),
|
|
||||||
fShapes(new (nothrow) ShapeContainer())
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
IconListener::~IconListener()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
Icon::Icon()
|
||||||
|
: fPaths(new (nothrow) PathContainer(true)),
|
||||||
|
fShapes(new (nothrow) ShapeContainer()),
|
||||||
|
fListeners(2)
|
||||||
|
{
|
||||||
|
if (fShapes)
|
||||||
|
fShapes->AddListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
Icon::~Icon()
|
Icon::~Icon()
|
||||||
{
|
{
|
||||||
delete fShapes;
|
if (fShapes) {
|
||||||
|
fShapes->MakeEmpty();
|
||||||
|
fShapes->RemoveListener(this);
|
||||||
|
delete fShapes;
|
||||||
|
}
|
||||||
delete fPaths;
|
delete fPaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ShapeAdded
|
||||||
|
void
|
||||||
|
Icon::ShapeAdded(Shape* shape)
|
||||||
|
{
|
||||||
|
shape->AddObserver(this);
|
||||||
|
_NotifyAreaInvalidated(shape->Bounds());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShapeRemoved
|
||||||
|
void
|
||||||
|
Icon::ShapeRemoved(Shape* shape)
|
||||||
|
{
|
||||||
|
shape->RemoveObserver(this);
|
||||||
|
_NotifyAreaInvalidated(shape->Bounds());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ObjectChanged
|
||||||
|
void
|
||||||
|
Icon::ObjectChanged(const Observable* object)
|
||||||
|
{
|
||||||
|
const Shape* shape = dynamic_cast<const Shape*>(object);
|
||||||
|
if (shape) {
|
||||||
|
BRect area = shape->LastBounds();
|
||||||
|
area = area | shape->Bounds(true);
|
||||||
|
area.InsetBy(-1, -1);
|
||||||
|
_NotifyAreaInvalidated(area);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddListener
|
||||||
|
bool
|
||||||
|
Icon::AddListener(IconListener* listener)
|
||||||
|
{
|
||||||
|
if (listener && !fListeners.HasItem((void*)listener))
|
||||||
|
return fListeners.AddItem((void*)listener);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveListener
|
||||||
|
bool
|
||||||
|
Icon::RemoveListener(IconListener* listener)
|
||||||
|
{
|
||||||
|
return fListeners.RemoveItem((void*)listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
// _NotifyShapeRemoved
|
||||||
|
void
|
||||||
|
Icon::_NotifyAreaInvalidated(const BRect& area) const
|
||||||
|
{
|
||||||
|
BList listeners(fListeners);
|
||||||
|
int32 count = listeners.CountItems();
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
IconListener* listener
|
||||||
|
= (IconListener*)listeners.ItemAtFast(i);
|
||||||
|
listener->AreaInvalidated(area);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,22 +9,51 @@
|
|||||||
#ifndef ICON_H
|
#ifndef ICON_H
|
||||||
#define ICON_H
|
#define ICON_H
|
||||||
|
|
||||||
class PathContainer;
|
#include <List.h>
|
||||||
class ShapeContainer;
|
|
||||||
|
|
||||||
class Icon {
|
#include "Observer.h"
|
||||||
|
#include "ShapeContainer.h"
|
||||||
|
|
||||||
|
class PathContainer;
|
||||||
|
|
||||||
|
class IconListener {
|
||||||
|
public:
|
||||||
|
IconListener();
|
||||||
|
virtual ~IconListener();
|
||||||
|
|
||||||
|
virtual void AreaInvalidated(const BRect& area) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Icon : public ShapeContainerListener,
|
||||||
|
public Observer {
|
||||||
public:
|
public:
|
||||||
Icon();
|
Icon();
|
||||||
virtual ~Icon();
|
virtual ~Icon();
|
||||||
|
|
||||||
|
// ShapeContainerListener interface
|
||||||
|
virtual void ShapeAdded(Shape* shape);
|
||||||
|
virtual void ShapeRemoved(Shape* shape);
|
||||||
|
|
||||||
|
// Observer interface
|
||||||
|
virtual void ObjectChanged(const Observable* object);
|
||||||
|
|
||||||
|
// Icon
|
||||||
PathContainer* Paths() const
|
PathContainer* Paths() const
|
||||||
{ return fPaths; }
|
{ return fPaths; }
|
||||||
ShapeContainer* Shapes() const
|
ShapeContainer* Shapes() const
|
||||||
{ return fShapes; }
|
{ return fShapes; }
|
||||||
|
|
||||||
|
bool AddListener(IconListener* listener);
|
||||||
|
bool RemoveListener(IconListener* listener);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void _NotifyAreaInvalidated(
|
||||||
|
const BRect& area) const;
|
||||||
|
|
||||||
PathContainer* fPaths;
|
PathContainer* fPaths;
|
||||||
ShapeContainer* fShapes;
|
ShapeContainer* fShapes;
|
||||||
|
|
||||||
|
BList fListeners;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ICON_H
|
#endif // ICON_H
|
||||||
|
|||||||
@@ -28,9 +28,10 @@ PathContainerListener::~PathContainerListener()
|
|||||||
|
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
PathContainer::PathContainer()
|
PathContainer::PathContainer(bool ownsPaths)
|
||||||
: fPaths(16),
|
: fPaths(16),
|
||||||
fListeners(2)
|
fListeners(2),
|
||||||
|
fOwnsPaths(ownsPaths)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +157,8 @@ PathContainer::_MakeEmpty()
|
|||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count; i++) {
|
||||||
VectorPath* path = PathAtFast(i);
|
VectorPath* path = PathAtFast(i);
|
||||||
_NotifyPathRemoved(path);
|
_NotifyPathRemoved(path);
|
||||||
path->Release();
|
if (fOwnsPaths)
|
||||||
|
path->Release();
|
||||||
}
|
}
|
||||||
fPaths.MakeEmpty();
|
fPaths.MakeEmpty();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class PathContainerListener {
|
|||||||
|
|
||||||
class PathContainer {
|
class PathContainer {
|
||||||
public:
|
public:
|
||||||
PathContainer();
|
PathContainer(bool ownsPaths);
|
||||||
virtual ~PathContainer();
|
virtual ~PathContainer();
|
||||||
|
|
||||||
bool AddPath(VectorPath* path);
|
bool AddPath(VectorPath* path);
|
||||||
@@ -50,6 +50,7 @@ class PathContainer {
|
|||||||
|
|
||||||
BList fPaths;
|
BList fPaths;
|
||||||
BList fListeners;
|
BList fListeners;
|
||||||
|
bool fOwnsPaths;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PATH_CONTAINER_H
|
#endif // PATH_CONTAINER_H
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ string_for_mode(uint32 mode)
|
|||||||
return "<unknown mode>";
|
return "<unknown mode>";
|
||||||
}
|
}
|
||||||
|
|
||||||
class Selection : protected BList
|
class PathManipulator::Selection : protected BList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline Selection(int32 count = 20)
|
inline Selection(int32 count = 20)
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ class CanvasView;
|
|||||||
class ChangePointCommand;
|
class ChangePointCommand;
|
||||||
class UndoStack;
|
class UndoStack;
|
||||||
class InsertPointCommand;
|
class InsertPointCommand;
|
||||||
class Selection;
|
|
||||||
class VectorPath;
|
class VectorPath;
|
||||||
|
|
||||||
//class PathSelection {
|
//class PathSelection {
|
||||||
@@ -146,6 +145,7 @@ class PathManipulator : public Manipulator {
|
|||||||
InsertPointCommand* fInsertPointCommand;
|
InsertPointCommand* fInsertPointCommand;
|
||||||
AddPointCommand* fAddPointCommand;
|
AddPointCommand* fAddPointCommand;
|
||||||
|
|
||||||
|
class Selection;
|
||||||
Selection* fSelection;
|
Selection* fSelection;
|
||||||
Selection* fOldSelection;
|
Selection* fOldSelection;
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "agg_bounding_rect.h"
|
||||||
|
|
||||||
#include "Style.h"
|
#include "Style.h"
|
||||||
#include "VectorPath.h"
|
#include "VectorPath.h"
|
||||||
@@ -13,10 +16,14 @@ Shape::Shape(::Style* style)
|
|||||||
: Observable(),
|
: Observable(),
|
||||||
Referenceable(),
|
Referenceable(),
|
||||||
PathContainerListener(),
|
PathContainerListener(),
|
||||||
fPaths(new (nothrow) PathContainer()),
|
|
||||||
|
fPaths(new (nothrow) PathContainer(false)),
|
||||||
fStyle(style),
|
fStyle(style),
|
||||||
|
|
||||||
fPathSource(fPaths),
|
fPathSource(fPaths),
|
||||||
fTransformers(4)
|
fTransformers(4),
|
||||||
|
|
||||||
|
fLastBounds(0, 0, -1, -1)
|
||||||
{
|
{
|
||||||
if (fPaths)
|
if (fPaths)
|
||||||
fPaths->AddListener(this);
|
fPaths->AddListener(this);
|
||||||
@@ -45,17 +52,31 @@ void
|
|||||||
Shape::PathAdded(VectorPath* path)
|
Shape::PathAdded(VectorPath* path)
|
||||||
{
|
{
|
||||||
path->Acquire();
|
path->Acquire();
|
||||||
|
path->AddObserver(this);
|
||||||
|
Notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
// PathRemoved
|
// PathRemoved
|
||||||
void
|
void
|
||||||
Shape::PathRemoved(VectorPath* path)
|
Shape::PathRemoved(VectorPath* path)
|
||||||
{
|
{
|
||||||
|
path->RemoveObserver(this);
|
||||||
|
Notify();
|
||||||
path->Release();
|
path->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
// ObjectChanged
|
||||||
|
void
|
||||||
|
Shape::ObjectChanged(const Observable* object)
|
||||||
|
{
|
||||||
|
// simply pass on the event for now
|
||||||
|
Notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
// InitCheck
|
// InitCheck
|
||||||
status_t
|
status_t
|
||||||
Shape::InitCheck() const
|
Shape::InitCheck() const
|
||||||
@@ -83,14 +104,26 @@ Shape::SetStyle(::Style* style)
|
|||||||
|
|
||||||
// Bounds
|
// Bounds
|
||||||
BRect
|
BRect
|
||||||
Shape::Bounds() const
|
Shape::Bounds(bool updateLast) const
|
||||||
{
|
{
|
||||||
// TODO: incorrect - use VertexSource instead!!
|
// TODO: what about sub-paths?!?
|
||||||
BRect bounds(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN);
|
// the problem is that the path ids are
|
||||||
|
// nowhere stored while converting VectorPath
|
||||||
|
// to agg::path_storage, but it is also unclear
|
||||||
|
// if those would mean anything later on in
|
||||||
|
// the Transformer pipeline
|
||||||
|
uint32 pathID[1];
|
||||||
|
pathID[0] = 0;
|
||||||
|
double left, top, right, bottom;
|
||||||
|
|
||||||
int32 count = fPaths->CountPaths();
|
::VertexSource& source = const_cast<Shape*>(this)->VertexSource();
|
||||||
for (int32 i = 0; i < count; i++)
|
agg::bounding_rect(source, pathID, 0, 1,
|
||||||
bounds = bounds | fPaths->PathAtFast(i)->Bounds();
|
&left, &top, &right, &bottom);
|
||||||
|
|
||||||
|
BRect bounds(left, top, right, bottom);
|
||||||
|
|
||||||
|
if (updateLast)
|
||||||
|
fLastBounds = bounds;
|
||||||
|
|
||||||
return bounds;
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <Rect.h>
|
#include <Rect.h>
|
||||||
|
|
||||||
#include "Observable.h"
|
#include "Observable.h"
|
||||||
|
#include "Observer.h"
|
||||||
#include "PathContainer.h"
|
#include "PathContainer.h"
|
||||||
#include "PathSource.h"
|
#include "PathSource.h"
|
||||||
#include "Referenceable.h"
|
#include "Referenceable.h"
|
||||||
@@ -12,6 +13,7 @@
|
|||||||
class Style;
|
class Style;
|
||||||
|
|
||||||
class Shape : public Observable,
|
class Shape : public Observable,
|
||||||
|
public Observer, // observing all the paths
|
||||||
public Referenceable,
|
public Referenceable,
|
||||||
public PathContainerListener {
|
public PathContainerListener {
|
||||||
public:
|
public:
|
||||||
@@ -22,6 +24,9 @@ class Shape : public Observable,
|
|||||||
virtual void PathAdded(VectorPath* path);
|
virtual void PathAdded(VectorPath* path);
|
||||||
virtual void PathRemoved(VectorPath* path);
|
virtual void PathRemoved(VectorPath* path);
|
||||||
|
|
||||||
|
// Observer interface
|
||||||
|
virtual void ObjectChanged(const Observable* object);
|
||||||
|
|
||||||
// Shape
|
// Shape
|
||||||
status_t InitCheck() const;
|
status_t InitCheck() const;
|
||||||
|
|
||||||
@@ -32,7 +37,9 @@ class Shape : public Observable,
|
|||||||
inline ::Style* Style() const
|
inline ::Style* Style() const
|
||||||
{ return fStyle; }
|
{ return fStyle; }
|
||||||
|
|
||||||
BRect Bounds() const;
|
inline BRect LastBounds() const
|
||||||
|
{ return fLastBounds; }
|
||||||
|
BRect Bounds(bool updateLast = false) const;
|
||||||
|
|
||||||
::VertexSource& VertexSource();
|
::VertexSource& VertexSource();
|
||||||
bool AppendTransformer(
|
bool AppendTransformer(
|
||||||
@@ -44,6 +51,8 @@ class Shape : public Observable,
|
|||||||
|
|
||||||
PathSource fPathSource;
|
PathSource fPathSource;
|
||||||
BList fTransformers;
|
BList fTransformers;
|
||||||
|
|
||||||
|
mutable BRect fLastBounds;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHAPE_H
|
#endif // SHAPE_H
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ bool
|
|||||||
ShapeContainer::AddListener(ShapeContainerListener* listener)
|
ShapeContainer::AddListener(ShapeContainerListener* listener)
|
||||||
{
|
{
|
||||||
if (listener && !fListeners.HasItem((void*)listener))
|
if (listener && !fListeners.HasItem((void*)listener))
|
||||||
return fListeners.AddItem(listener);
|
return fListeners.AddItem((void*)listener);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ ShapeContainer::AddListener(ShapeContainerListener* listener)
|
|||||||
bool
|
bool
|
||||||
ShapeContainer::RemoveListener(ShapeContainerListener* listener)
|
ShapeContainer::RemoveListener(ShapeContainerListener* listener)
|
||||||
{
|
{
|
||||||
return fListeners.RemoveItem(listener);
|
return fListeners.RemoveItem((void*)listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|||||||
Reference in New Issue
Block a user