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