xref: /haiku/src/apps/icon-o-matic/transformable/TransformGradientBox.cpp (revision e1c4049fed1047bdb957b0529e1921e97ef94770)
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)
182 {
183 	return new TransformGradientCommand(this, fGradient, Pivot(),
184 	   Translation(), LocalRotation(), LocalXScale(), LocalYScale(),
185 	   commandName);
186 }
187 
188