* 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
192 lines
3.1 KiB
C++
192 lines
3.1 KiB
C++
/*
|
|
* Copyright 2006, Haiku.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Authors:
|
|
* Stephan Aßmus <[email protected]>
|
|
*/
|
|
|
|
#include "ShapeContainer.h"
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include <OS.h>
|
|
|
|
#include "Shape.h"
|
|
|
|
// constructor
|
|
ShapeContainerListener::ShapeContainerListener()
|
|
{
|
|
}
|
|
|
|
// destructor
|
|
ShapeContainerListener::~ShapeContainerListener()
|
|
{
|
|
}
|
|
|
|
|
|
|
|
// constructor
|
|
ShapeContainer::ShapeContainer()
|
|
: fShapes(16),
|
|
fListeners(2)
|
|
{
|
|
}
|
|
|
|
// destructor
|
|
ShapeContainer::~ShapeContainer()
|
|
{
|
|
int32 count = fListeners.CountItems();
|
|
if (count > 0) {
|
|
debugger("~ShapeContainer() - there are still"
|
|
"listeners attached\n");
|
|
}
|
|
_MakeEmpty();
|
|
}
|
|
|
|
// #pragma mark -
|
|
|
|
// AddShape
|
|
bool
|
|
ShapeContainer::AddShape(Shape* shape)
|
|
{
|
|
if (!shape)
|
|
return false;
|
|
|
|
// prevent adding the same shape twice
|
|
if (HasShape(shape))
|
|
return false;
|
|
|
|
if (fShapes.AddItem((void*)shape)) {
|
|
_NotifyShapeAdded(shape);
|
|
return true;
|
|
}
|
|
|
|
fprintf(stderr, "ShapeContainer::AddShape() - out of memory!\n");
|
|
return false;
|
|
}
|
|
|
|
// RemoveShape
|
|
bool
|
|
ShapeContainer::RemoveShape(Shape* shape)
|
|
{
|
|
if (fShapes.RemoveItem((void*)shape)) {
|
|
_NotifyShapeRemoved(shape);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// RemoveShape
|
|
Shape*
|
|
ShapeContainer::RemoveShape(int32 index)
|
|
{
|
|
Shape* shape = (Shape*)fShapes.RemoveItem(index);
|
|
if (shape) {
|
|
_NotifyShapeRemoved(shape);
|
|
}
|
|
|
|
return shape;
|
|
}
|
|
|
|
// MakeEmpty
|
|
void
|
|
ShapeContainer::MakeEmpty()
|
|
{
|
|
_MakeEmpty();
|
|
}
|
|
|
|
// #pragma mark -
|
|
|
|
// CountShapes
|
|
int32
|
|
ShapeContainer::CountShapes() const
|
|
{
|
|
return fShapes.CountItems();
|
|
}
|
|
|
|
// HasShape
|
|
bool
|
|
ShapeContainer::HasShape(Shape* shape) const
|
|
{
|
|
return fShapes.HasItem((void*)shape);
|
|
}
|
|
|
|
// ShapeAt
|
|
Shape*
|
|
ShapeContainer::ShapeAt(int32 index) const
|
|
{
|
|
return (Shape*)fShapes.ItemAt(index);
|
|
}
|
|
|
|
// ShapeAtFast
|
|
Shape*
|
|
ShapeContainer::ShapeAtFast(int32 index) const
|
|
{
|
|
return (Shape*)fShapes.ItemAtFast(index);
|
|
}
|
|
|
|
// #pragma mark -
|
|
|
|
// AddListener
|
|
bool
|
|
ShapeContainer::AddListener(ShapeContainerListener* listener)
|
|
{
|
|
if (listener && !fListeners.HasItem((void*)listener))
|
|
return fListeners.AddItem((void*)listener);
|
|
return false;
|
|
}
|
|
|
|
// RemoveListener
|
|
bool
|
|
ShapeContainer::RemoveListener(ShapeContainerListener* listener)
|
|
{
|
|
return fListeners.RemoveItem((void*)listener);
|
|
}
|
|
|
|
// #pragma mark -
|
|
|
|
// _MakeEmpty
|
|
void
|
|
ShapeContainer::_MakeEmpty()
|
|
{
|
|
int32 count = CountShapes();
|
|
for (int32 i = 0; i < count; i++) {
|
|
Shape* shape = ShapeAtFast(i);
|
|
_NotifyShapeRemoved(shape);
|
|
shape->Release();
|
|
}
|
|
fShapes.MakeEmpty();
|
|
}
|
|
|
|
// #pragma mark -
|
|
|
|
// _NotifyShapeAdded
|
|
void
|
|
ShapeContainer::_NotifyShapeAdded(Shape* shape) const
|
|
{
|
|
BList listeners(fListeners);
|
|
int32 count = listeners.CountItems();
|
|
for (int32 i = 0; i < count; i++) {
|
|
ShapeContainerListener* listener
|
|
= (ShapeContainerListener*)listeners.ItemAtFast(i);
|
|
listener->ShapeAdded(shape);
|
|
}
|
|
}
|
|
|
|
// _NotifyShapeRemoved
|
|
void
|
|
ShapeContainer::_NotifyShapeRemoved(Shape* shape) const
|
|
{
|
|
BList listeners(fListeners);
|
|
int32 count = listeners.CountItems();
|
|
for (int32 i = 0; i < count; i++) {
|
|
ShapeContainerListener* listener
|
|
= (ShapeContainerListener*)listeners.ItemAtFast(i);
|
|
listener->ShapeRemoved(shape);
|
|
}
|
|
}
|
|
|