xref: /haiku/src/tests/servers/app/playground/ObjectView.cpp (revision 93aeb8c3bc3f13cb1f282e3e749258a23790d947)
1 // ObjectView.cpp
2 
3 #include <stdio.h>
4 
5 #include <Message.h>
6 #include <String.h>
7 #include <Window.h>
8 
9 #include "States.h"
10 
11 #include "ObjectView.h"
12 
13 // constructor
14 ObjectView::ObjectView(BRect frame, const char* name,
15 					 uint32 resizeFlags, uint32 flags)
16 	: BView(frame, name, resizeFlags, flags | B_FRAME_EVENTS),
17 	  fState(NULL),
18 	  fObjectType(OBJECT_LINE),
19 	  fStateList(20),
20 	  fColor((rgb_color){ 0, 80, 255, 100 }),
21 	  fDrawingMode(B_OP_ALPHA),
22 	  fFill(false),
23 	  fPenSize(10.0),
24 	  fScrolling(false),
25 	  fLastMousePos(0.0, 0.0)
26 {
27 
28 	SetLowColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_1_TINT));
29 
30 	BFont font;
31 	GetFont(&font);
32 	font.SetSize(20.0);
33 	font.SetRotation(6.0);
34 	SetFont(&font, B_FONT_ROTATION | B_FONT_SIZE);
35 }
36 
37 // AttachedToWindow
38 void
39 ObjectView::AttachedToWindow()
40 {
41 	SetViewColor(B_TRANSPARENT_COLOR);
42 }
43 
44 // Draw
45 void
46 ObjectView::Draw(BRect updateRect)
47 {
48 	FillRect(updateRect, B_SOLID_LOW);
49 
50 	rgb_color noTint = ui_color(B_PANEL_BACKGROUND_COLOR);
51 	rgb_color shadow = tint_color(noTint, B_DARKEN_2_TINT);
52 	rgb_color light = tint_color(noTint, B_LIGHTEN_MAX_TINT);
53 
54 	BRect r(Bounds());
55 
56 /*	BeginLineArray(4);
57 	AddLine(BPoint(r.left, r.top),
58 			BPoint(r.right, r.top), shadow);
59 	AddLine(BPoint(r.right, r.top + 1),
60 			BPoint(r.right, r.bottom), light);
61 	AddLine(BPoint(r.right - 1, r.bottom),
62 			BPoint(r.left, r.bottom), light);
63 	AddLine(BPoint(r.left, r.bottom - 1),
64 			BPoint(r.left, r.top + 1), shadow);
65 	EndLineArray();*/
66 
67 	SetHighColor(255, 0, 0, 128);
68 
69 	const char* message = "Click and drag";
70 	float width = StringWidth(message);
71 	BPoint p(r.Width() / 2.0 - width / 2.0,
72 			 r.Height() / 2.0);
73 
74 	DrawString(message, p);
75 
76 	message = "to draw an object!";
77 	width = StringWidth(message);
78 	p.x = r.Width() / 2.0 - width / 2.0;
79 	p.y += 25;
80 
81 	DrawString(message, p);
82 
83 	SetDrawingMode(B_OP_ALPHA);
84 	for (int32 i = 0; State* state = (State*)fStateList.ItemAt(i); i++)
85 		state->Draw(this);
86 }
87 
88 // MouseDown
89 void
90 ObjectView::MouseDown(BPoint where)
91 {
92 	uint32 buttons;
93 	int32 clicks;
94 	Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons);
95 	Window()->CurrentMessage()->FindInt32("clicks", &clicks);
96 printf("ObjectView::MouseDown() - clicks: %ld\n", clicks);
97 	fScrolling = buttons & B_SECONDARY_MOUSE_BUTTON;
98 
99 	SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
100 
101 	if (fScrolling) {
102 		fLastMousePos = where;
103 	} else {
104 		if (!fState)
105 			AddObject(State::StateFor(fObjectType, fColor, fDrawingMode,
106 									  fFill, fPenSize));
107 
108 		if (fState) {
109 //			Invalidate(fState->Bounds());
110 			fState->MouseDown(where);
111 //			Invalidate(fState->Bounds());
112 		}
113 	}
114 }
115 
116 // MouseUp
117 void
118 ObjectView::MouseUp(BPoint where)
119 {
120 	if (fScrolling) {
121 		fScrolling = false;
122 	} else {
123 		if (fState) {
124 			fState->MouseUp(where);
125 		}
126 	}
127 }
128 
129 // MouseMoved
130 void
131 ObjectView::MouseMoved(BPoint where, uint32 transit,
132 					   const BMessage* dragMessage)
133 {
134 	if (fScrolling) {
135 		BPoint offset = fLastMousePos - where;
136 		ScrollBy(offset.x, offset.y);
137 		fLastMousePos = where + offset;
138 	} else {
139 		if (fState && fState->IsTracking()) {
140 			BRect before = fState->Bounds();
141 
142 			fState->MouseMoved(where);
143 
144 			BRect after = fState->Bounds();
145 			BRect invalid(before | after);
146 			Invalidate(invalid);
147 		}
148 	}
149 }
150 
151 // SetState
152 void
153 ObjectView::SetState(State* state)
154 {
155 	if (fState != state) {
156 		if (fState) {
157 			fState->SetEditing(false);
158 			Invalidate(fState->Bounds());
159 		}
160 
161 		fState = state;
162 
163 		if (fState) {
164 			fState->SetEditing(true);
165 			Invalidate(fState->Bounds());
166 		}
167 	}
168 }
169 
170 // SetObjectType
171 void
172 ObjectView::SetObjectType(int32 type)
173 {
174 	if (type != fObjectType) {
175 		fObjectType = type;
176 		SetState(NULL);
177 	}
178 }
179 
180 // AddObject
181 void
182 ObjectView::AddObject(State* state)
183 {
184 	if (state) {
185 		fStateList.AddItem((void*)state);
186 		Window()->PostMessage(MSG_OBJECT_COUNT_CHANGED);
187 
188 		SetState(state);
189 	}
190 }
191 
192 // CountObjects
193 int32
194 ObjectView::CountObjects() const
195 {
196 	return fStateList.CountItems();
197 }
198 
199 // MakeEmpty
200 void
201 ObjectView::MakeEmpty()
202 {
203 	for (int32 i = 0; State* state = (State*)fStateList.ItemAt(i); i++)
204 		delete state;
205 	fStateList.MakeEmpty();
206 
207 	Window()->PostMessage(MSG_OBJECT_COUNT_CHANGED);
208 
209 	fState = NULL;
210 
211 	Invalidate();
212 }
213 
214 // SetStateColor
215 void
216 ObjectView::SetStateColor(rgb_color color)
217 {
218 	if (color.red != fColor.red ||
219 		color.green != fColor.green ||
220 		color.blue != fColor.blue ||
221 		color.alpha != fColor.alpha) {
222 
223 		fColor = color;
224 
225 		if (fState) {
226 			fState->SetColor(fColor);
227 			Invalidate(fState->Bounds());
228 		}
229 	}
230 }
231 
232 // SetStateDrawingMode
233 void
234 ObjectView::SetStateDrawingMode(drawing_mode mode)
235 {
236 	if (fDrawingMode != mode) {
237 		fDrawingMode = mode;
238 
239 		if (fState) {
240 			fState->SetDrawingMode(fDrawingMode);
241 			Invalidate(fState->Bounds());
242 		}
243 	}
244 }
245 
246 // SetStateFill
247 void
248 ObjectView::SetStateFill(bool fill)
249 {
250 	if (fFill != fill) {
251 		fFill = fill;
252 
253 		if (fState) {
254 			BRect before = fState->Bounds();
255 
256 			fState->SetFill(fFill);
257 
258 			BRect after = fState->Bounds();
259 			BRect invalid(before | after);
260 			Invalidate(invalid);
261 		}
262 	}
263 }
264 
265 // SetStatePenSize
266 void
267 ObjectView::SetStatePenSize(float penSize)
268 {
269 	if (fPenSize != penSize) {
270 		fPenSize = penSize;
271 
272 		if (fState) {
273 			BRect before = fState->Bounds();
274 
275 			fState->SetPenSize(fPenSize);
276 
277 			BRect after = fState->Bounds();
278 			BRect invalid(before | after);
279 			Invalidate(invalid);
280 		}
281 	}
282 }
283