2 * Copyright 2005-2014 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
7 #include <ChannelControl.h>
8 #include <PropertyInfo.h>
14 std::string min_label
;
15 std::string max_label
;
18 typedef std::map
<int32
, limit_label
> label_map
;
23 { B_GET_PROPERTY
, B_SET_PROPERTY
, 0 },
24 { B_DIRECT_SPECIFIER
, 0 }, NULL
, 0, { B_INT32_TYPE
}
28 { B_GET_PROPERTY
, B_SET_PROPERTY
, 0 },
29 { B_DIRECT_SPECIFIER
, 0 }, NULL
, 0, { B_INT32_TYPE
}
33 { B_GET_PROPERTY
, B_SET_PROPERTY
, 0 },
34 { B_DIRECT_SPECIFIER
, 0 }, NULL
, 0, { B_STRING_TYPE
}
38 { B_GET_PROPERTY
, B_SET_PROPERTY
, 0 },
39 { B_DIRECT_SPECIFIER
, 0 }, NULL
, 0, { B_STRING_TYPE
}
46 BChannelControl::BChannelControl(BRect frame
, const char* name
,
47 const char* label
, BMessage
* model
, int32 channel_count
,
48 uint32 resizingMode
, uint32 flags
)
50 BControl(frame
, name
, label
, model
, resizingMode
, flags
),
51 fChannelCount(channel_count
),
57 fModificationMsg(NULL
)
59 fChannelMin
= new int32
[channel_count
];
60 memset(fChannelMin
, 0, sizeof(int32
) * channel_count
);
62 fChannelMax
= new int32
[channel_count
];
63 for (int32 i
= 0; i
< channel_count
; i
++)
66 fChannelValues
= new int32
[channel_count
];
67 memset(fChannelValues
, 0, sizeof(int32
) * channel_count
);
69 fMultiLabels
= (void*)new label_map
;
73 BChannelControl::BChannelControl(const char* name
, const char* label
,
74 BMessage
* model
, int32 channelCount
, uint32 flags
)
76 BControl(name
, label
, model
, flags
),
77 fChannelCount(channelCount
),
83 fModificationMsg(NULL
)
85 fChannelMin
= new int32
[channelCount
];
86 memset(fChannelMin
, 0, sizeof(int32
) * channelCount
);
88 fChannelMax
= new int32
[channelCount
];
89 for (int32 i
= 0; i
< channelCount
; i
++)
92 fChannelValues
= new int32
[channelCount
];
93 memset(fChannelValues
, 0, sizeof(int32
) * channelCount
);
95 fMultiLabels
= (void*)new label_map
;
99 BChannelControl::BChannelControl(BMessage
* archive
)
106 fChannelValues(NULL
),
108 fModificationMsg(NULL
)
110 archive
->FindInt32("be:_m_channel_count", &fChannelCount
);
111 archive
->FindInt32("be:_m_value_channel", &fCurrentChannel
);
113 if (fChannelCount
> 0) {
114 fChannelMin
= new int32
[fChannelCount
];
115 memset(fChannelMin
, 0, sizeof(int32
) * fChannelCount
);
117 fChannelMax
= new int32
[fChannelCount
];
118 for (int32 i
= 0; i
< fChannelCount
; i
++)
119 fChannelMax
[i
] = 100;
121 fChannelValues
= new int32
[fChannelCount
];
122 memset(fChannelValues
, 0, sizeof(int32
) * fChannelCount
);
124 for (int32 c
= 0; c
< fChannelCount
; c
++) {
125 archive
->FindInt32("be:_m_channel_min", c
, &fChannelMin
[c
]);
126 archive
->FindInt32("be:_m_channel_max", c
, &fChannelMax
[c
]);
127 archive
->FindInt32("be:_m_channel_val", c
, &fChannelValues
[c
]);
131 const char* label
= NULL
;
132 if (archive
->FindString("be:_m_min_label", &label
) == B_OK
)
135 if (archive
->FindString("be:_m_max_label", &label
) == B_OK
)
138 BMessage
* modificationMessage
= new BMessage
;
139 if (archive
->FindMessage("_mod_msg", modificationMessage
) == B_OK
)
140 fModificationMsg
= modificationMessage
;
142 delete modificationMessage
;
144 fMultiLabels
= (void*)new label_map
;
148 BChannelControl::~BChannelControl()
150 delete[] fChannelMin
;
151 delete[] fChannelMax
;
152 delete[] fChannelValues
;
153 delete fModificationMsg
;
154 delete reinterpret_cast<label_map
*>(fMultiLabels
);
159 BChannelControl::Archive(BMessage
* data
, bool deep
) const
161 status_t status
= BControl::Archive(data
, deep
);
163 status
= data
->AddInt32("be:_m_channel_count", fChannelCount
);
166 status
= data
->AddInt32("be:_m_value_channel", fCurrentChannel
);
169 status
= data
->AddString("be:_m_min_label", fMinLabel
.String());
172 status
= data
->AddString("be:_m_max_label", fMaxLabel
.String());
174 if (status
== B_OK
&& fChannelValues
!= NULL
175 && fChannelMax
!= NULL
&& fChannelMin
!= NULL
) {
176 for (int32 i
= 0; i
< fChannelCount
; i
++) {
177 status
= data
->AddInt32("be:_m_channel_min", fChannelMin
[i
]);
181 status
= data
->AddInt32("be:_m_channel_max", fChannelMax
[i
]);
185 status
= data
->AddInt32("be:_m_channel_val", fChannelValues
[i
]);
196 BChannelControl::FrameResized(float newWidth
, float newHeight
)
198 BView::FrameResized(newWidth
, newHeight
);
203 BChannelControl::SetFont(const BFont
* font
, uint32 mask
)
205 BView::SetFont(font
, mask
);
210 BChannelControl::AttachedToWindow()
212 BControl::AttachedToWindow();
217 BChannelControl::DetachedFromWindow()
219 BControl::DetachedFromWindow();
224 BChannelControl::ResizeToPreferred()
226 BControl::ResizeToPreferred();
231 BChannelControl::MessageReceived(BMessage
* message
)
233 BControl::MessageReceived(message
);
238 BChannelControl::ResolveSpecifier(BMessage
* message
, int32 index
,
239 BMessage
* specifier
, int32 what
, const char* property
)
241 BHandler
* target
= this;
242 BPropertyInfo
propertyInfo(sPropertyInfo
);
243 if (propertyInfo
.FindMatch(message
, index
, specifier
, what
, property
)
245 target
= BControl::ResolveSpecifier(message
, index
, specifier
,
254 BChannelControl::GetSupportedSuites(BMessage
* data
)
259 status_t err
= data
->AddString("suites", "suite/vnd.Be-channel-control");
261 BPropertyInfo
propertyInfo(sPropertyInfo
);
263 err
= data
->AddFlat("messages", &propertyInfo
);
266 return BControl::GetSupportedSuites(data
);
273 BChannelControl::SetModificationMessage(BMessage
* message
)
275 delete fModificationMsg
;
276 fModificationMsg
= message
;
281 BChannelControl::ModificationMessage() const
283 return fModificationMsg
;
288 BChannelControl::Invoke(BMessage
* message
)
291 BMessage
invokeMessage(InvokeKind(¬ify
));
294 invokeMessage
= *message
;
295 else if (Message() != NULL
)
296 invokeMessage
= *Message();
298 invokeMessage
.AddInt32("be:current_channel", fCurrentChannel
);
300 return BControl::Invoke(&invokeMessage
);
305 BChannelControl::InvokeChannel(BMessage
* message
, int32 fromChannel
,
306 int32 channelCount
, const bool* _mask
)
309 BMessage
invokeMessage(InvokeKind(¬ify
));
312 invokeMessage
= *message
;
313 else if (Message() != NULL
)
314 invokeMessage
= *Message();
316 invokeMessage
.AddInt32("be:current_channel", fCurrentChannel
);
317 if (channelCount
< 0)
318 channelCount
= fChannelCount
- fromChannel
;
320 for (int32 i
= 0; i
< channelCount
; i
++) {
321 invokeMessage
.AddInt32("be:channel_value",
322 fChannelValues
[fromChannel
+ i
]);
323 invokeMessage
.AddBool("be:channel_changed", _mask
? _mask
[i
] : true);
326 return BControl::Invoke(&invokeMessage
);
331 BChannelControl::InvokeNotifyChannel(BMessage
* message
, uint32 kind
,
332 int32 fromChannel
, int32 channelCount
, const bool* _mask
)
334 BeginInvokeNotify(kind
);
335 status_t status
= InvokeChannel(message
, fromChannel
, channelCount
, _mask
);
343 BChannelControl::SetValue(int32 value
)
346 if (value
> fChannelMax
[fCurrentChannel
])
347 value
= fChannelMax
[fCurrentChannel
];
349 if (value
< fChannelMin
[fCurrentChannel
])
350 value
= fChannelMin
[fCurrentChannel
];
352 if (value
!= fChannelValues
[fCurrentChannel
]) {
353 StuffValues(fCurrentChannel
, 1, &value
);
354 BControl::SetValue(value
);
360 BChannelControl::SetCurrentChannel(int32 channel
)
362 if (channel
< 0 || channel
>= fChannelCount
)
365 if (channel
!= fCurrentChannel
) {
366 fCurrentChannel
= channel
;
367 BControl::SetValue(fChannelValues
[fCurrentChannel
]);
375 BChannelControl::CurrentChannel() const
377 return fCurrentChannel
;
382 BChannelControl::CountChannels() const
384 return fChannelCount
;
389 BChannelControl::SetChannelCount(int32 channel_count
)
391 if (channel_count
< 0 || channel_count
>= MaxChannelCount())
394 // TODO: Currently we only grow the buffer. Test what BeOS does
395 if (channel_count
> fChannelCount
) {
396 int32
* newMin
= new int32
[channel_count
];
397 int32
* newMax
= new int32
[channel_count
];
398 int32
* newVal
= new int32
[channel_count
];
400 memcpy(newMin
, fChannelMin
, fChannelCount
);
401 memcpy(newMax
, fChannelMax
, fChannelCount
);
402 memcpy(newVal
, fChannelValues
, fChannelCount
);
404 delete[] fChannelMin
;
405 delete[] fChannelMax
;
406 delete[] fChannelValues
;
408 fChannelMin
= newMin
;
409 fChannelMax
= newMax
;
410 fChannelValues
= newVal
;
413 fChannelCount
= channel_count
;
420 BChannelControl::ValueFor(int32 channel
) const
423 if (GetValue(&value
, channel
, 1) <= 0)
431 BChannelControl::GetValue(int32
* outValues
, int32 fromChannel
,
432 int32 channelCount
) const
435 for (i
= 0; i
< channelCount
; i
++)
436 outValues
[i
] = fChannelValues
[fromChannel
+ i
];
443 BChannelControl::SetValueFor(int32 channel
, int32 value
)
445 return SetValue(channel
, 1, &value
);
450 BChannelControl::SetValue(int32 fromChannel
, int32 channelCount
,
453 return StuffValues(fromChannel
, channelCount
, values
);
458 BChannelControl::SetAllValue(int32 values
)
460 int32
* newValues
= new int32
[fChannelCount
];
461 for (int32 i
= 0; i
< fChannelCount
; i
++) {
462 int32 limitedValue
= max_c(values
, MinLimitList()[i
]);
463 limitedValue
= min_c(limitedValue
, MaxLimitList()[i
]);
465 newValues
[i
] = limitedValue
;
468 delete[] fChannelValues
;
469 fChannelValues
= newValues
;
470 BControl::SetValue(fChannelValues
[fCurrentChannel
]);
477 BChannelControl::SetLimitsFor(int32 channel
, int32 minimum
, int32 maximum
)
479 return SetLimitsFor(channel
, 1, &minimum
, &maximum
);
484 BChannelControl::GetLimitsFor(int32 channel
, int32
* minimum
,
485 int32
* maximum
) const
487 return GetLimitsFor(channel
, 1, minimum
, maximum
);
492 BChannelControl::SetLimitsFor(int32 fromChannel
, int32 channelCount
,
493 const int32
* minimum
, const int32
* maximum
)
495 if (fromChannel
+ channelCount
> CountChannels())
496 channelCount
= CountChannels() - fromChannel
;
498 for (int i
= 0; i
< channelCount
; i
++) {
499 if (minimum
[i
] > maximum
[i
])
502 fChannelMin
[fromChannel
+ i
] = minimum
[i
];
503 fChannelMax
[fromChannel
+ i
] = maximum
[i
];
504 if (fChannelValues
[fromChannel
+ i
] < minimum
[i
])
505 fChannelValues
[fromChannel
+ i
] = minimum
[i
];
506 else if (fChannelValues
[fromChannel
+ i
] > maximum
[i
])
507 fChannelValues
[fromChannel
+ i
] = maximum
[i
];
515 BChannelControl::GetLimitsFor(int32 fromChannel
, int32 channelCount
,
516 int32
* minimum
, int32
* maximum
) const
518 if (minimum
== NULL
|| maximum
== NULL
)
521 if (fChannelMin
== NULL
|| fChannelMax
== NULL
)
523 if (fromChannel
+ channelCount
> CountChannels())
524 channelCount
= CountChannels() - fromChannel
;
526 for (int i
= 0; i
< channelCount
; i
++) {
527 minimum
[i
] = fChannelMin
[fromChannel
+ i
];
528 maximum
[i
] = fChannelMax
[fromChannel
+ i
];
536 BChannelControl::SetLimits(int32 minimum
, int32 maximum
)
538 if (minimum
> maximum
)
541 int32 numChannels
= CountChannels();
543 for (int32 c
= 0; c
< numChannels
; c
++) {
544 fChannelMin
[c
] = minimum
;
545 fChannelMax
[c
] = maximum
;
546 if (fChannelValues
[c
] < minimum
)
547 fChannelValues
[c
] = minimum
;
548 else if (fChannelValues
[c
] > maximum
)
549 fChannelValues
[c
] = maximum
;
557 BChannelControl::GetLimits(int32
* outMinimum
, int32
* outMaximum
) const
559 if (outMinimum
== NULL
|| outMaximum
== NULL
)
562 if (fChannelMin
== NULL
|| fChannelMax
== NULL
)
565 int32 numChannels
= CountChannels();
566 for (int32 c
= 0; c
< numChannels
; c
++) {
567 outMinimum
[c
] = fChannelMin
[c
];
568 outMaximum
[c
] = fChannelMax
[c
];
576 BChannelControl::SetLimitLabels(const char* minLabel
, const char* maxLabel
)
578 if (minLabel
!= fMinLabel
)
579 fMinLabel
= minLabel
;
581 if (maxLabel
!= fMaxLabel
)
582 fMaxLabel
= maxLabel
;
591 BChannelControl::MinLimitLabel() const
593 return fMinLabel
.String();
598 BChannelControl::MaxLimitLabel() const
600 return fMaxLabel
.String();
605 BChannelControl::SetLimitLabelsFor(int32 channel
, const char* minLabel
,
606 const char* maxLabel
)
608 (*(label_map
*)fMultiLabels
)[channel
].max_label
= maxLabel
;
609 (*(label_map
*)fMultiLabels
)[channel
].min_label
= minLabel
;
615 BChannelControl::SetLimitLabelsFor(int32 fromChannel
, int32 channelCount
,
616 const char* minLabel
, const char* maxLabel
)
618 for (int32 i
= fromChannel
; i
< fromChannel
+ channelCount
; i
++) {
619 SetLimitLabelsFor(i
, minLabel
, maxLabel
);
626 BChannelControl::MinLimitLabelFor(int32 channel
) const
628 if (fMultiLabels
!= NULL
) {
629 label_map::const_iterator iter
= ((label_map
*)fMultiLabels
)->find(channel
);
630 if (iter
!= ((label_map
*)fMultiLabels
)->end())
631 return (*iter
).second
.min_label
.c_str();
638 BChannelControl::MaxLimitLabelFor(int32 channel
) const
640 if (fMultiLabels
!= NULL
) {
641 label_map::const_iterator iter
= ((label_map
*)fMultiLabels
)->find(channel
);
642 if (iter
!= ((label_map
*)fMultiLabels
)->end())
643 return (*iter
).second
.max_label
.c_str();
650 BChannelControl::StuffValues(int32 fromChannel
, int32 channelCount
,
656 if (fromChannel
< 0 || fromChannel
> fChannelCount
657 || fromChannel
+ channelCount
> fChannelCount
) {
661 for (int32 i
= 0; i
< channelCount
; i
++) {
662 if (values
[i
] <= fChannelMax
[fromChannel
+ i
]
663 && values
[i
] >= fChannelMin
[fromChannel
+ i
]) {
664 fChannelValues
[fromChannel
+ i
] = values
[i
];
668 // if the current channel was updated, update also the control value
669 if (fCurrentChannel
>= fromChannel
670 && fCurrentChannel
<= fromChannel
+ channelCount
) {
671 BControl::SetValue(fChannelValues
[fCurrentChannel
]);
678 void BChannelControl::_Reserverd_ChannelControl_0(void*, ...) {}
679 void BChannelControl::_Reserverd_ChannelControl_1(void*, ...) {}
680 void BChannelControl::_Reserverd_ChannelControl_2(void*, ...) {}
681 void BChannelControl::_Reserverd_ChannelControl_3(void*, ...) {}
682 void BChannelControl::_Reserverd_ChannelControl_4(void*, ...) {}
683 void BChannelControl::_Reserverd_ChannelControl_5(void*, ...) {}
684 void BChannelControl::_Reserverd_ChannelControl_6(void*, ...) {}
685 void BChannelControl::_Reserverd_ChannelControl_7(void*, ...) {}
686 void BChannelControl::_Reserverd_ChannelControl_8(void*, ...) {}
687 void BChannelControl::_Reserverd_ChannelControl_9(void*, ...) {}
688 void BChannelControl::_Reserverd_ChannelControl_10(void*, ...) {}
689 void BChannelControl::_Reserverd_ChannelControl_11(void*, ...) {}