btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / apps / icon-o-matic / shape / commands / FreezeTransformationCommand.cpp
blob105479227a44e3af398fc9b8242c7d52954f64d1
1 /*
2 * Copyright 2006, Haiku.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Stephan Aßmus <superstippi@gmx.de>
7 */
9 #include "FreezeTransformationCommand.h"
11 #include <new>
12 #include <stdio.h>
13 #include <string.h>
15 #include <Catalog.h>
16 #include <Locale.h>
18 #include "GradientTransformable.h"
19 #include "Shape.h"
20 #include "Style.h"
21 #include "VectorPath.h"
24 #undef B_TRANSLATION_CONTEXT
25 #define B_TRANSLATION_CONTEXT "Icon-O-Matic-FreezeTransformationCmd"
28 using std::nothrow;
30 // constructor
31 FreezeTransformationCommand::FreezeTransformationCommand(
32 Shape** const shapes,
33 int32 count)
34 : Command(),
35 fShapes(shapes && count > 0 ? new (nothrow) Shape*[count] : NULL),
36 fOriginalTransformations(count > 0 ? new (nothrow) double[
37 count * Transformable::matrix_size]
38 : NULL),
39 fCount(count)
41 if (!fShapes || !fOriginalTransformations)
42 return;
44 memcpy(fShapes, shapes, sizeof(Shape*) * fCount);
46 bool initOk = false;
48 for (int32 i = 0; i < fCount; i++) {
49 if (!fShapes[i])
50 continue;
51 if (!fShapes[i]->IsIdentity())
52 initOk = true;
53 fShapes[i]->StoreTo(&fOriginalTransformations[
54 i * Transformable::matrix_size]);
57 if (!initOk) {
58 delete[] fShapes;
59 fShapes = NULL;
60 delete[] fOriginalTransformations;
61 fOriginalTransformations = NULL;
65 // destructor
66 FreezeTransformationCommand::~FreezeTransformationCommand()
68 delete[] fShapes;
69 delete[] fOriginalTransformations;
72 // InitCheck
73 status_t
74 FreezeTransformationCommand::InitCheck()
76 return fShapes && fOriginalTransformations ? B_OK : B_NO_INIT;
79 // Perform
80 status_t
81 FreezeTransformationCommand::Perform()
83 for (int32 i = 0; i < fCount; i++) {
84 if (!fShapes[i] || fShapes[i]->IsIdentity())
85 continue;
87 _ApplyTransformation(fShapes[i], *(fShapes[i]));
88 fShapes[i]->Reset();
91 return B_OK;
94 // Undo
95 status_t
96 FreezeTransformationCommand::Undo()
98 for (int32 i = 0; i < fCount; i++) {
99 if (!fShapes[i])
100 continue;
102 // restore original transformation
103 fShapes[i]->LoadFrom(&fOriginalTransformations[
104 i * Transformable::matrix_size]);
106 Transformable transform(*(fShapes[i]));
107 if (!transform.IsValid() || transform.IsIdentity())
108 continue;
110 transform.Invert();
111 _ApplyTransformation(fShapes[i], transform);
114 return B_OK;
117 // GetName
118 void
119 FreezeTransformationCommand::GetName(BString& name)
121 if (fCount > 1)
122 name << B_TRANSLATE("Freeze Shapes");
123 else
124 name << B_TRANSLATE("Freeze Shape");
127 // #pragma mark -
129 // _ApplyTransformation
130 void
131 FreezeTransformationCommand::_ApplyTransformation(Shape* shape,
132 const Transformable& transform)
134 // apply inverse of old shape transformation to every assigned path
135 int32 pathCount = shape->Paths()->CountPaths();
136 for (int32 i = 0; i < pathCount; i++) {
137 VectorPath* path = shape->Paths()->PathAtFast(i);
138 int32 shapes = 0;
139 int32 listeners = path->CountListeners();
140 for (int32 j = 0; j < listeners; j++) {
141 if (dynamic_cast<Shape*>(path->ListenerAtFast(j)))
142 shapes++;
144 // only freeze transformation of path if only one
145 // shape has it assigned
146 if (shapes == 1) {
147 path->ApplyTransform(transform);
148 } else {
149 printf("Not transfering transformation of \"%s\" onto "
150 "path \"%s\", because %" B_PRId32 " other shapes "
151 "have it assigned.\n", shape->Name(), path->Name(),
152 shapes - 1);
155 // take care of style too
156 if (shape->Style() && shape->Style()->Gradient()) {
157 // TODO: not if more than one shape have this style assigned!
158 shape->Style()->Gradient()->Multiply(transform);