1/* 2 * Copyright 2009-2010, Haiku. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7/*! Decorator looking like Mac OS 9 */ 8 9 10#include "MacDecorator.h" 11 12#include <new> 13#include <stdio.h> 14 15#include <GradientLinear.h> 16#include <Point.h> 17#include <View.h> 18 19#include "DesktopSettings.h" 20#include "DrawingEngine.h" 21#include "PatternHandler.h" 22#include "RGBColor.h" 23 24 25//#define DEBUG_DECORATOR 26#ifdef DEBUG_DECORATOR 27# define STRACE(x) printf x 28#else 29# define STRACE(x) ; 30#endif 31 32 33MacDecorAddOn::MacDecorAddOn(image_id id, const char* name) 34 : 35 DecorAddOn(id, name) 36{ 37 38} 39 40 41Decorator* 42MacDecorAddOn::_AllocateDecorator(DesktopSettings& settings, BRect rect) 43{ 44 return new (std::nothrow)MacDecorator(settings, rect); 45} 46 47 48MacDecorator::MacDecorator(DesktopSettings& settings, BRect rect) 49 : 50 Decorator(settings, rect) 51{ 52 _UpdateFont(settings); 53 54 frame_highcol = (rgb_color){ 255, 255, 255, 255 }; 55 frame_midcol = (rgb_color){ 216, 216, 216, 255 }; 56 frame_lowcol = (rgb_color){ 110, 110, 110, 255 }; 57 frame_lowercol = (rgb_color){ 0, 0, 0, 255 }; 58 59 fButtonHighColor = (rgb_color){ 232, 232, 232, 255 }; 60 fButtonLowColor = (rgb_color){ 128, 128, 128, 255 }; 61 62 fFocusTextColor = settings.UIColor(B_WINDOW_TEXT_COLOR); 63 fNonFocusTextColor = settings.UIColor(B_WINDOW_INACTIVE_TEXT_COLOR); 64 65 _DoLayout(); 66 67 textoffset=5; 68 69 STRACE(("MacDecorator()\n")); 70} 71 72 73MacDecorator::~MacDecorator() 74{ 75 STRACE(("~MacDecorator()\n")); 76} 77 78 79// TODO : Add GetSettings 80 81 82void 83MacDecorator::Draw(BRect update) 84{ 85 STRACE(("MacDecorator: Draw(%.1f,%.1f,%.1f,%.1f)\n", 86 update.left, update.top, update.right, update.bottom)); 87 88 // We need to draw a few things: the tab, the borders, 89 // and the buttons 90 fDrawingEngine->SetDrawState(&fDrawState); 91 92 _DrawFrame(update); 93 _DrawTab(update); 94} 95 96 97void 98MacDecorator::Draw() 99{ 100 STRACE("MacDecorator::Draw()\n"); 101 fDrawingEngine->SetDrawState(&fDrawState); 102 103 _DrawFrame(fBorderRect); 104 _DrawTab(fTitleBarRect); 105} 106 107 108// TODO : add GetSizeLimits 109 110 111Decorator::Region 112MacDecorator::RegionAt(BPoint where, int32& tab) const 113{ 114 // Let the base class version identify hits of the buttons and the tab. 115 Region region = Decorator::RegionAt(where, tab); 116 if (region != REGION_NONE) 117 return region; 118 119 // check the resize corner 120 if (fTopTab->look == B_DOCUMENT_WINDOW_LOOK && fResizeRect.Contains(where)) 121 return REGION_RIGHT_BOTTOM_CORNER; 122 123 // hit-test the borders 124 if (!(fTopTab->flags & B_NOT_RESIZABLE) 125 && (fTopTab->look == B_TITLED_WINDOW_LOOK 126 || fTopTab->look == B_FLOATING_WINDOW_LOOK 127 || fTopTab->look == B_MODAL_WINDOW_LOOK) 128 && fBorderRect.Contains(where) && !fFrame.Contains(where)) { 129 return REGION_BOTTOM_BORDER; 130 // TODO: Determine the actual border! 131 } 132 133 return REGION_NONE; 134} 135 136 137void 138MacDecorator::_DoLayout() 139{ 140 const int32 kDefaultBorderWidth = 6; 141 STRACE(("MacDecorator: Do Layout\n")); 142 // Here we determine the size of every rectangle that we use 143 // internally when we are given the size of the client rectangle. 144 145 bool hasTab = false; 146 147 if (fTopTab) { 148 switch (fTopTab->look) { 149 case B_MODAL_WINDOW_LOOK: 150 fBorderWidth = kDefaultBorderWidth; 151 break; 152 153 case B_TITLED_WINDOW_LOOK: 154 case B_DOCUMENT_WINDOW_LOOK: 155 hasTab = true; 156 fBorderWidth = kDefaultBorderWidth; 157 break; 158 case B_FLOATING_WINDOW_LOOK: 159 hasTab = true; 160 fBorderWidth = 3; 161 break; 162 163 case B_BORDERED_WINDOW_LOOK: 164 fBorderWidth = 1; 165 break; 166 167 default: 168 fBorderWidth = 0; 169 } 170 } else 171 fBorderWidth = 0; 172 fBorderRect=fFrame; 173 fBorderRect.InsetBy(-fBorderWidth, -fBorderWidth); 174 175 // calculate our tab rect 176 if (hasTab) { 177 fBorderRect.top +=3; 178 179 font_height fontHeight; 180 fDrawState.Font().GetHeight(fontHeight); 181 182 // TODO the tab is drawn in a fixed height for now 183 fTitleBarRect.Set(fFrame.left - fBorderWidth, 184 fFrame.top - 23, 185 ((fFrame.right - fFrame.left) < 32.0 ? 186 fFrame.left + 32.0 : fFrame.right) + fBorderWidth, 187 fFrame.top - 3); 188 189 fTopTab->tabRect = fTitleBarRect; // TODO actually handle multiple tabs 190 191 fTopTab->zoomRect=fTitleBarRect; 192 fTopTab->zoomRect.left=fTopTab->zoomRect.right - 12; 193 fTopTab->zoomRect.bottom=fTopTab->zoomRect.top + 12; 194 fTopTab->zoomRect.OffsetBy(-4, 4); 195 196 fTopTab->closeRect=fTopTab->zoomRect; 197 fTopTab->minimizeRect=fTopTab->zoomRect; 198 199 fTopTab->closeRect.OffsetTo(fTitleBarRect.left + 4, 200 fTitleBarRect.top + 4); 201 202 fTopTab->zoomRect.OffsetBy(0 - (fTopTab->zoomRect.Width() + 4), 0); 203 if (Title(fTopTab) && fDrawingEngine) { 204 titlepixelwidth=fDrawingEngine->StringWidth(Title(fTopTab), 205 strlen(Title(fTopTab))); 206 207 if (titlepixelwidth<(fTopTab->zoomRect.left 208 - fTopTab->closeRect.right-10)) { 209 // start with offset from closerect.right 210 textoffset=int(((fTopTab->zoomRect.left - 5) 211 - (fTopTab->closeRect.right + 5)) / 2); 212 textoffset-=int(titlepixelwidth / 2); 213 214 // now make it the offset from fTabRect.left 215 textoffset+=int(fTopTab->closeRect.right + 5 216 - fTitleBarRect.left); 217 } else 218 textoffset=int(fTopTab->closeRect.right) + 5; 219 } else { 220 textoffset = 0; 221 titlepixelwidth = 0; 222 } 223 } else { 224 // no tab 225 if (fTopTab) { 226 fTopTab->tabRect.Set(0.0, 0.0, -1.0, -1.0); 227 fTopTab->closeRect.Set(0.0, 0.0, -1.0, -1.0); 228 fTopTab->zoomRect.Set(0.0, 0.0, -1.0, -1.0); 229 fTopTab->minimizeRect.Set(0.0, 0.0, -1.0, -1.0); 230 } 231 } 232} 233 234 235void 236MacDecorator::_DrawFrame(BRect invalid) 237{ 238 if (fTopTab->look == B_NO_BORDER_WINDOW_LOOK) 239 return; 240 241 if (fBorderWidth <= 0) 242 return; 243 244 BRect r = fBorderRect; 245 switch (fTopTab->look) { 246 case B_TITLED_WINDOW_LOOK: 247 case B_DOCUMENT_WINDOW_LOOK: 248 case B_MODAL_WINDOW_LOOK: 249 { 250 if (IsFocus(fTopTab)) { 251 BPoint offset = r.LeftTop(); 252 BPoint pt2 = r.LeftBottom(); 253 254 // Draw the left side of the frame 255 fDrawingEngine->StrokeLine(offset,pt2,frame_lowercol); 256 offset.x++; 257 pt2.x++; 258 pt2.y--; 259 260 fDrawingEngine->StrokeLine(offset,pt2,frame_highcol); 261 offset.x++; 262 pt2.x++; 263 pt2.y--; 264 265 fDrawingEngine->StrokeLine(offset,pt2,frame_midcol); 266 offset.x++; 267 pt2.x++; 268 fDrawingEngine->StrokeLine(offset,pt2,frame_midcol); 269 offset.x++; 270 pt2.x++; 271 pt2.y--; 272 273 fDrawingEngine->StrokeLine(offset,pt2,frame_lowcol); 274 offset.x++; 275 offset.y+=2; 276 BPoint topleftpt=offset; 277 pt2.x++; 278 pt2.y--; 279 280 fDrawingEngine->StrokeLine(offset,pt2,frame_lowercol); 281 282 283 offset=r.RightTop(); 284 pt2=r.RightBottom(); 285 286 // Draw the right side of the frame 287 fDrawingEngine->StrokeLine(offset,pt2,frame_lowercol); 288 offset.x--; 289 pt2.x--; 290 291 fDrawingEngine->StrokeLine(offset,pt2,frame_lowcol); 292 offset.x--; 293 pt2.x--; 294 295 fDrawingEngine->StrokeLine(offset,pt2,frame_midcol); 296 offset.x--; 297 pt2.x--; 298 fDrawingEngine->StrokeLine(offset,pt2,frame_midcol); 299 offset.x--; 300 pt2.x--; 301 302 fDrawingEngine->StrokeLine(offset,pt2,frame_highcol); 303 offset.x--; 304 offset.y+=2; 305 BPoint toprightpt=offset; 306 pt2.x--; 307 308 fDrawingEngine->StrokeLine(offset,pt2,frame_lowercol); 309 310 // Draw the top side of the frame that is not in the tab 311 offset=r.RightTop(); 312 pt2=r.RightBottom(); 313 314 fDrawingEngine->StrokeLine(topleftpt,toprightpt,frame_lowercol); 315 topleftpt.y--; 316 toprightpt.x++; 317 toprightpt.y--; 318 319 fDrawingEngine->StrokeLine(topleftpt,toprightpt,frame_lowcol); 320 321 offset=r.LeftBottom(); 322 pt2=r.RightBottom(); 323 324 // Draw the bottom side of the frame 325 fDrawingEngine->StrokeLine(offset,pt2,frame_lowercol); 326 offset.x++; 327 offset.y--; 328 pt2.x--; 329 pt2.y--; 330 331 fDrawingEngine->StrokeLine(offset,pt2,frame_lowcol); 332 offset.x++; 333 offset.y--; 334 pt2.x--; 335 pt2.y--; 336 337 fDrawingEngine->StrokeLine(offset,pt2,frame_midcol); 338 offset.x++; 339 offset.y--; 340 pt2.x--; 341 pt2.y--; 342 343 fDrawingEngine->StrokeLine(offset,pt2,frame_midcol); 344 offset.x++; 345 offset.y--; 346 pt2.x--; 347 pt2.y--; 348 349 fDrawingEngine->StrokeLine(offset,pt2,frame_highcol); 350 offset.x+=2; 351 offset.y--; 352 pt2.x--; 353 pt2.y--; 354 355 fDrawingEngine->StrokeLine(offset,pt2,frame_lowercol); 356 offset.y--; 357 pt2.x--; 358 pt2.y--; 359 } else { 360 fDrawingEngine->StrokeLine(r.LeftTop(), r.LeftBottom(), frame_lowcol); 361 fDrawingEngine->StrokeLine(r.RightTop(), r.RightBottom(), frame_lowcol); 362 fDrawingEngine->StrokeLine(r.LeftBottom(), r.RightBottom(), frame_lowcol); 363 364 for (int i = 0; i < 4; i++) { 365 r.InsetBy(1, 1); 366 fDrawingEngine->StrokeLine(r.LeftTop(), r.LeftBottom(), frame_midcol); 367 fDrawingEngine->StrokeLine(r.RightTop(), r.RightBottom(), frame_midcol); 368 fDrawingEngine->StrokeLine(r.LeftBottom(), r.RightBottom(), frame_midcol); 369 } 370 371 r.InsetBy(1, 1); 372 fDrawingEngine->StrokeLine(r.LeftTop(), r.LeftBottom(), frame_lowcol); 373 fDrawingEngine->StrokeLine(r.RightTop(), r.RightBottom(), frame_lowcol); 374 fDrawingEngine->StrokeLine(r.LeftBottom(), r.RightBottom(), frame_lowcol); 375 } 376 break; 377 } 378 case B_BORDERED_WINDOW_LOOK: 379 fDrawingEngine->StrokeRect(r, frame_midcol); 380 break; 381 382 default: 383 // don't draw a border frame 384 break; 385 } 386} 387 388 389void 390MacDecorator::_DrawTab(BRect invalid) 391{ 392 // If a window has a tab, this will draw it and any buttons which are 393 // in it. 394 if (!fTitleBarRect.IsValid() || !invalid.Intersects(fTitleBarRect)) 395 return; 396 397 BRect rect(fTitleBarRect); 398 fDrawingEngine->SetHighColor(RGBColor(frame_midcol)); 399 fDrawingEngine->FillRect(rect,frame_midcol); 400 401 if (IsFocus(fTopTab)) { 402 fDrawingEngine->StrokeLine(rect.LeftTop(),rect.RightTop(),frame_lowercol); 403 fDrawingEngine->StrokeLine(rect.LeftTop(),rect.LeftBottom(),frame_lowercol); 404 fDrawingEngine->StrokeLine(rect.RightBottom(),rect.RightTop(),frame_lowercol); 405 406 rect.InsetBy(1,1); 407 rect.bottom++; 408 409 fDrawingEngine->StrokeLine(rect.LeftTop(),rect.RightTop(),frame_highcol); 410 fDrawingEngine->StrokeLine(rect.LeftTop(),rect.LeftBottom(),frame_highcol); 411 fDrawingEngine->StrokeLine(rect.RightBottom(),rect.RightTop(),frame_lowcol); 412 413 // Draw the neat little lines on either side of the title if there's room 414 if (fTitleBarRect.left + textoffset > fTopTab->closeRect.right + 5) { 415 // Left side 416 417 BPoint offset(fTopTab->closeRect.right+5,fTopTab->closeRect.top), 418 pt2(fTitleBarRect.left+textoffset-5,fTopTab->closeRect.top); 419 fDrawState.SetHighColor(RGBColor(frame_highcol)); 420 for (int32 i = 0; i < 6; i++) { 421 fDrawingEngine->StrokeLine(offset,pt2,fDrawState.HighColor()); 422 offset.y+=2; 423 pt2.y+=2; 424 } 425 426 offset.Set(fTopTab->closeRect.right+6,fTopTab->closeRect.top+1), 427 pt2.Set(fTitleBarRect.left+textoffset-4,fTopTab->closeRect.top+1); 428 fDrawState.SetHighColor(RGBColor(frame_lowcol)); 429 for (int32 i = 0; i < 6; i++) { 430 fDrawingEngine->StrokeLine(offset, pt2, fDrawState.HighColor()); 431 offset.y += 2; 432 pt2.y += 2; 433 } 434 435 // Right side 436 437 offset.Set(fTitleBarRect.left + textoffset + titlepixelwidth + 6, 438 fTopTab->zoomRect.top), pt2.Set(fTopTab->zoomRect.left - 6, 439 fTopTab->zoomRect.top); 440 if (offset.x < pt2.x) { 441 fDrawState.SetHighColor(RGBColor(frame_highcol)); 442 for (int32 i = 0; i < 6; i++) { 443 fDrawingEngine->StrokeLine(offset, pt2, 444 fDrawState.HighColor()); 445 offset.y += 2; 446 pt2.y += 2; 447 } 448 offset.Set(fTitleBarRect.left+textoffset + titlepixelwidth + 7, 449 fTopTab->zoomRect.top + 1), pt2.Set(fTopTab->zoomRect.left - 5, 450 fTopTab->zoomRect.top + 1); 451 fDrawState.SetHighColor(frame_lowcol); 452 for(int32 i = 0; i < 6; i++) { 453 fDrawingEngine->StrokeLine(offset, pt2, 454 fDrawState.HighColor()); 455 offset.y += 2; 456 pt2.y += 2; 457 } 458 } 459 } 460 461 // Draw the buttons if we're supposed to 462 if (!(fTopTab->flags & B_NOT_CLOSABLE)) 463 _DrawClose(fTopTab->closeRect); 464 if (!(fTopTab->flags & B_NOT_ZOOMABLE)) 465 _DrawZoom(fTopTab->zoomRect); 466 } else { 467 // Not focused - Just draw a plain light grey area with the title in the middle 468 fDrawingEngine->StrokeLine(rect.LeftTop(),rect.RightTop(),frame_lowcol); 469 fDrawingEngine->StrokeLine(rect.LeftTop(),rect.LeftBottom(),frame_lowcol); 470 fDrawingEngine->StrokeLine(rect.RightBottom(),rect.RightTop(),frame_lowcol); 471 } 472 473 _DrawTitle(fTitleBarRect); 474} 475 476 477void 478MacDecorator::_DrawClose(BRect r) 479{ 480 bool down = fTopTab->closePressed; 481 482 // Just like DrawZoom, but for a close button 483 BRect rect(r); 484 485 BPoint offset(r.LeftTop()), pt2(r.RightTop()); 486 487 // Topleft dark grey border 488 pt2.x--; 489 fDrawingEngine->SetHighColor(RGBColor(136, 136, 136)); 490 fDrawingEngine->StrokeLine(offset, pt2); 491 492 pt2 = r.LeftBottom(); 493 pt2.y--; 494 fDrawingEngine->StrokeLine(offset, pt2); 495 496 // Bottomright white border 497 offset = r.RightBottom(); 498 pt2 = r.RightTop(); 499 pt2.y++; 500 fDrawingEngine->SetHighColor(RGBColor(255, 255, 255)); 501 fDrawingEngine->StrokeLine(offset, pt2); 502 503 pt2 = r.LeftBottom(); 504 pt2.x++; 505 fDrawingEngine->StrokeLine(offset, pt2); 506 507 // Black outline 508 rect.InsetBy(1, 1); 509 fDrawingEngine->SetHighColor(RGBColor(0, 0, 0)); 510 fDrawingEngine->StrokeRect(rect); 511 512 // Double-shaded button 513 rect.InsetBy(1, 1); 514 _DrawBlendedRect(fDrawingEngine, rect, down); 515 rect.InsetBy(1, 1); 516 _DrawBlendedRect(fDrawingEngine, rect, !down); 517} 518 519 520void 521MacDecorator::_DrawTitle(BRect rect) 522{ 523 if (IsFocus(fTopTab)) 524 fDrawingEngine->SetHighColor(fFocusTextColor); 525 else 526 fDrawingEngine->SetHighColor(fNonFocusTextColor); 527 528 fDrawingEngine->SetLowColor(frame_midcol); 529 530 fTruncatedTitle = Title(fTopTab); 531 fDrawState.Font().TruncateString(&fTruncatedTitle, B_TRUNCATE_END, 532 (fTopTab->zoomRect.left - 5) - (fTopTab->closeRect.right + 5)); 533 fTruncatedTitleLength = fTruncatedTitle.Length(); 534 fDrawingEngine->SetFont(fDrawState.Font()); 535 536 fDrawingEngine->DrawString(fTruncatedTitle,fTruncatedTitleLength, 537 BPoint(fTitleBarRect.left+textoffset,fTopTab->closeRect.bottom-1)); 538} 539 540 541void 542MacDecorator::_DrawZoom(BRect r) 543{ 544 bool down = fTopTab->zoomPressed; 545 546 // Just like DrawZoom, but for a close button 547 BRect rect(r); 548 BPoint offset(r.LeftTop()),pt2(r.RightTop()); 549 550 pt2.x--; 551 fDrawState.SetHighColor(RGBColor(136, 136, 136)); 552 fDrawingEngine->StrokeLine(offset, pt2, fDrawState.HighColor()); 553 554 pt2 = r.LeftBottom(); 555 pt2.y--; 556 fDrawingEngine->StrokeLine(offset, pt2, fDrawState.HighColor()); 557 558 offset = r.RightBottom(); 559 pt2 = r.RightTop(); 560 pt2.y++; 561 fDrawState.SetHighColor(RGBColor(255, 255, 255)); 562 fDrawingEngine->StrokeLine(offset, pt2, fDrawState.HighColor()); 563 564 pt2 = r.LeftBottom(); 565 pt2.x++; 566 fDrawingEngine->StrokeLine(offset, pt2, fDrawState.HighColor()); 567 568 rect.InsetBy(1, 1); 569 fDrawState.SetHighColor(RGBColor(0, 0, 0)); 570 fDrawingEngine->StrokeRect(rect, fDrawState.HighColor()); 571 572 rect.InsetBy(1, 1); 573 _DrawBlendedRect(fDrawingEngine, rect, down); 574 rect.InsetBy(1,1); 575 _DrawBlendedRect(fDrawingEngine, rect, !down); 576 577 rect.top += 2; 578 rect.left--; 579 rect.right++; 580 581 fDrawState.SetHighColor(RGBColor(0, 0, 0)); 582 fDrawingEngine->StrokeLine(rect.LeftTop(), rect.RightTop(), 583 fDrawState.HighColor()); 584} 585 586 587void 588MacDecorator::_DrawMinimize(BRect r) 589{ 590 bool down = fTopTab->minimizePressed; 591 592 // Just like DrawZoom, but for a Minimize button 593 BRect rect(r); 594 BPoint offset(r.LeftTop()), pt2(r.RightTop()); 595 596 pt2.x--; 597 fDrawState.SetHighColor(RGBColor(136, 136, 136)); 598 fDrawingEngine->StrokeLine(offset, pt2, fDrawState.HighColor()); 599 600 pt2 = r.LeftBottom(); 601 pt2.y--; 602 fDrawingEngine->StrokeLine(offset, pt2, fDrawState.HighColor()); 603 604 offset = r.RightBottom(); 605 pt2 = r.RightTop(); 606 pt2.y++; 607 fDrawState.SetHighColor(RGBColor(255, 255, 255)); 608 fDrawingEngine->StrokeLine(offset, pt2, fDrawState.HighColor()); 609 610 pt2 = r.LeftBottom(); 611 pt2.x++; 612 fDrawingEngine->StrokeLine(offset, pt2, fDrawState.HighColor()); 613 614 rect.InsetBy(1, 1); 615 fDrawState.SetHighColor(RGBColor(0, 0, 0)); 616 fDrawingEngine->StrokeRect(rect, fDrawState.HighColor()); 617 618 rect.InsetBy(1, 1); 619 _DrawBlendedRect(fDrawingEngine, rect, down); 620 rect.InsetBy(1, 1); 621 _DrawBlendedRect(fDrawingEngine, rect, !down); 622 623 rect.top += 4; 624 rect.bottom -= 4; 625 rect.InsetBy(-2, 0); 626 627 fDrawState.SetHighColor(RGBColor(0, 0, 0)); 628 fDrawingEngine->StrokeRect(rect, fDrawState.HighColor()); 629} 630 631 632void 633MacDecorator::_SetTitle(Tab* tab, const char* string, BRegion* updateRegion) 634{ 635 // TODO: we could be much smarter about the update region 636 // TODO may this change the other tabs too ? (to make space for a longer 637 // title ?) 638 639 BRect rect = TabRect(fTopTab); 640 641 _DoLayout(); 642 643 if (updateRegion == NULL) 644 return; 645 646 rect = rect | TabRect(fTopTab); 647 648 rect.bottom++; 649 // the border will look differently when the title is adjacent 650 651 updateRegion->Include(rect); 652} 653 654 655void 656MacDecorator::_FontsChanged(DesktopSettings& settings, 657 BRegion* updateRegion) 658{ 659 // get previous extent 660 if (updateRegion != NULL) 661 updateRegion->Include(&GetFootprint()); 662 663 _UpdateFont(settings); 664 _DoLayout(); 665 666 _InvalidateFootprint(); 667 if (updateRegion != NULL) 668 updateRegion->Include(&GetFootprint()); 669} 670 671 672void 673MacDecorator::_SetLook(DesktopSettings& settings, window_look look, 674 BRegion* updateRegion) 675{ 676 // TODO: we could be much smarter about the update region 677 678 // get previous extent 679 if (updateRegion != NULL) 680 updateRegion->Include(&GetFootprint()); 681 682 fTopTab->look = look; 683 684 _UpdateFont(settings); 685 _DoLayout(); 686 687 _InvalidateFootprint(); 688 if (updateRegion != NULL) 689 updateRegion->Include(&GetFootprint()); 690} 691 692 693void 694MacDecorator::_SetFlags(uint32 flags, BRegion* updateRegion) 695{ 696 // TODO: we could be much smarter about the update region 697 698 // get previous extent 699 if (updateRegion != NULL) 700 updateRegion->Include(&GetFootprint()); 701 702 _DoLayout(); 703 704 _InvalidateFootprint(); 705 if (updateRegion != NULL) 706 updateRegion->Include(&GetFootprint()); 707} 708 709 710// TODO : _SetFocus 711 712 713void 714MacDecorator::_MoveBy(BPoint offset) 715{ 716 // TODO handle all tabs 717 fFrame.OffsetBy(offset); 718 fTopTab->closeRect.OffsetBy(offset); 719 fTitleBarRect.OffsetBy(offset); 720 fTopTab->tabRect = fTitleBarRect; 721 fResizeRect.OffsetBy(offset); 722 fTopTab->zoomRect.OffsetBy(offset); 723 fBorderRect.OffsetBy(offset); 724} 725 726 727void 728MacDecorator::_ResizeBy(BPoint offset, BRegion* dirty) 729{ 730 // Move all internal rectangles the appropriate amount 731 fFrame.right += offset.x; 732 fFrame.bottom += offset.y; 733 734 fTitleBarRect.right += offset.x; 735 fBorderRect.right += offset.x; 736 fBorderRect.bottom += offset.y; 737 // fZoomRect.OffsetBy(offset.x, 0); 738 // fMinimizeRect.OffsetBy(offset.x, 0); 739 if (dirty) { 740 dirty->Include(fTitleBarRect); 741 dirty->Include(fBorderRect); 742 } 743 744 745 // TODO probably some other layouting stuff here 746 _DoLayout(); 747} 748 749 750// TODO : _SetSettings 751 752 753void 754MacDecorator::_GetFootprint(BRegion* region) 755{ 756 // This function calculates the decorator's footprint in coordinates 757 // relative to the view. This is most often used to set a Window 758 // object's visible region. 759 if (!region) 760 return; 761 762 region->MakeEmpty(); 763 764 if (fTopTab->look == B_NO_BORDER_WINDOW_LOOK) 765 return; 766 767 region->Set(fBorderRect); 768 region->Exclude(fFrame); 769 770 if (fTopTab->look == B_BORDERED_WINDOW_LOOK) 771 return; 772 region->Include(fTitleBarRect); 773} 774 775 776void 777MacDecorator::_UpdateFont(DesktopSettings& settings) 778{ 779 ServerFont font; 780 if (fTopTab && fTopTab->look == B_FLOATING_WINDOW_LOOK) 781 settings.GetDefaultPlainFont(font); 782 else 783 settings.GetDefaultBoldFont(font); 784 785 font.SetFlags(B_FORCE_ANTIALIASING); 786 font.SetSpacing(B_STRING_SPACING); 787 fDrawState.SetFont(font); 788} 789 790 791/*! \brief Draws a rectangle with a gradient. 792 \param down The rectangle should be drawn recessed or not 793*/ 794void 795MacDecorator::_DrawBlendedRect(DrawingEngine* engine, BRect rect, 796 bool down/*, bool focus*/) 797{ 798 // figure out which colors to use 799 rgb_color startColor, endColor; 800 if (down) { 801 startColor = fButtonLowColor; 802 endColor = frame_highcol; 803 } else { 804 startColor = fButtonHighColor; 805 endColor = frame_lowercol; 806 } 807 808 // fill 809 BGradientLinear gradient; 810 gradient.SetStart(rect.LeftTop()); 811 gradient.SetEnd(rect.RightBottom()); 812 gradient.AddColor(startColor, 0); 813 gradient.AddColor(endColor, 255); 814 815 engine->FillRect(rect, gradient); 816} 817 818 819Decorator::Tab* 820MacDecorator::_AllocateNewTab() 821{ 822 Decorator::Tab* tab = new(std::nothrow) MacDecorator::Tab; 823 if (tab == NULL) 824 return NULL; 825 // Set appropriate colors based on the current focus value. In this case, 826 // each decorator defaults to not having the focus. 827 _SetFocus(tab); 828 return tab; 829} 830 831 832bool 833MacDecorator::_AddTab(DesktopSettings& settings, int32 index, 834 BRegion* updateRegion) 835{ 836 _UpdateFont(settings); 837 838 _DoLayout(); 839 if (updateRegion != NULL) 840 updateRegion->Include(fTitleBarRect); 841 return true; 842} 843 844 845bool 846MacDecorator::_RemoveTab(int32 index, BRegion* updateRegion) 847{ 848 BRect oldTitle = fTitleBarRect; 849 _DoLayout(); 850 if (updateRegion != NULL) { 851 updateRegion->Include(oldTitle); 852 updateRegion->Include(fTitleBarRect); 853 } 854 return true; 855} 856 857 858bool 859MacDecorator::_MoveTab(int32 from, int32 to, bool isMoving, 860 BRegion* updateRegion) 861{ 862 return false; //TODO 863 #if 0 864 MacDecorator::Tab* toTab = _TabAt(to); 865 if (toTab == NULL) 866 return false; 867 868 if (from < to) { 869 fOldMovingTab.OffsetBy(toTab->tabRect.Width(), 0); 870 toTab->tabRect.OffsetBy(-fOldMovingTab.Width(), 0); 871 } else { 872 fOldMovingTab.OffsetBy(-toTab->tabRect.Width(), 0); 873 toTab->tabRect.OffsetBy(fOldMovingTab.Width(), 0); 874 } 875 876 toTab->tabOffset = uint32(toTab->tabRect.left - fLeftBorder.left); 877 _LayoutTabItems(toTab, toTab->tabRect); 878 879 _CalculateTabsRegion(); 880 881 if (updateRegion != NULL) 882 updateRegion->Include(fTitleBarRect); 883 return true; 884 #endif 885} 886 887 888// #pragma mark - 889 890 891extern "C" DecorAddOn* 892instantiate_decor_addon(image_id id, const char* name) 893{ 894 return new (std::nothrow)MacDecorAddOn(id, name); 895} 896