272 lines
9.1 KiB
C#
272 lines
9.1 KiB
C#
//$ Copyright 2015-22, Code Respawn Technologies Pvt Ltd - All Rights Reserved $//
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace DungeonArchitect.UI.Widgets
|
|
{
|
|
public class WidgetUtils
|
|
{
|
|
public static void GetWidgets(IWidget widget, ref List<IWidget> result)
|
|
{
|
|
if (widget == null)
|
|
{
|
|
return;
|
|
}
|
|
result.Add(widget);
|
|
|
|
var children = widget.GetChildWidgets();
|
|
if (children != null)
|
|
{
|
|
foreach (var child in children)
|
|
{
|
|
GetWidgets(child, ref result);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static List<T> GetWidgetsOfType<T>(IWidget root) where T : IWidget
|
|
{
|
|
var widgets = new List<IWidget>();
|
|
GetWidgets(root, ref widgets);
|
|
|
|
var result = new List<T>();
|
|
foreach (var widget in widgets)
|
|
{
|
|
if (widget != null && widget is T)
|
|
{
|
|
result.Add((T)widget);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static void HandleWidgetInput(UISystem uiSystem, Event e, Vector2 mousePosition, IWidget widget)
|
|
{
|
|
if (widget != null)
|
|
{
|
|
var bounds = new Rect(Vector2.zero, widget.WidgetBounds.size);
|
|
if (bounds.Contains(mousePosition))
|
|
{
|
|
mousePosition += widget.ScrollPosition;
|
|
|
|
bool propagateInput = false;
|
|
if (widget == uiSystem.FocusedWidget)
|
|
{
|
|
propagateInput = true;
|
|
}
|
|
|
|
if (widget.RequiresInputEveryFrame())
|
|
{
|
|
propagateInput = true;
|
|
}
|
|
|
|
if (propagateInput)
|
|
{
|
|
var widgetEvent = new Event(e);
|
|
widgetEvent.mousePosition = mousePosition;
|
|
widget.HandleInput(widgetEvent, uiSystem);
|
|
}
|
|
|
|
// Check if the children can be found first
|
|
var children = widget.GetChildWidgets();
|
|
if (children != null)
|
|
{
|
|
foreach (var child in children)
|
|
{
|
|
if (child == null) continue;
|
|
var childMousePosition = mousePosition - child.WidgetBounds.position;
|
|
HandleWidgetInput(uiSystem, e, childMousePosition, child);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static bool BuildWidgetEvent(Vector2 mousePosition, IWidget root, IWidget widgetToFind, ref Vector2 widgetMousePosition)
|
|
{
|
|
mousePosition += root.ScrollPosition;
|
|
if (root == widgetToFind)
|
|
{
|
|
widgetMousePosition = mousePosition;
|
|
return true;
|
|
}
|
|
|
|
var children = root.GetChildWidgets();
|
|
if (children != null)
|
|
{
|
|
foreach (var child in children)
|
|
{
|
|
if (child == null) continue;
|
|
|
|
var childMousePosition = mousePosition - child.WidgetBounds.position;
|
|
if (BuildWidgetEvent(childMousePosition, child, widgetToFind, ref widgetMousePosition))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static bool FindWidgetOnCursor(Event e, IWidget widget, out Event outEvent, out IWidget outWidget)
|
|
{
|
|
if (widget != null)
|
|
{
|
|
var mousePosition = e.mousePosition;
|
|
var bounds = new Rect(Vector2.zero, widget.WidgetBounds.size);
|
|
if (bounds.Contains(mousePosition))
|
|
{
|
|
mousePosition += widget.ScrollPosition;
|
|
// Check if the children can be found first
|
|
var children = widget.GetChildWidgets();
|
|
if (children != null)
|
|
{
|
|
foreach (var child in children)
|
|
{
|
|
var childEvent = new Event(e);
|
|
childEvent.mousePosition = mousePosition - child.WidgetBounds.position;
|
|
if (FindWidgetOnCursor(childEvent, child, out outEvent, out outWidget))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
outEvent = new Event(e);
|
|
outWidget = widget;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
outEvent = null;
|
|
outWidget = null;
|
|
return false;
|
|
}
|
|
|
|
public static void ProcessDragOperation(Event e, IWidget widget, UISystem uiSystem)
|
|
{
|
|
if (e.type == EventType.DragUpdated || e.type == EventType.DragPerform)
|
|
{
|
|
Event widgetEvent;
|
|
IWidget widgetOnCursor;
|
|
if (FindWidgetOnCursor(e, widget, out widgetEvent, out widgetOnCursor))
|
|
{
|
|
if (widgetOnCursor != null)
|
|
{
|
|
if (e.type == EventType.DragUpdated)
|
|
{
|
|
widgetOnCursor.HandleInput(e, uiSystem);
|
|
}
|
|
else if (e.type == EventType.DragPerform)
|
|
{
|
|
// Request the focus so our focus input handling code will handle this
|
|
if (uiSystem != null)
|
|
{
|
|
uiSystem.RequestFocus(widgetOnCursor);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static bool ProcessInputFocus(Vector2 mousePosition, UISystem uiSystem, IWidget widget)
|
|
{
|
|
if (uiSystem == null || widget == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var bounds = new Rect(Vector2.zero, widget.WidgetBounds.size);
|
|
if (!bounds.Contains(mousePosition))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
mousePosition += widget.ScrollPosition;
|
|
|
|
|
|
if (widget.CanAcquireFocus())
|
|
{
|
|
uiSystem.RequestFocus(widget);
|
|
return true;
|
|
}
|
|
|
|
var children = widget.GetChildWidgets();
|
|
if (children != null)
|
|
{
|
|
foreach (var child in children)
|
|
{
|
|
if (child == null) continue;
|
|
var childMousePosition = mousePosition - child.WidgetBounds.position;
|
|
if (ProcessInputFocus(childMousePosition, uiSystem, child))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static void DrawWidgetFocusHighlight(UIRenderer renderer, Rect bounds, Color color)
|
|
{
|
|
DrawWidgetFocusHighlight(renderer, bounds, color, 1);
|
|
}
|
|
|
|
|
|
public static void DrawWidgetFocusHighlight(UIRenderer renderer, Rect bounds, Color color, float thickness)
|
|
{
|
|
DrawWidgetFocusHighlight(renderer, bounds, color, thickness, null);
|
|
}
|
|
|
|
public static void DrawWidgetFocusHighlight(UIRenderer renderer, Rect bounds, Color color, float thickness, Texture2D texture)
|
|
{
|
|
const float padding = 1;
|
|
float x0 = (bounds.xMin + padding);
|
|
float y0 = (bounds.yMin + padding);
|
|
float x1 = (bounds.xMax - padding);
|
|
float y1 = (bounds.yMax - padding);
|
|
|
|
Vector2 P00 = new Vector2(x0, y0);
|
|
Vector2 P10 = new Vector2(x1, y0);
|
|
Vector2 P11 = new Vector2(x1, y1);
|
|
Vector2 P01 = new Vector2(x0, y1);
|
|
if (thickness == 1)
|
|
{
|
|
renderer.DrawPolyLine(color, P00, P10, P11, P01, P00);
|
|
}
|
|
else
|
|
{
|
|
if (texture != null)
|
|
{
|
|
renderer.DrawAAPolyLine(texture, thickness, color, P00, P10, P11, P01, P00);
|
|
}
|
|
else
|
|
{
|
|
renderer.DrawAAPolyLine(thickness, color, P00, P10, P11, P01, P00);
|
|
}
|
|
}
|
|
}
|
|
|
|
public readonly static Color FOCUS_HIGHLITE_COLOR = new Color(1, 0.5f, 0, 1);
|
|
public static void DrawWidgetGroup(UISystem uiSystem, UIRenderer renderer, IWidget widget)
|
|
{
|
|
renderer.BeginGroup(widget.WidgetBounds);
|
|
widget.Draw(uiSystem, renderer);
|
|
renderer.EndGroup();
|
|
}
|
|
|
|
public static bool IsDragEvent(Event e)
|
|
{
|
|
return e.type == EventType.DragPerform
|
|
|| e.type == EventType.DragUpdated
|
|
|| e.type == EventType.DragExited
|
|
|| e.type == EventType.MouseDrag;
|
|
}
|
|
}
|
|
|
|
|
|
}
|