diff --git a/ChangeLog b/ChangeLog index cede733b7..447ecd813 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,36 @@ +Thu Oct 30 15:51:43 1997 Scott Christley + + * GNUmakefile: Add Tools directory. + * Headers/gnustep/gui/NSBrowser.h: Initial implementation. + * Headers/gnustep/gui/NSBrowserCell.h: Initial implementation. + * Source/NSBrowser.m: Initial implementation. + * Source/NSBrowserCell.m: Initial implementation. + * Documentation/news.tmpl.texi: Update. + * Documentation/status.tmpl.texi: Update. + + * Source/NSCell.m (-initImageCell:, -initTextCell:): init super. + + * Source/NSClipView.m (-init): Set background to gray as we may not + have a window yet. + + * Source/NSMatrix.m: Fix column and row range checks. + + * Source/NSTextFieldCell.m (-copyWithZone:): Set draws + background flag for new cell. + + * Source/NSView.m: Reset subview needs display variables + when view is removed from superview. + + * Source/GNUmakefile: Add NSPasteboard.m. + + * Testing/GNUmakefile: Use test.make + * Testing/GNUmakefile.postamble: Remove install code. + * Testing/GNUmakefile.preamble: Add directory and library. + + * Tools/GNUmakefile: Make system root the default install dir. + * Tools/GNUmakefile.postamble: Install after instead of before. + * Tools/GNUmakefile.preamble: Add directory and library. + Wed Oct 29 12:22:22 1997 Ovidiu Predescu Bug fixes for NSForm and NSFormCell from Benhur Stein diff --git a/Documentation/news.tmpl.texi b/Documentation/news.tmpl.texi index 9dfc41b94..aec064b48 100644 --- a/Documentation/news.tmpl.texi +++ b/Documentation/news.tmpl.texi @@ -13,6 +13,13 @@ The currently released version of the library is @samp{@value{GNUSTEP-GUI-VERSIO @itemize @bullet +@item +NSBrowser and NSBrowserCell have been implemented. There is one odd +display artifact; lists which are smaller than the browser column area +have the list justified to the bottom of the column versus the top of +the column. This is actually an issue with NSMatrix and will be +remedied when flip views are implemented. + @item Two important optimizations that speed up the displaying of views and flushing of windows have been implemented. Only the views that need display and those diff --git a/Documentation/status.tmpl.texi b/Documentation/status.tmpl.texi index 28b9602ad..81454a1ed 100644 --- a/Documentation/status.tmpl.texi +++ b/Documentation/status.tmpl.texi @@ -61,9 +61,13 @@ Many of the methods have code, but whether the class is usable depends upon how much implementation has been done in the backend. -@item NSBrowser:: [2] +@item NSBrowser:: [9] +There is an odd display artifact; lists which are smaller than the +browser column area have the list justified to the bottom of the column +versus the top of the column. This is actually an issue with NSMatrix +and will be remedied when flip views are implemented. -@item NSBrowserCell:: [2] +@item NSBrowserCell:: [9] @item NSButton:: [9] Repeat intervals have been implemented. diff --git a/GNUmakefile b/GNUmakefile index 5a37e50c2..b8906ab22 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -32,7 +32,7 @@ include $(GNUSTEP_SYSTEM_ROOT)/Makefiles/common.make # # The list of subproject directories # -SUBPROJECTS = Source Images Testing +SUBPROJECTS = Source Images Tools Testing -include GNUmakefile.preamble diff --git a/Headers/gnustep/gui/NSBrowser.h b/Headers/gnustep/gui/NSBrowser.h index 10c9a60cb..a99ccb302 100644 --- a/Headers/gnustep/gui/NSBrowser.h +++ b/Headers/gnustep/gui/NSBrowser.h @@ -3,7 +3,7 @@ Control to display and select from hierarchal lists - Copyright (C) 1996 Free Software Foundation, Inc. + Copyright (C) 1996, 1997 Free Software Foundation, Inc. Author: Scott Christley Date: 1996 @@ -41,6 +41,33 @@ @interface NSBrowser : NSControl { // Attributes + Class _browserCellClass; + id _browserCellPrototype; + id _browserMatrixClass; + NSString *_pathSeparator; + BOOL _isLoaded; + BOOL _allowsBranchSelection; + BOOL _allowsEmptySelection; + BOOL _allowsMultipleSelection; + BOOL _reusesColumns; + int _maxVisibleColumns; + float _minColumnWidth; + BOOL _separatesColumns; + BOOL _takesTitleFromPreviousColumn; + BOOL _isTitled; + BOOL _hasHorizontalScroller; + NSScroller *_horizontalScroller; + BOOL _acceptsArrowKeys; + BOOL _sendsActionOnArrowKeys; + id _browserDelegate; + BOOL _passiveDelegate; + SEL _doubleAction; + NSMutableArray *_browserColumns; + id _titleCell; + NSSize _columnSize; + int _lastColumnLoaded; + int _firstVisibleColumn; + int _lastVisibleColumn; } // @@ -208,7 +235,10 @@ - (int)browser:(NSBrowser *)sender numberOfRowsInColumn:(int)column; - (BOOL)browser:(NSBrowser *)sender - selectCell:(NSString *)title +selectCellWithString:(NSString *)title + inColumn:(int)column; +- (BOOL)browser:(NSBrowser *)sender + selectRow:(int)row inColumn:(int)column; - (NSString *)browser:(NSBrowser *)sender titleOfColumn:(int)column; diff --git a/Headers/gnustep/gui/NSBrowserCell.h b/Headers/gnustep/gui/NSBrowserCell.h index 4c00f3fe0..5c0f9a9be 100644 --- a/Headers/gnustep/gui/NSBrowserCell.h +++ b/Headers/gnustep/gui/NSBrowserCell.h @@ -32,10 +32,20 @@ #include @class NSImage; +@class NSTextFieldCell; @interface NSBrowserCell : NSCell { // Attributes + NSImage *_alternateImage; + NSCell *_branchImage; + NSCell *_highlightBranchImage; + NSTextFieldCell *_browserText; + BOOL _isLeaf; + BOOL _isLoaded; + + // reserved for the backend + void *_be_bfc_reserved; } // diff --git a/Source/GNUmakefile b/Source/GNUmakefile index a2c74dac8..9adafc3e6 100644 --- a/Source/GNUmakefile +++ b/Source/GNUmakefile @@ -76,6 +76,7 @@ NSMenuItem.m \ NSOpenPanel.m \ NSPageLayout.m \ NSPanel.m \ +NSPasteboard.m \ NSPrinter.m \ NSPrintInfo.m \ NSPrintOperation.m \ @@ -102,7 +103,6 @@ TrackingRectangle.m \ PSMatrix.m \ tiff.m \ externs.m -# NSPasteboard.m libgnustep-gui_HEADER_FILES_DIR = ../Headers libgnustep-gui_HEADER_FILES_INSTALL_DIR = /gnustep/gui diff --git a/Source/NSBrowser.m b/Source/NSBrowser.m index ec759be0f..511435037 100644 --- a/Source/NSBrowser.m +++ b/Source/NSBrowser.m @@ -1,9 +1,9 @@ /* NSBrowser.m - Description... + Control to display and select from hierarchal lists - Copyright (C) 1996 Free Software Foundation, Inc. + Copyright (C) 1996, 1997 Free Software Foundation, Inc. Author: Scott Christley Date: 1996 @@ -28,7 +28,136 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define COLUMN_SEP 6 + +// +// Internal class for maintaining information about columns +// +@interface NSBrowserColumn : NSObject +{ + BOOL _isLoaded; + id _columnScrollView; + id _columnMatrix; + id _emptyView; + int _numberOfRows; + NSString *_columnTitle; +} + +- (void)setIsLoaded:(BOOL)flag; +- (BOOL)isLoaded; +- (void)setColumnScrollView:(id)aView; +- columnScrollView; +- (void)setColumnMatrix:(id)aMatrix; +- columnMatrix; +- (void)setNumberOfRows:(int)num; +- (int)numberOfRows; +- (void)setColumnTitle:(NSString *)aString; +- (NSString *)columnTitle; +- emptyView; + +@end + +@implementation NSBrowserColumn + +- init +{ + [super init]; + + _isLoaded = NO; + _emptyView = [[NSView alloc] init]; + + return self; +} + +- (void)dealloc +{ + [_columnTitle release]; + [super dealloc]; +} + +- (void)setIsLoaded:(BOOL)flag +{ + _isLoaded = flag; +} + +- (BOOL)isLoaded +{ + return _isLoaded; +} + +- (void)setColumnScrollView:(id)aView +{ + _columnScrollView = aView; +} + +- columnScrollView +{ + return _columnScrollView; +} + +- (void)setColumnMatrix:(id)aMatrix +{ + _columnMatrix = aMatrix; +} + +- columnMatrix +{ + return _columnMatrix; +} + +- (void)setNumberOfRows:(int)num +{ + _numberOfRows = num; +} + +- (int)numberOfRows +{ + return _numberOfRows; +} + +- (void)setColumnTitle:(NSString *)aString +{ + [aString retain]; + [_columnTitle release]; + _columnTitle = aString; +} + +- (NSString *)columnTitle +{ + return _columnTitle; +} + +- emptyView +{ + return _emptyView; +} + +@end + +// +// Private NSBrowser methods +// +@interface NSBrowser (Private) +- (void)_adjustMatrixOfColumn:(int)column; +- (void)_adjustScrollerFrameOfColumn:(int)column force:(BOOL)flag; +- (void)_adjustScrollerFrames:(BOOL)flag; +- (void)_performLoadOfColumn:(int)column; +- (void)_unloadFromColumn:(int)column; +@end + +// +// NSBrowser implementation +// @implementation NSBrowser // @@ -48,79 +177,207 @@ // + (Class)cellClass { - return NULL; + return [NSBrowserCell class]; } // // Instance methods // +- initWithFrame:(NSRect)rect +{ + NSSize bs; + NSRect scroller_rect; + + [super initWithFrame: rect]; + + _browserCellClass = [NSBrowser cellClass]; + _browserCellPrototype = [[_browserCellClass alloc] init]; + _browserMatrixClass = [NSMatrix class]; + _pathSeparator = [[NSString alloc] initWithCString: "/"]; + _isLoaded = NO; + _allowsBranchSelection = YES; + _allowsEmptySelection = YES; + _allowsMultipleSelection = YES; + _reusesColumns = NO; + _maxVisibleColumns = 1; + bs = [NSCell sizeForBorderType: NSBezelBorder]; + _minColumnWidth = [NSScroller scrollerWidth] + (2 * bs.width); + _separatesColumns = YES; + _takesTitleFromPreviousColumn = YES; + _isTitled = YES; + _hasHorizontalScroller = YES; + scroller_rect.origin = NSZeroPoint; + scroller_rect.size.width = frame.size.width; + scroller_rect.size.height = [NSScroller scrollerWidth]; + _horizontalScroller = [[NSScroller alloc] initWithFrame: scroller_rect]; + [_horizontalScroller setTarget: self]; + [_horizontalScroller setAction: @selector(scrollViaScroller:)]; + [self addSubview: _horizontalScroller]; + _acceptsArrowKeys = YES; + _sendsActionOnArrowKeys = YES; + _browserDelegate = nil; + _passiveDelegate = YES; + _doubleAction = NULL; + _browserColumns = [[NSMutableArray alloc] init]; + _titleCell = [NSTextFieldCell new]; + [_titleCell setEditable: NO]; + [_titleCell setTextColor: [NSColor whiteColor]]; + [_titleCell setBackgroundColor: [NSColor darkGrayColor]]; + //[_titleCell setBordered: YES]; + //[_titleCell setBezeled: YES]; + [_titleCell setAlignment: NSCenterTextAlignment]; + + // Calculate geometry + [self tile]; + + // Create a single column + _lastColumnLoaded = -1; + _firstVisibleColumn = 0; + _lastVisibleColumn = 0; + [self addColumn]; + + return self; +} + +- (void)dealloc +{ + [_browserCellPrototype release]; + [_pathSeparator release]; + [_horizontalScroller release]; + [_browserColumns release]; + [_titleCell release]; + + [super dealloc]; +} // // Setting the Delegate // - (id)delegate { - return nil; + return _browserDelegate; } - (void)setDelegate:(id)anObject -{} +{ + BOOL flag = NO; + BOOL both = NO; + + if (![anObject respondsToSelector: + @selector(browser:willDisplayCell:atRow:column:)]) + [NSException raise: NSBrowserIllegalDelegateException + format: @"Delegate does not respond to %s\n", + "browser:willDisplayCell:atRow:column:"]; + + if ([anObject respondsToSelector: + @selector(browser:numberOfRowsInColumn:)]) + { + _passiveDelegate = YES; + flag = YES; + } + + if ([anObject respondsToSelector: + @selector(browser:createRowsForColumn:inMatrix:)]) + { + _passiveDelegate = NO; + + // If flag is already set + // then delegate must respond to both methods + if (flag) + both = YES; + + flag = YES; + } + + if (!flag) + [NSException raise: NSBrowserIllegalDelegateException + format: @"Delegate does not respond to %s or %s\n", + "browser:numberOfRowsInColumn:", + "browser:createRowsForColumn:inMatrix:"]; + + if (both) + [NSException raise: NSBrowserIllegalDelegateException + format: @"Delegate responds to both %s and %s\n", + "browser:numberOfRowsInColumn:", + "browser:createRowsForColumn:inMatrix:"]; + + [anObject retain]; + [_browserDelegate release]; + _browserDelegate = anObject; +} // // Target and Action // - (SEL)doubleAction { - return NULL; + return _doubleAction; } - (BOOL)sendAction { - return NO; + return [self sendAction: [self action] to: [self target]]; } - (void)setDoubleAction:(SEL)aSelector -{} +{ + _doubleAction = aSelector; +} // // Setting Component Classes // - (id)cellPrototype { - return nil; + return _browserCellPrototype; } - (Class)matrixClass { - return NULL; + return _browserMatrixClass; } - (void)setCellClass:(Class)classId -{} +{ + _browserCellClass = classId; + + // set the prototype for the new class + [self setCellPrototype: [[_browserCellClass alloc] init]]; +} - (void)setCellPrototype:(NSCell *)aCell -{} +{ + [aCell retain]; + [_browserCellPrototype release]; + _browserCellPrototype = aCell; +} - (void)setMatrixClass:(Class)classId -{} +{ + _browserMatrixClass = classId; +} // // Setting NSBrowser Behavior // - (BOOL)reusesColumns { - return NO; + return _reusesColumns; } - (void)setReusesColumns:(BOOL)flag -{} +{ + _reusesColumns = flag; +} - (void)setTakesTitleFromPreviousColumn:(BOOL)flag -{} +{ + _takesTitleFromPreviousColumn = flag; +} - (BOOL)takesTitleFromPreviousColumn { - return NO; + return _takesTitleFromPreviousColumn; } // @@ -128,56 +385,73 @@ // - (BOOL)allowsBranchSelection { - return NO; + return _allowsBranchSelection; } - (BOOL)allowsEmptySelection { - return NO; + return _allowsEmptySelection; } - (BOOL)allowsMultipleSelection { - return NO; + return _allowsMultipleSelection; } - (void)setAllowsBranchSelection:(BOOL)flag -{} +{ + _allowsBranchSelection = flag; +} - (void)setAllowsEmptySelection:(BOOL)flag -{} +{ + _allowsEmptySelection = flag; +} - (void)setAllowsMultipleSelection:(BOOL)flag -{} +{ + _allowsMultipleSelection = flag; +} // // Setting Arrow Key Behavior // - (BOOL)acceptsArrowKeys { - return NO; + return _acceptsArrowKeys; } - (BOOL)sendsActionOnArrowKeys { - return NO; + return _sendsActionOnArrowKeys; } - (void)setAcceptsArrowKeys:(BOOL)flag -{} +{ + _acceptsArrowKeys = flag; +} - (void)setSendsActionOnArrowKeys:(BOOL)flag -{} +{ + _sendsActionOnArrowKeys = flag; +} // // Showing a Horizontal Scroller // - (void)setHasHorizontalScroller:(BOOL)flag -{} +{ + _hasHorizontalScroller = flag; + + if (!flag) + [_horizontalScroller removeFromSuperview]; + + [self tile]; +} - (BOOL)hasHorizontalScroller { - return NO; + return _hasHorizontalScroller; } // @@ -185,151 +459,628 @@ // - (int)maxVisibleColumns { - return 0; + return _maxVisibleColumns; } - (int)minColumnWidth { - return 0; + return _minColumnWidth; } - (BOOL)separatesColumns { - return NO; + return _separatesColumns; } - (void)setMaxVisibleColumns:(int)columnCount -{} +{ + int i, count = [_browserColumns count]; + + _maxVisibleColumns = columnCount; + + // Create additional columns if necessary + for (i = count; i < _maxVisibleColumns; ++i) + [self addColumn]; + + _lastVisibleColumn = _maxVisibleColumns - _firstVisibleColumn - 1; + + [self tile]; + [self _adjustScrollerFrames: NO]; +} - (void)setMinColumnWidth:(int)columnWidth -{} +{ + float sw = [NSScroller scrollerWidth]; + NSSize bs = [NSCell sizeForBorderType: NSBezelBorder]; + float bw = 2 * bs.width; + + // Take the border into account + if (_separatesColumns) + sw += bw; + + // Column width cannot be less than scroller and border + if (columnWidth < sw) + _minColumnWidth = sw; + else + _minColumnWidth = columnWidth; + + [self tile]; +} - (void)setSeparatesColumns:(BOOL)flag -{} +{ + _separatesColumns = flag; + + [self tile]; +} // // Manipulating Columns // - (void)addColumn -{} +{ + NSBrowserColumn *bc; + NSScrollView *sc; + int n = [_browserColumns count]; + + bc = [[NSBrowserColumn alloc] init]; + + // Create a scrollview + sc = [[NSScrollView alloc] + initWithFrame: [self frameOfInsideOfColumn: n]]; + [sc setHasHorizontalScroller: NO]; + [sc setHasVerticalScroller: YES]; + [bc setColumnScrollView: sc]; + [self addSubview: sc]; + + [_browserColumns addObject: bc]; +} - (int)columnOfMatrix:(NSMatrix *)matrix { - return 0; + NSBrowserColumn *bc; + int i, count = [_browserColumns count]; + + // Loop through columns and compare matrixes + for (i = 0;i < count; ++i) + { + bc = [_browserColumns objectAtIndex: i]; + if (matrix == [bc columnMatrix]) + return i; + } + + // Not found + return NSNotFound; } - (void)displayAllColumns -{} +{ + int i, count = [_browserColumns count]; + + for (i = 0; i < count; ++i) + { + //NSBrowserColumn *bc = [_browserColumns objectAtIndex: i]; + + // Only display if loaded + //if ([bc isLoaded]) + [self displayColumn: i]; + } +} - (void)displayColumn:(int)column -{} +{ + NSBrowserColumn *bc; + + // If not visible then nothing to display + if ((column < _firstVisibleColumn) || (column > _lastVisibleColumn)) + return; + + bc = [_browserColumns objectAtIndex: column]; + + // Ask the delegate for the column title + if ([_browserDelegate respondsToSelector: + @selector(browser:titleOfColumn:)]) + [self setTitle: [_browserDelegate browser: self + titleOfColumn: column] + ofColumn: column]; + else + { + // Check if we take title from previous column + if ([self takesTitleFromPreviousColumn]) + { + // If first column then use the path separator + if (column == 0) + [self setTitle: _pathSeparator ofColumn: 0]; + else + { + // Get the selected cell + // Use its string value as the title + // Only if it is not a leaf + id c = [self selectedCellInColumn: column - 1]; + if ([c isLeaf]) + [self setTitle: @"" ofColumn: column]; + else + [self setTitle: [c stringValue] ofColumn: column]; + } + } + else + [self setTitle: @"" ofColumn: column]; + } + + // Draw the title + [self drawTitle: [bc columnTitle] + inRect: [self titleFrameOfColumn: column] + ofColumn: column]; +} - (int)firstVisibleColumn { - return 0; + return _firstVisibleColumn; } - (BOOL)isLoaded { - return NO; + return _isLoaded; } - (int)lastColumn { - return 0; + return _lastColumnLoaded; } - (int)lastVisibleColumn { - return 0; + return _lastVisibleColumn; } - (void)loadColumnZero -{} +{ + // load column 0 + [self _performLoadOfColumn: 0]; + + // Unload other columns + [self _unloadFromColumn: 1]; + + // set last column loaded + [self setLastColumn: 0]; + + _isLoaded = YES; + [self tile]; + [self _adjustScrollerFrames: YES]; +} - (int)numberOfVisibleColumns { - return 0; + int i, j, count = [_browserColumns count]; + BOOL done; + + // As I interpret it, the number of visible columns + // is the total number of scrollviews in the scrolling + // region regardless of whether they are actually + // visible or not. + + // We have at least upto the last visible column + i = _lastVisibleColumn; + + // Plus any loaded columns after that + done = NO; + j = i + 1; + while ((!done) && (j < count)) + { + NSBrowserColumn *bc = [_browserColumns objectAtIndex: j]; + if ([bc isLoaded]) + { + i = j; + ++j; + } + else + done = YES; + } + + // Should be at least the max visible columns + if (i < _maxVisibleColumns) + return _maxVisibleColumns; + else + return i + 1; } - (void)reloadColumn:(int)column -{} +{ + NSBrowserColumn *bc; + + // Make sure the column even exists + if (column >= (int)[_browserColumns count]) + return; + + bc = [_browserColumns objectAtIndex: column]; + + // If the column has not be loaded then do not reload + if (![bc isLoaded]) + return; + + // Perform the data load + [self _performLoadOfColumn: column]; + + // Unload the columns after + [self _unloadFromColumn: column + 1]; + + // set last column loaded + [self setLastColumn: column]; +} - (void)selectAll:(id)sender -{} +{ + id matrix = [self matrixInColumn: _lastVisibleColumn]; + [matrix selectAll: sender]; +} - (int)selectedColumn { - return 0; + id o, e = [_browserColumns reverseObjectEnumerator]; + BOOL found = NO; + id c = nil; + int i = [_browserColumns count] - 1; + + while ((!found) && (o = [e nextObject])) + { + id matrix = [o columnMatrix]; + + c = [matrix selectedCell]; + if (c) + found = YES; + else + --i; + } + + if (found) + return i; + else + return NSNotFound; } - (void)setLastColumn:(int)column -{} +{ + _lastColumnLoaded = column; +} - (void)validateVisibleColumns -{} +{ + int i; + + // xxx Should we trigger an exception? + if (![_browserDelegate respondsToSelector: + @selector(browser:isColumnValid:)]) + return; + + // Loop through the visible columns + for (i = _firstVisibleColumn; i <= _lastVisibleColumn; ++i) + { + // Ask delegate if the column is valid and if not + // then reload the column + BOOL v = [_browserDelegate browser: self isColumnValid: i]; + if (!v) + [self reloadColumn: i]; + } +} // // Manipulating Column Titles // - (void)drawTitle:(NSString *)title inRect:(NSRect)aRect -ofColumn:(int)column -{} + ofColumn:(int)column +{ + // Not titled then nothing to draw + if (![self isTitled]) + return; + + // If column is not visible then nothing to draw + if ((column < _firstVisibleColumn) || (column > _lastVisibleColumn)) + return; + + [_titleCell setStringValue: title]; + [_titleCell drawWithFrame: aRect inView: self]; +} - (BOOL)isTitled { - return NO; + return _isTitled; } - (void)setTitled:(BOOL)flag -{} +{ + _isTitled = flag; + + [self tile]; +} - (void)setTitle:(NSString *)aString ofColumn:(int)column -{} +{ + NSBrowserColumn *bc = [_browserColumns objectAtIndex: column]; + [bc setColumnTitle: aString]; + + // If column is not visible then nothing to redisplay + if ((column < _firstVisibleColumn) || (column > _lastVisibleColumn)) + return; + else + [self setNeedsDisplayInRect: [self titleFrameOfColumn: column]]; +} - (NSRect)titleFrameOfColumn:(int)column { - return NSZeroRect; + NSRect r; + int n; + + // Not titled then no frame + if (![self isTitled]) + return NSZeroRect; + + // Number of columns over from the first + n = column - _firstVisibleColumn; + + // Calculate the frame + r.origin.x = n * _columnSize.width; + r.origin.y = frame.size.height - [self titleHeight] + 2; + r.size.width = _columnSize.width; + r.size.height = [self titleHeight] - 4; + + if (_separatesColumns) + r.origin.x += n * COLUMN_SEP; + + return r; } - (float)titleHeight { - return 0; + return 24; } - (NSString *)titleOfColumn:(int)column { - return nil; + NSBrowserColumn *bc = [_browserColumns objectAtIndex: column]; + return [bc columnTitle]; } // // Scrolling an NSBrowser // - (void)scrollColumnsLeftBy:(int)shiftAmount -{} +{ + // Cannot shift past the zero column + if ((_firstVisibleColumn - shiftAmount) < 0) + shiftAmount = _firstVisibleColumn; + + // No amount to shift then nothing to do + if (shiftAmount == 0) + return; + + // Notify the delegate + if ([_browserDelegate respondsToSelector: @selector(browserWillScroll:)]) + [_browserDelegate browserWillScroll: self]; + + // Shift + _firstVisibleColumn = _firstVisibleColumn - shiftAmount; + _lastVisibleColumn = _lastVisibleColumn - shiftAmount; + + // Update the scrollviews + [self _adjustScrollerFrames: YES]; + + // Update the scroller + [self updateScroller]; + + // Notify the delegate + if ([_browserDelegate respondsToSelector: @selector(browserDidScroll:)]) + [_browserDelegate browserDidScroll: self]; +} - (void)scrollColumnsRightBy:(int)shiftAmount -{} +{ + // Cannot shift past the last loaded column + if ((shiftAmount + _lastVisibleColumn) > _lastColumnLoaded) + shiftAmount = _lastColumnLoaded - _lastVisibleColumn; + + // No amount to shift then nothing to do + if (shiftAmount == 0) + return; + + // Notify the delegate + if ([_browserDelegate respondsToSelector: @selector(browserWillScroll:)]) + [_browserDelegate browserWillScroll: self]; + + // Shift + _firstVisibleColumn = _firstVisibleColumn + shiftAmount; + _lastVisibleColumn = _lastVisibleColumn + shiftAmount; + + // Update the scrollviews + [self _adjustScrollerFrames: YES]; + + // Update the scroller + [self updateScroller]; + + // Notify the delegate + if ([_browserDelegate respondsToSelector: @selector(browserDidScroll:)]) + [_browserDelegate browserDidScroll: self]; +} - (void)scrollColumnToVisible:(int)column -{} +{ + int i; + + // If its the last visible column then we are there already + if (_lastVisibleColumn == column) + return; + + // If there are not enough columns to scroll with + // then the column must be visible + if ([self numberOfVisibleColumns] <= _maxVisibleColumns) + return; + + i = _lastVisibleColumn - column; + if (i > 0) + [self scrollColumnsLeftBy: i]; + else + [self scrollColumnsRightBy: (-i)]; +} - (void)scrollViaScroller:(NSScroller *)sender -{} +{ + NSScrollerPart hit = [sender hitPart]; + + // Scroll to the left + if ((hit == NSScrollerDecrementLine) || (hit == NSScrollerDecrementPage)) + { + [self scrollColumnsLeftBy: 1]; + return; + } + + // Scroll to the right + if ((hit == NSScrollerIncrementLine) || (hit == NSScrollerIncrementPage)) + { + [self scrollColumnsRightBy: 1]; + return; + } + + // The knob or knob slot + if ((hit == NSScrollerKnob) || (hit == NSScrollerKnobSlot)) + { + float f = [sender floatValue]; + int c = [self numberOfVisibleColumns] - 1; + float i; + + // If the number of loaded columns has shrunk then + // there will be more columns displayed then loaded + // so use that value instead + if (c > _lastColumnLoaded) + i = c - _maxVisibleColumns + 1; + else + i = _lastColumnLoaded - _maxVisibleColumns + 1; + + if (_lastColumnLoaded != 0) + { + f = (f - 1) * i; + f += _lastColumnLoaded; + [self scrollColumnToVisible: (int)f]; + } + else + [self updateScroller]; + return; + } +} - (void)updateScroller -{} +{ + // If there are not enough columns to scroll with + // then the column must be visible + if ((_lastColumnLoaded == 0) || + (_lastColumnLoaded <= (_maxVisibleColumns - 1))) + [_horizontalScroller setEnabled: NO]; + else + { + float prop = (float)_maxVisibleColumns / (float)(_lastColumnLoaded + 1); + float i = _lastColumnLoaded - _maxVisibleColumns + 1; + float f = 1 + ((_lastVisibleColumn - _lastColumnLoaded) / i); + [_horizontalScroller setFloatValue: f knobProportion: prop]; + [_horizontalScroller setEnabled: YES]; + } + + return; +} // // Event Handling // - (void)doClick:(id)sender -{} +{ + int column = [self columnOfMatrix: sender]; + NSArray *a; + BOOL shouldSelect = YES; + + // If the matrix isn't ours then just return + if (column == NSNotFound) + return; + + // Ask delegate if selection is ok + if ([_browserDelegate respondsTo: @selector(browser:selectRow:inColumn:)]) + { + int row = [sender selectedRow]; + shouldSelect = [_browserDelegate browser: self selectRow: row + inColumn: column]; + } + else + { + // Try the other method + if ([_browserDelegate + respondsTo: @selector(browser:selectCellWithString:inColumn:)]) + { + id c = [sender selectedCell]; + shouldSelect = [_browserDelegate browser: self + selectCellWithString: + [c stringValue] + inColumn: column]; + } + } + + // If we should not select the cell + // then select it and return + if (!shouldSelect) + { + [sender deselectSelectedCell]; + return; + } + + a = [sender selectedCells]; + + // If only one cell is selected + if ([a count] == 1) + { + id c = [a objectAtIndex: 0]; + + // If the cell is a leaf + // then unload the columns after + if ([c isLeaf]) + { + [self _unloadFromColumn: column + 1]; + [self setLastColumn: column]; + } + else + { + // The cell is not a leaf so we need to load a column + + // If last column then add a column + if (column == (int)([_browserColumns count] - 1)) + [self addColumn]; + + // Load column + [self _performLoadOfColumn: column + 1]; + [self setLastColumn: column + 1]; + [self _adjustMatrixOfColumn: column + 1]; + [self _unloadFromColumn: column + 2]; + + // If this column is the last visible + // then scroll right by one column + if (column == _lastVisibleColumn) + [self scrollColumnsRightBy: 1]; + } + } + else + { + // If multiple selection + // then we unload the columns after + [self _unloadFromColumn: column + 1]; + [self setLastColumn: column]; + } + + // Send the action to target + [self sendAction]; +} - (void)doDoubleClick:(id)sender -{} +{ + // We have already handled the single click + // so send the double action + [self sendAction: _doubleAction to: [self target]]; +} // // Getting Matrices and Cells @@ -337,27 +1088,77 @@ ofColumn:(int)column - (id)loadedCellAtRow:(int)row column:(int)column { - return nil; + NSBrowserColumn *bc; + NSArray *columnCells; + id matrix; + int count = [_browserColumns count]; + id aCell; + + // column range check + if (column >= count) + return nil; + + bc = [_browserColumns objectAtIndex: column]; + matrix = [bc columnMatrix]; + columnCells = [matrix cells]; + count = [columnCells count]; + + // row range check + if (row >= count) + return nil; + + // Get the cell + aCell = [matrix cellAtRow: row column: 0]; + + // Load if not already loaded + if ([aCell isLoaded]) + return aCell; + else + { + [_browserDelegate browser: self willDisplayCell: aCell + atRow: row column: column]; + [aCell setLoaded: YES]; + } + + return aCell; } - (NSMatrix *)matrixInColumn:(int)column { - return nil; + NSBrowserColumn *bc = [_browserColumns objectAtIndex: column]; + return [bc columnMatrix]; } - (id)selectedCell { - return nil; + int i = [self selectedColumn]; + id matrix; + + // Nothing selected + if (i == NSNotFound) + return nil; + + matrix = [self matrixInColumn: i]; + return [matrix selectedCell]; } - (id)selectedCellInColumn:(int)column { - return nil; + id matrix = [self matrixInColumn: column]; + return [matrix selectedCell]; } - (NSArray *)selectedCells { - return nil; + int i = [self selectedColumn]; + id matrix; + + // Nothing selected + if (i == NSNotFound) + return nil; + + matrix = [self matrixInColumn: i]; + return [matrix selectedCells]; } // @@ -365,12 +1166,30 @@ ofColumn:(int)column // - (NSRect)frameOfColumn:(int)column { - return NSZeroRect; + NSRect r = NSZeroRect; + int n; + + // Number of columns over from the first + n = column - _firstVisibleColumn; + + // Calculate the frame + r.size = _columnSize; + r.origin.x = n * _columnSize.width; + + if (_separatesColumns) + r.origin.x += n * COLUMN_SEP; + + // Adjust for horizontal scroller + if (_hasHorizontalScroller) + r.origin.y = [NSScroller scrollerWidth] + 4; + + return r; } - (NSRect)frameOfInsideOfColumn:(int)column { - return NSZeroRect; + // xxx what does this one do? + return [self frameOfColumn: column]; } // @@ -378,17 +1197,33 @@ ofColumn:(int)column // - (NSString *)path { - return nil; + return [self pathToColumn: _lastColumnLoaded + 1]; } - (NSString *)pathSeparator { - return nil; + return _pathSeparator; } - (NSString *)pathToColumn:(int)column { - return nil; + int i; + NSMutableString *s = [NSMutableString stringWithCString: ""]; + + // Cannot go past the number of loaded columns + if (column > _lastColumnLoaded) + column = _lastColumnLoaded + 1; + + [s appendString: _pathSeparator]; + for (i = 0;i < column; ++i) + { + id c = [self selectedCellInColumn: i]; + if (i != 0) + [s appendString: _pathSeparator]; + [s appendString: [c stringValue]]; + } + + return [[[NSString alloc] initWithString: s] autorelease]; } - (BOOL)setPath:(NSString *)path @@ -397,58 +1232,96 @@ ofColumn:(int)column } - (void)setPathSeparator:(NSString *)aString -{} +{ + [aString retain]; + [_pathSeparator release]; + _pathSeparator = aString; +} // // Arranging an NSBrowser's Components // - (void)tile -{} +{ + NSRect scroller_rect; + int num; + + // It is assumed the frame/bounds are set appropriately + // before calling this method + + // Determine number of columns and their widths + num = _maxVisibleColumns; + if (_separatesColumns) + _columnSize.width = (frame.size.width - ((num - 1) * COLUMN_SEP)) + / (float)num; + else + _columnSize.width = frame.size.width / (float)num; + _columnSize.height = frame.size.height; + + // Horizontal scroller + if (_hasHorizontalScroller) + { + scroller_rect.origin = frame.origin; + scroller_rect.size.width = frame.size.width; + scroller_rect.size.height = [NSScroller scrollerWidth] + 4; + _columnSize.height -= scroller_rect.size.height; + } + else + scroller_rect = NSZeroRect; + + // Title + if (_isTitled) + _columnSize.height -= [self titleHeight]; + + if (_columnSize.height < 0) + _columnSize.height = 0; + +} + +- (void)drawRect:(NSRect)rect +{ + int i; + + // Load the first column if not already done + if (!_isLoaded) + { + [self loadColumnZero]; + [self displayAllColumns]; + } + + // Loop through the visible columns + for (i = _firstVisibleColumn; i <= _lastVisibleColumn; ++i) + { + // If the column title intersects with the rect to be drawn + // then draw that column + NSRect r = NSIntersectionRect([self titleFrameOfColumn: i], rect); + if (! NSIsEmptyRect(r)) + [self displayColumn: i]; + } +} // -// Methods Implemented by the Delegate +// Displaying the Control and Cell // -- (void)browser:(NSBrowser *)sender -createRowsForColumn:(int)column -inMatrix:(NSMatrix *)matrix -{} - -- (BOOL)browser:(NSBrowser *)sender - isColumnValid:(int)column +- (void)drawCell:(NSCell *)aCell { - return NO; } -- (int)browser:(NSBrowser *)sender -numberOfRowsInColumn:(int)column +- (void)drawCellInside:(NSCell *)aCell { - return 0; } -- (BOOL)browser:(NSBrowser *)sender - selectCell:(NSString *)title -inColumn:(int)column +- (void)selectCell:(NSCell *)aCell { - return NO; } -- (NSString *)browser:(NSBrowser *)sender - titleOfColumn:(int)column +- (void)updateCell:(NSCell *)aCell { - return nil; } -- (void)browser:(NSBrowser *)sender -willDisplayCell:(id)cell -atRow:(int)row -column:(int)column -{} - -- (void)browserDidScroll:(NSBrowser *)sender -{} - -- (void)browserWillScroll:(NSBrowser *)sender -{} +- (void)updateCellInside:(NSCell *)aCell +{ +} // // NSCoding protocol @@ -466,3 +1339,214 @@ column:(int)column } @end + +// +// Private NSBrowser methods +// +@implementation NSBrowser (Private) + +- (void)_adjustMatrixOfColumn:(int)column +{ + NSBrowserColumn *bc; + NSScrollView *sc; + id matrix; + NSSize cs, ms; + NSRect mr; + + if (column >= (int)[_browserColumns count]) + return; + + bc = [_browserColumns objectAtIndex: column]; + sc = [bc columnScrollView]; + matrix = [bc columnMatrix]; + + // Adjust matrixes to fit in the scrollview + // Only set if column has been loaded + if (sc && matrix && [bc isLoaded]) + { + cs = [sc contentSize]; + [matrix sizeToCells]; + ms = [matrix cellSize]; + ms.width = cs.width; + [matrix setCellSize: ms]; + mr = [matrix frame]; + +#if 0 + // Adjust because NSMatrix has incorrect origin + if (mr.size.height < cs.height) + { + mr.origin.y = cs.height - mr.size.height; + [matrix setFrame: mr]; + } +#endif + [sc setDocumentView: matrix]; + } +} + +- (void)_adjustScrollerFrameOfColumn:(int)column force:(BOOL)flag +{ + // Only if we've loaded the first column + if ((_isLoaded) || (flag)) + { + NSBrowserColumn *bc; + NSScrollView *sc; + + if (column >= (int)[_browserColumns count]) + return; + + bc = [_browserColumns objectAtIndex: column]; + sc = [bc columnScrollView]; + + // Set the scrollview frame + // Only set before the column has been loaded + // Or we are being forced + if (sc && ((![bc isLoaded]) || flag)) + [sc setFrame: [self frameOfInsideOfColumn: column]]; + } +} + +- (void)_adjustScrollerFrames:(BOOL)force +{ + int i, count = [_browserColumns count]; + + // Loop through the columns + for (i = 0;i < count; ++i) + { + // If its a visible column + if ((i >= _firstVisibleColumn) && (i <= _lastVisibleColumn)) + { + NSBrowserColumn *bc = [_browserColumns objectAtIndex: i]; + id sc = [bc columnScrollView]; + + // Add as subview if necessary + if (sc) + if (![sc superview]) + [self addSubview: sc]; + + [self _adjustScrollerFrameOfColumn: i force: force]; + [self _adjustMatrixOfColumn: i]; + } + else + { + // If it is not visible + NSBrowserColumn *bc = [_browserColumns objectAtIndex: i]; + id sc = [bc columnScrollView]; + + // Remove it from its superview if it has one + if (sc) + if ([sc superview]) + { + NSLog(@"before: %d\n", [sc retainCount]); + [sc removeFromSuperview]; + NSLog(@"after: %d\n", [sc retainCount]); + } + } + } +} + +- (void)_performLoadOfColumn:(int)column +{ + NSBrowserColumn *bc = [_browserColumns objectAtIndex: column]; + + // Loading is different based upon passive/active delegate + if (_passiveDelegate) + { + // Ask the delegate for the number of rows + int n = [_browserDelegate browser: self numberOfRowsInColumn: column]; + + if (_reusesColumns) + { + } + else + { + id matrix; + id sc = [bc columnScrollView]; + id oldm = [bc columnMatrix]; + NSRect matrixRect = {{0, 0}, {100, 100}}; + int i; + + // If we are not reusing matrixes + // then delete the old matrix and create a new one + [oldm release]; + matrix = [[_browserMatrixClass alloc] + initWithFrame: matrixRect + mode: NSListModeMatrix + prototype: _browserCellPrototype + numberOfRows: n + numberOfColumns: 1]; + [matrix setAllowsEmptySelection: _allowsEmptySelection]; + if (!_allowsMultipleSelection) + [matrix setMode: NSRadioModeMatrix]; + [matrix setTarget: self]; + [matrix setAction: @selector(doClick:)]; + [matrix setDoubleAction: @selector(doDoubleClick:)]; + + [bc setColumnMatrix: matrix]; + [sc setDocumentView: matrix]; + + // Now loop through the cells and load each one + for (i = 0;i < n; ++i) + [self loadedCellAtRow: i column: column]; + } + } + else + { + if (_reusesColumns) + { + } + else + { + id matrix; + id sc = [bc columnScrollView]; + id oldm = [bc columnMatrix]; + NSRect matrixRect = {{0, 0}, {100, 100}}; + + // If we are not reusing matrixes + // then delete the old matrix and create a new one + [oldm release]; + matrix = [[_browserMatrixClass alloc] + initWithFrame: matrixRect + mode: NSListModeMatrix + prototype: _browserCellPrototype + numberOfRows: 0 + numberOfColumns: 0]; + [matrix setAllowsEmptySelection: _allowsEmptySelection]; + if (!_allowsMultipleSelection) + [matrix setMode: NSRadioModeMatrix]; + [matrix setTarget: self]; + [matrix setAction: @selector(doClick:)]; + [matrix setDoubleAction: @selector(doDoubleClick:)]; + + [bc setColumnMatrix: matrix]; + [sc setDocumentView: matrix]; + + // Tell the delegate to create the rows + [_browserDelegate browser: self createRowsForColumn: column + inMatrix: matrix]; + } + } + + [bc setIsLoaded: YES]; +} + +- (void)_unloadFromColumn:(int)column +{ + int i, count = [_browserColumns count]; + + for (i = column; i < count; ++i) + { + NSBrowserColumn *bc = [_browserColumns objectAtIndex: i]; + if ([bc isLoaded]) + { + id sc = [bc columnScrollView]; + + // Make the column appear empty + // by removing the matrix + [sc setDocumentView: [bc emptyView]]; + + [bc setIsLoaded: NO]; + } + } +} + +@end diff --git a/Source/NSBrowserCell.m b/Source/NSBrowserCell.m index cf9c3f553..62b370603 100644 --- a/Source/NSBrowserCell.m +++ b/Source/NSBrowserCell.m @@ -3,7 +3,7 @@ Cell class for the NSBrowser - Copyright (C) 1996 Free Software Foundation, Inc. + Copyright (C) 1996, 1997 Free Software Foundation, Inc. Author: Scott Christley Date: 1996 @@ -28,7 +28,42 @@ #include #include +#include +#include +// Class variables +static NSImage *branch_image; +static NSImage *highlight_image; + +// Private methods +@interface NSBrowserCell (Private) +- (void)setBranchImageCell:aCell; +- (void)setHighlightBranchImageCell:aCell; +- (void)setTextFieldCell:aCell; +@end + +@implementation NSBrowserCell (Private) + +- (void)setBranchImageCell:aCell +{ + _branchImage = aCell; +} + +- (void)setHighlightBranchImageCell:aCell +{ + _highlightBranchImage = aCell; +} + +- (void)setTextFieldCell:aCell +{ + _browserText = aCell; +} + +@end + +// +// NSBrowserCell implementation +// @implementation NSBrowserCell // @@ -40,6 +75,10 @@ { // Initial version [self setVersion:1]; + + // The default images + branch_image = [NSImage imageNamed: @"common_ArrowRight"]; + highlight_image = [NSImage imageNamed: @"common_ArrowRightH"]; } } @@ -48,59 +87,177 @@ // + (NSImage *)branchImage { - return nil; + return branch_image; } + (NSImage *)highlightedBranchImage { - return nil; + return highlight_image; } // // Instance methods // +- init +{ + return [self initTextCell: @"aTitle"]; +} + +- initTextCell:(NSString *)aString +{ + [super initTextCell: aString]; + + // Our image cells + _branchImage = [[NSCell alloc] initImageCell: [NSBrowserCell branchImage]]; + _highlightBranchImage = [[NSCell alloc] initImageCell: + [NSBrowserCell highlightedBranchImage]]; + + // Our text cell + _browserText = [[NSTextFieldCell alloc] initTextCell: aString]; + [_browserText setEditable: NO]; + [_browserText setBordered: NO]; + [_browserText setDrawsBackground: YES]; + + _alternateImage = nil; + _isLeaf = NO; + _isLoaded = NO; + + return self; +} + +- (void)dealloc +{ + [_branchImage release]; + [_highlightBranchImage release]; + [_alternateImage release]; + [_browserText release]; + + [super dealloc]; +} + +- (id)copyWithZone:(NSZone*)zone +{ + NSBrowserCell* c = [super copyWithZone:zone]; + + // Copy the image cells + [c setBranchImageCell: [_branchImage copy]]; + [c setHighlightBranchImageCell: [_branchImage copy]]; + [c setAlternateImage: _alternateImage]; + + // Copy the text cell + [c setTextFieldCell: [_browserText copy]]; + + [c setLeaf: _isLeaf]; + [c setLoaded: NO]; + + return c; +} + // // Accessing Graphic Attributes // - (NSImage *)alternateImage { - return nil; + return _alternateImage; } - (void)setAlternateImage:(NSImage *)anImage -{} +{ + [anImage retain]; + [_alternateImage release]; + _alternateImage = anImage; + + // Set the image in our highlight cell + if (_alternateImage) + [_highlightBranchImage setImage: _alternateImage]; + else + [_highlightBranchImage setImage: [NSBrowserCell highlightedBranchImage]]; +} // // Placing in the Browser Hierarchy // - (BOOL)isLeaf { - return NO; + return _isLeaf; } - (void)setLeaf:(BOOL)flag -{} +{ + _isLeaf = flag; +} // // Determining Loaded Status // - (BOOL)isLoaded { - return NO; + return _isLoaded; } - (void)setLoaded:(BOOL)flag -{} +{ + _isLoaded = flag; +} // // Setting State // - (void)reset -{} +{ + cell_highlighted = NO; + cell_state = NO; +} - (void)set -{} +{ + cell_highlighted = YES; + cell_state = YES; +} + +// +// Setting the NSCell's Value +// +- (double)doubleValue +{ + return [_browserText doubleValue]; +} + +- (float)floatValue; +{ + return [_browserText floatValue]; +} + +- (int)intValue +{ + return [_browserText intValue]; +} + +- (NSString *)stringValue +{ + return [_browserText stringValue]; +} + +- (void)setDoubleValue:(double)aDouble +{ + [_browserText setDoubleValue: aDouble]; +} + +- (void)setFloatValue:(float)aFloat +{ + [_browserText setFloatValue: aFloat]; +} + +- (void)setIntValue:(int)anInt +{ + [_browserText setIntValue: anInt]; +} + +- (void)setStringValue:(NSString *)aString +{ + [_browserText setStringValue: aString]; +} // // NSCoding protocol @@ -108,12 +265,24 @@ - (void)encodeWithCoder:aCoder { [super encodeWithCoder:aCoder]; + + [aCoder encodeObject: _browserText]; + [aCoder encodeObject: _branchImage]; + [aCoder encodeObject: _highlightBranchImage]; + [aCoder encodeValueOfObjCType: @encode(BOOL) at: &_isLeaf]; + [aCoder encodeValueOfObjCType: @encode(BOOL) at: &_isLoaded]; } - initWithCoder:aDecoder { [super initWithCoder:aDecoder]; + _browserText = [aDecoder decodeObject]; + _branchImage = [aDecoder decodeObject]; + _highlightBranchImage = [aDecoder decodeObject]; + [aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_isLeaf]; + [aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_isLoaded]; + return self; } diff --git a/Source/NSCell.m b/Source/NSCell.m index c3d57adfa..449a6ed9b 100644 --- a/Source/NSCell.m +++ b/Source/NSCell.m @@ -98,6 +98,8 @@ - (id)initImageCell:(NSImage *)anImage { + [super init]; + [self _init]; // Not an image class --then forget it @@ -113,6 +115,8 @@ - (id)initTextCell:(NSString *)aString { + [super init]; + [self _init]; cell_font = [[NSFont userFontOfSize:12] retain]; diff --git a/Source/NSClipView.m b/Source/NSClipView.m index 5eb31c8e1..e3cbf2f69 100644 --- a/Source/NSClipView.m +++ b/Source/NSClipView.m @@ -59,7 +59,7 @@ { [super init]; [self setAutoresizesSubviews:YES]; - [self setBackgroundColor:[[self window] backgroundColor]]; + [self setBackgroundColor:[NSColor lightGrayColor]]; return self; } diff --git a/Source/NSMatrix.m b/Source/NSMatrix.m index f2511d970..279874f48 100644 --- a/Source/NSMatrix.m +++ b/Source/NSMatrix.m @@ -132,7 +132,7 @@ static void growMatrix (tMatrix m, int numRows, int numCols) /* Grow the existing rows to numCols */ for (i = 0; i < numRows; i++) { m->matrix[i] = realloc (m->matrix[i], numCols * sizeof (BOOL)); - for (j = m->allocatedCols; j < numCols; j++) + for (j = m->allocatedCols - 1; j < numCols; j++) m->matrix[i][j] = NO; } m->allocatedCols = numCols; @@ -422,9 +422,9 @@ static int mouseDownFlags = 0; int i; /* Grow the matrix if necessary */ - if (column > numCols) + if (column >= numCols) [self renewRows:(numRows == 0 ? 1 : numRows) columns:column]; - else if (numRows == 0) { + if (numRows == 0) { numRows = 1; [cells addObject:[NSMutableArray array]]; } @@ -443,9 +443,9 @@ static int mouseDownFlags = 0; int i; /* Grow the matrix if necessary */ - if (column > numCols) + if (column >= numCols) [self renewRows:(numRows == 0 ? 1 : numRows) columns:column]; - else if (numRows == 0) { + if (numRows == 0) { numRows = 1; [cells addObject:[NSMutableArray array]]; } @@ -465,9 +465,9 @@ static int mouseDownFlags = 0; int i; /* Grow the matrix if necessary */ - if (row > numRows) + if (row >= numRows) [self renewRows:row columns:(numCols == 0 ? 1 : numCols)]; - else if (numCols == 0) + if (numCols == 0) numCols = 1; [cells insertObject:[NSMutableArray arrayWithCapacity:numCols] atIndex:row]; @@ -485,9 +485,9 @@ static int mouseDownFlags = 0; - (void)insertRow:(int)row withCells:(NSArray*)cellArray { /* Grow the matrix if necessary */ - if (row > numRows) + if (row >= numRows) [self renewRows:row columns:(numCols == 0 ? 1 : numCols)]; - else if (numCols == 0) + if (numCols == 0) numCols = 1; [cells insertObject:[cellArray subarrayWithRange:NSMakeRange(0, numCols)] diff --git a/Source/NSTextFieldCell.m b/Source/NSTextFieldCell.m index b3284cf57..f3b0aba28 100644 --- a/Source/NSTextFieldCell.m +++ b/Source/NSTextFieldCell.m @@ -99,6 +99,7 @@ [c setBackgroundColor: background_color]; [c setTextColor: text_color]; + [c setDrawsBackground: draw_background]; return c; } diff --git a/Source/NSView.m b/Source/NSView.m index fbefdc80a..e330a5e21 100644 --- a/Source/NSView.m +++ b/Source/NSView.m @@ -883,18 +883,30 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil; - (void)_removeSubviewFromViewsThatNeedDisplay:(NSView*)view { + // If no subviews need to be displayed then + // then view must not be among them + if (!_subviewsThatNeedDisplay) + return; + /* Remove view from the list of subviews that need display */ if (_subviewsThatNeedDisplay == view) - _subviewsThatNeedDisplay = view->_nextSiblingSubviewThatNeedsDisplay; + { + _subviewsThatNeedDisplay = view->_nextSiblingSubviewThatNeedsDisplay; + [view _recursivelyResetNeedsDisplayInAllViews]; + } else { NSView* currentView; for (currentView = _subviewsThatNeedDisplay; - currentView->_nextSiblingSubviewThatNeedsDisplay; + currentView && currentView->_nextSiblingSubviewThatNeedsDisplay; currentView = currentView->_nextSiblingSubviewThatNeedsDisplay) if (currentView->_nextSiblingSubviewThatNeedsDisplay == view) - currentView->_nextSiblingSubviewThatNeedsDisplay + { + currentView->_nextSiblingSubviewThatNeedsDisplay = view->_nextSiblingSubviewThatNeedsDisplay; + [view _recursivelyResetNeedsDisplayInAllViews]; + break; + } } } @@ -934,6 +946,7 @@ static NSRecursiveLock *gnustep_gui_nsview_lock = nil; currentView = nextView; } _subviewsThatNeedDisplay = NULL; + _nextSiblingSubviewThatNeedsDisplay = NULL; } - (void)_displayNeededViews diff --git a/Testing/GNUmakefile b/Testing/GNUmakefile index 697f31a67..76bcad344 100644 --- a/Testing/GNUmakefile +++ b/Testing/GNUmakefile @@ -1,13 +1,40 @@ +# +# Testing level makefile for GNUstep GUI Library +# +# Copyright (C) 1997 Free Software Foundation, Inc. +# +# Author: Richard Frith-Macdonald +# +# 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. +# +# If you are interested in a warranty or support for this source code, +# contact Scott Christley at scottc@net-community.com +# +# 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. + include $(GNUSTEP_SYSTEM_ROOT)/Makefiles/common.make # The application to be compiled -TOOL_NAME = testpb +TEST_TOOL_NAME = testpb # The source files to be compiled testpb_OBJC_FILES = testpb.m -include GNUmakefile.preamble -include $(GNUSTEP_SYSTEM_ROOT)/Makefiles/tool.make +include $(GNUSTEP_SYSTEM_ROOT)/Makefiles/test.make -include GNUmakefile.postamble diff --git a/Testing/GNUmakefile.postamble b/Testing/GNUmakefile.postamble index 5f54a155b..dec5a0b97 100644 --- a/Testing/GNUmakefile.postamble +++ b/Testing/GNUmakefile.postamble @@ -15,8 +15,7 @@ # after-all:: # Things to do before installing -before-install:: - $(INSTALL) -m 05755 gpbs $(GNUSTEP_SYSTEM_ROOT)/Tools +# before-install:: # Things to do after installing # after-install:: diff --git a/Testing/GNUmakefile.preamble b/Testing/GNUmakefile.preamble index 4ecdeb101..909088a1b 100644 --- a/Testing/GNUmakefile.preamble +++ b/Testing/GNUmakefile.preamble @@ -27,10 +27,10 @@ ADDITIONAL_INCLUDE_DIRS += -I../Headers -I$(GNUSTEP_SYSTEM_ROOT)/Headers # ADDITIONAL_LDFLAGS += # Additional library directories the linker should search -ADDITIONAL_LIB_DIRS += +ADDITIONAL_LIB_DIRS += -L../Source/$(GNUSTEP_OBJ_DIR) # Additional libraries when linking tools -ADDITIONAL_TOOL_LIBS += -lgnustep-gui +ADDITIONAL_TOOL_LIBS += -lgnustep-gui -ltiff # Additional libraries when linking applications ADDITIONAL_GUI_LIBS += diff --git a/Tools/GNUmakefile b/Tools/GNUmakefile index 8a669b9db..d16f9454f 100644 --- a/Tools/GNUmakefile +++ b/Tools/GNUmakefile @@ -1,3 +1,32 @@ +# +# Tools level makefile for GNUstep GUI Library +# +# Copyright (C) 1997 Free Software Foundation, Inc. +# +# Author: Scott Christley +# +# 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. +# +# If you are interested in a warranty or support for this source code, +# contact Scott Christley at scottc@net-community.com +# +# 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. + +GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_SYSTEM_ROOT) + include $(GNUSTEP_SYSTEM_ROOT)/Makefiles/common.make # The application to be compiled