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 < 0) 267 channelCount = fChannelCount - fromChannel; 268 269 for (int32 i = 0; i < channelCount; i++) { 270 invokeMessage.AddInt32("be:channel_value", fChannelValues[fromChannel + i]); 271 invokeMessage.AddBool("be:channel_changed", inMask ? inMask[i] : true); 272 } 273 274 return BControl::Invoke(&invokeMessage); 275 } 276 277 278 status_t 279 BChannelControl::InvokeNotifyChannel(BMessage *msg, uint32 kind, 280 int32 fromChannel, int32 channelCount, const bool *inMask) 281 { 282 BeginInvokeNotify(kind); 283 status_t status = InvokeChannel(msg, fromChannel, channelCount, inMask); 284 EndInvokeNotify(); 285 286 return status; 287 } 288 289 290 void 291 BChannelControl::SetValue(int32 value) 292 { 293 // Get real 294 if (value > fChannelMax[fCurrentChannel]) 295 value = fChannelMax[fCurrentChannel]; 296 297 if (value < fChannelMin[fCurrentChannel]); 298 value = fChannelMin[fCurrentChannel]; 299 300 if (value != fChannelValues[fCurrentChannel]) { 301 StuffValues(fCurrentChannel, 1, &value); 302 BControl::SetValue(value); 303 } 304 } 305 306 307 status_t 308 BChannelControl::SetCurrentChannel(int32 channel) 309 { 310 if (channel < 0 || channel >= fChannelCount) 311 return B_BAD_INDEX; 312 313 if (channel != fCurrentChannel) { 314 fCurrentChannel = channel; 315 BControl::SetValue(fChannelValues[fCurrentChannel]); 316 } 317 318 return B_OK; 319 } 320 321 322 int32 323 BChannelControl::CurrentChannel() const 324 { 325 return fCurrentChannel; 326 } 327 328 329 int32 330 BChannelControl::CountChannels() const 331 { 332 return fChannelCount; 333 } 334 335 336 status_t 337 BChannelControl::SetChannelCount(int32 channel_count) 338 { 339 if (channel_count < 0 || channel_count >= MaxChannelCount()) 340 return B_BAD_VALUE; 341 342 // TODO: Currently we only grow the buffer. Test what BeOS does 343 if (channel_count > fChannelCount) { 344 int32 *newMin = new int32[channel_count]; 345 int32 *newMax = new int32[channel_count]; 346 int32 *newVal = new int32[channel_count]; 347 348 memcpy(newMin, fChannelMin, fChannelCount); 349 memcpy(newMax, fChannelMax, fChannelCount); 350 memcpy(newVal, fChannelValues, fChannelCount); 351 352 delete[] fChannelMin; 353 delete[] fChannelMax; 354 delete[] fChannelValues; 355 356 fChannelMin = newMin; 357 fChannelMax = newMax; 358 fChannelValues = newVal; 359 } 360 361 fChannelCount = channel_count; 362 363 return B_OK; 364 } 365 366 367 int32 368 BChannelControl::ValueFor(int32 channel) const 369 { 370 int32 value = 0; 371 if (GetValue(&value, channel, 1) <= 0) 372 return -1; 373 374 return value; 375 } 376 377 378 int32 379 BChannelControl::GetValue(int32 *outValues, int32 fromChannel, 380 int32 channelCount) const 381 { 382 int32 i = 0; 383 for (i = 0; i < channelCount; i++) 384 outValues[i] = fChannelValues[fromChannel + i]; 385 386 return i; 387 } 388 389 390 status_t 391 BChannelControl::SetValueFor(int32 channel, int32 value) 392 { 393 return SetValue(channel, 1, &value); 394 } 395 396 397 status_t 398 BChannelControl::SetValue(int32 fromChannel, int32 channelCount, 399 const int32 *inValues) 400 { 401 return StuffValues(fromChannel, channelCount, inValues); 402 } 403 404 405 status_t 406 BChannelControl::SetAllValue(int32 values) 407 { 408 int32 *newValues = new int32[fChannelCount]; 409 for (int32 i = 0; i < fChannelCount; i++) { 410 int32 limitedValue = max_c(values, MinLimitList()[i]); 411 limitedValue = min_c(limitedValue, MaxLimitList()[i]); 412 413 newValues[i] = limitedValue; 414 } 415 416 delete[] fChannelValues; 417 fChannelValues = newValues; 418 BControl::SetValue(fChannelValues[fCurrentChannel]); 419 420 return B_OK; 421 } 422 423 424 status_t 425 BChannelControl::SetLimitsFor(int32 channel, int32 minimum, int32 maximum) 426 { 427 return SetLimitsFor(channel, 1, &minimum, &maximum); 428 } 429 430 431 status_t 432 BChannelControl::GetLimitsFor(int32 channel, int32 *minimum, int32 *maximum) const 433 { 434 return GetLimitsFor(channel, 1, minimum, maximum); 435 } 436 437 438 status_t 439 BChannelControl::SetLimitsFor(int32 fromChannel, int32 channelCount, 440 const int32 *minimum, const int32 *maximum) 441 { 442 if (fromChannel + channelCount > CountChannels()) 443 channelCount = CountChannels() - fromChannel; 444 for (int i=0; i<channelCount; i++) { 445 if (minimum[i] > maximum[i]) 446 return B_BAD_VALUE; 447 fChannelMin[fromChannel + i] = minimum[i]; 448 fChannelMax[fromChannel + i] = maximum[i]; 449 if (fChannelValues[fromChannel + i] < minimum[i]) 450 fChannelValues[fromChannel + i] = minimum[i]; 451 else if (fChannelValues[fromChannel + i] > maximum[i]) 452 fChannelValues[fromChannel + i] = maximum[i]; 453 } 454 return B_OK; 455 } 456 457 458 status_t 459 BChannelControl::GetLimitsFor(int32 fromChannel, int32 channelCount, 460 int32 *minimum, int32 *maximum) const 461 { 462 if (minimum == NULL || maximum == NULL) 463 return B_BAD_VALUE; 464 465 if (fChannelMin == NULL || fChannelMax == NULL) 466 return B_ERROR; 467 if (fromChannel + channelCount > CountChannels()) 468 channelCount = CountChannels() - fromChannel; 469 for (int i=0; i<channelCount; i++) { 470 minimum[i] = fChannelMin[fromChannel + i]; 471 maximum[i] = fChannelMax[fromChannel + i]; 472 } 473 474 return B_OK; 475 } 476 477 478 status_t 479 BChannelControl::SetLimits(int32 minimum, int32 maximum) 480 { 481 if (minimum > maximum) 482 return B_BAD_VALUE; 483 484 int32 numChannels = CountChannels(); 485 486 for (int32 c = 0; c < numChannels; c++) { 487 fChannelMin[c] = minimum; 488 fChannelMax[c] = maximum; 489 if (fChannelValues[c] < minimum) 490 fChannelValues[c] = minimum; 491 else if (fChannelValues[c] > maximum) 492 fChannelValues[c] = maximum; 493 } 494 495 return B_OK; 496 } 497 498 499 status_t 500 BChannelControl::GetLimits(int32 *outMinimum, int32 *outMaximum) const 501 { 502 if (outMinimum == NULL || outMaximum == NULL) 503 return B_BAD_VALUE; 504 505 if (fChannelMin == NULL || fChannelMax == NULL) 506 return B_ERROR; 507 508 int32 numChannels = CountChannels(); 509 for (int32 c = 0; c < numChannels; c++) { 510 outMinimum[c] = fChannelMin[c]; 511 outMaximum[c] = fChannelMax[c]; 512 } 513 514 return B_OK; 515 } 516 517 518 status_t 519 BChannelControl::SetLimitLabels(const char *minLabel, const char *maxLabel) 520 { 521 if (minLabel != fMinLabel) 522 fMinLabel = minLabel; 523 524 if (maxLabel != fMaxLabel) 525 fMaxLabel = maxLabel; 526 527 Invalidate(); 528 529 return B_OK; 530 } 531 532 533 const char * 534 BChannelControl::MinLimitLabel() const 535 { 536 return fMinLabel.String(); 537 } 538 539 540 const char * 541 BChannelControl::MaxLimitLabel() const 542 { 543 return fMaxLabel.String(); 544 } 545 546 547 status_t 548 BChannelControl::SetLimitLabelsFor(int32 channel, const char *minLabel, const char *maxLabel) 549 { 550 return B_ERROR; 551 } 552 553 554 status_t 555 BChannelControl::SetLimitLabelsFor(int32 from_channel, int32 channel_count, const char *minLabel, const char *maxLabel) 556 { 557 return B_ERROR; 558 } 559 560 561 const char * 562 BChannelControl::MinLimitLabelFor(int32 channel) const 563 { 564 return NULL; 565 } 566 567 568 const char * 569 BChannelControl::MaxLimitLabelFor(int32 channel) const 570 { 571 return NULL; 572 } 573 574 575 status_t 576 BChannelControl::StuffValues(int32 fromChannel, int32 channelCount, 577 const int32 *inValues) 578 { 579 if (inValues == NULL) 580 return B_BAD_VALUE; 581 582 if (fromChannel < 0 || fromChannel > fChannelCount 583 || fromChannel + channelCount > fChannelCount) 584 return B_BAD_INDEX; 585 586 for (int32 i = 0; i < channelCount; i++) { 587 if (inValues[i] <= fChannelMax[fromChannel + i] 588 && inValues[i] >= fChannelMin[fromChannel + i]) 589 fChannelValues[fromChannel + i] = inValues[i]; 590 } 591 592 // If the current channel was updated, update also the control value 593 if (fCurrentChannel >= fromChannel && fCurrentChannel <= fromChannel + channelCount) 594 BControl::SetValue(fChannelValues[fCurrentChannel]); 595 596 return B_OK; 597 } 598 599 600 void BChannelControl::_Reserverd_ChannelControl_0(void *, ...) {} 601 void BChannelControl::_Reserverd_ChannelControl_1(void *, ...) {} 602 void BChannelControl::_Reserverd_ChannelControl_2(void *, ...) {} 603 void BChannelControl::_Reserverd_ChannelControl_3(void *, ...) {} 604 void BChannelControl::_Reserverd_ChannelControl_4(void *, ...) {} 605 void BChannelControl::_Reserverd_ChannelControl_5(void *, ...) {} 606 void BChannelControl::_Reserverd_ChannelControl_6(void *, ...) {} 607 void BChannelControl::_Reserverd_ChannelControl_7(void *, ...) {} 608 void BChannelControl::_Reserverd_ChannelControl_8(void *, ...) {} 609 void BChannelControl::_Reserverd_ChannelControl_9(void *, ...) {} 610 void BChannelControl::_Reserverd_ChannelControl_10(void *, ...) {} 611 void BChannelControl::_Reserverd_ChannelControl_11(void *, ...) {} 612