This is SelectView.m in view mode; [Download] [Up]
/* SelectView.m - Copyright 1993 Steve Ludtke */ /* This object displays a list and allows you to select various lines. */ /* Multiple lines can be selected if <shift> is depressed. The order in */ /* which the items were selected is stored in 2 redundant structures */ /* This object works well in a ScrollView */ /* funtion is pretty simple, so there aren't many comments. To use it, */ /* just pass it an initialized SELDAT structure (see Mtypes.h) */ #import "Mtypes.h" #import "SelectView.h" #import "Inspector.h" @implementation SelectView -initFrame:(const NXRect *)rect { [super initFrame:rect]; [self setFlipped:YES]; /* make origin upper left */ nsel=0; title[0]=gtitle[0]=0; return self; } /* initialize everything from passed data structure */ -setData:(int)n :(struct SELDAT *)Data :Notify { int i; data=Data; ndat=n; notify=Notify; nsel=0; for (i=0; i<n; i++) { data[i].sel=0; data[i].stab= -1; } [self sizeTo:frame.size.width :12.0*(n+1)]; [self display]; return self; } -setHeader:(char *)Title { strcpy(title,Title); return self; } -setGHeader:(char *)Title { strcpy(gtitle,Title); return self; } -select:(int)n { if (n>=ndat||n<0) return self; if (data[n].sel) return self; data[nsel].stab=n; /* store selected line in list */ nsel++; data[n].sel=nsel; /* tag this item as selected */ [self display]; if (notify) [notify selected:self :n :nsel]; return self; } -selectAry:(short)n :(short *)sel { int i; [self deselectAll]; for (i=0; i<n; i++) { data[nsel].stab=sel[i]; nsel++; data[sel[i]].sel=nsel; } [self display]; if (notify&&nsel) [notify selected:self :sel[0] :nsel]; else if (notify) [notify deselected:self :0 :0]; return self; } /* somewhat messy deselect routine, I should clean it up a bit sometime */ -deselect:(int)n { int i; if (n>=ndat||n<0) return self; if (!data[n].sel) return self; for (i=data[n].sel-1; i<nsel; i++) data[i].stab=data[i+1].stab; nsel--; data[n].sel=0; for (i=0; i<nsel; i++) data[data[i].stab].sel=i+1; [self display]; if (notify) [notify deselected:self :n :nsel]; return self; } -notifyO { if (notify) [notify deselected:self :0 :nsel]; return self; } -mouseDown:(NXEvent *)oevent { int n,f=0; NXEvent evs; float ix,iy; evs=*oevent; oevent=&evs; [self convertPoint:&oevent->location fromView:nil]; ix=oevent->location.x; iy=oevent->location.y; n=floor(iy/12.0)-1; if (n==-1) return self; if (data[n].sel) f=1; if (evs.flags&NX_SHIFTMASK) { if (f) [self deselect:n]; else [self select:n]; } else { if (nsel==1&&f) [self deselect:n]; else { [self deselectAll]; [self select:n]; } } return self; } -selectAll:sender { int i; for (i=0; i<ndat; i++) data[i].sel=data[i].stab=i+1; nsel=ndat; [self display]; if (notify) [notify selected:self :0 :nsel]; return self; } -deselectAll { int i; for (i=0; i<ndat; i++) { data[i].sel=0; data[i].stab= -1; } nsel=0; [self display]; return self; } -drawSelf:(const NXRect *)rects :(int)nr { int i,j,f,l; NXRect fill; PSsetohlfs(); for (i=0; i<nr; i++) { PSsetgray(1.0); NXRectFill(&rects[i]); f=floor(rects[i].origin.y/12.0)-1; l=f+1+floor(rects[i].size.height/12.0); if (l>=ndat) l=ndat-1; if (f>=ndat) f=l+1; if (f==-1) { PSsetgray(0.0); PSmoveto(1.0,10.0); PSshow(title); f++; /* this will overlay a title in the symbol font if available */ if (strlen(gtitle)!=0) { PSsetsymb(); PSmoveto(1.0,10.0); PSshow(gtitle); PSsetohlfs(); } PSstroke(); } for (j=f; j<=l; j++) { if (data[j].sel) { PSsetgray(.6666667); fill=frame; fill.origin.y=j*12.0+12.0; fill.size.height=12.0; NXRectFill(&fill); } PSsetgray(0.0); PSmoveto(1.0,(float)j*12.0+22.0); PSshow(data[j].text); PSstroke(); } } return self; } -(BOOL)acceptsFirstMouse { return YES; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.