home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.mdf / Apps / DevTools / ClassBuilder / Source / Glyph.m < prev    next >
Encoding:
Text File  |  1993-01-25  |  6.7 KB  |  286 lines

  1. #pragma .h  #import <objc/Object.h> 
  2. #pragma .h #import <appkit/graphics.h>
  3. #pragma .h struct gFlags
  4. #pragma .h { unsigned isRoot: 1 ;
  5. #pragma .h   unsigned isTarget: 1 ;
  6. #pragma .h   unsigned noDraw: 1 ; } ;
  7. #import "Glyph.h"
  8. #import "Terminator.h"
  9. #import <dpsclient/psops.h>
  10. #import <appkit/Application.h>
  11.  
  12.  
  13. @implementation Glyph: Object
  14. { @public
  15.   NXRect frame ;
  16.   Glyph *is, *then, *ancestor ;
  17.   // these belong as a bitstructure
  18.   struct gFlags flags ;
  19.   char iam[20] ;
  20. }
  21.  
  22. - ancestor ;
  23. { return ancestor ;
  24. }
  25.  
  26. - ancestor: aGlyph ;
  27. { return ancestor = aGlyph ;
  28. }
  29.  
  30. -convertFromAncestor: (NXPoint *) aPnt ;
  31. // Convert aPnt from my ancestor's coord system to 
  32. // my own. Does nothing if I am the root
  33. { if(!flags.isRoot)
  34.   { aPnt->x -= frame.origin.x ;
  35.     aPnt->y -= frame.origin.y ;
  36.   }
  37.   return self ;
  38. }
  39.  
  40.  
  41. -convertFromRootGlyph: (NXPoint *) aPnt ;
  42. // Convert aPnt from rootGlyph's coord system
  43. // to my coord system.
  44. { Glyph *aGlyph ;
  45.   aGlyph = self ;
  46.   while(!aGlyph->flags.isRoot) 
  47.   { aPnt->x -= aGlyph->frame.origin.x ;
  48.     aPnt->y -= aGlyph->frame.origin.y ;
  49.     aGlyph = aGlyph->ancestor ;
  50.  if([aGlyph isTerminator])
  51.  { [NXApp printf: "from oops\n"] ;
  52.    return self ;
  53.  }
  54.   }
  55.    return self ; 
  56. }
  57.  
  58. -convertToAncestor: (NXPoint *) aPnt ;
  59. // Convert aPnt from my coord system to that
  60. // of my ancestor. Does nothing if I am the
  61. // rootGlyph
  62. { if(!flags.isRoot)
  63.   { aPnt->x += frame.origin.x ;
  64.     aPnt->y += frame.origin.y ;
  65.   }
  66.   return self ;
  67. }
  68.  
  69. -convertToRootGlyph: (NXPoint *) aPnt ;
  70. // Convert aPnt from my coord system
  71. // to that of the rootGlyph.
  72. { Glyph *aGlyph ;
  73.   aGlyph = self ;
  74.   while(!aGlyph->flags.isRoot)
  75.   { aPnt->x += aGlyph->frame.origin.x ;
  76.     aPnt->y += aGlyph->frame.origin.y ;
  77.     aGlyph = aGlyph->ancestor ;
  78.  if([aGlyph isTerminator])
  79.  { [NXApp printf: "to oops\n"] ;
  80.    return self ;
  81.  }
  82.   }
  83.   return self ; 
  84. }
  85.  
  86. - display: (const NXRect *) aRect ;
  87. { // I traverses a glist recursively, 
  88.   // translating coord systems and calling
  89.   // drawself as needed. I only draw if
  90.   // my frame intersects visRect, which
  91.   // must be in my ancestor's coord system.
  92.   // If I am the target: I don't translate...
  93.   // the target's origin is 0.0 with
  94.   // respect to the ground view
  95.   // it is drawing into. 
  96.   // If noDraw, then I don't draw myself or
  97.   // any of my subGlyphs. This is used to prevent 
  98.   // the target glyph from drawing into the bGrnd.
  99.   if(NXIntersectsRect(aRect,&frame))
  100.   { NXRect bRect, bounds ;
  101.     bRect.size.width = aRect->size.width ;
  102.     bRect.size.height = aRect->size.height ;
  103.     bounds.origin.x = bounds.origin.y = 0.0 ;
  104.     bounds.size.width = frame.size.width ;
  105.     bounds.size.height = frame.size.height ;
  106.     PSgsave() ;
  107.     if(!flags.isTarget)
  108.     { PStranslate(frame.origin.x, frame.origin.y) ;
  109.       bRect.origin.x = aRect->origin.x - frame.origin.x ;
  110.       bRect.origin.y = aRect->origin.y - frame.origin.y ;
  111.     }
  112.     else
  113.       bRect.origin.x = bRect.origin.y = 0.0 ;
  114.     NXIntersectionRect(&bounds,&bRect) ; // don't allow drawing
  115.     NXRectClip(&bRect) ; // outside of my frame or interRect 
  116.     if(!flags.noDraw) 
  117.     { [self drawSelf: &bRect] ;
  118.       [is display: &bRect] ;
  119.     }
  120.     PSgrestore() ;
  121.   }
  122.   [then display: aRect] ;
  123.   return self ;
  124. }
  125.  
  126.  
  127. - drawSelf: (NXRect *) aRect ;
  128. { // draw my image into whatever is
  129.   // currently focused. Only that part
  130.   // of the image intersecting aRect, in
  131.   // my coord system, needs to be drawn.
  132.   if(flags.isRoot) 
  133.   { PSsetgray(0.8) ;
  134.     PSrectfill(aRect->origin.x,aRect->origin.y,
  135.     aRect->size.width,aRect->size.height) ;
  136.     return self ;
  137.   }
  138.   PSsetgray(0.0) ;
  139.   PSmoveto(0.0,0.0) ;
  140.   PSlineto(0.0,frame.size.height) ;
  141.   PSlineto(frame.size.width,frame.size.height);
  142.   PSlineto(frame.size.width,0.0) ;
  143.   PSlineto(0.0,0.0) ;
  144.   PSlineto(frame.size.width,frame.size.height) ;
  145.   PSstroke() ;
  146.   return self ;
  147. }
  148.  
  149. - enlist: (Glyph *) aGlyt ;
  150. { // I am a Glist ; link aGlyt into myself,
  151.   // return the head of the list
  152.   aGlyt->ancestor = ancestor ;
  153.   if([aGlyt precedes: self]) // link before me
  154.   { aGlyt->then = self ;
  155.     return aGlyt ;
  156.   }
  157.   then = [then enlist: aGlyt] ;// ask my neighbour to enlist it
  158.   return self ; 
  159. }
  160.  
  161.  
  162. - hitTest: (NXPoint *) aPnt ;
  163. // return id of deepest, leftmost glyph in hierarchy
  164. // which contains aPnt.  aPnt is in my superview's coordinate
  165. // system. Returns nil if no appropriate glyph can be
  166. // found (i.e. not in my frame, nor any of my
  167. // Glist's frames).
  168. { if(NXPointInRect(aPnt,&frame))
  169.   { id deeperHit ;
  170.     NXPoint thePnt ;
  171.     thePnt.x = aPnt->x - frame.origin.x ; // thePnt = aPnt
  172.     thePnt.y = aPnt->y - frame.origin.y ; // in my coord system
  173.     if(deeperHit = [is hitTest: &thePnt])
  174.       return deeperHit ;
  175.     else
  176.       return self ;
  177.   }
  178.   return [then hitTest: aPnt] ;
  179. }
  180.  
  181. - (char *) iam ;
  182. { return iam ;
  183. }
  184.  
  185. - iam: (char *) str ;
  186. { strcpy(iam,str) ;
  187. }
  188.  
  189. - init ;
  190. { // make sure we are terminated
  191.   [super init];
  192.   is = then = ancestor = [Terminator new] ;  
  193.   // cook up a temporary frame
  194.   frame.origin.x = frame.origin.y = 0.0 ;
  195.   frame.size.width = frame.size.height = 50.0 ;
  196.   return self;
  197. }
  198.  
  199. - is ;
  200. { return is ;
  201. }
  202.  
  203. - is: aGlyph ;
  204. { return is = aGlyph ;
  205. }
  206.  
  207. - (BOOL) isTerminator ;
  208. { return NO ;
  209. }
  210.  
  211. - moveTo:(float) x :(float)y ;
  212. { // move my origin to aPnt in my ancestor's
  213.   // coord system.
  214.   frame.origin.x = x ;
  215.   frame.origin.y = y ;
  216.   return self ;
  217. }
  218.  
  219. - plant: (Glyph *) aGlyt ;
  220. { // link aGlyt as a subGlyph of myself, i.e.
  221.   // "plant" it as a branch of my subtree
  222.   aGlyt->ancestor = self ;
  223.   if([is isTerminator])
  224.     is = aGlyt ;
  225.   else
  226.     is = [is enlist: aGlyt] ;
  227.   return self ;
  228. }
  229.  
  230. - (BOOL) precedes: (Glyph *) aGlyph ;
  231. { // answer YES iff aGlyph should come before
  232.   // me in my Glist. Defaults to left-to-right order
  233.   if([aGlyph isTerminator] ||
  234.     (aGlyph->frame.origin.x > frame.origin.x))
  235.     return YES ;
  236.   else
  237.     return NO ;
  238. }
  239.  
  240. - sizeTo: (float)width : (float)height ;
  241. { // changes my size, but does nothing about
  242.   // redisplaying it!
  243.   frame.size.width = width ;
  244.   frame.size.height = height ;
  245.   return self ;
  246. }
  247.  
  248.  
  249. - then ;
  250. { return then ;
  251. }
  252.  
  253. - then: aGlyph ;
  254. { return then = aGlyph ;
  255. }
  256.  
  257. - test: (int) anInt ;
  258. { // remove when you are satisfied...
  259.   char *name = "none" ;
  260.   if(iam[0] != '\0')
  261.     name = iam ;
  262.   [NXApp printf: "(%d %s %s %s %s)\n",anInt,name,[is iam],
  263.        [then iam], [ancestor iam]] ;
  264.   [is test: anInt + 1] ;
  265.   [then test: anInt] ;
  266.   return self ;
  267. }
  268.  
  269. - unlink ;
  270. { // unlink myself (as a Glyt) from the TTree I am a part of.
  271.   // Note: I must be part of a TTree, else bomb!
  272.   if(flags.isRoot) // can't unlink the root glyph!
  273.     return self ;
  274.   if(ancestor->is == self) // the simple case...
  275.     ancestor->is = then ;
  276.   else 
  277.   { Glyph *cursor = ancestor->is ;
  278.     while(cursor->then != self) // find predecessor
  279.       cursor = cursor->then ;
  280.     cursor->then = then ;
  281.   }
  282.   ancestor = then = [Terminator new] ;
  283.   return self ;
  284. }
  285.  
  286. @end