xref: /haiku/src/apps/icon-o-matic/transformable/TransformPointsBox.cpp (revision a75a222b35d17cd83bc75253f3cd8e24a6a911f4)
10e1ba39fSStephan Aßmus /*
20e1ba39fSStephan Aßmus  * Copyright 2006, Haiku. All rights reserved.
30e1ba39fSStephan Aßmus  * Distributed under the terms of the MIT License.
40e1ba39fSStephan Aßmus  *
50e1ba39fSStephan Aßmus  * Authors:
60e1ba39fSStephan Aßmus  *		Stephan Aßmus <superstippi@gmx.de>
70e1ba39fSStephan Aßmus  */
80e1ba39fSStephan Aßmus 
90e1ba39fSStephan Aßmus #include "TransformPointsBox.h"
100e1ba39fSStephan Aßmus 
110e1ba39fSStephan Aßmus #include <new>
120e1ba39fSStephan Aßmus #include <stdio.h>
130e1ba39fSStephan Aßmus #include <string.h>
140e1ba39fSStephan Aßmus 
150e1ba39fSStephan Aßmus #include "StateView.h"
16f4bd80a2SStephan Aßmus #include "TransformPointsCommand.h"
170e1ba39fSStephan Aßmus #include "VectorPath.h"
180e1ba39fSStephan Aßmus 
190e1ba39fSStephan Aßmus using std::nothrow;
200e1ba39fSStephan Aßmus 
210e1ba39fSStephan Aßmus // constructor
TransformPointsBox(CanvasView * view,PathManipulator * manipulator,VectorPath * path,const int32 * indices,int32 count)220e1ba39fSStephan Aßmus TransformPointsBox::TransformPointsBox(CanvasView* view,
230e1ba39fSStephan Aßmus 									   PathManipulator* manipulator,
240e1ba39fSStephan Aßmus 									   VectorPath* path,
250e1ba39fSStephan Aßmus 									   const int32* indices,
260e1ba39fSStephan Aßmus 									   int32 count)
270e1ba39fSStephan Aßmus 	: CanvasTransformBox(view),
280e1ba39fSStephan Aßmus 	  fManipulator(manipulator),
290e1ba39fSStephan Aßmus 	  fPath(path),
300e1ba39fSStephan Aßmus 	  fIndices(path && count > 0 ? new (nothrow) int32[count] : NULL),
310e1ba39fSStephan Aßmus 	  fCount(count),
320e1ba39fSStephan Aßmus 	  fPoints(count > 0 ? new (nothrow) control_point[count] : NULL)
330e1ba39fSStephan Aßmus {
340cbb6c11SStephan Aßmus 	fPath->AcquireReference();
352291f756SStephan Aßmus 
360e1ba39fSStephan Aßmus 	BRect bounds(0, 0, -1, -1);
370e1ba39fSStephan Aßmus 
380e1ba39fSStephan Aßmus 	if (fPoints && fIndices) {
390e1ba39fSStephan Aßmus 		// copy indices
400e1ba39fSStephan Aßmus 		memcpy(fIndices, indices, fCount * sizeof(int32));
410e1ba39fSStephan Aßmus 		// make a copy of the points as they are and calculate bounds
420e1ba39fSStephan Aßmus 		for (int32 i = 0; i < fCount; i++) {
430e1ba39fSStephan Aßmus 			if (fPath->GetPointsAt(fIndices[i], fPoints[i].point,
440e1ba39fSStephan Aßmus 												fPoints[i].point_in,
450e1ba39fSStephan Aßmus 												fPoints[i].point_out,
460e1ba39fSStephan Aßmus 												&fPoints[i].connected)) {
470e1ba39fSStephan Aßmus 				BRect dummy(fPoints[i].point, fPoints[i].point);
480e1ba39fSStephan Aßmus 				if (i == 0) {
490e1ba39fSStephan Aßmus 					bounds = dummy;
500e1ba39fSStephan Aßmus 				} else {
510e1ba39fSStephan Aßmus 					bounds = bounds | dummy;
520e1ba39fSStephan Aßmus 				}
530e1ba39fSStephan Aßmus 				dummy.Set(fPoints[i].point_in.x, fPoints[i].point_in.y,
540e1ba39fSStephan Aßmus 						  fPoints[i].point_in.x, fPoints[i].point_in.y);
550e1ba39fSStephan Aßmus 				bounds = bounds | dummy;
560e1ba39fSStephan Aßmus 				dummy.Set(fPoints[i].point_out.x, fPoints[i].point_out.y,
570e1ba39fSStephan Aßmus 						  fPoints[i].point_out.x, fPoints[i].point_out.y);
580e1ba39fSStephan Aßmus 				bounds = bounds | dummy;
590e1ba39fSStephan Aßmus 			} else {
601705656eSAugustin Cavalier 				memset((void*)&fPoints[i], 0, sizeof(control_point));
610e1ba39fSStephan Aßmus 			}
620e1ba39fSStephan Aßmus 		}
630e1ba39fSStephan Aßmus 	}
640e1ba39fSStephan Aßmus 
650e1ba39fSStephan Aßmus 	SetBox(bounds);
660e1ba39fSStephan Aßmus }
670e1ba39fSStephan Aßmus 
680e1ba39fSStephan Aßmus // destructor
~TransformPointsBox()690e1ba39fSStephan Aßmus TransformPointsBox::~TransformPointsBox()
700e1ba39fSStephan Aßmus {
710e1ba39fSStephan Aßmus 	delete[] fIndices;
720e1ba39fSStephan Aßmus 	delete[] fPoints;
730cbb6c11SStephan Aßmus 	fPath->ReleaseReference();
740e1ba39fSStephan Aßmus }
750e1ba39fSStephan Aßmus 
760e1ba39fSStephan Aßmus // #pragma mark -
770e1ba39fSStephan Aßmus 
780e1ba39fSStephan Aßmus // ObjectChanged
790e1ba39fSStephan Aßmus void
ObjectChanged(const Observable * object)800e1ba39fSStephan Aßmus TransformPointsBox::ObjectChanged(const Observable* object)
810e1ba39fSStephan Aßmus {
820e1ba39fSStephan Aßmus }
830e1ba39fSStephan Aßmus 
840e1ba39fSStephan Aßmus // #pragma mark -
850e1ba39fSStephan Aßmus 
860e1ba39fSStephan Aßmus // Update
870e1ba39fSStephan Aßmus void
Update(bool deep)880e1ba39fSStephan Aßmus TransformPointsBox::Update(bool deep)
890e1ba39fSStephan Aßmus {
900e1ba39fSStephan Aßmus 	BRect r = Bounds();
910e1ba39fSStephan Aßmus 
920e1ba39fSStephan Aßmus 	TransformBox::Update(deep);
930e1ba39fSStephan Aßmus 
940e1ba39fSStephan Aßmus 	BRect dirty(r | Bounds());
950e1ba39fSStephan Aßmus 	dirty.InsetBy(-8, -8);
960e1ba39fSStephan Aßmus 	fView->Invalidate(dirty);
970e1ba39fSStephan Aßmus 
980e1ba39fSStephan Aßmus 	if (!deep || !fIndices || !fPoints)
990e1ba39fSStephan Aßmus 		return;
1000e1ba39fSStephan Aßmus 
1010e1ba39fSStephan Aßmus 	for (int32 i = 0; i < fCount; i++) {
1020e1ba39fSStephan Aßmus 
1030e1ba39fSStephan Aßmus 		BPoint transformed = fPoints[i].point;
1040e1ba39fSStephan Aßmus 		BPoint transformedIn = fPoints[i].point_in;
1050e1ba39fSStephan Aßmus 		BPoint transformedOut = fPoints[i].point_out;
1060e1ba39fSStephan Aßmus 
1070e1ba39fSStephan Aßmus 		Transform(&transformed);
1080e1ba39fSStephan Aßmus 		Transform(&transformedIn);
1090e1ba39fSStephan Aßmus 		Transform(&transformedOut);
1100e1ba39fSStephan Aßmus 
1110e1ba39fSStephan Aßmus 		fPath->SetPoint(fIndices[i], transformed,
1120e1ba39fSStephan Aßmus 									 transformedIn,
1130e1ba39fSStephan Aßmus 									 transformedOut,
1140e1ba39fSStephan Aßmus 									 fPoints[i].connected);
1150e1ba39fSStephan Aßmus 	}
1160e1ba39fSStephan Aßmus }
1170e1ba39fSStephan Aßmus 
1180e1ba39fSStephan Aßmus // MakeCommand
1190e1ba39fSStephan Aßmus TransformCommand*
MakeCommand(const char * commandName)120*a75a222bSZardshard TransformPointsBox::MakeCommand(const char* commandName)
1210e1ba39fSStephan Aßmus {
122f4bd80a2SStephan Aßmus 	return new TransformPointsCommand(this, fPath,
123f4bd80a2SStephan Aßmus 
124f4bd80a2SStephan Aßmus 									  fIndices,
125f4bd80a2SStephan Aßmus 									  fPoints,
126f4bd80a2SStephan Aßmus 									  fCount,
127f4bd80a2SStephan Aßmus 
128f4bd80a2SStephan Aßmus 									  Pivot(),
129f4bd80a2SStephan Aßmus 									  Translation(),
130f4bd80a2SStephan Aßmus 									  LocalRotation(),
131f4bd80a2SStephan Aßmus 									  LocalXScale(),
132f4bd80a2SStephan Aßmus 									  LocalYScale(),
133f4bd80a2SStephan Aßmus 
134*a75a222bSZardshard 									  commandName);
1350e1ba39fSStephan Aßmus }
1360e1ba39fSStephan Aßmus 
1370e1ba39fSStephan Aßmus // #pragma mark -
1380e1ba39fSStephan Aßmus 
1390e1ba39fSStephan Aßmus // Cancel
1400e1ba39fSStephan Aßmus void
Cancel()1410e1ba39fSStephan Aßmus TransformPointsBox::Cancel()
1420e1ba39fSStephan Aßmus {
1430e1ba39fSStephan Aßmus 	SetTransformation(B_ORIGIN, B_ORIGIN, 0.0, 1.0, 1.0);
1440e1ba39fSStephan Aßmus }
1450e1ba39fSStephan Aßmus 
146