1/*
2 * Copyright 2006, Haiku. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Stephan A��mus <superstippi@gmx.de>
7 */
8
9#include "TransformPointsBox.h"
10
11#include <new>
12#include <stdio.h>
13#include <string.h>
14
15#include "StateView.h"
16#include "TransformPointsCommand.h"
17#include "VectorPath.h"
18
19using std::nothrow;
20
21// constructor
22TransformPointsBox::TransformPointsBox(CanvasView* view,
23									   PathManipulator* manipulator,
24									   VectorPath* path,
25									   const int32* indices,
26									   int32 count)
27	: CanvasTransformBox(view),
28	  fManipulator(manipulator),
29	  fPath(path),
30	  fIndices(path && count > 0 ? new (nothrow) int32[count] : NULL),
31	  fCount(count),
32	  fPoints(count > 0 ? new (nothrow) control_point[count] : NULL)
33{
34	fPath->AcquireReference();
35
36	BRect bounds(0, 0, -1, -1);
37
38	if (fPoints && fIndices) {
39		// copy indices
40		memcpy(fIndices, indices, fCount * sizeof(int32));
41		// make a copy of the points as they are and calculate bounds
42		for (int32 i = 0; i < fCount; i++) {
43			if (fPath->GetPointsAt(fIndices[i], fPoints[i].point,
44												fPoints[i].point_in,
45												fPoints[i].point_out,
46												&fPoints[i].connected)) {
47				BRect dummy(fPoints[i].point, fPoints[i].point);
48				if (i == 0) {
49					bounds = dummy;
50				} else {
51					bounds = bounds | dummy;
52				}
53				dummy.Set(fPoints[i].point_in.x, fPoints[i].point_in.y,
54						  fPoints[i].point_in.x, fPoints[i].point_in.y);
55				bounds = bounds | dummy;
56				dummy.Set(fPoints[i].point_out.x, fPoints[i].point_out.y,
57						  fPoints[i].point_out.x, fPoints[i].point_out.y);
58				bounds = bounds | dummy;
59			} else {
60				memset((void*)&fPoints[i], 0, sizeof(control_point));
61			}
62		}
63	}
64
65	SetBox(bounds);
66}
67
68// destructor
69TransformPointsBox::~TransformPointsBox()
70{
71	delete[] fIndices;
72	delete[] fPoints;
73	fPath->ReleaseReference();
74}
75
76// #pragma mark -
77
78// ObjectChanged
79void
80TransformPointsBox::ObjectChanged(const Observable* object)
81{
82}
83
84// #pragma mark -
85
86// Update
87void
88TransformPointsBox::Update(bool deep)
89{
90	BRect r = Bounds();
91
92	TransformBox::Update(deep);
93
94	BRect dirty(r | Bounds());
95	dirty.InsetBy(-8, -8);
96	fView->Invalidate(dirty);
97
98	if (!deep || !fIndices || !fPoints)
99		return;
100
101	for (int32 i = 0; i < fCount; i++) {
102
103		BPoint transformed = fPoints[i].point;
104		BPoint transformedIn = fPoints[i].point_in;
105		BPoint transformedOut = fPoints[i].point_out;
106
107		Transform(&transformed);
108		Transform(&transformedIn);
109		Transform(&transformedOut);
110
111		fPath->SetPoint(fIndices[i], transformed,
112									 transformedIn,
113									 transformedOut,
114									 fPoints[i].connected);
115	}
116}
117
118// MakeCommand
119TransformCommand*
120TransformPointsBox::MakeCommand(const char* commandName)
121{
122	return new TransformPointsCommand(this, fPath,
123
124									  fIndices,
125									  fPoints,
126									  fCount,
127
128									  Pivot(),
129									  Translation(),
130									  LocalRotation(),
131									  LocalXScale(),
132									  LocalYScale(),
133
134									  commandName);
135}
136
137// #pragma mark -
138
139// Cancel
140void
141TransformPointsBox::Cancel()
142{
143	SetTransformation(B_ORIGIN, B_ORIGIN, 0.0, 1.0, 1.0);
144}
145
146