1 /* 2 * Copyright 2004-2009, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <ScrollView.h> 8 9 #include <ControlLook.h> 10 #include <LayoutUtils.h> 11 #include <Message.h> 12 #include <Region.h> 13 #include <Window.h> 14 15 #include <binary_compatibility/Interface.h> 16 17 static const float kFancyBorderSize = 2; 18 static const float kPlainBorderSize = 1; 19 20 21 BScrollView::BScrollView(const char *name, BView *target, uint32 resizingMode, 22 uint32 flags, bool horizontal, bool vertical, border_style border) 23 : BView(_ComputeFrame(target, horizontal, vertical, border), name, 24 resizingMode, _ModifyFlags(flags, border)), 25 fTarget(target), 26 fBorder(border) 27 { 28 _Init(horizontal, vertical); 29 } 30 31 32 BScrollView::BScrollView(const char* name, BView* target, uint32 flags, 33 bool horizontal, bool vertical, border_style border) 34 : BView(name, _ModifyFlags(flags, border)), 35 fTarget(target), 36 fBorder(border) 37 { 38 _Init(horizontal, vertical); 39 } 40 41 42 BScrollView::BScrollView(BMessage *archive) 43 : BView(archive), 44 fHighlighted(false) 45 { 46 int32 border; 47 fBorder = archive->FindInt32("_style", &border) == B_OK ? 48 (border_style)border : B_FANCY_BORDER; 49 50 // In a shallow archive, we may not have a target anymore. We must 51 // be prepared for this case 52 53 // don't confuse our scroll bars with our (eventual) target 54 int32 firstBar = 0; 55 if (!archive->FindBool("_no_target_")) { 56 fTarget = ChildAt(0); 57 firstBar++; 58 } else 59 fTarget = NULL; 60 61 // search for our scroll bars 62 63 fHorizontalScrollBar = NULL; 64 fVerticalScrollBar = NULL; 65 66 BView *view; 67 while ((view = ChildAt(firstBar++)) != NULL) { 68 BScrollBar *bar = dynamic_cast<BScrollBar *>(view); 69 if (bar == NULL) 70 continue; 71 72 if (bar->Orientation() == B_HORIZONTAL) 73 fHorizontalScrollBar = bar; 74 else if (bar->Orientation() == B_VERTICAL) 75 fVerticalScrollBar = bar; 76 } 77 78 fPreviousWidth = uint16(Bounds().Width()); 79 fPreviousHeight = uint16(Bounds().Height()); 80 } 81 82 83 BScrollView::~BScrollView() 84 { 85 } 86 87 88 // #pragma mark - 89 90 91 BArchivable* 92 BScrollView::Instantiate(BMessage* archive) 93 { 94 if (validate_instantiation(archive, "BScrollView")) 95 return new BScrollView(archive); 96 97 return NULL; 98 } 99 100 101 status_t 102 BScrollView::Archive(BMessage* archive, bool deep) const 103 { 104 status_t status = BView::Archive(archive, deep); 105 if (status != B_OK) 106 return status; 107 108 // If this is a deep archive, the BView class will take care 109 // of our children. 110 111 if (status == B_OK && fBorder != B_FANCY_BORDER) 112 status = archive->AddInt32("_style", fBorder); 113 if (status == B_OK && fTarget == NULL) 114 status = archive->AddBool("_no_target_", true); 115 116 // The highlighted state is not archived, but since it is 117 // usually (or should be) used to indicate focus, this 118 // is probably the right thing to do. 119 120 return status; 121 } 122 123 124 void 125 BScrollView::AttachedToWindow() 126 { 127 BView::AttachedToWindow(); 128 129 if ((fHorizontalScrollBar == NULL && fVerticalScrollBar == NULL) 130 || (fHorizontalScrollBar != NULL && fVerticalScrollBar != NULL) 131 || Window()->Look() != B_DOCUMENT_WINDOW_LOOK) 132 return; 133 134 // If we have only one bar, we need to check if we are in the 135 // bottom right edge of a window with the B_DOCUMENT_LOOK to 136 // adjust the size of the bar to acknowledge the resize knob. 137 138 BRect bounds = ConvertToScreen(Bounds()); 139 BRect windowBounds = Window()->Frame(); 140 141 if (bounds.right - _BorderSize() != windowBounds.right 142 || bounds.bottom - _BorderSize() != windowBounds.bottom) 143 return; 144 145 if (fHorizontalScrollBar) 146 fHorizontalScrollBar->ResizeBy(-B_V_SCROLL_BAR_WIDTH, 0); 147 else if (fVerticalScrollBar) 148 fVerticalScrollBar->ResizeBy(0, -B_H_SCROLL_BAR_HEIGHT); 149 } 150 151 152 void 153 BScrollView::DetachedFromWindow() 154 { 155 BView::DetachedFromWindow(); 156 } 157 158 159 void 160 BScrollView::AllAttached() 161 { 162 BView::AllAttached(); 163 } 164 165 166 void 167 BScrollView::AllDetached() 168 { 169 BView::AllDetached(); 170 } 171 172 173 void 174 BScrollView::Draw(BRect updateRect) 175 { 176 if (be_control_look != NULL) { 177 uint32 flags = 0; 178 if (fHighlighted && Window()->IsActive()) 179 flags |= BControlLook::B_FOCUSED; 180 BRect rect(Bounds()); 181 rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); 182 183 BRect verticalScrollBarFrame(0, 0, -1, -1); 184 if (fVerticalScrollBar) 185 verticalScrollBarFrame = fVerticalScrollBar->Frame(); 186 BRect horizontalScrollBarFrame(0, 0, -1, -1); 187 if (fHorizontalScrollBar) 188 horizontalScrollBarFrame = fHorizontalScrollBar->Frame(); 189 190 be_control_look->DrawScrollViewFrame(this, rect, updateRect, 191 verticalScrollBarFrame, horizontalScrollBarFrame, base, fBorder, 192 flags); 193 194 return; 195 } 196 197 if (fBorder == B_PLAIN_BORDER) { 198 SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 199 B_DARKEN_2_TINT)); 200 StrokeRect(Bounds()); 201 return; 202 } else if (fBorder != B_FANCY_BORDER) 203 return; 204 205 BRect bounds = Bounds(); 206 SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 207 B_DARKEN_2_TINT)); 208 StrokeRect(bounds.InsetByCopy(1, 1)); 209 210 if (fHighlighted && Window()->IsActive()) { 211 SetHighColor(ui_color(B_NAVIGATION_BASE_COLOR)); 212 StrokeRect(bounds); 213 } else { 214 SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 215 B_DARKEN_1_TINT)); 216 StrokeLine(bounds.LeftBottom(), bounds.LeftTop()); 217 bounds.left++; 218 StrokeLine(bounds.LeftTop(), bounds.RightTop()); 219 220 SetHighColor(ui_color(B_SHINE_COLOR)); 221 StrokeLine(bounds.LeftBottom(), bounds.RightBottom()); 222 bounds.top++; 223 bounds.bottom--; 224 StrokeLine(bounds.RightBottom(), bounds.RightTop()); 225 } 226 } 227 228 229 // #pragma mark - 230 231 232 void 233 BScrollView::WindowActivated(bool active) 234 { 235 if (fHighlighted) 236 Invalidate(); 237 238 BView::WindowActivated(active); 239 } 240 241 242 void 243 BScrollView::MakeFocus(bool state) 244 { 245 BView::MakeFocus(state); 246 } 247 248 249 // #pragma mark - 250 251 252 void 253 BScrollView::GetPreferredSize(float *_width, float *_height) 254 { 255 BSize size = PreferredSize(); 256 257 if (_width) 258 *_width = size.width; 259 if (_height) 260 *_height = size.height; 261 } 262 263 264 BSize 265 BScrollView::MinSize() 266 { 267 BSize size = _ComputeSize(fTarget != NULL ? fTarget->MinSize() 268 : BSize(16, 16)); 269 270 return BLayoutUtils::ComposeSize(ExplicitMinSize(), size); 271 } 272 273 274 BSize 275 BScrollView::MaxSize() 276 { 277 BSize size = _ComputeSize(fTarget != NULL ? fTarget->MaxSize() 278 : BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED)); 279 280 return BLayoutUtils::ComposeSize(ExplicitMaxSize(), size); 281 } 282 283 284 BSize 285 BScrollView::PreferredSize() 286 { 287 BSize size = _ComputeSize(fTarget != NULL ? fTarget->PreferredSize() 288 : BSize(32, 32)); 289 290 return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), size); 291 } 292 293 294 void 295 BScrollView::ResizeToPreferred() 296 { 297 if (Window() == NULL) 298 return; 299 BView::ResizeToPreferred(); 300 } 301 302 303 void 304 BScrollView::InvalidateLayout(bool descendants) 305 { 306 BView::InvalidateLayout(descendants); 307 } 308 309 310 void 311 BScrollView::DoLayout() 312 { 313 if (!(Flags() & B_SUPPORTS_LAYOUT)) 314 return; 315 316 // If the user set a layout, we let the base class version call its hook. 317 if (GetLayout()) { 318 BView::DoLayout(); 319 return; 320 } 321 322 BRect innerFrame = _InnerFrame(); 323 324 if (fTarget != NULL) { 325 fTarget->MoveTo(innerFrame.left, innerFrame.top); 326 fTarget->ResizeTo(innerFrame.Width(), innerFrame.Height()); 327 328 //BLayoutUtils::AlignInFrame(fTarget, fTarget->Bounds()); 329 } 330 331 _AlignScrollBars(fHorizontalScrollBar != NULL, fVerticalScrollBar != NULL, 332 innerFrame); 333 } 334 335 336 void 337 BScrollView::FrameMoved(BPoint position) 338 { 339 BView::FrameMoved(position); 340 } 341 342 343 void 344 BScrollView::FrameResized(float width, float height) 345 { 346 BView::FrameResized(width, height); 347 348 if (fBorder == B_NO_BORDER) 349 return; 350 351 BRect bounds = Bounds(); 352 float border = _BorderSize() - 1; 353 354 if (be_control_look && fHorizontalScrollBar && fVerticalScrollBar) { 355 BRect scrollCorner(bounds); 356 scrollCorner.left = min_c( 357 fPreviousWidth - fVerticalScrollBar->Frame().Height(), 358 fHorizontalScrollBar->Frame().right + 1); 359 scrollCorner.top = min_c( 360 fPreviousHeight - fHorizontalScrollBar->Frame().Width(), 361 fVerticalScrollBar->Frame().bottom + 1); 362 Invalidate(scrollCorner); 363 } 364 365 // changes in width 366 367 if (bounds.Width() > fPreviousWidth) { 368 // invalidate the region between the old and the new right border 369 BRect rect = bounds; 370 rect.left += fPreviousWidth - border; 371 rect.right--; 372 Invalidate(rect); 373 } else if (bounds.Width() < fPreviousWidth) { 374 // invalidate the region of the new right border 375 BRect rect = bounds; 376 rect.left = rect.right - border; 377 Invalidate(rect); 378 } 379 380 // changes in height 381 382 if (bounds.Height() > fPreviousHeight) { 383 // invalidate the region between the old and the new bottom border 384 BRect rect = bounds; 385 rect.top += fPreviousHeight - border; 386 rect.bottom--; 387 Invalidate(rect); 388 } else if (bounds.Height() < fPreviousHeight) { 389 // invalidate the region of the new bottom border 390 BRect rect = bounds; 391 rect.top = rect.bottom - border; 392 Invalidate(rect); 393 } 394 395 fPreviousWidth = uint16(bounds.Width()); 396 fPreviousHeight = uint16(bounds.Height()); 397 } 398 399 400 // #pragma mark - 401 402 403 void 404 BScrollView::MessageReceived(BMessage* message) 405 { 406 switch (message->what) { 407 default: 408 BView::MessageReceived(message); 409 } 410 } 411 412 413 void 414 BScrollView::MouseDown(BPoint point) 415 { 416 BView::MouseDown(point); 417 } 418 419 420 void 421 BScrollView::MouseUp(BPoint point) 422 { 423 BView::MouseUp(point); 424 } 425 426 427 void 428 BScrollView::MouseMoved(BPoint point, uint32 code, const BMessage *dragMessage) 429 { 430 BView::MouseMoved(point, code, dragMessage); 431 } 432 433 434 // #pragma mark - 435 436 437 BScrollBar* 438 BScrollView::ScrollBar(orientation posture) const 439 { 440 if (posture == B_HORIZONTAL) 441 return fHorizontalScrollBar; 442 443 return fVerticalScrollBar; 444 } 445 446 447 void 448 BScrollView::SetBorder(border_style border) 449 { 450 if (fBorder == border) 451 return; 452 453 if (Flags() & B_SUPPORTS_LAYOUT) { 454 fBorder = border; 455 SetFlags(_ModifyFlags(Flags(), border)); 456 457 DoLayout(); 458 459 BRect bounds(Bounds()); 460 Invalidate(BRect(bounds.LeftTop(), bounds.RightBottom())); 461 Invalidate(BRect(bounds.LeftBottom(), bounds.RightBottom())); 462 return; 463 } 464 465 float offset = _BorderSize() - _BorderSize(border); 466 float resize = 2 * offset; 467 468 float horizontalGap = 0, verticalGap = 0; 469 float change = 0; 470 if (border == B_NO_BORDER || fBorder == B_NO_BORDER) { 471 if (fHorizontalScrollBar != NULL) 472 verticalGap = border != B_NO_BORDER ? 1 : -1; 473 if (fVerticalScrollBar != NULL) 474 horizontalGap = border != B_NO_BORDER ? 1 : -1; 475 476 change = border != B_NO_BORDER ? -1 : 1; 477 if (fHorizontalScrollBar == NULL || fVerticalScrollBar == NULL) 478 change *= 2; 479 } 480 481 fBorder = border; 482 483 int32 savedResizingMode = 0; 484 if (fTarget != NULL) { 485 savedResizingMode = fTarget->ResizingMode(); 486 fTarget->SetResizingMode(B_FOLLOW_NONE); 487 } 488 489 MoveBy(offset, offset); 490 ResizeBy(-resize - horizontalGap, -resize - verticalGap); 491 492 if (fTarget != NULL) { 493 fTarget->MoveBy(-offset, -offset); 494 fTarget->SetResizingMode(savedResizingMode); 495 } 496 497 if (fHorizontalScrollBar != NULL) { 498 fHorizontalScrollBar->MoveBy(-offset - verticalGap, offset + verticalGap); 499 fHorizontalScrollBar->ResizeBy(resize + horizontalGap - change, 0); 500 } 501 if (fVerticalScrollBar != NULL) { 502 fVerticalScrollBar->MoveBy(offset + horizontalGap, -offset - horizontalGap); 503 fVerticalScrollBar->ResizeBy(0, resize + verticalGap - change); 504 } 505 506 SetFlags(_ModifyFlags(Flags(), border)); 507 } 508 509 510 border_style 511 BScrollView::Border() const 512 { 513 return fBorder; 514 } 515 516 517 status_t 518 BScrollView::SetBorderHighlighted(bool state) 519 { 520 if (fHighlighted == state) 521 return B_OK; 522 523 if (fBorder != B_FANCY_BORDER) 524 // highlighting only works for B_FANCY_BORDER 525 return B_ERROR; 526 527 fHighlighted = state; 528 529 if (fHorizontalScrollBar != NULL) 530 fHorizontalScrollBar->SetBorderHighlighted(state); 531 if (fVerticalScrollBar != NULL) 532 fVerticalScrollBar->SetBorderHighlighted(state); 533 534 BRect bounds = Bounds(); 535 if (be_control_look != NULL) 536 bounds.InsetBy(1, 1); 537 538 Invalidate(BRect(bounds.left, bounds.top, bounds.right, bounds.top)); 539 Invalidate(BRect(bounds.left, bounds.top + 1, bounds.left, 540 bounds.bottom - 1)); 541 Invalidate(BRect(bounds.right, bounds.top + 1, bounds.right, 542 bounds.bottom - 1)); 543 Invalidate(BRect(bounds.left, bounds.bottom, bounds.right, bounds.bottom)); 544 545 return B_OK; 546 } 547 548 549 bool 550 BScrollView::IsBorderHighlighted() const 551 { 552 return fHighlighted; 553 } 554 555 556 void 557 BScrollView::SetTarget(BView *target) 558 { 559 if (fTarget == target) 560 return; 561 562 if (fTarget != NULL) { 563 fTarget->TargetedByScrollView(NULL); 564 RemoveChild(fTarget); 565 566 // we are not supposed to delete the view 567 } 568 569 fTarget = target; 570 if (fHorizontalScrollBar != NULL) 571 fHorizontalScrollBar->SetTarget(target); 572 if (fVerticalScrollBar != NULL) 573 fVerticalScrollBar->SetTarget(target); 574 575 if (target != NULL) { 576 target->MoveTo(_BorderSize(), _BorderSize()); 577 BRect innerFrame = _InnerFrame(); 578 target->ResizeTo(innerFrame.Width() - 1, innerFrame.Height() - 1); 579 target->TargetedByScrollView(this); 580 581 AddChild(target, ChildAt(0)); 582 // This way, we are making sure that the target will 583 // be added top most in the list (which is important 584 // for unarchiving) 585 } 586 } 587 588 589 BView* 590 BScrollView::Target() const 591 { 592 return fTarget; 593 } 594 595 596 // #pragma mark - 597 598 599 600 BHandler* 601 BScrollView::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier, 602 int32 form, const char* property) 603 { 604 return BView::ResolveSpecifier(msg, index, specifier, form, property); 605 } 606 607 608 status_t 609 BScrollView::GetSupportedSuites(BMessage *data) 610 { 611 return BView::GetSupportedSuites(data); 612 } 613 614 615 status_t 616 BScrollView::Perform(perform_code code, void* _data) 617 { 618 switch (code) { 619 case PERFORM_CODE_MIN_SIZE: 620 ((perform_data_min_size*)_data)->return_value 621 = BScrollView::MinSize(); 622 return B_OK; 623 case PERFORM_CODE_MAX_SIZE: 624 ((perform_data_max_size*)_data)->return_value 625 = BScrollView::MaxSize(); 626 return B_OK; 627 case PERFORM_CODE_PREFERRED_SIZE: 628 ((perform_data_preferred_size*)_data)->return_value 629 = BScrollView::PreferredSize(); 630 return B_OK; 631 case PERFORM_CODE_LAYOUT_ALIGNMENT: 632 ((perform_data_layout_alignment*)_data)->return_value 633 = BScrollView::LayoutAlignment(); 634 return B_OK; 635 case PERFORM_CODE_HAS_HEIGHT_FOR_WIDTH: 636 ((perform_data_has_height_for_width*)_data)->return_value 637 = BScrollView::HasHeightForWidth(); 638 return B_OK; 639 case PERFORM_CODE_GET_HEIGHT_FOR_WIDTH: 640 { 641 perform_data_get_height_for_width* data 642 = (perform_data_get_height_for_width*)_data; 643 BScrollView::GetHeightForWidth(data->width, &data->min, &data->max, 644 &data->preferred); 645 return B_OK; 646 } 647 case PERFORM_CODE_SET_LAYOUT: 648 { 649 perform_data_set_layout* data = (perform_data_set_layout*)_data; 650 BScrollView::SetLayout(data->layout); 651 return B_OK; 652 } 653 case PERFORM_CODE_INVALIDATE_LAYOUT: 654 { 655 perform_data_invalidate_layout* data 656 = (perform_data_invalidate_layout*)_data; 657 BScrollView::InvalidateLayout(data->descendants); 658 return B_OK; 659 } 660 case PERFORM_CODE_DO_LAYOUT: 661 { 662 BScrollView::DoLayout(); 663 return B_OK; 664 } 665 } 666 667 return BView::Perform(code, _data); 668 } 669 670 671 // #pragma mark - 672 673 674 void 675 BScrollView::_Init(bool horizontal, bool vertical) 676 { 677 fHorizontalScrollBar = NULL; 678 fVerticalScrollBar = NULL; 679 fHighlighted = false; 680 681 if (be_control_look != NULL) 682 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 683 684 if (horizontal) { 685 fHorizontalScrollBar = new BScrollBar(BRect(0, 0, 14, 14), "_HSB_", 686 fTarget, 0, 1000, B_HORIZONTAL); 687 AddChild(fHorizontalScrollBar); 688 } 689 690 if (vertical) { 691 fVerticalScrollBar = new BScrollBar(BRect(0, 0, 14, 14), "_VSB_", 692 fTarget, 0, 1000, B_VERTICAL); 693 AddChild(fVerticalScrollBar); 694 } 695 696 BRect targetFrame; 697 if (fTarget) { 698 // layout target and add it 699 fTarget->TargetedByScrollView(this); 700 fTarget->MoveTo(B_ORIGIN); 701 702 if (fBorder != B_NO_BORDER) 703 fTarget->MoveBy(_BorderSize(), _BorderSize()); 704 705 AddChild(fTarget); 706 targetFrame = fTarget->Frame(); 707 } else { 708 // no target specified 709 targetFrame = Bounds(); 710 if (horizontal) 711 targetFrame.bottom -= B_H_SCROLL_BAR_HEIGHT + 1; 712 if (vertical) 713 targetFrame.right -= B_V_SCROLL_BAR_WIDTH + 1; 714 if (fBorder == B_FANCY_BORDER) { 715 targetFrame.bottom--; 716 targetFrame.right--; 717 } 718 } 719 720 _AlignScrollBars(horizontal, vertical, targetFrame); 721 722 fPreviousWidth = uint16(Bounds().Width()); 723 fPreviousHeight = uint16(Bounds().Height()); 724 } 725 726 727 float 728 BScrollView::_BorderSize() const 729 { 730 return _BorderSize(fBorder); 731 } 732 733 734 BRect 735 BScrollView::_InnerFrame() const 736 { 737 BRect frame = Bounds(); 738 739 float borderSize = _BorderSize(); 740 frame.InsetBy(borderSize, borderSize); 741 742 if (fHorizontalScrollBar != NULL) { 743 frame.bottom -= B_H_SCROLL_BAR_HEIGHT; 744 if (borderSize == 0) 745 frame.bottom--; 746 } 747 if (fVerticalScrollBar != NULL) { 748 frame.right -= B_V_SCROLL_BAR_WIDTH; 749 if (borderSize == 0) 750 frame.right--; 751 } 752 753 return frame; 754 } 755 756 757 BSize 758 BScrollView::_ComputeSize(BSize targetSize) const 759 { 760 BRect frame = _ComputeFrame( 761 BRect(0, 0, targetSize.width, targetSize.height)); 762 763 return BSize(frame.Width(), frame.Height()); 764 } 765 766 767 BRect 768 BScrollView::_ComputeFrame(BRect targetRect) const 769 { 770 return _ComputeFrame(targetRect, fHorizontalScrollBar != NULL, 771 fVerticalScrollBar != NULL, fBorder); 772 } 773 774 775 void 776 BScrollView::_AlignScrollBars(bool horizontal, bool vertical, BRect targetFrame) 777 { 778 if (horizontal) { 779 BRect rect = targetFrame; 780 rect.top = rect.bottom + 1; 781 rect.bottom = rect.top + B_H_SCROLL_BAR_HEIGHT; 782 if (fBorder != B_NO_BORDER || vertical) { 783 // extend scrollbar so that it overlaps one pixel with vertical 784 // scrollbar 785 rect.right++; 786 } 787 788 if (fBorder != B_NO_BORDER) { 789 // the scrollbar draws part of the surrounding frame on the left 790 rect.left--; 791 } 792 793 fHorizontalScrollBar->MoveTo(rect.left, rect.top); 794 fHorizontalScrollBar->ResizeTo(rect.Width(), rect.Height()); 795 } 796 797 if (vertical) { 798 BRect rect = targetFrame; 799 rect.left = rect.right + 1; 800 rect.right = rect.left + B_V_SCROLL_BAR_WIDTH; 801 if (fBorder != B_NO_BORDER || horizontal) { 802 // extend scrollbar so that it overlaps one pixel with vertical 803 // scrollbar 804 rect.bottom++; 805 } 806 807 if (fBorder != B_NO_BORDER) { 808 // the scrollbar draws part of the surrounding frame on the left 809 rect.top--; 810 } 811 812 fVerticalScrollBar->MoveTo(rect.left, rect.top); 813 fVerticalScrollBar->ResizeTo(rect.Width(), rect.Height()); 814 } 815 } 816 817 818 /*! This static method is used to calculate the frame that the 819 ScrollView will cover depending on the frame of its target 820 and which border style is used. 821 It is used in the constructor and at other places. 822 */ 823 /*static*/ BRect 824 BScrollView::_ComputeFrame(BRect frame, bool horizontal, bool vertical, 825 border_style border) 826 { 827 if (vertical) 828 frame.right += B_V_SCROLL_BAR_WIDTH; 829 if (horizontal) 830 frame.bottom += B_H_SCROLL_BAR_HEIGHT; 831 832 float borderSize = _BorderSize(border); 833 frame.InsetBy(-borderSize, -borderSize); 834 835 if (borderSize == 0) { 836 if (vertical) 837 frame.right++; 838 if (horizontal) 839 frame.bottom++; 840 } 841 842 return frame; 843 } 844 845 846 /*static*/ BRect 847 BScrollView::_ComputeFrame(BView *target, bool horizontal, bool vertical, 848 border_style border) 849 { 850 return _ComputeFrame(target != NULL ? target->Frame() 851 : BRect(0, 0, 16, 16), horizontal, vertical, border); 852 } 853 854 855 /*! This method returns the size of the specified border. 856 */ 857 /*static*/ float 858 BScrollView::_BorderSize(border_style border) 859 { 860 if (border == B_FANCY_BORDER) 861 return kFancyBorderSize; 862 if (border == B_PLAIN_BORDER) 863 return kPlainBorderSize; 864 865 return 0; 866 } 867 868 869 /*! This method changes the "flags" argument as passed on to 870 the BView constructor. 871 */ 872 /*static*/ int32 873 BScrollView::_ModifyFlags(int32 flags, border_style border) 874 { 875 // We either need B_FULL_UPDATE_ON_RESIZE or 876 // B_FRAME_EVENTS if we have to draw a border 877 if (border != B_NO_BORDER) 878 return flags | B_WILL_DRAW | (flags & B_FULL_UPDATE_ON_RESIZE ? 0 : B_FRAME_EVENTS); 879 880 return flags & ~(B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE); 881 } 882 883 884 // #pragma mark - 885 886 887 BScrollView & 888 BScrollView::operator=(const BScrollView &) 889 { 890 return *this; 891 } 892 893 894 void BScrollView::_ReservedScrollView1() {} 895 void BScrollView::_ReservedScrollView2() {} 896 void BScrollView::_ReservedScrollView3() {} 897 void BScrollView::_ReservedScrollView4() {} 898 899