xref: /haiku/src/kits/interface/Deskbar.cpp (revision 1826e60db574bf3cb8f2c394897c0b82e50dc3a0)
1 /*
2  * Copyright 2001-2018 Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Jérôme Duval
7  *		Axel Dörfler
8  *		Jeremy Rand, jrand@magma.ca
9  *		John Scipione, jscipione@gmail.com
10  */
11 
12 
13 #include <Deskbar.h>
14 
15 #include <string.h>
16 
17 #include <Messenger.h>
18 #include <Message.h>
19 #include <View.h>
20 #include <Rect.h>
21 #include <InterfaceDefs.h>
22 #include <Node.h>
23 
24 #include <DeskbarPrivate.h>
25 
26 
27 // TODO: in case the BDeskbar methods are called from a Deskbar add-on,
28 //	they will currently deadlock most of the time (only those that do
29 //	not need a reply will work).
30 //	That should be fixed in the Deskbar itself, even if the Be API found
31 //	a way around that (that doesn't work too well, BTW)
32 
33 // The API in this file should be considered as part of OpenTracker - but
34 // should work with all versions of Tracker available for Haiku.
35 
36 
37 status_t
get_deskbar_frame(BRect * frame)38 get_deskbar_frame(BRect* frame)
39 {
40 	BMessenger deskbar(kDeskbarSignature);
41 
42 	status_t result;
43 
44 	BMessage request(B_GET_PROPERTY);
45 	request.AddSpecifier("Frame");
46 	request.AddSpecifier("Window", (int32)0);
47 
48 	BMessage reply;
49 	result = deskbar.SendMessage(&request, &reply);
50 	if (result == B_OK)
51 		result = reply.FindRect("result", frame);
52 
53 	return result;
54 }
55 
56 
57 //	#pragma mark - BDeskbar
58 
59 
BDeskbar()60 BDeskbar::BDeskbar()
61 	:
62 	fMessenger(new BMessenger(kDeskbarSignature))
63 {
64 }
65 
66 
~BDeskbar()67 BDeskbar::~BDeskbar()
68 {
69 	delete fMessenger;
70 }
71 
72 
73 bool
IsRunning() const74 BDeskbar::IsRunning() const
75 {
76 	return fMessenger->IsValid();
77 }
78 
79 
80 //	#pragma mark - Item querying methods
81 
82 
83 BRect
Frame() const84 BDeskbar::Frame() const
85 {
86 	BRect frame(0.0, 0.0, 0.0, 0.0);
87 	get_deskbar_frame(&frame);
88 
89 	return frame;
90 }
91 
92 
93 deskbar_location
Location(bool * _isExpanded) const94 BDeskbar::Location(bool* _isExpanded) const
95 {
96 	deskbar_location location = B_DESKBAR_RIGHT_TOP;
97 	BMessage request(kMsgLocation);
98 	BMessage reply;
99 
100 	if (_isExpanded)
101 		*_isExpanded = true;
102 
103 	if (fMessenger->IsTargetLocal()) {
104 		// ToDo: do something about this!
105 		// (if we just ask the Deskbar in this case, we would deadlock)
106 		return location;
107 	}
108 
109 	if (fMessenger->SendMessage(&request, &reply) == B_OK) {
110 		int32 value;
111 		if (reply.FindInt32("location", &value) == B_OK)
112 			location = static_cast<deskbar_location>(value);
113 
114 		if (_isExpanded && reply.FindBool("expanded", _isExpanded) != B_OK)
115 			*_isExpanded = true;
116 	}
117 
118 	return location;
119 }
120 
121 
122 status_t
SetLocation(deskbar_location location,bool expanded)123 BDeskbar::SetLocation(deskbar_location location, bool expanded)
124 {
125 	BMessage request(kMsgSetLocation);
126 	request.AddInt32("location", static_cast<int32>(location));
127 	request.AddBool("expand", expanded);
128 
129 	return fMessenger->SendMessage(&request);
130 }
131 
132 
133 //	#pragma mark - Other state methods
134 
135 
136 bool
IsExpanded() const137 BDeskbar::IsExpanded() const
138 {
139 	BMessage request(kMsgIsExpanded);
140 	BMessage reply;
141 	bool isExpanded = true;
142 
143 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
144 		reply.FindBool("expanded", &isExpanded);
145 
146 	return isExpanded;
147 }
148 
149 
150 status_t
Expand(bool expand)151 BDeskbar::Expand(bool expand)
152 {
153 	BMessage request(kMsgExpand);
154 	request.AddBool("expand", expand);
155 
156 	return fMessenger->SendMessage(&request);
157 }
158 
159 
160 bool
IsAlwaysOnTop() const161 BDeskbar::IsAlwaysOnTop() const
162 {
163 	BMessage request(kMsgIsAlwaysOnTop);
164 	BMessage reply;
165 	bool isAlwaysOnTop = false;
166 
167 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
168 		reply.FindBool("always on top", &isAlwaysOnTop);
169 
170 	return isAlwaysOnTop;
171 }
172 
173 
174 status_t
SetAlwaysOnTop(bool alwaysOnTop)175 BDeskbar::SetAlwaysOnTop(bool alwaysOnTop)
176 {
177 	BMessage request(kMsgAlwaysOnTop);
178 	request.AddBool("always on top", alwaysOnTop);
179 
180 	return fMessenger->SendMessage(&request);
181 }
182 
183 
184 bool
IsAutoRaise() const185 BDeskbar::IsAutoRaise() const
186 {
187 	BMessage request(kMsgIsAutoRaise);
188 	BMessage reply;
189 	bool isAutoRaise = false;
190 
191 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
192 		reply.FindBool("auto raise", &isAutoRaise);
193 
194 	return isAutoRaise;
195 }
196 
197 
198 status_t
SetAutoRaise(bool autoRaise)199 BDeskbar::SetAutoRaise(bool autoRaise)
200 {
201 	BMessage request(kMsgAutoRaise);
202 	request.AddBool("auto raise", autoRaise);
203 
204 	return fMessenger->SendMessage(&request);
205 }
206 
207 
208 bool
IsAutoHide() const209 BDeskbar::IsAutoHide() const
210 {
211 	BMessage request(kMsgIsAutoHide);
212 	BMessage reply;
213 	bool isAutoHidden = false;
214 
215 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
216 		reply.FindBool("auto hide", &isAutoHidden);
217 
218 	return isAutoHidden;
219 }
220 
221 
222 status_t
SetAutoHide(bool autoHide)223 BDeskbar::SetAutoHide(bool autoHide)
224 {
225 	BMessage request(kMsgAutoHide);
226 	request.AddBool("auto hide", autoHide);
227 
228 	return fMessenger->SendMessage(&request);
229 }
230 
231 
232 //	#pragma mark - Item querying methods
233 
234 
235 status_t
GetItemInfo(int32 id,const char ** _name) const236 BDeskbar::GetItemInfo(int32 id, const char** _name) const
237 {
238 	if (_name == NULL)
239 		return B_BAD_VALUE;
240 
241 	// Note: Be's implementation returns B_BAD_VALUE if *_name was NULL,
242 	// not just if _name was NULL.  This doesn't make much sense, so we
243 	// do not imitate this behaviour.
244 
245 	BMessage request(kMsgGetItemInfo);
246 	request.AddInt32("id", id);
247 
248 	BMessage reply;
249 	status_t result = fMessenger->SendMessage(&request, &reply);
250 	if (result == B_OK) {
251 		const char* name;
252 		result = reply.FindString("name", &name);
253 		if (result == B_OK) {
254 			*_name = strdup(name);
255 			if (*_name == NULL)
256 				result = B_NO_MEMORY;
257 		}
258 	}
259 
260 	return result;
261 }
262 
263 
264 status_t
GetItemInfo(const char * name,int32 * _id) const265 BDeskbar::GetItemInfo(const char* name, int32* _id) const
266 {
267 	if (name == NULL)
268 		return B_BAD_VALUE;
269 
270 	BMessage request(kMsgGetItemInfo);
271 	request.AddString("name", name);
272 
273 	BMessage reply;
274 	status_t result = fMessenger->SendMessage(&request, &reply);
275 	if (result == B_OK)
276 		result = reply.FindInt32("id", _id);
277 
278 	return result;
279 }
280 
281 
282 bool
HasItem(int32 id) const283 BDeskbar::HasItem(int32 id) const
284 {
285 	BMessage request(kMsgHasItem);
286 	request.AddInt32("id", id);
287 
288 	BMessage reply;
289 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
290 		return reply.FindBool("exists");
291 
292 	return false;
293 }
294 
295 
296 bool
HasItem(const char * name) const297 BDeskbar::HasItem(const char* name) const
298 {
299 	BMessage request(kMsgHasItem);
300 	request.AddString("name", name);
301 
302 	BMessage reply;
303 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
304 		return reply.FindBool("exists");
305 
306 	return false;
307 }
308 
309 
310 uint32
CountItems() const311 BDeskbar::CountItems() const
312 {
313 	BMessage request(kMsgCountItems);
314 	BMessage reply;
315 
316 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
317 		return reply.FindInt32("count");
318 
319 	return 0;
320 }
321 
322 
323 float
MaxItemWidth() const324 BDeskbar::MaxItemWidth() const
325 {
326 	BMessage request(kMsgMaxItemSize);
327 	BMessage reply;
328 
329 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
330 		return reply.GetFloat("width", 129);
331 
332 	return 129;
333 }
334 
335 
336 float
MaxItemHeight() const337 BDeskbar::MaxItemHeight() const
338 {
339 	BMessage request(kMsgMaxItemSize);
340 	BMessage reply;
341 
342 	if (fMessenger->SendMessage(&request, &reply) == B_OK)
343 		return reply.GetFloat("height", 16);
344 
345 	return 16;
346 }
347 
348 
349 //	#pragma mark - Item modification methods
350 
351 
352 status_t
AddItem(BView * view,int32 * _id)353 BDeskbar::AddItem(BView* view, int32* _id)
354 {
355 	BMessage archive;
356 	status_t result = view->Archive(&archive);
357 	if (result < B_OK)
358 		return result;
359 
360 	BMessage request(kMsgAddView);
361 	request.AddMessage("view", &archive);
362 
363 	BMessage reply;
364 	result = fMessenger->SendMessage(&request, &reply);
365 	if (result == B_OK) {
366 		if (_id != NULL)
367 			result = reply.FindInt32("id", _id);
368 		else
369 			reply.FindInt32("error", &result);
370 	}
371 
372 	return result;
373 }
374 
375 
376 status_t
AddItem(entry_ref * addon,int32 * _id)377 BDeskbar::AddItem(entry_ref* addon, int32* _id)
378 {
379 	BMessage request(kMsgAddAddOn);
380 	request.AddRef("addon", addon);
381 
382 	BMessage reply;
383 	status_t status = fMessenger->SendMessage(&request, &reply);
384 	if (status == B_OK) {
385 		if (_id != NULL)
386 			status = reply.FindInt32("id", _id);
387 		else
388 			reply.FindInt32("error", &status);
389 	}
390 
391 	return status;
392 }
393 
394 
395 status_t
RemoveItem(int32 id)396 BDeskbar::RemoveItem(int32 id)
397 {
398 	BMessage request(kMsgRemoveItem);
399 	request.AddInt32("id", id);
400 
401 	// ToDo: the Deskbar does not reply to this message, so we don't
402 	// know if it really succeeded - we can just acknowledge that the
403 	// message was sent to the Deskbar
404 
405 	return fMessenger->SendMessage(&request);
406 }
407 
408 
409 status_t
RemoveItem(const char * name)410 BDeskbar::RemoveItem(const char* name)
411 {
412 	BMessage request(kMsgRemoveItem);
413 	request.AddString("name", name);
414 
415 	// ToDo: the Deskbar does not reply to this message, so we don't
416 	// know if it really succeeded - we can just acknowledge that the
417 	// message was sent to the Deskbar
418 
419 	return fMessenger->SendMessage(&request);
420 }
421