home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Educational / MolViewer / Source / SelectView.m < prev    next >
Encoding:
Text File  |  1995-06-12  |  3.2 KB  |  182 lines

  1. /* SelectView.m - Copyright 1993  Steve Ludtke */
  2. /* This object displays a list and allows you to select various lines. */
  3. /* Multiple lines can be selected if <shift> is depressed. The order in */
  4. /* which the items were selected is stored in 2 redundant structures */
  5. /* This object works well in a ScrollView */
  6.  
  7. /* funtion is pretty simple, so there aren't many comments. To use it, */
  8. /* just pass it an initialized SELDAT structure (see Mtypes.h) */
  9.  
  10. #import "Mtypes.h"
  11. #import "SelectView.h"
  12. #import "Inspector.h"
  13.  
  14. @implementation SelectView
  15. -initFrame:(const NXRect *)rect
  16. {
  17. [super initFrame:rect];
  18. [self setFlipped:YES];        /* make origin upper left */
  19. nsel=0;
  20. title[0]=gtitle[0]=0;
  21. return self;
  22. }
  23.  
  24. /* initialize everything from passed data structure */
  25. -setData:(int)n :(struct SELDAT *)Data :Notify
  26. {
  27. int i;
  28.  
  29. data=Data;
  30. ndat=n;
  31. notify=Notify;
  32. nsel=0;
  33.  
  34. for (i=0; i<n; i++) { data[i].sel=0; data[i].stab= -1; }
  35.  
  36. [self sizeTo:frame.size.width :12.0*(n+1)];
  37. [self display];
  38. return self;
  39. }
  40.  
  41. -setHeader:(char *)Title
  42. {
  43. strcpy(title,Title);
  44. return self;
  45. }
  46.  
  47. -setGHeader:(char *)Title
  48. {
  49. strcpy(gtitle,Title);
  50. return self;
  51. }
  52.  
  53. -select:(int)n
  54. {
  55. if (data[n].sel) return self;
  56.  
  57. data[nsel].stab=n;        /* store selected line in list */
  58. nsel++;
  59. data[n].sel=nsel;        /* tag this item as selected */
  60.  
  61. [self display];
  62. if (notify) [notify selected:n :nsel];
  63. return self;
  64. }
  65.  
  66. /* somewhat messy deselect routine, I should clean it up a bit sometime */
  67. -deselect:(int)n
  68. {
  69. int i;
  70.  
  71. if (!data[n].sel) return self;
  72. for (i=data[n].sel-1; i<nsel; i++) data[i].stab=data[i+1].stab;
  73. nsel--;
  74. data[n].sel=0;
  75. for (i=0; i<nsel; i++) data[data[i].stab].sel=i+1;
  76.  
  77. [self display];
  78. if (notify) [notify deselected:n :nsel];
  79. return self;
  80. }
  81.  
  82. -mouseDown:(NXEvent *)oevent 
  83. {
  84. int n,f=0;
  85. NXEvent evs;
  86. float ix,iy;
  87.  
  88. evs=*oevent;
  89. oevent=&evs;
  90. [self convertPoint:&oevent->location fromView:nil];
  91. ix=oevent->location.x;
  92. iy=oevent->location.y;
  93.  
  94. n=floor(iy/12.0)-1;
  95. if (n==-1) return self;
  96. if (data[n].sel) f=1;
  97. if (evs.flags&NX_SHIFTMASK) {
  98.     if (f) [self deselect:n];
  99.     else [self select:n];
  100. }
  101. else {
  102.     if (nsel==1&&f) [self deselect:n];
  103.     else {
  104.         [self deselectAll];  
  105.         [self select:n];
  106.     }
  107. }
  108. return self;
  109. }
  110.  
  111. -selectAll:sender
  112. {
  113. int i;
  114.  
  115. for (i=0; i<ndat; i++) data[i].sel=data[i].stab=i+1;
  116. nsel=ndat;
  117.  
  118. [self display];
  119. if (notify) [notify selected:0 :nsel];
  120. return self;
  121. }
  122.  
  123. -deselectAll
  124. {
  125. int i;
  126.  
  127. for (i=0; i<ndat; i++) { data[i].sel=0; data[i].stab= -1; }
  128. nsel=0;
  129. [self display];
  130. return self;
  131. }
  132.  
  133. -drawSelf:(const NXRect *)rects :(int)nr
  134. {
  135. int i,j,f,l;
  136. NXRect fill;
  137.  
  138. PSsetohlfs();
  139. for (i=0; i<nr; i++) {
  140.     PSsetgray(1.0);
  141.     NXRectFill(&rects[i]);
  142.     f=floor(rects[i].origin.y/12.0)-1;
  143.     l=f+1+floor(rects[i].size.height/12.0);
  144.     if (l>=ndat) l=ndat-1;
  145.     if (f>=ndat) f=l+1;
  146.     if (f==-1) {
  147.         PSsetgray(0.0);
  148.         PSmoveto(0,10.0);
  149.         PSshow(title);
  150.         f++;
  151.         /* this will overlay a title in the symbol font if available */
  152.         if (strlen(gtitle)!=0) {
  153.             PSsetsymb();
  154.             PSmoveto(0,10.0);
  155.             PSshow(gtitle);
  156.             PSsetohlfs();
  157.         }
  158.         PSstroke();
  159.     }
  160.     for (j=f; j<=l; j++) {
  161.         if (data[j].sel) {
  162.             PSsetgray(.6666667);
  163.             fill=frame;
  164.             fill.origin.y=j*12.0+12.0;
  165.             fill.size.height=12.0;
  166.             NXRectFill(&fill);
  167.         }
  168.         PSsetgray(0.0);
  169.         PSmoveto(0,(float)j*12.0+22.0);
  170.         PSshow(data[j].text);
  171.         PSstroke();
  172.     }
  173. }
  174. return self;
  175. }
  176.  
  177. -(BOOL)acceptsFirstMouse
  178. {
  179. return YES;
  180. }
  181. @end
  182.