xref: /haiku/src/apps/icon-o-matic/transformable/TransformPointsBox.cpp (revision 3386b8b7858f5659c205b8f088eb568692699591)
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 	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
69 TransformPointsBox::~TransformPointsBox()
70 {
71 	delete[] fIndices;
72 	delete[] fPoints;
73 	fPath->ReleaseReference();
74 }
75 
76 // #pragma mark -
77 
78 // ObjectChanged
79 void
80 TransformPointsBox::ObjectChanged(const Observable* object)
81 {
82 }
83 
84 // #pragma mark -
85 
86 // Update
87 void
88 TransformPointsBox::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
119 TransformCommand*
120 TransformPointsBox::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
140 void
141 TransformPointsBox::Cancel()
142 {
143 	SetTransformation(B_ORIGIN, B_ORIGIN, 0.0, 1.0, 1.0);
144 }
145 
146