zxl
/
CTT
forked from Cal/CTT
1
0
Fork 0
CTT/Unity/Assets/ThirdParty/FairyGUI/Scripts/UI/GRoot.cs

737 lines
16 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using UnityEngine;
using System.Collections.Generic;
namespace FairyGUI
{
/// <summary>
/// GRoot is a topmost component of UI display list.You dont need to create GRoot. It is created automatically.
/// </summary>
public class GRoot : GComponent
{
/// <summary>
///
/// </summary>
public static float contentScaleFactor
{
get { return UIContentScaler.scaleFactor; }
}
GGraph _modalLayer;
GObject _modalWaitPane;
List<GObject> _popupStack;
List<GObject> _justClosedPopups;
GObject _tooltipWin;
GObject _defaultTooltipWin;
internal static GRoot _inst;
public static GRoot inst
{
get
{
if (_inst == null)
Stage.Instantiate();
return _inst;
}
}
public GRoot()
{
this.name = this.rootContainer.name = this.rootContainer.gameObject.name = "GRoot";
this.opaque = false;
_popupStack = new List<GObject>();
_justClosedPopups = new List<GObject>();
Stage.inst.onTouchBegin.AddCapture(__stageTouchBegin);
}
/// <summary>
/// Set content scale factor.
/// </summary>
/// <param name="designResolutionX">Design resolution of x axis.</param>
/// <param name="designResolutionY">Design resolution of y axis.</param>
public void SetContentScaleFactor(int designResolutionX, int designResolutionY)
{
SetContentScaleFactor(designResolutionX, designResolutionY, UIContentScaler.ScreenMatchMode.MatchWidthOrHeight);
}
/// <summary>
/// Set content scale factor.
/// </summary>
/// <param name="designResolutionX">Design resolution of x axis.</param>
/// <param name="designResolutionY">Design resolution of y axis.</param>
/// <param name="screenMatchMode">Match mode.</param>
public void SetContentScaleFactor(int designResolutionX, int designResolutionY, UIContentScaler.ScreenMatchMode screenMatchMode)
{
UIContentScaler scaler = Stage.inst.gameObject.GetComponent<UIContentScaler>();
scaler.designResolutionX = designResolutionX;
scaler.designResolutionY = designResolutionY;
scaler.scaleMode = UIContentScaler.ScaleMode.ScaleWithScreenSize;
scaler.screenMatchMode = screenMatchMode;
scaler.ApplyChange();
ApplyContentScaleFactor();
}
/// <summary>
/// This is called after screen size changed.
/// </summary>
public void ApplyContentScaleFactor()
{
this.SetSize(Mathf.CeilToInt(Screen.width / UIContentScaler.scaleFactor), Mathf.CeilToInt(Screen.height / UIContentScaler.scaleFactor));
this.SetScale(UIContentScaler.scaleFactor, UIContentScaler.scaleFactor);
}
/// <summary>
/// Display a window.
/// </summary>
/// <param name="win"></param>
public void ShowWindow(Window win)
{
AddChild(win);
AdjustModalLayer();
}
/// <summary>
/// Call window.Hide
/// 关闭一个窗口。将调用Window.Hide方法。
/// </summary>
/// <param name="win"></param>
public void HideWindow(Window win)
{
win.Hide();
}
/// <summary>
/// Remove a window from stage immediatelly. window.Hide/window.OnHide will never be called.
///立刻关闭一个窗口。不会调用Window.Hide方法Window.OnHide也不会被调用。
/// </summary>
/// <param name="win"></param>
public void HideWindowImmediately(Window win)
{
HideWindowImmediately(win, false);
}
/// <summary>
/// Remove a window from stage immediatelly. window.Hide/window.OnHide will never be called.
/// 立刻关闭一个窗口。不会调用Window.Hide方法Window.OnHide也不会被调用。
/// </summary>
/// <param name="win"></param>
/// <param name="dispose">True to dispose the window.</param>
public void HideWindowImmediately(Window win, bool dispose)
{
if (win.parent == this)
RemoveChild(win, dispose);
else if (dispose)
win.Dispose();
AdjustModalLayer();
}
/// <summary>
/// 将一个窗口提到所有窗口的最前面
/// </summary>
/// <param name="win"></param>
public void BringToFront(Window win)
{
int cnt = this.numChildren;
int i;
if (this._modalLayer.parent != null && !win.modal)
i = this.GetChildIndex(this._modalLayer) - 1;
else
i = cnt - 1;
for (; i >= 0; i--)
{
GObject g = this.GetChildAt(i);
if (g == win)
return;
if (g is Window)
break;
}
if (i >= 0)
this.SetChildIndex(win, i);
}
/// <summary>
/// Display a modal layer and a waiting sign in the front.
/// 显示一个半透明层和一个等待标志在最前面。半透明层的颜色可以通过UIConfig.modalLayerColor设定。
/// 等待标志的资源可以通过UIConfig.globalModalWaiting。等待标志组件会设置为屏幕大小请内部做好关联。
/// </summary>
public void ShowModalWait()
{
if (UIConfig.globalModalWaiting != null)
{
if (_modalWaitPane == null)
{
_modalWaitPane = UIPackage.CreateObjectFromURL(UIConfig.globalModalWaiting);
_modalWaitPane.SetHome(this);
}
_modalWaitPane.SetSize(this.width, this.height);
_modalWaitPane.AddRelation(this, RelationType.Size);
AddChild(_modalWaitPane);
}
}
/// <summary>
/// Hide modal layer and waiting sign.
/// </summary>
public void CloseModalWait()
{
if (_modalWaitPane != null && _modalWaitPane.parent != null)
RemoveChild(_modalWaitPane);
}
/// <summary>
/// Close all windows except modal windows.
/// </summary>
public void CloseAllExceptModals()
{
GObject[] arr = _children.ToArray();
foreach (GObject g in arr)
{
if ((g is Window) && !(g as Window).modal)
HideWindowImmediately(g as Window);
}
}
/// <summary>
/// Close all windows.
/// </summary>
public void CloseAllWindows()
{
GObject[] arr = _children.ToArray();
foreach (GObject g in arr)
{
if (g is Window)
HideWindowImmediately(g as Window);
}
}
/// <summary>
/// Get window on top.
/// </summary>
/// <returns></returns>
public Window GetTopWindow()
{
int cnt = this.numChildren;
for (int i = cnt - 1; i >= 0; i--)
{
GObject g = this.GetChildAt(i);
if (g is Window)
{
return (Window)(g);
}
}
return null;
}
/// <summary>
///
/// </summary>
public GGraph modalLayer
{
get
{
if (_modalLayer == null)
CreateModalLayer();
return _modalLayer;
}
}
void CreateModalLayer()
{
_modalLayer = new GGraph();
_modalLayer.DrawRect(this.width, this.height, 0, Color.white, UIConfig.modalLayerColor);
_modalLayer.AddRelation(this, RelationType.Size);
_modalLayer.name = _modalLayer.gameObjectName = "ModalLayer";
_modalLayer.SetHome(this);
}
/// <summary>
/// Return true if a modal window is on stage.
/// </summary>
public bool hasModalWindow
{
get { return _modalLayer != null && _modalLayer.parent != null; }
}
/// <summary>
/// Return true if modal waiting layer is on stage.
/// </summary>
public bool modalWaiting
{
get
{
return (_modalWaitPane != null) && _modalWaitPane.onStage;
}
}
/// <summary>
/// Get current touch target. (including hover)
/// </summary>
public GObject touchTarget
{
get
{
return DisplayObjectToGObject(Stage.inst.touchTarget);
}
}
/// <summary>
///
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public GObject DisplayObjectToGObject(DisplayObject obj)
{
while (obj != null)
{
if (obj.gOwner != null)
return obj.gOwner;
obj = obj.parent;
}
return null;
}
private void AdjustModalLayer()
{
if (_modalLayer == null)
CreateModalLayer();
int cnt = this.numChildren;
if (_modalWaitPane != null && _modalWaitPane.parent != null)
SetChildIndex(_modalWaitPane, cnt - 1);
for (int i = cnt - 1; i >= 0; i--)
{
GObject g = this.GetChildAt(i);
if ((g is Window) && (g as Window).modal)
{
if (_modalLayer.parent == null)
AddChildAt(_modalLayer, i);
else
SetChildIndexBefore(_modalLayer, i);
return;
}
}
if (_modalLayer.parent != null)
RemoveChild(_modalLayer);
}
/// <summary>
/// Show a popup object.
/// 显示一个popup。
/// popup的特点是点击popup对象外的区域popup对象将自动消失。
/// </summary>
/// <param name="popup"></param>
public void ShowPopup(GObject popup)
{
ShowPopup(popup, null, null);
}
/// <summary>
/// Show a popup object along with the specific target object.
/// 显示一个popup。将popup显示在指定对象的上边或者下边。
/// popup的特点是点击popup对象外的区域popup对象将自动消失。
/// </summary>
/// <param name="popup"></param>
/// <param name="target"></param>
public void ShowPopup(GObject popup, GObject target)
{
ShowPopup(popup, target, null);
}
/// <summary>
/// Show a popup object along with the specific target object.
/// 显示一个popup。将popup显示在指定对象的上方或者下方。
/// popup的特点是点击popup对象外的区域popup对象将自动消失。
/// </summary>
/// <param name="popup"></param>
/// <param name="target"></param>
/// <param name="downward">True to display downwards, false to display upwards, null to display automatically.</param>
public void ShowPopup(GObject popup, GObject target, object downward)
{
if (_popupStack.Count > 0)
{
int k = _popupStack.IndexOf(popup);
if (k != -1)
{
for (int i = _popupStack.Count - 1; i >= k; i--)
{
int last = _popupStack.Count - 1;
ClosePopup(_popupStack[last]);
_popupStack.RemoveAt(last);
}
}
}
_popupStack.Add(popup);
if (target != null)
{
GObject p = target;
while (p != null)
{
if (p.parent == this)
{
if (popup.sortingOrder < p.sortingOrder)
{
popup.sortingOrder = p.sortingOrder;
}
break;
}
p = p.parent;
}
}
AddChild(popup);
AdjustModalLayer();
if ((popup is Window) && target == null && downward == null)
return;
Vector2 pos = GetPoupPosition(popup, target, downward);
popup.xy = pos;
}
/// <summary>
///
/// </summary>
/// <param name="popup"></param>
/// <param name="target"></param>
/// <param name="downward"></param>
/// <returns></returns>
public Vector2 GetPoupPosition(GObject popup, GObject target, object downward)
{
Vector2 pos;
Vector2 size = Vector2.zero;
if (target != null)
{
pos = target.LocalToRoot(Vector2.zero, this);
size = target.LocalToRoot(target.size, this) - pos;
}
else
{
pos = this.GlobalToLocal(Stage.inst.touchPosition);
}
float xx, yy;
xx = pos.x;
if (xx + popup.width > this.width)
xx = xx + size.x - popup.width;
yy = pos.y + size.y;
if ((downward == null && yy + popup.height > this.height)
|| downward != null && (bool)downward == false)
{
yy = pos.y - popup.height - 1;
if (yy < 0)
{
yy = 0;
xx += size.x / 2;
}
}
return new Vector2(Mathf.RoundToInt(xx), Mathf.RoundToInt(yy));
}
/// <summary>
/// If a popup is showing, then close it; otherwise, open it.
/// </summary>
/// <param name="popup"></param>
public void TogglePopup(GObject popup)
{
TogglePopup(popup, null, null);
}
/// <summary>
///
/// </summary>
/// <param name="popup"></param>
/// <param name="target"></param>
public void TogglePopup(GObject popup, GObject target)
{
TogglePopup(popup, target, null);
}
/// <summary>
///
/// </summary>
/// <param name="popup"></param>
/// <param name="target"></param>
/// <param name="downward"></param>
public void TogglePopup(GObject popup, GObject target, object downward)
{
if (_justClosedPopups.IndexOf(popup) != -1)
return;
ShowPopup(popup, target, downward);
}
/// <summary>
/// Close all popups.
/// </summary>
public void HidePopup()
{
HidePopup(null);
}
/// <summary>
/// Close a popup.
/// </summary>
/// <param name="popup"></param>
public void HidePopup(GObject popup)
{
if (popup != null)
{
int k = _popupStack.IndexOf(popup);
if (k != -1)
{
for (int i = _popupStack.Count - 1; i >= k; i--)
{
int last = _popupStack.Count - 1;
ClosePopup(_popupStack[last]);
_popupStack.RemoveAt(last);
}
}
}
else
{
foreach (GObject obj in _popupStack)
ClosePopup(obj);
_popupStack.Clear();
}
}
/// <summary>
///
/// </summary>
public bool hasAnyPopup
{
get { return _popupStack.Count > 0; }
}
void ClosePopup(GObject target)
{
if (target.parent != null)
{
if (target is Window)
((Window)target).Hide();
else
RemoveChild(target);
}
}
/// <summary>
///
/// </summary>
/// <param name="msg"></param>
public void ShowTooltips(string msg)
{
if (_defaultTooltipWin == null)
{
string resourceURL = UIConfig.tooltipsWin;
if (string.IsNullOrEmpty(resourceURL))
{
Debug.LogWarning("FairyGUI: UIConfig.tooltipsWin not defined");
return;
}
_defaultTooltipWin = UIPackage.CreateObjectFromURL(resourceURL);
_defaultTooltipWin.SetHome(this);
_defaultTooltipWin.touchable = false;
}
_defaultTooltipWin.text = msg;
ShowTooltipsWin(_defaultTooltipWin);
}
/// <summary>
///
/// </summary>
/// <param name="tooltipWin"></param>
public void ShowTooltipsWin(GObject tooltipWin)
{
HideTooltips();
_tooltipWin = tooltipWin;
Timers.inst.Add(0.1f, 1, __showTooltipsWin);
}
void __showTooltipsWin(object param)
{
if (_tooltipWin == null)
return;
float xx = Stage.inst.touchPosition.x + 10;
float yy = Stage.inst.touchPosition.y + 20;
Vector2 pt = this.GlobalToLocal(new Vector2(xx, yy));
xx = pt.x;
yy = pt.y;
if (xx + _tooltipWin.width > this.width)
xx = xx - _tooltipWin.width;
if (yy + _tooltipWin.height > this.height)
{
yy = yy - _tooltipWin.height - 1;
if (yy < 0)
yy = 0;
}
_tooltipWin.x = Mathf.RoundToInt(xx);
_tooltipWin.y = Mathf.RoundToInt(yy);
AddChild(_tooltipWin);
}
/// <summary>
///
/// </summary>
public void HideTooltips()
{
if (_tooltipWin != null)
{
if (_tooltipWin.parent != null)
RemoveChild(_tooltipWin);
_tooltipWin = null;
}
}
/// <summary>
///
/// </summary>
public GObject focus
{
get
{
GObject result = null;
DisplayObject mc = Stage.inst.focus;
while (mc != Stage.inst && mc != null)
{
GObject gg = mc.gOwner;
if (gg != null && gg.touchable && gg.focusable)
{
result = gg;
break;
}
mc = mc.parent;
}
return result;
}
set
{
if (value != null && (!value.focusable || !value.onStage))
{
Debug.LogError("invalid focus target");
return;
}
if (value == null)
Stage.inst.focus = null;
else
Stage.inst.focus = value.displayObject;
}
}
void __stageTouchBegin(EventContext context)
{
if (_tooltipWin != null)
HideTooltips();
CheckPopups();
}
void CheckPopups()
{
_justClosedPopups.Clear();
if (_popupStack.Count > 0)
{
DisplayObject mc = Stage.inst.touchTarget as DisplayObject;
bool handled = false;
while (mc != Stage.inst && mc != null)
{
if (mc.gOwner != null)
{
int k = _popupStack.IndexOf(mc.gOwner);
if (k != -1)
{
for (int i = _popupStack.Count - 1; i > k; i--)
{
int last = _popupStack.Count - 1;
GObject popup = _popupStack[last];
ClosePopup(popup);
_justClosedPopups.Add(popup);
_popupStack.RemoveAt(last);
}
handled = true;
break;
}
}
mc = mc.parent;
}
if (!handled)
{
for (int i = _popupStack.Count - 1; i >= 0; i--)
{
GObject popup = _popupStack[i];
ClosePopup(popup);
_justClosedPopups.Add(popup);
}
_popupStack.Clear();
}
}
}
/// <summary>
///
/// </summary>
public void EnableSound()
{
Stage.inst.EnableSound();
}
/// <summary>
///
/// </summary>
public void DisableSound()
{
Stage.inst.DisableSound();
}
/// <summary>
///
/// </summary>
/// <param name="clip"></param>
/// <param name="volumeScale"></param>
public void PlayOneShotSound(AudioClip clip, float volumeScale)
{
Stage.inst.PlayOneShotSound(clip, volumeScale);
}
/// <summary>
///
/// </summary>
/// <param name="clip"></param>
public void PlayOneShotSound(AudioClip clip)
{
Stage.inst.PlayOneShotSound(clip);
}
/// <summary>
///
/// </summary>
public float soundVolume
{
get { return Stage.inst.soundVolume; }
set { Stage.inst.soundVolume = value; }
}
}
}