xref: /haiku/src/apps/icon-o-matic/transformable/TransformPointsBox.cpp (revision 55b40aa53a835472ec7952b138ae4256203d02e4)
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 
19 using std::nothrow;
20 
21 // constructor
22 TransformPointsBox::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 	BRect bounds(0, 0, -1, -1);
35 
36 	if (fPoints && fIndices) {
37 		// copy indices
38 		memcpy(fIndices, indices, fCount * sizeof(int32));
39 		// make a copy of the points as they are and calculate bounds
40 		for (int32 i = 0; i < fCount; i++) {
41 			if (fPath->GetPointsAt(fIndices[i], fPoints[i].point,
42 												fPoints[i].point_in,
43 												fPoints[i].point_out,
44 												&fPoints[i].connected)) {
45 				BRect dummy(fPoints[i].point, fPoints[i].point);
46 				if (i == 0) {
47 					bounds = dummy;
48 				} else {
49 					bounds = bounds | dummy;
50 				}
51 				dummy.Set(fPoints[i].point_in.x, fPoints[i].point_in.y,
52 						  fPoints[i].point_in.x, fPoints[i].point_in.y);
53 				bounds = bounds | dummy;
54 				dummy.Set(fPoints[i].point_out.x, fPoints[i].point_out.y,
55 						  fPoints[i].point_out.x, fPoints[i].point_out.y);
56 				bounds = bounds | dummy;
57 			} else {
58 				memset(&fPoints[i], 0, sizeof(control_point));
59 			}
60 		}
61 	}
62 
63 	SetBox(bounds);
64 }
65 
66 // destructor
67 TransformPointsBox::~TransformPointsBox()
68 {
69 	delete[] fIndices;
70 	delete[] fPoints;
71 }
72 
73 // #pragma mark -
74 
75 // ObjectChanged
76 void
77 TransformPointsBox::ObjectChanged(const Observable* object)
78 {
79 }
80 
81 // #pragma mark -
82 
83 // Update
84 void
85 TransformPointsBox::Update(bool deep)
86 {
87 	BRect r = Bounds();
88 
89 	TransformBox::Update(deep);
90 
91 	BRect dirty(r | Bounds());
92 	dirty.InsetBy(-8, -8);
93 	fView->Invalidate(dirty);
94 
95 	if (!deep || !fIndices || !fPoints)
96 		return;
97 
98 	for (int32 i = 0; i < fCount; i++) {
99 
100 		BPoint transformed = fPoints[i].point;
101 		BPoint transformedIn = fPoints[i].point_in;
102 		BPoint transformedOut = fPoints[i].point_out;
103 
104 		Transform(&transformed);
105 		Transform(&transformedIn);
106 		Transform(&transformedOut);
107 
108 		fPath->SetPoint(fIndices[i], transformed,
109 									 transformedIn,
110 									 transformedOut,
111 									 fPoints[i].connected);
112 	}
113 }
114 
115 // MakeCommand
116 TransformCommand*
117 TransformPointsBox::MakeCommand(const char* commandName,
118 								uint32 nameIndex)
119 {
120 	return new TransformPointsCommand(this, fPath,
121 
122 									  fIndices,
123 									  fPoints,
124 									  fCount,
125 
126 									  Pivot(),
127 									  Translation(),
128 									  LocalRotation(),
129 									  LocalXScale(),
130 									  LocalYScale(),
131 
132 									  commandName,
133 									  nameIndex);
134 }
135 
136 // #pragma mark -
137 
138 // Cancel
139 void
140 TransformPointsBox::Cancel()
141 {
142 	SetTransformation(B_ORIGIN, B_ORIGIN, 0.0, 1.0, 1.0);
143 }
144 
145