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