Files
Fishing2/Assets/ThirdParty/Rewired/Extras/ControlMapper/Scripts/ScrollRectSelectableChild.cs
2025-05-10 12:49:47 +08:00

98 lines
4.2 KiB
C#

// Copyright (c) 2015 Augie R. Maddox, Guavaman Enterprises. All rights reserved.
#pragma warning disable 0219
#pragma warning disable 0618
#pragma warning disable 0649
namespace Rewired.UI.ControlMapper {
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using System.Collections.Generic;
using System.Collections;
using Rewired;
[AddComponentMenu("")]
[RequireComponent(typeof(Selectable))]
public class ScrollRectSelectableChild : MonoBehaviour, ISelectHandler {
public bool useCustomEdgePadding = false;
public float customEdgePadding = 50.0f;
private ScrollRect parentScrollRect;
private RectTransform parentScrollRectContentTransform { get { return parentScrollRect.content; } }
private Selectable _selectable;
private Selectable selectable { get { return _selectable ?? (_selectable = GetComponent<Selectable>()); } }
private RectTransform rectTransform { get { return transform as RectTransform; } }
void Start() {
parentScrollRect = transform.GetComponentInParent<ScrollRect>();
if(parentScrollRect == null) {
Debug.LogError("Rewired Control Mapper: No ScrollRect found! This component must be a child of a ScrollRect!");
return;
}
}
#region ISelectHandlder Implementation
public void OnSelect(BaseEventData eventData) {
if(parentScrollRect == null) return;
// Check if this is a keyboard/joystick move event -- mouse click events are excluded otherwise clicks will miss when scroll rect is moved
AxisEventData aed = eventData as AxisEventData;
if(aed == null) return;
// Evaluate object size and position and determine if visible within the scroll rect
RectTransform parentScrollRectTransform = parentScrollRect.transform as RectTransform;
// Get the selectable rect relative to the view rect
Rect relSelectableRect = Utils.MathTools.TransformRect(rectTransform.rect, rectTransform, parentScrollRectTransform);
// Get the view rect
Rect viewRect = parentScrollRectTransform.rect;
// Reduce the size of the visible rect so we stay a bit away from the edge and still scroll to the next item
Rect paddedViewRect = parentScrollRectTransform.rect;
float yPad;
// float xPad;
if(useCustomEdgePadding) {
yPad = customEdgePadding;
} else {
yPad = relSelectableRect.height; // scroll when we are 1 selectable unit from edge
//xPad = relSelectableRect.width; // scroll when we are 1 selectable unit from edge
}
paddedViewRect.yMax -= yPad;
paddedViewRect.yMin += yPad;
// Do not do the horizontal padding because this causes problems with 1-column scroll views. No need for it in this usage.
//paddedViewRect.xMax -= xPad;
//paddedViewRect.xMin += xPad;
// Check if selectable is not fully inside the padded visible rect area
if(Utils.MathTools.RectContains(paddedViewRect, relSelectableRect)) { // rect is visible
return;
}
// Offset scroll rect to fit selectable
Vector2 offset;
if(!Utils.MathTools.GetOffsetToContainRect(paddedViewRect, relSelectableRect, out offset)) { // get the view area offet required to fit this element
return; // selectable cannot fit within view rect
}
// Offset the view rect to be within valid area
Vector2 newPos = parentScrollRectContentTransform.anchoredPosition;
newPos.x = Mathf.Clamp(newPos.x + offset.x, 0.0f, Mathf.Abs(viewRect.width - parentScrollRectContentTransform.sizeDelta.x)); // prevent overscroll
newPos.y = Mathf.Clamp(newPos.y + offset.y, 0.0f, Mathf.Abs(viewRect.height - parentScrollRectContentTransform.sizeDelta.y)); // prevent overscroll
// Set the new scroll rect position
parentScrollRectContentTransform.anchoredPosition = newPos;
}
#endregion
}
}