1997-08-05 21:50:10 +00:00
|
|
|
/*
|
1996-05-30 20:03:15 +00:00
|
|
|
NSClipView.m
|
|
|
|
|
|
|
|
Copyright (C) 1996 Free Software Foundation, Inc.
|
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
Author: Ovidiu Predescu <ovidiu@net-community.com>
|
|
|
|
Date: July 1997
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
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 Library 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
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public
|
1997-08-05 21:50:10 +00:00
|
|
|
License along with this library; if not, write to the Free
|
|
|
|
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <Foundation/NSNotification.h>
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1997-02-18 00:29:25 +00:00
|
|
|
#include <AppKit/NSClipView.h>
|
1997-08-05 21:50:10 +00:00
|
|
|
#include <AppKit/NSCursor.h>
|
|
|
|
#include <AppKit/NSColor.h>
|
|
|
|
#include <AppKit/NSWindow.h>
|
|
|
|
#include <AppKit/NSGraphics.h>
|
|
|
|
|
|
|
|
#define ASSIGN(a, b) \
|
|
|
|
[b retain]; \
|
|
|
|
[a release]; \
|
|
|
|
a = b;
|
|
|
|
|
|
|
|
#ifdef MIN
|
|
|
|
# undef MIN
|
|
|
|
#endif
|
|
|
|
#define MIN(a, b) \
|
|
|
|
({typedef _ta = (a), _tb = (b); \
|
|
|
|
_ta _a = (a); _tb _b = (b); \
|
|
|
|
_a < _b ? _a : _b; })
|
|
|
|
|
|
|
|
#ifdef MAX
|
|
|
|
# undef MAX
|
|
|
|
#endif
|
|
|
|
#define MAX(a, b) \
|
|
|
|
({typedef _ta = (a), _tb = (b); \
|
|
|
|
_ta _a = (a); _tb _b = (b); \
|
|
|
|
_a > _b ? _a : _b; })
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
@implementation NSClipView
|
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
- init
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1997-08-05 21:50:10 +00:00
|
|
|
[super init];
|
|
|
|
[self setAutoresizesSubviews:YES];
|
|
|
|
[self setBackgroundColor:[[self window] backgroundColor]];
|
|
|
|
return self;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
- (void)setDocumentView:(NSView*)aView
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1997-08-05 21:50:10 +00:00
|
|
|
if (_documentView)
|
|
|
|
[_documentView removeFromSuperview];
|
|
|
|
|
|
|
|
ASSIGN(_documentView, aView);
|
|
|
|
[self addSubview:_documentView];
|
|
|
|
|
|
|
|
/* Register to notifications sent by the document view */
|
|
|
|
[_documentView setPostsFrameChangedNotifications:YES];
|
|
|
|
[_documentView setPostsBoundsChangedNotifications:YES];
|
|
|
|
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
|
|
selector:@selector(viewFrameChanged:)
|
|
|
|
name:NSViewFrameDidChangeNotification object:_documentView];
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
|
|
selector:@selector(viewBoundsChanged:)
|
|
|
|
name:NSViewBoundsDidChangeNotification object:_documentView];
|
|
|
|
|
|
|
|
/* TODO: invoke superview's reflectScrolledClipView:? */
|
|
|
|
[[self superview] reflectScrolledClipView:self];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
- (void)resetCursorRects
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1997-08-05 21:50:10 +00:00
|
|
|
[self addCursorRect:[self bounds] cursor:_cursor];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
- (void)scrollToPoint:(NSPoint)point
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1997-08-05 21:50:10 +00:00
|
|
|
NSPoint currentPoint = [self bounds].origin;
|
|
|
|
|
1997-08-06 20:29:07 +00:00
|
|
|
NSDebugLog (@"scrollToPoint: current point (%f, %f), point (%f, %f)",
|
1997-08-05 21:50:10 +00:00
|
|
|
currentPoint.x, currentPoint.y,
|
|
|
|
point.x, point.y);
|
|
|
|
|
|
|
|
point = [self constrainScrollPoint:point];
|
|
|
|
[super setBoundsOrigin:point];
|
|
|
|
if (_copiesOnScroll)
|
|
|
|
/* TODO: move the visible portion of the document */;
|
|
|
|
else {
|
|
|
|
NSPoint frameOrigin = [_documentView frame].origin;
|
|
|
|
NSPoint newFrameOrigin;
|
|
|
|
|
|
|
|
newFrameOrigin.x = frameOrigin.x - (point.x - currentPoint.x);
|
|
|
|
newFrameOrigin.y = frameOrigin.y - (point.y - currentPoint.y);
|
|
|
|
[_documentView setPostsFrameChangedNotifications:NO];
|
|
|
|
[_documentView setFrameOrigin:newFrameOrigin];
|
|
|
|
[_documentView setPostsFrameChangedNotifications:YES];
|
|
|
|
[self display];
|
|
|
|
[[self window] flushWindow];
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
- (NSPoint)constrainScrollPoint:(NSPoint)proposedNewOrigin
|
|
|
|
{
|
|
|
|
NSRect documentFrame = [self documentRect];
|
|
|
|
NSPoint new = proposedNewOrigin;
|
|
|
|
|
|
|
|
if (proposedNewOrigin.x < documentFrame.origin.x)
|
|
|
|
new.x = documentFrame.origin.x;
|
|
|
|
else if (proposedNewOrigin.x
|
|
|
|
> documentFrame.size.width - bounds.size.width)
|
|
|
|
new.x = documentFrame.size.width - bounds.size.width;
|
|
|
|
|
|
|
|
if (proposedNewOrigin.y < documentFrame.origin.y)
|
|
|
|
new.y = documentFrame.origin.y;
|
|
|
|
else if (proposedNewOrigin.y
|
|
|
|
> documentFrame.size.height - bounds.size.height)
|
|
|
|
new.y = documentFrame.size.height - bounds.size.height;
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
- (NSRect)documentRect
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1997-08-05 21:50:10 +00:00
|
|
|
NSRect documentFrame = [_documentView frame];
|
|
|
|
NSRect clipViewBounds = [self bounds];
|
|
|
|
NSRect rect;
|
|
|
|
|
|
|
|
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;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
- (NSRect)documentVisibleRect
|
|
|
|
{
|
|
|
|
NSRect documentBounds = [_documentView bounds];
|
|
|
|
NSRect clipViewBounds = [self bounds];
|
|
|
|
NSRect rect;
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
rect.origin = clipViewBounds.origin;
|
|
|
|
rect.size.width = MIN(documentBounds.size.width, clipViewBounds.size.width);
|
|
|
|
rect.size.height = MIN(documentBounds.size.height,
|
|
|
|
clipViewBounds.size.height);
|
|
|
|
|
|
|
|
return rect;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)autoscroll:(NSEvent*)theEvent
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1997-08-05 21:50:10 +00:00
|
|
|
return 0;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
- (void)viewBoundsChanged:(NSNotification*)aNotification
|
|
|
|
{
|
|
|
|
[[self superview] reflectScrolledClipView:self];
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
- (void)viewFrameChanged:(NSNotification*)aNotification
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1997-08-05 21:50:10 +00:00
|
|
|
[[self superview] reflectScrolledClipView:self];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
- (void)scaleUnitSquareToSize:(NSSize)newUnitSize
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1997-08-05 21:50:10 +00:00
|
|
|
[super scaleUnitSquareToSize:newUnitSize];
|
|
|
|
[[self superview] reflectScrolledClipView:self];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
- (void)setBoundsOrigin:(NSPoint)aPoint
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1997-08-05 21:50:10 +00:00
|
|
|
[super setBoundsOrigin:aPoint];
|
|
|
|
[[self superview] reflectScrolledClipView:self];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
- (void)setBoundsSize:(NSSize)aSize
|
|
|
|
{
|
|
|
|
[super setBoundsSize:aSize];
|
|
|
|
[[self superview] reflectScrolledClipView:self];
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
- (void)setFrameSize:(NSSize)aSize
|
|
|
|
{
|
|
|
|
[super setFrameSize:aSize];
|
|
|
|
[[self superview] reflectScrolledClipView:self];
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
- (void)setFrameOrigin:(NSPoint)aPoint
|
|
|
|
{
|
|
|
|
[super setFrameOrigin:aPoint];
|
|
|
|
[[self superview] reflectScrolledClipView:self];
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
- (void)setFrame:(NSRect)rect
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1997-08-05 21:50:10 +00:00
|
|
|
[super setFrame:rect];
|
|
|
|
[[self superview] reflectScrolledClipView:self];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
- (void)translateOriginToPoint:(NSPoint)aPoint
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1997-08-05 21:50:10 +00:00
|
|
|
[super translateOriginToPoint:aPoint];
|
|
|
|
[[self superview] reflectScrolledClipView:self];
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1997-08-05 21:50:10 +00:00
|
|
|
- (id)documentView { return _documentView; }
|
|
|
|
- (void)setCopiesOnScroll:(BOOL)flag { _copiesOnScroll = flag; }
|
|
|
|
- (BOOL)copiesOnScroll { return _copiesOnScroll; }
|
|
|
|
- (void)setDocumentCursor:(NSCursor*)aCursor { ASSIGN(_cursor, aCursor); }
|
|
|
|
- (NSCursor*)documentCursor { return _cursor; }
|
|
|
|
- (NSColor*)backgroundColor { return _backgroundColor; }
|
|
|
|
- (BOOL)isFlipped { return [_documentView isFlipped]; }
|
|
|
|
- (BOOL)acceptsFirstResponder { return _documentView != nil; }
|
|
|
|
|
|
|
|
- (void)setBackgroundColor:(NSColor*)aColor
|
|
|
|
{
|
|
|
|
ASSIGN(_backgroundColor, aColor);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Disable rotation of clip view */
|
|
|
|
- (void)rotateByAngle:(float)angle
|
|
|
|
{}
|
|
|
|
|
|
|
|
- (void)setBoundsRotation:(float)angle
|
|
|
|
{}
|
|
|
|
|
|
|
|
- (void)setFrameRotation:(float)angle
|
|
|
|
{}
|
|
|
|
|
|
|
|
/* Managing responder chain */
|
|
|
|
- (BOOL)becomeFirstResponder
|
|
|
|
{
|
|
|
|
return [_documentView becomeFirstResponder];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@end
|