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