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