214 lines
7.1 KiB
C#
214 lines
7.1 KiB
C#
/*
|
|
* 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
|
|
}
|
|
}
|
|
} |