xref: /haiku/src/kits/interface/ChannelControl.cpp (revision 5e96d7d537fbec23bad4ae9b4c8e7b02e769f0c6)
1 /*
2  * Copyright 2005-2009, Haiku Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <ChannelControl.h>
8 #include <PropertyInfo.h>
9 
10 
11 static property_info
12 sPropertyInfo[] = {
13 	{ "ChannelCount",
14 		{ B_GET_PROPERTY, B_SET_PROPERTY, 0 },
15 		{ B_DIRECT_SPECIFIER, 0 }, NULL, 0, { B_INT32_TYPE }
16 	},
17 
18 	{ "CurrentChannel",
19 		{ B_GET_PROPERTY, B_SET_PROPERTY, 0 },
20 		{ B_DIRECT_SPECIFIER, 0	}, NULL, 0, { B_INT32_TYPE }
21 	},
22 
23 	{ "MaxLimitLabel",
24 		{ B_GET_PROPERTY, B_SET_PROPERTY, 0 },
25 		{ B_DIRECT_SPECIFIER, 0	}, NULL, 0, { B_STRING_TYPE }
26 	},
27 
28 	{ "MinLimitLabel",
29 		{ B_GET_PROPERTY, B_SET_PROPERTY, 0 },
30 		{ B_DIRECT_SPECIFIER, 0	}, NULL, 0, { B_STRING_TYPE }
31 	},
32 
33 	{ 0 }
34 };
35 
36 
37 BChannelControl::BChannelControl(BRect frame, const char *name, const char *label,
38 	BMessage *model, int32 channel_count, uint32 resizeMode, uint32 flags)
39 	: BControl(frame, name, label, model, resizeMode, flags),
40 	fChannelCount(channel_count),
41 	fCurrentChannel(0),
42 	fChannelMin(NULL),
43 	fChannelMax(NULL),
44 	fChannelValues(NULL),
45 	fMultiLabels(NULL),
46 	fModificationMsg(NULL)
47 {
48 	fChannelMin = new int32[channel_count];
49 	memset(fChannelMin, 0, sizeof(int32) * channel_count);
50 
51 	fChannelMax = new int32[channel_count];
52 	for (int32 i = 0; i < channel_count; i++)
53 		fChannelMax[i] = 100;
54 
55 	fChannelValues = new int32[channel_count];
56 	memset(fChannelValues, 0, sizeof(int32) * channel_count);
57 }
58 
59 
60 BChannelControl::BChannelControl(const char *name, const char *label,
61 	BMessage *model, int32 channel_count, uint32 flags)
62 	: BControl(name, label, model, flags),
63 	fChannelCount(channel_count),
64 	fCurrentChannel(0),
65 	fChannelMin(NULL),
66 	fChannelMax(NULL),
67 	fChannelValues(NULL),
68 	fMultiLabels(NULL),
69 	fModificationMsg(NULL)
70 {
71 	fChannelMin = new int32[channel_count];
72 	memset(fChannelMin, 0, sizeof(int32) * channel_count);
73 
74 	fChannelMax = new int32[channel_count];
75 	for (int32 i = 0; i < channel_count; i++)
76 		fChannelMax[i] = 100;
77 
78 	fChannelValues = new int32[channel_count];
79 	memset(fChannelValues, 0, sizeof(int32) * channel_count);
80 }
81 
82 
83 BChannelControl::BChannelControl(BMessage *archive)
84 	: BControl(archive),
85 	fChannelCount(0),
86 	fCurrentChannel(0),
87 	fChannelMin(NULL),
88 	fChannelMax(NULL),
89 	fChannelValues(NULL),
90 	fMultiLabels(NULL),
91 	fModificationMsg(NULL)
92 {
93 	archive->FindInt32("be:_m_channel_count", &fChannelCount);
94 	archive->FindInt32("be:_m_value_channel", &fCurrentChannel);
95 
96 	if (fChannelCount > 0) {
97 		fChannelMin = new int32[fChannelCount];
98 		memset(fChannelMin, 0, sizeof(int32) * fChannelCount);
99 
100 		fChannelMax = new int32[fChannelCount];
101 		for (int32 i = 0; i < fChannelCount; i++)
102 			fChannelMax[i] = 100;
103 
104 		fChannelValues = new int32[fChannelCount];
105 		memset(fChannelValues, 0, sizeof(int32) * fChannelCount);
106 
107 		for (int32 c = 0; c < fChannelCount; c++) {
108 			archive->FindInt32("be:_m_channel_min", c, &fChannelMin[c]);
109 			archive->FindInt32("be:_m_channel_max", c, &fChannelMax[c]);
110 			archive->FindInt32("be:_m_channel_val", c, &fChannelValues[c]);
111 		}
112 	}
113 
114 	const char *label = NULL;
115 	if (archive->FindString("be:_m_min_label", &label) == B_OK)
116 		fMinLabel = label;
117 	if (archive->FindString("be:_m_max_label", &label) == B_OK)
118 		fMaxLabel = label;
119 
120 	BMessage *modificationMessage = new BMessage;
121 	if (archive->FindMessage("_mod_msg", modificationMessage) == B_OK)
122 		fModificationMsg = modificationMessage;
123 	else
124 		delete modificationMessage;
125 
126 }
127 
128 
129 BChannelControl::~BChannelControl()
130 {
131 	delete[] fChannelMin;
132 	delete[] fChannelMax;
133 	delete[] fChannelValues;
134 	delete fModificationMsg;
135 }
136 
137 
138 status_t
139 BChannelControl::Archive(BMessage *message, bool deep) const
140 {
141 	status_t status = BControl::Archive(message, deep);
142 	if (status == B_OK)
143 		status = message->AddInt32("be:_m_channel_count", fChannelCount);
144 	if (status == B_OK)
145 		status = message->AddInt32("be:_m_value_channel", fCurrentChannel);
146 	if (status == B_OK)
147 		status = message->AddString("be:_m_min_label", fMinLabel.String());
148 	if (status == B_OK)
149 		status = message->AddString("be:_m_max_label", fMaxLabel.String());
150 
151 	if (status == B_OK && fChannelValues != NULL
152 		&& fChannelMax != NULL && fChannelMin != NULL) {
153 		for (int32 i = 0; i < fChannelCount; i++) {
154 			status = message->AddInt32("be:_m_channel_min", fChannelMin[i]);
155 			if (status < B_OK)
156 				break;
157 			status = message->AddInt32("be:_m_channel_max", fChannelMax[i]);
158 			if (status < B_OK)
159 				break;
160 			status = message->AddInt32("be:_m_channel_val", fChannelValues[i]);
161 			if (status < B_OK)
162 				break;
163 		}
164 	}
165 
166 	return status;
167 }
168 
169 
170 void
171 BChannelControl::FrameResized(float width, float height)
172 {
173 	BView::FrameResized(width, height);
174 }
175 
176 
177 void
178 BChannelControl::SetFont(const BFont *font, uint32 mask)
179 {
180 	BView::SetFont(font, mask);
181 }
182 
183 
184 void
185 BChannelControl::AttachedToWindow()
186 {
187 	BControl::AttachedToWindow();
188 }
189 
190 
191 void
192 BChannelControl::DetachedFromWindow()
193 {
194 	BControl::DetachedFromWindow();
195 }
196 
197 
198 void
199 BChannelControl::ResizeToPreferred()
200 {
201 	BControl::ResizeToPreferred();
202 }
203 
204 
205 void
206 BChannelControl::MessageReceived(BMessage *message)
207 {
208 	BControl::MessageReceived(message);
209 }
210 
211 
212 BHandler *
213 BChannelControl::ResolveSpecifier(BMessage *msg, int32 index, BMessage *specifier,
214 	int32 form, const char *property)
215 {
216 	BHandler *target = this;
217 	BPropertyInfo propertyInfo(sPropertyInfo);
218 	if (propertyInfo.FindMatch(msg, index, specifier, form, property) < B_OK)
219 		target = BControl::ResolveSpecifier(msg, index, specifier, form, property);
220 
221 	return target;
222 }
223 
224 
225 status_t
226 BChannelControl::GetSupportedSuites(BMessage *data)
227 {
228 	if (data == NULL)
229 		return B_BAD_VALUE;
230 
231 	status_t err = data->AddString("suites", "suite/vnd.Be-channel-control");
232 
233 	BPropertyInfo propertyInfo(sPropertyInfo);
234 	if (err == B_OK)
235 		err = data->AddFlat("messages", &propertyInfo);
236 
237 	if (err == B_OK)
238 		return BControl::GetSupportedSuites(data);
239 	return err;
240 }
241 
242 
243 void
244 BChannelControl::SetModificationMessage(BMessage *message)
245 {
246 	delete fModificationMsg;
247 	fModificationMsg = message;
248 }
249 
250 
251 BMessage *
252 BChannelControl::ModificationMessage() const
253 {
254 	return fModificationMsg;
255 }
256 
257 
258 status_t
259 BChannelControl::Invoke(BMessage *msg)
260 {
261 	bool notify = false;
262 	BMessage invokeMessage(InvokeKind(&notify));
263 
264 	if (msg != NULL)
265 		invokeMessage = *msg;
266 	else if (Message() != NULL)
267 		invokeMessage = *Message();
268 
269 	invokeMessage.AddInt32("be:current_channel", fCurrentChannel);
270 
271 	return BControl::Invoke(&invokeMessage);
272 }
273 
274 
275 status_t
276 BChannelControl::InvokeChannel(BMessage *msg, int32 fromChannel,
277 	int32 channelCount, const bool *inMask)
278 {
279 	bool notify = false;
280 	BMessage invokeMessage(InvokeKind(&notify));
281 
282 	if (msg != NULL)
283 		invokeMessage = *msg;
284 	else if (Message() != NULL)
285 		invokeMessage = *Message();
286 
287 	invokeMessage.AddInt32("be:current_channel", fCurrentChannel);
288 
289 	if (channelCount < 0)
290 		channelCount = fChannelCount - fromChannel;
291 
292 	for (int32 i = 0; i < channelCount; i++) {
293 		invokeMessage.AddInt32("be:channel_value", fChannelValues[fromChannel + i]);
294 		invokeMessage.AddBool("be:channel_changed", inMask ? inMask[i] : true);
295 	}
296 
297 	return BControl::Invoke(&invokeMessage);
298 }
299 
300 
301 status_t
302 BChannelControl::InvokeNotifyChannel(BMessage *msg, uint32 kind,
303 	int32 fromChannel, int32 channelCount, const bool *inMask)
304 {
305 	BeginInvokeNotify(kind);
306 	status_t status = InvokeChannel(msg, fromChannel, channelCount, inMask);
307 	EndInvokeNotify();
308 
309 	return status;
310 }
311 
312 
313 void
314 BChannelControl::SetValue(int32 value)
315 {
316 	// Get real
317 	if (value > fChannelMax[fCurrentChannel])
318 		value = fChannelMax[fCurrentChannel];
319 
320 	if (value < fChannelMin[fCurrentChannel])
321 		value = fChannelMin[fCurrentChannel];
322 
323 	if (value != fChannelValues[fCurrentChannel]) {
324 		StuffValues(fCurrentChannel, 1, &value);
325 		BControl::SetValue(value);
326 	}
327 }
328 
329 
330 status_t
331 BChannelControl::SetCurrentChannel(int32 channel)
332 {
333 	if (channel < 0 || channel >= fChannelCount)
334 		return B_BAD_INDEX;
335 
336 	if (channel != fCurrentChannel) {
337 		fCurrentChannel = channel;
338 		BControl::SetValue(fChannelValues[fCurrentChannel]);
339 	}
340 
341 	return B_OK;
342 }
343 
344 
345 int32
346 BChannelControl::CurrentChannel() const
347 {
348 	return fCurrentChannel;
349 }
350 
351 
352 int32
353 BChannelControl::CountChannels() const
354 {
355 	return fChannelCount;
356 }
357 
358 
359 status_t
360 BChannelControl::SetChannelCount(int32 channel_count)
361 {
362 	if (channel_count < 0 || channel_count >= MaxChannelCount())
363 		return B_BAD_VALUE;
364 
365 	// TODO: Currently we only grow the buffer. Test what BeOS does
366 	if (channel_count > fChannelCount) {
367 		int32 *newMin = new int32[channel_count];
368 		int32 *newMax = new int32[channel_count];
369 		int32 *newVal = new int32[channel_count];
370 
371 		memcpy(newMin, fChannelMin, fChannelCount);
372 		memcpy(newMax, fChannelMax, fChannelCount);
373 		memcpy(newVal, fChannelValues, fChannelCount);
374 
375 		delete[] fChannelMin;
376 		delete[] fChannelMax;
377 		delete[] fChannelValues;
378 
379 		fChannelMin = newMin;
380 		fChannelMax = newMax;
381 		fChannelValues = newVal;
382 	}
383 
384 	fChannelCount = channel_count;
385 
386 	return B_OK;
387 }
388 
389 
390 int32
391 BChannelControl::ValueFor(int32 channel) const
392 {
393 	int32 value = 0;
394 	if (GetValue(&value, channel, 1) <= 0)
395 		return -1;
396 
397 	return value;
398 }
399 
400 
401 int32
402 BChannelControl::GetValue(int32 *outValues, int32 fromChannel,
403 	int32 channelCount) const
404 {
405 	int32 i = 0;
406 	for (i = 0; i < channelCount; i++)
407 		outValues[i] = fChannelValues[fromChannel + i];
408 
409 	return i;
410 }
411 
412 
413 status_t
414 BChannelControl::SetValueFor(int32 channel, int32 value)
415 {
416 	return SetValue(channel, 1, &value);
417 }
418 
419 
420 status_t
421 BChannelControl::SetValue(int32 fromChannel, int32 channelCount,
422 	const int32 *inValues)
423 {
424 	return StuffValues(fromChannel, channelCount, inValues);
425 }
426 
427 
428 status_t
429 BChannelControl::SetAllValue(int32 values)
430 {
431 	int32 *newValues = new int32[fChannelCount];
432 	for (int32 i = 0; i < fChannelCount; i++) {
433 		int32 limitedValue = max_c(values, MinLimitList()[i]);
434 		limitedValue = min_c(limitedValue, MaxLimitList()[i]);
435 
436 		newValues[i] = limitedValue;
437 	}
438 
439 	delete[] fChannelValues;
440 	fChannelValues = newValues;
441 	BControl::SetValue(fChannelValues[fCurrentChannel]);
442 
443 	return B_OK;
444 }
445 
446 
447 status_t
448 BChannelControl::SetLimitsFor(int32 channel, int32 minimum, int32 maximum)
449 {
450 	return SetLimitsFor(channel, 1, &minimum, &maximum);
451 }
452 
453 
454 status_t
455 BChannelControl::GetLimitsFor(int32 channel, int32 *minimum, int32 *maximum) const
456 {
457 	return GetLimitsFor(channel, 1, minimum, maximum);
458 }
459 
460 
461 status_t
462 BChannelControl::SetLimitsFor(int32 fromChannel, int32 channelCount,
463 	const int32 *minimum, const int32 *maximum)
464 {
465 	if (fromChannel + channelCount > CountChannels())
466 		channelCount = CountChannels() - fromChannel;
467 	for (int i=0; i<channelCount; i++) {
468 		if (minimum[i] > maximum[i])
469 			return B_BAD_VALUE;
470 		fChannelMin[fromChannel + i] = minimum[i];
471 		fChannelMax[fromChannel + i] = maximum[i];
472 		if (fChannelValues[fromChannel + i] < minimum[i])
473 			fChannelValues[fromChannel + i] = minimum[i];
474 		else if (fChannelValues[fromChannel + i] > maximum[i])
475 			fChannelValues[fromChannel + i] = maximum[i];
476 	}
477 	return B_OK;
478 }
479 
480 
481 status_t
482 BChannelControl::GetLimitsFor(int32 fromChannel, int32 channelCount,
483 	int32 *minimum, int32 *maximum) const
484 {
485 	if (minimum == NULL || maximum == NULL)
486 		return B_BAD_VALUE;
487 
488 	if (fChannelMin == NULL || fChannelMax == NULL)
489 		return B_ERROR;
490 	if (fromChannel + channelCount > CountChannels())
491 		channelCount = CountChannels() - fromChannel;
492 	for (int i=0; i<channelCount; i++) {
493 		minimum[i] = fChannelMin[fromChannel + i];
494 		maximum[i] = fChannelMax[fromChannel + i];
495 	}
496 
497 	return B_OK;
498 }
499 
500 
501 status_t
502 BChannelControl::SetLimits(int32 minimum, int32 maximum)
503 {
504 	if (minimum > maximum)
505 		return B_BAD_VALUE;
506 
507 	int32 numChannels = CountChannels();
508 
509 	for (int32 c = 0; c < numChannels; c++) {
510 		fChannelMin[c] = minimum;
511 		fChannelMax[c] = maximum;
512 		if (fChannelValues[c] < minimum)
513 			fChannelValues[c] = minimum;
514 		else if (fChannelValues[c] > maximum)
515 			fChannelValues[c] = maximum;
516 	}
517 
518 	return B_OK;
519 }
520 
521 
522 status_t
523 BChannelControl::GetLimits(int32 *outMinimum, int32 *outMaximum) const
524 {
525 	if (outMinimum == NULL || outMaximum == NULL)
526 		return B_BAD_VALUE;
527 
528 	if (fChannelMin == NULL || fChannelMax == NULL)
529 		return B_ERROR;
530 
531 	int32 numChannels = CountChannels();
532 	for (int32 c = 0; c < numChannels; c++) {
533 		outMinimum[c] = fChannelMin[c];
534 		outMaximum[c] = fChannelMax[c];
535 	}
536 
537 	return B_OK;
538 }
539 
540 
541 status_t
542 BChannelControl::SetLimitLabels(const char *minLabel, const char *maxLabel)
543 {
544 	if (minLabel != fMinLabel)
545 		fMinLabel = minLabel;
546 
547 	if (maxLabel != fMaxLabel)
548 		fMaxLabel = maxLabel;
549 
550 	Invalidate();
551 
552 	return B_OK;
553 }
554 
555 
556 const char *
557 BChannelControl::MinLimitLabel() const
558 {
559 	return fMinLabel.String();
560 }
561 
562 
563 const char *
564 BChannelControl::MaxLimitLabel() const
565 {
566 	return fMaxLabel.String();
567 }
568 
569 
570 status_t
571 BChannelControl::SetLimitLabelsFor(int32 channel, const char *minLabel, const char *maxLabel)
572 {
573 	return B_ERROR;
574 }
575 
576 
577 status_t
578 BChannelControl::SetLimitLabelsFor(int32 from_channel, int32 channel_count, const char *minLabel, const char *maxLabel)
579 {
580 	return B_ERROR;
581 }
582 
583 
584 const char *
585 BChannelControl::MinLimitLabelFor(int32 channel) const
586 {
587 	return NULL;
588 }
589 
590 
591 const char *
592 BChannelControl::MaxLimitLabelFor(int32 channel) const
593 {
594 	return NULL;
595 }
596 
597 
598 status_t
599 BChannelControl::StuffValues(int32 fromChannel, int32 channelCount,
600 	const int32 *inValues)
601 {
602 	if (inValues == NULL)
603 		return B_BAD_VALUE;
604 
605 	if (fromChannel < 0 || fromChannel > fChannelCount
606 						|| fromChannel + channelCount > fChannelCount)
607 		return B_BAD_INDEX;
608 
609 	for (int32 i = 0; i < channelCount; i++) {
610 		if (inValues[i] <= fChannelMax[fromChannel + i]
611 						&& inValues[i] >= fChannelMin[fromChannel + i])
612 			fChannelValues[fromChannel + i] = inValues[i];
613 	}
614 
615 	// If the current channel was updated, update also the control value
616 	if (fCurrentChannel >= fromChannel && fCurrentChannel <= fromChannel + channelCount)
617 		BControl::SetValue(fChannelValues[fCurrentChannel]);
618 
619 	return B_OK;
620 }
621 
622 
623 void BChannelControl::_Reserverd_ChannelControl_0(void *, ...) {}
624 void BChannelControl::_Reserverd_ChannelControl_1(void *, ...) {}
625 void BChannelControl::_Reserverd_ChannelControl_2(void *, ...) {}
626 void BChannelControl::_Reserverd_ChannelControl_3(void *, ...) {}
627 void BChannelControl::_Reserverd_ChannelControl_4(void *, ...) {}
628 void BChannelControl::_Reserverd_ChannelControl_5(void *, ...) {}
629 void BChannelControl::_Reserverd_ChannelControl_6(void *, ...) {}
630 void BChannelControl::_Reserverd_ChannelControl_7(void *, ...) {}
631 void BChannelControl::_Reserverd_ChannelControl_8(void *, ...) {}
632 void BChannelControl::_Reserverd_ChannelControl_9(void *, ...) {}
633 void BChannelControl::_Reserverd_ChannelControl_10(void *, ...) {}
634 void BChannelControl::_Reserverd_ChannelControl_11(void *, ...) {}
635