1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2001-2002, OpenBeOS 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 // 22 // File Name: BColorControl.h 23 // Author: Marc Flerackers (mflerackers@androme.be) 24 // Description: BColorControl displays a palette of selectable colors. 25 //------------------------------------------------------------------------------ 26 27 // Standard Includes ----------------------------------------------------------- 28 #include <stdio.h> 29 30 // System Includes ------------------------------------------------------------- 31 #include "ColorControl.h" 32 #include "TextControl.h" 33 #include <Support/Errors.h> 34 35 // Project Includes ------------------------------------------------------------ 36 37 // Local Includes -------------------------------------------------------------- 38 39 // Local Defines --------------------------------------------------------------- 40 41 // Globals --------------------------------------------------------------------- 42 43 const uint32 U_COLOR_CONTROL_RED_CHANGED_MSG = 'CCRC'; 44 const uint32 U_COLOR_CONTROL_GREEN_CHANGED_MSG = 'CCGC'; 45 const uint32 U_COLOR_CONTROL_BLUE_CHANGED_MSG = 'CCBC'; 46 47 //------------------------------------------------------------------------------ 48 BColorControl::BColorControl(BPoint leftTop, color_control_layout matrix, 49 float cellSize, const char *name, 50 BMessage *message, bool bufferedDrawing) 51 : BControl(BRect(leftTop, leftTop), name, NULL, message, 52 B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE) 53 { 54 switch (matrix) 55 { 56 case B_CELLS_4x64: 57 fColumns = 4; 58 fRows = 64; 59 break; 60 case B_CELLS_8x32: 61 fColumns = 8; 62 fRows = 32; 63 break; 64 case B_CELLS_16x16: 65 fColumns = 16; 66 fRows = 16; 67 break; 68 case B_CELLS_32x8: 69 fColumns = 32; 70 fRows = 8; 71 break; 72 case B_CELLS_64x4: 73 fColumns = 64; 74 fRows = 4; 75 break; 76 } 77 78 fCellSize = cellSize; 79 80 BRect rect(0.0f, 0.0f, 196, 52); 81 82 ResizeTo(rect.Width() + 70, rect.Height()); 83 84 fRedText = new BTextControl(BRect(rect.right + 1, 0.0f, 85 rect.right + 70, 15.0f), "_red", "Red:", NULL, 86 new BMessage(U_COLOR_CONTROL_RED_CHANGED_MSG)); 87 AddChild(fRedText); 88 89 fGreenText = new BTextControl(BRect(rect.right + 1, 16.0f, 90 rect.right + 70, 30.0f), "_green", "Green:", NULL, 91 new BMessage(U_COLOR_CONTROL_GREEN_CHANGED_MSG)); 92 AddChild(fGreenText); 93 94 fBlueText = new BTextControl(BRect(rect.right + 1, 31.0f, 95 rect.right + 70, 45), "_blue", "Blue:", NULL, 96 new BMessage(U_COLOR_CONTROL_BLUE_CHANGED_MSG)); 97 AddChild(fBlueText); 98 99 fFocusedComponent = 0; 100 } 101 //------------------------------------------------------------------------------ 102 BColorControl::BColorControl(BMessage *archive) 103 : BControl(archive) 104 { 105 int32 layout; 106 bool use_offscreen; 107 108 archive->FindInt32("_layout", &layout); 109 SetLayout((color_control_layout)layout); 110 111 archive->FindFloat("_csize", &fCellSize); 112 113 archive->FindBool("_use_off", &use_offscreen); 114 } 115 //------------------------------------------------------------------------------ 116 BColorControl::~BColorControl() 117 { 118 } 119 //------------------------------------------------------------------------------ 120 BArchivable *BColorControl::Instantiate(BMessage *archive) 121 { 122 if ( validate_instantiation(archive, "BColorControl")) 123 return new BColorControl(archive); 124 else 125 return NULL; 126 } 127 //------------------------------------------------------------------------------ 128 status_t BColorControl::Archive(BMessage *archive, bool deep) const 129 { 130 BControl::Archive(archive, deep); 131 132 archive->AddInt32("_layout", Layout()); 133 archive->AddFloat("_csize", fCellSize); 134 archive->AddBool("_use_off", fOffscreenView != NULL); 135 136 return B_OK; 137 } 138 //------------------------------------------------------------------------------ 139 void BColorControl::SetValue(int32 color) 140 { 141 BControl::SetValue(color); 142 143 rgb_color c = ValueAsColor(); 144 char string[4]; 145 146 sprintf(string, "%d", c.red); 147 fRedText->SetText( string); 148 sprintf(string, "%d", c.green); 149 fGreenText->SetText( string); 150 sprintf(string, "%d", c.blue); 151 fBlueText->SetText(string); 152 153 Invoke(); 154 } 155 //------------------------------------------------------------------------------ 156 rgb_color BColorControl::ValueAsColor() 157 { 158 int32 value = Value(); 159 rgb_color color; 160 161 color.red = (value & 0xFF000000) >> 24; 162 color.green = (value & 0x00FF0000) >> 16; 163 color.blue = (value & 0x0000FF00) >> 8; 164 color.alpha = 255; 165 166 return color; 167 } 168 //------------------------------------------------------------------------------ 169 void BColorControl::SetEnabled(bool enabled) 170 { 171 BControl::SetEnabled(enabled); 172 173 fRedText->SetEnabled(enabled); 174 fGreenText->SetEnabled(enabled); 175 fBlueText->SetEnabled(enabled); 176 } 177 //------------------------------------------------------------------------------ 178 void BColorControl::AttachedToWindow() 179 { 180 if (Parent()) 181 SetViewColor(Parent()->ViewColor()); 182 183 BControl::AttachedToWindow(); 184 185 fRedText->SetTarget(this); 186 fGreenText->SetTarget(this); 187 fBlueText->SetTarget(this); 188 } 189 //------------------------------------------------------------------------------ 190 void BColorControl::MessageReceived(BMessage *message) 191 { 192 switch (message->what) 193 { 194 case U_COLOR_CONTROL_RED_CHANGED_MSG: 195 { 196 unsigned char shade; 197 rgb_color color = ValueAsColor(); 198 199 sscanf(fRedText->Text(), "%d", &shade); 200 201 color.red = max_c(0, min_c(shade, 255)); 202 203 SetValue(color); 204 205 break; 206 } 207 case U_COLOR_CONTROL_GREEN_CHANGED_MSG: 208 { 209 unsigned char shade; 210 rgb_color color = ValueAsColor(); 211 212 sscanf(fGreenText->Text(), "%d", &shade); 213 214 color.green = max_c(0, min_c(shade, 255)); 215 216 SetValue(color); 217 218 break; 219 } 220 case U_COLOR_CONTROL_BLUE_CHANGED_MSG: 221 { 222 unsigned char shade; 223 rgb_color color = ValueAsColor(); 224 225 sscanf(fBlueText->Text(), "%d", &shade); 226 227 color.blue = max_c(0, min_c(shade, 255)); 228 229 SetValue(color); 230 231 break; 232 } 233 default: 234 BControl::MessageReceived(message); 235 } 236 } 237 //------------------------------------------------------------------------------ 238 void BColorControl::Draw(BRect updateRect) 239 { 240 BRect rect(0.0f, 0.0f, 196, 52); 241 242 rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR), 243 lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT), 244 darken1 = tint_color(no_tint, B_DARKEN_1_TINT), 245 darken4 = tint_color(no_tint, B_DARKEN_4_TINT); 246 247 // First bevel 248 SetHighColor(darken1); 249 StrokeLine(rect.LeftBottom(), rect.LeftTop()); 250 StrokeLine(rect.LeftTop(), rect.RightTop()); 251 SetHighColor(lightenmax); 252 StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), rect.RightBottom()); 253 StrokeLine(rect.RightBottom(), BPoint(rect.right, rect.top + 1.0f)); 254 255 rect.InsetBy(1.0f, 1.0f); 256 257 // Second bevel 258 SetHighColor(darken4); 259 StrokeLine(rect.LeftBottom(), rect.LeftTop()); 260 StrokeLine(rect.LeftTop(), rect.RightTop()); 261 SetHighColor(no_tint); 262 StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), rect.RightBottom()); 263 StrokeLine(rect.RightBottom(), BPoint(rect.right, rect.top + 1.0f)); 264 265 // Ramps 266 rgb_color white = {255, 255, 255, 255}; 267 rgb_color red = {255, 0, 0, 255}; 268 rgb_color green = {0, 255, 0, 255}; 269 rgb_color blue = {0, 0, 255, 255}; 270 271 rect.InsetBy(1.0f, 1.0f); 272 273 ColorRamp(BRect(), BRect(rect.left, rect.top, 274 rect.right, rect.top + 12.0f), this, white, 0, false); 275 276 ColorRamp(BRect(), BRect(rect.left, rect.top + 13.0f, 277 rect.right, rect.top + 24.0f), this, red, 0, false); 278 279 ColorRamp(BRect(), BRect(rect.left, rect.top + 25.0f, 280 rect.right, rect.top + 36.0f), this, green, 0, false); 281 282 ColorRamp(BRect(), BRect(rect.left, rect.top + 37.0f, 283 rect.right, rect.top + 48.0f), this, blue, 0, false); 284 285 // Selectors 286 rgb_color color = ValueAsColor(); 287 float x, y = rect.top + 16.0f; 288 289 SetPenSize(2.0f); 290 291 x = rect.left + color.red * (rect.Width() - 7) / 255; 292 SetHighColor(255, 255, 255); 293 StrokeEllipse(BRect(x, y, x + 4.0f, y + 4.0f)); 294 295 y += 11; 296 297 x = rect.left + color.green * (rect.Width() - 7) / 255; 298 SetHighColor(255, 255, 255); 299 StrokeEllipse(BRect(x, y, x + 4.0f, y + 4.0f)); 300 301 y += 11; 302 303 x = rect.left + color.blue * (rect.Width() - 7) / 255; 304 SetHighColor(255, 255, 255); 305 StrokeEllipse(BRect ( x, y, x + 4.0f, y + 4.0f)); 306 307 SetPenSize(1.0f); 308 } 309 //------------------------------------------------------------------------------ 310 void BColorControl::MouseDown(BPoint point) 311 { 312 rgb_color color = ValueAsColor(); 313 314 BRect rect(0.0f, 0.0f, 196, 52); 315 316 uint8 shade = (unsigned char)max_c(0, 317 min_c((point.x - 2) * 255 / (rect.Width() - 4.0f), 255)); 318 319 if (point.y - 2 < 12) 320 { 321 color.red = color.green = color.blue = shade; 322 fFocusedComponent = 1; 323 } 324 else if (point.y - 2 < 24) 325 { 326 color.red = shade; 327 fFocusedComponent = 2; 328 } 329 else if (point.y - 2 < 36) 330 { 331 color.green = shade; 332 fFocusedComponent = 3; 333 } 334 else if (point.y - 2 < 48) 335 { 336 color.blue = shade; 337 fFocusedComponent = 4; 338 } 339 340 SetValue(color); 341 342 MakeFocus(); 343 SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); 344 } 345 //------------------------------------------------------------------------------ 346 void BColorControl::KeyDown(const char *bytes, int32 numBytes) 347 { 348 } 349 //------------------------------------------------------------------------------ 350 void BColorControl::SetCellSize(float cellSide) 351 { 352 fCellSize = cellSide; 353 } 354 //------------------------------------------------------------------------------ 355 float BColorControl::CellSize() const 356 { 357 return fCellSize; 358 } 359 //------------------------------------------------------------------------------ 360 void BColorControl::SetLayout(color_control_layout layout) 361 { 362 switch (layout) 363 { 364 case B_CELLS_4x64: 365 fColumns = 4; 366 fRows = 64; 367 break; 368 case B_CELLS_8x32: 369 fColumns = 8; 370 fRows = 32; 371 break; 372 case B_CELLS_16x16: 373 fColumns = 16; 374 fRows = 16; 375 break; 376 case B_CELLS_32x8: 377 fColumns = 32; 378 fRows = 8; 379 break; 380 case B_CELLS_64x4: 381 fColumns = 64; 382 fRows = 4; 383 break; 384 } 385 } 386 //------------------------------------------------------------------------------ 387 color_control_layout BColorControl::Layout() const 388 { 389 if (fColumns == 4 &&fRows == 64) 390 return B_CELLS_4x64; 391 if (fColumns == 8 &&fRows == 32) 392 return B_CELLS_8x32; 393 if (fColumns == 16 &&fRows == 16) 394 return B_CELLS_16x16; 395 if (fColumns == 32 &&fRows == 8) 396 return B_CELLS_32x8; 397 if (fColumns == 64 &&fRows == 4) 398 return B_CELLS_64x4; 399 400 return B_CELLS_32x8; 401 } 402 //------------------------------------------------------------------------------ 403 void BColorControl::WindowActivated(bool state) 404 { 405 BControl::WindowActivated(state); 406 } 407 //------------------------------------------------------------------------------ 408 void BColorControl::MouseUp(BPoint point) 409 { 410 fFocusedComponent = 0; 411 } 412 //------------------------------------------------------------------------------ 413 void BColorControl::MouseMoved(BPoint point, uint32 transit, 414 const BMessage *message) 415 { 416 if (fFocusedComponent != 0) 417 { 418 rgb_color color = ValueAsColor(); 419 420 BRect rect(0.0f, 0.0f, 196, 52); 421 422 uint8 shade = (unsigned char)max_c(0, 423 min_c((point.x - 2) * 255 / (rect.Width() - 4.0f), 255)); 424 425 switch (fFocusedComponent) 426 { 427 case 1: 428 color.red = color.green = color.blue = shade; 429 break; 430 case 2: 431 color.red = shade; 432 break; 433 case 3: 434 color.green = shade; 435 break; 436 case 4: 437 color.blue = shade; 438 break; 439 } 440 441 SetValue(color); 442 } 443 } 444 //------------------------------------------------------------------------------ 445 void BColorControl::DetachedFromWindow() 446 { 447 BControl::DetachedFromWindow(); 448 } 449 //------------------------------------------------------------------------------ 450 void BColorControl::GetPreferredSize(float *width, float *height) 451 { 452 *width = fColumns * fCellSize + 4.0f + 88.0f; 453 *height = fRows * fCellSize + 4.0f; 454 } 455 //------------------------------------------------------------------------------ 456 void BColorControl::ResizeToPreferred() 457 { 458 BControl::ResizeToPreferred(); 459 } 460 //------------------------------------------------------------------------------ 461 status_t BColorControl::Invoke(BMessage *msg) 462 { 463 return BControl::Invoke(msg); 464 } 465 //------------------------------------------------------------------------------ 466 void BColorControl::FrameMoved(BPoint new_position) 467 { 468 BControl::FrameMoved(new_position); 469 } 470 //------------------------------------------------------------------------------ 471 void BColorControl::FrameResized(float new_width, float new_height) 472 { 473 BControl::FrameResized(new_width, new_height); 474 } 475 //------------------------------------------------------------------------------ 476 BHandler *BColorControl::ResolveSpecifier(BMessage *msg, int32 index, 477 BMessage *specifier, int32 form, 478 const char *property) 479 { 480 return BControl::ResolveSpecifier(msg, index, specifier, form, property); 481 } 482 //------------------------------------------------------------------------------ 483 status_t BColorControl::GetSupportedSuites(BMessage *data) 484 { 485 return BControl::GetSupportedSuites(data); 486 } 487 //------------------------------------------------------------------------------ 488 void BColorControl::MakeFocus(bool state) 489 { 490 BControl::MakeFocus(state); 491 } 492 //------------------------------------------------------------------------------ 493 void BColorControl::AllAttached() 494 { 495 BControl::AllAttached(); 496 } 497 //------------------------------------------------------------------------------ 498 void BColorControl::AllDetached() 499 { 500 BControl::AllDetached(); 501 } 502 //------------------------------------------------------------------------------ 503 status_t BColorControl::Perform(perform_code d, void *arg) 504 { 505 return B_ERROR; 506 } 507 //------------------------------------------------------------------------------ 508 void BColorControl::_ReservedColorControl1() {} 509 void BColorControl::_ReservedColorControl2() {} 510 void BColorControl::_ReservedColorControl3() {} 511 void BColorControl::_ReservedColorControl4() {} 512 //------------------------------------------------------------------------------ 513 BColorControl &BColorControl::operator=(const BColorControl &) 514 { 515 return *this; 516 } 517 //------------------------------------------------------------------------------ 518 void BColorControl::LayoutView(bool calc_frame) 519 { 520 } 521 //------------------------------------------------------------------------------ 522 void BColorControl::UpdateOffscreen() 523 { 524 } 525 //------------------------------------------------------------------------------ 526 void BColorControl::UpdateOffscreen(BRect update) 527 { 528 } 529 //------------------------------------------------------------------------------ 530 void BColorControl::DrawColorArea(BView *target, BRect update) 531 { 532 } 533 //------------------------------------------------------------------------------ 534 void BColorControl::ColorRamp(BRect r, BRect where, BView *target, rgb_color c, 535 int16 flag, bool focused) 536 { 537 rgb_color color = {255, 255, 255, 255}; 538 float width = where.Width(); 539 540 for (float i = 0; i <= width; i++) 541 { 542 color.red = (uint8)(i * c.red / width); 543 color.green = (uint8)(i * c.green / width); 544 color.blue = (uint8)(i * c.blue / width); 545 546 target->SetHighColor(color); 547 target->StrokeLine(BPoint(where.left + i, where.top), 548 BPoint(where.left + i, where.bottom)); 549 } 550 } 551 //------------------------------------------------------------------------------ 552 void BColorControl::KbAdjustColor(uint32 key) 553 { 554 } 555 //------------------------------------------------------------------------------ 556 bool BColorControl::key_down32(uint32 key) 557 { 558 return false; 559 } 560 //------------------------------------------------------------------------------ 561 bool BColorControl::key_down8(uint32 key) 562 { 563 return false; 564 } 565 //------------------------------------------------------------------------------ 566 BRect BColorControl::CalcFrame(BPoint start, color_control_layout layout, 567 int32 size) 568 { 569 BRect rect; 570 571 switch (layout) 572 { 573 case B_CELLS_4x64: 574 rect.Set(0.0f, 0.0f, 4 * size + 4.0f, 575 64 * size + 4.0f); 576 break; 577 case B_CELLS_8x32: 578 rect.Set(0.0f, 0.0f, 8 * size + 4.0f, 579 32 * size + 4.0f); 580 break; 581 case B_CELLS_16x16: 582 rect.Set(0.0f, 0.0f, 16 * size + 4.0f, 583 16 * size + 4.0f); 584 break; 585 case B_CELLS_32x8: 586 rect.Set(0.0f, 0.0f, 32 * size + 4.0f, 587 8 * size + 4.0f); 588 break; 589 case B_CELLS_64x4: 590 rect.Set(0.0f, 0.0f, 64 * size + 4.0f, 591 4 * size + 4.0f); 592 break; 593 } 594 595 return rect; 596 } 597 //------------------------------------------------------------------------------ 598 void BColorControl::InitData(color_control_layout layout, float size, 599 bool use_offscreen, BMessage *data) 600 { 601 } 602 //------------------------------------------------------------------------------ 603 void BColorControl::DoMouseMoved(BPoint pt) 604 { 605 } 606 //------------------------------------------------------------------------------ 607 void BColorControl::DoMouseUp(BPoint pt) 608 { 609 } 610 //------------------------------------------------------------------------------ 611