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