1/*
2 * Copyright 2010, Haiku.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Clemens Zeidler <haiku@clemens-zeidler.de>
7 */
8
9
10#include "DesktopListener.h"
11
12
13DesktopListener::~DesktopListener()
14{
15
16}
17
18
19DesktopObservable::DesktopObservable()
20	:
21	fWeAreInvoking(false)
22{
23
24}
25
26
27void
28DesktopObservable::RegisterListener(DesktopListener* listener, Desktop* desktop)
29{
30	fDesktopListenerList.Add(listener);
31	listener->ListenerRegistered(desktop);
32}
33
34
35void
36DesktopObservable::UnregisterListener(DesktopListener* listener)
37{
38	fDesktopListenerList.Remove(listener);
39	listener->ListenerUnregistered();
40}
41
42
43const DesktopListenerDLList&
44DesktopObservable::GetDesktopListenerList()
45{
46	return fDesktopListenerList;
47}
48
49
50bool
51DesktopObservable::MessageForListener(Window* sender,
52	BPrivate::LinkReceiver& link, BPrivate::LinkSender& reply)
53{
54	int32 identifier;
55	link.Read<int32>(&identifier);
56	for (DesktopListener* listener = fDesktopListenerList.First();
57		listener != NULL; listener = fDesktopListenerList.GetNext(listener)) {
58		if (listener->Identifier() == identifier) {
59			if (!listener->HandleMessage(sender, link, reply))
60				break;
61			return true;
62		}
63	}
64	return false;
65}
66
67
68void
69DesktopObservable::NotifyWindowAdded(Window* window)
70{
71	if (fWeAreInvoking)
72		return;
73	InvokeGuard invokeGuard(fWeAreInvoking);
74
75	for (DesktopListener* listener = fDesktopListenerList.First();
76		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
77		listener->WindowAdded(window);
78}
79
80
81void
82DesktopObservable::NotifyWindowRemoved(Window* window)
83{
84	if (fWeAreInvoking)
85		return;
86	InvokeGuard invokeGuard(fWeAreInvoking);
87
88	for (DesktopListener* listener = fDesktopListenerList.First();
89		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
90		listener->WindowRemoved(window);
91}
92
93
94bool
95DesktopObservable::NotifyKeyPressed(uint32 what, int32 key, int32 modifiers)
96{
97	if (fWeAreInvoking)
98		return false;
99	InvokeGuard invokeGuard(fWeAreInvoking);
100
101	bool skipEvent = false;
102	for (DesktopListener* listener = fDesktopListenerList.First();
103		listener != NULL; listener = fDesktopListenerList.GetNext(listener)) {
104		if (listener->KeyPressed(what, key, modifiers))
105			skipEvent = true;
106	}
107	return skipEvent;
108}
109
110
111void
112DesktopObservable::NotifyMouseEvent(BMessage* message)
113{
114	if (fWeAreInvoking)
115		return;
116	InvokeGuard invokeGuard(fWeAreInvoking);
117
118	for (DesktopListener* listener = fDesktopListenerList.First();
119		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
120		listener->MouseEvent(message);
121}
122
123
124void
125DesktopObservable::NotifyMouseDown(Window* window, BMessage* message,
126	const BPoint& where)
127{
128	if (fWeAreInvoking)
129		return;
130	InvokeGuard invokeGuard(fWeAreInvoking);
131
132	for (DesktopListener* listener = fDesktopListenerList.First();
133		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
134		listener->MouseDown(window, message, where);
135}
136
137
138void
139DesktopObservable::NotifyMouseUp(Window* window, BMessage* message,
140	const BPoint& where)
141{
142	if (fWeAreInvoking)
143		return;
144	InvokeGuard invokeGuard(fWeAreInvoking);
145
146	for (DesktopListener* listener = fDesktopListenerList.First();
147		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
148		listener->MouseUp(window, message, where);
149}
150
151
152void
153DesktopObservable::NotifyMouseMoved(Window* window, BMessage* message,
154	const BPoint& where)
155{
156	if (fWeAreInvoking)
157		return;
158	InvokeGuard invokeGuard(fWeAreInvoking);
159
160	for (DesktopListener* listener = fDesktopListenerList.First();
161		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
162		listener->MouseMoved(window, message, where);
163}
164
165
166void
167DesktopObservable::NotifyWindowMoved(Window* window)
168{
169	if (fWeAreInvoking)
170		return;
171	InvokeGuard invokeGuard(fWeAreInvoking);
172
173	for (DesktopListener* listener = fDesktopListenerList.First();
174		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
175		listener->WindowMoved(window);
176}
177
178
179void
180DesktopObservable::NotifyWindowResized(Window* window)
181{
182	if (fWeAreInvoking)
183		return;
184	InvokeGuard invokeGuard(fWeAreInvoking);
185
186	for (DesktopListener* listener = fDesktopListenerList.First();
187		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
188		listener->WindowResized(window);
189}
190
191
192void
193DesktopObservable::NotifyWindowActivated(Window* window)
194{
195	if (fWeAreInvoking)
196		return;
197	InvokeGuard invokeGuard(fWeAreInvoking);
198
199	for (DesktopListener* listener = fDesktopListenerList.First();
200		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
201		listener->WindowActivated(window);
202}
203
204
205void
206DesktopObservable::NotifyWindowSentBehind(Window* window, Window* behindOf)
207{
208	if (fWeAreInvoking)
209		return;
210	InvokeGuard invokeGuard(fWeAreInvoking);
211
212	for (DesktopListener* listener = fDesktopListenerList.First();
213		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
214		listener->WindowSentBehind(window, behindOf);
215}
216
217
218void
219DesktopObservable::NotifyWindowWorkspacesChanged(Window* window,
220	uint32 workspaces)
221{
222	if (fWeAreInvoking)
223		return;
224	InvokeGuard invokeGuard(fWeAreInvoking);
225
226	for (DesktopListener* listener = fDesktopListenerList.First();
227		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
228		listener->WindowWorkspacesChanged(window, workspaces);
229}
230
231
232void
233DesktopObservable::NotifyWindowHidden(Window* window, bool fromMinimize)
234{
235	if (fWeAreInvoking)
236		return;
237	InvokeGuard invokeGuard(fWeAreInvoking);
238
239	for (DesktopListener* listener = fDesktopListenerList.First();
240		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
241		listener->WindowHidden(window, fromMinimize);
242}
243
244
245void
246DesktopObservable::NotifyWindowMinimized(Window* window, bool minimize)
247{
248	if (fWeAreInvoking)
249		return;
250	InvokeGuard invokeGuard(fWeAreInvoking);
251
252	for (DesktopListener* listener = fDesktopListenerList.First();
253		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
254		listener->WindowMinimized(window, minimize);
255}
256
257
258void
259DesktopObservable::NotifyWindowTabLocationChanged(Window* window,
260	float location, bool isShifting)
261{
262	if (fWeAreInvoking)
263		return;
264	InvokeGuard invokeGuard(fWeAreInvoking);
265
266	for (DesktopListener* listener = fDesktopListenerList.First();
267		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
268		listener->WindowTabLocationChanged(window, location, isShifting);
269}
270
271
272void
273DesktopObservable::NotifySizeLimitsChanged(Window* window, int32 minWidth,
274	int32 maxWidth, int32 minHeight, int32 maxHeight)
275{
276	if (fWeAreInvoking)
277		return;
278	InvokeGuard invokeGuard(fWeAreInvoking);
279
280	for (DesktopListener* listener = fDesktopListenerList.First();
281		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
282		listener->SizeLimitsChanged(window, minWidth, maxWidth, minHeight,
283			maxHeight);
284}
285
286
287void
288DesktopObservable::NotifyWindowLookChanged(Window* window, window_look look)
289{
290	if (fWeAreInvoking)
291		return;
292	InvokeGuard invokeGuard(fWeAreInvoking);
293
294	for (DesktopListener* listener = fDesktopListenerList.First();
295		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
296		listener->WindowLookChanged(window, look);
297}
298
299
300void
301DesktopObservable::NotifyWindowFeelChanged(Window* window, window_feel feel)
302{
303	if (fWeAreInvoking)
304		return;
305	InvokeGuard invokeGuard(fWeAreInvoking);
306
307	for (DesktopListener* listener = fDesktopListenerList.First();
308		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
309		listener->WindowFeelChanged(window, feel);
310}
311
312
313bool
314DesktopObservable::SetDecoratorSettings(Window* window,
315	const BMessage& settings)
316{
317	if (fWeAreInvoking)
318		return false;
319	InvokeGuard invokeGuard(fWeAreInvoking);
320
321	bool changed = false;
322	for (DesktopListener* listener = fDesktopListenerList.First();
323		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
324		changed = changed | listener->SetDecoratorSettings(window, settings);
325
326	return changed;
327}
328
329
330void
331DesktopObservable::GetDecoratorSettings(Window* window, BMessage& settings)
332{
333	if (fWeAreInvoking)
334		return;
335	InvokeGuard invokeGuard(fWeAreInvoking);
336
337	for (DesktopListener* listener = fDesktopListenerList.First();
338		listener != NULL; listener = fDesktopListenerList.GetNext(listener))
339		listener->GetDecoratorSettings(window, settings);
340}
341
342
343DesktopObservable::InvokeGuard::InvokeGuard(bool& invoking)
344	:
345	fInvoking(invoking)
346{
347	fInvoking = true;
348}
349
350
351DesktopObservable::InvokeGuard::~InvokeGuard()
352{
353	fInvoking = false;
354}
355