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 21 using std::nothrow; 22 23 24 // constructor 25 TransformGradientBox::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 49 TransformGradientBox::~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 62 void 63 TransformGradientBox::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 96 void 97 TransformGradientBox::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 123 Command* 124 TransformGradientBox::Perform() 125 { 126 return NULL; 127 } 128 129 130 // Cancel 131 Command* 132 TransformGradientBox::Cancel() 133 { 134 SetTransformation(B_ORIGIN, B_ORIGIN, 0.0, 1.0, 1.0); 135 136 return NULL; 137 } 138 139 140 // TransformFromCanvas 141 void 142 TransformGradientBox::TransformFromCanvas(BPoint& point) const 143 { 144 if (fShape) 145 fShape->InverseTransform(&point); 146 fCanvasView->ConvertFromCanvas(&point); 147 } 148 149 150 // TransformToCanvas 151 void 152 TransformGradientBox::TransformToCanvas(BPoint& point) const 153 { 154 fCanvasView->ConvertToCanvas(&point); 155 if (fShape) 156 fShape->Transform(&point); 157 } 158 159 160 // ZoomLevel 161 float 162 TransformGradientBox::ZoomLevel() const 163 { 164 return fCanvasView->ZoomLevel(); 165 } 166 167 168 // ViewSpaceRotation 169 double 170 TransformGradientBox::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 180 TransformCommand* 181 TransformGradientBox::MakeCommand(const char* commandName, uint32 nameIndex) 182 { 183 return new TransformGradientCommand(this, fGradient, Pivot(), 184 Translation(), LocalRotation(), LocalXScale(), LocalYScale(), 185 commandName, nameIndex); 186 } 187 188