* work in progress on GUI classes
- added IconView which just uses an IconRenderer to display a preview
of the icon at a certain size
- PathListView and ShapeListView (very much work in progress)
* actually had the gamma correction applied in the wrong direction...
now the anti-aliasing looks as smooth as planned
* added SetName() and Name() to Shape and VectorPath... will be in a
common base class later on
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17988 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <[email protected]>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "IconView.h"
|
||||||
|
|
||||||
|
#include <Bitmap.h>
|
||||||
|
|
||||||
|
#include "ui_defines.h"
|
||||||
|
|
||||||
|
#include "IconRenderer.h"
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
IconView::IconView(BRect frame, const char* name)
|
||||||
|
: BView(frame, name, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW),
|
||||||
|
fBitmap(new BBitmap(frame.OffsetToCopy(B_ORIGIN), 0, B_RGB32)),
|
||||||
|
fIcon(NULL),
|
||||||
|
fRenderer(new IconRenderer(fBitmap)),
|
||||||
|
fDirtyIconArea(fBitmap->Bounds()),
|
||||||
|
|
||||||
|
fScale((frame.Width() + 1.0) / 64.0)
|
||||||
|
{
|
||||||
|
fRenderer->SetScale(fScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
IconView::~IconView()
|
||||||
|
{
|
||||||
|
SetIcon(NULL);
|
||||||
|
delete fRenderer;
|
||||||
|
delete fBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
// AttachedToWindow
|
||||||
|
void
|
||||||
|
IconView::AttachedToWindow()
|
||||||
|
{
|
||||||
|
SetViewColor(B_TRANSPARENT_COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
void
|
||||||
|
IconView::Draw(BRect updateRect)
|
||||||
|
{
|
||||||
|
if (fDirtyIconArea.IsValid()) {
|
||||||
|
fRenderer->Render(fDirtyIconArea);
|
||||||
|
fDirtyIconArea.Set(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
// icon
|
||||||
|
DrawBitmap(fBitmap, B_ORIGIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
// AreaInvalidated
|
||||||
|
void
|
||||||
|
IconView::AreaInvalidated(const BRect& area)
|
||||||
|
{
|
||||||
|
BRect scaledArea(area);
|
||||||
|
scaledArea.left *= fScale;
|
||||||
|
scaledArea.top *= fScale;
|
||||||
|
scaledArea.right *= fScale;
|
||||||
|
scaledArea.bottom *= fScale;
|
||||||
|
|
||||||
|
if (fDirtyIconArea.Contains(scaledArea))
|
||||||
|
return;
|
||||||
|
|
||||||
|
fDirtyIconArea = fDirtyIconArea | scaledArea;
|
||||||
|
|
||||||
|
Invalidate(scaledArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
// SetIcon
|
||||||
|
void
|
||||||
|
IconView::SetIcon(Icon* icon)
|
||||||
|
{
|
||||||
|
if (fIcon == icon)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fIcon)
|
||||||
|
fIcon->RemoveListener(this);
|
||||||
|
|
||||||
|
fIcon = icon;
|
||||||
|
fRenderer->SetIcon(icon);
|
||||||
|
|
||||||
|
if (fIcon)
|
||||||
|
fIcon->AddListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <[email protected]>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ICON_VIEW_H
|
||||||
|
#define ICON_VIEW_H
|
||||||
|
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
|
#include "Icon.h"
|
||||||
|
|
||||||
|
class BBitmap;
|
||||||
|
class IconRenderer;
|
||||||
|
|
||||||
|
class IconView : public BView,
|
||||||
|
public IconListener {
|
||||||
|
public:
|
||||||
|
IconView(BRect frame, const char* name);
|
||||||
|
virtual ~IconView();
|
||||||
|
|
||||||
|
// BView interface
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
virtual void Draw(BRect updateRect);
|
||||||
|
|
||||||
|
// IconListener interface
|
||||||
|
virtual void AreaInvalidated(const BRect& area);
|
||||||
|
|
||||||
|
// IconView
|
||||||
|
void SetIcon(Icon* icon);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BBitmap* fBitmap;
|
||||||
|
Icon* fIcon;
|
||||||
|
IconRenderer* fRenderer;
|
||||||
|
BRect fDirtyIconArea;
|
||||||
|
|
||||||
|
double fScale;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ICON_VIEW_H
|
||||||
@@ -41,10 +41,12 @@ Application Icon-O-Matic :
|
|||||||
# generic/command
|
# generic/command
|
||||||
Command.cpp
|
Command.cpp
|
||||||
CommandStack.cpp
|
CommandStack.cpp
|
||||||
|
# generic/selection
|
||||||
Selectable.cpp
|
Selectable.cpp
|
||||||
Selection.cpp
|
Selection.cpp
|
||||||
# generic/gui
|
# generic/gui
|
||||||
Group.cpp
|
Group.cpp
|
||||||
|
ListViews.cpp
|
||||||
SwatchView.cpp
|
SwatchView.cpp
|
||||||
# generic/gui/panel
|
# generic/gui/panel
|
||||||
Panel.cpp
|
Panel.cpp
|
||||||
@@ -70,6 +72,8 @@ Application Icon-O-Matic :
|
|||||||
support.cpp
|
support.cpp
|
||||||
support_ui.cpp
|
support_ui.cpp
|
||||||
# gui
|
# gui
|
||||||
|
PathListView.cpp
|
||||||
|
ShapeListView.cpp
|
||||||
SwatchGroup.cpp
|
SwatchGroup.cpp
|
||||||
# gradient
|
# gradient
|
||||||
Gradient.cpp
|
Gradient.cpp
|
||||||
@@ -98,6 +102,7 @@ Application Icon-O-Matic :
|
|||||||
#
|
#
|
||||||
CanvasView.cpp
|
CanvasView.cpp
|
||||||
IconEditorApp.cpp
|
IconEditorApp.cpp
|
||||||
|
IconView.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
MainWindow.cpp
|
MainWindow.cpp
|
||||||
: be libagg.a
|
: be libagg.a
|
||||||
|
|||||||
@@ -11,10 +11,14 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
|
#include <ScrollView.h>
|
||||||
|
|
||||||
#include "Document.h"
|
#include "Document.h"
|
||||||
#include "CanvasView.h"
|
#include "CanvasView.h"
|
||||||
#include "IconEditorApp.h"
|
#include "IconEditorApp.h"
|
||||||
|
#include "IconView.h"
|
||||||
|
#include "PathListView.h"
|
||||||
|
#include "ShapeListView.h"
|
||||||
#include "SwatchGroup.h"
|
#include "SwatchGroup.h"
|
||||||
|
|
||||||
// TODO: just for testing
|
// TODO: just for testing
|
||||||
@@ -25,6 +29,7 @@
|
|||||||
#include "PathManipulator.h"
|
#include "PathManipulator.h"
|
||||||
#include "Shape.h"
|
#include "Shape.h"
|
||||||
#include "ShapeContainer.h"
|
#include "ShapeContainer.h"
|
||||||
|
#include "ShapeListView.h"
|
||||||
#include "StrokeTransformer.h"
|
#include "StrokeTransformer.h"
|
||||||
#include "Style.h"
|
#include "Style.h"
|
||||||
#include "StyleManager.h"
|
#include "StyleManager.h"
|
||||||
@@ -36,8 +41,7 @@ MainWindow::MainWindow(IconEditorApp* app, Document* document)
|
|||||||
B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
|
B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
|
||||||
B_ASYNCHRONOUS_CONTROLS),
|
B_ASYNCHRONOUS_CONTROLS),
|
||||||
fApp(app),
|
fApp(app),
|
||||||
fDocument(document),
|
fDocument(document)
|
||||||
fCanvasView(NULL)
|
|
||||||
{
|
{
|
||||||
_Init();
|
_Init();
|
||||||
}
|
}
|
||||||
@@ -87,6 +91,19 @@ MainWindow::_Init()
|
|||||||
// fCanvasView->SetSelection(fDocument->Selection());
|
// fCanvasView->SetSelection(fDocument->Selection());
|
||||||
fCanvasView->SetIcon(fDocument->Icon());
|
fCanvasView->SetIcon(fDocument->Icon());
|
||||||
|
|
||||||
|
fPathListView->SetPathContainer(fDocument->Icon()->Paths());
|
||||||
|
// fPathListView->SetCommandStack(fDocument->CommandStack());
|
||||||
|
// fPathListView->SetSelection(fDocument->Selection());
|
||||||
|
|
||||||
|
fShapeListView->SetShapeContainer(fDocument->Icon()->Shapes());
|
||||||
|
// fShapeListView->SetCommandStack(fDocument->CommandStack());
|
||||||
|
// fShapeListView->SetSelection(fDocument->Selection());
|
||||||
|
|
||||||
|
fIconPreview16->SetIcon(fDocument->Icon());
|
||||||
|
fIconPreview32->SetIcon(fDocument->Icon());
|
||||||
|
// fIconPreview48->SetIcon(fDocument->Icon());
|
||||||
|
fIconPreview64->SetIcon(fDocument->Icon());
|
||||||
|
|
||||||
// TODO: for testing only:
|
// TODO: for testing only:
|
||||||
MultipleManipulatorState* state = new MultipleManipulatorState(fCanvasView);
|
MultipleManipulatorState* state = new MultipleManipulatorState(fCanvasView);
|
||||||
fCanvasView->SetState(state);
|
fCanvasView->SetState(state);
|
||||||
@@ -112,6 +129,7 @@ MainWindow::_Init()
|
|||||||
Shape* shape = new Shape(style2);
|
Shape* shape = new Shape(style2);
|
||||||
shape->Paths()->AddPath(path);
|
shape->Paths()->AddPath(path);
|
||||||
|
|
||||||
|
shape->SetName("Gradient");
|
||||||
fDocument->Icon()->Shapes()->AddShape(shape);
|
fDocument->Icon()->Shapes()->AddShape(shape);
|
||||||
|
|
||||||
shape = new Shape(style1);
|
shape = new Shape(style1);
|
||||||
@@ -121,6 +139,7 @@ MainWindow::_Init()
|
|||||||
transformer->width(5.0);
|
transformer->width(5.0);
|
||||||
shape->AppendTransformer(transformer);
|
shape->AppendTransformer(transformer);
|
||||||
|
|
||||||
|
shape->SetName("Outline");
|
||||||
fDocument->Icon()->Shapes()->AddShape(shape);
|
fDocument->Icon()->Shapes()->AddShape(shape);
|
||||||
|
|
||||||
Style* style3 = new Style();
|
Style* style3 = new Style();
|
||||||
@@ -137,6 +156,7 @@ MainWindow::_Init()
|
|||||||
*transformer2 *= agg::trans_affine_scaling(0.8, 0.6);
|
*transformer2 *= agg::trans_affine_scaling(0.8, 0.6);
|
||||||
shape->AppendTransformer(transformer2);
|
shape->AppendTransformer(transformer2);
|
||||||
|
|
||||||
|
shape->SetName("Transformed");
|
||||||
fDocument->Icon()->Shapes()->AddShape(shape);
|
fDocument->Icon()->Shapes()->AddShape(shape);
|
||||||
|
|
||||||
PathManipulator* pathManipulator = new PathManipulator(path);
|
PathManipulator* pathManipulator = new PathManipulator(path);
|
||||||
@@ -157,7 +177,54 @@ MainWindow::_CreateGUI(BRect bounds)
|
|||||||
|
|
||||||
fCanvasView = new CanvasView(bounds);
|
fCanvasView = new CanvasView(bounds);
|
||||||
|
|
||||||
|
bounds.left = fSwatchGroup->Frame().right + 5;
|
||||||
|
bounds.top = fSwatchGroup->Frame().top + 5;
|
||||||
|
bounds.right = bounds.left + 15;
|
||||||
|
bounds.bottom = bounds.top + 15;
|
||||||
|
fIconPreview16 = new IconView(bounds, "icon preview 16");
|
||||||
|
|
||||||
|
bounds.OffsetBy(bounds.Width() + 6, 0);
|
||||||
|
bounds.right = bounds.left + 31;
|
||||||
|
bounds.bottom = bounds.top + 31;
|
||||||
|
fIconPreview32 = new IconView(bounds, "icon preview 32");
|
||||||
|
|
||||||
|
// bounds.OffsetBy(bounds.Width() + 6, 0);
|
||||||
|
// bounds.right = bounds.left + 47;
|
||||||
|
// bounds.bottom = bounds.top + 47;
|
||||||
|
// fIconPreview48 = new IconView(bounds, "icon preview 48");
|
||||||
|
|
||||||
|
bounds.OffsetBy(bounds.Width() + 6, 0);
|
||||||
|
bounds.right = bounds.left + 63;
|
||||||
|
bounds.bottom = bounds.top + 63;
|
||||||
|
fIconPreview64 = new IconView(bounds, "icon preview 64");
|
||||||
|
|
||||||
|
bounds.OffsetBy(bounds.Width() + 6, 0);
|
||||||
|
bounds.right = bounds.left + 100;
|
||||||
|
bounds.bottom = fCanvasView->Frame().top - 5.0;
|
||||||
|
|
||||||
|
fPathListView = new PathListView(bounds, "path list view");
|
||||||
|
|
||||||
|
bounds.OffsetBy(bounds.Width() + 6 + B_V_SCROLL_BAR_WIDTH, 0);
|
||||||
|
fShapeListView = new ShapeListView(bounds, "shape list view");
|
||||||
|
|
||||||
bg->AddChild(fSwatchGroup);
|
bg->AddChild(fSwatchGroup);
|
||||||
|
|
||||||
|
bg->AddChild(fIconPreview16);
|
||||||
|
bg->AddChild(fIconPreview32);
|
||||||
|
// bg->AddChild(fIconPreview48);
|
||||||
|
bg->AddChild(fIconPreview64);
|
||||||
|
|
||||||
|
bg->AddChild(new BScrollView("path list scroll view",
|
||||||
|
fPathListView,
|
||||||
|
B_FOLLOW_LEFT | B_FOLLOW_TOP,
|
||||||
|
0, false, true,
|
||||||
|
B_NO_BORDER));
|
||||||
|
bg->AddChild(new BScrollView("shape list scroll view",
|
||||||
|
fShapeListView,
|
||||||
|
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,
|
||||||
|
0, false, true,
|
||||||
|
B_NO_BORDER));
|
||||||
|
|
||||||
bg->AddChild(fCanvasView);
|
bg->AddChild(fCanvasView);
|
||||||
|
|
||||||
return bg;
|
return bg;
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
class CanvasView;
|
class CanvasView;
|
||||||
class Document;
|
class Document;
|
||||||
class IconEditorApp;
|
class IconEditorApp;
|
||||||
|
class IconView;
|
||||||
|
class PathListView;
|
||||||
|
class ShapeListView;
|
||||||
class SwatchGroup;
|
class SwatchGroup;
|
||||||
class ViewState;
|
class ViewState;
|
||||||
|
|
||||||
@@ -36,6 +39,14 @@ class MainWindow : public BWindow {
|
|||||||
|
|
||||||
CanvasView* fCanvasView;
|
CanvasView* fCanvasView;
|
||||||
SwatchGroup* fSwatchGroup;
|
SwatchGroup* fSwatchGroup;
|
||||||
|
|
||||||
|
IconView* fIconPreview16;
|
||||||
|
IconView* fIconPreview32;
|
||||||
|
IconView* fIconPreview48;
|
||||||
|
IconView* fIconPreview64;
|
||||||
|
|
||||||
|
PathListView* fPathListView;
|
||||||
|
ShapeListView* fShapeListView;
|
||||||
// TODO: for testing only...
|
// TODO: for testing only...
|
||||||
ViewState* fState;
|
ViewState* fState;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ StyleHandler::generate_span(agg::rgba8* span, int x, int y,
|
|||||||
|
|
||||||
agg::trans_affine transformation;
|
agg::trans_affine transformation;
|
||||||
// TODO: construct the gradient transformation here
|
// TODO: construct the gradient transformation here
|
||||||
|
// remember to invert() it!
|
||||||
|
|
||||||
switch (gradient->Type()) {
|
switch (gradient->Type()) {
|
||||||
case GRADIENT_LINEAR: {
|
case GRADIENT_LINEAR: {
|
||||||
@@ -191,7 +192,9 @@ IconRenderer::IconRenderer(BBitmap* bitmap)
|
|||||||
fBinaryScanline(),
|
fBinaryScanline(),
|
||||||
fSpanAllocator(),
|
fSpanAllocator(),
|
||||||
|
|
||||||
fRasterizer()
|
fRasterizer(),
|
||||||
|
|
||||||
|
fGlobalTransform()
|
||||||
{
|
{
|
||||||
// attach rendering buffer to bitmap
|
// attach rendering buffer to bitmap
|
||||||
fRenderingBuffer.attach((uint8*)bitmap->Bits(),
|
fRenderingBuffer.attach((uint8*)bitmap->Bits(),
|
||||||
@@ -230,6 +233,14 @@ IconRenderer::Render(const BRect& area)
|
|||||||
_Render(fBitmap->Bounds() & area);
|
_Render(fBitmap->Bounds() & area);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//SetScale
|
||||||
|
void
|
||||||
|
IconRenderer::SetScale(double scale)
|
||||||
|
{
|
||||||
|
fGlobalTransform.reset();
|
||||||
|
fGlobalTransform.multiply(agg::trans_affine_scaling(scale));
|
||||||
|
}
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
// _Render
|
// _Render
|
||||||
@@ -247,17 +258,23 @@ IconRenderer::_Render(const BRect& r)
|
|||||||
(int)ceilf(r.bottom));
|
(int)ceilf(r.bottom));
|
||||||
|
|
||||||
fRasterizer.reset();
|
fRasterizer.reset();
|
||||||
// iterate over shapes in icon and
|
// iterate over the shapes in the icon,
|
||||||
// add the vector paths to the rasterizer
|
// add the vector paths to the rasterizer
|
||||||
// and associate the shapes style
|
// and associate each shapes style
|
||||||
int32 shapeCount = fIcon->Shapes()->CountShapes();
|
int32 shapeCount = fIcon->Shapes()->CountShapes();
|
||||||
for (int32 s = 0; s < shapeCount; s++) {
|
for (int32 i = 0; i < shapeCount; i++) {
|
||||||
Shape* shape = fIcon->Shapes()->ShapeAtFast(s);
|
Shape* shape = fIcon->Shapes()->ShapeAtFast(i);
|
||||||
|
|
||||||
int32 styleIndex = fStyles->IndexOf(shape->Style());
|
int32 styleIndex = fStyles->IndexOf(shape->Style());
|
||||||
fRasterizer.styles(styleIndex, -1);
|
fRasterizer.styles(styleIndex, -1);
|
||||||
|
|
||||||
|
if (fGlobalTransform.is_identity()) {
|
||||||
fRasterizer.add_path(shape->VertexSource());
|
fRasterizer.add_path(shape->VertexSource());
|
||||||
|
} else {
|
||||||
|
agg::conv_transform<VertexSource, Transformation>
|
||||||
|
scaledPath(shape->VertexSource(), fGlobalTransform);
|
||||||
|
fRasterizer.add_path(scaledPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyleHandler styleHandler(fStyles, fGammaTable);
|
StyleHandler styleHandler(fStyles, fGammaTable);
|
||||||
@@ -269,6 +286,7 @@ IconRenderer::_Render(const BRect& r)
|
|||||||
fSpanAllocator,
|
fSpanAllocator,
|
||||||
styleHandler);
|
styleHandler);
|
||||||
|
|
||||||
fPixelFormat.apply_gamma_dir(fGammaTable);
|
if (fGammaTable.gamma() != 1.0)
|
||||||
|
fPixelFormat.apply_gamma_inv(fGammaTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,13 +10,14 @@
|
|||||||
#define ICON_RENDERER_H
|
#define ICON_RENDERER_H
|
||||||
|
|
||||||
#include "agg_gamma_lut.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"
|
#include "agg_pixfmt_rgba.h"
|
||||||
|
#include "agg_rasterizer_compound_aa.h"
|
||||||
|
#include "agg_rendering_buffer.h"
|
||||||
|
#include "agg_renderer_scanline.h"
|
||||||
|
#include "agg_scanline_bin.h"
|
||||||
|
#include "agg_scanline_u.h"
|
||||||
|
#include "agg_span_allocator.h"
|
||||||
|
#include "agg_trans_affine.h"
|
||||||
|
|
||||||
class BBitmap;
|
class BBitmap;
|
||||||
class Icon;
|
class Icon;
|
||||||
@@ -37,6 +38,8 @@ typedef agg::span_allocator<agg::rgba8> SpanAllocator;
|
|||||||
typedef agg::rasterizer_compound_aa
|
typedef agg::rasterizer_compound_aa
|
||||||
<agg::rasterizer_sl_clip_dbl> CompoundRasterizer;
|
<agg::rasterizer_sl_clip_dbl> CompoundRasterizer;
|
||||||
|
|
||||||
|
typedef agg::trans_affine Transformation;
|
||||||
|
|
||||||
class IconRenderer {
|
class IconRenderer {
|
||||||
public:
|
public:
|
||||||
IconRenderer(BBitmap* bitmap);
|
IconRenderer(BBitmap* bitmap);
|
||||||
@@ -47,6 +50,8 @@ class IconRenderer {
|
|||||||
void Render();
|
void Render();
|
||||||
void Render(const BRect& area);
|
void Render(const BRect& area);
|
||||||
|
|
||||||
|
void SetScale(double scale);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _Render(const BRect& area);
|
void _Render(const BRect& area);
|
||||||
|
|
||||||
@@ -67,6 +72,8 @@ class IconRenderer {
|
|||||||
SpanAllocator fSpanAllocator;
|
SpanAllocator fSpanAllocator;
|
||||||
|
|
||||||
CompoundRasterizer fRasterizer;
|
CompoundRasterizer fRasterizer;
|
||||||
|
|
||||||
|
Transformation fGlobalTransform;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ICON_RENDERER_H
|
#endif // ICON_RENDERER_H
|
||||||
|
|||||||
@@ -240,7 +240,8 @@ DragSortableListView::InitiateDrag( BPoint point, int32 index, bool )
|
|||||||
}
|
}
|
||||||
BBitmap* dragBitmap = new BBitmap(dragRect, B_RGB32, true);
|
BBitmap* dragBitmap = new BBitmap(dragRect, B_RGB32, true);
|
||||||
if (dragBitmap && dragBitmap->IsValid()) {
|
if (dragBitmap && dragBitmap->IsValid()) {
|
||||||
if ( BView *v = new BView( dragBitmap->Bounds(), "helper", B_FOLLOW_NONE, B_WILL_DRAW ) ) {
|
if (BView *v = new BView(dragBitmap->Bounds(), "helper",
|
||||||
|
B_FOLLOW_NONE, B_WILL_DRAW)) {
|
||||||
dragBitmap->AddChild(v);
|
dragBitmap->AddChild(v);
|
||||||
dragBitmap->Lock();
|
dragBitmap->Lock();
|
||||||
BRect itemBounds(dragRect) ;
|
BRect itemBounds(dragRect) ;
|
||||||
@@ -628,27 +629,23 @@ DragSortableListView::MoveItems( BList& items, int32 index )
|
|||||||
// removal
|
// removal
|
||||||
BList removedItems;
|
BList removedItems;
|
||||||
int32 count = items.CountItems();
|
int32 count = items.CountItems();
|
||||||
for ( int32 i = 0; i < count; i++ )
|
for (int32 i = 0; i < count; i++) {
|
||||||
{
|
|
||||||
BListItem* item = (BListItem*)items.ItemAt(i);
|
BListItem* item = (BListItem*)items.ItemAt(i);
|
||||||
int32 removeIndex = IndexOf(item);
|
int32 removeIndex = IndexOf(item);
|
||||||
if ( RemoveItem( item ) && removedItems.AddItem( (void*)item ) )
|
if (RemoveItem(item) && removedItems.AddItem((void*)item)) {
|
||||||
{
|
|
||||||
if (removeIndex < index)
|
if (removeIndex < index)
|
||||||
index--;
|
index--;
|
||||||
}
|
}
|
||||||
// else ??? -> blow up
|
// else ??? -> blow up
|
||||||
}
|
}
|
||||||
for ( int32 i = 0; BListItem* item = (BListItem*)removedItems.ItemAt( i ); i++ )
|
for (int32 i = 0;
|
||||||
{
|
BListItem* item = (BListItem*)removedItems.ItemAt(i); i++) {
|
||||||
if ( AddItem( item, index ) )
|
if (AddItem(item, index)) {
|
||||||
{
|
|
||||||
// after we're done, the newly inserted items will be selected
|
// after we're done, the newly inserted items will be selected
|
||||||
Select(index, true);
|
Select(index, true);
|
||||||
// next items will be inserted after this one
|
// next items will be inserted after this one
|
||||||
index++;
|
index++;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
delete item;
|
delete item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -664,22 +661,19 @@ DragSortableListView::CopyItems( BList& items, int32 index )
|
|||||||
// need to be cloned
|
// need to be cloned
|
||||||
BList clonedItems;
|
BList clonedItems;
|
||||||
int32 count = items.CountItems();
|
int32 count = items.CountItems();
|
||||||
for ( int32 i = 0; i < count; i++ )
|
for (int32 i = 0; i < count; i++) {
|
||||||
{
|
|
||||||
BListItem* item = CloneItem(IndexOf((BListItem*)items.ItemAt(i)));
|
BListItem* item = CloneItem(IndexOf((BListItem*)items.ItemAt(i)));
|
||||||
if (item && !clonedItems.AddItem((void*)item))
|
if (item && !clonedItems.AddItem((void*)item))
|
||||||
delete item;
|
delete item;
|
||||||
}
|
}
|
||||||
for ( int32 i = 0; BListItem* item = (BListItem*)clonedItems.ItemAt( i ); i++ )
|
for (int32 i = 0;
|
||||||
{
|
BListItem* item = (BListItem*)clonedItems.ItemAt(i); i++) {
|
||||||
if ( AddItem( item, index ) )
|
if (AddItem(item, index)) {
|
||||||
{
|
|
||||||
// after we're done, the newly inserted items will be selected
|
// after we're done, the newly inserted items will be selected
|
||||||
Select(index, true);
|
Select(index, true);
|
||||||
// next items will be inserted after this one
|
// next items will be inserted after this one
|
||||||
index++;
|
index++;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
delete item;
|
delete item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -689,8 +683,7 @@ void
|
|||||||
DragSortableListView::RemoveItemList(BList& items)
|
DragSortableListView::RemoveItemList(BList& items)
|
||||||
{
|
{
|
||||||
int32 count = items.CountItems();
|
int32 count = items.CountItems();
|
||||||
for ( int32 i = 0; i < count; i++ )
|
for (int32 i = 0; i < count; i++) {
|
||||||
{
|
|
||||||
BListItem* item = (BListItem*)items.ItemAt(i);
|
BListItem* item = (BListItem*)items.ItemAt(i);
|
||||||
if (RemoveItem(item))
|
if (RemoveItem(item))
|
||||||
delete item;
|
delete item;
|
||||||
@@ -827,6 +820,7 @@ SimpleListView::~SimpleListView()
|
|||||||
delete fSelectionChangeMessage;
|
delete fSelectionChangeMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LIB_LAYOUT
|
||||||
// layoutprefs
|
// layoutprefs
|
||||||
minimax
|
minimax
|
||||||
SimpleListView::layoutprefs()
|
SimpleListView::layoutprefs()
|
||||||
@@ -847,6 +841,7 @@ SimpleListView::layout(BRect frame)
|
|||||||
ResizeTo(frame.Width(), frame.Height());
|
ResizeTo(frame.Width(), frame.Height());
|
||||||
return Frame();
|
return Frame();
|
||||||
}
|
}
|
||||||
|
#endif // LIB_LAYOUT
|
||||||
|
|
||||||
// MessageReceived
|
// MessageReceived
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -13,7 +13,9 @@
|
|||||||
#include <ListView.h>
|
#include <ListView.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
|
|
||||||
|
#ifdef LIB_LAYOUT
|
||||||
# include <layout.h>
|
# include <layout.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "MouseWheelFilter.h"
|
#include "MouseWheelFilter.h"
|
||||||
|
|
||||||
@@ -148,7 +150,11 @@ class DragSortableListView : public MouseWheelTarget,
|
|||||||
};
|
};
|
||||||
|
|
||||||
// SimpleListView
|
// SimpleListView
|
||||||
class SimpleListView : public MView, public DragSortableListView {
|
class SimpleListView :
|
||||||
|
#ifdef LIB_LAYOUT
|
||||||
|
public MView,
|
||||||
|
#endif
|
||||||
|
public DragSortableListView {
|
||||||
public:
|
public:
|
||||||
SimpleListView(BRect frame,
|
SimpleListView(BRect frame,
|
||||||
BMessage* selectionChangeMessage = NULL);
|
BMessage* selectionChangeMessage = NULL);
|
||||||
@@ -164,10 +170,11 @@ class SimpleListView : public MView, public DragSortableListView {
|
|||||||
| B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE);
|
| B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE);
|
||||||
~SimpleListView();
|
~SimpleListView();
|
||||||
|
|
||||||
|
#ifdef LIB_LAYOUT
|
||||||
// MView
|
// MView
|
||||||
virtual minimax layoutprefs();
|
virtual minimax layoutprefs();
|
||||||
virtual BRect layout(BRect frame);
|
virtual BRect layout(BRect frame);
|
||||||
|
#endif
|
||||||
// BListView
|
// BListView
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
virtual void SelectionChanged();
|
virtual void SelectionChanged();
|
||||||
|
|||||||
@@ -0,0 +1,308 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <[email protected]>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PathListView.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <Application.h>
|
||||||
|
#include <ListItem.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <Mime.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include "VectorPath.h"
|
||||||
|
#include "Observer.h"
|
||||||
|
#include "Selection.h"
|
||||||
|
|
||||||
|
class PathListItem : public SimpleItem,
|
||||||
|
public Observer {
|
||||||
|
public:
|
||||||
|
PathListItem(VectorPath* p,
|
||||||
|
PathListView* listView)
|
||||||
|
: SimpleItem(""),
|
||||||
|
path(NULL),
|
||||||
|
fListView(listView)
|
||||||
|
{
|
||||||
|
SetPath(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~PathListItem()
|
||||||
|
{
|
||||||
|
SetPath(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void ObjectChanged(const Observable* object)
|
||||||
|
{
|
||||||
|
UpdateText();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetPath(VectorPath* p)
|
||||||
|
{
|
||||||
|
if (p == path)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (path) {
|
||||||
|
path->RemoveObserver(this);
|
||||||
|
path->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
path = p;
|
||||||
|
|
||||||
|
if (path) {
|
||||||
|
path->Acquire();
|
||||||
|
path->AddObserver(this);
|
||||||
|
UpdateText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void UpdateText()
|
||||||
|
{
|
||||||
|
SetText(path->Name());
|
||||||
|
// :-/
|
||||||
|
if (fListView->LockLooper()) {
|
||||||
|
fListView->InvalidateItem(
|
||||||
|
fListView->IndexOf(this));
|
||||||
|
fListView->UnlockLooper();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VectorPath* path;
|
||||||
|
private:
|
||||||
|
PathListView* fListView;
|
||||||
|
};
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
PathListView::PathListView(BRect frame,
|
||||||
|
const char* name,
|
||||||
|
BMessage* message, BHandler* target)
|
||||||
|
: SimpleListView(frame, name,
|
||||||
|
NULL, B_SINGLE_SELECTION_LIST),
|
||||||
|
fMessage(message),
|
||||||
|
fPathContainer(NULL),
|
||||||
|
fSelection(NULL)
|
||||||
|
{
|
||||||
|
SetTarget(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
PathListView::~PathListView()
|
||||||
|
{
|
||||||
|
_MakeEmpty();
|
||||||
|
delete fMessage;
|
||||||
|
|
||||||
|
if (fPathContainer)
|
||||||
|
fPathContainer->RemoveListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SelectionChanged
|
||||||
|
void
|
||||||
|
PathListView::SelectionChanged()
|
||||||
|
{
|
||||||
|
// NOTE: single selection list
|
||||||
|
|
||||||
|
PathListItem* item
|
||||||
|
= dynamic_cast<PathListItem*>(ItemAt(CurrentSelection(0)));
|
||||||
|
if (item && fMessage) {
|
||||||
|
BMessage message(*fMessage);
|
||||||
|
message.AddPointer("path", (void*)item->path);
|
||||||
|
Invoke(&message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// modify global Selection
|
||||||
|
if (!fSelection)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// if (item)
|
||||||
|
// fSelection->Select(item->path);
|
||||||
|
// else
|
||||||
|
// fSelection->DeselectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessageReceived
|
||||||
|
void
|
||||||
|
PathListView::MessageReceived(BMessage* message)
|
||||||
|
{
|
||||||
|
SimpleListView::MessageReceived(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeDragMessage
|
||||||
|
void
|
||||||
|
PathListView::MakeDragMessage(BMessage* message) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// AcceptDragMessage
|
||||||
|
bool
|
||||||
|
PathListView::AcceptDragMessage(const BMessage* message) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDropTargetRect
|
||||||
|
void
|
||||||
|
PathListView::SetDropTargetRect(const BMessage* message, BPoint where)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// MoveItems
|
||||||
|
void
|
||||||
|
PathListView::MoveItems(BList& items, int32 toIndex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyItems
|
||||||
|
void
|
||||||
|
PathListView::CopyItems(BList& items, int32 toIndex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveItemList
|
||||||
|
void
|
||||||
|
PathListView::RemoveItemList(BList& indices)
|
||||||
|
{
|
||||||
|
// TODO: allow removing items
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloneItem
|
||||||
|
BListItem*
|
||||||
|
PathListView::CloneItem(int32 index) const
|
||||||
|
{
|
||||||
|
if (PathListItem* item = dynamic_cast<PathListItem*>(ItemAt(index))) {
|
||||||
|
return new PathListItem(item->path,
|
||||||
|
const_cast<PathListView*>(this));
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
// PathAdded
|
||||||
|
void
|
||||||
|
PathListView::PathAdded(VectorPath* path)
|
||||||
|
{
|
||||||
|
// NOTE: we are in the thread that messed with the
|
||||||
|
// ShapeContainer, 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...
|
||||||
|
_AddPath(path);
|
||||||
|
|
||||||
|
UnlockLooper();
|
||||||
|
}
|
||||||
|
|
||||||
|
// PathRemoved
|
||||||
|
void
|
||||||
|
PathListView::PathRemoved(VectorPath* path)
|
||||||
|
{
|
||||||
|
// NOTE: we are in the thread that messed with the
|
||||||
|
// ShapeContainer, 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 VectorPath objects
|
||||||
|
_RemovePath(path);
|
||||||
|
|
||||||
|
UnlockLooper();
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
// SetPathContainer
|
||||||
|
void
|
||||||
|
PathListView::SetPathContainer(PathContainer* container)
|
||||||
|
{
|
||||||
|
if (fPathContainer == container)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// detach from old container
|
||||||
|
if (fPathContainer)
|
||||||
|
fPathContainer->RemoveListener(this);
|
||||||
|
|
||||||
|
_MakeEmpty();
|
||||||
|
|
||||||
|
fPathContainer = container;
|
||||||
|
|
||||||
|
if (!fPathContainer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fPathContainer->AddListener(this);
|
||||||
|
|
||||||
|
// sync
|
||||||
|
// if (!fPathContainer->ReadLock())
|
||||||
|
// return;
|
||||||
|
|
||||||
|
int32 count = fPathContainer->CountPaths();
|
||||||
|
for (int32 i = 0; i < count; i++)
|
||||||
|
_AddPath(fPathContainer->PathAtFast(i));
|
||||||
|
|
||||||
|
// fPathContainer->ReadUnlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSelection
|
||||||
|
void
|
||||||
|
PathListView::SetSelection(Selection* selection)
|
||||||
|
{
|
||||||
|
fSelection = selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
// _AddPath
|
||||||
|
bool
|
||||||
|
PathListView::_AddPath(VectorPath* path)
|
||||||
|
{
|
||||||
|
if (path)
|
||||||
|
return AddItem(new PathListItem(path, this));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _RemovePath
|
||||||
|
bool
|
||||||
|
PathListView::_RemovePath(VectorPath* path)
|
||||||
|
{
|
||||||
|
PathListItem* item = _ItemForPath(path);
|
||||||
|
if (item && RemoveItem(item)) {
|
||||||
|
delete item;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _ItemForPath
|
||||||
|
PathListItem*
|
||||||
|
PathListView::_ItemForPath(VectorPath* path) const
|
||||||
|
{
|
||||||
|
for (int32 i = 0;
|
||||||
|
PathListItem* item = dynamic_cast<PathListItem*>(ItemAt(i));
|
||||||
|
i++) {
|
||||||
|
if (item->path == path)
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _MakeEmpty
|
||||||
|
void
|
||||||
|
PathListView::_MakeEmpty()
|
||||||
|
{
|
||||||
|
// NOTE: BListView::MakeEmpty() uses ScrollTo()
|
||||||
|
// for which the object needs to be attached to
|
||||||
|
// a BWindow.... :-(
|
||||||
|
int32 count = CountItems();
|
||||||
|
for (int32 i = count - 1; i >= 0; i--)
|
||||||
|
delete RemoveItem(i);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <[email protected]>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PATH_LIST_VIEW_H
|
||||||
|
#define PATH_LIST_VIEW_H
|
||||||
|
|
||||||
|
#include "ListViews.h"
|
||||||
|
#include "PathContainer.h"
|
||||||
|
|
||||||
|
class VectorPath;
|
||||||
|
class PathListItem;
|
||||||
|
class Selection;
|
||||||
|
|
||||||
|
class PathListView : public SimpleListView,
|
||||||
|
public PathContainerListener {
|
||||||
|
public:
|
||||||
|
PathListView(BRect frame,
|
||||||
|
const char* name,
|
||||||
|
BMessage* selectionMessage = NULL,
|
||||||
|
BHandler* target = NULL);
|
||||||
|
virtual ~PathListView();
|
||||||
|
|
||||||
|
// SimpleListView interface
|
||||||
|
virtual void SelectionChanged();
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
// ShapeContainerListener interface
|
||||||
|
virtual void PathAdded(VectorPath* path);
|
||||||
|
virtual void PathRemoved(VectorPath* path);
|
||||||
|
|
||||||
|
// PathListView
|
||||||
|
void SetPathContainer(PathContainer* container);
|
||||||
|
void SetSelection(Selection* selection);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _AddPath(VectorPath* path);
|
||||||
|
bool _RemovePath(VectorPath* path);
|
||||||
|
|
||||||
|
PathListItem* _ItemForPath(VectorPath* path) const;
|
||||||
|
void _MakeEmpty();
|
||||||
|
|
||||||
|
BMessage* fMessage;
|
||||||
|
|
||||||
|
PathContainer* fPathContainer;
|
||||||
|
Selection* fSelection;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PATH_LIST_VIEW_H
|
||||||
@@ -0,0 +1,340 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <[email protected]>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ShapeListView.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <Application.h>
|
||||||
|
#include <ListItem.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <Mime.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include "Shape.h"
|
||||||
|
#include "Observer.h"
|
||||||
|
#include "Selection.h"
|
||||||
|
|
||||||
|
class ShapeListItem : public SimpleItem,
|
||||||
|
public Observer {
|
||||||
|
public:
|
||||||
|
ShapeListItem(Shape* s,
|
||||||
|
ShapeListView* listView)
|
||||||
|
: SimpleItem(""),
|
||||||
|
shape(NULL),
|
||||||
|
fListView(listView)
|
||||||
|
{
|
||||||
|
SetClip(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~ShapeListItem()
|
||||||
|
{
|
||||||
|
SetClip(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void ObjectChanged(const Observable* object)
|
||||||
|
{
|
||||||
|
UpdateText();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetClip(Shape* s)
|
||||||
|
{
|
||||||
|
if (s == shape)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (shape) {
|
||||||
|
shape->RemoveObserver(this);
|
||||||
|
shape->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
shape = s;
|
||||||
|
|
||||||
|
if (shape) {
|
||||||
|
shape->Acquire();
|
||||||
|
shape->AddObserver(this);
|
||||||
|
UpdateText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void UpdateText()
|
||||||
|
{
|
||||||
|
SetText(shape->Name());
|
||||||
|
// :-/
|
||||||
|
if (fListView->LockLooper()) {
|
||||||
|
fListView->InvalidateItem(
|
||||||
|
fListView->IndexOf(this));
|
||||||
|
fListView->UnlockLooper();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Shape* shape;
|
||||||
|
private:
|
||||||
|
ShapeListView* fListView;
|
||||||
|
};
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MSG_DRAG_SHAPE = 'drgs',
|
||||||
|
};
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
ShapeListView::ShapeListView(BRect frame,
|
||||||
|
const char* name,
|
||||||
|
BMessage* message, BHandler* target)
|
||||||
|
: SimpleListView(frame, name,
|
||||||
|
NULL, B_MULTIPLE_SELECTION_LIST),
|
||||||
|
fMessage(message),
|
||||||
|
fShapeContainer(NULL),
|
||||||
|
fSelection(NULL)
|
||||||
|
{
|
||||||
|
SetDragCommand(MSG_DRAG_SHAPE);
|
||||||
|
SetTarget(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
ShapeListView::~ShapeListView()
|
||||||
|
{
|
||||||
|
_MakeEmpty();
|
||||||
|
delete fMessage;
|
||||||
|
|
||||||
|
if (fShapeContainer)
|
||||||
|
fShapeContainer->RemoveListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SelectionChanged
|
||||||
|
void
|
||||||
|
ShapeListView::SelectionChanged()
|
||||||
|
{
|
||||||
|
// TODO: single selection versus multiple selection
|
||||||
|
|
||||||
|
ShapeListItem* item = dynamic_cast<ShapeListItem*>(ItemAt(CurrentSelection(0)));
|
||||||
|
if (item && fMessage) {
|
||||||
|
BMessage message(*fMessage);
|
||||||
|
message.AddPointer("shape", (void*)item->shape);
|
||||||
|
Invoke(&message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// modify global Selection
|
||||||
|
if (!fSelection)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (item)
|
||||||
|
fSelection->Select(item->shape);
|
||||||
|
else
|
||||||
|
fSelection->DeselectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessageReceived
|
||||||
|
void
|
||||||
|
ShapeListView::MessageReceived(BMessage* message)
|
||||||
|
{
|
||||||
|
SimpleListView::MessageReceived(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeDragMessage
|
||||||
|
void
|
||||||
|
ShapeListView::MakeDragMessage(BMessage* message) const
|
||||||
|
{
|
||||||
|
SimpleListView::MakeDragMessage(message);
|
||||||
|
message->AddPointer("container", fShapeContainer);
|
||||||
|
int32 count = CountItems();
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
ShapeListItem* item = dynamic_cast<ShapeListItem*>(ItemAt(CurrentSelection(i)));
|
||||||
|
if (item) {
|
||||||
|
message->AddPointer("shape", (void*)item->shape);
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// message->AddInt32("be:actions", B_COPY_TARGET);
|
||||||
|
// message->AddInt32("be:actions", B_TRASH_TARGET);
|
||||||
|
//
|
||||||
|
// message->AddString("be:types", B_FILE_MIME_TYPE);
|
||||||
|
//// message->AddString("be:filetypes", "");
|
||||||
|
//// message->AddString("be:type_descriptions", "");
|
||||||
|
//
|
||||||
|
// message->AddString("be:clip_name", item->shape->Name());
|
||||||
|
//
|
||||||
|
// message->AddString("be:originator", "Icon-O-Matic");
|
||||||
|
// message->AddPointer("be:originator_data", (void*)item->shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
// AcceptDragMessage
|
||||||
|
bool
|
||||||
|
ShapeListView::AcceptDragMessage(const BMessage* message) const
|
||||||
|
{
|
||||||
|
return SimpleListView::AcceptDragMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDropTargetRect
|
||||||
|
void
|
||||||
|
ShapeListView::SetDropTargetRect(const BMessage* message, BPoint where)
|
||||||
|
{
|
||||||
|
SimpleListView::SetDropTargetRect(message, where);
|
||||||
|
}
|
||||||
|
|
||||||
|
// MoveItems
|
||||||
|
void
|
||||||
|
ShapeListView::MoveItems(BList& items, int32 toIndex)
|
||||||
|
{
|
||||||
|
SimpleListView::MoveItems(items, toIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyItems
|
||||||
|
void
|
||||||
|
ShapeListView::CopyItems(BList& items, int32 toIndex)
|
||||||
|
{
|
||||||
|
MoveItems(items, toIndex);
|
||||||
|
// copy operation not allowed -> ?!?
|
||||||
|
// TODO: what about clips that reference the same file but
|
||||||
|
// with different "in/out points"
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveItemList
|
||||||
|
void
|
||||||
|
ShapeListView::RemoveItemList(BList& indices)
|
||||||
|
{
|
||||||
|
// TODO: allow removing items
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloneItem
|
||||||
|
BListItem*
|
||||||
|
ShapeListView::CloneItem(int32 index) const
|
||||||
|
{
|
||||||
|
if (ShapeListItem* item = dynamic_cast<ShapeListItem*>(ItemAt(index))) {
|
||||||
|
return new ShapeListItem(item->shape,
|
||||||
|
const_cast<ShapeListView*>(this));
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
// ShapeAdded
|
||||||
|
void
|
||||||
|
ShapeListView::ShapeAdded(Shape* shape)
|
||||||
|
{
|
||||||
|
// NOTE: we are in the thread that messed with the
|
||||||
|
// ShapeContainer, 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...
|
||||||
|
_AddShape(shape);
|
||||||
|
|
||||||
|
UnlockLooper();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShapeRemoved
|
||||||
|
void
|
||||||
|
ShapeListView::ShapeRemoved(Shape* shape)
|
||||||
|
{
|
||||||
|
// NOTE: we are in the thread that messed with the
|
||||||
|
// ShapeContainer, 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 Shape objects
|
||||||
|
_RemoveShape(shape);
|
||||||
|
|
||||||
|
UnlockLooper();
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
// SetShapeContainer
|
||||||
|
void
|
||||||
|
ShapeListView::SetShapeContainer(ShapeContainer* container)
|
||||||
|
{
|
||||||
|
if (fShapeContainer == container)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// detach from old container
|
||||||
|
if (fShapeContainer)
|
||||||
|
fShapeContainer->RemoveListener(this);
|
||||||
|
|
||||||
|
_MakeEmpty();
|
||||||
|
|
||||||
|
fShapeContainer = container;
|
||||||
|
|
||||||
|
if (!fShapeContainer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fShapeContainer->AddListener(this);
|
||||||
|
|
||||||
|
// sync
|
||||||
|
// if (!fShapeContainer->ReadLock())
|
||||||
|
// return;
|
||||||
|
|
||||||
|
int32 count = fShapeContainer->CountShapes();
|
||||||
|
for (int32 i = 0; i < count; i++)
|
||||||
|
_AddShape(fShapeContainer->ShapeAtFast(i));
|
||||||
|
|
||||||
|
// fShapeContainer->ReadUnlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSelection
|
||||||
|
void
|
||||||
|
ShapeListView::SetSelection(Selection* selection)
|
||||||
|
{
|
||||||
|
fSelection = selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
// _AddShape
|
||||||
|
bool
|
||||||
|
ShapeListView::_AddShape(Shape* shape)
|
||||||
|
{
|
||||||
|
if (shape)
|
||||||
|
return AddItem(new ShapeListItem(shape, this));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _RemoveShape
|
||||||
|
bool
|
||||||
|
ShapeListView::_RemoveShape(Shape* shape)
|
||||||
|
{
|
||||||
|
ShapeListItem* item = _ItemForShape(shape);
|
||||||
|
if (item && RemoveItem(item)) {
|
||||||
|
delete item;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _ItemForShape
|
||||||
|
ShapeListItem*
|
||||||
|
ShapeListView::_ItemForShape(Shape* shape) const
|
||||||
|
{
|
||||||
|
for (int32 i = 0;
|
||||||
|
ShapeListItem* item = dynamic_cast<ShapeListItem*>(ItemAt(i));
|
||||||
|
i++) {
|
||||||
|
if (item->shape == shape)
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _MakeEmpty
|
||||||
|
void
|
||||||
|
ShapeListView::_MakeEmpty()
|
||||||
|
{
|
||||||
|
// NOTE: BListView::MakeEmpty() uses ScrollTo()
|
||||||
|
// for which the object needs to be attached to
|
||||||
|
// a BWindow.... :-(
|
||||||
|
int32 count = CountItems();
|
||||||
|
for (int32 i = count - 1; i >= 0; i--)
|
||||||
|
delete RemoveItem(i);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <[email protected]>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SHAPE_LIST_VIEW_H
|
||||||
|
#define SHAPE_LIST_VIEW_H
|
||||||
|
|
||||||
|
#include "ListViews.h"
|
||||||
|
#include "ShapeContainer.h"
|
||||||
|
|
||||||
|
class Shape;
|
||||||
|
class ShapeListItem;
|
||||||
|
class Selection;
|
||||||
|
|
||||||
|
class ShapeListView : public SimpleListView,
|
||||||
|
public ShapeContainerListener {
|
||||||
|
public:
|
||||||
|
ShapeListView(BRect frame,
|
||||||
|
const char* name,
|
||||||
|
BMessage* selectionMessage = NULL,
|
||||||
|
BHandler* target = NULL);
|
||||||
|
virtual ~ShapeListView();
|
||||||
|
|
||||||
|
// SimpleListView interface
|
||||||
|
virtual void SelectionChanged();
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
// ShapeContainerListener interface
|
||||||
|
virtual void ShapeAdded(Shape* shape);
|
||||||
|
virtual void ShapeRemoved(Shape* shape);
|
||||||
|
|
||||||
|
// ShapeListView
|
||||||
|
void SetShapeContainer(ShapeContainer* container);
|
||||||
|
void SetSelection(Selection* selection);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _AddShape(Shape* shape);
|
||||||
|
bool _RemoveShape(Shape* shape);
|
||||||
|
|
||||||
|
ShapeListItem* _ItemForShape(Shape* shape) const;
|
||||||
|
void _MakeEmpty();
|
||||||
|
|
||||||
|
BMessage* fMessage;
|
||||||
|
|
||||||
|
ShapeContainer* fShapeContainer;
|
||||||
|
Selection* fSelection;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SHAPE_LIST_VIEW_H
|
||||||
@@ -23,7 +23,9 @@ Shape::Shape(::Style* style)
|
|||||||
fPathSource(fPaths),
|
fPathSource(fPaths),
|
||||||
fTransformers(4),
|
fTransformers(4),
|
||||||
|
|
||||||
fLastBounds(0, 0, -1, -1)
|
fLastBounds(0, 0, -1, -1),
|
||||||
|
|
||||||
|
fName("<shape>")
|
||||||
{
|
{
|
||||||
if (fPaths)
|
if (fPaths)
|
||||||
fPaths->AddListener(this);
|
fPaths->AddListener(this);
|
||||||
@@ -77,6 +79,16 @@ Shape::ObjectChanged(const Observable* object)
|
|||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
// SelectedChanged
|
||||||
|
void
|
||||||
|
Shape::SelectedChanged()
|
||||||
|
{
|
||||||
|
// simply pass on the event for now
|
||||||
|
Notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
// InitCheck
|
// InitCheck
|
||||||
status_t
|
status_t
|
||||||
Shape::InitCheck() const
|
Shape::InitCheck() const
|
||||||
@@ -158,3 +170,24 @@ Shape::AppendTransformer(Transformer* transformer)
|
|||||||
Notify();
|
Notify();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
// SetName
|
||||||
|
void
|
||||||
|
Shape::SetName(const char* name)
|
||||||
|
{
|
||||||
|
if (fName == name)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fName = name;
|
||||||
|
Notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name
|
||||||
|
const char*
|
||||||
|
Shape::Name() const
|
||||||
|
{
|
||||||
|
return fName.String();
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,18 +3,21 @@
|
|||||||
|
|
||||||
#include <List.h>
|
#include <List.h>
|
||||||
#include <Rect.h>
|
#include <Rect.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
#include "Observable.h"
|
#include "Observable.h"
|
||||||
#include "Observer.h"
|
#include "Observer.h"
|
||||||
#include "PathContainer.h"
|
#include "PathContainer.h"
|
||||||
#include "PathSource.h"
|
#include "PathSource.h"
|
||||||
#include "Referenceable.h"
|
#include "Referenceable.h"
|
||||||
|
#include "Selectable.h"
|
||||||
|
|
||||||
class Style;
|
class Style;
|
||||||
|
|
||||||
class Shape : public Observable,
|
class Shape : public Observable,
|
||||||
public Observer, // observing all the paths
|
public Observer, // observing all the paths
|
||||||
public Referenceable,
|
public Referenceable,
|
||||||
|
public Selectable,
|
||||||
public PathContainerListener {
|
public PathContainerListener {
|
||||||
public:
|
public:
|
||||||
Shape(::Style* style);
|
Shape(::Style* style);
|
||||||
@@ -27,6 +30,9 @@ class Shape : public Observable,
|
|||||||
// Observer interface
|
// Observer interface
|
||||||
virtual void ObjectChanged(const Observable* object);
|
virtual void ObjectChanged(const Observable* object);
|
||||||
|
|
||||||
|
// Selectable interface
|
||||||
|
virtual void SelectedChanged();
|
||||||
|
|
||||||
// Shape
|
// Shape
|
||||||
status_t InitCheck() const;
|
status_t InitCheck() const;
|
||||||
|
|
||||||
@@ -45,6 +51,9 @@ class Shape : public Observable,
|
|||||||
bool AppendTransformer(
|
bool AppendTransformer(
|
||||||
Transformer* transformer);
|
Transformer* transformer);
|
||||||
|
|
||||||
|
void SetName(const char* name);
|
||||||
|
const char* Name() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PathContainer* fPaths;
|
PathContainer* fPaths;
|
||||||
::Style* fStyle;
|
::Style* fStyle;
|
||||||
@@ -53,6 +62,8 @@ class Shape : public Observable,
|
|||||||
BList fTransformers;
|
BList fTransformers;
|
||||||
|
|
||||||
mutable BRect fLastBounds;
|
mutable BRect fLastBounds;
|
||||||
|
|
||||||
|
BString fName;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHAPE_H
|
#endif // SHAPE_H
|
||||||
|
|||||||
@@ -78,7 +78,8 @@ VectorPath::VectorPath()
|
|||||||
fClosed(false),
|
fClosed(false),
|
||||||
fPointCount(0),
|
fPointCount(0),
|
||||||
fAllocCount(0),
|
fAllocCount(0),
|
||||||
fCachedBounds(0.0, 0.0, -1.0, -1.0)
|
fCachedBounds(0.0, 0.0, -1.0, -1.0),
|
||||||
|
fName("<path>")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +91,8 @@ VectorPath::VectorPath(const VectorPath& from)
|
|||||||
fPath(NULL),
|
fPath(NULL),
|
||||||
fPointCount(0),
|
fPointCount(0),
|
||||||
fAllocCount(0),
|
fAllocCount(0),
|
||||||
fCachedBounds(0.0, 0.0, -1.0, -1.0)
|
fCachedBounds(0.0, 0.0, -1.0, -1.0),
|
||||||
|
fName()
|
||||||
{
|
{
|
||||||
*this = from;
|
*this = from;
|
||||||
}
|
}
|
||||||
@@ -104,7 +106,8 @@ VectorPath::VectorPath(const BMessage* archive)
|
|||||||
fClosed(false),
|
fClosed(false),
|
||||||
fPointCount(0),
|
fPointCount(0),
|
||||||
fAllocCount(0),
|
fAllocCount(0),
|
||||||
fCachedBounds(0.0, 0.0, -1.0, -1.0)
|
fCachedBounds(0.0, 0.0, -1.0, -1.0),
|
||||||
|
fName()
|
||||||
{
|
{
|
||||||
if (archive) {
|
if (archive) {
|
||||||
type_code typeFound;
|
type_code typeFound;
|
||||||
@@ -130,6 +133,9 @@ VectorPath::VectorPath(const BMessage* archive)
|
|||||||
if (archive->FindBool("path closed", &fClosed) < B_OK) {
|
if (archive->FindBool("path closed", &fClosed) < B_OK) {
|
||||||
fClosed = false;
|
fClosed = false;
|
||||||
}
|
}
|
||||||
|
if (archive->FindString("name", &fName) < B_OK) {
|
||||||
|
fName = "<path>";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,6 +161,7 @@ VectorPath::operator=(const VectorPath& from)
|
|||||||
fPointCount = 0;
|
fPointCount = 0;
|
||||||
fCachedBounds.Set(0.0, 0.0, -1.0, -1.0);
|
fCachedBounds.Set(0.0, 0.0, -1.0, -1.0);
|
||||||
}
|
}
|
||||||
|
fName = from.fName;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -171,7 +178,9 @@ status_t
|
|||||||
VectorPath::Archive(BMessage* into, bool deep) const
|
VectorPath::Archive(BMessage* into, bool deep) const
|
||||||
{
|
{
|
||||||
status_t ret = BArchivable::Archive(into, deep);
|
status_t ret = BArchivable::Archive(into, deep);
|
||||||
if (ret >= B_OK) {
|
if (ret < B_OK)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (fPointCount > 0) {
|
if (fPointCount > 0) {
|
||||||
// improve BMessage efficency by preallocating storage for all points
|
// improve BMessage efficency by preallocating storage for all points
|
||||||
// with the first call
|
// with the first call
|
||||||
@@ -203,14 +212,19 @@ VectorPath::Archive(BMessage* into, bool deep) const
|
|||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "failed adding points!\n");
|
fprintf(stderr, "failed adding points!\n");
|
||||||
}
|
}
|
||||||
|
if (ret >= B_OK) {
|
||||||
|
ret = into->AddString("name", fName.String());
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "failed adding close!\n");
|
||||||
|
}
|
||||||
if (ret < B_OK) {
|
if (ret < B_OK) {
|
||||||
fprintf(stderr, "failed adding closed!\n");
|
fprintf(stderr, "failed adding name!\n");
|
||||||
}
|
}
|
||||||
// finish off
|
// finish off
|
||||||
if (ret < B_OK) {
|
if (ret < B_OK) {
|
||||||
ret = into->AddString("class", "VectorPath");
|
ret = into->AddString("class", "VectorPath");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -829,6 +843,28 @@ VectorPath::_SetPoint(int32 index, BPoint point)
|
|||||||
fCachedBounds.Set(0.0, 0.0, -1.0, -1.0);
|
fCachedBounds.Set(0.0, 0.0, -1.0, -1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
// SetName
|
||||||
|
void
|
||||||
|
VectorPath::SetName(const char* name)
|
||||||
|
{
|
||||||
|
if (fName == name)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fName = name;
|
||||||
|
Notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name
|
||||||
|
const char*
|
||||||
|
VectorPath::Name() const
|
||||||
|
{
|
||||||
|
return fName.String();
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
// _SetPointCount
|
// _SetPointCount
|
||||||
bool
|
bool
|
||||||
VectorPath::_SetPointCount(int32 count)
|
VectorPath::_SetPointCount(int32 count)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <Archivable.h>
|
#include <Archivable.h>
|
||||||
#include <Rect.h>
|
#include <Rect.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
#include <agg_path_storage.h>
|
#include <agg_path_storage.h>
|
||||||
|
|
||||||
@@ -121,6 +122,9 @@ class VectorPath : public BArchivable,
|
|||||||
|
|
||||||
bool GetAGGPathStorage(agg::path_storage& path) const;
|
bool GetAGGPathStorage(agg::path_storage& path) const;
|
||||||
|
|
||||||
|
void SetName(const char* name);
|
||||||
|
const char* Name() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BRect _Bounds() const;
|
BRect _Bounds() const;
|
||||||
void _SetPoint(int32 index, BPoint point);
|
void _SetPoint(int32 index, BPoint point);
|
||||||
@@ -134,6 +138,9 @@ class VectorPath : public BArchivable,
|
|||||||
int32 fAllocCount;
|
int32 fAllocCount;
|
||||||
|
|
||||||
mutable BRect fCachedBounds;
|
mutable BRect fCachedBounds;
|
||||||
|
|
||||||
|
// TODO: should this really be part of VectorPath?
|
||||||
|
BString fName;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VECTOR_PATH_H
|
#endif // VECTOR_PATH_H
|
||||||
|
|||||||
Reference in New Issue
Block a user