Wire selection fixes:

- Fixed MathUtils.LineToPointDistance returning NaN if both points of the line are at the same position, preventing from selecting some wire nodes in the wiring mode.
- Added an indicator that shows when a node is highlighted.
- Wire nodes a higher preference for being highlighted than wire sections. Makes it easier to select nodes that are on top of another wire.

Closes #215
This commit is contained in:
Joonas Rikkonen
2018-01-01 15:04:53 +02:00
parent 79f3f04c3b
commit 78c13ddb42
3 changed files with 38 additions and 23 deletions
@@ -3,6 +3,7 @@ using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Input;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace Barotrauma.Items.Components namespace Barotrauma.Items.Components
{ {
@@ -36,6 +37,12 @@ namespace Barotrauma.Items.Components
} }
} }
private static Sprite wireSprite;
private static Wire draggingWire;
private static int? selectedNodeIndex;
private static int? highlightedNodeIndex;
public void Draw(SpriteBatch spriteBatch, bool editing) public void Draw(SpriteBatch spriteBatch, bool editing)
{ {
if (sections.Count == 0 && !IsActive) if (sections.Count == 0 && !IsActive)
@@ -69,7 +76,7 @@ namespace Barotrauma.Items.Components
foreach (WireSection section in sections) foreach (WireSection section in sections)
{ {
section.Draw(spriteBatch, item.Color, drawOffset, depth, 0.3f); section.Draw(spriteBatch, item.Submarine == null ? Color.Green : item.Color, drawOffset, depth, 0.3f);
} }
if (IsActive && nodes.Count > 0 && Vector2.Distance(newNodePos, nodes[nodes.Count - 1]) > nodeDistance) if (IsActive && nodes.Count > 0 && Vector2.Distance(newNodePos, nodes[nodes.Count - 1]) > nodeDistance)
@@ -91,14 +98,15 @@ namespace Barotrauma.Items.Components
if (item.Submarine != null) drawPos += item.Submarine.Position + item.Submarine.HiddenSubPosition; if (item.Submarine != null) drawPos += item.Submarine.Position + item.Submarine.HiddenSubPosition;
drawPos.Y = -drawPos.Y; drawPos.Y = -drawPos.Y;
if ((highlightedNodeIndex == i && item.IsHighlighted) || (selectedNodeIndex == i && item.IsSelected))
{
GUI.DrawRectangle(spriteBatch, drawPos + new Vector2(-10, -10), new Vector2(20, 20), Color.Red, false, 0.0f);
}
if (item.IsSelected) if (item.IsSelected)
{ {
GUI.DrawRectangle(spriteBatch, drawPos + new Vector2(-5, -5), new Vector2(10, 10), item.Color, true, 0.0f); GUI.DrawRectangle(spriteBatch, drawPos + new Vector2(-5, -5), new Vector2(10, 10), item.Color, true, 0.0f);
if (highlightedNodeIndex == i)
{
GUI.DrawRectangle(spriteBatch, drawPos + new Vector2(-10, -10), new Vector2(20, 20), Color.Red, false, 0.0f);
}
} }
else else
{ {
@@ -196,28 +204,36 @@ namespace Barotrauma.Items.Components
//check which wire is highlighted with the cursor //check which wire is highlighted with the cursor
Wire highlighted = null; Wire highlighted = null;
float closestDist = 0.0f; float closestDist = float.PositiveInfinity;
foreach (Wire w in wires) foreach (Wire w in wires)
{ {
Vector2 mousePos = GameMain.SubEditorScreen.Cam.ScreenToWorld(PlayerInput.MousePosition); Vector2 mousePos = GameMain.SubEditorScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
if (w.item.Submarine != null) mousePos -= (w.item.Submarine.Position + w.item.Submarine.HiddenSubPosition); if (w.item.Submarine != null) mousePos -= (w.item.Submarine.Position + w.item.Submarine.HiddenSubPosition);
float dist = 0.0f; float dist = 0.0f;
if (w.GetClosestNodeIndex(mousePos, highlighted == null ? nodeSelectDist : closestDist, out dist) > -1) int highlightedNode = w.GetClosestNodeIndex(mousePos, highlighted == null ? nodeSelectDist : closestDist, out dist);
if (highlightedNode > -1)
{ {
highlighted = w; if (dist < closestDist)
closestDist = dist; {
highlightedNodeIndex = highlightedNode;
highlighted = w;
closestDist = dist;
}
} }
if (w.GetClosestSectionIndex(mousePos, highlighted == null ? sectionSelectDist : closestDist, out dist) > -1) if (w.GetClosestSectionIndex(mousePos, highlighted == null ? sectionSelectDist : closestDist, out dist) > -1)
{ {
highlighted = w; //prefer nodes over sections
closestDist = dist; if (dist + nodeSelectDist * 0.5f < closestDist)
{
highlightedNodeIndex = null;
highlighted = w;
closestDist = dist + nodeSelectDist * 0.5f;
}
} }
} }
if (highlighted != null) if (highlighted != null)
{ {
highlighted.item.IsHighlighted = true; highlighted.item.IsHighlighted = true;
@@ -30,21 +30,13 @@ namespace Barotrauma.Items.Components
const float nodeDistance = 32.0f; const float nodeDistance = 32.0f;
const float heightFromFloor = 128.0f; const float heightFromFloor = 128.0f;
static Sprite wireSprite;
private List<Vector2> nodes; private List<Vector2> nodes;
private List<WireSection> sections; private List<WireSection> sections;
Connection[] connections; private Connection[] connections;
private Vector2 newNodePos; private Vector2 newNodePos;
private static Wire draggingWire;
private static int? selectedNodeIndex;
private static int? highlightedNodeIndex;
public bool Hidden, Locked; public bool Hidden, Locked;
public Connection[] Connections public Connection[] Connections
@@ -55,12 +47,14 @@ namespace Barotrauma.Items.Components
public Wire(Item item, XElement element) public Wire(Item item, XElement element)
: base(item, element) : base(item, element)
{ {
#if CLIENT
if (wireSprite == null) if (wireSprite == null)
{ {
wireSprite = new Sprite("Content/Items/wireHorizontal.png", new Vector2(0.5f, 0.5f)); wireSprite = new Sprite("Content/Items/wireHorizontal.png", new Vector2(0.5f, 0.5f));
wireSprite.Depth = 0.85f; wireSprite.Depth = 0.85f;
} }
#endif
nodes = new List<Vector2>(); nodes = new List<Vector2>();
sections = new List<WireSection>(); sections = new List<WireSection>();
@@ -336,6 +336,11 @@ namespace Barotrauma
float xDiff = lineB.X - lineA.X; float xDiff = lineB.X - lineA.X;
float yDiff = lineB.Y - lineA.Y; float yDiff = lineB.Y - lineA.Y;
if (xDiff == 0 && yDiff == 0)
{
return Vector2.Distance(lineA, point);
}
return (float)(Math.Abs(xDiff * (lineA.Y - point.Y) - yDiff * (lineA.X - point.X)) / return (float)(Math.Abs(xDiff * (lineA.Y - point.Y) - yDiff * (lineA.X - point.X)) /
Math.Sqrt(xDiff * xDiff + yDiff * yDiff)); Math.Sqrt(xDiff * xDiff + yDiff * yDiff));
} }