using System; using UnityEngine; using FairyGUI.Utils; namespace FairyGUI { /// <summary> /// GLoader class /// </summary> public class GLoader : GObject, IAnimationGear, IColorGear { /// <summary> /// Display an error sign if the loader fails to load the content. /// UIConfig.loaderErrorSign muse be set. /// </summary> public bool showErrorSign; string _url; AlignType _align; VertAlignType _verticalAlign; bool _autoSize; FillType _fill; bool _shrinkOnly; bool _updatingLayout; PackageItem _contentItem; Action<NTexture> _reloadDelegate; MovieClip _content; GObject _errorSign; GComponent _content2; #if FAIRYGUI_PUERTS public Action __loadExternal; public Action<NTexture> __freeExternal; #endif public GLoader() { _url = string.Empty; _align = AlignType.Left; _verticalAlign = VertAlignType.Top; showErrorSign = true; _reloadDelegate = OnExternalReload; } override protected void CreateDisplayObject() { displayObject = new Container("GLoader"); displayObject.gOwner = this; _content = new MovieClip(); ((Container)displayObject).AddChild(_content); ((Container)displayObject).opaque = true; } override public void Dispose() { if (_disposed) return; if (_content.texture != null) { if (_contentItem == null) { _content.texture.onSizeChanged -= _reloadDelegate; try { FreeExternal(_content.texture); } catch (Exception err) { Debug.LogWarning(err); } } } if (_errorSign != null) _errorSign.Dispose(); if (_content2 != null) _content2.Dispose(); _content.Dispose(); base.Dispose(); } /// <summary> /// /// </summary> public string url { get { return _url; } set { if (_url == value) return; ClearContent(); _url = value; LoadContent(); UpdateGear(7); } } override public string icon { get { return _url; } set { this.url = value; } } /// <summary> /// /// </summary> public AlignType align { get { return _align; } set { if (_align != value) { _align = value; UpdateLayout(); } } } /// <summary> /// /// </summary> public VertAlignType verticalAlign { get { return _verticalAlign; } set { if (_verticalAlign != value) { _verticalAlign = value; UpdateLayout(); } } } /// <summary> /// /// </summary> public FillType fill { get { return _fill; } set { if (_fill != value) { _fill = value; UpdateLayout(); } } } /// <summary> /// /// </summary> public bool shrinkOnly { get { return _shrinkOnly; } set { if (_shrinkOnly != value) { _shrinkOnly = value; UpdateLayout(); } } } /// <summary> /// /// </summary> public bool autoSize { get { return _autoSize; } set { if (_autoSize != value) { _autoSize = value; UpdateLayout(); } } } /// <summary> /// /// </summary> public bool playing { get { return _content.playing; } set { _content.playing = value; UpdateGear(5); } } /// <summary> /// /// </summary> public int frame { get { return _content.frame; } set { _content.frame = value; UpdateGear(5); } } /// <summary> /// /// </summary> public float timeScale { get { return _content.timeScale; } set { _content.timeScale = value; } } /// <summary> /// /// </summary> public bool ignoreEngineTimeScale { get { return _content.ignoreEngineTimeScale; } set { _content.ignoreEngineTimeScale = value; } } /// <summary> /// /// </summary> /// <param name="time"></param> public void Advance(float time) { _content.Advance(time); } /// <summary> /// /// </summary> public Material material { get { return _content.material; } set { _content.material = value; } } /// <summary> /// /// </summary> public string shader { get { return _content.shader; } set { _content.shader = value; } } /// <summary> /// /// </summary> public Color color { get { return _content.color; } set { if (_content.color != value) { _content.color = value; UpdateGear(4); } } } /// <summary> /// /// </summary> public FillMethod fillMethod { get { return _content.fillMethod; } set { _content.fillMethod = value; } } /// <summary> /// /// </summary> public int fillOrigin { get { return _content.fillOrigin; } set { _content.fillOrigin = value; } } /// <summary> /// /// </summary> public bool fillClockwise { get { return _content.fillClockwise; } set { _content.fillClockwise = value; } } /// <summary> /// /// </summary> public float fillAmount { get { return _content.fillAmount; } set { _content.fillAmount = value; } } /// <summary> /// /// </summary> public Image image { get { return _content; } } /// <summary> /// /// </summary> public MovieClip movieClip { get { return _content; } } /// <summary> /// /// </summary> public GComponent component { get { return _content2; } } /// <summary> /// /// </summary> public NTexture texture { get { return _content.texture; } set { this.url = null; _content.texture = value; if (value != null) { sourceWidth = value.width; sourceHeight = value.height; } else { sourceWidth = sourceHeight = 0; } UpdateLayout(); } } override public IFilter filter { get { return _content.filter; } set { _content.filter = value; } } override public BlendMode blendMode { get { return _content.blendMode; } set { _content.blendMode = value; } } /// <summary> /// /// </summary> protected void LoadContent() { ClearContent(); if (string.IsNullOrEmpty(_url)) return; if (_url.StartsWith(UIPackage.URL_PREFIX)) LoadFromPackage(_url); else LoadExternal(); } protected void LoadFromPackage(string itemURL) { _contentItem = UIPackage.GetItemByURL(itemURL); if (_contentItem != null) { _contentItem = _contentItem.getBranch(); sourceWidth = _contentItem.width; sourceHeight = _contentItem.height; _contentItem = _contentItem.getHighResolution(); _contentItem.Load(); if (_contentItem.type == PackageItemType.Image) { _content.texture = _contentItem.texture; _content.textureScale = new Vector2(_contentItem.width / (float)sourceWidth, _contentItem.height / (float)sourceHeight); _content.scale9Grid = _contentItem.scale9Grid; _content.scaleByTile = _contentItem.scaleByTile; _content.tileGridIndice = _contentItem.tileGridIndice; UpdateLayout(); } else if (_contentItem.type == PackageItemType.MovieClip) { _content.interval = _contentItem.interval; _content.swing = _contentItem.swing; _content.repeatDelay = _contentItem.repeatDelay; _content.frames = _contentItem.frames; UpdateLayout(); } else if (_contentItem.type == PackageItemType.Component) { GObject obj = UIPackage.CreateObjectFromURL(itemURL); if (obj == null) SetErrorState(); else if (!(obj is GComponent)) { obj.Dispose(); SetErrorState(); } else { _content2 = (GComponent)obj; ((Container)displayObject).AddChild(_content2.displayObject); UpdateLayout(); } } else { if (_autoSize) this.SetSize(_contentItem.width, _contentItem.height); SetErrorState(); Debug.LogWarning("Unsupported type of GLoader: " + _contentItem.type); } } else SetErrorState(); } virtual protected void LoadExternal() { #if FAIRYGUI_PUERTS if (__loadExternal != null) { __loadExternal(); return; } #endif Texture2D tex = (Texture2D)Resources.Load(_url, typeof(Texture2D)); if (tex != null) onExternalLoadSuccess(new NTexture(tex)); else onExternalLoadFailed(); } virtual protected void FreeExternal(NTexture texture) { #if FAIRYGUI_PUERTS if (__freeExternal != null) { __freeExternal(texture); return; } #endif } public void onExternalLoadSuccess(NTexture texture) { _content.texture = texture; sourceWidth = texture.width; sourceHeight = texture.height; _content.scale9Grid = null; _content.scaleByTile = false; texture.onSizeChanged += _reloadDelegate; UpdateLayout(); } public void onExternalLoadFailed() { SetErrorState(); } void OnExternalReload(NTexture texture) { sourceWidth = texture.width; sourceHeight = texture.height; UpdateLayout(); } private void SetErrorState() { if (!showErrorSign || !Application.isPlaying) return; if (_errorSign == null) { if (UIConfig.loaderErrorSign != null) _errorSign = UIPackage.CreateObjectFromURL(UIConfig.loaderErrorSign); else return; } if (_errorSign != null) { _errorSign.SetSize(this.width, this.height); ((Container)displayObject).AddChild(_errorSign.displayObject); } } protected void ClearErrorState() { if (_errorSign != null && _errorSign.displayObject.parent != null) ((Container)displayObject).RemoveChild(_errorSign.displayObject); } protected void UpdateLayout() { if (_content2 == null && _content.texture == null && _content.frames == null) { if (_autoSize) { _updatingLayout = true; SetSize(50, 30); _updatingLayout = false; } return; } float contentWidth = sourceWidth; float contentHeight = sourceHeight; if (_autoSize) { _updatingLayout = true; if (contentWidth == 0) contentWidth = 50; if (contentHeight == 0) contentHeight = 30; SetSize(contentWidth, contentHeight); _updatingLayout = false; if (_width == contentWidth && _height == contentHeight) { if (_content2 != null) { _content2.SetXY(0, 0); _content2.SetScale(1, 1); } else { _content.SetXY(0, 0); _content.SetSize(contentWidth, contentHeight); } InvalidateBatchingState(); return; } //如果不相等,可能是由于大小限制造成的,要后续处理 } float sx = 1, sy = 1; if (_fill != FillType.None) { sx = this.width / sourceWidth; sy = this.height / sourceHeight; if (sx != 1 || sy != 1) { if (_fill == FillType.ScaleMatchHeight) sx = sy; else if (_fill == FillType.ScaleMatchWidth) sy = sx; else if (_fill == FillType.Scale) { if (sx > sy) sx = sy; else sy = sx; } else if (_fill == FillType.ScaleNoBorder) { if (sx > sy) sy = sx; else sx = sy; } if (_shrinkOnly) { if (sx > 1) sx = 1; if (sy > 1) sy = 1; } contentWidth = sourceWidth * sx; contentHeight = sourceHeight * sy; } } if (_content2 != null) _content2.SetScale(sx, sy); else _content.size = new Vector2(contentWidth, contentHeight); float nx; float ny; if (_align == AlignType.Center) nx = (this.width - contentWidth) / 2; else if (_align == AlignType.Right) nx = this.width - contentWidth; else nx = 0; if (_verticalAlign == VertAlignType.Middle) ny = (this.height - contentHeight) / 2; else if (_verticalAlign == VertAlignType.Bottom) ny = this.height - contentHeight; else ny = 0; if (_content2 != null) _content2.SetXY(nx, ny); else _content.SetXY(nx, ny); InvalidateBatchingState(); } private void ClearContent() { ClearErrorState(); if (_content.texture != null) { if (_contentItem == null) { _content.texture.onSizeChanged -= _reloadDelegate; FreeExternal(_content.texture); } _content.texture = null; } _content.frames = null; if (_content2 != null) { _content2.Dispose(); _content2 = null; } _contentItem = null; } override protected void HandleSizeChanged() { base.HandleSizeChanged(); if (!_updatingLayout) UpdateLayout(); } override public void Setup_BeforeAdd(ByteBuffer buffer, int beginPos) { base.Setup_BeforeAdd(buffer, beginPos); buffer.Seek(beginPos, 5); _url = buffer.ReadS(); _align = (AlignType)buffer.ReadByte(); _verticalAlign = (VertAlignType)buffer.ReadByte(); _fill = (FillType)buffer.ReadByte(); _shrinkOnly = buffer.ReadBool(); _autoSize = buffer.ReadBool(); showErrorSign = buffer.ReadBool(); _content.playing = buffer.ReadBool(); _content.frame = buffer.ReadInt(); if (buffer.ReadBool()) _content.color = buffer.ReadColor(); _content.fillMethod = (FillMethod)buffer.ReadByte(); if (_content.fillMethod != FillMethod.None) { _content.fillOrigin = buffer.ReadByte(); _content.fillClockwise = buffer.ReadBool(); _content.fillAmount = buffer.ReadFloat(); } if (!string.IsNullOrEmpty(_url)) LoadContent(); } } }