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.