mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-30 14:00:37 +00:00
The first implementation of scroll views.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@2370 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
03d0b58c1f
commit
e6f636ee30
17 changed files with 1513 additions and 1038 deletions
|
@ -1,12 +1,10 @@
|
|||
/*
|
||||
/*
|
||||
NSScrollView.m
|
||||
|
||||
Description...
|
||||
|
||||
Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
|
||||
Author: Scott Christley <scottc@net-community.com>
|
||||
Date: 1996
|
||||
Author: Ovidiu Predescu <ovidiu@net-community.com>
|
||||
Date: July 1997
|
||||
|
||||
This file is part of the GNUstep GUI Library.
|
||||
|
||||
|
@ -21,187 +19,418 @@
|
|||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; see the file COPYING.LIB.
|
||||
If not, write to the Free Software Foundation,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <AppKit/NSScroller.h>
|
||||
#include <AppKit/NSClipView.h>
|
||||
#include <AppKit/NSScrollView.h>
|
||||
|
||||
#define ASSIGN(a, b) \
|
||||
[b retain]; \
|
||||
[a release]; \
|
||||
a = b;
|
||||
|
||||
@implementation NSScrollView
|
||||
|
||||
//
|
||||
// Class methods
|
||||
//
|
||||
static Class rulerViewClass = nil;
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
if (self == [NSScrollView class])
|
||||
{
|
||||
// Initial version
|
||||
[self setVersion:1];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Laying Out the NSScrollView
|
||||
//
|
||||
+ (NSSize)contentSizeForFrameSize:(NSSize)size
|
||||
hasHorizontalScroller:(BOOL)horizFlag
|
||||
hasVerticalScroller:(BOOL)vertFlag
|
||||
borderType:(NSBorderType)aType
|
||||
+ (void)setRulerViewClass:(Class)aClass
|
||||
{
|
||||
return NSZeroSize;
|
||||
rulerViewClass = aClass;
|
||||
}
|
||||
|
||||
+ (NSSize)frameSizeForContentSize:(NSSize)size
|
||||
hasHorizontalScroller:(BOOL)horizFlag
|
||||
hasVerticalScroller:(BOOL)vertFlag
|
||||
borderType:(NSBorderType)aType
|
||||
+ (Class)rulerViewClass
|
||||
{
|
||||
return NSZeroSize;
|
||||
return rulerViewClass;
|
||||
}
|
||||
|
||||
//
|
||||
// Instance methods
|
||||
//
|
||||
//
|
||||
// Determining Component Sizes
|
||||
//
|
||||
- (NSSize)contentSize
|
||||
/* Backends should rewrite the following 2 methods and adjust the frames
|
||||
depending on the border type. */
|
||||
|
||||
+ (NSSize)contentSizeForFrameSize:(NSSize)frameSize
|
||||
hasHorizontalScroller:(BOOL)hFlag
|
||||
hasVerticalScroller:(BOOL)vFlag
|
||||
borderType:(NSBorderType)borderType
|
||||
{
|
||||
return NSZeroSize;
|
||||
NSSize size = frameSize;
|
||||
|
||||
if (hFlag)
|
||||
size.height -= [NSScroller scrollerWidth];
|
||||
if (vFlag)
|
||||
size.width -= [NSScroller scrollerWidth];
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
- (NSRect)documentVisibleRect
|
||||
+ (NSSize)frameSizeForContentSize:(NSSize)contentSize
|
||||
hasHorizontalScroller:(BOOL)hFlag
|
||||
hasVerticalScroller:(BOOL)vFlag
|
||||
borderType:(NSBorderType)borderType
|
||||
{
|
||||
return NSZeroRect;
|
||||
NSSize size = contentSize;
|
||||
|
||||
if (hFlag)
|
||||
size.height += [NSScroller scrollerWidth];
|
||||
if (vFlag)
|
||||
size.width += [NSScroller scrollerWidth];
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
//
|
||||
// Laying Out the NSScrollView
|
||||
//
|
||||
- (void)setHasHorizontalScroller:(BOOL)flag
|
||||
{}
|
||||
|
||||
- (BOOL)hasHorizontalScroller
|
||||
- initWithFrame:(NSRect)rect
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)setHasVerticalScroller:(BOOL)flag
|
||||
{}
|
||||
|
||||
- (BOOL)hasVerticalScroller
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)tile
|
||||
{}
|
||||
|
||||
- (void)toggleRuler:(id)sender
|
||||
{}
|
||||
|
||||
- (BOOL)isRulerVisible
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
//
|
||||
// Managing Component Views
|
||||
//
|
||||
- (void)setDocumentView:(NSView *)aView
|
||||
{}
|
||||
|
||||
- (id)documentView
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)setHorizontalScroller:(NSScroller *)anObject
|
||||
{}
|
||||
|
||||
- (NSScroller *)horizontalScroller
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)setVerticalScroller:(NSScroller *)anObject
|
||||
{}
|
||||
|
||||
- (NSScroller *)verticalScroller
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)reflectScrolledClipView:(NSClipView *)cView
|
||||
{}
|
||||
|
||||
//
|
||||
// Modifying Graphic Attributes
|
||||
//
|
||||
- (void)setBorderType:(NSBorderType)aType
|
||||
{}
|
||||
|
||||
- (NSBorderType)borderType
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (void)setBackgroundColor:(NSColor *)color
|
||||
{}
|
||||
|
||||
- (NSColor *)backgroundColor
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
//
|
||||
// Setting Scrolling Behavior
|
||||
//
|
||||
- (float)lineScroll
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
- (float)pageScroll
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
- (void)setScrollsDynamically:(BOOL)flag
|
||||
{}
|
||||
|
||||
- (BOOL)scrollsDynamically
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)setLineScroll:(float)value
|
||||
{}
|
||||
|
||||
- (void)setPageScroll:(float)value
|
||||
{}
|
||||
|
||||
//
|
||||
// Managing the Cursor
|
||||
//
|
||||
- (void)setDocumentCursor:(NSCursor *)anObject
|
||||
{}
|
||||
|
||||
//
|
||||
// NSCoding protocol
|
||||
//
|
||||
- (void)encodeWithCoder:aCoder
|
||||
{
|
||||
[super encodeWithCoder:aCoder];
|
||||
}
|
||||
|
||||
- initWithCoder:aDecoder
|
||||
{
|
||||
[super initWithCoder:aDecoder];
|
||||
[super initWithFrame:rect];
|
||||
[self setContentView:[[NSClipView new] autorelease]];
|
||||
_lineScroll = 10;
|
||||
_pageScroll = 10;
|
||||
_borderType = NSBezelBorder;
|
||||
_scrollsDynamically = YES;
|
||||
[self tile];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- init
|
||||
{
|
||||
return [self initWithFrame:NSZeroRect];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_contentView release];
|
||||
|
||||
[_horizScroller release];
|
||||
[_vertScroller release];
|
||||
[_horizRuler release];
|
||||
[_vertRuler release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)setContentView:(NSClipView*)aView
|
||||
{
|
||||
ASSIGN(_contentView, aView);
|
||||
[self addSubview:_contentView];
|
||||
[self tile];
|
||||
}
|
||||
|
||||
- (void)setHorizontalScroller:(NSScroller*)aScroller
|
||||
{
|
||||
[_horizScroller removeFromSuperview];
|
||||
|
||||
/* Do not add the scroller view to the subviews array yet; the user has to
|
||||
explicitly invoke -setHasHorizontalScroller:. */
|
||||
|
||||
ASSIGN(_horizScroller, aScroller);
|
||||
if (_horizScroller) {
|
||||
[_horizScroller setTarget:self];
|
||||
[_horizScroller setAction:@selector(_doScroll:)];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setHasHorizontalScroller:(BOOL)flag
|
||||
{
|
||||
if (_hasHorizScroller == flag)
|
||||
return;
|
||||
|
||||
_hasHorizScroller = flag;
|
||||
|
||||
if (_hasHorizScroller) {
|
||||
if (!_horizScroller)
|
||||
[self setHorizontalScroller:[[NSScroller new] autorelease]];
|
||||
[self addSubview:_horizScroller];
|
||||
}
|
||||
else
|
||||
[_horizScroller removeFromSuperview];
|
||||
|
||||
[self tile];
|
||||
}
|
||||
|
||||
- (void)setVerticalScroller:(NSScroller*)aScroller
|
||||
{
|
||||
[_vertScroller removeFromSuperview];
|
||||
|
||||
/* Do not add the scroller view to the subviews array yet; the user has to
|
||||
explicitly invoke -setHasVerticalScroller:. */
|
||||
|
||||
ASSIGN(_vertScroller, aScroller);
|
||||
if (_vertScroller) {
|
||||
[_vertScroller setTarget:self];
|
||||
[_vertScroller setAction:@selector(_doScroll:)];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setHasVerticalScroller:(BOOL)flag
|
||||
{
|
||||
if (_hasVertScroller == flag)
|
||||
return;
|
||||
|
||||
_hasVertScroller = flag;
|
||||
|
||||
if (_hasVertScroller) {
|
||||
if (!_vertScroller) {
|
||||
[self setVerticalScroller:[[NSScroller new] autorelease]];
|
||||
if (_contentView && ![_contentView isFlipped])
|
||||
[_vertScroller setFloatValue:1];
|
||||
}
|
||||
[self addSubview:_vertScroller];
|
||||
}
|
||||
else
|
||||
[_vertScroller removeFromSuperview];
|
||||
|
||||
[self tile];
|
||||
}
|
||||
|
||||
- (void)_doScroll:(NSScroller*)scroller
|
||||
{
|
||||
float floatValue = [scroller floatValue];
|
||||
NSRect clipViewBounds = [_contentView bounds];
|
||||
NSScrollerPart hitPart = [scroller hitPart];
|
||||
NSRect documentRect = [_contentView documentRect];
|
||||
float amount = 0;
|
||||
NSPoint point;
|
||||
BOOL wasAScrollerButton = YES;
|
||||
|
||||
NSLog (@"_doScroll: float value = %f", floatValue);
|
||||
|
||||
if (hitPart == NSScrollerIncrementLine)
|
||||
amount = _lineScroll;
|
||||
else if (hitPart == NSScrollerIncrementPage)
|
||||
amount = _pageScroll;
|
||||
else if (hitPart == NSScrollerDecrementLine)
|
||||
amount = -_lineScroll;
|
||||
else if (hitPart == NSScrollerDecrementPage)
|
||||
amount = -_pageScroll;
|
||||
else
|
||||
wasAScrollerButton = NO;
|
||||
|
||||
if (wasAScrollerButton) {
|
||||
if (scroller == _horizScroller) {
|
||||
point.x = clipViewBounds.origin.x + amount;
|
||||
point.y = clipViewBounds.origin.y;
|
||||
}
|
||||
else if (scroller == _vertScroller) {
|
||||
point.x = clipViewBounds.origin.x;
|
||||
/* For the vertical scroller the amount should actually be reversed */
|
||||
amount = -amount;
|
||||
|
||||
/* If the view is flipped we also have to reverse the meanings of
|
||||
increasing or decreasing of the y coordinate */
|
||||
if (![_contentView isFlipped])
|
||||
amount = -amount;
|
||||
|
||||
NSLog (@"increment/decrement: amount = %f, flipped = %d",
|
||||
amount, [_contentView isFlipped]);
|
||||
point.y = clipViewBounds.origin.y + amount;
|
||||
}
|
||||
else {
|
||||
/* do nothing */
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (scroller == _horizScroller) {
|
||||
point.x = floatValue * (documentRect.size.width
|
||||
- clipViewBounds.size.width);
|
||||
point.y = clipViewBounds.origin.y;
|
||||
}
|
||||
else if (scroller == _vertScroller) {
|
||||
point.x = clipViewBounds.origin.x;
|
||||
if (![_contentView isFlipped])
|
||||
floatValue = 1 - floatValue;
|
||||
point.y = floatValue * (documentRect.size.height
|
||||
- clipViewBounds.size.height);
|
||||
}
|
||||
else {
|
||||
/* do nothing */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
[_contentView scrollToPoint:point];
|
||||
|
||||
/* Update the scroller knob if the scroll occurred due to a
|
||||
scroller button. */
|
||||
if (wasAScrollerButton) {
|
||||
NSRect newClipViewBounds = [_contentView bounds];
|
||||
|
||||
if (newClipViewBounds.origin.x != clipViewBounds.origin.x) {
|
||||
/* Update the horizontal scroller */
|
||||
floatValue = newClipViewBounds.origin.x
|
||||
/ (documentRect.size.width - newClipViewBounds.size.width);
|
||||
[_horizScroller setFloatValue:floatValue];
|
||||
[_horizScroller display];
|
||||
NSLog (@"new horiz float value %f", floatValue);
|
||||
}
|
||||
|
||||
if (newClipViewBounds.origin.x != clipViewBounds.origin.y) {
|
||||
/* Update the vertical scroller */
|
||||
floatValue = newClipViewBounds.origin.y
|
||||
/ (documentRect.size.height - newClipViewBounds.size.height);
|
||||
/* Take care if the document view is not flipped by reversing the meaning
|
||||
of the float value. */
|
||||
if (![_contentView isFlipped])
|
||||
floatValue = 1 - floatValue;
|
||||
[_vertScroller setFloatValue:floatValue];
|
||||
[_vertScroller display];
|
||||
NSLog (@"new vert float value %f", floatValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)reflectScrolledClipView:(NSClipView*)aClipView
|
||||
{
|
||||
NSRect documentRect = [_contentView documentRect];
|
||||
NSRect clipViewBounds = [_contentView bounds];
|
||||
float floatValue;
|
||||
float knobProportion;
|
||||
|
||||
NSLog (@"reflectScrolledClipView:");
|
||||
|
||||
if (_hasVertScroller) {
|
||||
if (documentRect.size.height < clipViewBounds.size.height)
|
||||
[_vertScroller setEnabled:NO];
|
||||
else {
|
||||
[_vertScroller setEnabled:YES];
|
||||
knobProportion = clipViewBounds.size.height / documentRect.size.height;
|
||||
floatValue = clipViewBounds.origin.y / clipViewBounds.size.height;
|
||||
if (![_contentView isFlipped])
|
||||
floatValue = 1 - floatValue;
|
||||
[_vertScroller setFloatValue:floatValue knobProportion:knobProportion];
|
||||
}
|
||||
}
|
||||
|
||||
if (_hasHorizScroller) {
|
||||
if (documentRect.size.width < clipViewBounds.size.width)
|
||||
[_horizScroller setEnabled:NO];
|
||||
else {
|
||||
[_horizScroller setEnabled:YES];
|
||||
knobProportion = clipViewBounds.size.width / documentRect.size.width;
|
||||
floatValue = clipViewBounds.origin.x / clipViewBounds.size.width;
|
||||
[_horizScroller setFloatValue:floatValue knobProportion:knobProportion];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setHorizontalRulerView:(NSRulerView*)aRulerView
|
||||
{
|
||||
/* TODO */
|
||||
ASSIGN(_horizRuler, aRulerView);
|
||||
}
|
||||
|
||||
- (void)setHasHorizontalRuler:(BOOL)flag
|
||||
{
|
||||
/* TODO */
|
||||
if (_hasHorizRuler == flag)
|
||||
return;
|
||||
|
||||
_hasHorizRuler = flag;
|
||||
}
|
||||
|
||||
- (void)setVerticalRulerView:(NSRulerView*)ruler
|
||||
{
|
||||
/* TODO */
|
||||
ASSIGN(_vertRuler, ruler);
|
||||
}
|
||||
|
||||
- (void)setHasVerticalRuler:(BOOL)flag
|
||||
{
|
||||
/* TODO */
|
||||
if (_hasVertRuler == flag)
|
||||
return;
|
||||
|
||||
_hasVertRuler = flag;
|
||||
}
|
||||
|
||||
- (void)setRulersVisible:(BOOL)flag
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
- (void)setFrame:(NSRect)rect
|
||||
{
|
||||
[super setFrame:rect];
|
||||
[self tile];
|
||||
}
|
||||
|
||||
- (void)setFrameSize:(NSSize)size
|
||||
{
|
||||
[super setFrameSize:size];
|
||||
[self tile];
|
||||
}
|
||||
|
||||
/* This method should be implemented in the backend to position the scroll
|
||||
view's interface elements */
|
||||
- (void)tile
|
||||
{
|
||||
}
|
||||
|
||||
- (NSRect)documentVisibleRect
|
||||
{
|
||||
return [_contentView documentVisibleRect];
|
||||
}
|
||||
|
||||
- (void)setBackgroundColor:(NSColor*)aColor
|
||||
{
|
||||
[_contentView setBackgroundColor:aColor];
|
||||
}
|
||||
|
||||
- (NSColor*)backgroundColor
|
||||
{
|
||||
return [_contentView backgroundColor];
|
||||
}
|
||||
|
||||
- (void)setBorderType:(NSBorderType)borderType
|
||||
{
|
||||
_borderType = borderType;
|
||||
}
|
||||
|
||||
- (void)setDocumentView:(NSView*)aView
|
||||
{
|
||||
[_contentView setDocumentView:aView];
|
||||
if (_contentView && ![_contentView isFlipped])
|
||||
[_vertScroller setFloatValue:1];
|
||||
[self tile];
|
||||
}
|
||||
|
||||
- (id)documentView
|
||||
{
|
||||
return [_contentView documentView];
|
||||
}
|
||||
|
||||
- (void)setDocumentCursor:(NSCursor*)aCursor
|
||||
{
|
||||
[_contentView setDocumentCursor:aCursor];
|
||||
}
|
||||
|
||||
- (NSCursor*)documentCursor
|
||||
{
|
||||
return [_contentView documentCursor];
|
||||
}
|
||||
|
||||
- (NSBorderType)borderType { return _borderType; }
|
||||
- (NSScroller*)verticalScroller { return _vertScroller; }
|
||||
- (BOOL)hasVerticalScroller { return _hasVertScroller; }
|
||||
- (BOOL)hasHorizontalRuler { return _hasHorizRuler; }
|
||||
- (NSSize)contentSize { return [_contentView bounds].size; }
|
||||
- (NSClipView*)contentView { return _contentView; }
|
||||
- (NSRulerView*)horizontalRulerView { return _horizRuler; }
|
||||
- (BOOL)hasVerticalRuler { return _hasVertRuler; }
|
||||
- (NSRulerView*)verticalRulerView { return _vertRuler; }
|
||||
- (BOOL)rulersVisible { return _rulersVisible; }
|
||||
- (void)setLineScroll:(float)aFloat { _lineScroll = aFloat; }
|
||||
- (float)lineScroll { return _lineScroll; }
|
||||
- (void)setPageScroll:(float)aFloat { _pageScroll = aFloat; }
|
||||
- (float)pageScroll { return _pageScroll; }
|
||||
- (void)setScrollsDynamically:(BOOL)flag { _scrollsDynamically = flag; }
|
||||
- (BOOL)scrollsDynamically { return _scrollsDynamically; }
|
||||
- (NSScroller*)horizontalScroller { return _horizScroller; }
|
||||
- (BOOL)hasHorizontalScroller { return _hasHorizScroller; }
|
||||
|
||||
@end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue