* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "FreezeTransformationCommand.h"
#include <new>
#include <stdio.h>
#include <string.h>
#include <Catalog.h>
#include <Locale.h>
#include <StringFormat.h>
#include "GradientTransformable.h"
#include "PathSourceShape.h"
#include "Style.h"
#include "VectorPath.h"
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "Icon-O-Matic-FreezeTransformationCmd"
using std::nothrow;
FreezeTransformationCommand::FreezeTransformationCommand(
PathSourceShape** const shapes,
int32 count)
: Command(),
fShapes(shapes && count > 0 ? new (nothrow) PathSourceShape*[count] : NULL),
fOriginalTransformations(count > 0 ? new (nothrow) double[
count * Transformable::matrix_size]
: NULL),
fCount(count)
{
if (!fShapes || !fOriginalTransformations)
return;
memcpy(fShapes, shapes, sizeof(PathSourceShape*) * fCount);
bool initOk = false;
for (int32 i = 0; i < fCount; i++) {
if (!fShapes[i])
continue;
if (!fShapes[i]->IsIdentity())
initOk = true;
fShapes[i]->StoreTo(&fOriginalTransformations[
i * Transformable::matrix_size]);
}
if (!initOk) {
delete[] fShapes;
fShapes = NULL;
delete[] fOriginalTransformations;
fOriginalTransformations = NULL;
}
}
FreezeTransformationCommand::~FreezeTransformationCommand()
{
delete[] fShapes;
delete[] fOriginalTransformations;
}
status_t
FreezeTransformationCommand::InitCheck()
{
return fShapes && fOriginalTransformations ? B_OK : B_NO_INIT;
}
status_t
FreezeTransformationCommand::Perform()
{
for (int32 i = 0; i < fCount; i++) {
if (!fShapes[i] || fShapes[i]->IsIdentity())
continue;
_ApplyTransformation(fShapes[i], *(fShapes[i]));
fShapes[i]->Reset();
}
return B_OK;
}
status_t
FreezeTransformationCommand::Undo()
{
for (int32 i = 0; i < fCount; i++) {
if (!fShapes[i])
continue;
fShapes[i]->LoadFrom(&fOriginalTransformations[
i * Transformable::matrix_size]);
Transformable transform(*(fShapes[i]));
if (!transform.IsValid() || transform.IsIdentity())
continue;
transform.Invert();
_ApplyTransformation(fShapes[i], transform);
}
return B_OK;
}
void
FreezeTransformationCommand::GetName(BString& name)
{
static BStringFormat format(B_TRANSLATE("Freeze {0, plural, "
"one{shape} other{shapes}}"));
format.Format(name, fCount);
}
void
FreezeTransformationCommand::_ApplyTransformation(PathSourceShape* shape,
const Transformable& transform)
{
int32 pathCount = shape->Paths()->CountItems();
for (int32 i = 0; i < pathCount; i++) {
VectorPath* path = shape->Paths()->ItemAtFast(i);
int32 shapes = 0;
int32 listeners = path->CountListeners();
for (int32 j = 0; j < listeners; j++) {
if (dynamic_cast<Shape*>(path->ListenerAtFast(j)))
shapes++;
}
if (shapes == 1) {
path->ApplyTransform(transform);
} else {
printf("Not transfering transformation of \"%s\" onto "
"path \"%s\", because %" B_PRId32 " other shapes "
"have it assigned.\n", shape->Name(), path->Name(),
shapes - 1);
}
}
if (shape->Style() && shape->Style()->Gradient()) {
shape->Style()->Gradient()->Multiply(transform);
}
}