xref: /haiku/src/apps/icon-o-matic/transformable/TransformObjectsCommand.cpp (revision 0562493379cd52eb7103531f895f10bb8e77c085)
1 /*
2  * Copyright 2006, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Stephan Aßmus <superstippi@gmx.de>
7  */
8 
9 #include "TransformObjectsCommand.h"
10 
11 #include <new>
12 #include <stdio.h>
13 
14 #include "ChannelTransform.h"
15 
16 using std::nothrow;
17 
18 // constructor
19 TransformObjectsCommand::TransformObjectsCommand(
20 								TransformBox* box,
21 								Transformable** const objects,
22 								const double* originals,
23 								int32 count,
24 
25 								BPoint pivot,
26 								BPoint translation,
27 								double rotation,
28 								double xScale,
29 								double yScale,
30 
31 								const char* name,
32 								int32 nameIndex)
33 	: TransformCommand(pivot,
34 					   translation,
35 					   rotation,
36 					   xScale,
37 					   yScale,
38 					   name,
39 					   nameIndex),
40 	  fTransformBox(box),
41 	  fObjects(objects && count > 0 ?
42 	  		   new (nothrow) Transformable*[count] : NULL),
43 	  fOriginals(originals && count > 0 ?
44 	  			 new (nothrow) double[
45 	  			 	count * Transformable::matrix_size] : NULL),
46 	  fCount(count)
47 {
48 	if (!fObjects || !fOriginals)
49 		return;
50 
51 	memcpy(fObjects, objects, fCount * sizeof(Transformable*));
52 	memcpy(fOriginals, originals,
53 		   fCount * Transformable::matrix_size * sizeof(double));
54 
55 	if (fTransformBox)
56 		fTransformBox->AddListener(this);
57 }
58 
59 // destructor
60 TransformObjectsCommand::~TransformObjectsCommand()
61 {
62 	if (fTransformBox)
63 		fTransformBox->RemoveListener(this);
64 
65 	delete[] fObjects;
66 	delete[] fOriginals;
67 }
68 
69 // InitCheck
70 status_t
71 TransformObjectsCommand::InitCheck()
72 {
73 	return fObjects && fOriginals ? TransformCommand::InitCheck()
74 								  : B_NO_INIT;
75 }
76 
77 // #pragma mark -
78 
79 // TransformBoxDeleted
80 void
81 TransformObjectsCommand::TransformBoxDeleted(
82 									const TransformBox* box)
83 {
84 	if (fTransformBox == box) {
85 		if (fTransformBox)
86 			fTransformBox->RemoveListener(this);
87 		fTransformBox = NULL;
88 	}
89 }
90 
91 // #pragma mark -
92 
93 // _SetTransformation
94 status_t
95 TransformObjectsCommand::_SetTransformation(
96 								BPoint pivot, BPoint translation,
97 								double rotation,
98 								double xScale, double yScale) const
99 {
100 	if (fTransformBox) {
101 		fTransformBox->SetTransformation(pivot, translation,
102 										 rotation, xScale, yScale);
103 		return B_OK;
104 	}
105 
106 
107 	ChannelTransform transform;
108 	transform.SetTransformation(pivot, translation,
109 								rotation, xScale, yScale);
110 	// restore original transformations
111 	int32 matrixSize = Transformable::matrix_size;
112 	for (int32 i = 0; i < fCount; i++) {
113 		if (fObjects[i]) {
114 			fObjects[i]->LoadFrom(&fOriginals[i * matrixSize]);
115 			fObjects[i]->Multiply(transform);
116 		}
117 	}
118 	return B_OK;
119 }
120 
121