* add more classes:
PathContainer - a list of VectorPath objects ShapeContainer - a list of Shape objects Icon - the object contains VectorPaths and Shapes using these paths IconRenderer - renders an Icon into a BBitmap using AGG compound shape rasterization with additional gamma correction * Shape has a PathContainer instead of a single VectorPath * Document has an Icon instance * changed the inheritance of some classes to us Referenceable more git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17873 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -33,6 +33,8 @@ UseLibraryHeaders agg ;
|
||||
Application Icon-O-Matic :
|
||||
#document
|
||||
Document.cpp
|
||||
Icon.cpp
|
||||
IconRenderer.cpp
|
||||
#generic/command
|
||||
Command.cpp
|
||||
CommandStack.cpp
|
||||
@@ -58,8 +60,10 @@ Application Icon-O-Matic :
|
||||
Style.cpp
|
||||
StyleManager.cpp
|
||||
#shape
|
||||
PathContainer.cpp
|
||||
PathManipulator.cpp
|
||||
Shape.cpp
|
||||
ShapeContainer.cpp
|
||||
VectorPath.cpp
|
||||
#shape/commands
|
||||
AddPointCommand.cpp
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <Entry.h>
|
||||
|
||||
#include "CommandStack.h"
|
||||
#include "Icon.h"
|
||||
#include "Selection.h"
|
||||
|
||||
using std::nothrow;
|
||||
@@ -20,6 +21,7 @@ using std::nothrow;
|
||||
// constructor
|
||||
Document::Document(const char* name)
|
||||
: RWLocker("document rw lock"),
|
||||
fIcon(new (nothrow) ::Icon()),
|
||||
fCommandStack(new (nothrow) ::CommandStack()),
|
||||
fSelection(new (nothrow) ::Selection()),
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
struct entry_ref;
|
||||
|
||||
class CommandStack;
|
||||
class Icon;
|
||||
class Selection;
|
||||
|
||||
class Document : public RWLocker {
|
||||
@@ -23,20 +24,24 @@ class Document : public RWLocker {
|
||||
Document(const char* name = NULL);
|
||||
virtual ~Document();
|
||||
|
||||
::CommandStack* CommandStack() const
|
||||
inline ::CommandStack* CommandStack() const
|
||||
{ return fCommandStack; }
|
||||
|
||||
::Selection* Selection() const
|
||||
inline ::Selection* Selection() const
|
||||
{ return fSelection; }
|
||||
|
||||
void SetName(const char* name);
|
||||
const char* Name() const;
|
||||
|
||||
void SetRef(const entry_ref& ref);
|
||||
const entry_ref* Ref() const
|
||||
inline const entry_ref* Ref() const
|
||||
{ return fRef; }
|
||||
|
||||
inline ::Icon* Icon() const
|
||||
{ return fIcon; }
|
||||
|
||||
private:
|
||||
::Icon* fIcon;
|
||||
::CommandStack* fCommandStack;
|
||||
::Selection* fSelection;
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <[email protected]>
|
||||
*/
|
||||
|
||||
#include "Icon.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
#include "PathContainer.h"
|
||||
#include "ShapeContainer.h"
|
||||
|
||||
using std::nothrow;
|
||||
|
||||
// constructor
|
||||
Icon::Icon()
|
||||
: fPaths(new (nothrow) PathContainer()),
|
||||
fShapes(new (nothrow) ShapeContainer())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// destructor
|
||||
Icon::~Icon()
|
||||
{
|
||||
delete fShapes;
|
||||
delete fPaths;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <[email protected]>
|
||||
*/
|
||||
|
||||
#ifndef ICON_H
|
||||
#define ICON_H
|
||||
|
||||
class PathContainer;
|
||||
class ShapeContainer;
|
||||
|
||||
class Icon {
|
||||
public:
|
||||
Icon();
|
||||
virtual ~Icon();
|
||||
|
||||
PathContainer* Paths() const
|
||||
{ return fPaths; }
|
||||
ShapeContainer* Shapes() const
|
||||
{ return fShapes; }
|
||||
|
||||
private:
|
||||
PathContainer* fPaths;
|
||||
ShapeContainer* fShapes;
|
||||
};
|
||||
|
||||
#endif // ICON_H
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <[email protected]>
|
||||
*/
|
||||
|
||||
#include "IconRenderer.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <Bitmap.h>
|
||||
|
||||
#include "Icon.h"
|
||||
#include "Style.h"
|
||||
#include "StyleManager.h"
|
||||
|
||||
using std::nothrow;
|
||||
|
||||
class StyleHandler {
|
||||
public:
|
||||
StyleHandler(const StyleManager* styles,
|
||||
GammaTable& gammaTable)
|
||||
: fStyles(styles),
|
||||
fGammaTable(gammaTable),
|
||||
fTransparent(0, 0, 0, 0),
|
||||
fColor(0, 0, 0, 0)
|
||||
{}
|
||||
|
||||
bool is_solid(unsigned styleIndex) const
|
||||
{
|
||||
Style* style = fStyles->StyleAt(styleIndex);
|
||||
if (!style)
|
||||
return true;
|
||||
|
||||
return style->Gradient() != NULL;
|
||||
}
|
||||
|
||||
const agg::rgba8& color(unsigned styleIndex)
|
||||
{
|
||||
Style* style = fStyles->StyleAt(styleIndex);
|
||||
if (!style)
|
||||
return fTransparent;
|
||||
|
||||
const rgb_color& c = style->Color();
|
||||
fColor = agg::rgba8(fGammaTable.dir(c.red),
|
||||
fGammaTable.dir(c.green),
|
||||
fGammaTable.dir(c.blue),
|
||||
c.alpha);
|
||||
fColor.premultiply();
|
||||
return fColor;
|
||||
}
|
||||
|
||||
void generate_span(agg::rgba8* span, int x, int y,
|
||||
unsigned len, unsigned styleIndex)
|
||||
{
|
||||
// TODO: render gradient of Style at styleIndex into span
|
||||
}
|
||||
|
||||
private:
|
||||
const StyleManager* fStyles;
|
||||
GammaTable& fGammaTable;
|
||||
agg::rgba8 fTransparent;
|
||||
agg::rgba8 fColor;
|
||||
};
|
||||
|
||||
|
||||
// constructor
|
||||
IconRenderer::IconRenderer(BBitmap* bitmap)
|
||||
: fBitmap(bitmap),
|
||||
fIcon(NULL),
|
||||
fStyles(StyleManager::Default()),
|
||||
|
||||
fGammaTable(2.2),
|
||||
|
||||
fRenderingBuffer(),
|
||||
fPixelFormat(fRenderingBuffer),
|
||||
fPixelFormatPre(fRenderingBuffer),
|
||||
fBaseRenderer(fPixelFormat),
|
||||
fBaseRendererPre(fPixelFormatPre),
|
||||
|
||||
fScanline(),
|
||||
fBinaryScanline(),
|
||||
fSpanAllocator(),
|
||||
|
||||
fRasterizer()
|
||||
{
|
||||
// attach rendering buffer to bitmap
|
||||
fRenderingBuffer.attach((uint8*)bitmap->Bits(),
|
||||
bitmap->Bounds().IntegerWidth() + 1,
|
||||
bitmap->Bounds().IntegerHeight() + 1,
|
||||
bitmap->BytesPerRow());
|
||||
|
||||
// attach bitmap
|
||||
}
|
||||
|
||||
// destructor
|
||||
IconRenderer::~IconRenderer()
|
||||
{
|
||||
}
|
||||
|
||||
// SetIcon
|
||||
void
|
||||
IconRenderer::SetIcon(Icon* icon)
|
||||
{
|
||||
if (fIcon == icon)
|
||||
return;
|
||||
|
||||
fIcon = icon;
|
||||
// TODO: ... ?
|
||||
}
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
// _RenderIcon
|
||||
void
|
||||
IconRenderer::_RenderIcon()
|
||||
{
|
||||
fBaseRenderer.clear(agg::rgba8(0, 0, 0, 0));
|
||||
|
||||
if (!fIcon)
|
||||
return;
|
||||
|
||||
// TODO: iterate over shapes in icon and
|
||||
// add the vector paths to the rasterizer
|
||||
|
||||
StyleHandler styleHandler(fStyles, fGammaTable);
|
||||
|
||||
agg::render_scanlines_compound(fRasterizer,
|
||||
fScanline,
|
||||
fBinaryScanline,
|
||||
fBaseRendererPre,
|
||||
fSpanAllocator,
|
||||
styleHandler);
|
||||
|
||||
fPixelFormat.apply_gamma_dir(fGammaTable);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <[email protected]>
|
||||
*/
|
||||
|
||||
#ifndef ICON_RENDERER_H
|
||||
#define ICON_RENDERER_H
|
||||
|
||||
#include "agg_gamma_lut.h"
|
||||
#include "agg_rendering_buffer.h"
|
||||
#include "agg_rasterizer_compound_aa.h"
|
||||
#include "agg_scanline_u.h"
|
||||
#include "agg_scanline_bin.h"
|
||||
#include "agg_renderer_scanline.h"
|
||||
#include "agg_span_allocator.h"
|
||||
#include "agg_pixfmt_rgba.h"
|
||||
|
||||
class BBitmap;
|
||||
class Icon;
|
||||
class StyleManager;
|
||||
|
||||
typedef agg::gamma_lut
|
||||
<agg::int8u, agg::int8u> GammaTable;
|
||||
|
||||
typedef agg::rendering_buffer RenderingBuffer;
|
||||
typedef agg::pixfmt_bgra32 PixelFormat;
|
||||
typedef agg::pixfmt_bgra32_pre PixelFormatPre;
|
||||
typedef agg::renderer_base<PixelFormat> BaseRenderer;
|
||||
typedef agg::renderer_base<PixelFormatPre> BaseRendererPre;
|
||||
|
||||
typedef agg::scanline_u8 Scanline;
|
||||
typedef agg::scanline_bin BinaryScanline;
|
||||
typedef agg::span_allocator<agg::rgba8> SpanAllocator;
|
||||
typedef agg::rasterizer_compound_aa
|
||||
<agg::rasterizer_sl_clip_dbl> CompoundRasterizer;
|
||||
|
||||
class IconRenderer {
|
||||
public:
|
||||
IconRenderer(BBitmap* bitmap);
|
||||
virtual ~IconRenderer();
|
||||
|
||||
void SetIcon(Icon* icon);
|
||||
|
||||
private:
|
||||
void _RenderIcon();
|
||||
|
||||
BBitmap* fBitmap;
|
||||
Icon* fIcon;
|
||||
StyleManager* fStyles;
|
||||
|
||||
GammaTable fGammaTable;
|
||||
|
||||
RenderingBuffer fRenderingBuffer;
|
||||
PixelFormat fPixelFormat;
|
||||
PixelFormatPre fPixelFormatPre;
|
||||
BaseRenderer fBaseRenderer;
|
||||
BaseRendererPre fBaseRendererPre;
|
||||
|
||||
Scanline fScanline;
|
||||
BinaryScanline fBinaryScanline;
|
||||
SpanAllocator fSpanAllocator;
|
||||
|
||||
CompoundRasterizer fRasterizer;
|
||||
};
|
||||
|
||||
#endif // ICON_RENDERER_H
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <[email protected]>
|
||||
*/
|
||||
|
||||
#include "PathContainer.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include "VectorPath.h"
|
||||
|
||||
// constructor
|
||||
PathContainerListener::PathContainerListener()
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
PathContainerListener::~PathContainerListener()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
// constructor
|
||||
PathContainer::PathContainer()
|
||||
: fPaths(16),
|
||||
fListeners(2)
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
PathContainer::~PathContainer()
|
||||
{
|
||||
int32 count = fListeners.CountItems();
|
||||
if (count > 0) {
|
||||
debugger("~PathContainer() - there are still"
|
||||
"listeners attached\n");
|
||||
}
|
||||
_MakeEmpty();
|
||||
}
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
// AddPath
|
||||
bool
|
||||
PathContainer::AddPath(VectorPath* path)
|
||||
{
|
||||
if (!path)
|
||||
return false;
|
||||
|
||||
// prevent adding the same path twice
|
||||
if (HasPath(path))
|
||||
return false;
|
||||
|
||||
if (fPaths.AddItem((void*)path)) {
|
||||
_NotifyPathAdded(path);
|
||||
return true;
|
||||
}
|
||||
|
||||
fprintf(stderr, "PathContainer::AddPath() - out of memory!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// RemovePath
|
||||
bool
|
||||
PathContainer::RemovePath(VectorPath* path)
|
||||
{
|
||||
if (fPaths.RemoveItem((void*)path)) {
|
||||
_NotifyPathRemoved(path);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// RemovePath
|
||||
VectorPath*
|
||||
PathContainer::RemovePath(int32 index)
|
||||
{
|
||||
VectorPath* path = (VectorPath*)fPaths.RemoveItem(index);
|
||||
if (path) {
|
||||
_NotifyPathRemoved(path);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
// MakeEmpty
|
||||
void
|
||||
PathContainer::MakeEmpty()
|
||||
{
|
||||
_MakeEmpty();
|
||||
}
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
// CountPaths
|
||||
int32
|
||||
PathContainer::CountPaths() const
|
||||
{
|
||||
return fPaths.CountItems();
|
||||
}
|
||||
|
||||
// HasPath
|
||||
bool
|
||||
PathContainer::HasPath(VectorPath* path) const
|
||||
{
|
||||
return fPaths.HasItem((void*)path);
|
||||
}
|
||||
|
||||
// PathAt
|
||||
VectorPath*
|
||||
PathContainer::PathAt(int32 index) const
|
||||
{
|
||||
return (VectorPath*)fPaths.ItemAt(index);
|
||||
}
|
||||
|
||||
// PathAtFast
|
||||
VectorPath*
|
||||
PathContainer::PathAtFast(int32 index) const
|
||||
{
|
||||
return (VectorPath*)fPaths.ItemAtFast(index);
|
||||
}
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
// AddListener
|
||||
bool
|
||||
PathContainer::AddListener(PathContainerListener* listener)
|
||||
{
|
||||
if (listener && !fListeners.HasItem((void*)listener))
|
||||
return fListeners.AddItem(listener);
|
||||
return false;
|
||||
}
|
||||
|
||||
// RemoveListener
|
||||
bool
|
||||
PathContainer::RemoveListener(PathContainerListener* listener)
|
||||
{
|
||||
return fListeners.RemoveItem(listener);
|
||||
}
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
// _MakeEmpty
|
||||
void
|
||||
PathContainer::_MakeEmpty()
|
||||
{
|
||||
int32 count = CountPaths();
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
VectorPath* path = PathAtFast(i);
|
||||
_NotifyPathRemoved(path);
|
||||
path->Release();
|
||||
}
|
||||
fPaths.MakeEmpty();
|
||||
}
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
// _NotifyPathAdded
|
||||
void
|
||||
PathContainer::_NotifyPathAdded(VectorPath* path) const
|
||||
{
|
||||
BList listeners(fListeners);
|
||||
int32 count = listeners.CountItems();
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
PathContainerListener* listener
|
||||
= (PathContainerListener*)listeners.ItemAtFast(i);
|
||||
listener->PathAdded(path);
|
||||
}
|
||||
}
|
||||
|
||||
// _NotifyPathRemoved
|
||||
void
|
||||
PathContainer::_NotifyPathRemoved(VectorPath* path) const
|
||||
{
|
||||
BList listeners(fListeners);
|
||||
int32 count = listeners.CountItems();
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
PathContainerListener* listener
|
||||
= (PathContainerListener*)listeners.ItemAtFast(i);
|
||||
listener->PathRemoved(path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <[email protected]>
|
||||
*/
|
||||
|
||||
#ifndef PATH_CONTAINER_H
|
||||
#define PATH_CONTAINER_H
|
||||
|
||||
#include <List.h>
|
||||
|
||||
class VectorPath;
|
||||
|
||||
class PathContainerListener {
|
||||
public:
|
||||
PathContainerListener();
|
||||
virtual ~PathContainerListener();
|
||||
|
||||
virtual void PathAdded(VectorPath* path) = 0;
|
||||
virtual void PathRemoved(VectorPath* path) = 0;
|
||||
};
|
||||
|
||||
class PathContainer {
|
||||
public:
|
||||
PathContainer();
|
||||
virtual ~PathContainer();
|
||||
|
||||
bool AddPath(VectorPath* path);
|
||||
bool RemovePath(VectorPath* path);
|
||||
VectorPath* RemovePath(int32 index);
|
||||
|
||||
void MakeEmpty();
|
||||
|
||||
int32 CountPaths() const;
|
||||
bool HasPath(VectorPath* path) const;
|
||||
|
||||
VectorPath* PathAt(int32 index) const;
|
||||
VectorPath* PathAtFast(int32 index) const;
|
||||
|
||||
bool AddListener(PathContainerListener* listener);
|
||||
bool RemoveListener(PathContainerListener* listener);
|
||||
|
||||
private:
|
||||
void _MakeEmpty();
|
||||
|
||||
void _NotifyPathAdded(VectorPath* path) const;
|
||||
void _NotifyPathRemoved(VectorPath* path) const;
|
||||
|
||||
BList fPaths;
|
||||
BList fListeners;
|
||||
};
|
||||
|
||||
#endif // PATH_CONTAINER_H
|
||||
@@ -1,15 +1,24 @@
|
||||
#include "Shape.h"
|
||||
|
||||
#include <new>
|
||||
#include <limits.h>
|
||||
|
||||
#include "Style.h"
|
||||
#include "VectorPath.h"
|
||||
|
||||
using std::nothrow;
|
||||
|
||||
// constructor
|
||||
Shape::Shape(VectorPath* path, ::Style* style)
|
||||
: fPath(path),
|
||||
Shape::Shape(::Style* style)
|
||||
: Observable(),
|
||||
Referenceable(),
|
||||
PathContainerListener(),
|
||||
fPaths(new (nothrow) PathContainer()),
|
||||
fStyle(style)
|
||||
{
|
||||
if (fPath)
|
||||
fPath->Acquire();
|
||||
if (fPaths)
|
||||
fPaths->AddListener(this);
|
||||
|
||||
if (fStyle)
|
||||
fStyle->Acquire();
|
||||
}
|
||||
@@ -17,28 +26,35 @@ Shape::Shape(VectorPath* path, ::Style* style)
|
||||
// destructor
|
||||
Shape::~Shape()
|
||||
{
|
||||
if (fPath)
|
||||
fPath->Release();
|
||||
fPaths->MakeEmpty();
|
||||
fPaths->RemoveListener(this);
|
||||
delete fPaths;
|
||||
|
||||
if (fStyle)
|
||||
fStyle->Release();
|
||||
}
|
||||
|
||||
// SetPath
|
||||
// PathAdded
|
||||
void
|
||||
Shape::SetPath(VectorPath* path)
|
||||
Shape::PathAdded(VectorPath* path)
|
||||
{
|
||||
if (fPath == path)
|
||||
return;
|
||||
path->Acquire();
|
||||
}
|
||||
|
||||
if (fPath)
|
||||
fPath->Release();
|
||||
// PathRemoved
|
||||
void
|
||||
Shape::PathRemoved(VectorPath* path)
|
||||
{
|
||||
path->Release();
|
||||
}
|
||||
|
||||
fPath = path;
|
||||
// #pragma mark -
|
||||
|
||||
if (fPath)
|
||||
fPath->Acquire();
|
||||
|
||||
Notify();
|
||||
// InitCheck
|
||||
status_t
|
||||
Shape::InitCheck() const
|
||||
{
|
||||
return fPaths ? B_OK : B_NO_MEMORY;
|
||||
}
|
||||
|
||||
// SetStyle
|
||||
@@ -63,7 +79,11 @@ Shape::SetStyle(::Style* style)
|
||||
BRect
|
||||
Shape::Bounds() const
|
||||
{
|
||||
if (fPath)
|
||||
return fPath->Bounds();
|
||||
return BRect(0, 0, -1, -1);
|
||||
BRect bounds(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN);
|
||||
|
||||
int32 count = fPaths->CountPaths();
|
||||
for (int32 i = 0; i < count; i++)
|
||||
bounds = bounds | fPaths->PathAtFast(i)->Bounds();
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
@@ -4,19 +4,27 @@
|
||||
#include <Rect.h>
|
||||
|
||||
#include "Observable.h"
|
||||
#include "PathContainer.h"
|
||||
#include "Referenceable.h"
|
||||
|
||||
class Style;
|
||||
class VectorPath;
|
||||
|
||||
class Shape : public Observable {
|
||||
class Shape : public Observable,
|
||||
public Referenceable,
|
||||
public PathContainerListener {
|
||||
public:
|
||||
Shape(VectorPath* path,
|
||||
::Style* style);
|
||||
Shape(::Style* style);
|
||||
virtual ~Shape();
|
||||
|
||||
void SetPath(VectorPath* path);
|
||||
inline VectorPath* Path() const
|
||||
{ return fPath; }
|
||||
// PathContainerListener interface
|
||||
virtual void PathAdded(VectorPath* path);
|
||||
virtual void PathRemoved(VectorPath* path);
|
||||
|
||||
// Shape
|
||||
status_t InitCheck() const;
|
||||
|
||||
inline PathContainer* Paths() const
|
||||
{ return fPaths; }
|
||||
|
||||
void SetStyle(::Style* style);
|
||||
inline ::Style* Style() const
|
||||
@@ -25,7 +33,7 @@ class Shape : public Observable {
|
||||
BRect Bounds() const;
|
||||
|
||||
private:
|
||||
VectorPath* fPath;
|
||||
PathContainer* fPaths;
|
||||
::Style* fStyle;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* 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(listener);
|
||||
return false;
|
||||
}
|
||||
|
||||
// RemoveListener
|
||||
bool
|
||||
ShapeContainer::RemoveListener(ShapeContainerListener* listener)
|
||||
{
|
||||
return fListeners.RemoveItem(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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <[email protected]>
|
||||
*/
|
||||
|
||||
#ifndef SHAPE_CONTAINER_H
|
||||
#define SHAPE_CONTAINER_H
|
||||
|
||||
#include <List.h>
|
||||
|
||||
class Shape;
|
||||
|
||||
class ShapeContainerListener {
|
||||
public:
|
||||
ShapeContainerListener();
|
||||
virtual ~ShapeContainerListener();
|
||||
|
||||
virtual void ShapeAdded(Shape* shape) = 0;
|
||||
virtual void ShapeRemoved(Shape* shape) = 0;
|
||||
};
|
||||
|
||||
class ShapeContainer {
|
||||
public:
|
||||
ShapeContainer();
|
||||
virtual ~ShapeContainer();
|
||||
|
||||
bool AddShape(Shape* shape);
|
||||
bool RemoveShape(Shape* shape);
|
||||
Shape* RemoveShape(int32 index);
|
||||
|
||||
void MakeEmpty();
|
||||
|
||||
int32 CountShapes() const;
|
||||
bool HasShape(Shape* shape) const;
|
||||
|
||||
Shape* ShapeAt(int32 index) const;
|
||||
Shape* ShapeAtFast(int32 index) const;
|
||||
|
||||
bool AddListener(ShapeContainerListener* listener);
|
||||
bool RemoveListener(
|
||||
ShapeContainerListener* listener);
|
||||
|
||||
private:
|
||||
void _MakeEmpty();
|
||||
|
||||
void _NotifyShapeAdded(Shape* shape) const;
|
||||
void _NotifyShapeRemoved(Shape* shape) const;
|
||||
|
||||
BList fShapes;
|
||||
BList fListeners;
|
||||
};
|
||||
|
||||
#endif // SHAPE_CONTAINER_H
|
||||
@@ -26,10 +26,16 @@ StyleManagerListener::~StyleManagerListener()
|
||||
}
|
||||
|
||||
|
||||
// init global StyleManager instance
|
||||
StyleManager
|
||||
StyleManager::fDefaultInstance;
|
||||
|
||||
|
||||
// constructor
|
||||
StyleManager::StyleManager()
|
||||
: RWLocker()
|
||||
: RWLocker(),
|
||||
fStyles(32),
|
||||
fListeners(2)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -156,6 +162,12 @@ StyleManager::RemoveListener(StyleManagerListener* listener)
|
||||
return fListeners.RemoveItem(listener);
|
||||
}
|
||||
|
||||
StyleManager*
|
||||
StyleManager::Default()
|
||||
{
|
||||
return &fDefaultInstance;
|
||||
}
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
// _StateChanged
|
||||
|
||||
@@ -46,6 +46,8 @@ class StyleManager : public RWLocker {
|
||||
bool AddListener(StyleManagerListener* listener);
|
||||
bool RemoveListener(StyleManagerListener* listener);
|
||||
|
||||
static StyleManager* Default();
|
||||
|
||||
private:
|
||||
void _StateChanged();
|
||||
void _MakeEmpty();
|
||||
@@ -55,6 +57,8 @@ class StyleManager : public RWLocker {
|
||||
|
||||
BList fStyles;
|
||||
BList fListeners;
|
||||
|
||||
static StyleManager fDefaultInstance;
|
||||
};
|
||||
|
||||
#endif // STYLE_MANAGER_H
|
||||
|
||||
Reference in New Issue
Block a user