multiselect: only check for clickables if left mouse; allow shift-drag to draw by disabling item drag
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Comfort.Common;
|
||||
using BepInEx.Configuration;
|
||||
using Comfort.Common;
|
||||
using EFT.UI;
|
||||
using EFT.UI.DragAndDrop;
|
||||
using System;
|
||||
@@ -56,37 +57,19 @@ public class DrawMultiSelect : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
// checking ItemUiContext is a quick and easy way to know the mouse is over an item
|
||||
if (Input.GetKeyDown(Settings.SelectionBoxKey.Value.MainKey) && ItemUiContext.Instance.R().ItemContext == null)
|
||||
if (Settings.SelectionBoxKey.Value.IsDownIgnoreOthers())
|
||||
{
|
||||
PointerEventData eventData = new(EventSystem.current)
|
||||
bool shiftDown = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
|
||||
|
||||
// Only need to check we aren't over draggables/clickables if the multiselect key is left mouse
|
||||
if (Settings.SelectionBoxKey.Value.MainKey == KeyCode.Mouse0 && !shiftDown && !MouseIsOverClickable())
|
||||
{
|
||||
position = Input.mousePosition
|
||||
};
|
||||
|
||||
List<RaycastResult> results = [];
|
||||
localRaycaster.Raycast(eventData, results);
|
||||
preloaderRaycaster.Raycast(eventData, results);
|
||||
|
||||
foreach (GameObject gameObject in results.Select(r => r.gameObject))
|
||||
{
|
||||
var draggables = gameObject.GetComponents<MonoBehaviour>()
|
||||
.Where(c => c is IDragHandler || c is IBeginDragHandler || c is TextMeshProUGUI) // tmp_inputfield is draggable, but textmesh isn't so explicitly include
|
||||
.Where(c => c is not ScrollRectNoDrag) // this disables scrolling, it doesn't add it
|
||||
.Where(c => c.name != "Inner"); // there's a random DragTrigger sitting in ItemInfoWindows
|
||||
|
||||
var clickables = gameObject.GetComponents<MonoBehaviour>()
|
||||
.Where(c => c is IPointerClickHandler || c is IPointerDownHandler || c is IPointerUpHandler);
|
||||
|
||||
if (draggables.Any() || clickables.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
selectOrigin = Input.mousePosition;
|
||||
drawing = true;
|
||||
secondary = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
|
||||
secondary = shiftDown;
|
||||
}
|
||||
|
||||
if (drawing)
|
||||
@@ -137,7 +120,7 @@ public class DrawMultiSelect : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
if (drawing && !Input.GetKey(Settings.SelectionBoxKey.Value.MainKey))
|
||||
if (drawing && !Settings.SelectionBoxKey.Value.IsPressedIgnoreOthers())
|
||||
{
|
||||
drawing = false;
|
||||
if (secondary)
|
||||
@@ -171,6 +154,42 @@ public class DrawMultiSelect : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
private bool MouseIsOverClickable()
|
||||
{
|
||||
// checking ItemUiContext is a quick and easy way to know the mouse is over an item
|
||||
if (ItemUiContext.Instance.R().ItemContext != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
PointerEventData eventData = new(EventSystem.current)
|
||||
{
|
||||
position = Input.mousePosition
|
||||
};
|
||||
|
||||
List<RaycastResult> results = [];
|
||||
localRaycaster.Raycast(eventData, results);
|
||||
preloaderRaycaster.Raycast(eventData, results);
|
||||
|
||||
foreach (GameObject gameObject in results.Select(r => r.gameObject))
|
||||
{
|
||||
var draggables = gameObject.GetComponents<MonoBehaviour>()
|
||||
.Where(c => c is IDragHandler || c is IBeginDragHandler || c is TextMeshProUGUI) // tmp_inputfield is draggable, but textmesh isn't so explicitly include
|
||||
.Where(c => c is not ScrollRectNoDrag) // this disables scrolling, it doesn't add it
|
||||
.Where(c => c.name != "Inner"); // there's a random DragTrigger sitting in ItemInfoWindows
|
||||
|
||||
var clickables = gameObject.GetComponents<MonoBehaviour>()
|
||||
.Where(c => c is IPointerClickHandler || c is IPointerDownHandler || c is IPointerUpHandler);
|
||||
|
||||
if (draggables.Any() || clickables.Any())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool IsOnTop(Rect itemRect, Transform itemTransform, GraphicRaycaster raycaster)
|
||||
{
|
||||
// Otherwise, ensure it's not overlapped by window UI
|
||||
|
@@ -24,7 +24,7 @@ public static class MultiSelectPatches
|
||||
// Used to prevent infinite recursion of CanAccept/AcceptItem
|
||||
private static bool InPatch = false;
|
||||
|
||||
// If the CanAccept method should render highlights
|
||||
// Keep track of preview images when dragging
|
||||
private static readonly List<Image> Previews = [];
|
||||
|
||||
// Point that various QuickFindPlace overrides should start at
|
||||
@@ -165,6 +165,12 @@ public static class MultiSelectPatches
|
||||
return;
|
||||
}
|
||||
|
||||
// Mainly this tests for when selection box is rebound to another mouse button, to enable secondary selection
|
||||
if (shiftDown && Settings.SelectionBoxKey.Value.IsDownIgnoreOthers())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (__instance is not GridItemView gridItemView2 || !MultiSelect.IsSelected(gridItemView2))
|
||||
{
|
||||
MultiSelect.Clear();
|
||||
@@ -400,6 +406,13 @@ public static class MultiSelectPatches
|
||||
return AccessTools.Method(typeof(ItemView), nameof(ItemView.OnBeginDrag));
|
||||
}
|
||||
|
||||
[PatchPrefix]
|
||||
public static bool Prefix()
|
||||
{
|
||||
// Disable drag if shift is down
|
||||
return !Input.GetKey(KeyCode.LeftShift) && !Input.GetKey(KeyCode.RightShift);
|
||||
}
|
||||
|
||||
[PatchPostfix]
|
||||
public static void Postfix(ItemView __instance)
|
||||
{
|
||||
|
18
Settings.cs
18
Settings.cs
@@ -2,6 +2,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UIFixes;
|
||||
@@ -833,10 +834,25 @@ public static class SettingExtensions
|
||||
configEntry.SettingChanged += (_, _) => onChange(configEntry.Value);
|
||||
}
|
||||
|
||||
|
||||
public static void Bind<T>(this ConfigEntry<T> configEntry, Action<T> onChange)
|
||||
{
|
||||
configEntry.Subscribe(onChange);
|
||||
onChange(configEntry.Value);
|
||||
}
|
||||
|
||||
// KeyboardShortcut methods return false if any other key is down
|
||||
public static bool IsDownIgnoreOthers(this KeyboardShortcut shortcut)
|
||||
{
|
||||
return Input.GetKeyDown(shortcut.MainKey) && shortcut.Modifiers.All(Input.GetKey);
|
||||
}
|
||||
|
||||
public static bool IsPressedIgnoreOthers(this KeyboardShortcut shortcut)
|
||||
{
|
||||
return Input.GetKey(shortcut.MainKey) && shortcut.Modifiers.All(Input.GetKey);
|
||||
}
|
||||
|
||||
public static bool IsUpIgnoreOthers(this KeyboardShortcut shortcut)
|
||||
{
|
||||
return Input.GetKeyUp(shortcut.MainKey) && shortcut.Modifiers.All(Input.GetKey);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user