您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
172 行
4.8 KiB
172 行
4.8 KiB
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.RMGUI;
|
|
using UnityEngine.RMGUI.StyleEnums.Values;
|
|
|
|
namespace RMGUI.GraphView
|
|
{
|
|
public class Resizer : Manipulator, IDecorator
|
|
{
|
|
public MouseButton activateButton { get; set; }
|
|
|
|
// When applyInvTransform is true, Resizer will apply target's inverse transform before drawing/picking
|
|
// (has the effect of being zoom factor independent)
|
|
public bool applyInvTransform { get; set; }
|
|
|
|
private Vector2 m_Start;
|
|
private Rect m_StartPos;
|
|
|
|
private string m_SizeStr;
|
|
private Vector2 m_MinimumSize;
|
|
|
|
// We need to delay style creation because we need to make sure we have a GUISkin loaded.
|
|
private GUIStyle m_StyleWidget;
|
|
private GUIStyle m_StyleLabel;
|
|
|
|
private readonly Rect k_WidgetRect = new Rect(0, 0, 10, 6);
|
|
private readonly Rect k_WidgetPickRect = new Rect(0, 0, 20, 20);
|
|
private readonly Rect k_WidgetTextOffset = new Rect(0, 0, 5, 5);
|
|
|
|
public Resizer()
|
|
{
|
|
m_MinimumSize = new Vector2(30.0f, 30.0f);
|
|
m_SizeStr = "";
|
|
activateButton = MouseButton.LeftMouse;
|
|
}
|
|
|
|
public Resizer(Vector2 minimumSize)
|
|
{
|
|
m_MinimumSize = minimumSize;
|
|
m_SizeStr = "";
|
|
}
|
|
|
|
public override EventPropagation HandleEvent(Event evt, VisualElement finalTarget)
|
|
{
|
|
GraphElement ce = target as GraphElement;
|
|
if (ce==null)
|
|
return EventPropagation.Continue;
|
|
|
|
var data = ce.GetData<GraphElementData>();
|
|
if (data==null)
|
|
return EventPropagation.Continue;
|
|
|
|
if ( (data.capabilities & Capabilities.Resizable) != Capabilities.Resizable)
|
|
return EventPropagation.Continue;
|
|
|
|
switch (evt.type)
|
|
{
|
|
case EventType.MouseDown:
|
|
if (evt.button == (int) activateButton)
|
|
{
|
|
m_Start = evt.mousePosition;
|
|
m_StartPos = target.position;
|
|
|
|
var adjustedWidget = k_WidgetPickRect;
|
|
if (applyInvTransform)
|
|
{
|
|
var inv = target.globalTransform.inverse;
|
|
adjustedWidget.width *= inv.m00; // Apply scale
|
|
adjustedWidget.height *= inv.m11;
|
|
}
|
|
|
|
var widget = m_StartPos;
|
|
|
|
widget.x = widget.width - adjustedWidget.width;
|
|
widget.y = widget.height - adjustedWidget.height;
|
|
widget.width = adjustedWidget.width;
|
|
widget.height = adjustedWidget.height;
|
|
|
|
if (widget.Contains(m_Start))
|
|
{
|
|
// Warn user if target uses a relative CSS position type
|
|
if (target.positionType != PositionType.Absolute)
|
|
{
|
|
Debug.LogWarning("Attempting to resize an object with a non absolute CSS position type");
|
|
}
|
|
this.TakeCapture();
|
|
return EventPropagation.Stop;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case EventType.MouseDrag:
|
|
if (this.HasCapture() && target.positionType == PositionType.Absolute)
|
|
{
|
|
var diff = evt.mousePosition - m_Start;
|
|
var newSize = new Vector2(m_StartPos.width + diff.x, m_StartPos.height + diff.y);
|
|
|
|
if (newSize.x < m_MinimumSize.x)
|
|
newSize.x = m_MinimumSize.x;
|
|
if (newSize.y < m_MinimumSize.y)
|
|
newSize.y = m_MinimumSize.y;
|
|
|
|
data.position = new Rect(data.position.x, data.position.y, newSize.x, newSize.y);
|
|
|
|
m_SizeStr = String.Format("{0:0}", target.position.width) + "x" + String.Format("{0:0}", target.position.height);
|
|
|
|
return EventPropagation.Stop;
|
|
}
|
|
return EventPropagation.Continue;
|
|
|
|
case EventType.MouseUp:
|
|
if (this.HasCapture() && evt.button == (int)activateButton)
|
|
{
|
|
this.ReleaseCapture();
|
|
return EventPropagation.Stop;
|
|
}
|
|
break;
|
|
}
|
|
return EventPropagation.Continue;
|
|
}
|
|
|
|
public void PrePaint(VisualElement t, PaintContext pc)
|
|
{
|
|
}
|
|
|
|
public void PostPaint(VisualElement t, PaintContext pc)
|
|
{
|
|
// TODO: I would like to listen for skin change and create GUIStyle then and only then
|
|
if (m_StyleWidget == null)
|
|
{
|
|
m_StyleWidget = new GUIStyle("WindowBottomResize") { fixedHeight = 0 };
|
|
}
|
|
|
|
if (m_StyleLabel == null)
|
|
{
|
|
m_StyleLabel = new GUIStyle("Label");
|
|
}
|
|
|
|
// Draw resize widget
|
|
var widget = k_WidgetRect;
|
|
if (applyInvTransform)
|
|
{
|
|
var inv = pc.worldXForm.inverse;
|
|
widget.width *= inv.m00;
|
|
widget.height *= inv.m11;
|
|
}
|
|
|
|
widget.position = new Vector2(target.position.max.x - widget.width, target.position.max.y - widget.height);
|
|
|
|
// todo painter as drawimage
|
|
m_StyleWidget.Draw(widget, GUIContent.none, 0);
|
|
|
|
if (this.HasCapture())
|
|
{
|
|
// Get adjusted text offset
|
|
var adjustedWidget = k_WidgetTextOffset;
|
|
if (applyInvTransform)
|
|
{
|
|
var inv = pc.worldXForm.inverse;
|
|
adjustedWidget.width *= inv.m00; // Apply scale
|
|
adjustedWidget.height *= inv.m11;
|
|
}
|
|
|
|
// Now define widget to locate label
|
|
widget = new Rect(target.position.max.x + adjustedWidget.width,
|
|
target.position.max.y + adjustedWidget.height,
|
|
200.0f, 20.0f);
|
|
m_StyleLabel.Draw(widget, new GUIContent(m_SizeStr), false, false, false, false);
|
|
}
|
|
}
|
|
}
|
|
}
|