home *** CD-ROM | disk | FTP | other *** search
- /* 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 (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:n :nsel];
- return self;
- }
-
- /* somewhat messy deselect routine, I should clean it up a bit sometime */
- -deselect:(int)n
- {
- int i;
-
- 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:n :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: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(0,10.0);
- PSshow(title);
- f++;
- /* this will overlay a title in the symbol font if available */
- if (strlen(gtitle)!=0) {
- PSsetsymb();
- PSmoveto(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(0,(float)j*12.0+22.0);
- PSshow(data[j].text);
- PSstroke();
- }
- }
- return self;
- }
-
- -(BOOL)acceptsFirstMouse
- {
- return YES;
- }
- @end
-