* 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:
parent
deca617c6b
commit
cfda5dd75b
99
src/apps/icon-o-matic/IconView.cpp
Normal file
99
src/apps/icon-o-matic/IconView.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
*/
|
||||
|
||||
#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);
|
||||
}
|
||||
|
44
src/apps/icon-o-matic/IconView.h
Normal file
44
src/apps/icon-o-matic/IconView.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
*/
|
||||
|
||||
#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
|
||||
Command.cpp
|
||||
CommandStack.cpp
|
||||
# generic/selection
|
||||
Selectable.cpp
|
||||
Selection.cpp
|
||||
# generic/gui
|
||||
Group.cpp
|
||||
ListViews.cpp
|
||||
SwatchView.cpp
|
||||
# generic/gui/panel
|
||||
Panel.cpp
|
||||
@ -70,6 +72,8 @@ Application Icon-O-Matic :
|
||||
support.cpp
|
||||
support_ui.cpp
|
||||
# gui
|
||||
PathListView.cpp
|
||||
ShapeListView.cpp
|
||||
SwatchGroup.cpp
|
||||
# gradient
|
||||
Gradient.cpp
|
||||
@ -98,6 +102,7 @@ Application Icon-O-Matic :
|
||||
#
|
||||
CanvasView.cpp
|
||||
IconEditorApp.cpp
|
||||
IconView.cpp
|
||||
main.cpp
|
||||
MainWindow.cpp
|
||||
: be libagg.a
|
||||
|
@ -11,10 +11,14 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Message.h>
|
||||
#include <ScrollView.h>
|
||||
|
||||
#include "Document.h"
|
||||
#include "CanvasView.h"
|
||||
#include "IconEditorApp.h"
|
||||
#include "IconView.h"
|
||||
#include "PathListView.h"
|
||||
#include "ShapeListView.h"
|
||||
#include "SwatchGroup.h"
|
||||
|
||||
// TODO: just for testing
|
||||
@ -25,6 +29,7 @@
|
||||
#include "PathManipulator.h"
|
||||
#include "Shape.h"
|
||||
#include "ShapeContainer.h"
|
||||
#include "ShapeListView.h"
|
||||
#include "StrokeTransformer.h"
|
||||
#include "Style.h"
|
||||
#include "StyleManager.h"
|
||||
@ -36,8 +41,7 @@ MainWindow::MainWindow(IconEditorApp* app, Document* document)
|
||||
B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
|
||||
B_ASYNCHRONOUS_CONTROLS),
|
||||
fApp(app),
|
||||
fDocument(document),
|
||||
fCanvasView(NULL)
|
||||
fDocument(document)
|
||||
{
|
||||
_Init();
|
||||
}
|
||||
@ -87,6 +91,19 @@ MainWindow::_Init()
|
||||
// fCanvasView->SetSelection(fDocument->Selection());
|
||||
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:
|
||||
MultipleManipulatorState* state = new MultipleManipulatorState(fCanvasView);
|
||||
fCanvasView->SetState(state);
|
||||
@ -112,6 +129,7 @@ MainWindow::_Init()
|
||||
Shape* shape = new Shape(style2);
|
||||
shape->Paths()->AddPath(path);
|
||||
|
||||
shape->SetName("Gradient");
|
||||
fDocument->Icon()->Shapes()->AddShape(shape);
|
||||
|
||||
shape = new Shape(style1);
|
||||
@ -121,6 +139,7 @@ MainWindow::_Init()
|
||||
transformer->width(5.0);
|
||||
shape->AppendTransformer(transformer);
|
||||
|
||||
shape->SetName("Outline");
|
||||
fDocument->Icon()->Shapes()->AddShape(shape);
|
||||
|
||||
Style* style3 = new Style();
|
||||
@ -137,6 +156,7 @@ MainWindow::_Init()
|
||||
*transformer2 *= agg::trans_affine_scaling(0.8, 0.6);
|
||||
shape->AppendTransformer(transformer2);
|
||||
|
||||
shape->SetName("Transformed");
|
||||
fDocument->Icon()->Shapes()->AddShape(shape);
|
||||
|
||||
PathManipulator* pathManipulator = new PathManipulator(path);
|
||||
@ -157,7 +177,54 @@ MainWindow::_CreateGUI(BRect 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(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);
|
||||
|
||||
return bg;
|
||||
|
@ -14,6 +14,9 @@
|
||||
class CanvasView;
|
||||
class Document;
|
||||
class IconEditorApp;
|
||||
class IconView;
|
||||
class PathListView;
|
||||
class ShapeListView;
|
||||
class SwatchGroup;
|
||||
class ViewState;
|
||||
|
||||
@ -36,6 +39,14 @@ class MainWindow : public BWindow {
|
||||
|
||||
CanvasView* fCanvasView;
|
||||
SwatchGroup* fSwatchGroup;
|
||||
|
||||
IconView* fIconPreview16;
|
||||
IconView* fIconPreview32;
|
||||
IconView* fIconPreview48;
|
||||
IconView* fIconPreview64;
|
||||
|
||||
PathListView* fPathListView;
|
||||
ShapeListView* fShapeListView;
|
||||
// TODO: for testing only...
|
||||
ViewState* fState;
|
||||
};
|
||||
|
@ -103,6 +103,7 @@ StyleHandler::generate_span(agg::rgba8* span, int x, int y,
|
||||
|
||||
agg::trans_affine transformation;
|
||||
// TODO: construct the gradient transformation here
|
||||
// remember to invert() it!
|
||||
|
||||
switch (gradient->Type()) {
|
||||
case GRADIENT_LINEAR: {
|
||||
@ -191,7 +192,9 @@ IconRenderer::IconRenderer(BBitmap* bitmap)
|
||||
fBinaryScanline(),
|
||||
fSpanAllocator(),
|
||||
|
||||
fRasterizer()
|
||||
fRasterizer(),
|
||||
|
||||
fGlobalTransform()
|
||||
{
|
||||
// attach rendering buffer to bitmap
|
||||
fRenderingBuffer.attach((uint8*)bitmap->Bits(),
|
||||
@ -230,6 +233,14 @@ IconRenderer::Render(const BRect& area)
|
||||
_Render(fBitmap->Bounds() & area);
|
||||
}
|
||||
|
||||
//SetScale
|
||||
void
|
||||
IconRenderer::SetScale(double scale)
|
||||
{
|
||||
fGlobalTransform.reset();
|
||||
fGlobalTransform.multiply(agg::trans_affine_scaling(scale));
|
||||
}
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
// _Render
|
||||
@ -247,17 +258,23 @@ IconRenderer::_Render(const BRect& r)
|
||||
(int)ceilf(r.bottom));
|
||||
|
||||
fRasterizer.reset();
|
||||
// iterate over shapes in icon and
|
||||
// iterate over the shapes in the icon,
|
||||
// add the vector paths to the rasterizer
|
||||
// and associate the shapes style
|
||||
// and associate each shapes style
|
||||
int32 shapeCount = fIcon->Shapes()->CountShapes();
|
||||
for (int32 s = 0; s < shapeCount; s++) {
|
||||
Shape* shape = fIcon->Shapes()->ShapeAtFast(s);
|
||||
for (int32 i = 0; i < shapeCount; i++) {
|
||||
Shape* shape = fIcon->Shapes()->ShapeAtFast(i);
|
||||
|
||||
int32 styleIndex = fStyles->IndexOf(shape->Style());
|
||||
fRasterizer.styles(styleIndex, -1);
|
||||
|
||||
if (fGlobalTransform.is_identity()) {
|
||||
fRasterizer.add_path(shape->VertexSource());
|
||||
} else {
|
||||
agg::conv_transform<VertexSource, Transformation>
|
||||
scaledPath(shape->VertexSource(), fGlobalTransform);
|
||||
fRasterizer.add_path(scaledPath);
|
||||
}
|
||||
}
|
||||
|
||||
StyleHandler styleHandler(fStyles, fGammaTable);
|
||||
@ -269,6 +286,7 @@ IconRenderer::_Render(const BRect& r)
|
||||
fSpanAllocator,
|
||||
styleHandler);
|
||||
|
||||
fPixelFormat.apply_gamma_dir(fGammaTable);
|
||||
if (fGammaTable.gamma() != 1.0)
|
||||
fPixelFormat.apply_gamma_inv(fGammaTable);
|
||||
}
|
||||
|
||||
|
@ -10,13 +10,14 @@
|
||||
#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"
|
||||
#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 Icon;
|
||||
@ -37,6 +38,8 @@ typedef agg::span_allocator<agg::rgba8> SpanAllocator;
|
||||
typedef agg::rasterizer_compound_aa
|
||||
<agg::rasterizer_sl_clip_dbl> CompoundRasterizer;
|
||||
|
||||
typedef agg::trans_affine Transformation;
|
||||
|
||||
class IconRenderer {
|
||||
public:
|
||||
IconRenderer(BBitmap* bitmap);
|
||||
@ -47,6 +50,8 @@ class IconRenderer {
|
||||
void Render();
|
||||
void Render(const BRect& area);
|
||||
|
||||
void SetScale(double scale);
|
||||
|
||||
private:
|
||||
void _Render(const BRect& area);
|
||||
|
||||
@ -67,6 +72,8 @@ class IconRenderer {
|
||||
SpanAllocator fSpanAllocator;
|
||||
|
||||
CompoundRasterizer fRasterizer;
|
||||
|
||||
Transformation fGlobalTransform;
|
||||
};
|
||||
|
||||
#endif // ICON_RENDERER_H
|
||||
|
@ -32,8 +32,8 @@ enum {
|
||||
};
|
||||
|
||||
// SimpleItem class
|
||||
SimpleItem::SimpleItem( const char *name )
|
||||
: BStringItem( name )
|
||||
SimpleItem::SimpleItem(const char *name)
|
||||
: BStringItem(name)
|
||||
{
|
||||
}
|
||||
|
||||
@ -47,13 +47,13 @@ SimpleItem::Draw(BView *owner, BRect frame, uint32 flags)
|
||||
{
|
||||
DrawBackground(owner, frame, flags);
|
||||
// label
|
||||
owner->SetHighColor( 0, 0, 0, 255 );
|
||||
owner->SetHighColor(0, 0, 0, 255);
|
||||
font_height fh;
|
||||
owner->GetFontHeight( &fh );
|
||||
owner->GetFontHeight(&fh);
|
||||
const char* text = Text();
|
||||
BString truncatedString( text );
|
||||
owner->TruncateString( &truncatedString, B_TRUNCATE_MIDDLE,
|
||||
frame.Width() - TEXT_OFFSET - 4.0 );
|
||||
BString truncatedString(text);
|
||||
owner->TruncateString(&truncatedString, B_TRUNCATE_MIDDLE,
|
||||
frame.Width() - TEXT_OFFSET - 4.0);
|
||||
float height = frame.Height();
|
||||
float textHeight = fh.ascent + fh.descent;
|
||||
BPoint textPoint;
|
||||
@ -76,13 +76,13 @@ SimpleItem::DrawBackground(BView *owner, BRect frame, uint32 flags)
|
||||
}
|
||||
// figure out bg-color
|
||||
rgb_color color = (rgb_color){ 255, 255, 255, 255 };
|
||||
if ( flags & FLAGS_TINTED_LINE )
|
||||
color = tint_color( color, 1.06 );
|
||||
if (flags & FLAGS_TINTED_LINE)
|
||||
color = tint_color(color, 1.06);
|
||||
// background
|
||||
if ( IsSelected() )
|
||||
color = tint_color( color, B_DARKEN_2_TINT );
|
||||
owner->SetLowColor( color );
|
||||
owner->FillRect( frame, B_SOLID_LOW );
|
||||
if (IsSelected())
|
||||
color = tint_color(color, B_DARKEN_2_TINT);
|
||||
owner->SetLowColor(color);
|
||||
owner->FillRect(frame, B_SOLID_LOW);
|
||||
}
|
||||
|
||||
// DragSortableListView class
|
||||
@ -150,7 +150,7 @@ DragSortableListView::MakeFocus(bool focused)
|
||||
*/
|
||||
// Draw
|
||||
void
|
||||
DragSortableListView::Draw( BRect updateRect )
|
||||
DragSortableListView::Draw(BRect updateRect)
|
||||
{
|
||||
int32 firstIndex = IndexOf(updateRect.LeftTop());
|
||||
int32 lastIndex = IndexOf(updateRect.RightBottom());
|
||||
@ -206,58 +206,59 @@ DragSortableListView::TargetedByScrollView(BScrollView* scrollView)
|
||||
|
||||
// InitiateDrag
|
||||
bool
|
||||
DragSortableListView::InitiateDrag( BPoint point, int32 index, bool )
|
||||
DragSortableListView::InitiateDrag(BPoint point, int32 index, bool)
|
||||
{
|
||||
// supress drag&drop while an item is focused
|
||||
if (fFocusedIndex >= 0)
|
||||
return false;
|
||||
|
||||
bool success = false;
|
||||
BListItem* item = ItemAt( CurrentSelection( 0 ) );
|
||||
if ( !item ) {
|
||||
BListItem* item = ItemAt(CurrentSelection(0));
|
||||
if (!item) {
|
||||
// workarround a timing problem
|
||||
Select( index );
|
||||
item = ItemAt( index );
|
||||
Select(index);
|
||||
item = ItemAt(index);
|
||||
}
|
||||
if ( item ) {
|
||||
if (item) {
|
||||
// create drag message
|
||||
BMessage msg( fDragCommand );
|
||||
MakeDragMessage( &msg );
|
||||
BMessage msg(fDragCommand);
|
||||
MakeDragMessage(&msg);
|
||||
// figure out drag rect
|
||||
float width = Bounds().Width();
|
||||
BRect dragRect(0.0, 0.0, width, -1.0);
|
||||
// figure out, how many items fit into our bitmap
|
||||
int32 numItems;
|
||||
bool fade = false;
|
||||
for (numItems = 0; BListItem* item = ItemAt( CurrentSelection( numItems ) ); numItems++) {
|
||||
dragRect.bottom += ceilf( item->Height() ) + 1.0;
|
||||
if ( dragRect.Height() > MAX_DRAG_HEIGHT ) {
|
||||
for (numItems = 0; BListItem* item = ItemAt(CurrentSelection(numItems)); numItems++) {
|
||||
dragRect.bottom += ceilf(item->Height()) + 1.0;
|
||||
if (dragRect.Height() > MAX_DRAG_HEIGHT) {
|
||||
fade = true;
|
||||
dragRect.bottom = MAX_DRAG_HEIGHT;
|
||||
numItems++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
BBitmap* dragBitmap = new BBitmap( dragRect, B_RGB32, true );
|
||||
if ( dragBitmap && dragBitmap->IsValid() ) {
|
||||
if ( BView *v = new BView( dragBitmap->Bounds(), "helper", B_FOLLOW_NONE, B_WILL_DRAW ) ) {
|
||||
dragBitmap->AddChild( v );
|
||||
BBitmap* dragBitmap = new BBitmap(dragRect, B_RGB32, true);
|
||||
if (dragBitmap && dragBitmap->IsValid()) {
|
||||
if (BView *v = new BView(dragBitmap->Bounds(), "helper",
|
||||
B_FOLLOW_NONE, B_WILL_DRAW)) {
|
||||
dragBitmap->AddChild(v);
|
||||
dragBitmap->Lock();
|
||||
BRect itemBounds( dragRect) ;
|
||||
BRect itemBounds(dragRect) ;
|
||||
itemBounds.bottom = 0.0;
|
||||
// let all selected items, that fit into our drag_bitmap, draw
|
||||
for ( int32 i = 0; i < numItems; i++ ) {
|
||||
int32 index = CurrentSelection( i );
|
||||
BListItem* item = ItemAt( index );
|
||||
itemBounds.bottom = itemBounds.top + ceilf( item->Height() );
|
||||
if ( itemBounds.bottom > dragRect.bottom )
|
||||
for (int32 i = 0; i < numItems; i++) {
|
||||
int32 index = CurrentSelection(i);
|
||||
BListItem* item = ItemAt(index);
|
||||
itemBounds.bottom = itemBounds.top + ceilf(item->Height());
|
||||
if (itemBounds.bottom > dragRect.bottom)
|
||||
itemBounds.bottom = dragRect.bottom;
|
||||
DrawListItem( v, index, itemBounds );
|
||||
DrawListItem(v, index, itemBounds);
|
||||
itemBounds.top = itemBounds.bottom + 1.0;
|
||||
}
|
||||
// make a black frame arround the edge
|
||||
v->SetHighColor( 0, 0, 0, 255 );
|
||||
v->StrokeRect( v->Bounds() );
|
||||
v->SetHighColor(0, 0, 0, 255);
|
||||
v->StrokeRect(v->Bounds());
|
||||
v->Sync();
|
||||
|
||||
uint8 *bits = (uint8 *)dragBitmap->Bits();
|
||||
@ -266,18 +267,18 @@ DragSortableListView::InitiateDrag( BPoint point, int32 index, bool )
|
||||
int32 bpr = dragBitmap->BytesPerRow();
|
||||
|
||||
if (fade) {
|
||||
for ( int32 y = 0; y < height - ALPHA / 2; y++, bits += bpr ) {
|
||||
for (int32 y = 0; y < height - ALPHA / 2; y++, bits += bpr) {
|
||||
uint8 *line = bits + 3;
|
||||
for (uint8 *end = line + 4 * width; line < end; line += 4)
|
||||
*line = ALPHA;
|
||||
}
|
||||
for ( int32 y = height - ALPHA / 2; y < height; y++, bits += bpr ) {
|
||||
for (int32 y = height - ALPHA / 2; y < height; y++, bits += bpr) {
|
||||
uint8 *line = bits + 3;
|
||||
for (uint8 *end = line + 4 * width; line < end; line += 4)
|
||||
*line = (height - y) << 1;
|
||||
}
|
||||
} else {
|
||||
for ( int32 y = 0; y < height; y++, bits += bpr ) {
|
||||
for (int32 y = 0; y < height; y++, bits += bpr) {
|
||||
uint8 *line = bits + 3;
|
||||
for (uint8 *end = line + 4 * width; line < end; line += 4)
|
||||
*line = ALPHA;
|
||||
@ -290,9 +291,9 @@ DragSortableListView::InitiateDrag( BPoint point, int32 index, bool )
|
||||
dragBitmap = NULL;
|
||||
}
|
||||
if (dragBitmap)
|
||||
DragMessage( &msg, dragBitmap, B_OP_ALPHA, BPoint( 0.0, 0.0 ) );
|
||||
DragMessage(&msg, dragBitmap, B_OP_ALPHA, BPoint(0.0, 0.0));
|
||||
else
|
||||
DragMessage( &msg, dragRect.OffsetToCopy( point ), this );
|
||||
DragMessage(&msg, dragRect.OffsetToCopy(point), this);
|
||||
|
||||
_SetDragMessage(&msg);
|
||||
success = true;
|
||||
@ -302,10 +303,10 @@ DragSortableListView::InitiateDrag( BPoint point, int32 index, bool )
|
||||
|
||||
// WindowActivated
|
||||
void
|
||||
DragSortableListView::WindowActivated( bool active )
|
||||
DragSortableListView::WindowActivated(bool active)
|
||||
{
|
||||
// workarround for buggy focus indication of BScrollView
|
||||
if ( BView* view = Parent() )
|
||||
if (BView* view = Parent())
|
||||
view->Invalidate();
|
||||
}
|
||||
|
||||
@ -315,26 +316,26 @@ DragSortableListView::MessageReceived(BMessage* message)
|
||||
{
|
||||
if (message->what == fDragCommand) {
|
||||
DragSortableListView *list = NULL;
|
||||
if ( message->FindPointer( "list", (void **)&list ) == B_OK
|
||||
&& list == this ) {
|
||||
if (message->FindPointer("list", (void **)&list) == B_OK
|
||||
&& list == this) {
|
||||
int32 count = CountItems();
|
||||
if ( fDropIndex < 0 || fDropIndex > count )
|
||||
if (fDropIndex < 0 || fDropIndex > count)
|
||||
fDropIndex = count;
|
||||
BList items;
|
||||
int32 index;
|
||||
for ( int32 i = 0; message->FindInt32( "index", i, &index ) == B_OK; i++ )
|
||||
if ( BListItem* item = ItemAt(index) )
|
||||
items.AddItem( (void*)item );
|
||||
if ( items.CountItems() > 0 ) {
|
||||
if ( modifiers() & B_SHIFT_KEY )
|
||||
CopyItems( items, fDropIndex );
|
||||
for (int32 i = 0; message->FindInt32("index", i, &index) == B_OK; i++)
|
||||
if (BListItem* item = ItemAt(index))
|
||||
items.AddItem((void*)item);
|
||||
if (items.CountItems() > 0) {
|
||||
if (modifiers() & B_SHIFT_KEY)
|
||||
CopyItems(items, fDropIndex);
|
||||
else
|
||||
MoveItems( items, fDropIndex );
|
||||
MoveItems(items, fDropIndex);
|
||||
}
|
||||
fDropIndex = -1;
|
||||
}
|
||||
} else {
|
||||
switch ( message->what ) {
|
||||
switch (message->what) {
|
||||
case MSG_TICK: {
|
||||
float scrollV = 0.0;
|
||||
BRect rect(Bounds());
|
||||
@ -370,7 +371,7 @@ DragSortableListView::MessageReceived(BMessage* message)
|
||||
// ModifiersChanged();
|
||||
// break;
|
||||
case B_MOUSE_WHEEL_CHANGED: {
|
||||
BListView::MessageReceived( message );
|
||||
BListView::MessageReceived(message);
|
||||
BPoint point;
|
||||
uint32 buttons;
|
||||
GetMouse(&point, &buttons, false);
|
||||
@ -379,7 +380,7 @@ DragSortableListView::MessageReceived(BMessage* message)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BListView::MessageReceived( message );
|
||||
BListView::MessageReceived(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -387,20 +388,20 @@ DragSortableListView::MessageReceived(BMessage* message)
|
||||
|
||||
// KeyDown
|
||||
void
|
||||
DragSortableListView::KeyDown( const char* bytes, int32 numBytes )
|
||||
DragSortableListView::KeyDown(const char* bytes, int32 numBytes)
|
||||
{
|
||||
if ( numBytes < 1 )
|
||||
if (numBytes < 1)
|
||||
return;
|
||||
|
||||
if ( ( bytes[0] == B_BACKSPACE ) || ( bytes[0] == B_DELETE ) )
|
||||
if ((bytes[0] == B_BACKSPACE) || (bytes[0] == B_DELETE))
|
||||
RemoveSelected();
|
||||
|
||||
BListView::KeyDown( bytes, numBytes );
|
||||
BListView::KeyDown(bytes, numBytes);
|
||||
}
|
||||
|
||||
// MouseDown
|
||||
void
|
||||
DragSortableListView::MouseDown( BPoint where )
|
||||
DragSortableListView::MouseDown(BPoint where)
|
||||
{
|
||||
int32 clicks = 1;
|
||||
uint32 buttons = 0;
|
||||
@ -478,14 +479,14 @@ DragSortableListView::MouseMoved(BPoint where, uint32 transit, const BMessage *m
|
||||
|
||||
// MouseUp
|
||||
void
|
||||
DragSortableListView::MouseUp( BPoint where )
|
||||
DragSortableListView::MouseUp(BPoint where)
|
||||
{
|
||||
// remove drop mark
|
||||
_SetDropAnticipationRect( BRect( 0.0, 0.0, -1.0, -1.0 ) );
|
||||
_SetDropAnticipationRect(BRect(0.0, 0.0, -1.0, -1.0));
|
||||
SetAutoScrolling(false);
|
||||
// be sure to forget drag message
|
||||
_SetDragMessage(NULL);
|
||||
BListView::MouseUp( where );
|
||||
BListView::MouseUp(where);
|
||||
|
||||
BCursor cursor(B_HAND_CURSOR);
|
||||
SetViewCursor(&cursor, true);
|
||||
@ -493,9 +494,9 @@ DragSortableListView::MouseUp( BPoint where )
|
||||
|
||||
// DrawItem
|
||||
void
|
||||
DragSortableListView::DrawItem( BListItem *item, BRect itemFrame, bool complete )
|
||||
DragSortableListView::DrawItem(BListItem *item, BRect itemFrame, bool complete)
|
||||
{
|
||||
DrawListItem( this, IndexOf( item ), itemFrame );
|
||||
DrawListItem(this, IndexOf(item), itemFrame);
|
||||
/* if (IsFocus()) {
|
||||
SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR));
|
||||
StrokeRect(Bounds());
|
||||
@ -620,7 +621,7 @@ DragSortableListView::ScrollTo(int32 index)
|
||||
|
||||
// MoveItems
|
||||
void
|
||||
DragSortableListView::MoveItems( BList& items, int32 index )
|
||||
DragSortableListView::MoveItems(BList& items, int32 index)
|
||||
{
|
||||
DeselectAll();
|
||||
// we remove the items while we look at them, the insertion index is decreased
|
||||
@ -628,34 +629,30 @@ DragSortableListView::MoveItems( BList& items, int32 index )
|
||||
// removal
|
||||
BList removedItems;
|
||||
int32 count = items.CountItems();
|
||||
for ( int32 i = 0; i < count; i++ )
|
||||
{
|
||||
BListItem* item = (BListItem*)items.ItemAt( i );
|
||||
int32 removeIndex = IndexOf( item );
|
||||
if ( RemoveItem( item ) && removedItems.AddItem( (void*)item ) )
|
||||
{
|
||||
if ( removeIndex < index )
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
BListItem* item = (BListItem*)items.ItemAt(i);
|
||||
int32 removeIndex = IndexOf(item);
|
||||
if (RemoveItem(item) && removedItems.AddItem((void*)item)) {
|
||||
if (removeIndex < index)
|
||||
index--;
|
||||
}
|
||||
// else ??? -> blow up
|
||||
}
|
||||
for ( int32 i = 0; BListItem* item = (BListItem*)removedItems.ItemAt( i ); i++ )
|
||||
{
|
||||
if ( AddItem( item, index ) )
|
||||
{
|
||||
for (int32 i = 0;
|
||||
BListItem* item = (BListItem*)removedItems.ItemAt(i); i++) {
|
||||
if (AddItem(item, index)) {
|
||||
// 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
|
||||
index++;
|
||||
}
|
||||
else
|
||||
} else
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
// CopyItems
|
||||
void
|
||||
DragSortableListView::CopyItems( BList& items, int32 index )
|
||||
DragSortableListView::CopyItems(BList& items, int32 index)
|
||||
{
|
||||
DeselectAll();
|
||||
// by inserting the items after we copied all items first, we avoid
|
||||
@ -664,35 +661,31 @@ DragSortableListView::CopyItems( BList& items, int32 index )
|
||||
// need to be cloned
|
||||
BList clonedItems;
|
||||
int32 count = items.CountItems();
|
||||
for ( int32 i = 0; i < count; i++ )
|
||||
{
|
||||
BListItem* item = CloneItem( IndexOf( (BListItem*)items.ItemAt( i ) ) );
|
||||
if ( item && !clonedItems.AddItem( (void*)item ) )
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
BListItem* item = CloneItem(IndexOf((BListItem*)items.ItemAt(i)));
|
||||
if (item && !clonedItems.AddItem((void*)item))
|
||||
delete item;
|
||||
}
|
||||
for ( int32 i = 0; BListItem* item = (BListItem*)clonedItems.ItemAt( i ); i++ )
|
||||
{
|
||||
if ( AddItem( item, index ) )
|
||||
{
|
||||
for (int32 i = 0;
|
||||
BListItem* item = (BListItem*)clonedItems.ItemAt(i); i++) {
|
||||
if (AddItem(item, index)) {
|
||||
// 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
|
||||
index++;
|
||||
}
|
||||
else
|
||||
} else
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveItemList
|
||||
void
|
||||
DragSortableListView::RemoveItemList( BList& items )
|
||||
DragSortableListView::RemoveItemList(BList& items)
|
||||
{
|
||||
int32 count = items.CountItems();
|
||||
for ( int32 i = 0; i < count; i++ )
|
||||
{
|
||||
BListItem* item = (BListItem*)items.ItemAt( i );
|
||||
if ( RemoveItem( item ) )
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
BListItem* item = (BListItem*)items.ItemAt(i);
|
||||
if (RemoveItem(item))
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
@ -705,9 +698,9 @@ DragSortableListView::RemoveSelected()
|
||||
// return;
|
||||
|
||||
BList items;
|
||||
for ( int32 i = 0; BListItem* item = ItemAt( CurrentSelection( i ) ); i++ )
|
||||
items.AddItem( (void*)item );
|
||||
RemoveItemList( items );
|
||||
for (int32 i = 0; BListItem* item = ItemAt(CurrentSelection(i)); i++)
|
||||
items.AddItem((void*)item);
|
||||
RemoveItemList(items);
|
||||
}
|
||||
|
||||
// CountSelectedItems
|
||||
@ -715,7 +708,7 @@ int32
|
||||
DragSortableListView::CountSelectedItems() const
|
||||
{
|
||||
int32 count = 0;
|
||||
while ( CurrentSelection( count ) >= 0 )
|
||||
while (CurrentSelection(count) >= 0)
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
@ -802,22 +795,22 @@ DragSortableListView::_SetDragMessage(const BMessage* message)
|
||||
|
||||
|
||||
// SimpleListView class
|
||||
SimpleListView::SimpleListView( BRect frame, BMessage* selectionChangeMessage )
|
||||
: DragSortableListView( frame, "playlist listview",
|
||||
SimpleListView::SimpleListView(BRect frame, BMessage* selectionChangeMessage)
|
||||
: DragSortableListView(frame, "playlist listview",
|
||||
B_MULTIPLE_SELECTION_LIST, B_FOLLOW_ALL,
|
||||
B_WILL_DRAW | B_NAVIGABLE
|
||||
| B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE ),
|
||||
fSelectionChangeMessage( selectionChangeMessage )
|
||||
| B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE),
|
||||
fSelectionChangeMessage(selectionChangeMessage)
|
||||
{
|
||||
}
|
||||
|
||||
// SimpleListView class
|
||||
SimpleListView::SimpleListView( BRect frame, const char* name,
|
||||
SimpleListView::SimpleListView(BRect frame, const char* name,
|
||||
BMessage* selectionChangeMessage,
|
||||
list_view_type type,
|
||||
uint32 resizingMode, uint32 flags )
|
||||
: DragSortableListView( frame, name, type, resizingMode, flags ),
|
||||
fSelectionChangeMessage( selectionChangeMessage )
|
||||
uint32 resizingMode, uint32 flags)
|
||||
: DragSortableListView(frame, name, type, resizingMode, flags),
|
||||
fSelectionChangeMessage(selectionChangeMessage)
|
||||
{
|
||||
}
|
||||
|
||||
@ -827,6 +820,7 @@ SimpleListView::~SimpleListView()
|
||||
delete fSelectionChangeMessage;
|
||||
}
|
||||
|
||||
#ifdef LIB_LAYOUT
|
||||
// layoutprefs
|
||||
minimax
|
||||
SimpleListView::layoutprefs()
|
||||
@ -847,14 +841,15 @@ SimpleListView::layout(BRect frame)
|
||||
ResizeTo(frame.Width(), frame.Height());
|
||||
return Frame();
|
||||
}
|
||||
#endif // LIB_LAYOUT
|
||||
|
||||
// MessageReceived
|
||||
void
|
||||
SimpleListView::MessageReceived( BMessage* message)
|
||||
SimpleListView::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch ( message->what ) {
|
||||
switch (message->what) {
|
||||
default:
|
||||
DragSortableListView::MessageReceived( message );
|
||||
DragSortableListView::MessageReceived(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -899,10 +894,10 @@ void
|
||||
SimpleListView::MakeDragMessage(BMessage* message) const
|
||||
{
|
||||
if (message) {
|
||||
message->AddPointer( "list", (void*)dynamic_cast<const DragSortableListView*>(this));
|
||||
message->AddPointer("list", (void*)dynamic_cast<const DragSortableListView*>(this));
|
||||
int32 index;
|
||||
for (int32 i = 0; (index = CurrentSelection(i)) >= 0; i++)
|
||||
message->AddInt32( "index", index );
|
||||
message->AddInt32("index", index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,9 @@
|
||||
#include <ListView.h>
|
||||
#include <Message.h>
|
||||
|
||||
#include <layout.h>
|
||||
#ifdef LIB_LAYOUT
|
||||
# include <layout.h>
|
||||
#endif
|
||||
|
||||
#include "MouseWheelFilter.h"
|
||||
|
||||
@ -59,7 +61,7 @@ class SimpleItem : public BStringItem
|
||||
class DragSortableListView : public MouseWheelTarget,
|
||||
public BListView {
|
||||
public:
|
||||
DragSortableListView( BRect frame,
|
||||
DragSortableListView(BRect frame,
|
||||
const char* name,
|
||||
list_view_type type
|
||||
= B_SINGLE_SELECTION_LIST,
|
||||
@ -69,7 +71,7 @@ class DragSortableListView : public MouseWheelTarget,
|
||||
uint32 flags
|
||||
= B_WILL_DRAW
|
||||
| B_NAVIGABLE
|
||||
| B_FRAME_EVENTS );
|
||||
| B_FRAME_EVENTS);
|
||||
virtual ~DragSortableListView();
|
||||
|
||||
// BListView
|
||||
@ -77,19 +79,19 @@ class DragSortableListView : public MouseWheelTarget,
|
||||
virtual void DetachedFromWindow();
|
||||
virtual void FrameResized(float width, float height);
|
||||
// virtual void MakeFocus(bool focused);
|
||||
virtual void Draw( BRect updateRect );
|
||||
virtual void Draw(BRect updateRect);
|
||||
virtual void ScrollTo(BPoint where);
|
||||
virtual void TargetedByScrollView(BScrollView* scrollView);
|
||||
virtual bool InitiateDrag( BPoint point, int32 index,
|
||||
bool wasSelected );
|
||||
virtual void MessageReceived( BMessage* message );
|
||||
virtual void KeyDown( const char* bytes, int32 numBytes );
|
||||
virtual void MouseDown( BPoint where );
|
||||
virtual void MouseMoved( BPoint where, uint32 transit,
|
||||
const BMessage* dragMessage );
|
||||
virtual void MouseUp( BPoint where );
|
||||
virtual void WindowActivated( bool active );
|
||||
virtual void DrawItem( BListItem *item, BRect itemFrame,
|
||||
virtual bool InitiateDrag(BPoint point, int32 index,
|
||||
bool wasSelected);
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual void KeyDown(const char* bytes, int32 numBytes);
|
||||
virtual void MouseDown(BPoint where);
|
||||
virtual void MouseMoved(BPoint where, uint32 transit,
|
||||
const BMessage* dragMessage);
|
||||
virtual void MouseUp(BPoint where);
|
||||
virtual void WindowActivated(bool active);
|
||||
virtual void DrawItem(BListItem *item, BRect itemFrame,
|
||||
bool complete = false);
|
||||
|
||||
// MouseWheelTarget
|
||||
@ -148,11 +150,15 @@ class DragSortableListView : public MouseWheelTarget,
|
||||
};
|
||||
|
||||
// SimpleListView
|
||||
class SimpleListView : public MView, public DragSortableListView {
|
||||
class SimpleListView :
|
||||
#ifdef LIB_LAYOUT
|
||||
public MView,
|
||||
#endif
|
||||
public DragSortableListView {
|
||||
public:
|
||||
SimpleListView( BRect frame,
|
||||
BMessage* selectionChangeMessage = NULL );
|
||||
SimpleListView( BRect frame,
|
||||
SimpleListView(BRect frame,
|
||||
BMessage* selectionChangeMessage = NULL);
|
||||
SimpleListView(BRect frame,
|
||||
const char* name,
|
||||
BMessage* selectionChangeMessage = NULL,
|
||||
list_view_type type
|
||||
@ -161,13 +167,14 @@ class SimpleListView : public MView, public DragSortableListView {
|
||||
= B_FOLLOW_ALL_SIDES,
|
||||
uint32 flags
|
||||
= B_WILL_DRAW | B_NAVIGABLE
|
||||
| B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE );
|
||||
| B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE);
|
||||
~SimpleListView();
|
||||
|
||||
#ifdef LIB_LAYOUT
|
||||
// MView
|
||||
virtual minimax layoutprefs();
|
||||
virtual BRect layout(BRect frame);
|
||||
|
||||
#endif
|
||||
// BListView
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual void SelectionChanged();
|
||||
|
308
src/apps/icon-o-matic/gui/PathListView.cpp
Normal file
308
src/apps/icon-o-matic/gui/PathListView.cpp
Normal file
@ -0,0 +1,308 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
*/
|
||||
|
||||
#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);
|
||||
}
|
||||
|
66
src/apps/icon-o-matic/gui/PathListView.h
Normal file
66
src/apps/icon-o-matic/gui/PathListView.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
*/
|
||||
|
||||
#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
|
340
src/apps/icon-o-matic/gui/ShapeListView.cpp
Normal file
340
src/apps/icon-o-matic/gui/ShapeListView.cpp
Normal file
@ -0,0 +1,340 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
*/
|
||||
|
||||
#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);
|
||||
}
|
||||
|
66
src/apps/icon-o-matic/gui/ShapeListView.h
Normal file
66
src/apps/icon-o-matic/gui/ShapeListView.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
*/
|
||||
|
||||
#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),
|
||||
fTransformers(4),
|
||||
|
||||
fLastBounds(0, 0, -1, -1)
|
||||
fLastBounds(0, 0, -1, -1),
|
||||
|
||||
fName("<shape>")
|
||||
{
|
||||
if (fPaths)
|
||||
fPaths->AddListener(this);
|
||||
@ -77,6 +79,16 @@ Shape::ObjectChanged(const Observable* object)
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
// SelectedChanged
|
||||
void
|
||||
Shape::SelectedChanged()
|
||||
{
|
||||
// simply pass on the event for now
|
||||
Notify();
|
||||
}
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
// InitCheck
|
||||
status_t
|
||||
Shape::InitCheck() const
|
||||
@ -158,3 +170,24 @@ Shape::AppendTransformer(Transformer* transformer)
|
||||
Notify();
|
||||
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 <Rect.h>
|
||||
#include <String.h>
|
||||
|
||||
#include "Observable.h"
|
||||
#include "Observer.h"
|
||||
#include "PathContainer.h"
|
||||
#include "PathSource.h"
|
||||
#include "Referenceable.h"
|
||||
#include "Selectable.h"
|
||||
|
||||
class Style;
|
||||
|
||||
class Shape : public Observable,
|
||||
public Observer, // observing all the paths
|
||||
public Referenceable,
|
||||
public Selectable,
|
||||
public PathContainerListener {
|
||||
public:
|
||||
Shape(::Style* style);
|
||||
@ -27,6 +30,9 @@ class Shape : public Observable,
|
||||
// Observer interface
|
||||
virtual void ObjectChanged(const Observable* object);
|
||||
|
||||
// Selectable interface
|
||||
virtual void SelectedChanged();
|
||||
|
||||
// Shape
|
||||
status_t InitCheck() const;
|
||||
|
||||
@ -45,6 +51,9 @@ class Shape : public Observable,
|
||||
bool AppendTransformer(
|
||||
Transformer* transformer);
|
||||
|
||||
void SetName(const char* name);
|
||||
const char* Name() const;
|
||||
|
||||
private:
|
||||
PathContainer* fPaths;
|
||||
::Style* fStyle;
|
||||
@ -53,6 +62,8 @@ class Shape : public Observable,
|
||||
BList fTransformers;
|
||||
|
||||
mutable BRect fLastBounds;
|
||||
|
||||
BString fName;
|
||||
};
|
||||
|
||||
#endif // SHAPE_H
|
||||
|
@ -78,7 +78,8 @@ VectorPath::VectorPath()
|
||||
fClosed(false),
|
||||
fPointCount(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),
|
||||
fPointCount(0),
|
||||
fAllocCount(0),
|
||||
fCachedBounds(0.0, 0.0, -1.0, -1.0)
|
||||
fCachedBounds(0.0, 0.0, -1.0, -1.0),
|
||||
fName()
|
||||
{
|
||||
*this = from;
|
||||
}
|
||||
@ -104,7 +106,8 @@ VectorPath::VectorPath(const BMessage* archive)
|
||||
fClosed(false),
|
||||
fPointCount(0),
|
||||
fAllocCount(0),
|
||||
fCachedBounds(0.0, 0.0, -1.0, -1.0)
|
||||
fCachedBounds(0.0, 0.0, -1.0, -1.0),
|
||||
fName()
|
||||
{
|
||||
if (archive) {
|
||||
type_code typeFound;
|
||||
@ -130,6 +133,9 @@ VectorPath::VectorPath(const BMessage* archive)
|
||||
if (archive->FindBool("path closed", &fClosed) < B_OK) {
|
||||
fClosed = false;
|
||||
}
|
||||
if (archive->FindString("name", &fName) < B_OK) {
|
||||
fName = "<path>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,6 +161,7 @@ VectorPath::operator=(const VectorPath& from)
|
||||
fPointCount = 0;
|
||||
fCachedBounds.Set(0.0, 0.0, -1.0, -1.0);
|
||||
}
|
||||
fName = from.fName;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -171,7 +178,9 @@ status_t
|
||||
VectorPath::Archive(BMessage* into, bool deep) const
|
||||
{
|
||||
status_t ret = BArchivable::Archive(into, deep);
|
||||
if (ret >= B_OK) {
|
||||
if (ret < B_OK)
|
||||
return ret;
|
||||
|
||||
if (fPointCount > 0) {
|
||||
// improve BMessage efficency by preallocating storage for all points
|
||||
// with the first call
|
||||
@ -203,14 +212,19 @@ VectorPath::Archive(BMessage* into, bool deep) const
|
||||
} else {
|
||||
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) {
|
||||
fprintf(stderr, "failed adding closed!\n");
|
||||
fprintf(stderr, "failed adding name!\n");
|
||||
}
|
||||
// finish off
|
||||
if (ret < B_OK) {
|
||||
ret = into->AddString("class", "VectorPath");
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -829,6 +843,28 @@ VectorPath::_SetPoint(int32 index, BPoint point)
|
||||
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
|
||||
bool
|
||||
VectorPath::_SetPointCount(int32 count)
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <Archivable.h>
|
||||
#include <Rect.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <agg_path_storage.h>
|
||||
|
||||
@ -121,6 +122,9 @@ class VectorPath : public BArchivable,
|
||||
|
||||
bool GetAGGPathStorage(agg::path_storage& path) const;
|
||||
|
||||
void SetName(const char* name);
|
||||
const char* Name() const;
|
||||
|
||||
private:
|
||||
BRect _Bounds() const;
|
||||
void _SetPoint(int32 index, BPoint point);
|
||||
@ -134,6 +138,9 @@ class VectorPath : public BArchivable,
|
||||
int32 fAllocCount;
|
||||
|
||||
mutable BRect fCachedBounds;
|
||||
|
||||
// TODO: should this really be part of VectorPath?
|
||||
BString fName;
|
||||
};
|
||||
|
||||
#endif // VECTOR_PATH_H
|
||||
|
Loading…
Reference in New Issue
Block a user