1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850
|
/** <title>NSClipView</title>
Copyright (C) 1996 Free Software Foundation, Inc.
Author: Ovidiu Predescu <ovidiu@net-community.com>
Date: July 1997
Author: Richard Frith-Macdonald <richard@brainstorm.co.uk>
Date: January 1999
This file is part of the GNUstep GUI Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#import "config.h"
#import <Foundation/NSNotification.h>
#import <Foundation/NSException.h>
#import "AppKit/NSClipView.h"
#import "AppKit/NSCursor.h"
#import "AppKit/NSColor.h"
#import "AppKit/NSEvent.h"
#import "AppKit/NSGraphics.h"
#import "AppKit/NSTableView.h"
#import "AppKit/NSWindow.h"
#import "AppKit/PSOperators.h"
#import <GNUstepGUI/GSNibLoading.h>
#import "GSGuiPrivate.h"
#include <math.h>
@interface NSClipView (Private)
- (void) _scrollToPoint: (NSPoint)aPoint;
@end
/*
* Return the biggest integral (in device space) rect contained in rect.
* Conversion to/from device space is done using view.
*
*/
static inline NSRect integralRect (NSRect rect, NSView *view)
{
NSRect output;
int rounded;
output = [view convertRect: rect toView: nil];
rounded = (int)(output.origin.x);
if ((CGFloat)rounded != output.origin.x)
{
output.origin.x = rounded + 1;
}
rounded = (int)(output.origin.y);
if ((CGFloat)rounded != output.origin.y)
{
output.origin.y = rounded + 1;
}
rounded = (int)(NSMaxX (output));
if ((CGFloat)rounded != NSMaxX (output))
{
output.size.width = rounded - output.origin.x;
}
rounded = (int)(NSMaxY (output));
if ((CGFloat)rounded != NSMaxY (output))
{
output.size.height = rounded - output.origin.y;
}
return [view convertRect: output fromView: nil];
}
/* Note that the ivar _documentView is really just a convienience
variable. The actual document view is stored in NSClipView's
subview array. Deallocation, coding, etc of the view is then
handled by NSView
*/
@implementation NSClipView
- (id) initWithFrame: (NSRect)frameRect
{
self = [super initWithFrame:frameRect];
if (self)
{
[self setAutoresizesSubviews: YES];
[self setBackgroundColor: [NSColor controlBackgroundColor]];
_copiesOnScroll = YES;
_drawsBackground = YES;
}
return self;
}
- (void) dealloc
{
[self setDocumentView: nil];
RELEASE(_cursor);
RELEASE(_backgroundColor);
[super dealloc];
}
/**<p>Sets aView the NSClipView's document view to <var>aView</var>
</p>
<p>See Also: -documentView</p>
*/
- (void) setDocumentView: (NSView*)aView
{
NSNotificationCenter *nc;
NSView *nextKV;
if (_documentView == aView)
{
return;
}
nc = [NSNotificationCenter defaultCenter];
if (_documentView)
{
nextKV = [_documentView nextKeyView];
if ([nextKV isDescendantOf: _documentView])
{
nextKV = nil;
}
[nc removeObserver: self
name: NSViewFrameDidChangeNotification
object: _documentView];
[nc removeObserver: self
name: NSViewBoundsDidChangeNotification
object: _documentView];
/* if our documentView was a tableview, unregister its
* observers
*/
if ([_documentView isKindOfClass: [NSTableView class]])
{
[nc removeObserver: _documentView
name: NSViewFrameDidChangeNotification
object: self];
}
[_documentView removeFromSuperview];
}
else
{
nextKV = [self nextKeyView];
}
/* Don't retain this since it's stored in our subviews. */
_documentView = aView;
/* Update the view hierarchy coordinates if -isFlipped has changed.
Call this before doing anything else! */
[self _invalidateCoordinates];
if (_documentView)
{
NSRect df;
[self addSubview: _documentView];
df = [_documentView frame];
[self setBoundsOrigin: df.origin];
/* Register for notifications sent by the document view */
[_documentView setPostsFrameChangedNotifications: YES];
[_documentView setPostsBoundsChangedNotifications: YES];
[nc addObserver: self
selector: @selector(viewFrameChanged:)
name: NSViewFrameDidChangeNotification
object: _documentView];
[nc addObserver: self
selector: @selector(viewBoundsChanged:)
name: NSViewBoundsDidChangeNotification
object: _documentView];
/*
* if our document view is a tableview, let it know
* when we resize
*/
if ([_documentView isKindOfClass: [NSTableView class]])
{
[self setPostsFrameChangedNotifications: YES];
[nc addObserver: _documentView
selector: @selector(superviewFrameChanged:)
name: NSViewFrameDidChangeNotification
object: self];
}
[self setNextKeyView: _documentView];
if (![_documentView nextKeyView])
[_documentView setNextKeyView: nextKV];
}
else
[self setNextKeyView: nextKV];
[_super_view reflectScrolledClipView: self];
}
- (void) resetCursorRects
{
[self addCursorRect: _bounds cursor: _cursor];
}
- (void) scrollToPoint: (NSPoint)aPoint
{
[self setBoundsOrigin: [self constrainScrollPoint: aPoint]];
[self resetCursorRects];
}
- (void) setBounds: (NSRect)b
{
[super setBounds: b];
[self setNeedsDisplay: YES];
[_super_view reflectScrolledClipView: self];
}
- (void) setBoundsSize: (NSSize)aSize
{
[super setBoundsSize: aSize];
[self setNeedsDisplay: YES];
[_super_view reflectScrolledClipView: self];
}
- (void) setBoundsOrigin: (NSPoint)aPoint
{
NSRect originalBounds = _bounds;
NSRect newBounds = originalBounds;
NSRect intersection;
newBounds.origin = aPoint;
if (NSEqualPoints(originalBounds.origin, newBounds.origin))
{
return;
}
if (_documentView == nil)
{
return;
}
if (_copiesOnScroll && _window && [_window gState])
{
/* Copy the portion of the view that is common before and after
scrolling. Then, document view needs to redraw the remaining
areas. */
/* Common part - which is a first approx of what we could
copy... */
intersection = NSIntersectionRect (originalBounds, newBounds);
/* but we must make sure we only copy from visible rect - we
can't copy bits which have been clipped (ie discarded) */
intersection = NSIntersectionRect (intersection, [self visibleRect]);
/* Copying is done in device space so we only can copy by
integral rects in device space - adjust our copy rect */
intersection = integralRect (intersection, self);
/* At this point, intersection is the rectangle containing the
image we can recycle from the old to the new situation. We
must not make any assumption on its position/size, because it
has been intersected with visible rect, which is an arbitrary
rectangle as far as we know. */
if (NSEqualRects (intersection, NSZeroRect))
{
// no recyclable part -- docview should redraw everything
// from scratch
[super setBoundsOrigin: newBounds.origin];
[_documentView setNeedsDisplayInRect:
[self documentVisibleRect]];
}
else
{
/* It is assumed these dx and dy will be integer in device
space because they are the difference of the bounds
origins, both of which should be integers in device space
because of the code at the end of
constrainScrollPoint:. */
CGFloat dx = newBounds.origin.x - originalBounds.origin.x;
CGFloat dy = newBounds.origin.y - originalBounds.origin.y;
NSRect redrawRect;
/* Copy the intersection to the new position */
[self scrollRect: intersection by: NSMakeSize(-dx, -dy)];
/* Change coordinate system to the new one */
[super setBoundsOrigin: newBounds.origin];
/* Get the rectangle representing intersection in the new
bounds (mainly to keep code readable) */
intersection.origin.x -= dx;
intersection.origin.y -= dy;
// intersection.size is the same
/* Now mark everything which is outside intersection as
needing to be redrawn by hand. NB: During simple usage -
scrolling in a single direction (left/rigth/up/down) -
and a normal visible rect, only one of the following
rects will be non-empty. */
/* To the left of intersection */
redrawRect = NSMakeRect(NSMinX(_bounds), _bounds.origin.y,
NSMinX(intersection) - NSMinX(_bounds),
_bounds.size.height);
if (NSIsEmptyRect(redrawRect) == NO)
{
[_documentView setNeedsDisplayInRect:
[self convertRect: redrawRect
toView: _documentView]];
}
/* Right */
redrawRect = NSMakeRect(NSMaxX(intersection), _bounds.origin.y,
NSMaxX(_bounds) - NSMaxX(intersection),
_bounds.size.height);
if (NSIsEmptyRect(redrawRect) == NO)
{
[_documentView setNeedsDisplayInRect:
[self convertRect: redrawRect
toView: _documentView]];
}
/* Up (or Down according to whether it's flipped or not) */
redrawRect = NSMakeRect(_bounds.origin.x, NSMinY(_bounds),
_bounds.size.width,
NSMinY(intersection) - NSMinY(_bounds));
if (NSIsEmptyRect(redrawRect) == NO)
{
[_documentView setNeedsDisplayInRect:
[self convertRect: redrawRect
toView: _documentView]];
}
/* Down (or Up) */
redrawRect = NSMakeRect(_bounds.origin.x, NSMaxY(intersection),
_bounds.size.width,
NSMaxY(_bounds) - NSMaxY(intersection));
if (NSIsEmptyRect(redrawRect) == NO)
{
[_documentView setNeedsDisplayInRect:
[self convertRect: redrawRect
toView: _documentView]];
}
}
}
else
{
// dont copy anything -- docview draws it all
[super setBoundsOrigin: newBounds.origin];
[_documentView setNeedsDisplayInRect: [self documentVisibleRect]];
}
/* ?? TODO: Understand the following code - and add explanatory comment */
/*if ([NSView focusView] == _documentView)
{
PStranslate (NSMinX (originalBounds) - aPoint.x,
NSMinY (originalBounds) - aPoint.y);
}*/
[_super_view reflectScrolledClipView: self];
}
/**
*<p></p>
*/
- (NSPoint) constrainScrollPoint: (NSPoint)proposedNewOrigin
{
NSRect documentFrame;
NSPoint new = proposedNewOrigin;
if (_documentView == nil)
{
return _bounds.origin;
}
documentFrame = [_documentView frame];
if (documentFrame.size.width <= _bounds.size.width)
{
new.x = documentFrame.origin.x;
}
else if (proposedNewOrigin.x <= documentFrame.origin.x)
{
new.x = documentFrame.origin.x;
}
else if (proposedNewOrigin.x + _bounds.size.width >= NSMaxX(documentFrame))
{
new.x = NSMaxX(documentFrame) - _bounds.size.width;
}
if (documentFrame.size.height <= _bounds.size.height)
{
new.y = documentFrame.origin.y;
}
else if (proposedNewOrigin.y <= documentFrame.origin.y)
{
new.y = documentFrame.origin.y;
}
else if (proposedNewOrigin.y + _bounds.size.height >= NSMaxY(documentFrame))
{
new.y = NSMaxY(documentFrame) - _bounds.size.height;
}
/* Make it an integer coordinate in device space - this is to make
sure that when the coordinates are changed and we need to copy to
do the scrolling, the difference is an integer and so we can copy
the image translating it by an integer in device space - and not
by a float. */
new = [self convertPoint: new toView: nil];
new.x = GSRoundTowardsInfinity(new.x);
new.y = GSRoundTowardsInfinity(new.y);
new = [self convertPoint: new fromView: nil];
return new;
}
/**<p>Returns the document rectangle.</p>
<p>See Also: -documentVisibleRect </p>
*/
- (NSRect) documentRect
{
NSRect documentFrame;
NSRect clipViewBounds;
NSRect rect;
if (_documentView == nil)
{
return _bounds;
}
documentFrame = [_documentView frame];
clipViewBounds = _bounds;
rect.origin = documentFrame.origin;
rect.size.width = MAX(documentFrame.size.width, clipViewBounds.size.width);
rect.size.height = MAX(documentFrame.size.height, clipViewBounds.size.height);
return rect;
}
/**<p>Returns the document visible rectangle in the document views coordinate
* system.
* </p>
* <p>See Also: -documentRect [NSView-convertRect:toView:]</p>
*/
- (NSRect) documentVisibleRect
{
return [self convertRect: _bounds toView:_documentView];
}
- (void) drawRect: (NSRect)rect
{
if (_drawsBackground)
{
[_backgroundColor set];
NSRectFill(rect);
}
}
/**<p>Scrolls in response to mouse-dragged events. </p>
*/
- (BOOL) autoscroll: (NSEvent*)theEvent
{
NSPoint new;
NSPoint delta;
NSRect r;
if (_documentView == nil)
{
return NO;
}
new = [_documentView convertPoint: [theEvent locationInWindow]
fromView: nil];
r = [self documentVisibleRect];
if (new.x < NSMinX(r))
delta.x = new.x - NSMinX(r);
else if (new.x > NSMaxX(r))
delta.x = new.x - NSMaxX(r);
else
delta.x = 0;
if (new.y < NSMinY(r))
delta.y = new.y - NSMinY(r);
else if (new.y > NSMaxY(r))
delta.y = new.y - NSMaxY(r);
else
delta.y = 0;
new.x = _bounds.origin.x + delta.x;
new.y = _bounds.origin.y + delta.y;
new = [self constrainScrollPoint: new];
if (NSEqualPoints(new, _bounds.origin))
return NO;
[self setBoundsOrigin: new];
return YES;
}
- (void) viewBoundsChanged: (NSNotification*)aNotification
{
[_super_view reflectScrolledClipView: self];
}
/**<p>Used when the document view frame notify its change.
( with NSViewFrameDidChangeNotification )</p>
*/
- (void) viewFrameChanged: (NSNotification*)aNotification
{
[self _scrollToPoint: _bounds.origin];
/* If document frame does not completely cover _bounds */
if (NSContainsRect([_documentView frame], _bounds) == NO)
{
/*
* fill the area not covered by documentView with background color
*/
[self setNeedsDisplay: YES];
}
[_super_view reflectScrolledClipView: self];
}
- (void) scaleUnitSquareToSize: (NSSize)newUnitSize
{
[super scaleUnitSquareToSize: newUnitSize];
[_super_view reflectScrolledClipView: self];
}
- (void) setFrameSize: (NSSize)aSize
{
[super setFrameSize: aSize];
[self setBoundsOrigin: [self constrainScrollPoint: _bounds.origin]];
[_super_view reflectScrolledClipView: self];
}
- (void) setFrameOrigin: (NSPoint)aPoint
{
[super setFrameOrigin: aPoint];
[self setBoundsOrigin: [self constrainScrollPoint: _bounds.origin]];
[_super_view reflectScrolledClipView: self];
}
- (void) setFrame: (NSRect)rect
{
[super setFrame: rect];
[self setBoundsOrigin: [self constrainScrollPoint: _bounds.origin]];
[_super_view reflectScrolledClipView: self];
}
- (void) translateOriginToPoint: (NSPoint)aPoint
{
[super translateOriginToPoint: aPoint];
[_super_view reflectScrolledClipView: self];
}
/**
*<p>Returns the NSClipView's document view.</p>
*<p>See Also: -setDocumentView: </p>
*/
- (id) documentView
{
return _documentView;
}
/**
*/
- (void) setCopiesOnScroll: (BOOL)flag
{
_copiesOnScroll = flag;
}
/**
*/
- (BOOL) copiesOnScroll
{
return _copiesOnScroll;
}
/**<p>Sets the cursor for the document view to <var>aCursor</var></p>
<p>See Also: -documentCursor</p>
*/
- (void) setDocumentCursor: (NSCursor*)aCursor
{
ASSIGN(_cursor, aCursor);
}
/**<p>Returns the cursor of the document view</p>
<p>See Also: -setDocumentCursor: </p>
*/
- (NSCursor*) documentCursor
{
return _cursor;
}
/**<p>Returns the NSClipView's background color</p>
<p>See Also: -setBackgroundColor:</p>
*/
- (NSColor*) backgroundColor
{
return _backgroundColor;
}
/**<p>Sets the NSClipView's background color to <var>aColor</var> and marks
self for display. Sets the opaque flag if needed ( to YES if the
NSClipView does not draw its background, if the background color
is nil or if the background color alpha component is less than 1.0 , NO
otherwise) </p>
<p>See Also: -backgroundColor [NSView-isOpaque]</p>
*/
- (void) setBackgroundColor: (NSColor*)aColor
{
if (![_backgroundColor isEqual: aColor])
{
ASSIGN (_backgroundColor, aColor);
[self setNeedsDisplay: YES];
if (_drawsBackground == NO || _backgroundColor == nil
|| [_backgroundColor alphaComponent] < 1.0)
{
_isOpaque = NO;
}
else
{
_isOpaque = YES;
}
}
}
- (void) setDrawsBackground: (BOOL)flag
{
if (_drawsBackground != flag)
{
_drawsBackground = flag;
[self setNeedsDisplay: YES];
if (_drawsBackground == NO || _backgroundColor == nil
|| [_backgroundColor alphaComponent] < 1.0)
{
_isOpaque = NO;
}
else
{
_isOpaque = YES;
}
}
}
- (BOOL) drawsBackground
{
return _drawsBackground;
}
- (BOOL) isOpaque
{
return _isOpaque;
}
- (BOOL) isFlipped
{
return (_documentView != nil) ? [_documentView isFlipped] : NO;
}
/* Disable rotation of clip view */
- (void) rotateByAngle: (CGFloat)angle
{
}
- (void) setBoundsRotation: (CGFloat)angle
{
}
- (void) setFrameRotation: (CGFloat)angle
{
}
/* Managing responder chain */
- (BOOL) acceptsFirstResponder
{
if (_documentView == nil)
{
return NO;
}
else
{
return [_documentView acceptsFirstResponder];
}
}
- (BOOL) becomeFirstResponder
{
if (_documentView == nil)
{
return NO;
}
else
{
return [_window makeFirstResponder: _documentView];
}
}
- (void) setNextKeyView: (NSView *)aView
{
if (_documentView && aView != _documentView)
[_documentView setNextKeyView: aView];
else
[super setNextKeyView: aView];
}
/*
* NSCoding protocol
*/
- (void) encodeWithCoder: (NSCoder*)aCoder
{
[super encodeWithCoder: aCoder];
if ([aCoder allowsKeyedCoding])
{
unsigned int flags = 0;
[aCoder encodeObject: [self backgroundColor] forKey: @"NSBGColor"];
[aCoder encodeObject: [self documentCursor] forKey: @"NSCursor"];
[aCoder encodeObject: [self documentView] forKey: @"NSDocView"];
if ([self drawsBackground])
flags |= 4;
if ([self copiesOnScroll] == NO)
flags |= 2;
[aCoder encodeInt: flags forKey: @"NScvFlags"];
}
else
{
[aCoder encodeObject: _backgroundColor];
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &_copiesOnScroll];
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &_drawsBackground];
[aCoder encodeObject: _cursor];
}
}
- (id) initWithCoder: (NSCoder*)aDecoder
{
self = [super initWithCoder: aDecoder];
if (self == nil)
{
return nil;
}
if ([aDecoder allowsKeyedCoding])
{
[self setAutoresizesSubviews: YES];
[self setBackgroundColor: [aDecoder decodeObjectForKey: @"NSBGColor"]];
[self setDocumentCursor: [aDecoder decodeObjectForKey: @"NSCursor"]];
if ([aDecoder containsValueForKey: @"NScvFlags"])
{
int flags = [aDecoder decodeIntForKey: @"NScvFlags"];
BOOL drawsBackground = ((4 & flags) > 0);
BOOL noCopyOnScroll = ((2 & flags) > 0); // ??? Not sure...
[self setCopiesOnScroll: (noCopyOnScroll == NO)];
[self setDrawsBackground: drawsBackground];
}
if ([[self subviews] count] > 0)
{
NSRect rect;
id document = [aDecoder decodeObjectForKey: @"NSDocView"];
NSAssert([document class] != [NSCustomView class],
NSInvalidArgumentException);
rect = [document frame];
rect.origin = NSZeroPoint;
[document setFrame: rect];
RETAIN(document); // prevent it from being released.
[document removeFromSuperview];
[self setDocumentView: document];
RELEASE(document);
}
}
else
{
BOOL temp;
[self setAutoresizesSubviews: YES];
[self setBackgroundColor: [aDecoder decodeObject]];
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_copiesOnScroll];
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &temp];
[self setDrawsBackground: temp];
[aDecoder decodeValueOfObjCType: @encode(id) at: &_cursor];
if ([[self subviews] count] > 0)
{
NSView *document = [[self subviews] objectAtIndex: 0];
RETAIN(document); // prevent it from being released.
[document removeFromSuperview];
[self setDocumentView: document];
RELEASE(document);
}
}
return self;
}
@end
@implementation NSClipView (Private)
- (void) _scrollToPoint: (NSPoint)aPoint
{
NSRect proposedBounds;
NSRect proposedVisibleRect;
NSRect newVisibleRect;
NSRect newBounds;
// give documentView a chance to adjust its visible rectangle
proposedBounds = _bounds;
proposedBounds.origin = aPoint;
proposedVisibleRect = [self convertRect: proposedBounds
toView: _documentView];
newVisibleRect = [_documentView adjustScroll: proposedVisibleRect];
newBounds = [self convertRect: newVisibleRect fromView: _documentView];
[self scrollToPoint: newBounds.origin];
}
@end
|