home *** CD-ROM | disk | FTP | other *** search
- #pragma .h #import <objc/Object.h>
- #pragma .h #import <appkit/graphics.h>
- #pragma .h struct gFlags
- #pragma .h { unsigned isRoot: 1 ;
- #pragma .h unsigned isTarget: 1 ;
- #pragma .h unsigned noDraw: 1 ; } ;
- #import "Glyph.h"
- #import "Terminator.h"
- #import <dpsclient/psops.h>
- #import <appkit/Application.h>
-
-
- @implementation Glyph: Object
- { @public
- NXRect frame ;
- Glyph *is, *then, *ancestor ;
- // these belong as a bitstructure
- struct gFlags flags ;
- char iam[20] ;
- }
-
- - ancestor ;
- { return ancestor ;
- }
-
- - ancestor: aGlyph ;
- { return ancestor = aGlyph ;
- }
-
- -convertFromAncestor: (NXPoint *) aPnt ;
- // Convert aPnt from my ancestor's coord system to
- // my own. Does nothing if I am the root
- { if(!flags.isRoot)
- { aPnt->x -= frame.origin.x ;
- aPnt->y -= frame.origin.y ;
- }
- return self ;
- }
-
-
- -convertFromRootGlyph: (NXPoint *) aPnt ;
- // Convert aPnt from rootGlyph's coord system
- // to my coord system.
- { Glyph *aGlyph ;
- aGlyph = self ;
- while(!aGlyph->flags.isRoot)
- { aPnt->x -= aGlyph->frame.origin.x ;
- aPnt->y -= aGlyph->frame.origin.y ;
- aGlyph = aGlyph->ancestor ;
- if([aGlyph isTerminator])
- { [NXApp printf: "from oops\n"] ;
- return self ;
- }
- }
- return self ;
- }
-
- -convertToAncestor: (NXPoint *) aPnt ;
- // Convert aPnt from my coord system to that
- // of my ancestor. Does nothing if I am the
- // rootGlyph
- { if(!flags.isRoot)
- { aPnt->x += frame.origin.x ;
- aPnt->y += frame.origin.y ;
- }
- return self ;
- }
-
- -convertToRootGlyph: (NXPoint *) aPnt ;
- // Convert aPnt from my coord system
- // to that of the rootGlyph.
- { Glyph *aGlyph ;
- aGlyph = self ;
- while(!aGlyph->flags.isRoot)
- { aPnt->x += aGlyph->frame.origin.x ;
- aPnt->y += aGlyph->frame.origin.y ;
- aGlyph = aGlyph->ancestor ;
- if([aGlyph isTerminator])
- { [NXApp printf: "to oops\n"] ;
- return self ;
- }
- }
- return self ;
- }
-
- - display: (const NXRect *) aRect ;
- { // I traverses a glist recursively,
- // translating coord systems and calling
- // drawself as needed. I only draw if
- // my frame intersects visRect, which
- // must be in my ancestor's coord system.
- // If I am the target: I don't translate...
- // the target's origin is 0.0 with
- // respect to the ground view
- // it is drawing into.
- // If noDraw, then I don't draw myself or
- // any of my subGlyphs. This is used to prevent
- // the target glyph from drawing into the bGrnd.
- if(NXIntersectsRect(aRect,&frame))
- { NXRect bRect, bounds ;
- bRect.size.width = aRect->size.width ;
- bRect.size.height = aRect->size.height ;
- bounds.origin.x = bounds.origin.y = 0.0 ;
- bounds.size.width = frame.size.width ;
- bounds.size.height = frame.size.height ;
- PSgsave() ;
- if(!flags.isTarget)
- { PStranslate(frame.origin.x, frame.origin.y) ;
- bRect.origin.x = aRect->origin.x - frame.origin.x ;
- bRect.origin.y = aRect->origin.y - frame.origin.y ;
- }
- else
- bRect.origin.x = bRect.origin.y = 0.0 ;
- NXIntersectionRect(&bounds,&bRect) ; // don't allow drawing
- NXRectClip(&bRect) ; // outside of my frame or interRect
- if(!flags.noDraw)
- { [self drawSelf: &bRect] ;
- [is display: &bRect] ;
- }
- PSgrestore() ;
- }
- [then display: aRect] ;
- return self ;
- }
-
-
- - drawSelf: (NXRect *) aRect ;
- { // draw my image into whatever is
- // currently focused. Only that part
- // of the image intersecting aRect, in
- // my coord system, needs to be drawn.
- if(flags.isRoot)
- { PSsetgray(0.8) ;
- PSrectfill(aRect->origin.x,aRect->origin.y,
- aRect->size.width,aRect->size.height) ;
- return self ;
- }
- PSsetgray(0.0) ;
- PSmoveto(0.0,0.0) ;
- PSlineto(0.0,frame.size.height) ;
- PSlineto(frame.size.width,frame.size.height);
- PSlineto(frame.size.width,0.0) ;
- PSlineto(0.0,0.0) ;
- PSlineto(frame.size.width,frame.size.height) ;
- PSstroke() ;
- return self ;
- }
-
- - enlist: (Glyph *) aGlyt ;
- { // I am a Glist ; link aGlyt into myself,
- // return the head of the list
- aGlyt->ancestor = ancestor ;
- if([aGlyt precedes: self]) // link before me
- { aGlyt->then = self ;
- return aGlyt ;
- }
- then = [then enlist: aGlyt] ;// ask my neighbour to enlist it
- return self ;
- }
-
-
- - hitTest: (NXPoint *) aPnt ;
- // return id of deepest, leftmost glyph in hierarchy
- // which contains aPnt. aPnt is in my superview's coordinate
- // system. Returns nil if no appropriate glyph can be
- // found (i.e. not in my frame, nor any of my
- // Glist's frames).
- { if(NXPointInRect(aPnt,&frame))
- { id deeperHit ;
- NXPoint thePnt ;
- thePnt.x = aPnt->x - frame.origin.x ; // thePnt = aPnt
- thePnt.y = aPnt->y - frame.origin.y ; // in my coord system
- if(deeperHit = [is hitTest: &thePnt])
- return deeperHit ;
- else
- return self ;
- }
- return [then hitTest: aPnt] ;
- }
-
- - (char *) iam ;
- { return iam ;
- }
-
- - iam: (char *) str ;
- { strcpy(iam,str) ;
- }
-
- - init ;
- { // make sure we are terminated
- [super init];
- is = then = ancestor = [Terminator new] ;
- // cook up a temporary frame
- frame.origin.x = frame.origin.y = 0.0 ;
- frame.size.width = frame.size.height = 50.0 ;
- return self;
- }
-
- - is ;
- { return is ;
- }
-
- - is: aGlyph ;
- { return is = aGlyph ;
- }
-
- - (BOOL) isTerminator ;
- { return NO ;
- }
-
- - moveTo:(float) x :(float)y ;
- { // move my origin to aPnt in my ancestor's
- // coord system.
- frame.origin.x = x ;
- frame.origin.y = y ;
- return self ;
- }
-
- - plant: (Glyph *) aGlyt ;
- { // link aGlyt as a subGlyph of myself, i.e.
- // "plant" it as a branch of my subtree
- aGlyt->ancestor = self ;
- if([is isTerminator])
- is = aGlyt ;
- else
- is = [is enlist: aGlyt] ;
- return self ;
- }
-
- - (BOOL) precedes: (Glyph *) aGlyph ;
- { // answer YES iff aGlyph should come before
- // me in my Glist. Defaults to left-to-right order
- if([aGlyph isTerminator] ||
- (aGlyph->frame.origin.x > frame.origin.x))
- return YES ;
- else
- return NO ;
- }
-
- - sizeTo: (float)width : (float)height ;
- { // changes my size, but does nothing about
- // redisplaying it!
- frame.size.width = width ;
- frame.size.height = height ;
- return self ;
- }
-
-
- - then ;
- { return then ;
- }
-
- - then: aGlyph ;
- { return then = aGlyph ;
- }
-
- - test: (int) anInt ;
- { // remove when you are satisfied...
- char *name = "none" ;
- if(iam[0] != '\0')
- name = iam ;
- [NXApp printf: "(%d %s %s %s %s)\n",anInt,name,[is iam],
- [then iam], [ancestor iam]] ;
- [is test: anInt + 1] ;
- [then test: anInt] ;
- return self ;
- }
-
- - unlink ;
- { // unlink myself (as a Glyt) from the TTree I am a part of.
- // Note: I must be part of a TTree, else bomb!
- if(flags.isRoot) // can't unlink the root glyph!
- return self ;
- if(ancestor->is == self) // the simple case...
- ancestor->is = then ;
- else
- { Glyph *cursor = ancestor->is ;
- while(cursor->then != self) // find predecessor
- cursor = cursor->then ;
- cursor->then = then ;
- }
- ancestor = then = [Terminator new] ;
- return self ;
- }
-
- @end