From 3639baa4b00e8c555b5fba85800d809ca85a51bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 18 Jun 2006 19:05:44 +0000 Subject: [PATCH] * 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 --- src/apps/icon-o-matic/Jamfile | 4 + src/apps/icon-o-matic/document/Document.cpp | 2 + src/apps/icon-o-matic/document/Document.h | 11 +- src/apps/icon-o-matic/document/Icon.cpp | 31 +++ src/apps/icon-o-matic/document/Icon.h | 30 +++ .../icon-o-matic/document/IconRenderer.cpp | 139 +++++++++++++ src/apps/icon-o-matic/document/IconRenderer.h | 69 +++++++ src/apps/icon-o-matic/shape/PathContainer.cpp | 191 ++++++++++++++++++ src/apps/icon-o-matic/shape/PathContainer.h | 55 +++++ src/apps/icon-o-matic/shape/Shape.cpp | 60 ++++-- src/apps/icon-o-matic/shape/Shape.h | 24 ++- .../icon-o-matic/shape/ShapeContainer.cpp | 191 ++++++++++++++++++ src/apps/icon-o-matic/shape/ShapeContainer.h | 56 +++++ src/apps/icon-o-matic/style/StyleManager.cpp | 14 +- src/apps/icon-o-matic/style/StyleManager.h | 4 + 15 files changed, 849 insertions(+), 32 deletions(-) create mode 100644 src/apps/icon-o-matic/document/Icon.cpp create mode 100644 src/apps/icon-o-matic/document/Icon.h create mode 100644 src/apps/icon-o-matic/document/IconRenderer.cpp create mode 100644 src/apps/icon-o-matic/document/IconRenderer.h create mode 100644 src/apps/icon-o-matic/shape/PathContainer.cpp create mode 100644 src/apps/icon-o-matic/shape/PathContainer.h create mode 100644 src/apps/icon-o-matic/shape/ShapeContainer.cpp create mode 100644 src/apps/icon-o-matic/shape/ShapeContainer.h diff --git a/src/apps/icon-o-matic/Jamfile b/src/apps/icon-o-matic/Jamfile index 8ba1a2608e..c50ce4e1ee 100644 --- a/src/apps/icon-o-matic/Jamfile +++ b/src/apps/icon-o-matic/Jamfile @@ -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 diff --git a/src/apps/icon-o-matic/document/Document.cpp b/src/apps/icon-o-matic/document/Document.cpp index 3134af1614..52ae5ea5bc 100644 --- a/src/apps/icon-o-matic/document/Document.cpp +++ b/src/apps/icon-o-matic/document/Document.cpp @@ -13,6 +13,7 @@ #include #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()), diff --git a/src/apps/icon-o-matic/document/Document.h b/src/apps/icon-o-matic/document/Document.h index 6b6c716f42..f3718272e8 100644 --- a/src/apps/icon-o-matic/document/Document.h +++ b/src/apps/icon-o-matic/document/Document.h @@ -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; diff --git a/src/apps/icon-o-matic/document/Icon.cpp b/src/apps/icon-o-matic/document/Icon.cpp new file mode 100644 index 0000000000..d9c25cb1dc --- /dev/null +++ b/src/apps/icon-o-matic/document/Icon.cpp @@ -0,0 +1,31 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "Icon.h" + +#include + +#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; +} diff --git a/src/apps/icon-o-matic/document/Icon.h b/src/apps/icon-o-matic/document/Icon.h new file mode 100644 index 0000000000..09e1fa79fa --- /dev/null +++ b/src/apps/icon-o-matic/document/Icon.h @@ -0,0 +1,30 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#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 diff --git a/src/apps/icon-o-matic/document/IconRenderer.cpp b/src/apps/icon-o-matic/document/IconRenderer.cpp new file mode 100644 index 0000000000..3bfdd4a86b --- /dev/null +++ b/src/apps/icon-o-matic/document/IconRenderer.cpp @@ -0,0 +1,139 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "IconRenderer.h" + +#include + +#include + +#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); +} + diff --git a/src/apps/icon-o-matic/document/IconRenderer.h b/src/apps/icon-o-matic/document/IconRenderer.h new file mode 100644 index 0000000000..3c39e24559 --- /dev/null +++ b/src/apps/icon-o-matic/document/IconRenderer.h @@ -0,0 +1,69 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#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 + GammaTable; + +typedef agg::rendering_buffer RenderingBuffer; +typedef agg::pixfmt_bgra32 PixelFormat; +typedef agg::pixfmt_bgra32_pre PixelFormatPre; +typedef agg::renderer_base BaseRenderer; +typedef agg::renderer_base BaseRendererPre; + +typedef agg::scanline_u8 Scanline; +typedef agg::scanline_bin BinaryScanline; +typedef agg::span_allocator SpanAllocator; +typedef agg::rasterizer_compound_aa + 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 diff --git a/src/apps/icon-o-matic/shape/PathContainer.cpp b/src/apps/icon-o-matic/shape/PathContainer.cpp new file mode 100644 index 0000000000..1b566679d1 --- /dev/null +++ b/src/apps/icon-o-matic/shape/PathContainer.cpp @@ -0,0 +1,191 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "PathContainer.h" + +#include +#include + +#include + +#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); + } +} + diff --git a/src/apps/icon-o-matic/shape/PathContainer.h b/src/apps/icon-o-matic/shape/PathContainer.h new file mode 100644 index 0000000000..01927aef41 --- /dev/null +++ b/src/apps/icon-o-matic/shape/PathContainer.h @@ -0,0 +1,55 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef PATH_CONTAINER_H +#define PATH_CONTAINER_H + +#include + +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 diff --git a/src/apps/icon-o-matic/shape/Shape.cpp b/src/apps/icon-o-matic/shape/Shape.cpp index 636f5ec994..d8aacc9cb4 100644 --- a/src/apps/icon-o-matic/shape/Shape.cpp +++ b/src/apps/icon-o-matic/shape/Shape.cpp @@ -1,15 +1,24 @@ #include "Shape.h" +#include +#include + #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; } diff --git a/src/apps/icon-o-matic/shape/Shape.h b/src/apps/icon-o-matic/shape/Shape.h index 8a82e75c61..63428550ff 100644 --- a/src/apps/icon-o-matic/shape/Shape.h +++ b/src/apps/icon-o-matic/shape/Shape.h @@ -4,19 +4,27 @@ #include #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; }; diff --git a/src/apps/icon-o-matic/shape/ShapeContainer.cpp b/src/apps/icon-o-matic/shape/ShapeContainer.cpp new file mode 100644 index 0000000000..03270af1ee --- /dev/null +++ b/src/apps/icon-o-matic/shape/ShapeContainer.cpp @@ -0,0 +1,191 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "ShapeContainer.h" + +#include +#include + +#include + +#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); + } +} + diff --git a/src/apps/icon-o-matic/shape/ShapeContainer.h b/src/apps/icon-o-matic/shape/ShapeContainer.h new file mode 100644 index 0000000000..37b001c4c2 --- /dev/null +++ b/src/apps/icon-o-matic/shape/ShapeContainer.h @@ -0,0 +1,56 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef SHAPE_CONTAINER_H +#define SHAPE_CONTAINER_H + +#include + +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 diff --git a/src/apps/icon-o-matic/style/StyleManager.cpp b/src/apps/icon-o-matic/style/StyleManager.cpp index 14385ff855..7e8ae84263 100644 --- a/src/apps/icon-o-matic/style/StyleManager.cpp +++ b/src/apps/icon-o-matic/style/StyleManager.cpp @@ -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 diff --git a/src/apps/icon-o-matic/style/StyleManager.h b/src/apps/icon-o-matic/style/StyleManager.h index 1d2978dede..8969129d9c 100644 --- a/src/apps/icon-o-matic/style/StyleManager.h +++ b/src/apps/icon-o-matic/style/StyleManager.h @@ -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