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