xref: /haiku/src/apps/icon-o-matic/transformable/TransformGradientBox.cpp (revision a085e81e62d7a860f809b4fb7c7bf5654c396985)
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