12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385 |
- #import "qedefs.h"
- id xyview_i;
- id scalemenu_i, gridmenu_i, scrollview_i, gridbutton_i, scalebutton_i;
- vec3_t xy_viewnormal; // v_forward for xy view
- float xy_viewdist; // clip behind this plane
- @implementation XYView
- /*
- ==================
- initFrame:
- ==================
- */
- - initFrame:(const NXRect *)frameRect
- {
- [super initFrame:frameRect];
- [self allocateGState];
-
- NXSetRect (&realbounds, 0,0,0,0);
-
- gridsize = 16;
- scale = 1.0;
- xyview_i = self;
-
- xy_viewnormal[2] = -1;
- xy_viewdist = -1024;
-
- //
- // initialize the pop up menus
- //
- scalemenu_i = [[PopUpList alloc] init];
- [scalemenu_i setTarget: self];
- [scalemenu_i setAction: @selector(scaleMenuTarget:)];
- [scalemenu_i addItem: "12.5%"];
- [scalemenu_i addItem: "25%"];
- [scalemenu_i addItem: "50%"];
- [scalemenu_i addItem: "75%"];
- [scalemenu_i addItem: "100%"];
- [scalemenu_i addItem: "200%"];
- [scalemenu_i addItem: "300%"];
- [[scalemenu_i itemList] selectCellAt: 4 : 0];
-
- scalebutton_i = NXCreatePopUpListButton(scalemenu_i);
- gridmenu_i = [[PopUpList alloc] init];
- [gridmenu_i setTarget: self];
- [gridmenu_i setAction: @selector(gridMenuTarget:)];
- [gridmenu_i addItem: "grid 1"];
- [gridmenu_i addItem: "grid 2"];
- [gridmenu_i addItem: "grid 4"];
- [gridmenu_i addItem: "grid 8"];
- [gridmenu_i addItem: "grid 16"];
- [gridmenu_i addItem: "grid 32"];
- [gridmenu_i addItem: "grid 64"];
-
- [[gridmenu_i itemList] selectCellAt: 4 : 0];
-
- gridbutton_i = NXCreatePopUpListButton(gridmenu_i);
- // initialize the scroll view
- scrollview_i = [[PopScrollView alloc]
- initFrame: frameRect
- button1: scalebutton_i
- button2: gridbutton_i
- ];
- [scrollview_i setLineScroll: 64];
- [scrollview_i setAutosizing: NX_WIDTHSIZABLE | NX_HEIGHTSIZABLE];
-
- // link objects together
- [[scrollview_i setDocView: self] free];
-
- return scrollview_i;
- }
- - (BOOL)acceptsFirstResponder
- {
- return YES;
- }
- - setModeRadio: m
- { // this should be set from IB, but because I toss myself in a popscrollview
- // the connection gets lost
- mode_radio_i = m;
- [mode_radio_i setTarget: self];
- [mode_radio_i setAction: @selector(drawMode:)];
- return self;
- }
- - drawMode: sender
- {
- drawmode = [sender selectedCol];
- [quakeed_i updateXY];
- return self;
- }
- - setDrawMode: (drawmode_t)mode
- {
- drawmode = mode;
- [mode_radio_i selectCellAt:0: mode];
- [quakeed_i updateXY];
- return self;
- }
- - (float)currentScale
- {
- return scale;
- }
- /*
- ===================
- setOrigin:scale:
- ===================
- */
- - setOrigin: (NXPoint *)pt scale: (float)sc
- {
- NXRect sframe;
- NXRect newbounds;
-
- //
- // calculate the area visible in the cliprect
- //
- scale = sc;
-
- [superview getFrame: &sframe];
- [superview getFrame: &newbounds];
- newbounds.origin = *pt;
- newbounds.size.width /= scale;
- newbounds.size.height /= scale;
-
- //
- // union with the realbounds
- //
- NXUnionRect (&realbounds, &newbounds);
- //
- // redisplay everything
- //
- [quakeed_i disableDisplay];
- //
- // size this view
- //
- [self sizeTo: newbounds.size.width : newbounds.size.height];
- [self setDrawOrigin: newbounds.origin.x : newbounds.origin.y];
- [self moveTo: newbounds.origin.x : newbounds.origin.y];
-
- //
- // scroll and scale the clip view
- //
- [superview setDrawSize
- : sframe.size.width/scale
- : sframe.size.height/scale];
- [superview setDrawOrigin: pt->x : pt->y];
- [quakeed_i reenableDisplay];
- [scrollview_i display];
-
- return self;
- }
- - centerOn: (vec3_t)org
- {
- NXRect sbounds;
- NXPoint mid, delta;
-
- [[xyview_i superview] getBounds: &sbounds];
-
- mid.x = sbounds.origin.x + sbounds.size.width/2;
- mid.y = sbounds.origin.y + sbounds.size.height/2;
-
- delta.x = org[0] - mid.x;
- delta.y = org[1] - mid.y;
- sbounds.origin.x += delta.x;
- sbounds.origin.y += delta.y;
-
- [self setOrigin: &sbounds.origin scale: scale];
- return self;
- }
- /*
- ==================
- newSuperBounds
- When superview is resized
- ==================
- */
- - newSuperBounds
- {
- NXRect r;
-
- [superview getBounds: &r];
- [self newRealBounds: &r];
-
- return self;
- }
- /*
- ===================
- newRealBounds
- Called when the realbounds rectangle is changed.
- Should only change the scroll bars, not cause any redraws.
- If realbounds has shrunk, nothing will change.
- ===================
- */
- - newRealBounds: (NXRect *)nb
- {
- NXRect sbounds;
-
- realbounds = *nb;
-
- //
- // calculate the area visible in the cliprect
- //
- [superview getBounds: &sbounds];
- NXUnionRect (nb, &sbounds);
- //
- // size this view
- //
- [quakeed_i disableDisplay];
- [self suspendNotifyAncestorWhenFrameChanged:YES];
- [self sizeTo: sbounds.size.width : sbounds.size.height];
- [self setDrawOrigin: sbounds.origin.x : sbounds.origin.y];
- [self moveTo: sbounds.origin.x : sbounds.origin.y];
- [self suspendNotifyAncestorWhenFrameChanged:NO];
- [scrollview_i reflectScroll: superview];
- [quakeed_i reenableDisplay];
-
- [[scrollview_i horizScroller] display];
- [[scrollview_i vertScroller] display];
-
- return self;
- }
- /*
- ====================
- scaleMenuTarget:
- Called when the scaler popup on the window is used
- ====================
- */
- - scaleMenuTarget: sender
- {
- char const *item;
- NXRect visrect, sframe;
- float nscale;
-
- item = [[sender selectedCell] title];
- sscanf (item,"%f",&nscale);
- nscale /= 100;
-
- if (nscale == scale)
- return NULL;
-
- // keep the center of the view constant
- [superview getBounds: &visrect];
- [superview getFrame: &sframe];
- visrect.origin.x += visrect.size.width/2;
- visrect.origin.y += visrect.size.height/2;
-
- visrect.origin.x -= sframe.size.width/2/nscale;
- visrect.origin.y -= sframe.size.height/2/nscale;
-
- [self setOrigin: &visrect.origin scale: nscale];
-
- return self;
- }
- /*
- ==============
- zoomIn
- ==============
- */
- - zoomIn: (NXPoint *)constant
- {
- id itemlist;
- int selected, numrows, numcollumns;
- NXRect visrect;
- NXPoint ofs, new;
- //
- // set the popup
- //
- itemlist = [scalemenu_i itemList];
- [itemlist getNumRows: &numrows numCols:&numcollumns];
-
- selected = [itemlist selectedRow] + 1;
- if (selected >= numrows)
- return NULL;
-
- [itemlist selectCellAt: selected : 0];
- [scalebutton_i setTitle: [[itemlist selectedCell] title]];
- //
- // zoom the view
- //
- [superview getBounds: &visrect];
- ofs.x = constant->x - visrect.origin.x;
- ofs.y = constant->y - visrect.origin.y;
-
- new.x = constant->x - ofs.x / 2;
- new.y = constant->y - ofs.y / 2;
- [self setOrigin: &new scale: scale*2];
-
- return self;
- }
- /*
- ==============
- zoomOut
- ==============
- */
- - zoomOut: (NXPoint *)constant
- {
- id itemlist;
- int selected, numrows, numcollumns;
- NXRect visrect;
- NXPoint ofs, new;
-
- //
- // set the popup
- //
- itemlist = [scalemenu_i itemList];
- [itemlist getNumRows: &numrows numCols:&numcollumns];
-
- selected = [itemlist selectedRow] - 1;
- if (selected < 0)
- return NULL;
-
- [itemlist selectCellAt: selected : 0];
- [scalebutton_i setTitle: [[itemlist selectedCell] title]];
- //
- // zoom the view
- //
- [superview getBounds: &visrect];
- ofs.x = constant->x - visrect.origin.x;
- ofs.y = constant->y - visrect.origin.y;
-
- new.x = constant->x - ofs.x * 2;
- new.y = constant->y - ofs.y * 2;
- [self setOrigin: &new scale: scale/2];
-
- return self;
- }
- /*
- ====================
- gridMenuTarget:
- Called when the scaler popup on the window is used
- ====================
- */
- - gridMenuTarget: sender
- {
- char const *item;
- int grid;
-
- item = [[sender selectedCell] title];
- sscanf (item,"grid %d",&grid);
- if (grid == gridsize)
- return NULL;
-
- gridsize = grid;
- [quakeed_i updateAll];
- return self;
- }
- /*
- ====================
- snapToGrid
- ====================
- */
- - (float) snapToGrid: (float)f
- {
- int i;
-
- i = rint(f/gridsize);
-
- return i*gridsize;
- }
- - (int)gridsize
- {
- return gridsize;
- }
- /*
- ===================
- addToScrollRange::
- ===================
- */
- - addToScrollRange: (float)x :(float)y;
- {
- if (x < newrect.origin.x)
- {
- newrect.size.width += newrect.origin.x - x;
- newrect.origin.x = x;
- }
-
- if (y < newrect.origin.y)
- {
- newrect.size.height += newrect.origin.y - y;
- newrect.origin.y = y;
- }
-
- if (x > newrect.origin.x + newrect.size.width)
- newrect.size.width += x - (newrect.origin.x+newrect.size.width);
-
- if (y > newrect.origin.y + newrect.size.height)
- newrect.size.height += y - (newrect.origin.y+newrect.size.height);
-
- return self;
- }
- /*
- ===================
- superviewChanged
- ===================
- */
- - superviewChanged
- {
- [self newRealBounds: &realbounds];
-
- return self;
- }
- /*
- ===============================================================================
- DRAWING METHODS
- ===============================================================================
- */
- vec3_t cur_linecolor;
- void linestart (float r, float g, float b)
- {
- beginUserPath (upath,NO);
- cur_linecolor[0] = r;
- cur_linecolor[1] = g;
- cur_linecolor[2] = b;
- }
- void lineflush (void)
- {
- if (!upath->numberOfPoints)
- return;
- endUserPath (upath, dps_ustroke);
- PSsetrgbcolor (cur_linecolor[0], cur_linecolor[1], cur_linecolor[2]);
- sendUserPath (upath);
- beginUserPath (upath,NO);
- }
- void linecolor (float r, float g, float b)
- {
- if (cur_linecolor[0] == r && cur_linecolor[1] == g && cur_linecolor[2] == b)
- return; // do nothing
- lineflush ();
- cur_linecolor[0] = r;
- cur_linecolor[1] = g;
- cur_linecolor[2] = b;
- }
- void XYmoveto (vec3_t pt)
- {
- if (upath->numberOfPoints > 2048)
- lineflush ();
- UPmoveto (upath, pt[0], pt[1]);
- }
- void XYlineto (vec3_t pt)
- {
- UPlineto (upath, pt[0], pt[1]);
- }
- /*
- ============
- drawGrid
- Draws tile markings every 64 units, and grid markings at the grid scale if
- the grid lines are greater than or equal to 4 pixels apart
- Rect is in global world (unscaled) coordinates
- ============
- */
- - drawGrid: (const NXRect *)rect
- {
- int x,y, stopx, stopy;
- float top,bottom,right,left;
- char text[10];
- BOOL showcoords;
-
- showcoords = [quakeed_i showCoordinates];
- left = rect->origin.x-1;
- bottom = rect->origin.y-1;
- right = rect->origin.x+rect->size.width+2;
- top = rect->origin.y+rect->size.height+2;
- PSsetlinewidth (0.15);
- //
- // grid
- //
- // can't just divide by grid size because of negetive coordinate
- // truncating direction
- //
- if (gridsize >= 4/scale)
- {
- y = floor(bottom/gridsize);
- stopy = floor(top/gridsize);
- x = floor(left/gridsize);
- stopx = floor(right/gridsize);
-
- y *= gridsize;
- stopy *= gridsize;
- x *= gridsize;
- stopx *= gridsize;
- if (y<bottom)
- y+= gridsize;
- if (x<left)
- x+= gridsize;
- if (stopx >= right)
- stopx -= gridsize;
- if (stopy >= top)
- stopy -= gridsize;
-
- beginUserPath (upath,NO);
-
- for ( ; y<=stopy ; y+= gridsize)
- if (y&63)
- {
- UPmoveto (upath, left, y);
- UPlineto (upath, right, y);
- }
-
- for ( ; x<=stopx ; x+= gridsize)
- if (x&63)
- {
- UPmoveto (upath, x, top);
- UPlineto (upath, x, bottom);
- }
- endUserPath (upath, dps_ustroke);
- PSsetrgbcolor (0.8,0.8,1.0); // thin grid color
- sendUserPath (upath);
-
- }
- //
- // tiles
- //
- PSsetgray (0); // for text
- if (scale > 4.0/64)
- {
- y = floor(bottom/64);
- stopy = floor(top/64);
- x = floor(left/64);
- stopx = floor(right/64);
-
- y *= 64;
- stopy *= 64;
- x *= 64;
- stopx *= 64;
- if (y<bottom)
- y+= 64;
- if (x<left)
- x+= 64;
- if (stopx >= right)
- stopx -= 64;
- if (stopy >= top)
- stopy -= 64;
-
- beginUserPath (upath,NO);
-
- for ( ; y<=stopy ; y+= 64)
- {
- if (showcoords)
- {
- sprintf (text, "%i",y);
- PSmoveto(left,y);
- PSshow(text);
- }
- UPmoveto (upath, left, y);
- UPlineto (upath, right, y);
- }
-
- for ( ; x<=stopx ; x+= 64)
- {
- if (showcoords)
- {
- sprintf (text, "%i",x);
- PSmoveto(x,bottom+2);
- PSshow(text);
- }
- UPmoveto (upath, x, top);
- UPlineto (upath, x, bottom);
- }
-
- endUserPath (upath, dps_ustroke);
- PSsetgray (12.0/16);
- sendUserPath (upath);
- }
- return self;
- }
- /*
- ==================
- drawWire
- ==================
- */
- - drawWire: (const NXRect *)rects
- {
- NXRect visRect;
- int i,j, c, c2;
- id ent, brush;
- vec3_t mins, maxs;
- BOOL drawnames;
- drawnames = [quakeed_i showNames];
-
- if ([quakeed_i showCoordinates]) // if coords are showing, update everything
- {
- [self getVisibleRect:&visRect];
- rects = &visRect;
- xy_draw_rect = *rects;
- }
-
- NXRectClip(rects);
-
- // erase window
- NXEraseRect (rects);
-
- // draw grid
- [self drawGrid: rects];
- // draw all entities, world first so entities take priority
- linestart (0,0,0);
- c = [map_i count];
- for (i=0 ; i<c ; i++)
- {
- ent = [map_i objectAt: i];
- c2 = [ent count];
- for (j = c2-1 ; j >=0 ; j--)
- {
- brush = [ent objectAt: j];
- if ( [brush selected] )
- continue;
- if ([brush regioned])
- continue;
- [brush XYDrawSelf];
- }
- if (i > 0 && drawnames)
- { // draw entity names
- brush = [ent objectAt: 0];
- if (![brush regioned])
- {
- [brush getMins: mins maxs: maxs];
- PSmoveto(mins[0], mins[1]);
- PSsetrgbcolor (0,0,0);
- PSshow([ent valueForQKey: "classname"]);
- }
- }
- }
- lineflush ();
-
- // resize if needed
- newrect.origin.x -= gridsize;
- newrect.origin.y -= gridsize;
- newrect.size.width += 2*gridsize;
- newrect.size.height += 2*gridsize;
- if (!NXEqualRect (&newrect, &realbounds))
- [self newRealBounds: &newrect];
- return self;
- }
- /*
- =============
- drawSolid
- =============
- */
- - drawSolid
- {
- unsigned char *planes[5];
- NXRect visRect;
- [self getVisibleRect:&visRect];
- //
- // draw the image into imagebuffer
- //
- r_origin[0] = visRect.origin.x;
- r_origin[1] = visRect.origin.y;
-
- r_origin[2] = scale/2; // using Z as a scale for the 2D projection
-
- r_width = visRect.size.width*r_origin[2];
- r_height = visRect.size.height*r_origin[2];
-
- if (r_width != xywidth || r_height != xyheight)
- {
- xywidth = r_width;
- xyheight = r_height;
- if (xypicbuffer)
- {
- free (xypicbuffer);
- free (xyzbuffer);
- }
- xypicbuffer = malloc (r_width*(r_height+1)*4);
- xyzbuffer = malloc (r_width*(r_height+1)*4);
- }
-
- r_picbuffer = xypicbuffer;
- r_zbuffer = xyzbuffer;
-
- REN_BeginXY ();
- REN_ClearBuffers ();
- //
- // render the entities
- //
- [map_i makeAllPerform: @selector(XYRenderSelf)];
- //
- // display the output
- //
- [self lockFocus];
- [[self window] setBackingType:NX_RETAINED];
- planes[0] = (unsigned char *)r_picbuffer;
- NXDrawBitmap(
- &visRect,
- r_width,
- r_height,
- 8,
- 3,
- 32,
- r_width*4,
- NO,
- NO,
- NX_RGBColorSpace,
- planes
- );
-
- NXPing ();
- [[self window] setBackingType:NX_BUFFERED];
- [self unlockFocus];
-
- return self;
- }
- /*
- ===================
- drawSelf
- ===================
- */
- NXRect xy_draw_rect;
- - drawSelf:(const NXRect *)rects :(int)rectCount
- {
- static float drawtime; // static to shut up compiler warning
- if (timedrawing)
- drawtime = I_FloatTime ();
- xy_draw_rect = *rects;
- newrect.origin.x = newrect.origin.y = 99999;
- newrect.size.width = newrect.size.height = -2*99999;
- // setup for text
- PSselectfont("Helvetica-Medium",10/scale);
- PSrotate(0);
- if (drawmode == dr_texture || drawmode == dr_flat)
- [self drawSolid];
- else
- [self drawWire: rects];
-
- if (timedrawing)
- {
- NXPing ();
- drawtime = I_FloatTime() - drawtime;
- printf ("CameraView drawtime: %5.3f\n", drawtime);
- }
- return self;
- }
- /*
- ===============================================================================
- USER INTERACTION
- ===============================================================================
- */
- /*
- ================
- dragLoop:
- ================
- */
- static NXPoint oldreletive;
- - dragFrom: (NXEvent *)startevent
- useGrid: (BOOL)ug
- callback: (void (*) (float dx, float dy)) callback
- {
- NXEvent *event;
- NXPoint startpt, newpt;
- NXPoint reletive, delta;
- startpt = startevent->location;
- [self convertPoint:&startpt fromView:NULL];
-
- oldreletive.x = oldreletive.y = 0;
-
- if (ug)
- {
- startpt.x = [self snapToGrid: startpt.x];
- startpt.y = [self snapToGrid: startpt.y];
- }
-
- while (1)
- {
- event = [NXApp getNextEvent: NX_LMOUSEUPMASK | NX_LMOUSEDRAGGEDMASK
- | NX_RMOUSEUPMASK | NX_RMOUSEDRAGGEDMASK | NX_APPDEFINEDMASK];
- if (event->type == NX_LMOUSEUP || event->type == NX_RMOUSEUP)
- break;
- if (event->type == NX_APPDEFINED)
- { // doesn't work. grrr.
- [quakeed_i applicationDefined:event];
- continue;
- }
-
- newpt = event->location;
- [self convertPoint:&newpt fromView:NULL];
- if (ug)
- {
- newpt.x = [self snapToGrid: newpt.x];
- newpt.y = [self snapToGrid: newpt.y];
- }
- reletive.x = newpt.x - startpt.x;
- reletive.y = newpt.y - startpt.y;
- if (reletive.x == oldreletive.x && reletive.y == oldreletive.y)
- continue;
- delta.x = reletive.x - oldreletive.x;
- delta.y = reletive.y - oldreletive.y;
- oldreletive = reletive;
- callback (delta.x , delta.y );
-
- }
- return self;
- }
- //============================================================================
- void DragCallback (float dx, float dy)
- {
- sb_translate[0] = dx;
- sb_translate[1] = dy;
- sb_translate[2] = 0;
- [map_i makeSelectedPerform: @selector(translate)];
-
- [quakeed_i redrawInstance];
- }
- - selectionDragFrom: (NXEvent*)theEvent
- {
- qprintf ("dragging selection");
- [self dragFrom: theEvent
- useGrid: YES
- callback: DragCallback ];
- [quakeed_i updateAll];
- qprintf ("");
- return self;
-
- }
- //============================================================================
- void ScrollCallback (float dx, float dy)
- {
- NXRect basebounds;
- NXPoint neworg;
- float scale;
-
- [ [xyview_i superview] getBounds: &basebounds];
- [xyview_i convertRectFromSuperview: &basebounds];
- neworg.x = basebounds.origin.x - dx;
- neworg.y = basebounds.origin.y - dy;
-
- scale = [xyview_i currentScale];
-
- oldreletive.x -= dx;
- oldreletive.y -= dy;
- [xyview_i setOrigin: &neworg scale: scale];
- }
- - scrollDragFrom: (NXEvent*)theEvent
- {
- qprintf ("scrolling view");
- [self dragFrom: theEvent
- useGrid: YES
- callback: ScrollCallback ];
- qprintf ("");
- return self;
-
- }
- //============================================================================
- vec3_t direction;
- void DirectionCallback (float dx, float dy)
- {
- vec3_t org;
- float ya;
-
- direction[0] += dx;
- direction[1] += dy;
-
- [cameraview_i getOrigin: org];
- if (direction[0] == org[0] && direction[1] == org[1])
- return;
-
- ya = atan2 (direction[1] - org[1], direction[0] - org[0]);
- [cameraview_i setOrigin: org angle: ya];
- [quakeed_i newinstance];
- [cameraview_i display];
- }
- - directionDragFrom: (NXEvent*)theEvent
- {
- NXPoint pt;
- qprintf ("changing camera direction");
- pt= theEvent->location;
- [self convertPoint:&pt fromView:NULL];
- direction[0] = pt.x;
- direction[1] = pt.y;
-
- DirectionCallback (0,0);
-
- [self dragFrom: theEvent
- useGrid: NO
- callback: DirectionCallback ];
- qprintf ("");
- return self;
- }
- //============================================================================
- id newbrush;
- vec3_t neworg, newdrag;
- void NewCallback (float dx, float dy)
- {
- vec3_t min, max;
- int i;
-
- newdrag[0] += dx;
- newdrag[1] += dy;
-
- for (i=0 ; i<3 ; i++)
- {
- if (neworg[i] < newdrag[i])
- {
- min[i] = neworg[i];
- max[i] = newdrag[i];
- }
- else
- {
- min[i] = newdrag[i];
- max[i] = neworg[i];
- }
- }
-
- [newbrush setMins: min maxs: max];
-
- [quakeed_i redrawInstance];
- }
- - newBrushDragFrom: (NXEvent*)theEvent
- {
- id owner;
- texturedef_t td;
- NXPoint pt;
- qprintf ("sizing new brush");
-
- pt= theEvent->location;
- [self convertPoint:&pt fromView:NULL];
- neworg[0] = [self snapToGrid: pt.x];
- neworg[1] = [self snapToGrid: pt.y];
- neworg[2] = [map_i currentMinZ];
- newdrag[0] = neworg[0];
- newdrag[1] = neworg[1];
- newdrag[2] = [map_i currentMaxZ];
-
- owner = [map_i currentEntity];
-
- [texturepalette_i getTextureDef: &td];
-
- newbrush = [[SetBrush alloc] initOwner: owner
- mins: neworg maxs: newdrag texture: &td];
- [owner addObject: newbrush];
-
- [newbrush setSelected: YES];
-
- [self dragFrom: theEvent
- useGrid: YES
- callback: NewCallback ];
-
- [newbrush removeIfInvalid];
-
- [quakeed_i updateCamera];
- qprintf ("");
- return self;
-
- }
- //============================================================================
- void ControlCallback (float dx, float dy)
- {
- int i;
-
- for (i=0 ; i<numcontrolpoints ; i++)
- {
- controlpoints[i][0] += dx;
- controlpoints[i][1] += dy;
- }
-
- [[map_i selectedBrush] calcWindings];
- [quakeed_i redrawInstance];
- }
- - (BOOL)planeDragFrom: (NXEvent*)theEvent
- {
- NXPoint pt;
- vec3_t dragpoint;
- if ([map_i numSelected] != 1)
- return NO;
-
- pt= theEvent->location;
- [self convertPoint:&pt fromView:NULL];
- dragpoint[0] = pt.x;
- dragpoint[1] = pt.y;
- dragpoint[2] = 2048;
-
- [[map_i selectedBrush] getXYdragface: dragpoint];
- if (!numcontrolpoints)
- return NO;
-
- qprintf ("dragging brush plane");
-
- pt= theEvent->location;
- [self convertPoint:&pt fromView:NULL];
- [self dragFrom: theEvent
- useGrid: YES
- callback: ControlCallback ];
-
- [[map_i selectedBrush] removeIfInvalid];
-
- [quakeed_i updateAll];
- qprintf ("");
- return YES;
- }
- - (BOOL)shearDragFrom: (NXEvent*)theEvent
- {
- NXPoint pt;
- vec3_t dragpoint;
- vec3_t p1, p2;
- float time;
- id br;
- int face;
-
- if ([map_i numSelected] != 1)
- return NO;
- br = [map_i selectedBrush];
-
- pt= theEvent->location;
- [self convertPoint:&pt fromView:NULL];
- // if the XY point is inside the brush, make the point on top
- p1[0] = pt.x;
- p1[1] = pt.y;
- VectorCopy (p1, p2);
- p1[2] = -2048*xy_viewnormal[2];
- p2[2] = 2048*xy_viewnormal[2];
- VectorCopy (p1, dragpoint);
- [br hitByRay: p1 : p2 : &time : &face];
- if (time > 0)
- {
- dragpoint[2] = p1[2] + (time-0.01)*xy_viewnormal[2];
- }
- else
- {
- [br getMins: p1 maxs: p2];
- dragpoint[2] = (p1[2] + p2[2])/2;
- }
- [br getXYShearPoints: dragpoint];
- if (!numcontrolpoints)
- return NO;
-
- qprintf ("dragging brush plane");
-
- pt= theEvent->location;
- [self convertPoint:&pt fromView:NULL];
- [self dragFrom: theEvent
- useGrid: YES
- callback: ControlCallback ];
-
- [br removeIfInvalid];
-
- [quakeed_i updateAll];
- qprintf ("");
- return YES;
- }
- /*
- ===============================================================================
- INPUT METHODS
- ===============================================================================
- */
- /*
- ===================
- mouseDown
- ===================
- */
- - mouseDown:(NXEvent *)theEvent
- {
- NXPoint pt;
- id ent;
- vec3_t p1, p2;
- int flags;
-
- pt= theEvent->location;
- [self convertPoint:&pt fromView:NULL];
- p1[0] = p2[0] = pt.x;
- p1[1] = p2[1] = pt.y;
- p1[2] = xy_viewnormal[2] * -4096;
- p2[2] = xy_viewnormal[2] * 4096;
- flags = theEvent->flags & (NX_SHIFTMASK | NX_CONTROLMASK | NX_ALTERNATEMASK | NX_COMMANDMASK);
-
- //
- // shift click to select / deselect a brush from the world
- //
- if (flags == NX_SHIFTMASK)
- {
- [map_i selectRay: p1 : p2 : YES];
- return self;
- }
-
- //
- // cmd-shift click to set a target/targetname entity connection
- //
- if (flags == (NX_SHIFTMASK|NX_COMMANDMASK) )
- {
- [map_i entityConnect: p1 : p2];
- return self;
- }
-
- //
- // bare click to either drag selection, or rubber band a new brush
- //
- if ( flags == 0 )
- {
- // if double click, position Z checker
- if (theEvent->data.mouse.click > 1)
- {
- qprintf ("positioned Z checker");
- [zview_i setPoint: &pt];
- [quakeed_i newinstance];
- [quakeed_i updateZ];
- return self;
- }
-
- // check eye
- if ( [cameraview_i XYmouseDown: &pt flags: theEvent->flags] )
- return self; // camera move
-
- // check z post
- if ( [zview_i XYmouseDown: &pt] )
- return self; // z view move
- // check clippers
- if ( [clipper_i XYDrag: &pt] )
- return self;
- // check single plane dragging
- if ( [self planeDragFrom: theEvent] )
- return self;
- // check selection
- ent = [map_i grabRay: p1 : p2];
- if (ent)
- return [self selectionDragFrom: theEvent];
-
- if ([map_i numSelected])
- {
- qprintf ("missed");
- return self;
- }
-
- return [self newBrushDragFrom: theEvent];
- }
-
- //
- // control click = position and drag camera
- //
- if (flags == NX_CONTROLMASK)
- {
- [cameraview_i setXYOrigin: &pt];
- [quakeed_i newinstance];
- [cameraview_i display];
- [cameraview_i XYmouseDown: &pt flags: theEvent->flags];
- qprintf ("");
- return self;
- }
-
- //
- // command click = drag Z checker
- //
- if (flags == NX_COMMANDMASK)
- {
- // check single plane dragging
- [self shearDragFrom: theEvent];
- return self;
- qprintf ("moving Z checker");
- [zview_i setXYOrigin: &pt];
- [quakeed_i updateAll];
- [zview_i XYmouseDown: &pt];
- qprintf ("");
- return self;
- }
- //
- // alt click = set entire brush texture
- //
- if (flags == NX_ALTERNATEMASK)
- {
- if (drawmode != dr_texture)
- {
- qprintf ("No texture setting except in texture mode!\n");
- NopSound ();
- return self;
- }
- [map_i setTextureRay: p1 : p2 : YES];
- [quakeed_i updateAll];
- return self;
- }
-
- //
- // ctrl-alt click = set single face texture
- //
- if (flags == (NX_CONTROLMASK | NX_ALTERNATEMASK) )
- {
- if (drawmode != dr_texture)
- {
- qprintf ("No texture setting except in texture mode!\n");
- NopSound ();
- return self;
- }
- [map_i setTextureRay: p1 : p2 : NO];
- [quakeed_i updateAll];
- return self;
- }
-
- qprintf ("bad flags for click");
- NopSound ();
- return self;
- }
- /*
- ===================
- rightMouseDown
- ===================
- */
- - rightMouseDown:(NXEvent *)theEvent
- {
- NXPoint pt;
- int flags;
-
- pt= theEvent->location;
- [self convertPoint:&pt fromView:NULL];
- flags = theEvent->flags & (NX_SHIFTMASK | NX_CONTROLMASK | NX_ALTERNATEMASK | NX_COMMANDMASK);
- if (flags == NX_COMMANDMASK)
- {
- return [self scrollDragFrom: theEvent];
- }
- if (flags == NX_ALTERNATEMASK)
- {
- return [clipper_i XYClick: pt];
- }
-
- if (flags == 0 || flags == NX_CONTROLMASK)
- {
- return [self directionDragFrom: theEvent];
- }
-
- qprintf ("bad flags for click");
- NopSound ();
- return self;
- }
- @end
|