mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-18 14:31:50 +00:00
Added, Sectors, Linedefs, Things modes: map element selection order of rectangular selection is now direction-dependent.
This commit is contained in:
parent
e03936a0d6
commit
b1ac703485
4 changed files with 212 additions and 30 deletions
|
@ -68,7 +68,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
// Selection
|
||||
protected bool selecting;
|
||||
protected bool selectpressed; //mxd
|
||||
private Vector2D selectstart;
|
||||
protected Vector2D selectstart;
|
||||
protected RectangleF selectionrect;
|
||||
protected MarqueSelectionMode marqueSelectionMode; //mxd
|
||||
|
||||
|
@ -588,6 +588,31 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
base.OnMouseUp(e);
|
||||
}
|
||||
|
||||
//mxd
|
||||
public override void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
// Update marque color when modifier keys are pressed
|
||||
if(selecting && (e.Control || e.Shift))
|
||||
{
|
||||
OnUpdateMultiSelection();
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
|
||||
base.OnKeyDown(e);
|
||||
}
|
||||
|
||||
//mxd
|
||||
public override void OnKeyUp(KeyEventArgs e)
|
||||
{
|
||||
// Update marque color when modifier keys are released
|
||||
if(selecting && (!e.Control || !e.Shift))
|
||||
{
|
||||
OnUpdateMultiSelection();
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
base.OnKeyUp(e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Automatically called when dragging operation starts.
|
||||
/// </summary>
|
||||
|
|
|
@ -349,6 +349,52 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
return selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) && selectionrect.Contains(l.End.Position.x, l.End.Position.y);
|
||||
}
|
||||
|
||||
//mxd. Gets map elements inside of selectionoutline and sorts them by distance to targetpoint
|
||||
private List<Linedef> GetOrderedSelection(Vector2D targetpoint, List<Line2D> selectionoutline)
|
||||
{
|
||||
// Gather affected sectors
|
||||
List<Linedef> result = new List<Linedef>();
|
||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
||||
{
|
||||
if(IsInSelectionRect(l, selectionoutline)) result.Add(l);
|
||||
}
|
||||
|
||||
if(result.Count == 0) return result;
|
||||
|
||||
// Sort by distance to targetpoint
|
||||
result.Sort(delegate(Linedef l1, Linedef l2)
|
||||
{
|
||||
if(l1 == l2) return 0;
|
||||
|
||||
// Get closest distance from l1 to selectstart
|
||||
float closest1 = float.MaxValue;
|
||||
|
||||
Vector2D pos = l1.Start.Position;
|
||||
float curdistance = Vector2D.DistanceSq(pos, targetpoint);
|
||||
if(curdistance < closest1) closest1 = curdistance;
|
||||
|
||||
pos = l1.End.Position;
|
||||
curdistance = Vector2D.DistanceSq(pos, targetpoint);
|
||||
if(curdistance < closest1) closest1 = curdistance;
|
||||
|
||||
// Get closest distance from l2 to selectstart
|
||||
float closest2 = float.MaxValue;
|
||||
|
||||
pos = l2.Start.Position;
|
||||
curdistance = Vector2D.DistanceSq(pos, targetpoint);
|
||||
if(curdistance < closest2) closest2 = curdistance;
|
||||
|
||||
pos = l2.End.Position;
|
||||
curdistance = Vector2D.DistanceSq(pos, targetpoint);
|
||||
if(curdistance < closest2) closest2 = curdistance;
|
||||
|
||||
// Return closer one
|
||||
return (int)(closest1 - closest2);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//mxd. This sets up new labels
|
||||
private void SetupSectorLabels()
|
||||
{
|
||||
|
@ -992,7 +1038,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
if(selectionvolume)
|
||||
{
|
||||
List<Line2D> selectionOutline = new List<Line2D>
|
||||
List<Line2D> selectionoutline = new List<Line2D>
|
||||
{
|
||||
new Line2D(selectionrect.Left, selectionrect.Top, selectionrect.Right, selectionrect.Top),
|
||||
new Line2D(selectionrect.Right, selectionrect.Top, selectionrect.Right, selectionrect.Bottom),
|
||||
|
@ -1005,8 +1051,15 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
switch(marqueSelectionMode)
|
||||
{
|
||||
case MarqueSelectionMode.SELECT:
|
||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
||||
l.Selected = IsInSelectionRect(l, selectionOutline);
|
||||
// Get ordered selection
|
||||
List<Linedef> selectresult = GetOrderedSelection(base.selectstart, selectionoutline);
|
||||
|
||||
// First deselect everything...
|
||||
foreach(Linedef l in General.Map.Map.Linedefs) l.Selected = false;
|
||||
|
||||
// Then select lines in correct order
|
||||
foreach(Linedef l in selectresult) l.Selected = true;
|
||||
|
||||
if(selectthings)
|
||||
{
|
||||
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
|
||||
|
@ -1015,8 +1068,15 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
break;
|
||||
|
||||
case MarqueSelectionMode.ADD:
|
||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
||||
l.Selected |= IsInSelectionRect(l, selectionOutline);
|
||||
// Get ordered selection
|
||||
List<Linedef> addresult = GetOrderedSelection(selectstart, selectionoutline);
|
||||
|
||||
// First deselect everything inside of selection...
|
||||
foreach(Linedef l in addresult) l.Selected = false;
|
||||
|
||||
// Then reselect in correct order
|
||||
foreach(Linedef l in addresult) l.Selected = true;
|
||||
|
||||
if(selectthings)
|
||||
{
|
||||
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
|
||||
|
@ -1025,8 +1085,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
break;
|
||||
|
||||
case MarqueSelectionMode.SUBTRACT:
|
||||
// Selection order doesn't matter here
|
||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
||||
if(IsInSelectionRect(l, selectionOutline)) l.Selected = false;
|
||||
if(IsInSelectionRect(l, selectionoutline)) l.Selected = false;
|
||||
if(selectthings)
|
||||
{
|
||||
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
|
||||
|
@ -1034,9 +1095,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
}
|
||||
break;
|
||||
|
||||
// Should be Intersect selection mode
|
||||
default:
|
||||
// Selection order doesn't matter here
|
||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
||||
if(!IsInSelectionRect(l, selectionOutline)) l.Selected = false;
|
||||
if(!IsInSelectionRect(l, selectionoutline)) l.Selected = false;
|
||||
if(selectthings)
|
||||
{
|
||||
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
|
||||
|
|
|
@ -606,6 +606,48 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
return false;
|
||||
}
|
||||
|
||||
//mxd. Gets map elements inside of selectionoutline and sorts them by distance to targetpoint
|
||||
private List<Sector> GetOrderedSelection(Vector2D targetpoint, List<Line2D> selectionoutline)
|
||||
{
|
||||
// Gather affected sectors
|
||||
List<Sector> result = new List<Sector>();
|
||||
foreach(Sector s in General.Map.Map.Sectors)
|
||||
{
|
||||
if(IsInSelectionRect(s, selectionoutline)) result.Add(s);
|
||||
}
|
||||
|
||||
if(result.Count == 0) return result;
|
||||
|
||||
// Sort by distance to targetpoint
|
||||
result.Sort(delegate(Sector s1, Sector s2)
|
||||
{
|
||||
if(s1 == s2) return 0;
|
||||
|
||||
// Get closest distance from s1 to selectstart
|
||||
float closest1 = float.MaxValue;
|
||||
foreach(Sidedef side in s1.Sidedefs)
|
||||
{
|
||||
Vector2D pos = (side.IsFront ? side.Line.Start : side.Line.End).Position;
|
||||
float curdistance = Vector2D.DistanceSq(pos, targetpoint);
|
||||
if(curdistance < closest1) closest1 = curdistance;
|
||||
}
|
||||
|
||||
// Get closest distance from s2 to selectstart
|
||||
float closest2 = float.MaxValue;
|
||||
foreach(Sidedef side in s2.Sidedefs)
|
||||
{
|
||||
Vector2D pos = (side.IsFront ? side.Line.Start : side.Line.End).Position;
|
||||
float curdistance = Vector2D.DistanceSq(pos, targetpoint);
|
||||
if(curdistance < closest2) closest2 = curdistance;
|
||||
}
|
||||
|
||||
// Return closer one
|
||||
return (int)(closest1 - closest2);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//mxd
|
||||
public override void SelectMapElement(SelectableElement element)
|
||||
{
|
||||
|
@ -1195,54 +1237,63 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
return true;
|
||||
}
|
||||
|
||||
// This is called wheh selection ends
|
||||
//mxd. This is called wheh selection ends
|
||||
protected override void OnEndMultiSelection()
|
||||
{
|
||||
bool selectionvolume = ((Math.Abs(base.selectionrect.Width) > 0.1f) && (Math.Abs(base.selectionrect.Height) > 0.1f));
|
||||
|
||||
if(selectionvolume)
|
||||
{
|
||||
List<Line2D> selectionOutline = new List<Line2D> {
|
||||
List<Line2D> selectionoutline = new List<Line2D>
|
||||
{
|
||||
new Line2D(selectionrect.Left, selectionrect.Top, selectionrect.Right, selectionrect.Top),
|
||||
new Line2D(selectionrect.Right, selectionrect.Top, selectionrect.Right, selectionrect.Bottom),
|
||||
new Line2D(selectionrect.Left, selectionrect.Bottom, selectionrect.Right, selectionrect.Bottom),
|
||||
new Line2D(selectionrect.Left, selectionrect.Bottom, selectionrect.Left, selectionrect.Top)
|
||||
};
|
||||
|
||||
//mxd. (de)select sectors
|
||||
// (De)select sectors
|
||||
switch(marqueSelectionMode)
|
||||
{
|
||||
case MarqueSelectionMode.SELECT:
|
||||
foreach(Sector s in General.Map.Map.Sectors)
|
||||
{
|
||||
bool select = IsInSelectionRect(s, selectionOutline);
|
||||
if(select && !s.Selected) SelectSector(s, true, false);
|
||||
else if(!select && s.Selected) SelectSector(s, false, false);
|
||||
}
|
||||
// Get ordered selection
|
||||
List<Sector> selectresult = GetOrderedSelection(base.selectstart, selectionoutline);
|
||||
|
||||
// First deselect everything...
|
||||
foreach(Sector s in General.Map.Map.Sectors) SelectSector(s, false, false);
|
||||
|
||||
// Then select sectors in correct order
|
||||
foreach(Sector s in selectresult) SelectSector(s, true, false);
|
||||
break;
|
||||
|
||||
case MarqueSelectionMode.ADD:
|
||||
foreach(Sector s in General.Map.Map.Sectors)
|
||||
{
|
||||
if(!s.Selected && IsInSelectionRect(s, selectionOutline))
|
||||
SelectSector(s, true, false);
|
||||
}
|
||||
// Get ordered selection
|
||||
List<Sector> addresult = GetOrderedSelection(selectstart, selectionoutline);
|
||||
|
||||
// First deselect everything inside of selection...
|
||||
foreach(Sector s in addresult) SelectSector(s, false, false);
|
||||
|
||||
// Then reselect in correct order
|
||||
foreach(Sector s in addresult) SelectSector(s, true, false);
|
||||
break;
|
||||
|
||||
case MarqueSelectionMode.SUBTRACT:
|
||||
// Selection order doesn't matter here
|
||||
foreach(Sector s in General.Map.Map.Sectors)
|
||||
{
|
||||
if(!s.Selected) continue;
|
||||
if(IsInSelectionRect(s, selectionOutline))
|
||||
if(IsInSelectionRect(s, selectionoutline))
|
||||
SelectSector(s, false, false);
|
||||
}
|
||||
break;
|
||||
|
||||
default: //should be Intersect
|
||||
// Should be Intersect selection mode
|
||||
default:
|
||||
// Selection order doesn't matter here
|
||||
foreach(Sector s in General.Map.Map.Sectors)
|
||||
{
|
||||
if(!s.Selected) continue;
|
||||
if(!IsInSelectionRect(s, selectionOutline))
|
||||
if(!IsInSelectionRect(s, selectionoutline))
|
||||
SelectSector(s, false, false);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -804,21 +804,36 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
switch(marqueSelectionMode)
|
||||
{
|
||||
case MarqueSelectionMode.SELECT:
|
||||
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
|
||||
t.Selected = selectionrect.Contains(t.Position.x, t.Position.y);
|
||||
// Get ordered selection
|
||||
List<Thing> selectresult = GetOrderedSelection(base.selectstart, selectionrect);
|
||||
|
||||
// First deselect everything...
|
||||
foreach(Thing t in General.Map.Map.Things) t.Selected = false;
|
||||
|
||||
// Then select things in correct order
|
||||
foreach(Thing t in selectresult) t.Selected = true;
|
||||
break;
|
||||
|
||||
case MarqueSelectionMode.ADD:
|
||||
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
|
||||
t.Selected |= selectionrect.Contains(t.Position.x, t.Position.y);
|
||||
// Get ordered selection
|
||||
List<Thing> addresult = GetOrderedSelection(selectstart, selectionrect);
|
||||
|
||||
// First deselect everything inside of selection...
|
||||
foreach(Thing t in addresult) t.Selected = false;
|
||||
|
||||
// Then reselect in correct order
|
||||
foreach(Thing t in addresult) t.Selected = true;
|
||||
break;
|
||||
|
||||
case MarqueSelectionMode.SUBTRACT:
|
||||
// Selection order doesn't matter here
|
||||
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
|
||||
if(selectionrect.Contains(t.Position.x, t.Position.y)) t.Selected = false;
|
||||
break;
|
||||
|
||||
default: //should be Intersect
|
||||
// Should be Intersect selection mode
|
||||
default:
|
||||
// Selection order doesn't matter here
|
||||
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
|
||||
if(!selectionrect.Contains(t.Position.x, t.Position.y)) t.Selected = false;
|
||||
break;
|
||||
|
@ -891,6 +906,34 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
}
|
||||
}
|
||||
|
||||
//mxd. Gets map elements inside of selectionoutline and sorts them by distance to targetpoint
|
||||
private List<Thing> GetOrderedSelection(Vector2D targetpoint, RectangleF selection)
|
||||
{
|
||||
// Gather affected sectors
|
||||
List<Thing> result = new List<Thing>();
|
||||
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
|
||||
{
|
||||
if(selection.Contains(t.Position.x, t.Position.y)) result.Add(t);
|
||||
}
|
||||
|
||||
if(result.Count == 0) return result;
|
||||
|
||||
// Sort by distance to targetpoint
|
||||
result.Sort(delegate(Thing t1, Thing t2)
|
||||
{
|
||||
if(t1 == t2) return 0;
|
||||
|
||||
// Get closest distance from thing to selectstart
|
||||
float closest1 = Vector2D.DistanceSq(t1.Position, targetpoint);
|
||||
float closest2 = Vector2D.DistanceSq(t2.Position, targetpoint);
|
||||
|
||||
// Return closer one
|
||||
return (int)(closest1 - closest2);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//mxd. This sets up new labels
|
||||
private void SetupSectorLabels()
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue