xref: /haiku/src/apps/icon-o-matic/transformable/TransformGradientBox.cpp (revision ddac407426cd3b3d0b4589d7a161b300b3539a2a)
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 "TransformObjectsCommand.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 		return;
104 	}
105 
106 	// any TransformObjectsCommand cannot use the TransformBox
107 	// anymore
108 	_NotifyDeleted();
109 
110 	fGradient->StoreTo(fOriginals);
111 
112 	// figure out bounds and store initial transformations
113 	SetTransformation(*fGradient);
114 	SetBox(fGradient->GradientArea());
115 
116 	fView->UnlockLooper();
117 }
118 
119 
120 // Perform
121 Command*
122 TransformGradientBox::Perform()
123 {
124 	return NULL;
125 }
126 
127 
128 // Cancel
129 Command*
130 TransformGradientBox::Cancel()
131 {
132 	SetTransformation(B_ORIGIN, B_ORIGIN, 0.0, 1.0, 1.0);
133 
134 	return NULL;
135 }
136 
137 
138 // TransformFromCanvas
139 void
140 TransformGradientBox::TransformFromCanvas(BPoint& point) const
141 {
142 	if (fShape)
143 		fShape->InverseTransform(&point);
144 	fCanvasView->ConvertFromCanvas(&point);
145 }
146 
147 
148 // TransformToCanvas
149 void
150 TransformGradientBox::TransformToCanvas(BPoint& point) const
151 {
152 	fCanvasView->ConvertToCanvas(&point);
153 	if (fShape)
154 		fShape->Transform(&point);
155 }
156 
157 
158 // ZoomLevel
159 float
160 TransformGradientBox::ZoomLevel() const
161 {
162 	return fCanvasView->ZoomLevel();
163 }
164 
165 
166 // ViewSpaceRotation
167 double
168 TransformGradientBox::ViewSpaceRotation() const
169 {
170 	Transformable t(*this);
171 	if (fShape)
172 		t.Multiply(*fShape);
173 	return t.rotation() * 180.0 / M_PI;
174 }
175 
176 
177 // MakeCommand
178 TransformCommand*
179 TransformGradientBox::MakeCommand(const char* commandName, uint32 nameIndex)
180 {
181 	Transformable* objects[1];
182 	objects[0] = fGradient;
183 
184 	return new TransformObjectsCommand(this, objects, fOriginals, 1, Pivot(),
185 	   Translation(), LocalRotation(), LocalXScale(), LocalYScale(), commandName,
186 	   nameIndex);
187 }
188 
189