home *** CD-ROM | disk | FTP | other *** search
/ Superpower (Alt) / SUPERPOWER.iso / q / source / zview.m < prev   
Encoding:
Text File  |  1996-08-08  |  15.0 KB  |  873 lines

  1.  
  2. #import "qedefs.h"
  3.  
  4. id zview_i;
  5.  
  6. id zscrollview_i, zscalemenu_i, zscalebutton_i;
  7.  
  8. float    zplane;
  9. float    zplanedir;
  10.  
  11. @implementation ZView 
  12.  
  13. /*
  14. ==================
  15. initFrame:
  16. ==================
  17. */
  18. - initFrame:(const NXRect *)frameRect
  19. {
  20.     NXPoint    pt;
  21.     
  22.     origin[0] = 0.333;
  23.     origin[1] = 0.333;
  24.     
  25.     [super initFrame:frameRect];
  26.     [self allocateGState];
  27.     [self clearBounds];
  28.     
  29.     zview_i = self;
  30.     scale = 1;
  31.     
  32. //        
  33. // initialize the pop up menus
  34. //
  35.     zscalemenu_i = [[PopUpList alloc] init];
  36.     [zscalemenu_i setTarget: self];
  37.     [zscalemenu_i setAction: @selector(scaleMenuTarget:)];
  38.  
  39.     [zscalemenu_i addItem: "12.5%"];
  40.     [zscalemenu_i addItem: "25%"];
  41.     [zscalemenu_i addItem: "50%"];
  42.     [zscalemenu_i addItem: "75%"];
  43.     [zscalemenu_i addItem: "100%"];
  44.     [zscalemenu_i addItem: "200%"];
  45.     [zscalemenu_i addItem: "300%"];
  46.     [[zscalemenu_i itemList] selectCellAt: 4 : 0];
  47.     
  48.     zscalebutton_i = NXCreatePopUpListButton(zscalemenu_i);
  49.  
  50.  
  51. // initialize the scroll view
  52.     zscrollview_i = [[ZScrollView alloc] 
  53.         initFrame:         frameRect 
  54.         button1:         zscalebutton_i
  55.     ];
  56.     [zscrollview_i setAutosizing: NX_WIDTHSIZABLE | NX_HEIGHTSIZABLE];
  57.  
  58.     [[zscrollview_i setDocView: self] free];
  59.  
  60. //    [superview setDrawOrigin: 0 : 0];
  61.  
  62.     minheight = 0;
  63.     maxheight = 64;
  64.  
  65.     pt.x = -bounds.size.width;
  66.     pt.y = -128;
  67.  
  68.     [self newRealBounds];
  69.     
  70.     [self setOrigin: &pt scale: 1];
  71.     
  72.     return zscrollview_i;
  73. }
  74.  
  75. - setXYOrigin: (NXPoint *)pt
  76. {
  77.     origin[0] = pt->x + 0.333;
  78.     origin[1] = pt->y + 0.333;
  79.     return self;
  80. }
  81.  
  82. - (float)currentScale
  83. {
  84.     return scale;
  85. }
  86.  
  87. /*
  88. ===================
  89. setOrigin:scale:
  90. ===================
  91. */
  92. - setOrigin: (NXPoint *)pt scale: (float)sc
  93. {
  94.     NXRect        sframe;
  95.     NXRect        newbounds;
  96.     
  97. //
  98. // calculate the area visible in the cliprect
  99. //
  100.     scale = sc;
  101.     
  102.     [superview getFrame: &sframe];
  103.     [superview getFrame: &newbounds];
  104.     newbounds.origin = *pt;
  105.     newbounds.size.width /= scale; 
  106.     newbounds.size.height /= scale; 
  107.     
  108. //
  109. // union with the realbounds
  110. //
  111.     if (newbounds.origin.y > oldminheight)
  112.     {
  113.         newbounds.size.height += newbounds.origin.y - oldminheight;
  114.         newbounds.origin.y = oldminheight;
  115.     }
  116.     if (newbounds.origin.y+newbounds.size.height < oldmaxheight)
  117.     {
  118.         newbounds.size.height += oldmaxheight
  119.          - (newbounds.origin.y + newbounds.size.height);
  120.     }
  121.  
  122. //
  123. // redisplay everything
  124. //
  125.     [quakeed_i disableDisplay];
  126.  
  127. //
  128. // size this view
  129. //
  130.     [self sizeTo: newbounds.size.width : newbounds.size.height];
  131.     [self setDrawOrigin: -newbounds.size.width/2 : newbounds.origin.y];
  132.     [self moveTo: -newbounds.size.width/2 : newbounds.origin.y];
  133.     
  134. //
  135. // scroll and scale the clip view
  136. //
  137.     [superview setDrawSize
  138.         : sframe.size.width/scale 
  139.         : sframe.size.height/scale];
  140.     [superview setDrawOrigin: pt->x : pt->y];
  141.  
  142.     [quakeed_i reenableDisplay];
  143.     [zscrollview_i display];
  144.     
  145.     return self;
  146. }
  147.  
  148.  
  149. /*
  150. ====================
  151. scaleMenuTarget:
  152.  
  153. Called when the scaler popup on the window is used
  154. ====================
  155. */
  156. - scaleMenuTarget: sender
  157. {
  158.     char    const    *item;
  159.     NXRect        visrect, sframe;
  160.     float        nscale;
  161.     
  162.     item = [[sender selectedCell] title];
  163.     sscanf (item,"%f",&nscale);
  164.     nscale /= 100;
  165.     
  166.     if (nscale == scale)
  167.         return NULL;
  168.         
  169. // keep the center of the view constant
  170.     [superview getBounds: &visrect];
  171.     [superview getFrame: &sframe];
  172.     visrect.origin.x += visrect.size.width/2;
  173.     visrect.origin.y += visrect.size.height/2;
  174.     
  175.     visrect.origin.x -= sframe.size.width/2/nscale;
  176.     visrect.origin.y -= sframe.size.height/2/nscale;
  177.     
  178.     [self setOrigin: &visrect.origin scale: nscale];
  179.     
  180.     return self;
  181. }
  182.  
  183.  
  184. - clearBounds
  185. {
  186.     topbound = 999999;
  187.     bottombound = -999999;
  188.  
  189.     return self;
  190. }
  191.  
  192. - getBounds: (float *)top :(float *)bottom;
  193. {
  194.     *top = topbound;
  195.     *bottom = bottombound;
  196.     return self;
  197. }
  198.  
  199.  
  200. /*
  201. ==================
  202. addToHeightRange:
  203. ==================
  204. */
  205. - addToHeightRange: (float)height
  206. {
  207.     if (height < minheight)
  208.         minheight = height;
  209.     if (height > maxheight)
  210.         maxheight = height;
  211.     return self;
  212. }
  213.  
  214.  
  215. /*
  216. ==================
  217. newSuperBounds
  218.  
  219. When superview is resized
  220. ==================
  221. */
  222. - newSuperBounds
  223. {    
  224.     oldminheight++;
  225.     [self newRealBounds];
  226.     
  227.     return self;
  228. }
  229.  
  230.  
  231. /*
  232. ===================
  233. newRealBounds
  234.  
  235. Should only change the scroll bars, not cause any redraws.
  236. If realbounds has shrunk, nothing will change.
  237. ===================
  238. */
  239. - newRealBounds
  240. {
  241.     NXRect        sbounds;
  242.     float        vistop, visbottom;
  243.  
  244.     if (minheight == oldminheight && maxheight == oldmaxheight)
  245.         return self;
  246.         
  247.     oldminheight = minheight;
  248.     oldmaxheight = maxheight;
  249.         
  250.     minheight -= 16;
  251.     maxheight += 16;
  252.     
  253. //
  254. // calculate the area visible in the cliprect
  255. //
  256.     [superview getBounds: &sbounds];
  257.     visbottom = sbounds.origin.y;
  258.     vistop = visbottom + sbounds.size.height;
  259.     
  260.     if (vistop > maxheight)
  261.         maxheight = vistop;
  262.     if (visbottom < minheight)
  263.         minheight = visbottom;
  264.     if (minheight == bounds.origin.y && maxheight-minheight == bounds.size.height)
  265.         return self;
  266.         
  267.     sbounds.origin.y = minheight;
  268.     sbounds.size.height = maxheight - minheight;
  269.  
  270. //
  271. // size this view
  272. //
  273.     [quakeed_i disableDisplay];
  274.  
  275.     [self suspendNotifyAncestorWhenFrameChanged:YES];
  276.     [self sizeTo: sbounds.size.width : sbounds.size.height];
  277.     [self setDrawOrigin: -sbounds.size.width/2 : sbounds.origin.y];
  278.     [self moveTo: -sbounds.size.width/2 : sbounds.origin.y];
  279.     [self suspendNotifyAncestorWhenFrameChanged:NO];
  280.     [[superview superview] reflectScroll: superview];
  281.  
  282.     [quakeed_i reenableDisplay];
  283.     
  284.     [[[[self superview] superview] vertScroller] display];
  285.     
  286.     return self;
  287. }
  288.  
  289.  
  290.  
  291. /*
  292. ============
  293. drawGrid
  294.  
  295. Draws tile markings every 64 units, and grid markings at the grid scale if
  296. the grid lines are >= 4 pixels apart
  297.  
  298. Rect is in global world (unscaled) coordinates
  299. ============
  300. */
  301.  
  302. - drawGrid: (const NXRect *)rect
  303. {
  304.     int        y, stopy;
  305.     float    top,bottom;
  306.     int        left, right;
  307.     int        gridsize;
  308.     char    text[10];
  309.     BOOL    showcoords;
  310.     
  311.     showcoords = [quakeed_i showCoordinates];
  312.         
  313.     PSsetlinewidth (0);
  314.  
  315.     gridsize = [xyview_i gridsize];
  316.     
  317.     left = bounds.origin.x;
  318.     right = 24;
  319.     
  320.     bottom = rect->origin.y-1;
  321.     top = rect->origin.y+rect->size.height+2;
  322.  
  323. //
  324. // grid
  325. //
  326. // can't just divide by grid size because of negetive coordinate
  327. // truncating direction
  328. //
  329.     if (gridsize>= 4/scale)
  330.     {
  331.         y = floor(bottom/gridsize);
  332.         stopy = floor(top/gridsize);
  333.         
  334.         y *= gridsize;
  335.         stopy *= gridsize;
  336.         if (y<bottom)
  337.             y+= gridsize;
  338.             
  339.         beginUserPath (upath,NO);
  340.         
  341.         for ( ; y<=stopy ; y+= gridsize)
  342.             if (y&31)
  343.             {
  344.                 UPmoveto (upath, left, y);
  345.                 UPlineto (upath, right, y);
  346.             }
  347.     
  348.         endUserPath (upath, dps_ustroke);
  349.         PSsetrgbcolor (0.8,0.8,1.0);    // thin grid color
  350.         sendUserPath (upath);
  351.     }
  352.  
  353. //
  354. // half tiles
  355. //
  356.     y = floor(bottom/32);
  357.     stopy = floor(top/32);
  358.     
  359.     if ( ! (((int)y + 4096) & 1) )
  360.         y++;
  361.     y *= 32;
  362.     stopy *= 32;
  363.     if (stopy >= top)
  364.         stopy -= 32;
  365.     
  366.     beginUserPath (upath,NO);
  367.     
  368.     for ( ; y<=stopy ; y+= 64)
  369.     {
  370.         UPmoveto (upath, left, y);
  371.         UPlineto (upath, right, y);
  372.     }
  373.  
  374.     endUserPath (upath, dps_ustroke);
  375.     PSsetgray (12.0/16.0);
  376.     sendUserPath (upath);
  377.  
  378. //
  379. // tiles
  380. //
  381.     y = floor(bottom/64);
  382.     stopy = floor(top/64);
  383.     
  384.     y *= 64;
  385.     stopy *= 64;
  386.     if (y<bottom)
  387.         y+= 64;
  388.     if (stopy >= top)
  389.         stopy -= 64;
  390.         
  391.     beginUserPath (upath,NO);
  392.     PSsetgray (0);        // for text
  393.     PSselectfont("Helvetica-Medium",10/scale);
  394.     PSrotate(0);
  395.     
  396.     for ( ; y<=stopy ; y+= 64)
  397.     {
  398.         if (showcoords)
  399.         {
  400.             sprintf (text, "%i",y);
  401.             PSmoveto(left,y);
  402.             PSshow(text);
  403.         }
  404.         UPmoveto (upath, left+24, y);
  405.         UPlineto (upath, right, y);
  406.     }
  407.  
  408. // divider
  409.     UPmoveto (upath, 0, bounds.origin.y);
  410.     UPlineto (upath, 0, bounds.origin.y + bounds.size.height);
  411.     
  412.     endUserPath (upath, dps_ustroke);
  413.     PSsetgray (10.0/16.0);
  414.     sendUserPath (upath);
  415.  
  416. //
  417. // origin
  418. //
  419.     PSsetlinewidth (5);
  420.     PSsetgray (4.0/16.0);
  421.     PSmoveto (right,0);
  422.     PSlineto (left,0);
  423.     PSstroke ();
  424.     PSsetlinewidth (0.15);
  425.         
  426.     return self;
  427. }
  428.  
  429.  
  430. - drawZplane
  431. {
  432.     PSsetrgbcolor (0.2, 0.2, 0);
  433.     PSarc (0, zplane, 4, 0, M_PI*2);
  434.     PSfill ();
  435.     return self;
  436. }
  437.  
  438. /*
  439. ===============================================================================
  440. drawSelf
  441. ===============================================================================
  442. */
  443.  
  444. - drawSelf:(const NXRect *)rects :(int)rectCount
  445. {
  446.     NXRect        visRect;
  447.     
  448.     minheight = 999999;
  449.     maxheight = -999999;
  450.  
  451. // allways draw the entire bar    
  452.     [self getVisibleRect:&visRect];
  453.     rects = &visRect;
  454.  
  455. // erase window
  456.     NXEraseRect (&rects[0]);
  457.     
  458. // draw grid
  459.     [self drawGrid: &rects[0]];
  460.     
  461. // draw zplane
  462. //    [self drawZplane];
  463.     
  464. // draw all entities
  465.     [map_i makeUnselectedPerform: @selector(ZDrawSelf)];
  466.  
  467. // possibly resize the view
  468.     [self newRealBounds];
  469.  
  470.     return self;
  471. }
  472.  
  473. /*
  474. ==============
  475. XYDrawSelf
  476. ==============
  477. */
  478. - XYDrawSelf
  479. {
  480.     PSsetrgbcolor (0,0.5,1.0);
  481.     PSsetlinewidth (0.15);
  482.     PSmoveto (origin[0]-16, origin[1]-16);
  483.     PSrlineto (32,32);
  484.     PSmoveto (origin[0]-16, origin[1]+16);
  485.     PSrlineto (32,-32);
  486.     PSstroke ();
  487.  
  488.     return self;
  489. }
  490.  
  491.  
  492. /*
  493. ==============
  494. getPoint: (NXPoint *)pt
  495. ==============
  496. */
  497. - getPoint: (NXPoint *)pt
  498. {
  499.     pt->x = origin[0] + 0.333;    // offset a bit to avoid edge cases
  500.     pt->y = origin[1] + 0.333;
  501.     return self;
  502. }
  503.  
  504. - setPoint: (NXPoint *)pt
  505. {
  506.     origin[0] = pt->x;
  507.     origin[1] = pt->y;
  508.     return self;
  509. }
  510.  
  511.  
  512. /*
  513. ==============================================================================
  514.  
  515. MOUSE CLICKING
  516.  
  517. ==============================================================================
  518. */
  519.  
  520.  
  521. /*
  522. ================
  523. dragLoop:
  524. ================
  525. */
  526. static    NXPoint        oldreletive;
  527. - dragFrom: (NXEvent *)startevent 
  528.     useGrid: (BOOL)ug
  529.     callback: (void (*) (float dy)) callback
  530. {
  531.     NXEvent        *event;
  532.     NXPoint        startpt, newpt;
  533.     NXPoint        reletive, delta;
  534.     int        gridsize;
  535.  
  536.     gridsize = [xyview_i gridsize];
  537.     
  538.     startpt = startevent->location;
  539.     [self convertPoint:&startpt  fromView:NULL];
  540.     
  541.     oldreletive.x = oldreletive.y = 0;
  542.     
  543.     while (1)
  544.     {
  545.         event = [NXApp getNextEvent: 
  546.             NX_LMOUSEUPMASK | NX_LMOUSEDRAGGEDMASK
  547.             | NX_RMOUSEUPMASK | NX_RMOUSEDRAGGEDMASK];
  548.         if (event->type == NX_LMOUSEUP || event->type == NX_RMOUSEUP)
  549.             break;
  550.             
  551.         newpt = event->location;
  552.         [self convertPoint:&newpt  fromView:NULL];
  553.  
  554.         reletive.y = newpt.y - startpt.y;
  555.         
  556.         if (ug)
  557.         {    // we want truncate towards 0 behavior here
  558.             reletive.y = gridsize * (int)(reletive.y / gridsize);
  559.         }
  560.  
  561.         if (reletive.y == oldreletive.y)
  562.             continue;
  563.  
  564.         delta.y = reletive.y - oldreletive.y;
  565.         oldreletive = reletive;            
  566.         callback (delta.y);        
  567.     }
  568.  
  569.     return self;
  570. }
  571.  
  572. //============================================================================
  573.  
  574.  
  575. void ZDragCallback (float dy)
  576. {
  577.     sb_translate[0] = 0;
  578.     sb_translate[1] = 0;
  579.     sb_translate[2] = dy;
  580.  
  581.     [map_i makeSelectedPerform: @selector(translate)];
  582.     
  583.     [quakeed_i redrawInstance];
  584. }
  585.  
  586. - selectionDragFrom: (NXEvent*)theEvent    
  587. {
  588.     qprintf ("dragging selection");
  589.     [self    dragFrom:    theEvent 
  590.             useGrid:    YES
  591.             callback:    ZDragCallback ];
  592.     [quakeed_i updateCamera];
  593.     qprintf ("");
  594.     return self;
  595.     
  596. }
  597.  
  598. //============================================================================
  599.  
  600. void ZScrollCallback (float dy)
  601. {
  602.     NXRect        basebounds;
  603.     NXPoint        neworg;
  604.     float        scale;
  605.     
  606.     [ [zview_i superview] getBounds: &basebounds];
  607.     [zview_i convertRectFromSuperview: &basebounds];
  608.  
  609.     neworg.y = basebounds.origin.y - dy;
  610.     
  611.     scale = [zview_i currentScale];
  612.     
  613.     oldreletive.y -= dy;
  614.     [zview_i setOrigin: &neworg scale: scale];
  615. }
  616.  
  617. - scrollDragFrom: (NXEvent*)theEvent    
  618. {
  619.     qprintf ("scrolling view");
  620.     [self    dragFrom:    theEvent 
  621.             useGrid:    YES
  622.             callback:    ZScrollCallback ];
  623.     qprintf ("");
  624.     return self;
  625. }
  626.  
  627. //============================================================================
  628.  
  629. void ZControlCallback (float dy)
  630. {
  631.     int        i;
  632.     
  633.     for (i=0 ; i<numcontrolpoints ; i++)
  634.         controlpoints[i][2] += dy;
  635.     
  636.     [[map_i selectedBrush] calcWindings];    
  637.     [quakeed_i redrawInstance];
  638. }
  639.  
  640. - (BOOL)planeDragFrom: (NXEvent*)theEvent    
  641. {
  642.     NXPoint            pt;
  643.     vec3_t            dragpoint;
  644.     
  645.     if ([map_i numSelected] != 1)
  646.         return NO;
  647.  
  648.     pt= theEvent->location;
  649.     [self convertPoint:&pt  fromView:NULL];
  650.  
  651.     dragpoint[0] = origin[0];
  652.     dragpoint[1] = origin[1];
  653.     dragpoint[2] = pt.y;
  654.     
  655.     [[map_i selectedBrush] getZdragface: dragpoint];
  656.     if (!numcontrolpoints)
  657.         return NO;
  658.     
  659.     qprintf ("dragging brush plane");
  660.     
  661.     pt= theEvent->location;
  662.     [self convertPoint:&pt  fromView:NULL];
  663.  
  664.     [self    dragFrom:    theEvent 
  665.             useGrid:    YES
  666.             callback:    ZControlCallback ];
  667.             
  668.     [[map_i selectedBrush] removeIfInvalid];
  669.     
  670.     [quakeed_i updateCamera];
  671.     qprintf ("");
  672.     return YES;
  673. }
  674.  
  675.  
  676. //============================================================================
  677.  
  678. /*
  679. ===================
  680. mouseDown
  681. ===================
  682. */
  683. - mouseDown:(NXEvent *)theEvent
  684. {
  685.     NXPoint    pt;
  686.     int        flags;
  687.     vec3_t    p1;
  688.     
  689.     pt= theEvent->location;
  690.     [self convertPoint:&pt  fromView:NULL];
  691.  
  692.     p1[0] = origin[0];
  693.     p1[1] = origin[1];
  694.     p1[2] = pt.y;
  695.     
  696.     flags = theEvent->flags & (NX_SHIFTMASK | NX_CONTROLMASK | NX_ALTERNATEMASK | NX_COMMANDMASK);
  697.  
  698. //
  699. // shift click to select / deselect a brush from the world
  700. //
  701.     if (flags == NX_SHIFTMASK)
  702.     {        
  703.         [map_i selectRay: p1 : p1 : NO];
  704.         return self;
  705.     }
  706.         
  707. //
  708. // alt click = set entire brush texture
  709. //
  710.     if (flags == NX_ALTERNATEMASK)
  711.     {
  712.         [map_i setTextureRay: p1 : p1 : YES];
  713.         return self;
  714.     }
  715.  
  716. //
  717. // control click = position view
  718. //
  719.     if (flags == NX_CONTROLMASK)
  720.     {
  721.         [cameraview_i setZOrigin: pt.y];
  722.         [quakeed_i updateAll];
  723.         [cameraview_i ZmouseDown: &pt flags:theEvent->flags];
  724.         return self;
  725.     }
  726.  
  727. //
  728. // bare click to drag icons or new brush drag
  729. //
  730.     if ( flags == 0 )
  731.     {
  732. // check eye
  733.         if ( [cameraview_i ZmouseDown: &pt flags:theEvent->flags] )
  734.             return self;
  735.             
  736.         if ([map_i numSelected])
  737.         {
  738.             if ( pt.x > 0)
  739.             {
  740.                 if ([self planeDragFrom: theEvent])
  741.                     return self;
  742.             }
  743.             [self selectionDragFrom: theEvent];
  744.             return self;
  745.         }
  746.  
  747.     }
  748.         
  749.     qprintf ("bad flags for click");
  750.     NopSound ();
  751.     return self;
  752. }
  753.  
  754. /*
  755. ===================
  756. rightMouseDown
  757. ===================
  758. */
  759. - rightMouseDown:(NXEvent *)theEvent
  760. {
  761.     NXPoint    pt;
  762.     int        flags;
  763.         
  764.     pt= theEvent->location;
  765.     [self convertPoint:&pt  fromView:NULL];
  766.  
  767.     flags = theEvent->flags & (NX_SHIFTMASK | NX_CONTROLMASK | NX_ALTERNATEMASK | NX_COMMANDMASK);
  768.  
  769.     
  770. //
  771. // click = scroll view
  772. //
  773.     if (flags == 0)
  774.     {
  775.         return [self scrollDragFrom: theEvent];        
  776.     }
  777.  
  778.     qprintf ("bad flags for click");
  779.     NopSound ();
  780.  
  781.     return self;
  782. }
  783.  
  784.  
  785. /*
  786. ===============================================================================
  787.  
  788.                         XY mouse view methods
  789.  
  790. ===============================================================================
  791. */
  792.  
  793. /*
  794. ================
  795. modalMoveLoop
  796. ================
  797. */
  798. - modalMoveLoop: (NXPoint *)basept :(vec3_t)movemod : converter
  799. {
  800.     vec3_t        originbase;    
  801.     NXEvent        *event;
  802.     NXPoint        newpt;
  803.     vec3_t        delta;
  804.     
  805.     int            i;
  806.     
  807.     VectorCopy (origin, originbase);    
  808.     
  809. //
  810. // modal event loop using instance drawing
  811. //
  812.     goto drawentry;
  813.  
  814.     while (event->type != NX_LMOUSEUP)
  815.     {
  816.         //
  817.         // calculate new point
  818.         //
  819.         newpt = event->location;
  820.         [converter convertPoint:&newpt  fromView:NULL];
  821.                 
  822.         delta[0] = newpt.x-basept->x;
  823.         delta[1] = newpt.y-basept->y;
  824.         delta[2] = delta[1];        // height change
  825.         
  826.         for (i=0 ; i<3 ; i++)
  827.             origin[i] = originbase[i]+movemod[i]*delta[i];
  828.         
  829.                     
  830. drawentry:
  831.         //
  832.         // instance draw new frame
  833.         //
  834.         [quakeed_i newinstance];
  835.         [self display];
  836.         NXPing ();
  837.                 
  838.         event = [NXApp getNextEvent: 
  839.             NX_LMOUSEUPMASK | NX_LMOUSEDRAGGEDMASK];        
  840.     }
  841.  
  842. //
  843. // draw the brush back into the window buffer
  844. //
  845. //    [xyview_i display];
  846.     
  847.     return self;
  848. }
  849.  
  850. /*
  851. ===============
  852. XYmouseDown
  853. ===============
  854. */
  855. - (BOOL)XYmouseDown: (NXPoint *)pt
  856. {    
  857.     vec3_t        movemod;
  858.     
  859.     if (fabs(pt->x - origin[0]) > 16
  860.     || fabs(pt->y - origin[1]) > 16)
  861.         return NO;
  862.         
  863.     movemod[0] = 1;
  864.     movemod[1] = 1;
  865.     movemod[2] = 0;
  866.     
  867.     [self modalMoveLoop: pt : movemod : xyview_i];
  868.     
  869.     return YES;
  870. }
  871.  
  872. @end
  873.