10e1ba39fSStephan Aßmus /*
27f5bbbdcSAxel Dörfler * Copyright 2006-2009, Haiku.
30e1ba39fSStephan Aßmus * Distributed under the terms of the MIT License.
40e1ba39fSStephan Aßmus *
50e1ba39fSStephan Aßmus * Authors:
60e1ba39fSStephan Aßmus * Stephan Aßmus <superstippi@gmx.de>
70e1ba39fSStephan Aßmus */
80e1ba39fSStephan Aßmus
90e1ba39fSStephan Aßmus #include "TransformGradientBox.h"
100e1ba39fSStephan Aßmus
110e1ba39fSStephan Aßmus #include <new>
120e1ba39fSStephan Aßmus #include <stdio.h>
130e1ba39fSStephan Aßmus #include <string.h>
140e1ba39fSStephan Aßmus
150e1ba39fSStephan Aßmus #include "CanvasView.h"
16991547efSStephan Aßmus #include "GradientTransformable.h"
170e1ba39fSStephan Aßmus #include "Shape.h"
180e1ba39fSStephan Aßmus #include "StateView.h"
19c88bc5e9SStephan Aßmus #include "TransformGradientCommand.h"
200e1ba39fSStephan Aßmus
210e1ba39fSStephan Aßmus using std::nothrow;
220e1ba39fSStephan Aßmus
237f5bbbdcSAxel Dörfler
240e1ba39fSStephan Aßmus // constructor
TransformGradientBox(CanvasView * view,Gradient * gradient,Shape * parentShape)257f5bbbdcSAxel Dörfler TransformGradientBox::TransformGradientBox(CanvasView* view, Gradient* gradient,
260e1ba39fSStephan Aßmus Shape* parentShape)
277f5bbbdcSAxel Dörfler :
287f5bbbdcSAxel Dörfler TransformBox(view, BRect(0.0, 0.0, 1.0, 1.0)),
290e1ba39fSStephan Aßmus
300e1ba39fSStephan Aßmus fCanvasView(view),
310e1ba39fSStephan Aßmus
320e1ba39fSStephan Aßmus fShape(parentShape),
330e1ba39fSStephan Aßmus fGradient(gradient)
340e1ba39fSStephan Aßmus {
350e1ba39fSStephan Aßmus if (fShape) {
360cbb6c11SStephan Aßmus fShape->AcquireReference();
370e1ba39fSStephan Aßmus fShape->AddObserver(this);
380e1ba39fSStephan Aßmus }
392263aa8fSZardshard if (fGradient.IsSet()) {
400e1ba39fSStephan Aßmus // trigger init
410e1ba39fSStephan Aßmus ObjectChanged(fGradient);
420e1ba39fSStephan Aßmus } else {
430e1ba39fSStephan Aßmus SetBox(BRect(0, 0, -1, -1));
440e1ba39fSStephan Aßmus }
450e1ba39fSStephan Aßmus }
460e1ba39fSStephan Aßmus
477f5bbbdcSAxel Dörfler
480e1ba39fSStephan Aßmus // destructor
~TransformGradientBox()490e1ba39fSStephan Aßmus TransformGradientBox::~TransformGradientBox()
500e1ba39fSStephan Aßmus {
510e1ba39fSStephan Aßmus if (fShape) {
520e1ba39fSStephan Aßmus fShape->RemoveObserver(this);
530cbb6c11SStephan Aßmus fShape->ReleaseReference();
540e1ba39fSStephan Aßmus }
552263aa8fSZardshard if (fGradient.IsSet()) {
560e1ba39fSStephan Aßmus fGradient->RemoveObserver(this);
570e1ba39fSStephan Aßmus }
582263aa8fSZardshard }
590e1ba39fSStephan Aßmus
607f5bbbdcSAxel Dörfler
610e1ba39fSStephan Aßmus // Update
620e1ba39fSStephan Aßmus void
Update(bool deep)630e1ba39fSStephan Aßmus TransformGradientBox::Update(bool deep)
640e1ba39fSStephan Aßmus {
650e1ba39fSStephan Aßmus BRect r = Bounds();
660e1ba39fSStephan Aßmus
670e1ba39fSStephan Aßmus TransformBox::Update(deep);
680e1ba39fSStephan Aßmus
690e1ba39fSStephan Aßmus BRect dirty(r | Bounds());
700e1ba39fSStephan Aßmus dirty.InsetBy(-8, -8);
710e1ba39fSStephan Aßmus fView->Invalidate(dirty);
720e1ba39fSStephan Aßmus
732263aa8fSZardshard if (!deep || !fGradient.IsSet())
740e1ba39fSStephan Aßmus return;
750e1ba39fSStephan Aßmus
760e1ba39fSStephan Aßmus fGradient->RemoveObserver(this);
770e1ba39fSStephan Aßmus fGradient->SuspendNotifications(true);
780e1ba39fSStephan Aßmus
790e1ba39fSStephan Aßmus // reset the objects transformation to the saved state
800e1ba39fSStephan Aßmus fGradient->Reset();
810e1ba39fSStephan Aßmus // combine with the current transformation
820e1ba39fSStephan Aßmus fGradient->Multiply(*this);
830e1ba39fSStephan Aßmus
840e1ba39fSStephan Aßmus //printf("matrix:\n");
850e1ba39fSStephan Aßmus //double m[6];
860e1ba39fSStephan Aßmus //StoreTo(m);
870e1ba39fSStephan Aßmus //printf("[%5.10f] [%5.10f] [%5.10f]\n", m[0], m[1], m[2]);
880e1ba39fSStephan Aßmus //printf("[%5.10f] [%5.10f] [%5.10f]\n", m[3], m[4], m[5]);
890e1ba39fSStephan Aßmus //
900e1ba39fSStephan Aßmus fGradient->SuspendNotifications(false);
910e1ba39fSStephan Aßmus fGradient->AddObserver(this);
920e1ba39fSStephan Aßmus }
930e1ba39fSStephan Aßmus
947f5bbbdcSAxel Dörfler
950e1ba39fSStephan Aßmus // ObjectChanged
960e1ba39fSStephan Aßmus void
ObjectChanged(const Observable * object)970e1ba39fSStephan Aßmus TransformGradientBox::ObjectChanged(const Observable* object)
980e1ba39fSStephan Aßmus {
992263aa8fSZardshard if (!fGradient.IsSet() || !fView->LockLooper())
1000e1ba39fSStephan Aßmus return;
1010e1ba39fSStephan Aßmus
1020e1ba39fSStephan Aßmus if (object == fShape) {
1030e1ba39fSStephan Aßmus fView->Invalidate(Bounds());
104cd7f54f1SStephan Aßmus fView->UnlockLooper();
1050e1ba39fSStephan Aßmus return;
1060e1ba39fSStephan Aßmus }
1070e1ba39fSStephan Aßmus
108c88bc5e9SStephan Aßmus // any TransformGradientCommand cannot use the TransformBox
1090e1ba39fSStephan Aßmus // anymore
1100e1ba39fSStephan Aßmus _NotifyDeleted();
1110e1ba39fSStephan Aßmus
1120e1ba39fSStephan Aßmus fGradient->StoreTo(fOriginals);
1130e1ba39fSStephan Aßmus
1140e1ba39fSStephan Aßmus // figure out bounds and store initial transformations
1150e1ba39fSStephan Aßmus SetTransformation(*fGradient);
1160e1ba39fSStephan Aßmus SetBox(fGradient->GradientArea());
1170e1ba39fSStephan Aßmus
1180e1ba39fSStephan Aßmus fView->UnlockLooper();
1190e1ba39fSStephan Aßmus }
1200e1ba39fSStephan Aßmus
1217f5bbbdcSAxel Dörfler
1220e1ba39fSStephan Aßmus // Perform
1230e1ba39fSStephan Aßmus Command*
Perform()1240e1ba39fSStephan Aßmus TransformGradientBox::Perform()
1250e1ba39fSStephan Aßmus {
1260e1ba39fSStephan Aßmus return NULL;
1270e1ba39fSStephan Aßmus }
1280e1ba39fSStephan Aßmus
1297f5bbbdcSAxel Dörfler
1300e1ba39fSStephan Aßmus // Cancel
1310e1ba39fSStephan Aßmus Command*
Cancel()1320e1ba39fSStephan Aßmus TransformGradientBox::Cancel()
1330e1ba39fSStephan Aßmus {
1340e1ba39fSStephan Aßmus SetTransformation(B_ORIGIN, B_ORIGIN, 0.0, 1.0, 1.0);
1350e1ba39fSStephan Aßmus
1360e1ba39fSStephan Aßmus return NULL;
1370e1ba39fSStephan Aßmus }
1380e1ba39fSStephan Aßmus
1397f5bbbdcSAxel Dörfler
1400e1ba39fSStephan Aßmus // TransformFromCanvas
1410e1ba39fSStephan Aßmus void
TransformFromCanvas(BPoint & point) const1420e1ba39fSStephan Aßmus TransformGradientBox::TransformFromCanvas(BPoint& point) const
1430e1ba39fSStephan Aßmus {
1440e1ba39fSStephan Aßmus if (fShape)
1450e1ba39fSStephan Aßmus fShape->InverseTransform(&point);
1460e1ba39fSStephan Aßmus fCanvasView->ConvertFromCanvas(&point);
1470e1ba39fSStephan Aßmus }
1480e1ba39fSStephan Aßmus
1497f5bbbdcSAxel Dörfler
1500e1ba39fSStephan Aßmus // TransformToCanvas
1510e1ba39fSStephan Aßmus void
TransformToCanvas(BPoint & point) const1520e1ba39fSStephan Aßmus TransformGradientBox::TransformToCanvas(BPoint& point) const
1530e1ba39fSStephan Aßmus {
1540e1ba39fSStephan Aßmus fCanvasView->ConvertToCanvas(&point);
1550e1ba39fSStephan Aßmus if (fShape)
1560e1ba39fSStephan Aßmus fShape->Transform(&point);
1570e1ba39fSStephan Aßmus }
1580e1ba39fSStephan Aßmus
1597f5bbbdcSAxel Dörfler
1600e1ba39fSStephan Aßmus // ZoomLevel
1610e1ba39fSStephan Aßmus float
ZoomLevel() const1620e1ba39fSStephan Aßmus TransformGradientBox::ZoomLevel() const
1630e1ba39fSStephan Aßmus {
1640e1ba39fSStephan Aßmus return fCanvasView->ZoomLevel();
1650e1ba39fSStephan Aßmus }
1660e1ba39fSStephan Aßmus
1677f5bbbdcSAxel Dörfler
1680e1ba39fSStephan Aßmus // ViewSpaceRotation
1690e1ba39fSStephan Aßmus double
ViewSpaceRotation() const1700e1ba39fSStephan Aßmus TransformGradientBox::ViewSpaceRotation() const
1710e1ba39fSStephan Aßmus {
1720e1ba39fSStephan Aßmus Transformable t(*this);
1730e1ba39fSStephan Aßmus if (fShape)
1740e1ba39fSStephan Aßmus t.Multiply(*fShape);
1757f5bbbdcSAxel Dörfler return t.rotation() * 180.0 / M_PI;
1760e1ba39fSStephan Aßmus }
1770e1ba39fSStephan Aßmus
1787f5bbbdcSAxel Dörfler
1790e1ba39fSStephan Aßmus // MakeCommand
1800e1ba39fSStephan Aßmus TransformCommand*
MakeCommand(const char * commandName)181*a75a222bSZardshard TransformGradientBox::MakeCommand(const char* commandName)
1820e1ba39fSStephan Aßmus {
183c88bc5e9SStephan Aßmus return new TransformGradientCommand(this, fGradient, Pivot(),
184c88bc5e9SStephan Aßmus Translation(), LocalRotation(), LocalXScale(), LocalYScale(),
185*a75a222bSZardshard commandName);
1860e1ba39fSStephan Aßmus }
1870e1ba39fSStephan Aßmus
188