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->AcquireReference(); 37 fShape->AddObserver(this); 38 } 39 if (fGradient.IsSet()) { 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->ReleaseReference(); 54 } 55 if (fGradient.IsSet()) { 56 fGradient->RemoveObserver(this); 57 } 58} 59 60 61// Update 62void 63TransformGradientBox::Update(bool deep) 64{ 65 BRect r = Bounds(); 66 67 TransformBox::Update(deep); 68 69 BRect dirty(r | Bounds()); 70 dirty.InsetBy(-8, -8); 71 fView->Invalidate(dirty); 72 73 if (!deep || !fGradient.IsSet()) 74 return; 75 76 fGradient->RemoveObserver(this); 77 fGradient->SuspendNotifications(true); 78 79 // reset the objects transformation to the saved state 80 fGradient->Reset(); 81 // combine with the current transformation 82 fGradient->Multiply(*this); 83 84//printf("matrix:\n"); 85//double m[6]; 86//StoreTo(m); 87//printf("[%5.10f] [%5.10f] [%5.10f]\n", m[0], m[1], m[2]); 88//printf("[%5.10f] [%5.10f] [%5.10f]\n", m[3], m[4], m[5]); 89// 90 fGradient->SuspendNotifications(false); 91 fGradient->AddObserver(this); 92} 93 94 95// ObjectChanged 96void 97TransformGradientBox::ObjectChanged(const Observable* object) 98{ 99 if (!fGradient.IsSet() || !fView->LockLooper()) 100 return; 101 102 if (object == fShape) { 103 fView->Invalidate(Bounds()); 104 fView->UnlockLooper(); 105 return; 106 } 107 108 // any TransformGradientCommand cannot use the TransformBox 109 // anymore 110 _NotifyDeleted(); 111 112 fGradient->StoreTo(fOriginals); 113 114 // figure out bounds and store initial transformations 115 SetTransformation(*fGradient); 116 SetBox(fGradient->GradientArea()); 117 118 fView->UnlockLooper(); 119} 120 121 122// Perform 123Command* 124TransformGradientBox::Perform() 125{ 126 return NULL; 127} 128 129 130// Cancel 131Command* 132TransformGradientBox::Cancel() 133{ 134 SetTransformation(B_ORIGIN, B_ORIGIN, 0.0, 1.0, 1.0); 135 136 return NULL; 137} 138 139 140// TransformFromCanvas 141void 142TransformGradientBox::TransformFromCanvas(BPoint& point) const 143{ 144 if (fShape) 145 fShape->InverseTransform(&point); 146 fCanvasView->ConvertFromCanvas(&point); 147} 148 149 150// TransformToCanvas 151void 152TransformGradientBox::TransformToCanvas(BPoint& point) const 153{ 154 fCanvasView->ConvertToCanvas(&point); 155 if (fShape) 156 fShape->Transform(&point); 157} 158 159 160// ZoomLevel 161float 162TransformGradientBox::ZoomLevel() const 163{ 164 return fCanvasView->ZoomLevel(); 165} 166 167 168// ViewSpaceRotation 169double 170TransformGradientBox::ViewSpaceRotation() const 171{ 172 Transformable t(*this); 173 if (fShape) 174 t.Multiply(*fShape); 175 return t.rotation() * 180.0 / M_PI; 176} 177 178 179// MakeCommand 180TransformCommand* 181TransformGradientBox::MakeCommand(const char* commandName) 182{ 183 return new TransformGradientCommand(this, fGradient, Pivot(), 184 Translation(), LocalRotation(), LocalXScale(), LocalYScale(), 185 commandName); 186} 187 188