Files
XUniWindowController/Runtime/Scripts/UniWindowMoveHandle.cs

214 lines
7.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* UniWindowDragMove.cs
*
* 作者: Kirurobo http://twitter.com/kirurobo
* 许可证: MIT
*/
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.EventSystems;
#if ENABLE_LEGACY_INPUT_MANAGER
#elif ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
namespace Kirurobo
{
public class UniWindowMoveHandle : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler,
IPointerUpHandler
{
private UniWindowController _uniwinc;
/// <summary>
/// 窗口最大化时是否禁用移动
/// </summary>
[Tooltip("窗口已最大化(缩放)时禁用拖拽移动。")] public bool disableOnZoomed = true;
/// <summary>
/// 拖动中则为 true
/// </summary>
public bool IsDragging
{
get { return _isDragging; }
}
private bool _isDragging = false;
/// <summary>
/// 是否进行拖动
/// </summary>
private bool IsEnabled
{
get { return enabled && (!disableOnZoomed || !IsZoomed); }
}
/// <summary>
/// 是否适配显示器或最大化
/// </summary>
private bool IsZoomed
{
get { return (_uniwinc && (_uniwinc.shouldFitMonitor || _uniwinc.isZoomed)); }
}
/// <summary>
/// 记录拖动前自动命中测试是否启用
/// </summary>
private bool _isHitTestEnabled;
/// <summary>
/// 拖动开始时窗口内坐标[像素]
/// </summary>
private Vector2 _dragStartedPosition;
// 首次帧更新前调用 Start
void Start()
{
// 获取场景中的 UniWindowController
#if UNITY_2022_1_OR_NEWER
_uniwinc = GameObject.FindAnyObjectByType<UniWindowController>();
#else
_uniwinc = GameObject.FindObjectOfType<UniWindowController>();
#endif
if (_uniwinc) _isHitTestEnabled = _uniwinc.isHitTestEnabled;
//// 下面的代码似乎不需要,所以注释掉以免擅自更改
//Input.simulateMouseWithTouches = false;
}
/// <summary>
/// 拖动开始时的处理
/// </summary>
public void OnBeginDrag(PointerEventData eventData)
{
if (!IsEnabled)
{
return;
}
// 仅通过鼠标左键拖动
if (eventData.button != PointerEventData.InputButton.Left) return;
// Mac 上行为会有所不同
// 实际上仅在 Retina 支持启用时,但 eventData.position 的坐标系与窗口坐标系的缩放会不一致
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
_dragStartedPosition = _uniwinc.windowPosition - _uniwinc.cursorPosition;
#else
_dragStartedPosition = eventData.position;
#endif
// 如果 _isDragging 为 false则判断即将开始拖动
if (!_isDragging)
{
// 拖动期间禁用命中测试
_isHitTestEnabled = _uniwinc.isHitTestEnabled;
_uniwinc.isHitTestEnabled = false;
_uniwinc.isClickThrough = false;
}
_isDragging = true;
}
/// <summary>
/// 拖动结束时的处理
/// </summary>
public void OnEndDrag(PointerEventData eventData)
{
EndDragging();
}
/// <summary>
/// 鼠标抬起时也视为拖动结束
/// </summary>
/// <param name="eventData"></param>
public void OnPointerUp(PointerEventData eventData)
{
EndDragging();
}
/// <summary>
/// 结束拖动
/// </summary>
private void EndDragging()
{
if (_isDragging)
{
_uniwinc.isHitTestEnabled = _isHitTestEnabled;
}
_isDragging = false;
}
/// <summary>
/// 非最大化时,通过鼠标拖动移动窗口
/// </summary>
public void OnDrag(PointerEventData eventData)
{
if (!_uniwinc || !_isDragging) return;
// 如果拖动移动已被禁用,则结束拖动
if (!IsEnabled)
{
EndDragging();
return;
}
// // 如果鼠标左键未按下,则结束拖动
// if (eventData.button != PointerEventData.InputButton.Left) return;
// [Shift]、[Ctrl]、[Alt]、[Command] 键按下期间不视为拖动
var modifiers = UniWindowController.GetModifierKeys();
if (modifiers != UniWindowController.ModifierKey.None) return;
// 如果鼠标按钮已松开,则结束拖动
var buttons = UniWindowController.GetMouseButtons();
if ((buttons & UniWindowController.MouseButton.Left) == UniWindowController.MouseButton.None)
{
EndDragging();
return;
}
// #if ENABLE_LEGACY_INPUT_MANAGER
// // 在 Mac 上如果在多显示器之间移动EventSystem 的 OnEndDrag 可能无法正确调用,因此始终监控鼠标按钮
// if (!Input.Mouse.Button(0).IsPressed) {
// EndDragging();
// return;
// }
// if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)
// || Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)
// || Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt)) return;
// #elif ENABLE_INPUT_SYSTEM
// // 在 Mac 上如果在多显示器之间移动EventSystem 的 OnEndDrag 可能无法正确调用,因此始终监控鼠标按钮
// if (!Mouse.current.leftButton.isPressed) {
// EndDragging();
// return;
// }
// if (Keyboard.current[Key.LeftShift].isPressed || Keyboard.current[Key.RightShift].isPressed
// || Keyboard.current[Key.LeftCtrl].isPressed || Keyboard.current[Key.RightCtrl].isPressed
// || Keyboard.current[Key.LeftAlt].isPressed || Keyboard.current[Key.RightAlt].isPressed) return;
// #endif
// 如果是全屏则不移动窗口
// 在编辑器中可能会变为 true因此仅在非编辑器环境下确认
#if !UNITY_EDITOR
if (Screen.fullScreen)
{
EndDragging();
return;
}
#endif
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
// 在 Mac 上,通过原生插件获取/设置光标位置
_uniwinc.windowPosition = _uniwinc.cursorPosition + _dragStartedPosition;
//Debug.Log("Drag start: " + _dragStartedPosition);
#else
// 在 Windows 上,为支持触控操作而使用 eventData.position
// 将窗口移动与起始位置一致的屏幕位置偏移量
_uniwinc.windowPosition += eventData.position - _dragStartedPosition;
#endif
}
}
}