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	: 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
58TransformObjectsCommand::~TransformObjectsCommand()
59{
60	if (fTransformBox)
61		fTransformBox->RemoveListener(this);
62
63	delete[] fObjects;
64	delete[] fOriginals;
65}
66
67// InitCheck
68status_t
69TransformObjectsCommand::InitCheck()
70{
71	return fObjects && fOriginals ? TransformCommand::InitCheck()
72								  : B_NO_INIT;
73}
74
75// #pragma mark -
76
77// TransformBoxDeleted
78void
79TransformObjectsCommand::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
92status_t
93TransformObjectsCommand::_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