public override void Update(double deltaTime) { if (GameMain.GraphicsWidth != screenResolution.X || GameMain.GraphicsHeight != screenResolution.Y) { CreateGUI(); } Cam.MoveCamera((float)deltaTime, true, true); Vector2 mousePos = Cam.ScreenToWorld(PlayerInput.MousePosition); mousePos.Y = -mousePos.Y; foreach (EditorNode node in nodeList) { if (PlayerInput.PrimaryMouseButtonDown()) { NodeConnection?connection = node.GetConnectionOnMouse(mousePos); if (connection != null && connection.Type.NodeSide == NodeConnectionType.Side.Right) { if (connection.Type != NodeConnectionType.Out) { if (connection.ConnectedTo.Any()) { return; } } DraggedConnection = connection; } } // ReSharper disable once AssignmentInConditionalExpression if (node.IsHighlighted = node.HeaderRectangle.Contains(mousePos)) { if (PlayerInput.PrimaryMouseButtonDown()) { // Ctrl + clicking the headers add them to the "selection" that allows us to drag multiple nodes at once if (PlayerInput.IsCtrlDown()) { if (selectedNodes.Contains(node)) { selectedNodes.Remove(node); } else { selectedNodes.Add(node); } node.IsSelected = selectedNodes.Contains(node); break; } draggedNode = node; dragOffset = draggedNode.Position - mousePos; foreach (EditorNode selectedNode in selectedNodes) { if (!markedNodes.ContainsKey(selectedNode)) { markedNodes.Add(selectedNode, selectedNode.Position - mousePos); } } } } if (PlayerInput.SecondaryMouseButtonClicked()) { NodeConnection?connection = node.GetConnectionOnMouse(mousePos); if (node.GetDrawRectangle().Contains(mousePos) || connection != null) { CreateContextMenu(node, node.GetConnectionOnMouse(mousePos)); break; } } } if (PlayerInput.SecondaryMouseButtonClicked()) { foreach (var selectedNode in selectedNodes) { selectedNode.IsSelected = false; } selectedNodes.Clear(); } if (draggedNode != null) { if (!PlayerInput.PrimaryMouseButtonHeld()) { draggedNode = null; markedNodes.Clear(); } else { Vector2 offsetChange = Vector2.Zero; draggedNode.IsHighlighted = true; draggedNode.Position = mousePos + dragOffset; if (PlayerInput.KeyHit(Keys.Up)) { offsetChange.Y--; } if (PlayerInput.KeyHit(Keys.Down)) { offsetChange.Y++; } if (PlayerInput.KeyHit(Keys.Left)) { offsetChange.X--; } if (PlayerInput.KeyHit(Keys.Right)) { offsetChange.X++; } dragOffset += offsetChange; foreach (var(editorNode, offset) in markedNodes.Where(pair => pair.Key != draggedNode)) { editorNode.Position = mousePos + offset; } if (offsetChange != Vector2.Zero) { foreach (var(key, value) in markedNodes.ToList()) { markedNodes[key] = value + offsetChange; } } } } if (DraggedConnection != null) { if (!PlayerInput.PrimaryMouseButtonHeld()) { foreach (EditorNode node in nodeList) { var nodeOnMouse = node.GetConnectionOnMouse(mousePos); if (nodeOnMouse != null && nodeOnMouse != DraggedConnection && nodeOnMouse.Type.NodeSide == NodeConnectionType.Side.Left) { if (!DraggedConnection.CanConnect(nodeOnMouse)) { continue; } nodeOnMouse.ClearConnections(); DraggedConnection.Parent.Connect(DraggedConnection, nodeOnMouse); break; } } DraggedConnection = null; } else { DraggingPosition = mousePos; } } else { DraggingPosition = Vector2.Zero; } if (contextMenu != null) { Rectangle expandedRect = contextMenu.Rect; expandedRect.Inflate(20, 20); if (!expandedRect.Contains(PlayerInput.MousePosition)) { contextMenu = null; } } if (PlayerInput.MidButtonHeld()) { Vector2 moveSpeed = PlayerInput.MouseSpeed * (float)deltaTime * 60.0f / Cam.Zoom; moveSpeed.X = -moveSpeed.X; Cam.Position += moveSpeed; } base.Update(deltaTime); }
private static void UpdateHighlightedListBox(List <MapEntity> highlightedEntities, bool wiringMode) { if (highlightedEntities == null || highlightedEntities.Count < 2) { highlightedListBox = null; return; } if (highlightedListBox != null) { if (GUI.MouseOn == highlightedListBox || highlightedListBox.IsParentOf(GUI.MouseOn)) { return; } if (highlightedEntities.SequenceEqual(highlightedList)) { return; } } highlightedList = highlightedEntities; highlightedListBox = new GUIListBox(new RectTransform(new Point(180, highlightedEntities.Count * 18 + 5), GUI.Canvas) { MaxSize = new Point(int.MaxValue, 256), ScreenSpaceOffset = PlayerInput.MousePosition.ToPoint() + new Point(15) }, style: "GUIToolTip"); foreach (MapEntity entity in highlightedEntities) { var tooltip = string.Empty; if (wiringMode && entity is Item item) { var wire = item.GetComponent <Wire>(); if (wire?.Connections != null) { for (var i = 0; i < wire.Connections.Length; i++) { var conn = wire.Connections[i]; if (conn != null) { string[] tags = { "[item]", "[pin]" }; string[] values = { conn.Item?.Name, conn.Name }; tooltip += TextManager.GetWithVariables("wirelistformat", tags, values); } if (i != wire.Connections.Length - 1) { tooltip += '\n'; } } } } var textBlock = new GUITextBlock(new RectTransform(new Point(highlightedListBox.Content.Rect.Width, 15), highlightedListBox.Content.RectTransform), ToolBox.LimitString(entity.Name, GUI.SmallFont, 140), font: GUI.SmallFont) { ToolTip = tooltip, UserData = entity }; } highlightedListBox.OnSelected = (GUIComponent component, object obj) => { MapEntity entity = obj as MapEntity; if (PlayerInput.IsCtrlDown() && !wiringMode) { if (selectedList.Contains(entity)) { RemoveSelection(entity); } else { AddSelection(entity); } return(true); } SelectEntity(entity); return(true); }; }
public static void UpdateEditor(Camera cam) { if (highlightedListBox != null) { highlightedListBox.UpdateManually((float)Timing.Step); } if (editingHUD != null) { if (FilteredSelectedList.Count == 0 || editingHUD.UserData != FilteredSelectedList[0]) { foreach (GUIComponent component in editingHUD.Children) { var textBox = component as GUITextBox; if (textBox == null) { continue; } textBox.Deselect(); } editingHUD = null; } } FilteredSelectedList.Clear(); if (selectedList.Count == 0) { return; } foreach (var e in selectedList) { if (e is Gap gap && gap.ConnectedDoor != null) { continue; } FilteredSelectedList.Add(e); } var first = FilteredSelectedList.FirstOrDefault(); if (first != null) { first.UpdateEditing(cam); if (first.ResizeHorizontal || first.ResizeVertical) { first.UpdateResizing(cam); } } if (PlayerInput.IsCtrlDown()) { if (PlayerInput.KeyHit(Keys.N)) { float minX = selectedList[0].WorldRect.X, maxX = selectedList[0].WorldRect.Right; for (int i = 0; i < selectedList.Count; i++) { minX = Math.Min(minX, selectedList[i].WorldRect.X); maxX = Math.Max(maxX, selectedList[i].WorldRect.Right); } float centerX = (minX + maxX) / 2.0f; foreach (MapEntity me in selectedList) { me.FlipX(false); me.Move(new Vector2((centerX - me.WorldPosition.X) * 2.0f, 0.0f)); } } else if (PlayerInput.KeyHit(Keys.M)) { float minY = selectedList[0].WorldRect.Y - selectedList[0].WorldRect.Height, maxY = selectedList[0].WorldRect.Y; for (int i = 0; i < selectedList.Count; i++) { minY = Math.Min(minY, selectedList[i].WorldRect.Y - selectedList[i].WorldRect.Height); maxY = Math.Max(maxY, selectedList[i].WorldRect.Y); } float centerY = (minY + maxY) / 2.0f; foreach (MapEntity me in selectedList) { me.FlipY(false); me.Move(new Vector2(0.0f, (centerY - me.WorldPosition.Y) * 2.0f)); } } } }
/// <summary> /// Update the selection logic in submarine editor /// </summary> public static void UpdateSelecting(Camera cam) { if (resizing) { if (selectedList.Count == 0) { resizing = false; } return; } foreach (MapEntity e in mapEntityList) { e.isHighlighted = false; } if (DisableSelect) { DisableSelect = false; return; } if (GUI.MouseOn != null || !PlayerInput.MouseInsideWindow) { if (highlightedListBox == null || (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn))) { UpdateHighlightedListBox(null, false); return; } } if (MapEntityPrefab.Selected != null) { selectionPos = Vector2.Zero; selectedList.Clear(); return; } if (GUI.KeyboardDispatcher.Subscriber == null) { if (PlayerInput.KeyDown(Keys.Delete)) { selectedList.ForEach(e => { //orphaned wires may already have been removed if (!e.Removed) { e.Remove(); } }); selectedList.Clear(); } if (PlayerInput.IsCtrlDown()) { if (PlayerInput.KeyHit(Keys.C)) { Copy(selectedList); } else if (PlayerInput.KeyHit(Keys.X)) { Cut(selectedList); } else if (PlayerInput.KeyHit(Keys.V)) { Paste(cam.WorldViewCenter); } else if (PlayerInput.KeyHit(Keys.G)) { if (selectedList.Any()) { if (SelectionGroups.ContainsKey(selectedList.Last())) { // Ungroup all selected selectedList.ForEach(e => SelectionGroups.Remove(e)); } else { foreach (var entity in selectedList) { // Remove the old group, if any SelectionGroups.Remove(entity); // Create a group that can be accessed with any member SelectionGroups.Add(entity, selectedList); } } } } else if (PlayerInput.KeyHit(Keys.Z)) { SetPreviousRects(e => e.rectMemento.Undo()); } else if (PlayerInput.KeyHit(Keys.R)) { SetPreviousRects(e => e.rectMemento.Redo()); } void SetPreviousRects(Func <MapEntity, Rectangle> memoryMethod) { foreach (var e in SelectedList) { if (e.rectMemento != null) { Point diff = memoryMethod(e).Location - e.Rect.Location; // We have to call the move method, because there's a lot more than just storing the rect (in some cases) // We also have to reassign the rect, because the move method does not set the width and height. They might have changed too. // The Rect property is virtual and it's overridden for structs. Setting the rect via the property should automatically recreate the sections for resizable structures. e.Move(diff.ToVector2()); e.Rect = e.rectMemento.Current; } } } } } Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition); MapEntity highLightedEntity = null; if (startMovingPos == Vector2.Zero) { List <MapEntity> highlightedEntities = new List <MapEntity>(); if (highlightedListBox != null && highlightedListBox.IsParentOf(GUI.MouseOn)) { highLightedEntity = GUI.MouseOn.UserData as MapEntity; } else { foreach (MapEntity e in mapEntityList) { if (!e.SelectableInEditor) { continue; } if (e.IsMouseOn(position)) { int i = 0; while (i < highlightedEntities.Count && e.Sprite != null && (highlightedEntities[i].Sprite == null || highlightedEntities[i].SpriteDepth < e.SpriteDepth)) { i++; } highlightedEntities.Insert(i, e); if (i == 0) { highLightedEntity = e; } } } UpdateHighlighting(highlightedEntities); } if (highLightedEntity != null) { highLightedEntity.isHighlighted = true; } } if (GUI.KeyboardDispatcher.Subscriber == null) { int up = PlayerInput.KeyDown(Keys.Up) ? 1 : 0, down = PlayerInput.KeyDown(Keys.Down) ? -1 : 0, left = PlayerInput.KeyDown(Keys.Left) ? -1 : 0, right = PlayerInput.KeyDown(Keys.Right) ? 1 : 0; int xKeysDown = (left + right); int yKeysDown = (up + down); if (xKeysDown != 0 || yKeysDown != 0) { keyDelay += (float)Timing.Step; } else { keyDelay = 0; } Vector2 nudgeAmount = Vector2.Zero; if (keyDelay >= 0.5f) { nudgeAmount.Y = yKeysDown; nudgeAmount.X = xKeysDown; } if (PlayerInput.KeyHit(Keys.Up)) { nudgeAmount.Y = 1f; } if (PlayerInput.KeyHit(Keys.Down)) { nudgeAmount.Y = -1f; } if (PlayerInput.KeyHit(Keys.Left)) { nudgeAmount.X = -1f; } if (PlayerInput.KeyHit(Keys.Right)) { nudgeAmount.X = 1f; } if (nudgeAmount != Vector2.Zero) { foreach (MapEntity entityToNudge in selectedList) { entityToNudge.Move(nudgeAmount); } } } else { keyDelay = 0; } bool isShiftDown = PlayerInput.IsShiftDown(); //started moving selected entities if (startMovingPos != Vector2.Zero) { Item targetContainer = GetPotentialContainer(position, selectedList); if (targetContainer != null) { targetContainer.IsHighlighted = true; } if (PlayerInput.PrimaryMouseButtonReleased()) { //mouse released -> move the entities to the new position of the mouse Vector2 moveAmount = position - startMovingPos; if (!isShiftDown) { moveAmount.X = (float)(moveAmount.X > 0.0f ? Math.Floor(moveAmount.X / Submarine.GridSize.X) : Math.Ceiling(moveAmount.X / Submarine.GridSize.X)) * Submarine.GridSize.X; moveAmount.Y = (float)(moveAmount.Y > 0.0f ? Math.Floor(moveAmount.Y / Submarine.GridSize.Y) : Math.Ceiling(moveAmount.Y / Submarine.GridSize.Y)) * Submarine.GridSize.Y; } if (Math.Abs(moveAmount.X) >= Submarine.GridSize.X || Math.Abs(moveAmount.Y) >= Submarine.GridSize.Y || isShiftDown) { if (!isShiftDown) { moveAmount = Submarine.VectorToWorldGrid(moveAmount); } //clone if (PlayerInput.IsCtrlDown()) { var clones = Clone(selectedList); selectedList = clones; selectedList.ForEach(c => c.Move(moveAmount)); } else // move { List <MapEntity> deposited = new List <MapEntity>(); foreach (MapEntity e in selectedList) { if (e.rectMemento == null) { e.rectMemento = new Memento <Rectangle>(); e.rectMemento.Store(e.Rect); } e.Move(moveAmount); if (isShiftDown && e is Item item && targetContainer != null) { if (targetContainer.OwnInventory.TryPutItem(item, Character.Controlled)) { GUI.PlayUISound(GUISoundType.DropItem); deposited.Add(item); } else { GUI.PlayUISound(GUISoundType.PickItemFail); } } e.rectMemento.Store(e.Rect); } deposited.ForEach(entity => { selectedList.Remove(entity); }); } } startMovingPos = Vector2.Zero; } } //started dragging a "selection rectangle" else if (selectionPos != Vector2.Zero) { selectionSize.X = position.X - selectionPos.X; selectionSize.Y = selectionPos.Y - position.Y; List <MapEntity> newSelection = new List <MapEntity>();// FindSelectedEntities(selectionPos, selectionSize); if (Math.Abs(selectionSize.X) > Submarine.GridSize.X || Math.Abs(selectionSize.Y) > Submarine.GridSize.Y) { newSelection = FindSelectedEntities(selectionPos, selectionSize); } else { if (highLightedEntity != null) { if (SelectionGroups.TryGetValue(highLightedEntity, out List <MapEntity> group)) { newSelection.AddRange(group); } else { newSelection.Add(highLightedEntity); } } } if (PlayerInput.PrimaryMouseButtonReleased()) { if (PlayerInput.IsCtrlDown()) { foreach (MapEntity e in newSelection) { if (selectedList.Contains(e)) { RemoveSelection(e); } else { AddSelection(e); } } } else { selectedList = new List <MapEntity>(newSelection); //selectedList.Clear(); //newSelection.ForEach(e => AddSelection(e)); foreach (var entity in newSelection) { HandleDoorGapLinks(entity, onGapFound: (door, gap) => { door.RefreshLinkedGap(); if (!selectedList.Contains(gap)) { selectedList.Add(gap); } }, onDoorFound: (door, gap) => { if (!selectedList.Contains(door.Item)) { selectedList.Add(door.Item); } }); } } //select wire if both items it's connected to are selected var selectedItems = selectedList.Where(e => e is Item).Cast <Item>().ToList(); foreach (Item item in selectedItems) { if (item.Connections == null) { continue; } foreach (Connection c in item.Connections) { foreach (Wire w in c.Wires) { if (w == null || selectedList.Contains(w.Item)) { continue; } if (w.OtherConnection(c) != null && selectedList.Contains(w.OtherConnection(c).Item)) { selectedList.Add(w.Item); } } } } selectionPos = Vector2.Zero; selectionSize = Vector2.Zero; } } //default, not doing anything specific yet else { if (PlayerInput.PrimaryMouseButtonHeld() && PlayerInput.KeyUp(Keys.Space) && (highlightedListBox == null || (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn)))) { //if clicking a selected entity, start moving it foreach (MapEntity e in selectedList) { if (e.IsMouseOn(position)) { startMovingPos = position; } } selectionPos = position; //stop camera movement to prevent accidental dragging or rect selection Screen.Selected.Cam.StopMovement(); } } }
private void DrawWidgets(SpriteBatch spriteBatch) { float widgetSize = Image == null ? 100f : Math.Max(Image.Width, Image.Height) / 2f; int width = 3; int size = 32; if (DrawTarget == DrawTargetType.World) { width = Math.Max(width, (int)(width / Screen.Selected.Cam.Zoom)); } Widget currentWidget = GetWidget("transform", size, width, widget => { widget.MouseDown += () => { widget.color = GUI.Style.Green; prevAngle = Rotation; disableMove = true; }; widget.Deselected += () => { widget.color = Color.Yellow; disableMove = false; }; widget.MouseHeld += (deltaTime) => { Rotation = GetRotationAngle(Position) + (float)Math.PI / 2f; float distance = Vector2.Distance(Position, GetMousePos()); Scale = Math.Abs(distance) / widgetSize; if (PlayerInput.IsShiftDown()) { const float rotationStep = (float)(Math.PI / 4f); Rotation = (float)Math.Round(Rotation / rotationStep) * rotationStep; } if (PlayerInput.IsCtrlDown()) { const float scaleStep = 0.1f; Scale = (float)Math.Round(Scale / scaleStep) * scaleStep; } UpdateRectangle(); }; widget.PreUpdate += (deltaTime) => { if (DrawTarget != DrawTargetType.World) { return; } widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y); widget.DrawPos = Screen.Selected.Cam.WorldToScreen(widget.DrawPos); }; widget.PostUpdate += (deltaTime) => { if (DrawTarget != DrawTargetType.World) { return; } widget.DrawPos = Screen.Selected.Cam.ScreenToWorld(widget.DrawPos); widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y); }; widget.PreDraw += (sprtBtch, deltaTime) => { widget.tooltip = $"Scale: {Math.Round(Scale, 2)}\n" + $"Rotation: {(int) MathHelper.ToDegrees(Rotation)}"; float rotation = Rotation - (float)Math.PI / 2f; widget.DrawPos = Position + new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) * (Scale * widgetSize); widget.Update(deltaTime); }; }); currentWidget.Draw(spriteBatch, (float)Timing.Step); GUI.DrawLine(spriteBatch, Position, currentWidget.DrawPos, GUI.Style.Green, width: width); }
public void Update(float deltaTime) { if (!EditorMode) { return; } foreach (EditorImage image in Images) { image.Update(deltaTime); } if (PlayerInput.PrimaryMouseButtonDown()) { EditorImage?hover = Images.FirstOrDefault(img => img.IsMouseOn()); if (hover != null) { foreach (EditorImage image in Images) { image.Selected = false; } hover.Selected = true; } } if (PlayerInput.KeyHit(Keys.Delete) || (PlayerInput.IsCtrlDown() && PlayerInput.KeyHit(Keys.D))) { Images.RemoveAll(img => img.Selected); UpdateImageCategories(); } if (PlayerInput.KeyHit(Keys.Space)) { foreach (EditorImage image in Images) { if (image.Selected) { if (image.DrawTarget == EditorImage.DrawTargetType.World) { Vector2 pos = image.Position; pos.Y = -pos.Y; pos = Screen.Selected.Cam.WorldToScreen(pos); if (PlayerInput.IsShiftDown()) { pos = new Vector2(GameMain.GraphicsWidth / 2f, GameMain.GraphicsHeight / 2f); } image.Position = pos; image.DrawTarget = EditorImage.DrawTargetType.Camera; image.Scale *= Screen.Selected.Cam.Zoom; image.UpdateRectangle(); } else { Vector2 pos = Screen.Selected.Cam.ScreenToWorld(image.Position); pos.Y = -pos.Y; image.Position = pos; image.DrawTarget = EditorImage.DrawTargetType.World; image.Scale /= Screen.Selected.Cam.Zoom; image.UpdateRectangle(); } } } UpdateImageCategories(); } MapEntity.DisableSelect = true; }
/// <summary> /// Update the selection logic in submarine editor /// </summary> public static void UpdateSelecting(Camera cam) { if (resizing) { if (selectedList.Count == 0) { resizing = false; } return; } foreach (MapEntity e in mapEntityList) { e.isHighlighted = false; } if (DisableSelect) { DisableSelect = false; return; } if (GUI.MouseOn != null || !PlayerInput.MouseInsideWindow) { if (highlightedListBox == null || (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn))) { UpdateHighlightedListBox(null, false); return; } } if (MapEntityPrefab.Selected != null) { selectionPos = Vector2.Zero; selectedList.Clear(); return; } if (GUI.KeyboardDispatcher.Subscriber == null) { if (PlayerInput.KeyHit(Keys.Delete)) { if (selectedList.Any()) { SubEditorScreen.StoreCommand(new AddOrDeleteCommand(selectedList, true)); } selectedList.ForEach(e => { if (!e.Removed) { e.Remove(); } }); selectedList.Clear(); } if (PlayerInput.IsCtrlDown()) { #if DEBUG if (PlayerInput.KeyHit(Keys.D)) { bool terminate = false; foreach (MapEntity entity in selectedList) { if (entity is Item item && item.GetComponent <Planter>() is { } planter) { planter.Update(1.0f, cam); for (var i = 0; i < planter.GrowableSeeds.Length; i++) { Growable seed = planter.GrowableSeeds[i]; PlantSlot slot = planter.PlantSlots.ContainsKey(i) ? planter.PlantSlots[i] : Planter.NullSlot; if (seed == null) { continue; } seed.CreateDebugHUD(planter, slot); terminate = true; break; } } if (terminate) { break; } } } #endif if (PlayerInput.KeyHit(Keys.C)) { Copy(selectedList); } else if (PlayerInput.KeyHit(Keys.X)) { Cut(selectedList); } else if (PlayerInput.KeyHit(Keys.V)) { Paste(cam.WorldViewCenter); } else if (PlayerInput.KeyHit(Keys.G)) { if (selectedList.Any()) { if (SelectionGroups.ContainsKey(selectedList.Last())) { // Ungroup all selected selectedList.ForEach(e => SelectionGroups.Remove(e)); } else { foreach (var entity in selectedList) { // Remove the old group, if any SelectionGroups.Remove(entity); // Create a group that can be accessed with any member SelectionGroups.Add(entity, selectedList); } } } } } } Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition); MapEntity highLightedEntity = null; if (startMovingPos == Vector2.Zero) { List <MapEntity> highlightedEntities = new List <MapEntity>(); if (highlightedListBox != null && highlightedListBox.IsParentOf(GUI.MouseOn)) { highLightedEntity = GUI.MouseOn.UserData as MapEntity; } else { foreach (MapEntity e in mapEntityList) { if (!e.SelectableInEditor) { continue; } if (e.IsMouseOn(position)) { int i = 0; while (i < highlightedEntities.Count && e.Sprite != null && (highlightedEntities[i].Sprite == null || highlightedEntities[i].SpriteDepth < e.SpriteDepth)) { i++; } highlightedEntities.Insert(i, e); if (i == 0) { highLightedEntity = e; } } } UpdateHighlighting(highlightedEntities); } if (highLightedEntity != null) { highLightedEntity.isHighlighted = true; } } if (GUI.KeyboardDispatcher.Subscriber == null) { int up = PlayerInput.KeyDown(Keys.Up) ? 1 : 0, down = PlayerInput.KeyDown(Keys.Down) ? -1 : 0, left = PlayerInput.KeyDown(Keys.Left) ? -1 : 0, right = PlayerInput.KeyDown(Keys.Right) ? 1 : 0; int xKeysDown = (left + right); int yKeysDown = (up + down); if (xKeysDown != 0 || yKeysDown != 0) { keyDelay += (float)Timing.Step; } else { keyDelay = 0; } Vector2 nudgeAmount = Vector2.Zero; if (keyDelay >= 0.5f) { nudgeAmount.Y = yKeysDown; nudgeAmount.X = xKeysDown; } if (PlayerInput.KeyHit(Keys.Up)) { nudgeAmount.Y = 1f; } if (PlayerInput.KeyHit(Keys.Down)) { nudgeAmount.Y = -1f; } if (PlayerInput.KeyHit(Keys.Left)) { nudgeAmount.X = -1f; } if (PlayerInput.KeyHit(Keys.Right)) { nudgeAmount.X = 1f; } if (nudgeAmount != Vector2.Zero) { foreach (MapEntity entityToNudge in selectedList) { entityToNudge.Move(nudgeAmount); } } } else { keyDelay = 0; } bool isShiftDown = PlayerInput.IsShiftDown(); //started moving selected entities if (startMovingPos != Vector2.Zero) { Item targetContainer = GetPotentialContainer(position, selectedList); if (targetContainer != null) { targetContainer.IsHighlighted = true; } if (PlayerInput.PrimaryMouseButtonReleased()) { //mouse released -> move the entities to the new position of the mouse Vector2 moveAmount = position - startMovingPos; if (!isShiftDown) { moveAmount.X = (float)(moveAmount.X > 0.0f ? Math.Floor(moveAmount.X / Submarine.GridSize.X) : Math.Ceiling(moveAmount.X / Submarine.GridSize.X)) * Submarine.GridSize.X; moveAmount.Y = (float)(moveAmount.Y > 0.0f ? Math.Floor(moveAmount.Y / Submarine.GridSize.Y) : Math.Ceiling(moveAmount.Y / Submarine.GridSize.Y)) * Submarine.GridSize.Y; } if (Math.Abs(moveAmount.X) >= Submarine.GridSize.X || Math.Abs(moveAmount.Y) >= Submarine.GridSize.Y || isShiftDown) { if (!isShiftDown) { moveAmount = Submarine.VectorToWorldGrid(moveAmount); } //clone if (PlayerInput.IsCtrlDown()) { var clones = Clone(selectedList).Where(c => c != null).ToList(); selectedList = clones; SubEditorScreen.StoreCommand(new AddOrDeleteCommand(clones, false)); selectedList.ForEach(c => c.Move(moveAmount)); } else // move { var oldRects = selectedList.Select(e => e.Rect).ToList(); List <MapEntity> deposited = new List <MapEntity>(); foreach (MapEntity e in selectedList) { e.Move(moveAmount); if (isShiftDown && e is Item item && targetContainer != null) { if (targetContainer.OwnInventory.TryPutItem(item, Character.Controlled)) { SoundPlayer.PlayUISound(GUISoundType.DropItem); deposited.Add(item); } else { SoundPlayer.PlayUISound(GUISoundType.PickItemFail); } } } SubEditorScreen.StoreCommand(new TransformCommand(new List <MapEntity>(selectedList), selectedList.Select(entity => entity.Rect).ToList(), oldRects, false)); if (deposited.Any() && deposited.Any(entity => entity is Item)) { var depositedItems = deposited.Where(entity => entity is Item).Cast <Item>().ToList(); SubEditorScreen.StoreCommand(new InventoryPlaceCommand(targetContainer.OwnInventory, depositedItems, false)); } deposited.ForEach(entity => { selectedList.Remove(entity); }); } } startMovingPos = Vector2.Zero; } } //started dragging a "selection rectangle" else if (selectionPos != Vector2.Zero) { selectionSize.X = position.X - selectionPos.X; selectionSize.Y = selectionPos.Y - position.Y; List <MapEntity> newSelection = new List <MapEntity>();// FindSelectedEntities(selectionPos, selectionSize); if (Math.Abs(selectionSize.X) > Submarine.GridSize.X || Math.Abs(selectionSize.Y) > Submarine.GridSize.Y) { newSelection = FindSelectedEntities(selectionPos, selectionSize); } else { if (highLightedEntity != null) { if (SelectionGroups.TryGetValue(highLightedEntity, out List <MapEntity> group)) { newSelection.AddRange(group); } else { newSelection.Add(highLightedEntity); } } } if (PlayerInput.PrimaryMouseButtonReleased()) { if (PlayerInput.IsCtrlDown()) { foreach (MapEntity e in newSelection) { if (selectedList.Contains(e)) { RemoveSelection(e); } else { AddSelection(e); } } } else { selectedList = new List <MapEntity>(newSelection); //selectedList.Clear(); //newSelection.ForEach(e => AddSelection(e)); foreach (var entity in newSelection) { HandleDoorGapLinks(entity, onGapFound: (door, gap) => { door.RefreshLinkedGap(); if (!selectedList.Contains(gap)) { selectedList.Add(gap); } }, onDoorFound: (door, gap) => { if (!selectedList.Contains(door.Item)) { selectedList.Add(door.Item); } }); } } //select wire if both items it's connected to are selected var selectedItems = selectedList.Where(e => e is Item).Cast <Item>().ToList(); foreach (Item item in selectedItems) { if (item.Connections == null) { continue; } foreach (Connection c in item.Connections) { foreach (Wire w in c.Wires) { if (w == null || selectedList.Contains(w.Item)) { continue; } if (w.OtherConnection(c) != null && selectedList.Contains(w.OtherConnection(c).Item)) { selectedList.Add(w.Item); } } } } selectionPos = Vector2.Zero; selectionSize = Vector2.Zero; } } //default, not doing anything specific yet else { if (PlayerInput.PrimaryMouseButtonHeld() && PlayerInput.KeyUp(Keys.Space) && (highlightedListBox == null || (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn)))) { //if clicking a selected entity, start moving it foreach (MapEntity e in selectedList) { if (e.IsMouseOn(position)) { startMovingPos = position; } } selectionPos = position; //stop camera movement to prevent accidental dragging or rect selection Screen.Selected.Cam.StopMovement(); } } }
public void ReceiveCommandInput(char command) { if (Text == null) { Text = ""; } // Prevent alt gr from triggering any of these as that combination is often needed for special characters if (PlayerInput.IsAltDown()) { return; } switch (command) { case '\b' when !Readonly: //backspace if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl)) { SetText(string.Empty, false); CaretIndex = Text.Length; } else if (selectedCharacters > 0) { RemoveSelectedText(); } else if (Text.Length > 0 && CaretIndex > 0) { CaretIndex--; SetText(Text.Remove(CaretIndex, 1)); CalculateCaretPos(); ClearSelection(); } OnTextChanged?.Invoke(this, Text); break; case (char)0x3: // ctrl-c CopySelectedText(); break; case (char)0x16 when !Readonly: // ctrl-v string text = GetCopiedText(); RemoveSelectedText(); if (SetText(Text.Insert(CaretIndex, text))) { CaretIndex = Math.Min(Text.Length, CaretIndex + text.Length); OnTextChanged?.Invoke(this, Text); } break; case (char)0x18: // ctrl-x CopySelectedText(); if (!Readonly) { RemoveSelectedText(); } break; case (char)0x1: // ctrl-a if (PlayerInput.IsCtrlDown()) { SelectAll(); } break; case (char)0x1A when !Readonly && !SubEditorScreen.IsSubEditor(): // ctrl-z text = memento.Undo(); if (text != Text) { ClearSelection(); SetText(text, false); CaretIndex = Text.Length; OnTextChanged?.Invoke(this, Text); } break; case (char)0x12 when !Readonly && !SubEditorScreen.IsSubEditor(): // ctrl-r text = memento.Redo(); if (text != Text) { ClearSelection(); SetText(text, false); CaretIndex = Text.Length; OnTextChanged?.Invoke(this, Text); } break; } }