mirror of
https://github.com/GrahamKracker/UnityExplorer.git
synced 2025-07-15 15:57:52 +08:00
2.0.1
* Added unstrip fix for GetRootSceneObjects using Il2CPP internal call
This commit is contained in:
162
src/Unstrip/IMGUI/GUIUnstrip.cs
Normal file
162
src/Unstrip/IMGUI/GUIUnstrip.cs
Normal file
@ -0,0 +1,162 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
#if CPP
|
||||
using Explorer.Unstrip.IMGUI;
|
||||
#endif
|
||||
|
||||
namespace Explorer
|
||||
{
|
||||
public class GUIUnstrip
|
||||
{
|
||||
public static void BeginHorizontal(params GUILayoutOption[] options)
|
||||
=> BeginHorizontal(GUIContent.none, GUIStyle.none, options);
|
||||
|
||||
public static void BeginHorizontal(GUIStyle style, params GUILayoutOption[] options)
|
||||
=> BeginHorizontal(GUIContent.none, style, options);
|
||||
|
||||
public static void BeginHorizontal(GUIContent content, GUIStyle style, params GUILayoutOption[] options)
|
||||
{
|
||||
#if CPP
|
||||
Internal.BeginLayoutDirection(false, content, style, options);
|
||||
#else
|
||||
GUILayout.BeginHorizontal(content, style, options);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void BeginVertical(params GUILayoutOption[] options)
|
||||
=> BeginVertical(GUIContent.none, GUIStyle.none, options);
|
||||
|
||||
public static void BeginVertical(GUIStyle style, params GUILayoutOption[] options)
|
||||
=> BeginVertical(GUIContent.none, style, options);
|
||||
|
||||
public static void BeginVertical(GUIContent content, GUIStyle style, params GUILayoutOption[] options)
|
||||
{
|
||||
#if CPP
|
||||
Internal.BeginLayoutDirection(true, content, style, options);
|
||||
#else
|
||||
GUILayout.BeginVertical(content, style, options);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
public static Rect GetLastRect()
|
||||
{
|
||||
#if CPP
|
||||
return Internal_LayoutUtility.GetLastRect();
|
||||
#else
|
||||
return GUILayoutUtility.GetLastRect();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static string TextField(string text, GUILayoutOption[] options)
|
||||
{
|
||||
#if CPP
|
||||
return Internal.TextField(text, options);
|
||||
#else
|
||||
return GUILayout.TextField(text, options);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static Rect Window(int id, Rect rect, GUI.WindowFunction windowFunc, string title)
|
||||
{
|
||||
#if CPP
|
||||
return GUI.Window(id, rect, windowFunc, GUIContent.Temp(title), GUI.skin.window);
|
||||
#else
|
||||
return GUI.Window(id, rect, windowFunc, title);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool Button(Rect rect, string title)
|
||||
{
|
||||
#if CPP
|
||||
return GUI.Button(rect, GUIContent.Temp(title), GUI.skin.button);
|
||||
#else
|
||||
return GUI.Button(rect, title);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static string TextArea(string text, params GUILayoutOption[] options)
|
||||
{
|
||||
#if CPP
|
||||
return GUILayout.DoTextField(text, -1, true, GUI.skin.textArea, options);
|
||||
#else
|
||||
return GUILayout.TextArea(text, options);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void BringWindowToFront(int id)
|
||||
{
|
||||
#if CPP
|
||||
Internal.BringWindowToFront(id);
|
||||
#else
|
||||
GUI.BringWindowToFront(id);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static Vector2 ScreenToGUIPoint(Vector2 screenPoint)
|
||||
{
|
||||
#if CPP
|
||||
return Internal.ScreenToGUIPoint(screenPoint);
|
||||
#else
|
||||
return GUIUtility.ScreenToGUIPoint(screenPoint);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void Space(float pixels)
|
||||
{
|
||||
#if CPP
|
||||
Internal.Space(pixels);
|
||||
#else
|
||||
GUILayout.Space(pixels);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool RepeatButton(string text, params GUILayoutOption[] options)
|
||||
{
|
||||
#if CPP
|
||||
return Internal.DoRepeatButton(GUIContent.Temp(text), GUI.skin.button, options);
|
||||
#else
|
||||
return GUILayout.RepeatButton(text, options);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void BeginArea(Rect screenRect, GUIStyle style)
|
||||
{
|
||||
#if CPP
|
||||
Internal.BeginArea(screenRect, GUIContent.none, style);
|
||||
#else
|
||||
GUILayout.BeginArea(screenRect, style);
|
||||
#endif
|
||||
}
|
||||
|
||||
static public void EndArea()
|
||||
{
|
||||
#if CPP
|
||||
Internal.EndArea();
|
||||
#else
|
||||
GUILayout.EndArea();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options)
|
||||
{
|
||||
#if CPP
|
||||
return Internal.BeginScrollView(scroll, options);
|
||||
#else
|
||||
return GUILayout.BeginScrollView(scroll, options);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void EndScrollView(bool handleScrollWheel = true)
|
||||
{
|
||||
#if CPP
|
||||
Internal.EndScrollView(handleScrollWheel);
|
||||
#else
|
||||
GUILayout.EndScrollView();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
688
src/Unstrip/IMGUI/Internal.cs
Normal file
688
src/Unstrip/IMGUI/Internal.cs
Normal file
@ -0,0 +1,688 @@
|
||||
#if CPP
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngineInternal;
|
||||
using UnhollowerRuntimeLib;
|
||||
|
||||
namespace Explorer.Unstrip.IMGUI
|
||||
{
|
||||
public class Internal
|
||||
{
|
||||
#region Properties
|
||||
public static int s_ScrollControlId;
|
||||
|
||||
public static bool ScrollFailed = false;
|
||||
public static bool ManualUnstripFailed = false;
|
||||
|
||||
public static GenericStack ScrollStack => m_scrollStack ?? GetScrollStack();
|
||||
public static PropertyInfo m_scrollViewStatesInfo;
|
||||
public static GenericStack m_scrollStack;
|
||||
|
||||
public static Dictionary<int, Il2CppSystem.Object> StateCache => m_stateCacheDict ?? GetStateCacheDict();
|
||||
public static Dictionary<int, Il2CppSystem.Object> m_stateCacheDict;
|
||||
|
||||
public static GUIStyle SpaceStyle => m_spaceStyle ?? GetSpaceStyle();
|
||||
public static GUIStyle m_spaceStyle;
|
||||
|
||||
public static DateTime nextScrollStepTime;
|
||||
|
||||
public static MethodInfo ScreenToGuiPointMethod;
|
||||
public static bool m_screenToGuiAttemped;
|
||||
|
||||
public static MethodInfo m_bringWindowToFrontMethod;
|
||||
public static bool m_bringWindowFrontAttempted;
|
||||
|
||||
private static GenericStack GetScrollStack()
|
||||
{
|
||||
if (m_scrollViewStatesInfo == null)
|
||||
{
|
||||
if (typeof(GUI).GetProperty("scrollViewStates", ReflectionHelpers.CommonFlags) is PropertyInfo scrollStatesInfo)
|
||||
{
|
||||
m_scrollViewStatesInfo = scrollStatesInfo;
|
||||
}
|
||||
else if (typeof(GUI).GetProperty("s_ScrollViewStates", ReflectionHelpers.CommonFlags) is PropertyInfo s_scrollStatesInfo)
|
||||
{
|
||||
m_scrollViewStatesInfo = s_scrollStatesInfo;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_scrollViewStatesInfo?.GetValue(null, null) is GenericStack stack)
|
||||
{
|
||||
m_scrollStack = stack;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_scrollStack = new GenericStack();
|
||||
}
|
||||
|
||||
return m_scrollStack;
|
||||
}
|
||||
|
||||
private static Dictionary<int, Il2CppSystem.Object> GetStateCacheDict()
|
||||
{
|
||||
if (m_stateCacheDict == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var type = ReflectionHelpers.GetTypeByName("UnityEngine.GUIStateObjects");
|
||||
m_stateCacheDict = type.GetProperty("s_StateCache")
|
||||
.GetValue(null, null)
|
||||
as Dictionary<int, Il2CppSystem.Object>;
|
||||
|
||||
if (m_stateCacheDict == null) throw new Exception();
|
||||
}
|
||||
catch
|
||||
{
|
||||
m_stateCacheDict = new Dictionary<int, Il2CppSystem.Object>();
|
||||
}
|
||||
}
|
||||
return m_stateCacheDict;
|
||||
}
|
||||
|
||||
private static GUIStyle GetSpaceStyle()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_spaceStyle = typeof(GUILayoutUtility)
|
||||
.GetProperty("s_SpaceStyle")
|
||||
.GetValue(null, null)
|
||||
.Il2CppCast(typeof(GUIStyle))
|
||||
as GUIStyle;
|
||||
|
||||
if (m_spaceStyle == null) throw new Exception();
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (m_spaceStyle == null)
|
||||
{
|
||||
m_spaceStyle = new GUIStyle();
|
||||
}
|
||||
m_spaceStyle.stretchWidth = false;
|
||||
return m_spaceStyle;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GUILayout Methods
|
||||
|
||||
public static void BeginLayoutDirection(bool vertical, GUIContent content, GUIStyle style, GUILayoutOption[] options)
|
||||
{
|
||||
var g = GUILayoutUtility.BeginLayoutGroup(style, options, Il2CppType.Of<GUILayoutGroup>());
|
||||
g.isVertical = vertical;
|
||||
if (style != GUIStyle.none || content != GUIContent.none)
|
||||
GUI.Box(g.rect, content, style);
|
||||
}
|
||||
|
||||
public static string TextField(string text, GUILayoutOption[] options)
|
||||
{
|
||||
text = text ?? string.Empty;
|
||||
|
||||
int controlID = GUIUtility.GetControlID(FocusType.Keyboard);
|
||||
GUIContent guicontent = GUIContent.Temp(text);
|
||||
bool flag = GUIUtility.keyboardControl != controlID;
|
||||
if (flag)
|
||||
{
|
||||
guicontent = GUIContent.Temp(text);
|
||||
}
|
||||
else
|
||||
{
|
||||
guicontent = GUIContent.Temp(text);
|
||||
// guicontent = GUIContent.Temp(text + GUIUtility.compositionString);
|
||||
}
|
||||
Rect rect = Internal_LayoutUtility.GetRect(guicontent, GUI.skin.textField, options);
|
||||
bool flag2 = GUIUtility.keyboardControl == controlID;
|
||||
if (flag2)
|
||||
{
|
||||
guicontent = GUIContent.Temp(text);
|
||||
}
|
||||
DoTextField(rect, controlID, guicontent, false, -1, GUI.skin.textField);
|
||||
return guicontent.text;
|
||||
}
|
||||
|
||||
internal static void DoTextField(Rect position, int id, GUIContent content, bool multiline, int maxLength, GUIStyle style)
|
||||
{
|
||||
if (GetStateObject(Il2CppType.Of<TextEditor>(), id).TryCast<TextEditor>() is TextEditor textEditor)
|
||||
{
|
||||
if (maxLength >= 0 && content.text.Length > maxLength)
|
||||
{
|
||||
content.text = content.text.Substring(0, maxLength);
|
||||
}
|
||||
textEditor.m_Content.text = content.text;
|
||||
textEditor.SaveBackup();
|
||||
textEditor.position = position;
|
||||
textEditor.style = style;
|
||||
textEditor.multiline = multiline;
|
||||
textEditor.controlID = id;
|
||||
textEditor.DetectFocusChange();
|
||||
GUI.HandleTextFieldEventForDesktop(position, id, content, multiline, maxLength, style, textEditor);
|
||||
textEditor.UpdateScrollOffsetIfNeeded(Event.current);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool DoRepeatButton(GUIContent content, GUIStyle style, GUILayoutOption[] options)
|
||||
{
|
||||
return GUI.DoRepeatButton(Internal_LayoutUtility.GetRect(content, style, options), content, style, FocusType.Passive);
|
||||
}
|
||||
|
||||
public static void Space(float pixels)
|
||||
{
|
||||
if (GUILayoutUtility.current.topLevel.isVertical)
|
||||
Internal_LayoutUtility.GetRect(0, pixels, SpaceStyle, new GUILayoutOption[] { GUILayout.Height(pixels) });
|
||||
else
|
||||
Internal_LayoutUtility.GetRect(pixels, 0, SpaceStyle, new GUILayoutOption[] { GUILayout.Width(pixels) });
|
||||
|
||||
if (Event.current.type == EventType.Layout)
|
||||
{
|
||||
GUILayoutUtility.current.topLevel.entries[GUILayoutUtility.current.topLevel.entries.Count - 1].consideredForMargin = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static Vector2 ScreenToGUIPoint(Vector2 screenPoint)
|
||||
{
|
||||
if (!m_screenToGuiAttemped)
|
||||
{
|
||||
m_screenToGuiAttemped = true;
|
||||
ScreenToGuiPointMethod = typeof(GUIUtility).GetMethod("ScreenToGUIPoint");
|
||||
}
|
||||
if (ScreenToGuiPointMethod == null)
|
||||
{
|
||||
throw new Exception("Couldn't get method 'GUIUtility.ScreenToGUIPoint'!");
|
||||
}
|
||||
return (Vector2)ScreenToGuiPointMethod.Invoke(null, new object[] { screenPoint });
|
||||
}
|
||||
|
||||
public static void BringWindowToFront(int id)
|
||||
{
|
||||
if (!m_bringWindowFrontAttempted)
|
||||
{
|
||||
m_bringWindowFrontAttempted = true;
|
||||
m_bringWindowToFrontMethod = typeof(GUI).GetMethod("BringWindowToFront");
|
||||
}
|
||||
if (m_bringWindowToFrontMethod == null)
|
||||
{
|
||||
throw new Exception("Couldn't get method 'GUIUtility.BringWindowToFront'!");
|
||||
}
|
||||
m_bringWindowToFrontMethod.Invoke(null, new object[] { id });
|
||||
}
|
||||
|
||||
public static void BeginArea(Rect screenRect, GUIContent content, GUIStyle style)
|
||||
{
|
||||
var g = BeginLayoutArea(style, typeof(GUILayoutGroup));
|
||||
if (Event.current.type == EventType.Layout)
|
||||
{
|
||||
g.resetCoords = true;
|
||||
g.minWidth = g.maxWidth = screenRect.width;
|
||||
g.minHeight = g.maxHeight = screenRect.height;
|
||||
g.rect = Rect.MinMaxRect(screenRect.xMin, screenRect.yMin, g.rect.xMax, g.rect.yMax);
|
||||
}
|
||||
|
||||
BeginGroup(g.rect, content, style);
|
||||
}
|
||||
|
||||
internal static GUILayoutGroup BeginLayoutArea(GUIStyle style, Type layoutType)
|
||||
{
|
||||
EventType type = Event.current.type;
|
||||
GUILayoutGroup guilayoutGroup;
|
||||
if (type != EventType.Used && type != EventType.Layout)
|
||||
{
|
||||
guilayoutGroup = GUILayoutUtility.current.windows.GetNext().TryCast<GUILayoutGroup>();
|
||||
guilayoutGroup.ResetCursor();
|
||||
}
|
||||
else
|
||||
{
|
||||
guilayoutGroup = (GUILayoutGroup)Activator.CreateInstance(layoutType);
|
||||
guilayoutGroup.style = style;
|
||||
GUILayoutUtility.current.windows.Add(guilayoutGroup);
|
||||
}
|
||||
GUILayoutUtility.current.layoutGroups.Push(guilayoutGroup);
|
||||
GUILayoutUtility.current.topLevel = guilayoutGroup;
|
||||
return guilayoutGroup;
|
||||
}
|
||||
|
||||
public static void BeginGroup(Rect position, GUIContent content, GUIStyle style)
|
||||
{
|
||||
BeginGroup(position, content, style, Vector2.zero);
|
||||
}
|
||||
|
||||
internal static void BeginGroup(Rect position, GUIContent content, GUIStyle style, Vector2 scrollOffset)
|
||||
{
|
||||
int id = GUIUtility.GetControlID(GUI.s_BeginGroupHash, FocusType.Passive);
|
||||
|
||||
if (content != GUIContent.none || style != GUIStyle.none)
|
||||
{
|
||||
switch (Event.current.type)
|
||||
{
|
||||
case EventType.Repaint:
|
||||
style.Draw(position, content, id);
|
||||
break;
|
||||
default:
|
||||
if (position.Contains(Event.current.mousePosition))
|
||||
GUIUtility.mouseUsed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
GUIClip.Push(position, scrollOffset, Vector2.zero, false);
|
||||
}
|
||||
|
||||
public static void EndArea()
|
||||
{
|
||||
if (Event.current.type == EventType.Used)
|
||||
return;
|
||||
GUILayoutUtility.current.layoutGroups.Pop();
|
||||
GUILayoutUtility.current.topLevel = GUILayoutUtility.current.layoutGroups.Peek().TryCast<GUILayoutGroup>();
|
||||
GUI.EndGroup();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Scrolling
|
||||
|
||||
private static Il2CppSystem.Object GetStateObject(Il2CppSystem.Type type, int controlID)
|
||||
{
|
||||
Il2CppSystem.Object obj;
|
||||
if (StateCache.ContainsKey(controlID))
|
||||
{
|
||||
obj = StateCache[controlID];
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = Il2CppSystem.Activator.CreateInstance(type);
|
||||
StateCache.Add(controlID, obj);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options)
|
||||
{
|
||||
// First, just try normal way, may not have been stripped or was unstripped successfully.
|
||||
if (!ScrollFailed)
|
||||
{
|
||||
try
|
||||
{
|
||||
return GUILayout.BeginScrollView(scroll, options);
|
||||
}
|
||||
catch
|
||||
{
|
||||
ScrollFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Try manual implementation.
|
||||
if (!ManualUnstripFailed)
|
||||
{
|
||||
try
|
||||
{
|
||||
return BeginScrollView_ImplLayout(scroll,
|
||||
false,
|
||||
false,
|
||||
GUI.skin.horizontalScrollbar,
|
||||
GUI.skin.verticalScrollbar,
|
||||
GUI.skin.scrollView,
|
||||
options);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ExplorerCore.Log("Exception on manual BeginScrollView: " + e.GetType() + ", " + e.Message + "\r\n" + e.StackTrace);
|
||||
ManualUnstripFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Sorry! No scrolling for you.
|
||||
return scroll;
|
||||
}
|
||||
|
||||
internal static void EndScrollView(bool handleScrollWheel)
|
||||
{
|
||||
// Only end the scroll view for the relevant BeginScrollView option, if any.
|
||||
|
||||
if (!ScrollFailed)
|
||||
{
|
||||
GUILayout.EndScrollView();
|
||||
}
|
||||
else if (!ManualUnstripFailed)
|
||||
{
|
||||
GUILayoutUtility.EndLayoutGroup();
|
||||
|
||||
if (ScrollStack.Count <= 0) return;
|
||||
|
||||
var state = ScrollStack.Peek().TryCast<ScrollViewState>();
|
||||
var scrollExt = Internal_ScrollViewState.FromPointer(state.Pointer);
|
||||
|
||||
if (scrollExt == null) throw new Exception("Could not get scrollExt!");
|
||||
|
||||
GUIClip.Pop();
|
||||
|
||||
ScrollStack.Pop();
|
||||
|
||||
var position = scrollExt.position;
|
||||
|
||||
if (handleScrollWheel && Event.current.type == EventType.ScrollWheel && position.Contains(Event.current.mousePosition))
|
||||
{
|
||||
var pos = scrollExt.scrollPosition;
|
||||
pos.x = Mathf.Clamp(scrollExt.scrollPosition.x + Event.current.delta.x * 20f, 0f, scrollExt.viewRect.width - scrollExt.visibleRect.width);
|
||||
pos.y = Mathf.Clamp(scrollExt.scrollPosition.y + Event.current.delta.y * 20f, 0f, scrollExt.viewRect.height - scrollExt.visibleRect.height);
|
||||
|
||||
if (scrollExt.scrollPosition.x < 0f)
|
||||
{
|
||||
pos.x = 0f;
|
||||
}
|
||||
if (pos.y < 0f)
|
||||
{
|
||||
pos.y = 0f;
|
||||
}
|
||||
|
||||
scrollExt.apply = true;
|
||||
|
||||
Event.current.Use();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Vector2 BeginScrollView_ImplLayout(Vector2 scrollPosition, bool alwaysShowHorizontal, bool alwaysShowVertical,
|
||||
GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background, params GUILayoutOption[] options)
|
||||
{
|
||||
var guiscrollGroup = GUILayoutUtility.BeginLayoutGroup(background, null, Il2CppType.Of<GUIScrollGroup>())
|
||||
.TryCast<GUIScrollGroup>();
|
||||
|
||||
EventType type = Event.current.type;
|
||||
if (type == EventType.Layout)
|
||||
{
|
||||
guiscrollGroup.resetCoords = true;
|
||||
guiscrollGroup.isVertical = true;
|
||||
guiscrollGroup.stretchWidth = 1;
|
||||
guiscrollGroup.stretchHeight = 1;
|
||||
guiscrollGroup.verticalScrollbar = verticalScrollbar;
|
||||
guiscrollGroup.horizontalScrollbar = horizontalScrollbar;
|
||||
guiscrollGroup.needsVerticalScrollbar = alwaysShowVertical;
|
||||
guiscrollGroup.needsHorizontalScrollbar = alwaysShowHorizontal;
|
||||
guiscrollGroup.ApplyOptions(options);
|
||||
}
|
||||
|
||||
return BeginScrollView_Impl(guiscrollGroup.rect,
|
||||
scrollPosition,
|
||||
new Rect(0f, 0f, guiscrollGroup.clientWidth, guiscrollGroup.clientHeight),
|
||||
alwaysShowHorizontal,
|
||||
alwaysShowVertical,
|
||||
horizontalScrollbar,
|
||||
verticalScrollbar,
|
||||
background
|
||||
);
|
||||
}
|
||||
|
||||
private static Vector2 BeginScrollView_Impl(Rect position, Vector2 scrollPosition, Rect viewRect, bool alwaysShowHorizontal,
|
||||
bool alwaysShowVertical, GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background)
|
||||
{
|
||||
// GUIUtility.CheckOnGUI();
|
||||
|
||||
int controlID = GUIUtility.GetControlID(GUI.s_ScrollviewHash, FocusType.Passive);
|
||||
|
||||
var scrollViewState = GetStateObject(Il2CppType.Of<ScrollViewState>(), controlID)
|
||||
.TryCast<ScrollViewState>();
|
||||
|
||||
if (scrollViewState == null)
|
||||
return scrollPosition;
|
||||
|
||||
var scrollExt = Internal_ScrollViewState.FromPointer(scrollViewState.Pointer);
|
||||
|
||||
if (scrollExt == null)
|
||||
return scrollPosition;
|
||||
|
||||
bool apply = scrollExt.apply;
|
||||
if (apply)
|
||||
{
|
||||
scrollPosition = scrollExt.scrollPosition;
|
||||
scrollExt.apply = false;
|
||||
}
|
||||
|
||||
scrollExt.position = position;
|
||||
|
||||
scrollExt.scrollPosition = scrollPosition;
|
||||
scrollExt.visibleRect = scrollExt.viewRect = viewRect;
|
||||
|
||||
var rect = scrollExt.visibleRect;
|
||||
rect.width = position.width;
|
||||
rect.height = position.height;
|
||||
|
||||
ScrollStack.Push(scrollViewState);
|
||||
|
||||
Rect screenRect = new Rect(position.x, position.y, position.width, position.height);
|
||||
EventType type = Event.current.type;
|
||||
if (type != EventType.Layout)
|
||||
{
|
||||
if (type != EventType.Used)
|
||||
{
|
||||
bool flag = alwaysShowVertical;
|
||||
bool flag2 = alwaysShowHorizontal;
|
||||
if (flag2 || viewRect.width > screenRect.width)
|
||||
{
|
||||
rect.height = position.height - horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top;
|
||||
|
||||
screenRect.height -= horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top;
|
||||
flag2 = true;
|
||||
}
|
||||
if (flag || viewRect.height > screenRect.height)
|
||||
{
|
||||
rect.width = position.width - verticalScrollbar.fixedWidth + (float)verticalScrollbar.margin.left;
|
||||
|
||||
screenRect.width -= verticalScrollbar.fixedWidth + (float)verticalScrollbar.margin.left;
|
||||
flag = true;
|
||||
if (!flag2 && viewRect.width > screenRect.width)
|
||||
{
|
||||
rect.height = position.height - horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top;
|
||||
screenRect.height -= horizontalScrollbar.fixedHeight + (float)horizontalScrollbar.margin.top;
|
||||
flag2 = true;
|
||||
}
|
||||
}
|
||||
if (Event.current.type == EventType.Repaint && background != GUIStyle.none)
|
||||
{
|
||||
background.Draw(position, position.Contains(Event.current.mousePosition), false, flag2 && flag, false);
|
||||
}
|
||||
if (flag2 && horizontalScrollbar != GUIStyle.none)
|
||||
{
|
||||
scrollPosition.x = HorizontalScroll(
|
||||
new Rect(
|
||||
position.x,
|
||||
position.yMax - horizontalScrollbar.fixedHeight,
|
||||
screenRect.width,
|
||||
horizontalScrollbar.fixedHeight),
|
||||
scrollPosition.x,
|
||||
Mathf.Min(screenRect.width, viewRect.width),
|
||||
0f,
|
||||
viewRect.width,
|
||||
horizontalScrollbar
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
scrollPosition.x = ((horizontalScrollbar == GUIStyle.none)
|
||||
? Mathf.Clamp(scrollPosition.x, 0f, Mathf.Max(viewRect.width - position.width, 0f))
|
||||
: 0f);
|
||||
}
|
||||
if (flag && verticalScrollbar != GUIStyle.none)
|
||||
{
|
||||
scrollPosition.y = VerticalScroll(
|
||||
new Rect(
|
||||
screenRect.xMax + (float)verticalScrollbar.margin.left,
|
||||
screenRect.y,
|
||||
verticalScrollbar.fixedWidth,
|
||||
screenRect.height),
|
||||
scrollPosition.y,
|
||||
Mathf.Min(screenRect.height, viewRect.height),
|
||||
0f,
|
||||
viewRect.height,
|
||||
verticalScrollbar
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
scrollPosition.y = ((verticalScrollbar == GUIStyle.none)
|
||||
? Mathf.Clamp(scrollPosition.y, 0f, Mathf.Max(viewRect.height - position.height, 0f))
|
||||
: 0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
GUIUtility.GetControlID(GUI.s_RepeatButtonHash, FocusType.Passive);
|
||||
}
|
||||
GUIClip.Push(screenRect,
|
||||
new Vector2(
|
||||
Mathf.Round(-scrollPosition.x - viewRect.x),
|
||||
Mathf.Round(-scrollPosition.y - viewRect.y)),
|
||||
Vector2.zero,
|
||||
false
|
||||
);
|
||||
|
||||
return scrollPosition;
|
||||
}
|
||||
|
||||
public static float HorizontalScroll(Rect position, float value, float size, float leftValue, float rightValue, GUIStyle style)
|
||||
{
|
||||
return Scroller(position, value, size, leftValue, rightValue, style,
|
||||
GUI.skin.GetStyle(style.name + "thumb"),
|
||||
GUI.skin.GetStyle(style.name + "leftbutton"),
|
||||
GUI.skin.GetStyle(style.name + "rightbutton"),
|
||||
true);
|
||||
}
|
||||
|
||||
public static float VerticalScroll(Rect position, float value, float size, float topValue, float bottomValue, GUIStyle style)
|
||||
{
|
||||
return Scroller(position, value, size, topValue, bottomValue, style,
|
||||
GUI.skin.GetStyle(style.name + "thumb"),
|
||||
GUI.skin.GetStyle(style.name + "upbutton"),
|
||||
GUI.skin.GetStyle(style.name + "downbutton"),
|
||||
false);
|
||||
}
|
||||
|
||||
private static float Scroller(Rect position, float value, float size, float leftValue, float rightValue, GUIStyle slider,
|
||||
GUIStyle thumb, GUIStyle leftButton, GUIStyle rightButton, bool horiz)
|
||||
{
|
||||
GUIUtility.CheckOnGUI();
|
||||
int controlID = GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive, position);
|
||||
Rect position2;
|
||||
Rect rect;
|
||||
Rect rect2;
|
||||
if (horiz)
|
||||
{
|
||||
position2 = new Rect(position.x + leftButton.fixedWidth,
|
||||
position.y,
|
||||
position.width - leftButton.fixedWidth - rightButton.fixedWidth,
|
||||
position.height);
|
||||
|
||||
rect = new Rect(position.x, position.y, leftButton.fixedWidth, position.height);
|
||||
rect2 = new Rect(position.xMax - rightButton.fixedWidth, position.y, rightButton.fixedWidth, position.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
position2 = new Rect(position.x,
|
||||
position.y + leftButton.fixedHeight,
|
||||
position.width,
|
||||
position.height - leftButton.fixedHeight - rightButton.fixedHeight);
|
||||
|
||||
rect = new Rect(position.x, position.y, position.width, leftButton.fixedHeight);
|
||||
rect2 = new Rect(position.x, position.yMax - rightButton.fixedHeight, position.width, rightButton.fixedHeight);
|
||||
}
|
||||
|
||||
value = Slider(position2, value, size, leftValue, rightValue, slider, thumb, horiz, controlID);
|
||||
|
||||
bool flag = Event.current.type == EventType.MouseUp;
|
||||
if (ScrollerRepeatButton(controlID, rect, leftButton))
|
||||
{
|
||||
value -= 10f * ((leftValue >= rightValue) ? -1f : 1f);
|
||||
}
|
||||
if (ScrollerRepeatButton(controlID, rect2, rightButton))
|
||||
{
|
||||
value += 10f * ((leftValue >= rightValue) ? -1f : 1f);
|
||||
}
|
||||
if (flag && Event.current.type == EventType.Used)
|
||||
{
|
||||
s_ScrollControlId = 0;
|
||||
}
|
||||
if (leftValue < rightValue)
|
||||
{
|
||||
value = Mathf.Clamp(value, leftValue, rightValue - size);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = Mathf.Clamp(value, rightValue, leftValue - size);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static float Slider(Rect position, float value, float size, float start, float end, GUIStyle slider,
|
||||
GUIStyle thumb, bool horiz, int id)
|
||||
{
|
||||
if (id == 0)
|
||||
{
|
||||
id = GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive, position);
|
||||
}
|
||||
var sliderHandler = new Internal_SliderHandler(position, value, size, start, end, slider, thumb, horiz, id);
|
||||
return sliderHandler.Handle();
|
||||
}
|
||||
|
||||
private static bool ScrollerRepeatButton(int scrollerID, Rect rect, GUIStyle style)
|
||||
{
|
||||
bool result = false;
|
||||
if (GUI.DoRepeatButton(rect, GUIContent.none, style, FocusType.Passive))
|
||||
{
|
||||
bool flag = s_ScrollControlId != scrollerID;
|
||||
s_ScrollControlId = scrollerID;
|
||||
|
||||
if (flag)
|
||||
{
|
||||
result = true;
|
||||
nextScrollStepTime = DateTime.Now.AddMilliseconds(250.0);
|
||||
}
|
||||
else if (DateTime.Now >= nextScrollStepTime)
|
||||
{
|
||||
result = true;
|
||||
nextScrollStepTime = DateTime.Now.AddMilliseconds(30.0);
|
||||
}
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
GUI.InternalRepaintEditorWindow();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#region Extensions
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
public static Rect Unstripped_GetLast(this GUILayoutGroup group)
|
||||
{
|
||||
Rect result;
|
||||
if (group.m_Cursor > 0 && group.m_Cursor <= group.entries.Count)
|
||||
{
|
||||
GUILayoutEntry guilayoutEntry = group.entries[group.m_Cursor - 1];
|
||||
result = guilayoutEntry.rect;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = GUILayoutEntry.kDummyRect;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
#endif
|
91
src/Unstrip/IMGUI/Internal_LayoutUtility.cs
Normal file
91
src/Unstrip/IMGUI/Internal_LayoutUtility.cs
Normal file
@ -0,0 +1,91 @@
|
||||
#if CPP
|
||||
using UnityEngine;
|
||||
|
||||
namespace Explorer.Unstrip.IMGUI
|
||||
{
|
||||
public class Internal_LayoutUtility
|
||||
{
|
||||
public static Rect GetRect(float width, float height, GUIStyle style, params GUILayoutOption[] options)
|
||||
{
|
||||
switch (Event.current.type)
|
||||
{
|
||||
case EventType.Layout:
|
||||
GUILayoutUtility.current.topLevel.Add(new GUILayoutEntry(width, width, height, height, style, options));
|
||||
return GUILayoutUtility.kDummyRect;
|
||||
case EventType.Used:
|
||||
return GUILayoutUtility.kDummyRect;
|
||||
default:
|
||||
return GUILayoutUtility.current.topLevel.GetNext().rect;
|
||||
}
|
||||
}
|
||||
|
||||
public static Rect GetRect(GUIContent content, GUIStyle style, params GUILayoutOption[] options)
|
||||
{
|
||||
return DoGetRect(content, style, options);
|
||||
}
|
||||
|
||||
static Rect DoGetRect(GUIContent content, GUIStyle style, GUILayoutOption[] options)
|
||||
{
|
||||
switch (Event.current.type)
|
||||
{
|
||||
case EventType.Layout:
|
||||
if (style.isHeightDependantOnWidth)
|
||||
{
|
||||
GUILayoutUtility.current.topLevel.Add(new GUIWordWrapSizer(style, content, options));
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 sizeConstraints = new Vector2(0, 0);
|
||||
if (options != null)
|
||||
{
|
||||
foreach (var option in options)
|
||||
{
|
||||
if (float.TryParse(option.value.ToString(), out float f))
|
||||
{
|
||||
switch (option.type)
|
||||
{
|
||||
case GUILayoutOption.Type.maxHeight:
|
||||
sizeConstraints.y = f;
|
||||
break;
|
||||
case GUILayoutOption.Type.maxWidth:
|
||||
sizeConstraints.x = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 size = style.CalcSizeWithConstraints(content, sizeConstraints);
|
||||
// This is needed on non-integer scale ratios to avoid errors to accumulate in further layout calculations
|
||||
size.x = Mathf.Ceil(size.x);
|
||||
size.y = Mathf.Ceil(size.y);
|
||||
GUILayoutUtility.current.topLevel.Add(new GUILayoutEntry(size.x, size.x, size.y, size.y, style, options));
|
||||
}
|
||||
return GUILayoutUtility.kDummyRect;
|
||||
|
||||
case EventType.Used:
|
||||
return GUILayoutUtility.kDummyRect;
|
||||
default:
|
||||
var entry = GUILayoutUtility.current.topLevel.GetNext();
|
||||
//GUIDebugger.LogLayoutEntry(entry.rect, entry.marginLeft, entry.marginRight, entry.marginTop, entry.marginBottom, entry.style);
|
||||
return entry.rect;
|
||||
}
|
||||
}
|
||||
|
||||
public static Rect GetLastRect()
|
||||
{
|
||||
EventType type = Event.current.type;
|
||||
Rect last;
|
||||
if (type != EventType.Layout && type != EventType.Used)
|
||||
{
|
||||
last = GUILayoutUtility.current.topLevel.Unstripped_GetLast();
|
||||
}
|
||||
else
|
||||
{
|
||||
last = GUILayoutUtility.kDummyRect;
|
||||
}
|
||||
return last;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
29
src/Unstrip/IMGUI/Internal_ScrollViewState.cs
Normal file
29
src/Unstrip/IMGUI/Internal_ScrollViewState.cs
Normal file
@ -0,0 +1,29 @@
|
||||
#if CPP
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Explorer.Unstrip.IMGUI
|
||||
{
|
||||
public class Internal_ScrollViewState
|
||||
{
|
||||
public Rect position;
|
||||
public Rect visibleRect;
|
||||
public Rect viewRect;
|
||||
public Vector2 scrollPosition;
|
||||
public bool apply;
|
||||
|
||||
public static Dictionary<IntPtr, Internal_ScrollViewState> Dict = new Dictionary<IntPtr, Internal_ScrollViewState>();
|
||||
|
||||
public static Internal_ScrollViewState FromPointer(IntPtr ptr)
|
||||
{
|
||||
if (!Dict.ContainsKey(ptr))
|
||||
{
|
||||
Dict.Add(ptr, new Internal_ScrollViewState());
|
||||
}
|
||||
|
||||
return Dict[ptr];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
411
src/Unstrip/IMGUI/Internal_SliderHandler.cs
Normal file
411
src/Unstrip/IMGUI/Internal_SliderHandler.cs
Normal file
@ -0,0 +1,411 @@
|
||||
#if CPP
|
||||
using System;
|
||||
using UnhollowerRuntimeLib;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Explorer.Unstrip.IMGUI
|
||||
{
|
||||
public struct Internal_SliderHandler
|
||||
{
|
||||
public static int ScrollTroughSide
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!m_getScrollTroughSideFailed)
|
||||
{
|
||||
try
|
||||
{
|
||||
return GUI.scrollTroughSide;
|
||||
}
|
||||
catch
|
||||
{
|
||||
m_getScrollTroughSideFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return m_manualScrollTrough;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (!m_setScrollTroughSideFailed)
|
||||
{
|
||||
try
|
||||
{
|
||||
GUI.scrollTroughSide = value;
|
||||
return;
|
||||
}
|
||||
catch
|
||||
{
|
||||
m_setScrollTroughSideFailed = true;
|
||||
}
|
||||
}
|
||||
m_manualScrollTrough = value;
|
||||
}
|
||||
}
|
||||
private static bool m_getScrollTroughSideFailed;
|
||||
private static bool m_setScrollTroughSideFailed;
|
||||
private static int m_manualScrollTrough;
|
||||
|
||||
|
||||
private readonly Rect position;
|
||||
private readonly float currentValue;
|
||||
private readonly float size;
|
||||
private readonly float start;
|
||||
private readonly float end;
|
||||
private readonly GUIStyle slider;
|
||||
private readonly GUIStyle thumb;
|
||||
private readonly bool horiz;
|
||||
private readonly int id;
|
||||
|
||||
public Internal_SliderHandler(Rect position, float currentValue, float size, float start,
|
||||
float end, GUIStyle slider, GUIStyle thumb, bool horiz, int id)
|
||||
{
|
||||
this.position = position;
|
||||
this.currentValue = currentValue;
|
||||
this.size = size;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.slider = slider;
|
||||
this.thumb = thumb;
|
||||
this.horiz = horiz;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public float Handle()
|
||||
{
|
||||
float result;
|
||||
if (this.slider == null || this.thumb == null)
|
||||
{
|
||||
result = this.currentValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (this.CurrentEventType())
|
||||
{
|
||||
case EventType.MouseDown:
|
||||
return this.OnMouseDown();
|
||||
case EventType.MouseUp:
|
||||
return this.OnMouseUp();
|
||||
case EventType.MouseDrag:
|
||||
return this.OnMouseDrag();
|
||||
case EventType.Repaint:
|
||||
return this.OnRepaint();
|
||||
}
|
||||
result = this.currentValue;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private float OnMouseDown()
|
||||
{
|
||||
float result;
|
||||
if (!this.position.Contains(this.CurrentEvent().mousePosition) || this.IsEmptySlider())
|
||||
{
|
||||
result = this.currentValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
ScrollTroughSide = 0;
|
||||
GUIUtility.hotControl = this.id;
|
||||
this.CurrentEvent().Use();
|
||||
if (this.ThumbSelectionRect().Contains(this.CurrentEvent().mousePosition))
|
||||
{
|
||||
this.StartDraggingWithValue(this.ClampedCurrentValue());
|
||||
result = this.currentValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.changed = true;
|
||||
if (this.SupportsPageMovements())
|
||||
{
|
||||
var ext = Internal_SliderState.FromPointer(GetSliderState().Pointer);
|
||||
ext.isDragging = false;
|
||||
Internal.nextScrollStepTime = DateTime.Now.AddMilliseconds(250.0);
|
||||
ScrollTroughSide = this.CurrentScrollTroughSide();
|
||||
result = this.PageMovementValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
float num = this.ValueForCurrentMousePosition();
|
||||
this.StartDraggingWithValue(num);
|
||||
result = this.Clamp(num);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private float OnMouseDrag()
|
||||
{
|
||||
float result;
|
||||
if (GUIUtility.hotControl != this.id)
|
||||
{
|
||||
result = this.currentValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
var ext = Internal_SliderState.FromPointer(GetSliderState().Pointer);
|
||||
if (!ext.isDragging)
|
||||
{
|
||||
result = this.currentValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.changed = true;
|
||||
this.CurrentEvent().Use();
|
||||
float num = this.MousePosition() - ext.dragStartPos;
|
||||
float value = ext.dragStartValue + num / this.ValuesPerPixel();
|
||||
result = this.Clamp(value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private float OnMouseUp()
|
||||
{
|
||||
if (GUIUtility.hotControl == this.id)
|
||||
{
|
||||
this.CurrentEvent().Use();
|
||||
GUIUtility.hotControl = 0;
|
||||
}
|
||||
return this.currentValue;
|
||||
}
|
||||
|
||||
private float OnRepaint()
|
||||
{
|
||||
this.slider.Draw(this.position, GUIContent.none, this.id);
|
||||
if (!this.IsEmptySlider() && this.currentValue >= this.MinValue() && this.currentValue <= this.MaxValue())
|
||||
{
|
||||
this.thumb.Draw(this.ThumbRect(), GUIContent.none, this.id);
|
||||
}
|
||||
float result;
|
||||
if (GUIUtility.hotControl != this.id || !this.position.Contains(this.CurrentEvent().mousePosition) || this.IsEmptySlider())
|
||||
{
|
||||
result = this.currentValue;
|
||||
}
|
||||
else if (this.ThumbRect().Contains(this.CurrentEvent().mousePosition))
|
||||
{
|
||||
if (ScrollTroughSide != 0)
|
||||
{
|
||||
GUIUtility.hotControl = 0;
|
||||
}
|
||||
result = this.currentValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.InternalRepaintEditorWindow();
|
||||
if (DateTime.Now < Internal.nextScrollStepTime)
|
||||
{
|
||||
result = this.currentValue;
|
||||
}
|
||||
else if (this.CurrentScrollTroughSide() != ScrollTroughSide)
|
||||
{
|
||||
result = this.currentValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
Internal.nextScrollStepTime = DateTime.Now.AddMilliseconds(30.0);
|
||||
if (this.SupportsPageMovements())
|
||||
{
|
||||
Internal_SliderState.FromPointer(GetSliderState().Pointer).isDragging = false;
|
||||
GUI.changed = true;
|
||||
result = this.PageMovementValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = this.ClampedCurrentValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private EventType CurrentEventType()
|
||||
{
|
||||
return this.CurrentEvent().GetTypeForControl(this.id);
|
||||
}
|
||||
|
||||
|
||||
private int CurrentScrollTroughSide()
|
||||
{
|
||||
float num = (!this.horiz) ? this.CurrentEvent().mousePosition.y : this.CurrentEvent().mousePosition.x;
|
||||
float num2 = (!this.horiz) ? this.ThumbRect().y : this.ThumbRect().x;
|
||||
return (num <= num2) ? -1 : 1;
|
||||
}
|
||||
|
||||
private bool IsEmptySlider()
|
||||
{
|
||||
return this.start == this.end;
|
||||
}
|
||||
|
||||
private bool SupportsPageMovements()
|
||||
{
|
||||
return this.size != 0f && GUI.usePageScrollbars;
|
||||
}
|
||||
|
||||
private float PageMovementValue()
|
||||
{
|
||||
float num = this.currentValue;
|
||||
int num2 = (this.start <= this.end) ? 1 : -1;
|
||||
if (this.MousePosition() > this.PageUpMovementBound())
|
||||
{
|
||||
num += this.size * (float)num2 * 0.9f;
|
||||
}
|
||||
else
|
||||
{
|
||||
num -= this.size * (float)num2 * 0.9f;
|
||||
}
|
||||
return this.Clamp(num);
|
||||
}
|
||||
|
||||
private float PageUpMovementBound()
|
||||
{
|
||||
float result;
|
||||
if (this.horiz)
|
||||
{
|
||||
result = this.ThumbRect().xMax - this.position.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = this.ThumbRect().yMax - this.position.y;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Event CurrentEvent()
|
||||
{
|
||||
return Event.current;
|
||||
}
|
||||
|
||||
private float ValueForCurrentMousePosition()
|
||||
{
|
||||
float result;
|
||||
if (this.horiz)
|
||||
{
|
||||
result = (this.MousePosition() - this.ThumbRect().width * 0.5f) / this.ValuesPerPixel() + this.start - this.size * 0.5f;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (this.MousePosition() - this.ThumbRect().height * 0.5f) / this.ValuesPerPixel() + this.start - this.size * 0.5f;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private float Clamp(float value)
|
||||
{
|
||||
return Mathf.Clamp(value, this.MinValue(), this.MaxValue());
|
||||
}
|
||||
|
||||
private Rect ThumbSelectionRect()
|
||||
{
|
||||
return this.ThumbRect();
|
||||
}
|
||||
|
||||
private void StartDraggingWithValue(float dragStartValue)
|
||||
{
|
||||
var ext = Internal_SliderState.FromPointer(GetSliderState().Pointer);
|
||||
ext.dragStartPos = this.MousePosition();
|
||||
ext.dragStartValue = dragStartValue;
|
||||
ext.isDragging = true;
|
||||
}
|
||||
|
||||
private SliderState GetSliderState()
|
||||
{
|
||||
return GUIUtility.GetStateObject(Il2CppType.Of<SliderState>(), this.id).TryCast<SliderState>();
|
||||
}
|
||||
|
||||
private Rect ThumbRect()
|
||||
{
|
||||
return (!this.horiz) ? this.VerticalThumbRect() : this.HorizontalThumbRect();
|
||||
}
|
||||
|
||||
private Rect VerticalThumbRect()
|
||||
{
|
||||
float num = this.ValuesPerPixel();
|
||||
Rect result;
|
||||
if (this.start < this.end)
|
||||
{
|
||||
result = new Rect(this.position.x + (float)this.slider.padding.left, (this.ClampedCurrentValue() - this.start) * num + this.position.y + (float)this.slider.padding.top, this.position.width - (float)this.slider.padding.horizontal, this.size * num + this.ThumbSize());
|
||||
}
|
||||
else
|
||||
{
|
||||
result = new Rect(this.position.x + (float)this.slider.padding.left, (this.ClampedCurrentValue() + this.size - this.start) * num + this.position.y + (float)this.slider.padding.top, this.position.width - (float)this.slider.padding.horizontal, this.size * -num + this.ThumbSize());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Rect HorizontalThumbRect()
|
||||
{
|
||||
float num = this.ValuesPerPixel();
|
||||
Rect result;
|
||||
if (this.start < this.end)
|
||||
{
|
||||
result = new Rect((this.ClampedCurrentValue() - this.start) * num + this.position.x + (float)this.slider.padding.left, this.position.y + (float)this.slider.padding.top, this.size * num + this.ThumbSize(), this.position.height - (float)this.slider.padding.vertical);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = new Rect((this.ClampedCurrentValue() + this.size - this.start) * num + this.position.x + (float)this.slider.padding.left, this.position.y, this.size * -num + this.ThumbSize(), this.position.height);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private float ClampedCurrentValue()
|
||||
{
|
||||
return this.Clamp(this.currentValue);
|
||||
}
|
||||
|
||||
private float MousePosition()
|
||||
{
|
||||
float result;
|
||||
if (this.horiz)
|
||||
{
|
||||
result = this.CurrentEvent().mousePosition.x - this.position.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = this.CurrentEvent().mousePosition.y - this.position.y;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private float ValuesPerPixel()
|
||||
{
|
||||
float result;
|
||||
if (this.horiz)
|
||||
{
|
||||
result = (this.position.width - (float)this.slider.padding.horizontal - this.ThumbSize()) / (this.end - this.start);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (this.position.height - (float)this.slider.padding.vertical - this.ThumbSize()) / (this.end - this.start);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private float ThumbSize()
|
||||
{
|
||||
float result;
|
||||
if (this.horiz)
|
||||
{
|
||||
result = ((this.thumb.fixedWidth == 0f) ? ((float)this.thumb.padding.horizontal) : this.thumb.fixedWidth);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ((this.thumb.fixedHeight == 0f) ? ((float)this.thumb.padding.vertical) : this.thumb.fixedHeight);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private float MaxValue()
|
||||
{
|
||||
return Mathf.Max(this.start, this.end) - this.size;
|
||||
}
|
||||
|
||||
private float MinValue()
|
||||
{
|
||||
return Mathf.Min(this.start, this.end);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
26
src/Unstrip/IMGUI/Internal_SliderState.cs
Normal file
26
src/Unstrip/IMGUI/Internal_SliderState.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Explorer.Unstrip.IMGUI
|
||||
{
|
||||
public class Internal_SliderState
|
||||
{
|
||||
public float dragStartPos;
|
||||
public float dragStartValue;
|
||||
public bool isDragging;
|
||||
|
||||
public static Dictionary<IntPtr, Internal_SliderState> Dict = new Dictionary<IntPtr, Internal_SliderState>();
|
||||
|
||||
public static Internal_SliderState FromPointer(IntPtr ptr)
|
||||
{
|
||||
if (!Dict.ContainsKey(ptr))
|
||||
{
|
||||
Dict.Add(ptr, new Internal_SliderState());
|
||||
}
|
||||
|
||||
return Dict[ptr];
|
||||
}
|
||||
}
|
||||
}
|
41
src/Unstrip/Scene/SceneUnstrip.cs
Normal file
41
src/Unstrip/Scene/SceneUnstrip.cs
Normal file
@ -0,0 +1,41 @@
|
||||
#if CPP
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnhollowerBaseLib;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Explorer.Unstrip.Scene
|
||||
{
|
||||
public class SceneUnstrip
|
||||
{
|
||||
internal delegate void getRootSceneObjects(int handle, IntPtr list);
|
||||
internal static getRootSceneObjects getRootSceneObjects_iCall =
|
||||
IL2CPP.ResolveICall<getRootSceneObjects>("UnityEngine.SceneManagement.Scene::GetRootGameObjectsInternal");
|
||||
|
||||
public static void GetRootGameObjects_Internal(UnityEngine.SceneManagement.Scene scene, IntPtr list)
|
||||
{
|
||||
getRootSceneObjects_iCall(scene.handle, list);
|
||||
}
|
||||
|
||||
public static GameObject[] GetRootSceneObjects(UnityEngine.SceneManagement.Scene scene)
|
||||
{
|
||||
var list = new Il2CppSystem.Collections.Generic.List<GameObject>(GetRootCount_Internal(scene));
|
||||
|
||||
GetRootGameObjects_Internal(scene, list.Pointer);
|
||||
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
internal delegate int getRootCount(int handle);
|
||||
internal static getRootCount getRootCount_iCall =
|
||||
IL2CPP.ResolveICall<getRootCount>("UnityEngine.SceneManagement.Scene::GetRootCountInternal");
|
||||
|
||||
public static int GetRootCount_Internal(UnityEngine.SceneManagement.Scene scene)
|
||||
{
|
||||
return getRootCount_iCall(scene.handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
Reference in New Issue
Block a user