This is MiscSplitBrowser.m in view mode; [Download] [Up]
// Tue Mar 5 20:28:08 MET 1996
#import "MiscSplitBrowser.h"
/* toDo fix graphicbug in initial display (on the right)
* (which diappears by ther way after niling out a view and then move the divider
* back to the middle)
*/
enum {MiscLeft=0,MiscRight=1};
# define MISCSPLITBROWSER_VERSION 1
@implementation MiscSplitBrowser
+ initialize
{ if(self == [MiscSplitBrowser class])
{ [self setVersion:MISCSPLITBROWSER_VERSION];
}
[self setMatrixClass:[Matrix class]];
return self;
}
static id matrixClass;
+ matrixClass
{ return matrixClass;
}
+ setMatrixClass:theMatrixClass
{ return matrixClass=theMatrixClass;
}
#if 0
- getBounds:(NXRect *)lr
{ NXCoord borderWidth=-5;
[super getBounds:lr];
lr->origin.x+=borderWidth,lr->origin.y+=borderWidth;
lr->size.width-=(borderWidth*2),lr->size.height-=(borderWidth*2);
return self;
}
#endif
-(Matrix*) createMatrix:(NXRect *) theRect
{ Matrix *theMatrix=[[MiscSplitBrowser matrixClass] alloc];
theMatrix=[theMatrix initFrame:theRect];
[theMatrix setAutoscroll:YES];
[theMatrix setEmptySelectionEnabled:NO];
[theMatrix setCellClass:[NXBrowserCell class]];
[theMatrix setTarget:self],[theMatrix setAction:@selector(didClick:)];
return theMatrix;
}
- initFrame:(NXRect *) theRect
{ NXRect halfRect=*theRect;
ScrollView *leftScroll=[ScrollView alloc],*rightScroll=[ScrollView alloc];
halfRect.size.width/=2;
leftScroll=[leftScroll initFrame:&halfRect], rightScroll=[rightScroll initFrame:&halfRect];
[leftScroll setVertScrollerRequired:YES];
[leftScroll setBorderType:NX_BEZEL];
[rightScroll setVertScrollerRequired:YES];
[rightScroll setBorderType:NX_BEZEL];
[leftScroll setDocView: leftMatrix=[self createMatrix:&halfRect]];
[rightScroll setDocView:rightMatrix=[self createMatrix:&halfRect]];
[super initFrame:theRect];
[self setLeftView:leftScroll];
[self setRightView:rightScroll];
[self initViews];
pathSeparator='/';
return self;
}
- setSizeForMatrix:(Matrix *)theMatrix
{ NXRect theRect;
NXSize cellSize;
[theMatrix getCellSize:&cellSize];
[[theMatrix superview] getFrame:&theRect];
cellSize.width= theRect.size.width;
[theMatrix setCellSize:&cellSize];
[theMatrix sizeToCells];
return self;
}
- sideSplitViewDidResizeSubviews: sender
{ [self setSizeForMatrix:leftMatrix];
[self setSizeForMatrix:rightMatrix];
return self;
}
- selectCellNamed:(const char*)theName inMatrix:(Matrix*)theMatrix
{ List *cellList=[theMatrix cellList];
Cell *currCell;
int i;
for(i=0; currCell=[cellList objectAt:i];i++)
{ if(!strcmp([currCell stringValue],theName))
{ [theMatrix selectCellAt:i:0];
[theMatrix scrollCellToVisible:i:0];
return self;
}
} return nil;
}
- setPath:(const char *)thePath
{ char *str=NXCopyStringBuffer(thePath),
*ps=strchr(str,pathSeparator),*ps1;
if(ps) *ps=0;
[self selectCellNamed:str inMatrix:leftMatrix];
[self reloadColumn:1];
if(ps)
{ ps1=strchr(ps+1,pathSeparator);
if(ps1) *ps1=0;
[self selectCellNamed:ps+1 inMatrix:rightMatrix];
}
[self sendAction];
free((void*) str);
return self;
}
-(char *) getPath:(char *)pathString toColumn:(int) column
{ switch(MAX(column-1,0))
{ case MiscLeft:
sprintf(pathString,"%c%s",pathSeparator,[[leftMatrix selectedCell] stringValue]);
if(strlen(pathString) == 1) pathString[0]=0;
break;
case MiscRight:
{ const char *rptr=[[rightMatrix selectedCell] stringValue];
sprintf(pathString,"%c%s%c%s",pathSeparator,[[leftMatrix selectedCell] stringValue],
rptr? pathSeparator:0,rptr? rptr:"");
} break;
} return pathString;
}
- sendAction
{ if(target && action) [NXApp sendAction:action to:target from:self];
return self;
}
- reloadColumn:(int) theColumn
{ int numRows;
Matrix *theMatrix=nil;
[window disableFlushWindow];
switch(theColumn) // [self matrixOfColumn
{ case MiscLeft:
theMatrix=leftMatrix;
break;
case MiscRight:
theMatrix=rightMatrix;
break;
default: return nil;
}
numRows=[browserDelegate browser:self fillMatrix:theMatrix inColumn:theColumn];
[theMatrix renewRows:numRows cols:1];
[self setSizeForMatrix:theMatrix];
[theMatrix display];
[[window reenableFlushWindow] flushWindow];
return self;
}
- didClick:sender
{ if(sender == leftMatrix)
{ [self reloadColumn:1];
} return [self sendAction];
}
-(int) indexOfSelectedCellInMatrix:(Matrix*) theMatrix
{ int x,y;
if(!theMatrix) return -1;
[theMatrix getRow:&y andCol:&x ofCell:[theMatrix selectedCell]];
return y;
}
- loadColumnZeroPreserveSel:(BOOL)preserve
{ int leftSel=[self indexOfSelectedCellInMatrix:leftMatrix],
rightSel=[self indexOfSelectedCellInMatrix:rightMatrix];
if(preserve) [window disableFlushWindow];
[self reloadColumn:0];
if(preserve && leftSel >=0) [leftMatrix selectCellAt:leftSel:0];
if([leftMatrix selectedCell]) [self reloadColumn:1];
if(preserve && rightSel >=0) [rightMatrix selectCellAt:rightSel:0];
if(preserve) [[window reenableFlushWindow] flushWindow];
[self sendAction];
return self;
}
- loadColumnZero
{ return [self loadColumnZeroPreserveSel:NO];
}
-(Matrix*) matrixInColumn:(int) col
{ switch(col)
{ case MiscLeft: return leftMatrix;
case MiscRight: return rightMatrix;
} return nil;
}
-(int) selectedColumn
{ if([rightMatrix selectedCell]) return MiscRight;
if([leftMatrix selectedCell]) return MiscLeft;
return -1;
}
-(int) selectedRow
{ Matrix *theMatrix=[self matrixInColumn:[self selectedColumn]];
if(!theMatrix) return -1;
else return [self indexOfSelectedCellInMatrix:theMatrix];
}
-(int) lastColumn
{ if(![rightMatrix cellCount]) return MiscLeft;
else return MiscRight;
}
-(Matrix*) selectedMatrix
{ int selCol=[self selectedColumn];
if(selCol == -1) return nil;
return [self matrixInColumn:selCol];
}
-(Cell *) selectedCell
{ return [[self selectedMatrix] selectedCell];
}
- emptyValidationForRow:(int)y inMatrix:(Matrix *) theMatrix minCount:(int)min
{ if([theMatrix cellCount] > min)
{ if(y == [theMatrix cellCount]-1)
[theMatrix selectCellAt:MAX(y-1,0):0];
return self;
} return nil;
}
- reestablishSelection
{ [window disableFlushWindow];
if(([self selectedColumn] == MiscLeft) || ![self emptyValidationForRow:[self indexOfSelectedCellInMatrix:rightMatrix]
inMatrix:rightMatrix minCount:1])
{ [self emptyValidationForRow:[self indexOfSelectedCellInMatrix:leftMatrix] inMatrix:leftMatrix minCount:0];
} [[window reenableFlushWindow] flushWindow];
return self;
}
- selectPrevious
{
return self;
}
- selectNext
{
return self;
}
- acceptArrowKeys:(BOOL) doAccept andSendActionMessages:(BOOL) doSendActions
{
return self;
}
- (id)target
{ return target;
}
- setTarget:(id)aTarget
{ target=aTarget;
return self;
}
- (SEL)action
{ return action;
}
- setAction:(SEL)aAction
{ action=aAction;
return self;
}
- (unsigned short)pathSeparator
{ return pathSeparator;
}
- setPathSeparator:(unsigned short)aPathSeparator
{ pathSeparator=aPathSeparator;
return self;
}
- (SEL)doubleAction
{ return doubleAction;
}
- setDoubleAction:(SEL)aDoubleAction
{ doubleAction=aDoubleAction;
return self;
}
- (id)browserDelegate
{ return browserDelegate;
}
- setBrowserDelegate:(id)aBrowserDelegate
{ browserDelegate=aBrowserDelegate;
return self;
}
- setDelegate:theDelegate
{ [super setDelegate:theDelegate];
if(![self browserDelegate])
[self setBrowserDelegate:theDelegate];
return self;
}
- leftView
{ return leftView;
}
- rightView
{ return rightView;
}
- setDivider:(NXCoord) divx
{ dividerRect.origin.x =divx;
[window disableFlushWindow];
[self adjustSubviews];
[self display];
[[window reenableFlushWindow] flushWindow];
return self;
}
- awake
{ [super awake];
return self;
}
- read:(NXTypedStream *)stream
{ int version;
[super read:stream];
version = NXTypedStreamClassVersion(stream, "MiscSplitBrowser");
/*
* **** Archiving: READ ME **** This code (and its analogue in write:) is
* critical. When you bump MISC_DRAG_VIEW_VERSION, copy the whole _current_
* case ("case MISC_DRAG_VIEW_VERSION: ... break;"), and duplicate it.
* Change the "MISC_DRAG_VIEW_VERSION" in the old case to the OLD
* (pre-bump) version number. Now, dork the "new current" version into
* whatever you want. See how this code can now read EITHER version out of
* the typed stream?
*
* If you are adding yet another version, leave the previous versions in
* place. That way you can still read archived objects that are more than
* one version old. Don't forget to take whatever actions are necessary to
* harmonize those old values. For example, if you converted an "int" ivar
* to "double", you'd need to (in the old version) to read the int version
* into a temp variable, and convert it in to the double var. BJM 5/24/94
*/
switch (version)
{ case 1:
NXReadTypes(stream,"@::I@",&target,&action,&doubleAction,&pathSeparator,
&browserDelegate);
leftMatrix=NXReadObject(stream);
rightMatrix=NXReadObject(stream);
break;
} return self;
}
- write:(NXTypedStream *)stream
{ [super write:stream];
/*
* **** Archiving: READ ME **** Home stretch. Now (just like read:)
* duplicate the current case ("case MISC_DRAG_VIEW_VERSION: ... break;").
* Once again, change the "MISC_DRAG_VIEW_VERSION" of the first one to the
* OLD version number. Now adjust the new/current MISC_DRAG_VIEW_VERSION
* (remember, you've bumped it) to the new way of writing vars. See how
* this code (because the constant is in the switch statement) always
* writes out ONLY the current version, but leaves the old version(s)
* around to posterity. DO NOT DELETE THE OLD VERSIONS. Leave them to
* clutter up the world. BJM 5/24/94
*/
switch (MISCSPLITBROWSER_VERSION)
{ case MISCSPLITBROWSER_VERSION:
NXWriteTypes(stream,"@::I@",&target,&action,&doubleAction,&pathSeparator,
&browserDelegate);
NXWriteObject(stream,leftMatrix); // was writing references
NXWriteObject(stream,rightMatrix); // was writing references
break;
} return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.