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