void JObjectTree::OnMouse( JMouseEvent& e ) { JObject* pNode = PickNode( e.MouseX(), e.MouseY() ); if (e.Action() == aKeyDown && e.MouseKey() == meLeft) { SelectObject( pNode ); } if (pNode) e.Consume(); } // JObjectTree::OnMouse
void JObjectTree::OnDrag( JDragEvent& e ) { Vec2 mPos = e.GetCurPos(); if (e.Key() == mkMiddle) { if (e.GetType() == deDragStart && IsDraggable()) { if (PickNode( mPos.x, mPos.y ) != NULL) { e.SetDragObject( this ); SetDragged(); } } if (e.GetType() == deDrag && e.GetDragObject() == this) { m_RootPos += e.GetDelta(); } } else if (e.Key() == mkRight) { if (e.GetType() == deDragStart) { Frame ext; JObject* pNode = PickNode( mPos.x, mPos.y, &ext ); if (pNode) { e.SetSource( this ); m_pDraggedNode = pNode; m_DragShift = Vec2( mPos.x - ext.x, mPos.y - ext.y ); m_bClone = (GetKeyState( VK_CONTROL ) < 0); } e.Consume(); } if (e.GetType() == deDrag && e.GetSource() == this) { // check whether node can be dropped onto hovered one Frame ext; JObject* pNode = PickNode( e.GetCurPos().x, e.GetCurPos().y, &ext ); bool bAsChild = (mPos.x > ext.center().x); m_bCanDrop = CanDropNode( m_pDraggedNode, pNode, bAsChild, m_bClone ); if (m_bCanDrop) { if (bAsChild) { ext.x += ext.w - 10; ext.w = 10; m_InsExt = ext; } else { ext.y += ext.h; ext.w -= 10; ext.h = 4; m_InsExt = ext; } } e.Consume(); } if (e.GetType() == deDrop && e.GetSource() == this && m_pDraggedNode) { // find node we are going to drop onto Frame ext; JObject* pNode = PickNode( e.GetCurPos().x, e.GetCurPos().y, &ext ); bool bAsChild = (mPos.x > ext.center().x); if (CanDropNode( m_pDraggedNode, pNode, bAsChild, m_bClone )) { DropNode( m_pDraggedNode, pNode, bAsChild, m_bClone ); } m_pDraggedNode = NULL; e.Consume(); } } } // JObjectTree::OnDrag
static inline void DivideSegs(struct Seg *ts, struct Seg **rs, struct Seg **ls, const bbox_t bbox) { struct Seg *rights,*lefts; struct Seg *tmps,*best,*news,*prev; struct Seg *add_to_rs,*add_to_ls; struct Seg *new_best=NULL,*new_rs,*new_ls; struct Seg *strights,*stlefts; int num_new=0; short int x,y,val; best = PickNode(ts,bbox); /* Pick best node to use.*/ if(best == NULL) ProgError("Couldn't pick nodeline!"); node_x = vertices[best->start].x; node_y = vertices[best->start].y; node_dx = vertices[best->end].x-vertices[best->start].x; node_dy = vertices[best->end].y-vertices[best->start].y; /* When we get to here, best is a pointer to the partition seg. Using this partition line, we must split any lines that are intersected into a left and right half, flagging them to be put their respective sides Ok, now we have the best line to use as a partitioning line, we must split all of the segs into two lists (rightside & leftside). */ rights = NULL; /* Start off with empty*/ lefts = NULL; /* lists.*/ strights = NULL; /* Start off with empty*/ stlefts = NULL; /* lists.*/ psx = vertices[best->start].x; /* Partition line coords*/ psy = vertices[best->start].y; pex = vertices[best->end].x; pey = vertices[best->end].y; pdx = psx - pex; /* Partition line DX,DY*/ pdy = psy - pey; for(tmps=ts;tmps;tmps=tmps->next) { progress(); /* Something for the user to look at.*/ add_to_rs = NULL; add_to_ls = NULL; if(tmps != best) { lsx = vertices[tmps->start].x; /* Calculate this here, cos it doesn't*/ lsy = vertices[tmps->start].y; /* change for all the interations of*/ lex = vertices[tmps->end].x; /* the inner loop!*/ ley = vertices[tmps->end].y; val = DoLinesIntersect(); if((val&2 && val&64) || (val&4 && val&32)) /* If intersecting !!*/ { ComputeIntersection(&x,&y); /* printf("Splitting Linedef %d at %d,%d\n",tmps->linedef,x,y);*/ vertices = ResizeMemory(vertices, sizeof(struct Vertex) * (num_verts+1)); vertices[num_verts].x = x; vertices[num_verts].y = y; news = GetMemory(sizeof( struct Seg)); *news = *tmps; tmps->next = news; news->start = num_verts; tmps->end = num_verts; news->dist = SplitDist(news); /* printf("splitting dist = %d\n",news->dist);*/ /* printf("splitting vertices = %d,%d,%d,%d\n",tmps->start,tmps->end,news->start,news->end);*/ if(val&32) add_to_ls = tmps; if(val&64) add_to_rs = tmps; if(val&2) add_to_ls = news; if(val&4) add_to_rs = news; tmps = news; num_verts++; num_new++; } else { /* Not split, which side ?*/ if(val&34) add_to_ls = tmps; if(val&68) add_to_rs = tmps; if(val&1 && val&16) /* On same line*/ { /* 06/01/97 Lee Killough: this fixes a bug ever since 1.2x, probably 1.0, of BSP: when partitioning a parallel seg, you must take its vertices' orientation into account, NOT the flip bits, to determine which side of the partitioning line a parallel seg should go on. If you simply flip the linedef in question, you will be flipping both its vertices and sidedefs, and the flip bits as well, even though the basic geometry has not changed. Thus you need to use the vertices' orientation (whether the seg is in the same direction or not, regardless of its original linedef's being flipped or not), into account. Originally, some segs were partitioned backwards, and if it happened that there were different sectors on either side of the seg being partitioned, it could leave holes in space, causing either invisible barriers or disappearing Things, because the ssector would be associated with the wrong sector. The old logic of tmps->flip != best->flip seems to rest on the assumption that if two segs are parallel, they came from the same linedef. This is clearly not always true. */ /* if (tmps->flip != best->flip) old logic -- wrong!!! */ /* We know the segs are parallel or nearly so, so take their dot product to determine their relative orientation. */ if ( (lsx-lex)*pdx + (lsy-ley)*pdy < 0) add_to_ls = tmps; else add_to_rs = tmps; } } } else add_to_rs = tmps; /* This is the partition line*/ /* printf("Val = %X\n",val);*/ if(add_to_rs) /* CHECK IF SHOULD ADD RIGHT ONE */ { new_rs = GetMemory(sizeof(struct Seg)); *new_rs = *add_to_rs; if(add_to_rs == best) new_best = new_rs; new_rs->next = NULL; if(!rights) strights = rights = new_rs; else { rights->next = new_rs; rights = new_rs; } } if(add_to_ls) /* CHECK IF SHOULD ADD LEFT ONE */ { new_ls = GetMemory(sizeof(struct Seg)); *new_ls = *add_to_ls; if(add_to_ls == best) new_best = new_ls; new_ls->next = NULL; if(!lefts) stlefts = lefts = new_ls; else { lefts->next = new_ls; lefts = new_ls; } } } if(strights == NULL) { /* printf("No right side, moving partition into right side\n");*/ strights = rights = new_best; prev = NULL; for(tmps=stlefts;tmps;tmps=tmps->next) { if(tmps == new_best) { if(prev != NULL) prev->next=tmps->next; else stlefts=tmps->next; } prev=tmps; } prev->next = NULL; } if(stlefts == NULL) { /* printf("No left side, moving partition into left side\n");*/ stlefts = lefts = new_best; prev = NULL; for(tmps=strights;tmps;tmps=tmps->next) { if(tmps == new_best) { if(prev != NULL) prev->next=tmps->next; else strights=tmps->next; } prev=tmps; } stlefts->next = NULL; prev->next = NULL; /* Make sure end of list = NULL*/ } if(rights->next != NULL) rights->next = NULL; if(lefts->next != NULL) lefts->next = NULL; for(tmps=ts;tmps;tmps=best) { best=tmps->next; free(tmps); } /* printf("Made %d new Vertices and Segs\n",num_new);*/ *rs = strights ; *ls = stlefts; }