xref: /haiku/src/apps/icon-o-matic/transformable/TransformObjectsCommand.cpp (revision e1c4049fed1047bdb957b0529e1921e97ef94770)
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 	: TransformCommand(pivot,
33 					   translation,
34 					   rotation,
35 					   xScale,
36 					   yScale,
37 					   name),
38 	  fTransformBox(box),
39 	  fObjects(objects && count > 0 ?
40 	  		   new (nothrow) Transformable*[count] : NULL),
41 	  fOriginals(originals && count > 0 ?
42 	  			 new (nothrow) double[
43 	  			 	count * Transformable::matrix_size] : NULL),
44 	  fCount(count)
45 {
46 	if (!fObjects || !fOriginals)
47 		return;
48 
49 	memcpy(fObjects, objects, fCount * sizeof(Transformable*));
50 	memcpy(fOriginals, originals,
51 		   fCount * Transformable::matrix_size * sizeof(double));
52 
53 	if (fTransformBox)
54 		fTransformBox->AddListener(this);
55 }
56 
57 // destructor
58 TransformObjectsCommand::~TransformObjectsCommand()
59 {
60 	if (fTransformBox)
61 		fTransformBox->RemoveListener(this);
62 
63 	delete[] fObjects;
64 	delete[] fOriginals;
65 }
66 
67 // InitCheck
68 status_t
69 TransformObjectsCommand::InitCheck()
70 {
71 	return fObjects && fOriginals ? TransformCommand::InitCheck()
72 								  : B_NO_INIT;
73 }
74 
75 // #pragma mark -
76 
77 // TransformBoxDeleted
78 void
79 TransformObjectsCommand::TransformBoxDeleted(
80 									const TransformBox* box)
81 {
82 	if (fTransformBox == box) {
83 		if (fTransformBox)
84 			fTransformBox->RemoveListener(this);
85 		fTransformBox = NULL;
86 	}
87 }
88 
89 // #pragma mark -
90 
91 // _SetTransformation
92 status_t
93 TransformObjectsCommand::_SetTransformation(
94 								BPoint pivot, BPoint translation,
95 								double rotation,
96 								double xScale, double yScale) const
97 {
98 	if (fTransformBox) {
99 		fTransformBox->SetTransformation(pivot, translation,
100 										 rotation, xScale, yScale);
101 		return B_OK;
102 	}
103 
104 	ChannelTransform transform;
105 	transform.SetTransformation(pivot, translation,
106 								rotation, xScale, yScale);
107 	// restore original transformations
108 	int32 matrixSize = Transformable::matrix_size;
109 	for (int32 i = 0; i < fCount; i++) {
110 		if (fObjects[i]) {
111 			fObjects[i]->LoadFrom(&fOriginals[i * matrixSize]);
112 			fObjects[i]->Multiply(transform);
113 		}
114 	}
115 	return B_OK;
116 }
117 
118