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(¬ify)); 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(¬ify)); 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