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
16using std::nothrow;
17
18// constructor
19TransformObjectsCommand::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
60TransformObjectsCommand::~TransformObjectsCommand()
61{
62	if (fTransformBox)
63		fTransformBox->RemoveListener(this);
64
65	delete[] fObjects;
66	delete[] fOriginals;
67}
68
69// InitCheck
70status_t
71TransformObjectsCommand::InitCheck()
72{
73	return fObjects && fOriginals ? TransformCommand::InitCheck()
74								  : B_NO_INIT;
75}
76
77// #pragma mark -
78
79// TransformBoxDeleted
80void
81TransformObjectsCommand::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
94status_t
95TransformObjectsCommand::_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	ChannelTransform transform;
107	transform.SetTransformation(pivot, translation,
108								rotation, xScale, yScale);
109	// restore original transformations
110	int32 matrixSize = Transformable::matrix_size;
111	for (int32 i = 0; i < fCount; i++) {
112		if (fObjects[i]) {
113			fObjects[i]->LoadFrom(&fOriginals[i * matrixSize]);
114			fObjects[i]->Multiply(transform);
115		}
116	}
117	return B_OK;
118}
119
120