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->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 49 TransformGradientBox::~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 61 void 62 TransformGradientBox::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 95 void 96 TransformGradientBox::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 122 Command* 123 TransformGradientBox::Perform() 124 { 125 return NULL; 126 } 127 128 129 // Cancel 130 Command* 131 TransformGradientBox::Cancel() 132 { 133 SetTransformation(B_ORIGIN, B_ORIGIN, 0.0, 1.0, 1.0); 134 135 return NULL; 136 } 137 138 139 // TransformFromCanvas 140 void 141 TransformGradientBox::TransformFromCanvas(BPoint& point) const 142 { 143 if (fShape) 144 fShape->InverseTransform(&point); 145 fCanvasView->ConvertFromCanvas(&point); 146 } 147 148 149 // TransformToCanvas 150 void 151 TransformGradientBox::TransformToCanvas(BPoint& point) const 152 { 153 fCanvasView->ConvertToCanvas(&point); 154 if (fShape) 155 fShape->Transform(&point); 156 } 157 158 159 // ZoomLevel 160 float 161 TransformGradientBox::ZoomLevel() const 162 { 163 return fCanvasView->ZoomLevel(); 164 } 165 166 167 // ViewSpaceRotation 168 double 169 TransformGradientBox::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 179 TransformCommand* 180 TransformGradientBox::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