1/* 2 * Copyright 2006-2009, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Stephan A��mus <superstippi@gmx.de> 7 */ 8 9#include "TransformGradientBox.h" 10 11#include <new> 12#include <stdio.h> 13#include <string.h> 14 15#include "CanvasView.h" 16#include "GradientTransformable.h" 17#include "Shape.h" 18#include "StateView.h" 19#include "TransformGradientCommand.h" 20 21using std::nothrow; 22 23 24// constructor 25TransformGradientBox::TransformGradientBox(CanvasView* view, Gradient* gradient, 26 Shape* parentShape) 27 : 28 TransformBox(view, BRect(0.0, 0.0, 1.0, 1.0)), 29 30 fCanvasView(view), 31 32 fShape(parentShape), 33 fGradient(gradient) 34{ 35 if (fShape) { 36 fShape->Acquire(); 37 fShape->AddObserver(this); 38 } 39 if (fGradient) { 40 // trigger init 41 ObjectChanged(fGradient); 42 } else { 43 SetBox(BRect(0, 0, -1, -1)); 44 } 45} 46 47 48// destructor 49TransformGradientBox::~TransformGradientBox() 50{ 51 if (fShape) { 52 fShape->RemoveObserver(this); 53 fShape->Release(); 54 } 55 if (fGradient) 56 fGradient->RemoveObserver(this); 57} 58 59 60// Update 61void 62TransformGradientBox::Update(bool deep) 63{ 64 BRect r = Bounds(); 65 66 TransformBox::Update(deep); 67 68 BRect dirty(r | Bounds()); 69 dirty.InsetBy(-8, -8); 70 fView->Invalidate(dirty); 71 72 if (!deep || !fGradient) 73 return; 74 75 fGradient->RemoveObserver(this); 76 fGradient->SuspendNotifications(true); 77 78 // reset the objects transformation to the saved state 79 fGradient->Reset(); 80 // combine with the current transformation 81 fGradient->Multiply(*this); 82 83//printf("matrix:\n"); 84//double m[6]; 85//StoreTo(m); 86//printf("[%5.10f] [%5.10f] [%5.10f]\n", m[0], m[1], m[2]); 87//printf("[%5.10f] [%5.10f] [%5.10f]\n", m[3], m[4], m[5]); 88// 89 fGradient->SuspendNotifications(false); 90 fGradient->AddObserver(this); 91} 92 93 94// ObjectChanged 95void 96TransformGradientBox::ObjectChanged(const Observable* object) 97{ 98 if (!fGradient || !fView->LockLooper()) 99 return; 100 101 if (object == fShape) { 102 fView->Invalidate(Bounds()); 103 fView->UnlockLooper(); 104 return; 105 } 106 107 // any TransformGradientCommand cannot use the TransformBox 108 // anymore 109 _NotifyDeleted(); 110 111 fGradient->StoreTo(fOriginals); 112 113 // figure out bounds and store initial transformations 114 SetTransformation(*fGradient); 115 SetBox(fGradient->GradientArea()); 116 117 fView->UnlockLooper(); 118} 119 120 121// Perform 122Command* 123TransformGradientBox::Perform() 124{ 125 return NULL; 126} 127 128 129// Cancel 130Command* 131TransformGradientBox::Cancel() 132{ 133 SetTransformation(B_ORIGIN, B_ORIGIN, 0.0, 1.0, 1.0); 134 135 return NULL; 136} 137 138 139// TransformFromCanvas 140void 141TransformGradientBox::TransformFromCanvas(BPoint& point) const 142{ 143 if (fShape) 144 fShape->InverseTransform(&point); 145 fCanvasView->ConvertFromCanvas(&point); 146} 147 148 149// TransformToCanvas 150void 151TransformGradientBox::TransformToCanvas(BPoint& point) const 152{ 153 fCanvasView->ConvertToCanvas(&point); 154 if (fShape) 155 fShape->Transform(&point); 156} 157 158 159// ZoomLevel 160float 161TransformGradientBox::ZoomLevel() const 162{ 163 return fCanvasView->ZoomLevel(); 164} 165 166 167// ViewSpaceRotation 168double 169TransformGradientBox::ViewSpaceRotation() const 170{ 171 Transformable t(*this); 172 if (fShape) 173 t.Multiply(*fShape); 174 return t.rotation() * 180.0 / M_PI; 175} 176 177 178// MakeCommand 179TransformCommand* 180TransformGradientBox::MakeCommand(const char* commandName, uint32 nameIndex) 181{ 182 return new TransformGradientCommand(this, fGradient, Pivot(), 183 Translation(), LocalRotation(), LocalXScale(), LocalYScale(), 184 commandName, nameIndex); 185} 186 187