From f998bc767e43431ae3e8e1d369d0a42f45b8e0ca Mon Sep 17 00:00:00 2001 From: yhh <359807859@qq.com> Date: Tue, 9 Jul 2019 19:41:26 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dfairygui=E4=B8=80=E7=B3=BB?= =?UTF-8?q?=E5=88=97=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Engine/CLEngine.Core/gui/Core/Container.cs | 33 +- .../gui/Core/HitTest/HitTestContext.cs | 3 +- .../CLEngine.Core/gui/Core/Mesh/FillMesh.cs | 123 +- Engine/CLEngine.Core/gui/Core/Shape.cs | 42 +- Engine/CLEngine.Core/gui/Core/Stage.cs | 30 +- .../gui/Core/Text/DynamicFont.cs | 4 +- .../CLEngine.Core/gui/Core/Text/TextField.cs | 67 +- Engine/CLEngine.Core/gui/Tween/GPath.cs | 884 +++++----- Engine/CLEngine.Core/gui/Tween/GTween.cs | 2 +- Engine/CLEngine.Core/gui/Tween/GTweener.cs | 1564 +++++++++-------- Engine/CLEngine.Core/gui/UI/GButton.cs | 25 +- Engine/CLEngine.Core/gui/UI/GComponent.cs | 17 +- Engine/CLEngine.Core/gui/UI/GGroup.cs | 400 ++--- Engine/CLEngine.Core/gui/UI/GList.cs | 81 +- Engine/CLEngine.Core/gui/UI/GLoader.cs | 1277 +++++++------- Engine/CLEngine.Core/gui/UI/GObject.cs | 9 +- Engine/CLEngine.Core/gui/UI/GProgressBar.cs | 27 +- Engine/CLEngine.Core/gui/UI/Gears/GearBase.cs | 17 +- Engine/CLEngine.Core/gui/UI/Transition.cs | 66 +- Engine/CLEngine.Core/gui/UI/UIConfig.cs | 7 +- Engine/CLEngine.Core/gui/Utils/Timers.cs | 484 ++--- 21 files changed, 2627 insertions(+), 2535 deletions(-) diff --git a/Engine/CLEngine.Core/gui/Core/Container.cs b/Engine/CLEngine.Core/gui/Core/Container.cs index cb677a7..32bf9e2 100644 --- a/Engine/CLEngine.Core/gui/Core/Container.cs +++ b/Engine/CLEngine.Core/gui/Core/Container.cs @@ -26,7 +26,12 @@ namespace FairyGUI /// public bool touchChildren; - List _children; + /// + /// + /// + public bool reversedMask; + + List _children; DisplayObject _mask; Rectangle? _clipRect; @@ -358,18 +363,21 @@ namespace FairyGUI return rect; } - /// - /// - /// - /// - /// - public DisplayObject HitTest(Vector2 stagePoint, bool forTouch) + /// + /// + /// + /// + /// + /// + /// + public DisplayObject HitTest(Vector2 stagePoint, bool forTouch, int displayIndex = -1) { HitTestContext.screenPoint = stagePoint; HitTestContext.forTouch = forTouch; HitTestContext.raycastDone = false; + HitTestContext.displayIndex = displayIndex; - DisplayObject ret = HitTest(); + DisplayObject ret = HitTest(); if (ret != null) return ret; else if (this is Stage) @@ -397,7 +405,14 @@ namespace FairyGUI return null; } - DisplayObject target = null; + if (_mask != null && _mask.parent == this) + { + DisplayObject tmp = _mask.InternalHitTestMask(); + if (!reversedMask && tmp == null || reversedMask && tmp != null) + return null; + } + + DisplayObject target = null; if (touchChildren) { int count = _children.Count; diff --git a/Engine/CLEngine.Core/gui/Core/HitTest/HitTestContext.cs b/Engine/CLEngine.Core/gui/Core/HitTest/HitTestContext.cs index 22d6363..2324f15 100644 --- a/Engine/CLEngine.Core/gui/Core/HitTest/HitTestContext.cs +++ b/Engine/CLEngine.Core/gui/Core/HitTest/HitTestContext.cs @@ -13,5 +13,6 @@ namespace FairyGUI public static uint hitEntityId; public static Vector2 hitUV; public static bool forTouch; - } + public static int displayIndex; + } } diff --git a/Engine/CLEngine.Core/gui/Core/Mesh/FillMesh.cs b/Engine/CLEngine.Core/gui/Core/Mesh/FillMesh.cs index efceee2..d3270fb 100644 --- a/Engine/CLEngine.Core/gui/Core/Mesh/FillMesh.cs +++ b/Engine/CLEngine.Core/gui/Core/Mesh/FillMesh.cs @@ -86,65 +86,70 @@ namespace FairyGUI //4 vertex static void FillRadial90(VertexBuffer vb, Rectangle vertRect, Origin90 origin, float amount, bool clockwise) { - bool flipX = origin == Origin90.TopRight || origin == Origin90.BottomRight; - bool flipY = origin == Origin90.BottomLeft || origin == Origin90.BottomRight; - if (flipX != flipY) - clockwise = !clockwise; - - float ratio = clockwise ? amount : (1 - amount); - float tan = (float)Math.Tan(Math.PI * 0.5f * ratio); - float x = vertRect.X + (ratio == 0 ? float.MaxValue : (vertRect.Height / tan)); - float y = vertRect.Y + (ratio == 1 ? float.MaxValue : (vertRect.Width * tan)); - float x2 = x; - float y2 = y; - if (flipX) - x2 = vertRect.Width - x; - if (flipY) - y2 = vertRect.Height - y; - float xMin = flipX ? (vertRect.Width - vertRect.X) : vertRect.X; - float yMin = flipY ? (vertRect.Height - vertRect.Y) : vertRect.Y; - float xMax = flipX ? -vertRect.X : vertRect.Right; - float yMax = flipY ? -vertRect.Y : vertRect.Bottom; - - vb.AddVert(new Vector3(xMin, yMin, 0)); - - if (clockwise) - vb.AddVert(new Vector3(xMax, yMin, 0)); - - if (y > vertRect.Bottom) - { - if (amount < 0.5f) - vb.AddVert(new Vector3(x2, yMax, 0)); - else - vb.AddVert(new Vector3(xMax, yMax, 0)); - } - else - vb.AddVert(new Vector3(xMax, y2, 0)); - - if (x > vertRect.Right) - { - if (amount < 0.5f) - vb.AddVert(new Vector3(xMax, y2, 0)); - else - vb.AddVert(new Vector3(xMax, yMax, 0)); - } - else - vb.AddVert(new Vector3(x2, yMax, 0)); - - if (!clockwise) - vb.AddVert(new Vector3(xMin, yMax, 0)); - - if (flipX == flipY) - { - vb.AddTriangle(0, 1, 2); - vb.AddTriangle(0, 2, 3); - } - else - { - vb.AddTriangle(2, 1, 0); - vb.AddTriangle(3, 2, 0); - } - } + bool flipX = origin == Origin90.TopRight || origin == Origin90.BottomRight; + bool flipY = origin == Origin90.BottomLeft || origin == Origin90.BottomRight; + if (flipX != flipY) + clockwise = !clockwise; + + float ratio = clockwise ? amount : (1 - amount); + float tan = (float)Math.Tan(Math.PI * 0.5f * ratio); + bool thresold = false; + if (ratio != 1) + thresold = (vertRect.Height / vertRect.Width - tan) > 0; + if (!clockwise) + thresold = !thresold; + float x = vertRect.X + (ratio == 0 ? float.MaxValue : (vertRect.Height / tan)); + float y = vertRect.Y + (ratio == 1 ? float.MaxValue : (vertRect.Width * tan)); + float x2 = x; + float y2 = y; + if (flipX) + x2 = vertRect.Width - x; + if (flipY) + y2 = vertRect.Height - y; + float xMin = flipX ? (vertRect.Width - vertRect.X) : vertRect.X; + float yMin = flipY ? (vertRect.Height - vertRect.Y) : vertRect.Y; + float xMax = flipX ? -vertRect.X : vertRect.Right; + float yMax = flipY ? -vertRect.Y : vertRect.Bottom; + + vb.AddVert(new Vector3(xMin, yMin, 0)); + + if (clockwise) + vb.AddVert(new Vector3(xMax, yMin, 0)); + + if (y > vertRect.Bottom) + { + if (thresold) + vb.AddVert(new Vector3(x2, yMax, 0)); + else + vb.AddVert(new Vector3(xMax, yMax, 0)); + } + else + vb.AddVert(new Vector3(xMax, y2, 0)); + + if (x > vertRect.Right) + { + if (thresold) + vb.AddVert(new Vector3(xMax, y2, 0)); + else + vb.AddVert(new Vector3(xMax, yMax, 0)); + } + else + vb.AddVert(new Vector3(x2, yMax, 0)); + + if (!clockwise) + vb.AddVert(new Vector3(xMin, yMax, 0)); + + if (flipX == flipY) + { + vb.AddTriangle(0, 1, 2); + vb.AddTriangle(0, 2, 3); + } + else + { + vb.AddTriangle(2, 1, 0); + vb.AddTriangle(3, 2, 0); + } + } //8 vertex static void FillRadial180(VertexBuffer vb, Rectangle vertRect, Origin180 origin, float amount, bool clockwise) diff --git a/Engine/CLEngine.Core/gui/Core/Shape.cs b/Engine/CLEngine.Core/gui/Core/Shape.cs index 0a55c07..7cf9fd1 100644 --- a/Engine/CLEngine.Core/gui/Core/Shape.cs +++ b/Engine/CLEngine.Core/gui/Core/Shape.cs @@ -99,15 +99,16 @@ namespace FairyGUI /// public void DrawEllipse(Color fillColor) { - EllipseMesh mesh = graphics.GetMeshFactory(); - mesh.lineWidth = 0; - mesh.startDegree = 0; - mesh.endDegreee = 360; - mesh.fillColor = null; + EllipseMesh mesh = graphics.GetMeshFactory(); + mesh.lineWidth = 0; + mesh.startDegree = 0; + mesh.endDegreee = 360; + mesh.fillColor = null; + mesh.centerColor = null; - graphics.color = fillColor; - graphics.SetMeshDirty(); - } + graphics.color = fillColor; + graphics.SetMeshDirty(); + } /// /// @@ -120,17 +121,20 @@ namespace FairyGUI /// public void DrawEllipse(float lineSize, Color centerColor, Color lineColor, Color fillColor, float startDegree, float endDegree) { - EllipseMesh mesh = graphics.GetMeshFactory(); - mesh.lineWidth = lineSize; - mesh.centerColor = centerColor; - mesh.lineColor = lineColor; - mesh.fillColor = null; - mesh.startDegree = startDegree; - mesh.endDegreee = endDegree; - - graphics.color = fillColor; - graphics.SetMeshDirty(); - } + EllipseMesh mesh = graphics.GetMeshFactory(); + mesh.lineWidth = lineSize; + if (centerColor.Equals(fillColor)) + mesh.centerColor = null; + else + mesh.centerColor = centerColor; + mesh.lineColor = lineColor; + mesh.fillColor = null; + mesh.startDegree = startDegree; + mesh.endDegreee = endDegree; + + graphics.color = fillColor; + graphics.SetMeshDirty(); + } /// /// diff --git a/Engine/CLEngine.Core/gui/Core/Stage.cs b/Engine/CLEngine.Core/gui/Core/Stage.cs index 3753fb5..f8b5ec6 100644 --- a/Engine/CLEngine.Core/gui/Core/Stage.cs +++ b/Engine/CLEngine.Core/gui/Core/Stage.cs @@ -35,10 +35,10 @@ namespace FairyGUI Keys[] _lastKeys; int _lastScrollWheelValue; - /// - /// - /// - public static EventCallback0 beforeUpdate; + /// + /// + /// + public static EventCallback0 beforeUpdate; /// /// /// @@ -887,21 +887,27 @@ namespace FairyGUI public DisplayObject ClickTest() { - if (downTargets.Count == 0 - || clickCancelled - || Math.Abs(x - downX) > 50 || Math.Abs(y - downY) > 50) - return null; + if (downTargets.Count == 0 + || clickCancelled + || Math.Abs(x - downX) > 50 || Math.Abs(y - downY) > 50) + { + downTargets.Clear(); + return null; + } DisplayObject obj = downTargets[0]; - if (obj.stage != null) //依然派发到原来的downTarget,虽然可能它已经偏离当前位置,主要是为了正确处理点击缩放的效果 - return obj; + if (obj.stage != null) //依然派发到原来的downTarget,虽然可能它已经偏离当前位置,主要是为了正确处理点击缩放的效果 + { + downTargets.Clear(); + return obj; + } obj = target; while (obj != null) { int i = downTargets.IndexOf(obj); - if (i != -1 && obj.stage != null) - return obj; + if (i != -1 && obj.stage != null) + break; obj = obj.parent; } diff --git a/Engine/CLEngine.Core/gui/Core/Text/DynamicFont.cs b/Engine/CLEngine.Core/gui/Core/Text/DynamicFont.cs index 4d6547b..d1c7c51 100644 --- a/Engine/CLEngine.Core/gui/Core/Text/DynamicFont.cs +++ b/Engine/CLEngine.Core/gui/Core/Text/DynamicFont.cs @@ -12,12 +12,12 @@ namespace FairyGUI int _size; FontStyle _style; - static Dictionary sFontCache = new Dictionary(); + static Dictionary sFontCache = new Dictionary(); public DynamicFont(string name) { this.name = name; - } + } override public void SetFormat(TextFormat format, float fontSizeScale) { diff --git a/Engine/CLEngine.Core/gui/Core/Text/TextField.cs b/Engine/CLEngine.Core/gui/Core/Text/TextField.cs index 2c938d3..1290d7f 100644 --- a/Engine/CLEngine.Core/gui/Core/Text/TextField.cs +++ b/Engine/CLEngine.Core/gui/Core/Text/TextField.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using FairyGUI.Utils; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; @@ -45,8 +46,9 @@ namespace FairyGUI float _globalScale; Bitmap _canvas; NTexture _texture; + VertAlignType lineVAlign = UIConfig.richTextRowVerticalAlign; - RichTextField _richTextField; + RichTextField _richTextField; const int GUTTER_X = 2; const int GUTTER_Y = 2; @@ -752,8 +754,9 @@ namespace FairyGUI wordChars = 0; wordPossible = true; } - else if (wordPossible && (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z')) - { + else if (wordPossible && (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || + ch >= '0' && ch <= '9' || ch == '.' || ch == '"' || ch == '\'')) + { if (wordChars == 0) wordStart = line.width; else if (wordChars > 10) @@ -870,7 +873,7 @@ namespace FairyGUI _richTextField.SetSize(_textWidth, _textHeight); else SetSize(_textWidth, _textHeight); - _updatingSize = false; + _updatingSize = false; } else if (_autoSize == AutoSizeType.Height) { @@ -938,7 +941,7 @@ namespace FairyGUI return; } - if (_font is DynamicFont) + if (_font is DynamicFont) BuildMesh_systemFont(vb); else BuildMesh_bitmapFont(vb); @@ -1069,18 +1072,25 @@ namespace FairyGUI } else { - IHtmlObject htmlObj = element.htmlObject; - if (htmlObj != null) - { - element.position = new Vector2(charX + 1, line.y + (int)((line.height - htmlObj.height) / 2)); - htmlObj.SetPosition(element.position.X, element.position.Y); - if (lineClipped || clipped && (element.position.X < GUTTER_X || element.position.X + htmlObj.width > _contentRect.Width - GUTTER_X)) - element.status |= 1; - else - element.status &= 254; - charX += htmlObj.width + letterSpacing + 2; - } - } + IHtmlObject htmlObj = element.htmlObject; + if (htmlObj != null) + { + if (lineVAlign == VertAlignType.Bottom) + yIndent = (int)(line.height - htmlObj.height); + else if (lineVAlign == VertAlignType.Middle) + yIndent = (int)((line.height - htmlObj.height) / 2); + else + yIndent = 0; + + element.position = new Vector2(charX + 1, line.y + yIndent); + htmlObj.SetPosition(element.position.X, element.position.Y); + if (lineClipped || clipped && (element.position.X < GUTTER_X || element.position.X + htmlObj.width > _contentRect.Width - GUTTER_X)) + element.status |= 1; + else + element.status &= 254; + charX += htmlObj.width + letterSpacing + 2; + } + } } else { @@ -1330,15 +1340,20 @@ namespace FairyGUI continue; } - yIndent = (int)((line.height + line.textHeight) / 2 - glyph.height); - if (format.specialStyle == TextFormat.SpecialStyle.Subscript) - yIndent += (int)(glyph.height * 0.333f); - else if (format.specialStyle == TextFormat.SpecialStyle.Superscript) - yIndent -= (int)(lastGlyphHeight - glyph.height * 0.667f); - else - lastGlyphHeight = glyph.height; - - v0.X = charX + glyph.vertMin.X; + if (lineVAlign == VertAlignType.Bottom) + yIndent = (int)(line.height - glyph.height); + else if (lineVAlign == VertAlignType.Middle) + yIndent = (int)((line.height + line.textHeight) / 2 - glyph.height); + else + yIndent = (int)(line.textHeight - glyph.height); + if (format.specialStyle == TextFormat.SpecialStyle.Subscript) + yIndent += (int)(glyph.height * 0.333f); + else if (format.specialStyle == TextFormat.SpecialStyle.Superscript) + yIndent -= (int)(lastGlyphHeight - glyph.height * 0.667f); + else + lastGlyphHeight = glyph.height; + + v0.X = charX + glyph.vertMin.X; v0.Y = line.y + yIndent + glyph.vertMin.Y; v1.X = charX + glyph.vertMax.X; v1.Y = line.y + yIndent + glyph.vertMax.Y; diff --git a/Engine/CLEngine.Core/gui/Tween/GPath.cs b/Engine/CLEngine.Core/gui/Tween/GPath.cs index 8347447..77e219d 100644 --- a/Engine/CLEngine.Core/gui/Tween/GPath.cs +++ b/Engine/CLEngine.Core/gui/Tween/GPath.cs @@ -4,423 +4,469 @@ using Microsoft.Xna.Framework; namespace FairyGUI { - /// - /// - /// - [System.Serializable] - public struct GPathPoint - { - /// - /// - /// - public Vector3 pos; - - /// - /// - /// - public Vector3 control1; - - /// - /// - /// - public Vector3 control2; - - /// - /// - /// - public CurveType curveType; - - /// - /// - /// - public enum CurveType - { - CRSpline, - Bezier, - CubicBezier, - Straight - } - - /// - /// - /// - /// - public GPathPoint(Vector3 pos) - { - this.pos = pos; - this.control1 = Vector3.Zero; - this.control2 = Vector3.Zero; - this.curveType = CurveType.CRSpline; - } - - /// - /// - /// - /// - /// - public GPathPoint(Vector3 pos, Vector3 control) - { - this.pos = pos; - this.control1 = control; - this.control2 = Vector3.Zero; - this.curveType = CurveType.Bezier; - } - - /// - /// - /// - /// - /// - /// - public GPathPoint(Vector3 pos, Vector3 control1, Vector3 control2) - { - this.pos = pos; - this.control1 = control1; - this.control2 = control2; - this.curveType = CurveType.CubicBezier; - } - - /// - /// - /// - /// - /// - public GPathPoint(Vector3 pos, CurveType curveType) - { - this.pos = pos; - this.control1 = Vector3.Zero; - this.control2 = Vector3.Zero; - this.curveType = curveType; - } - } - - /// - /// - /// - public class GPath - { - struct Segment - { - public GPathPoint.CurveType type; - public float length; - public int ptStart; - public int ptCount; - } - - List _segments; - List _points; - float _fullLength; - - static List splinePoints = new List(); - - public GPath() - { - _segments = new List(); - _points = new List(); - } - - /// - /// - /// - public float length - { - get { return _fullLength; } - } - - /// - /// - /// - /// - public void Create(IEnumerable points) - { - _segments.Clear(); - _points.Clear(); - splinePoints.Clear(); - _fullLength = 0; - - var et = points.GetEnumerator(); - if (!et.MoveNext()) - return; - - GPathPoint prev = et.Current; - if (prev.curveType == GPathPoint.CurveType.CRSpline) - splinePoints.Add(prev.pos); - - while (et.MoveNext()) - { - GPathPoint current = et.Current; - - if (prev.curveType != GPathPoint.CurveType.CRSpline) - { - Segment seg = new Segment(); - seg.type = prev.curveType; - seg.ptStart = _points.Count; - if (prev.curveType == GPathPoint.CurveType.Straight) - { - seg.ptCount = 2; - _points.Add(prev.pos); - _points.Add(current.pos); - } - else if (prev.curveType == GPathPoint.CurveType.Bezier) - { - seg.ptCount = 3; - _points.Add(prev.pos); - _points.Add(current.pos); - _points.Add(prev.control1); - } - else if (prev.curveType == GPathPoint.CurveType.CubicBezier) - { - seg.ptCount = 4; - _points.Add(prev.pos); - _points.Add(current.pos); - _points.Add(prev.control1); - _points.Add(prev.control2); - } - seg.length = Vector3.Distance(prev.pos, current.pos); - _fullLength += seg.length; - _segments.Add(seg); - } - - if (current.curveType != GPathPoint.CurveType.CRSpline) - { - if (splinePoints.Count > 0) - { - splinePoints.Add(current.pos); - CreateSplineSegment(); - } - } - else - splinePoints.Add(current.pos); - - prev = current; - } - - if (splinePoints.Count > 1) - CreateSplineSegment(); - } - - void CreateSplineSegment() - { - int cnt = splinePoints.Count; - splinePoints.Insert(0, splinePoints[0]); - splinePoints.Add(splinePoints[cnt]); - splinePoints.Add(splinePoints[cnt]); - cnt += 3; - - Segment seg = new Segment(); - seg.type = GPathPoint.CurveType.CRSpline; - seg.ptStart = _points.Count; - seg.ptCount = cnt; - _points.AddRange(splinePoints); - - seg.length = 0; - for (int i = 1; i < cnt; i++) - seg.length += Vector3.Distance(splinePoints[i - 1], splinePoints[i]); - _fullLength += seg.length; - _segments.Add(seg); - splinePoints.Clear(); - } - - /// - /// - /// - public void Clear() - { - _segments.Clear(); - _points.Clear(); - } - - /// - /// - /// - /// - /// - public Vector3 GetPointAt(float t) - { - t = MathHelper.Clamp(t, 0, 1); - int cnt = _segments.Count; - if (cnt == 0) - return Vector3.Zero; - - Segment seg; - if (t == 1) - { - seg = _segments[cnt - 1]; - - if (seg.type == GPathPoint.CurveType.Straight) - return Vector3.Lerp(_points[seg.ptStart], _points[seg.ptStart + 1], t); - else if (seg.type == GPathPoint.CurveType.Bezier || seg.type == GPathPoint.CurveType.CubicBezier) - return OnBezierCurve(seg.ptStart, seg.ptCount, t); - else - return onCRSplineCurve(seg.ptStart, seg.ptCount, t); - } - - float len = t * _fullLength; - Vector3 pt = new Vector3(); - for (int i = 0; i < cnt; i++) - { - seg = _segments[i]; - - len -= seg.length; - if (len < 0) - { - t = len / seg.length; - - if (seg.type == GPathPoint.CurveType.Straight) - pt = Vector3.Lerp(_points[seg.ptStart], _points[seg.ptStart + 1], t); - else if (seg.type == GPathPoint.CurveType.Bezier || seg.type == GPathPoint.CurveType.CubicBezier) - pt = OnBezierCurve(seg.ptStart, seg.ptCount, t); - else - pt = onCRSplineCurve(seg.ptStart, seg.ptCount, t); - - break; - } - } - - return pt; - } - - /// - /// - /// - public int segmentCount - { - get { return _segments.Count; } - } - - /// - /// - /// - /// - /// - public float GetSegmentLength(int segmentIndex) - { - return _segments[segmentIndex].length; - } - - /// - /// - /// - /// - /// - /// - /// - /// - public void GetPointsInSegment(int segmentIndex, float t0, float t1, List points, List ts = null, float pointDensity = 0.1f) - { - if (points == null) - points = new List(); - - if (ts != null) - ts.Add(t0); - Segment seg = _segments[segmentIndex]; - if (seg.type == GPathPoint.CurveType.Straight) - { - points.Add(Vector3.Lerp(_points[seg.ptStart], _points[seg.ptStart + 1], t0)); - points.Add(Vector3.Lerp(_points[seg.ptStart], _points[seg.ptStart + 1], t1)); - } - else if (seg.type == GPathPoint.CurveType.Bezier || seg.type == GPathPoint.CurveType.CubicBezier) - { - points.Add(OnBezierCurve(seg.ptStart, seg.ptCount, t0)); - int SmoothAmount = (int)Math.Min(seg.length * pointDensity, 50); - for (int j = 0; j <= SmoothAmount; j++) - { - float t = (float)j / SmoothAmount; - if (t > t0 && t < t1) - { - points.Add(OnBezierCurve(seg.ptStart, seg.ptCount, t)); - if (ts != null) - ts.Add(t); - } - } - points.Add(OnBezierCurve(seg.ptStart, seg.ptCount, t1)); - } - else - { - points.Add(onCRSplineCurve(seg.ptStart, seg.ptCount, t0)); - int SmoothAmount = (int)Math.Min(seg.length * pointDensity, 50); - for (int j = 0; j <= SmoothAmount; j++) - { - float t = (float)j / SmoothAmount; - if (t > t0 && t < t1) - { - points.Add(onCRSplineCurve(seg.ptStart, seg.ptCount, t)); - if (ts != null) - ts.Add(t); - } - } - points.Add(onCRSplineCurve(seg.ptStart, seg.ptCount, t1)); - } - - if (ts != null) - ts.Add(t1); - } - - /// - /// - /// - /// - public void GetAllPoints(List points, float pointDensity = 0.1f) - { - int cnt = _segments.Count; - for (int i = 0; i < cnt; i++) - GetPointsInSegment(i, 0, 1, points, null, pointDensity); - } - - /// - /// Catmull rom spline implementation - /// by Stéphane Drouot, laei - http://games.laei.org - /// - /// Actual translation of math gebrish to C# credit is due to - /// Boon Cotter - http://www.booncotter.com/waypoints-catmull-rom-splines/ - /// - /// This takes a list of vector3 (or an array) and gives a function called .onCurve(t) - /// returning a value on a Catmull-Rom spline for 0 <= t <= 1 - /// - Vector3 onCRSplineCurve(int ptStart, int ptCount, float t) - { - int adjustedIndex = (int)Math.Floor(t * (ptCount - 4)) + ptStart; //Since the equation works with 4 points, we adjust the starting point depending on t to return a point on the specific segment - - Vector3 result = new Vector3(); - - Vector3 p0 = _points[adjustedIndex]; - Vector3 p1 = _points[adjustedIndex + 1]; - Vector3 p2 = _points[adjustedIndex + 2]; - Vector3 p3 = _points[adjustedIndex + 3]; - - float adjustedT = (t == 1f) ? 1f : Repeat(t * (ptCount - 4), 1f); // Then we adjust t to be that value on that new piece of segment... for t == 1f don't use repeat (that would return 0f); - - float t0 = ((-adjustedT + 2f) * adjustedT - 1f) * adjustedT * 0.5f; - float t1 = (((3f * adjustedT - 5f) * adjustedT) * adjustedT + 2f) * 0.5f; - float t2 = ((-3f * adjustedT + 4f) * adjustedT + 1f) * adjustedT * 0.5f; - float t3 = ((adjustedT - 1f) * adjustedT * adjustedT) * 0.5f; - - result.X = p0.X * t0 + p1.X * t1 + p2.X * t2 + p3.X * t3; - result.Y = p0.Y * t0 + p1.Y * t1 + p2.Y * t2 + p3.Y * t3; - result.Z = p0.Z * t0 + p1.Z * t1 + p2.Z * t2 + p3.Z * t3; - - return result; - } - - Vector3 OnBezierCurve(int ptStart, int ptCount, float t) - { - float t2 = 1f - t; - Vector3 p0 = _points[ptStart]; - Vector3 p1 = _points[ptStart + 1]; - Vector3 cp0 = _points[ptStart + 2]; - - if (ptCount == 4) - { - Vector3 cp1 = _points[ptStart + 3]; - return t2 * t2 * t2 * p0 + 3f * t2 * t2 * t * cp0 + 3f * t2 * t * t * cp1 + t * t * t * p1; - } - else - return t2 * t2 * p0 + 2f * t2 * t * cp0 + t * t * p1; - } - - static float Repeat(float t, float length) - { - return MathHelper.Clamp(t - (float)Math.Floor(t / length) * length, 0.0f, length); - } - } + /// + /// + /// + [System.Serializable] + public struct GPathPoint + { + /// + /// + /// + public Vector3 pos; + + /// + /// + /// + public Vector3 control1; + + /// + /// + /// + public Vector3 control2; + + /// + /// + /// + public CurveType curveType; + + /// + /// + /// + public enum CurveType + { + CRSpline, + Bezier, + CubicBezier, + Straight + } + + /// + /// + /// + /// + public GPathPoint(Vector3 pos) + { + this.pos = pos; + this.control1 = Vector3.Zero; + this.control2 = Vector3.Zero; + this.curveType = CurveType.CRSpline; + } + + /// + /// + /// + /// + /// + public GPathPoint(Vector3 pos, Vector3 control) + { + this.pos = pos; + this.control1 = control; + this.control2 = Vector3.Zero; + this.curveType = CurveType.Bezier; + } + + /// + /// + /// + /// + /// + /// + public GPathPoint(Vector3 pos, Vector3 control1, Vector3 control2) + { + this.pos = pos; + this.control1 = control1; + this.control2 = control2; + this.curveType = CurveType.CubicBezier; + } + + /// + /// + /// + /// + /// + public GPathPoint(Vector3 pos, CurveType curveType) + { + this.pos = pos; + this.control1 = Vector3.Zero; + this.control2 = Vector3.Zero; + this.curveType = curveType; + } + } + + /// + /// + /// + public class GPath + { + struct Segment + { + public GPathPoint.CurveType type; + public float length; + public int ptStart; + public int ptCount; + } + + List _segments; + List _points; + float _fullLength; + + static List helperList = new List(); + static List splinePoints = new List(); + + public GPath() + { + _segments = new List(); + _points = new List(); + } + + /// + /// + /// + public float length + { + get { return _fullLength; } + } + + /// + /// + /// + /// + public void Create(IEnumerable points) + { + _segments.Clear(); + _points.Clear(); + splinePoints.Clear(); + _fullLength = 0; + + var et = points.GetEnumerator(); + if (!et.MoveNext()) + return; + + GPathPoint prev = et.Current; + if (prev.curveType == GPathPoint.CurveType.CRSpline) + splinePoints.Add(prev.pos); + + while (et.MoveNext()) + { + GPathPoint current = et.Current; + + if (prev.curveType != GPathPoint.CurveType.CRSpline) + { + Segment seg = new Segment(); + seg.type = prev.curveType; + seg.ptStart = _points.Count; + if (prev.curveType == GPathPoint.CurveType.Straight) + { + seg.ptCount = 2; + _points.Add(prev.pos); + _points.Add(current.pos); + } + else if (prev.curveType == GPathPoint.CurveType.Bezier) + { + seg.ptCount = 3; + _points.Add(prev.pos); + _points.Add(current.pos); + _points.Add(prev.control1); + } + else if (prev.curveType == GPathPoint.CurveType.CubicBezier) + { + seg.ptCount = 4; + _points.Add(prev.pos); + _points.Add(current.pos); + _points.Add(prev.control1); + _points.Add(prev.control2); + } + seg.length = Vector3.Distance(prev.pos, current.pos); + _fullLength += seg.length; + _segments.Add(seg); + } + + if (current.curveType != GPathPoint.CurveType.CRSpline) + { + if (splinePoints.Count > 0) + { + splinePoints.Add(current.pos); + CreateSplineSegment(); + } + } + else + splinePoints.Add(current.pos); + + prev = current; + } + + if (splinePoints.Count > 1) + CreateSplineSegment(); + } + + void CreateSplineSegment() + { + int cnt = splinePoints.Count; + splinePoints.Insert(0, splinePoints[0]); + splinePoints.Add(splinePoints[cnt]); + splinePoints.Add(splinePoints[cnt]); + cnt += 3; + + Segment seg = new Segment(); + seg.type = GPathPoint.CurveType.CRSpline; + seg.ptStart = _points.Count; + seg.ptCount = cnt; + _points.AddRange(splinePoints); + + seg.length = 0; + for (int i = 1; i < cnt; i++) + seg.length += Vector3.Distance(splinePoints[i - 1], splinePoints[i]); + _fullLength += seg.length; + _segments.Add(seg); + splinePoints.Clear(); + } + + /// + /// + /// + public void Clear() + { + _segments.Clear(); + _points.Clear(); + } + + /// + /// + /// + /// + /// + public void Create(GPathPoint pt1, GPathPoint pt2) + { + helperList.Clear(); + helperList.Add(pt1); + helperList.Add(pt2); + Create(helperList); + } + + /// + /// + /// + /// + /// + /// + public void Create(GPathPoint pt1, GPathPoint pt2, GPathPoint pt3) + { + helperList.Clear(); + helperList.Add(pt1); + helperList.Add(pt2); + helperList.Add(pt3); + Create(helperList); + } + + /// + /// + /// + /// + /// + /// + /// + public void Create(GPathPoint pt1, GPathPoint pt2, GPathPoint pt3, GPathPoint pt4) + { + helperList.Clear(); + helperList.Add(pt1); + helperList.Add(pt2); + helperList.Add(pt3); + helperList.Add(pt4); + Create(helperList); + } + + /// + /// + /// + /// + /// + public Vector3 GetPointAt(float t) + { + t = MathHelper.Clamp(t, 0, 1); + int cnt = _segments.Count; + if (cnt == 0) + return Vector3.Zero; + + Segment seg; + if (t == 1) + { + seg = _segments[cnt - 1]; + + if (seg.type == GPathPoint.CurveType.Straight) + return Vector3.Lerp(_points[seg.ptStart], _points[seg.ptStart + 1], t); + else if (seg.type == GPathPoint.CurveType.Bezier || seg.type == GPathPoint.CurveType.CubicBezier) + return OnBezierCurve(seg.ptStart, seg.ptCount, t); + else + return onCRSplineCurve(seg.ptStart, seg.ptCount, t); + } + + float len = t * _fullLength; + Vector3 pt = new Vector3(); + for (int i = 0; i < cnt; i++) + { + seg = _segments[i]; + + len -= seg.length; + if (len < 0) + { + t = 1 + len / seg.length; + + if (seg.type == GPathPoint.CurveType.Straight) + pt = Vector3.Lerp(_points[seg.ptStart], _points[seg.ptStart + 1], t); + else if (seg.type == GPathPoint.CurveType.Bezier || seg.type == GPathPoint.CurveType.CubicBezier) + pt = OnBezierCurve(seg.ptStart, seg.ptCount, t); + else + pt = onCRSplineCurve(seg.ptStart, seg.ptCount, t); + + break; + } + } + + return pt; + } + + /// + /// + /// + public int segmentCount + { + get { return _segments.Count; } + } + + /// + /// + /// + /// + /// + public float GetSegmentLength(int segmentIndex) + { + return _segments[segmentIndex].length; + } + + /// + /// + /// + /// + /// + /// + /// + /// + public void GetPointsInSegment(int segmentIndex, float t0, float t1, List points, List ts = null, float pointDensity = 0.1f) + { + if (points == null) + points = new List(); + + if (ts != null) + ts.Add(t0); + Segment seg = _segments[segmentIndex]; + if (seg.type == GPathPoint.CurveType.Straight) + { + points.Add(Vector3.Lerp(_points[seg.ptStart], _points[seg.ptStart + 1], t0)); + points.Add(Vector3.Lerp(_points[seg.ptStart], _points[seg.ptStart + 1], t1)); + } + else if (seg.type == GPathPoint.CurveType.Bezier || seg.type == GPathPoint.CurveType.CubicBezier) + { + points.Add(OnBezierCurve(seg.ptStart, seg.ptCount, t0)); + int SmoothAmount = (int)Math.Min(seg.length * pointDensity, 50); + for (int j = 0; j <= SmoothAmount; j++) + { + float t = (float)j / SmoothAmount; + if (t > t0 && t < t1) + { + points.Add(OnBezierCurve(seg.ptStart, seg.ptCount, t)); + if (ts != null) + ts.Add(t); + } + } + points.Add(OnBezierCurve(seg.ptStart, seg.ptCount, t1)); + } + else + { + points.Add(onCRSplineCurve(seg.ptStart, seg.ptCount, t0)); + int SmoothAmount = (int)Math.Min(seg.length * pointDensity, 50); + for (int j = 0; j <= SmoothAmount; j++) + { + float t = (float)j / SmoothAmount; + if (t > t0 && t < t1) + { + points.Add(onCRSplineCurve(seg.ptStart, seg.ptCount, t)); + if (ts != null) + ts.Add(t); + } + } + points.Add(onCRSplineCurve(seg.ptStart, seg.ptCount, t1)); + } + + if (ts != null) + ts.Add(t1); + } + + /// + /// + /// + /// + public void GetAllPoints(List points, float pointDensity = 0.1f) + { + int cnt = _segments.Count; + for (int i = 0; i < cnt; i++) + GetPointsInSegment(i, 0, 1, points, null, pointDensity); + } + + /// + /// Catmull rom spline implementation + /// by Stéphane Drouot, laei - http://games.laei.org + /// + /// Actual translation of math gebrish to C# credit is due to + /// Boon Cotter - http://www.booncotter.com/waypoints-catmull-rom-splines/ + /// + /// This takes a list of vector3 (or an array) and gives a function called .onCurve(t) + /// returning a value on a Catmull-Rom spline for 0 <= t <= 1 + /// + Vector3 onCRSplineCurve(int ptStart, int ptCount, float t) + { + int adjustedIndex = (int)Math.Floor(t * (ptCount - 4)) + ptStart; //Since the equation works with 4 points, we adjust the starting point depending on t to return a point on the specific segment + + Vector3 result = new Vector3(); + + Vector3 p0 = _points[adjustedIndex]; + Vector3 p1 = _points[adjustedIndex + 1]; + Vector3 p2 = _points[adjustedIndex + 2]; + Vector3 p3 = _points[adjustedIndex + 3]; + + float adjustedT = (t == 1f) ? 1f : Repeat(t * (ptCount - 4), 1f); // Then we adjust t to be that value on that new piece of segment... for t == 1f don't use repeat (that would return 0f); + + float t0 = ((-adjustedT + 2f) * adjustedT - 1f) * adjustedT * 0.5f; + float t1 = (((3f * adjustedT - 5f) * adjustedT) * adjustedT + 2f) * 0.5f; + float t2 = ((-3f * adjustedT + 4f) * adjustedT + 1f) * adjustedT * 0.5f; + float t3 = ((adjustedT - 1f) * adjustedT * adjustedT) * 0.5f; + + result.X = p0.X * t0 + p1.X * t1 + p2.X * t2 + p3.X * t3; + result.Y = p0.Y * t0 + p1.Y * t1 + p2.Y * t2 + p3.Y * t3; + result.Z = p0.Z * t0 + p1.Z * t1 + p2.Z * t2 + p3.Z * t3; + + return result; + } + + Vector3 OnBezierCurve(int ptStart, int ptCount, float t) + { + float t2 = 1f - t; + Vector3 p0 = _points[ptStart]; + Vector3 p1 = _points[ptStart + 1]; + Vector3 cp0 = _points[ptStart + 2]; + + if (ptCount == 4) + { + Vector3 cp1 = _points[ptStart + 3]; + return t2 * t2 * t2 * p0 + 3f * t2 * t2 * t * cp0 + 3f * t2 * t * t * cp1 + t * t * t * p1; + } + else + return t2 * t2 * p0 + 2f * t2 * t * cp0 + t * t * p1; + } + + static float Repeat(float t, float length) + { + return MathHelper.Clamp(t - (float)Math.Floor(t / length) * length, 0.0f, length); + } + } } \ No newline at end of file diff --git a/Engine/CLEngine.Core/gui/Tween/GTween.cs b/Engine/CLEngine.Core/gui/Tween/GTween.cs index 4716118..317f9e1 100644 --- a/Engine/CLEngine.Core/gui/Tween/GTween.cs +++ b/Engine/CLEngine.Core/gui/Tween/GTween.cs @@ -10,7 +10,7 @@ namespace FairyGUI /// /// /// - public static bool catchCallbackExceptions = true; + public static bool catchCallbackExceptions = false; /// /// diff --git a/Engine/CLEngine.Core/gui/Tween/GTweener.cs b/Engine/CLEngine.Core/gui/Tween/GTweener.cs index 7b3680f..29934f6 100644 --- a/Engine/CLEngine.Core/gui/Tween/GTweener.cs +++ b/Engine/CLEngine.Core/gui/Tween/GTweener.cs @@ -4,780 +4,792 @@ using Microsoft.Xna.Framework; namespace FairyGUI { - /// - /// - /// - public delegate void GTweenCallback(); - - /// - /// - /// - /// - public delegate void GTweenCallback1(GTweener tweener); - - /// - /// - /// - public interface ITweenListener - { - /// - /// - /// - /// - void OnTweenStart(GTweener tweener); - - /// - /// - /// - /// - void OnTweenUpdate(GTweener tweener); - - /// - /// - /// - /// - void OnTweenComplete(GTweener tweener); - } - - /// - /// - /// - public class GTweener - { - internal object _target; - internal TweenPropType _propType; - internal bool _killed; - internal bool _paused; - - float _delay; - float _duration; - float _breakpoint; - EaseType _easeType; - float _easeOvershootOrAmplitude; - float _easePeriod; - int _repeat; - bool _yoyo; - float _timeScale; - bool _ignoreEngineTimeScale; - bool _snapping; - object _userData; - - GTweenCallback _onUpdate; - GTweenCallback _onStart; - GTweenCallback _onComplete; - GTweenCallback1 _onUpdate1; - GTweenCallback1 _onStart1; - GTweenCallback1 _onComplete1; - ITweenListener _listener; - - TweenValue _startValue; - TweenValue _endValue; - TweenValue _value; - TweenValue _deltaValue; - int _valueSize; - - bool _started; - int _ended; - float _elapsedTime; - float _normalizedTime; - - public GTweener() - { - _startValue = new TweenValue(); - _endValue = new TweenValue(); - _value = new TweenValue(); - _deltaValue = new TweenValue(); - } - - /// - /// - /// - /// - /// - public GTweener SetDelay(float value) - { - _delay = value; - return this; - } - - /// - /// - /// - public float delay - { - get { return _delay; } - } - - /// - /// - /// - /// - /// - public GTweener SetDuration(float value) - { - _duration = value; - return this; - } - - /// - /// - /// - public float duration - { - get { return _duration; } - } - - /// - /// - /// - /// - /// - public GTweener SetBreakpoint(float value) - { - _breakpoint = value; - return this; - } - - /// - /// - /// - /// - /// - public GTweener SetEase(EaseType value) - { - _easeType = value; - return this; - } - - /// - /// - /// - /// - /// - public GTweener SetEasePeriod(float value) - { - _easePeriod = value; - return this; - } - - /// - /// - /// - /// - /// - public GTweener SetEaseOvershootOrAmplitude(float value) - { - _easeOvershootOrAmplitude = value; - return this; - } - - /// - /// - /// - /// - /// - /// - public GTweener SetRepeat(int repeat, bool yoyo = false) - { - _repeat = repeat; - _yoyo = yoyo; - return this; - } - - /// - /// - /// - public int repeat - { - get { return _repeat; } - } - - /// - /// - /// - /// - /// - public GTweener SetTimeScale(float value) - { - _timeScale = value; - return this; - } - - /// - /// - /// - /// - /// - public GTweener SetIgnoreEngineTimeScale(bool value) - { - _ignoreEngineTimeScale = value; - return this; - } - - /// - /// - /// - /// - /// - public GTweener SetSnapping(bool value) - { - _snapping = value; - return this; - } - - /// - /// - /// - /// - /// - public GTweener SetTarget(object value) - { - _target = value; - _propType = TweenPropType.None; - return this; - } - - /// - /// - /// - /// - /// - /// - public GTweener SetTarget(object value, TweenPropType propType) - { - _target = value; - _propType = propType; - return this; - } - - /// - /// - /// - public object target - { - get { return _target; } - } - - /// - /// - /// - /// - /// - public GTweener SetUserData(object value) - { - _userData = value; - return this; - } - - /// - /// - /// - public object userData - { - get { return _userData; } - } - - /// - /// - /// - /// - /// - public GTweener OnUpdate(GTweenCallback callback) - { - _onUpdate = callback; - return this; - } - - /// - /// - /// - /// - /// - public GTweener OnStart(GTweenCallback callback) - { - _onStart = callback; - return this; - } - - /// - /// - /// - /// - /// - public GTweener OnComplete(GTweenCallback callback) - { - _onComplete = callback; - return this; - } - - /// - /// - /// - /// - /// - public GTweener OnUpdate(GTweenCallback1 callback) - { - _onUpdate1 = callback; - return this; - } - - /// - /// - /// - /// - /// - public GTweener OnStart(GTweenCallback1 callback) - { - _onStart1 = callback; - return this; - } - - /// - /// - /// - /// - /// - public GTweener OnComplete(GTweenCallback1 callback) - { - _onComplete1 = callback; - return this; - } - - /// - /// - /// - /// - /// - public GTweener SetListener(ITweenListener value) - { - _listener = value; - return this; - } - - /// - /// - /// - public TweenValue startValue - { - get { return _startValue; } - } - - /// - /// - /// - public TweenValue endValue - { - get { return _endValue; } - } - - /// - /// - /// - public TweenValue value - { - get { return _value; } - } - - /// - /// - /// - public TweenValue deltaValue - { - get { return _deltaValue; } - } - - /// - /// - /// - public float normalizedTime - { - get { return _normalizedTime; } - } - - /// - /// - /// - public bool completed - { - get { return _ended != 0; } - } - - /// - /// - /// - public bool allCompleted - { - get { return _ended == 1; } - } - - /// - /// - /// - /// - /// - public GTweener SetPaused(bool paused) - { - _paused = paused; - return this; - } - - /// - /// - /// - /// - public void Seek(float time) - { - if (_killed) - return; - - _elapsedTime = time; - if (_elapsedTime < _delay) - { - if (_started) - _elapsedTime = _delay; - else - return; - } - - Update(); - } - - /// - /// - /// - /// - public void Kill(bool complete = false) - { - if (_killed) - return; - - if (complete) - { - if (_ended == 0) - { - if (_breakpoint >= 0) - _elapsedTime = _delay + _breakpoint; - else if (_repeat >= 0) - _elapsedTime = _delay + _duration * (_repeat + 1); - else - _elapsedTime = _delay + _duration * 2; - Update(); - } - - CallCompleteCallback(); - } - - _killed = true; - } - - internal GTweener _To(float start, float end, float duration) - { - _valueSize = 1; - _startValue.x = start; - _endValue.x = end; - _duration = duration; - return this; - } - - internal GTweener _To(Vector2 start, Vector2 end, float duration) - { - _valueSize = 2; - _startValue.vec2 = start; - _endValue.vec2 = end; - _duration = duration; - return this; - } - - internal GTweener _To(Vector3 start, Vector3 end, float duration) - { - _valueSize = 3; - _startValue.vec3 = start; - _endValue.vec3 = end; - _duration = duration; - return this; - } - - internal GTweener _To(Vector4 start, Vector4 end, float duration) - { - _valueSize = 4; - _startValue.vec4 = start; - _endValue.vec4 = end; - _duration = duration; - return this; - } - - internal GTweener _To(Color start, Color end, float duration) - { - _valueSize = 4; - _startValue.color = start; - _endValue.color = end; - _duration = duration; - return this; - } - - internal GTweener _To(double start, double end, float duration) - { - _valueSize = 5; - _startValue.d = start; - _endValue.d = end; - _duration = duration; - return this; - } - - internal GTweener _Shake(Vector3 start, float amplitude, float duration) - { - _valueSize = 6; - _startValue.vec3 = start; - _startValue.w = amplitude; - _duration = duration; - _easeType = EaseType.Linear; - return this; - } - - internal void _Init() - { - _delay = 0; - _duration = 0; - _breakpoint = -1; - _easeType = EaseType.QuadOut; - _timeScale = 1; - _easePeriod = 0; - _easeOvershootOrAmplitude = 1.70158f; - _snapping = false; - _repeat = 0; - _yoyo = false; - _valueSize = 0; - _started = false; - _paused = false; - _killed = false; - _elapsedTime = 0; - _normalizedTime = 0; - _ended = 0; - } - - internal void _Reset() - { - _target = null; - _listener = null; - _userData = null; - _onStart = _onUpdate = _onComplete = null; - _onStart1 = _onUpdate1 = _onComplete1 = null; - } - - internal void _Update(GameTime gameTime) - { - if (_ended != 0) //Maybe completed by seek - { - CallCompleteCallback(); - _killed = true; - return; - } - - float dt = (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000f; - if (_timeScale != 1) - dt *= _timeScale; - if (dt == 0) - return; - - _elapsedTime += dt; - Update(); - - if (_ended != 0) - { - if (!_killed) - { - CallCompleteCallback(); - _killed = true; - } - } - } - - void Update() - { - _ended = 0; - - if (_valueSize == 0) //DelayedCall - { - if (_elapsedTime >= _delay + _duration) - _ended = 1; - - return; - } - - if (!_started) - { - if (_elapsedTime < _delay) - return; - - _started = true; - CallStartCallback(); - if (_killed) - return; - } - - bool reversed = false; - float tt = _elapsedTime - _delay; - if (_breakpoint >= 0 && tt >= _breakpoint) - { - tt = _breakpoint; - _ended = 2; - } - - if (_repeat != 0) - { - int round = (int)Math.Floor(tt / _duration); - tt -= _duration * round; - if (_yoyo) - reversed = round % 2 == 1; - - if (_repeat > 0 && _repeat - round < 0) - { - if (_yoyo) - reversed = _repeat % 2 == 1; - tt = _duration; - _ended = 1; - } - } - else if (tt >= _duration) - { - tt = _duration; - _ended = 1; - } - - _normalizedTime = EaseManager.Evaluate(_easeType, reversed ? (_duration - tt) : tt, _duration, - _easeOvershootOrAmplitude, _easePeriod); - - _value.SetZero(); - _deltaValue.SetZero(); - - if (_valueSize == 5) - { - double d = _startValue.d + (_endValue.d - _startValue.d) * _normalizedTime; - if (_snapping) - d = Math.Round(d); - _deltaValue.d = d - _value.d; - _value.d = d; - } - else if (_valueSize == 6) - { - if (_ended == 0) - { - Vector2 r = new Vector2(ToolSet.Random(-1.0f, 1.0f), ToolSet.Random(-1.0f, 1.0f)); - r.X = r.X > 0 ? 1 : -1; - r.Y = r.Y > 0 ? 1 : -1; - r *= _startValue.w * (1 - _normalizedTime); - - _deltaValue.vec2 = r; - _value.vec2 = _startValue.vec2 + r; - } - else - _value.vec2 = _startValue.vec2; - } - else - { - for (int i = 0; i < _valueSize; i++) - { - float n1 = _startValue[i]; - float n2 = _endValue[i]; - float f = n1 + (n2 - n1) * _normalizedTime; - if (_snapping) - f = (float)Math.Round(f); - _deltaValue[i] = f - _value[i]; - _value[i] = f; - } - } - - if (_target != null && _propType != TweenPropType.None) - TweenPropTypeUtils.SetProps(_target, _propType, _value); - - CallUpdateCallback(); - } - - void CallStartCallback() - { - if (GTween.catchCallbackExceptions) - { - try - { - if (_onStart1 != null) - _onStart1(this); - if (_onStart != null) - _onStart(); - if (_listener != null) - _listener.OnTweenStart(this); - } - catch (Exception e) - { - Log.Warning("FairyGUI: error in start callback > " + e.Message); - } - } - else - { - if (_onStart1 != null) - _onStart1(this); - if (_onStart != null) - _onStart(); - if (_listener != null) - _listener.OnTweenStart(this); - } - } - - void CallUpdateCallback() - { - if (GTween.catchCallbackExceptions) - { - try - { - if (_onUpdate1 != null) - _onUpdate1(this); - if (_onUpdate != null) - _onUpdate(); - if (_listener != null) - _listener.OnTweenUpdate(this); - } - catch (Exception e) - { - Log.Warning("FairyGUI: error in update callback > " + e.Message); - } - } - else - { - if (_onUpdate1 != null) - _onUpdate1(this); - if (_onUpdate != null) - _onUpdate(); - if (_listener != null) - _listener.OnTweenUpdate(this); - } - } - - void CallCompleteCallback() - { - if (GTween.catchCallbackExceptions) - { - try - { - if (_onComplete1 != null) - _onComplete1(this); - if (_onComplete != null) - _onComplete(); - if (_listener != null) - _listener.OnTweenComplete(this); - } - catch (Exception e) - { - Log.Warning("FairyGUI: error in complete callback > " + e.Message); - } - } - else - { - if (_onComplete1 != null) - _onComplete1(this); - if (_onComplete != null) - _onComplete(); - if (_listener != null) - _listener.OnTweenComplete(this); - } - } - } + /// + /// + /// + public delegate void GTweenCallback(); + + /// + /// + /// + /// + public delegate void GTweenCallback1(GTweener tweener); + + /// + /// + /// + public interface ITweenListener + { + /// + /// + /// + /// + void OnTweenStart(GTweener tweener); + + /// + /// + /// + /// + void OnTweenUpdate(GTweener tweener); + + /// + /// + /// + /// + void OnTweenComplete(GTweener tweener); + } + + /// + /// + /// + public class GTweener + { + internal object _target; + internal TweenPropType _propType; + internal bool _killed; + internal bool _paused; + + float _delay; + float _duration; + float _breakpoint; + EaseType _easeType; + float _easeOvershootOrAmplitude; + float _easePeriod; + int _repeat; + bool _yoyo; + float _timeScale; + bool _ignoreEngineTimeScale; + bool _snapping; + object _userData; + + GTweenCallback _onUpdate; + GTweenCallback _onStart; + GTweenCallback _onComplete; + GTweenCallback1 _onUpdate1; + GTweenCallback1 _onStart1; + GTweenCallback1 _onComplete1; + ITweenListener _listener; + + TweenValue _startValue; + TweenValue _endValue; + TweenValue _value; + TweenValue _deltaValue; + int _valueSize; + + bool _started; + int _ended; + float _elapsedTime; + float _normalizedTime; + + public GTweener() + { + _startValue = new TweenValue(); + _endValue = new TweenValue(); + _value = new TweenValue(); + _deltaValue = new TweenValue(); + } + + /// + /// + /// + /// + /// + public GTweener SetDelay(float value) + { + _delay = value; + return this; + } + + /// + /// + /// + public float delay + { + get { return _delay; } + } + + /// + /// + /// + /// + /// + public GTweener SetDuration(float value) + { + _duration = value; + return this; + } + + /// + /// + /// + public float duration + { + get { return _duration; } + } + + /// + /// + /// + /// + /// + public GTweener SetBreakpoint(float value) + { + _breakpoint = value; + return this; + } + + /// + /// + /// + /// + /// + public GTweener SetEase(EaseType value) + { + _easeType = value; + return this; + } + + /// + /// + /// + /// + /// + public GTweener SetEasePeriod(float value) + { + _easePeriod = value; + return this; + } + + /// + /// + /// + /// + /// + public GTweener SetEaseOvershootOrAmplitude(float value) + { + _easeOvershootOrAmplitude = value; + return this; + } + + /// + /// + /// + /// + /// + /// + public GTweener SetRepeat(int times, bool yoyo = false) + { + _repeat = times; + _yoyo = yoyo; + return this; + } + + /// + /// + /// + public int repeat + { + get { return _repeat; } + } + + /// + /// + /// + /// + /// + public GTweener SetTimeScale(float value) + { + _timeScale = value; + return this; + } + + /// + /// + /// + /// + /// + public GTweener SetIgnoreEngineTimeScale(bool value) + { + _ignoreEngineTimeScale = value; + return this; + } + + /// + /// + /// + /// + /// + public GTweener SetSnapping(bool value) + { + _snapping = value; + return this; + } + + /// + /// + /// + /// + /// + public GTweener SetTarget(object value) + { + _target = value; + _propType = TweenPropType.None; + return this; + } + + /// + /// + /// + /// + /// + /// + public GTweener SetTarget(object value, TweenPropType propType) + { + _target = value; + _propType = propType; + return this; + } + + /// + /// + /// + public object target + { + get { return _target; } + } + + /// + /// + /// + /// + /// + public GTweener SetUserData(object value) + { + _userData = value; + return this; + } + + /// + /// + /// + public object userData + { + get { return _userData; } + } + + /// + /// + /// + /// + /// + public GTweener OnUpdate(GTweenCallback callback) + { + _onUpdate = callback; + return this; + } + + /// + /// + /// + /// + /// + public GTweener OnStart(GTweenCallback callback) + { + _onStart = callback; + return this; + } + + /// + /// + /// + /// + /// + public GTweener OnComplete(GTweenCallback callback) + { + _onComplete = callback; + return this; + } + + /// + /// + /// + /// + /// + public GTweener OnUpdate(GTweenCallback1 callback) + { + _onUpdate1 = callback; + return this; + } + + /// + /// + /// + /// + /// + public GTweener OnStart(GTweenCallback1 callback) + { + _onStart1 = callback; + return this; + } + + /// + /// + /// + /// + /// + public GTweener OnComplete(GTweenCallback1 callback) + { + _onComplete1 = callback; + return this; + } + + /// + /// + /// + /// + /// + public GTweener SetListener(ITweenListener value) + { + _listener = value; + return this; + } + + /// + /// + /// + public TweenValue startValue + { + get { return _startValue; } + } + + /// + /// + /// + public TweenValue endValue + { + get { return _endValue; } + } + + /// + /// + /// + public TweenValue value + { + get { return _value; } + } + + /// + /// + /// + public TweenValue deltaValue + { + get { return _deltaValue; } + } + + /// + /// + /// + public float normalizedTime + { + get { return _normalizedTime; } + } + + /// + /// + /// + public bool completed + { + get { return _ended != 0; } + } + + /// + /// + /// + public bool allCompleted + { + get { return _ended == 1; } + } + + /// + /// + /// + /// + /// + public GTweener SetPaused(bool paused) + { + _paused = paused; + return this; + } + + /// + /// + /// + /// + public void Seek(float time) + { + if (_killed) + return; + + _elapsedTime = time; + if (_elapsedTime < _delay) + { + if (_started) + _elapsedTime = _delay; + else + return; + } + + Update(); + } + + /// + /// + /// + /// + public void Kill(bool complete = false) + { + if (_killed) + return; + + if (complete) + { + if (_ended == 0) + { + if (_breakpoint >= 0) + _elapsedTime = _delay + _breakpoint; + else if (_repeat >= 0) + _elapsedTime = _delay + _duration * (_repeat + 1); + else + _elapsedTime = _delay + _duration * 2; + Update(); + } + + CallCompleteCallback(); + } + + _killed = true; + } + + internal GTweener _To(float start, float end, float duration) + { + _valueSize = 1; + _startValue.x = start; + _endValue.x = end; + _value.x = start; + _duration = duration; + return this; + } + + internal GTweener _To(Vector2 start, Vector2 end, float duration) + { + _valueSize = 2; + _startValue.vec2 = start; + _endValue.vec2 = end; + _value.vec2 = start; + _duration = duration; + return this; + } + + internal GTweener _To(Vector3 start, Vector3 end, float duration) + { + _valueSize = 3; + _startValue.vec3 = start; + _endValue.vec3 = end; + _value.vec3 = start; + _duration = duration; + return this; + } + + internal GTweener _To(Vector4 start, Vector4 end, float duration) + { + _valueSize = 4; + _startValue.vec4 = start; + _endValue.vec4 = end; + _value.vec4 = start; + _duration = duration; + return this; + } + + internal GTweener _To(Color start, Color end, float duration) + { + _valueSize = 4; + _startValue.color = start; + _endValue.color = end; + _value.color = start; + _duration = duration; + return this; + } + + internal GTweener _To(double start, double end, float duration) + { + _valueSize = 5; + _startValue.d = start; + _endValue.d = end; + _value.d = start; + _duration = duration; + return this; + } + + internal GTweener _Shake(Vector3 start, float amplitude, float duration) + { + _valueSize = 6; + _startValue.vec3 = start; + _startValue.w = amplitude; + _duration = duration; + _easeType = EaseType.Linear; + return this; + } + + internal void _Init() + { + _delay = 0; + _duration = 0; + _breakpoint = -1; + _easeType = EaseType.QuadOut; + _timeScale = 1; + _easePeriod = 0; + _easeOvershootOrAmplitude = 1.70158f; + _snapping = false; + _repeat = 0; + _yoyo = false; + _valueSize = 0; + _started = false; + _paused = false; + _killed = false; + _elapsedTime = 0; + _normalizedTime = 0; + _ended = 0; + } + + internal void _Reset() + { + _target = null; + _listener = null; + _userData = null; + _onStart = _onUpdate = _onComplete = null; + _onStart1 = _onUpdate1 = _onComplete1 = null; + } + + internal void _Update(GameTime gameTime) + { + if ((_target is GObject) && ((GObject)_target)._disposed) + { + _killed = true; + return; + } + + if (_ended != 0) //Maybe completed by seek + { + CallCompleteCallback(); + _killed = true; + return; + } + + float dt = (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000f; + if (_timeScale != 1) + dt *= _timeScale; + if (dt == 0) + return; + + _elapsedTime += dt; + Update(); + + if (_ended != 0) + { + if (!_killed) + { + CallCompleteCallback(); + _killed = true; + } + } + } + + void Update() + { + _ended = 0; + + if (_valueSize == 0) //DelayedCall + { + if (_elapsedTime >= _delay + _duration) + _ended = 1; + + return; + } + + if (!_started) + { + if (_elapsedTime < _delay) + return; + + _started = true; + CallStartCallback(); + if (_killed) + return; + } + + bool reversed = false; + float tt = _elapsedTime - _delay; + if (_breakpoint >= 0 && tt >= _breakpoint) + { + tt = _breakpoint; + _ended = 2; + } + + if (_repeat != 0) + { + int round = (int)Math.Floor(tt / _duration); + tt -= _duration * round; + if (_yoyo) + reversed = round % 2 == 1; + + if (_repeat > 0 && _repeat - round < 0) + { + if (_yoyo) + reversed = _repeat % 2 == 1; + tt = _duration; + _ended = 1; + } + } + else if (tt >= _duration) + { + tt = _duration; + _ended = 1; + } + + _normalizedTime = EaseManager.Evaluate(_easeType, reversed ? (_duration - tt) : tt, _duration, + _easeOvershootOrAmplitude, _easePeriod); + + _value.SetZero(); + _deltaValue.SetZero(); + + if (_valueSize == 5) + { + double d = _startValue.d + (_endValue.d - _startValue.d) * _normalizedTime; + if (_snapping) + d = Math.Round(d); + _deltaValue.d = d - _value.d; + _value.d = d; + } + else if (_valueSize == 6) + { + if (_ended == 0) + { + Vector2 r = new Vector2(ToolSet.Random(-1.0f, 1.0f), ToolSet.Random(-1.0f, 1.0f)); + r.X = r.X > 0 ? 1 : -1; + r.Y = r.Y > 0 ? 1 : -1; + r *= _startValue.w * (1 - _normalizedTime); + + _deltaValue.vec2 = r; + _value.vec2 = _startValue.vec2 + r; + } + else + _value.vec2 = _startValue.vec2; + } + else + { + for (int i = 0; i < _valueSize; i++) + { + float n1 = _startValue[i]; + float n2 = _endValue[i]; + float f = n1 + (n2 - n1) * _normalizedTime; + if (_snapping) + f = (float)Math.Round(f); + _deltaValue[i] = f - _value[i]; + _value[i] = f; + } + } + + if (_target != null && _propType != TweenPropType.None) + TweenPropTypeUtils.SetProps(_target, _propType, _value); + + CallUpdateCallback(); + } + + void CallStartCallback() + { + if (GTween.catchCallbackExceptions) + { + try + { + if (_onStart1 != null) + _onStart1(this); + if (_onStart != null) + _onStart(); + if (_listener != null) + _listener.OnTweenStart(this); + } + catch (Exception e) + { + Log.Warning("FairyGUI: error in start callback > " + e.Message); + } + } + else + { + if (_onStart1 != null) + _onStart1(this); + if (_onStart != null) + _onStart(); + if (_listener != null) + _listener.OnTweenStart(this); + } + } + + void CallUpdateCallback() + { + if (GTween.catchCallbackExceptions) + { + try + { + if (_onUpdate1 != null) + _onUpdate1(this); + if (_onUpdate != null) + _onUpdate(); + if (_listener != null) + _listener.OnTweenUpdate(this); + } + catch (Exception e) + { + Log.Warning("FairyGUI: error in update callback > " + e.Message); + } + } + else + { + if (_onUpdate1 != null) + _onUpdate1(this); + if (_onUpdate != null) + _onUpdate(); + if (_listener != null) + _listener.OnTweenUpdate(this); + } + } + + void CallCompleteCallback() + { + if (GTween.catchCallbackExceptions) + { + try + { + if (_onComplete1 != null) + _onComplete1(this); + if (_onComplete != null) + _onComplete(); + if (_listener != null) + _listener.OnTweenComplete(this); + } + catch (Exception e) + { + Log.Warning("FairyGUI: error in complete callback > " + e.Message); + } + } + else + { + if (_onComplete1 != null) + _onComplete1(this); + if (_onComplete != null) + _onComplete(); + if (_listener != null) + _listener.OnTweenComplete(this); + } + } + } } diff --git a/Engine/CLEngine.Core/gui/UI/GButton.cs b/Engine/CLEngine.Core/gui/UI/GButton.cs index f7fc48e..567b4c5 100644 --- a/Engine/CLEngine.Core/gui/UI/GButton.cs +++ b/Engine/CLEngine.Core/gui/UI/GButton.cs @@ -315,14 +315,25 @@ namespace FairyGUI /// 模拟点击这个按钮。 /// /// If the down effect will simulate too. - public void FireClick(bool downEffect) + public void FireClick(bool downEffect, bool clickCall = false) { - if (downEffect && _mode == ButtonMode.Common) - { - SetState(OVER); - Timers.inst.Add(0.1f, 1, (object param) => { SetState(DOWN); }); - Timers.inst.Add(0.2f, 1, (object param) => { SetState(UP); }); - } + if (downEffect && _mode == ButtonMode.Common) + { + SetState(OVER); + Timers.inst.Add(0.1f, 1, (object param) => { SetState(DOWN); }); + Timers.inst.Add(0.2f, 1, (object param) => + { + SetState(UP); + if (clickCall) { } + }); + } + else + { + if (clickCall) + { + onClick.Call(); + } + } __click(); } diff --git a/Engine/CLEngine.Core/gui/UI/GComponent.cs b/Engine/CLEngine.Core/gui/UI/GComponent.cs index a607099..3f2bf04 100644 --- a/Engine/CLEngine.Core/gui/UI/GComponent.cs +++ b/Engine/CLEngine.Core/gui/UI/GComponent.cs @@ -862,7 +862,11 @@ namespace FairyGUI public DisplayObject mask { get { return container.mask; } - set { container.mask = value; } + set { + container.mask = value; + if (value != null && value.parent != container) + container.AddChild(value); + } } /// @@ -1358,9 +1362,10 @@ namespace FairyGUI int maskId = buffer.ReadShort(); if (maskId != -1) { - this.mask = GetChildAt(maskId).displayObject; - buffer.ReadBool(); //reversedMask - } + container.mask = GetChildAt(maskId).displayObject; + if (buffer.ReadBool()) + container.reversedMask = true; + } string hitTestId = buffer.ReadS(); if (hitTestId != null) { @@ -1369,8 +1374,8 @@ namespace FairyGUI { int i1 = buffer.ReadInt(); int i2 = buffer.ReadInt(); - this.rootContainer.hitArea = new PixelHitTest(pi.pixelHitTestData, i1, i2, sourceWidth, sourceHeight); - } + rootContainer.hitArea = new PixelHitTest(pi.pixelHitTestData, i1, i2, sourceWidth, sourceHeight); + } } buffer.Seek(0, 5); diff --git a/Engine/CLEngine.Core/gui/UI/GGroup.cs b/Engine/CLEngine.Core/gui/UI/GGroup.cs index e87a685..52cc082 100644 --- a/Engine/CLEngine.Core/gui/UI/GGroup.cs +++ b/Engine/CLEngine.Core/gui/UI/GGroup.cs @@ -98,113 +98,115 @@ namespace FairyGUI public void EnsureBoundsCorrect() { - if (_boundsChanged) - UpdateBounds(); - } + if (!_boundsChanged) + return; - void UpdateBounds() - { - Stage.beforeUpdate -= _refreshDelegate; - _boundsChanged = false; + Stage.beforeUpdate -= _refreshDelegate; + _boundsChanged = false; - if (parent == null) - return; + if (parent == null) + return; - HandleLayout(); + HandleLayout(); - int cnt = parent.numChildren; - int i; - GObject child; - float ax = int.MaxValue, ay = int.MaxValue; - float ar = int.MinValue, ab = int.MinValue; - float tmp; - bool empty = true; + UpdateBounds(); + } - for (i = 0; i < cnt; i++) - { - child = parent.GetChildAt(i); - if (child.group != this) - continue; - - tmp = child.x; - if (tmp < ax) - ax = tmp; - tmp = child.y; - if (tmp < ay) - ay = tmp; - tmp = child.x + child.width; - if (tmp > ar) - ar = tmp; - tmp = child.y + child.height; - if (tmp > ab) - ab = tmp; - - empty = false; - } - - if (!empty) - { - _updating = 1; - SetPosition(ax, ay); - _updating = 2; - SetSize(ar - ax, ab - ay); - } - else - { - _updating = 2; - SetSize(0, 0); - } - - _updating = 0; - } + void UpdateBounds() + { + int cnt = parent.numChildren; + int i; + GObject child; + float ax = int.MaxValue, ay = int.MaxValue; + float ar = int.MinValue, ab = int.MinValue; + float tmp; + bool empty = true; + + for (i = 0; i < cnt; i++) + { + child = parent.GetChildAt(i); + if (child.group != this) + continue; + + tmp = child.xMin; + if (tmp < ax) + ax = tmp; + tmp = child.yMin; + if (tmp < ay) + ay = tmp; + tmp = child.xMin + child.width; + if (tmp > ar) + ar = tmp; + tmp = child.yMin + child.height; + if (tmp > ab) + ab = tmp; + + empty = false; + } + + if (!empty) + { + _updating = 1; + SetPosition(ax, ay); + _updating = 2; + SetSize(ar - ax, ab - ay); + } + else + { + _updating = 2; + SetSize(0, 0); + } + + _updating = 0; + } void HandleLayout() { - _updating |= 1; - - if (_layout == GroupLayoutType.Horizontal) - { - float curX = float.NaN; - int cnt = parent.numChildren; - for (int i = 0; i < cnt; i++) - { - GObject child = parent.GetChildAt(i); - if (child.group != this) - continue; - - if (float.IsNaN(curX)) - curX = (int)child.x; - else - child.x = curX; - if (child.width != 0) - curX += (int)(child.width + _columnGap); - } - if (!_percentReady) - UpdatePercent(); - } - else if (_layout == GroupLayoutType.Vertical) - { - float curY = float.NaN; - int cnt = parent.numChildren; - for (int i = 0; i < cnt; i++) - { - GObject child = parent.GetChildAt(i); - if (child.group != this) - continue; - - if (float.IsNaN(curY)) - curY = (int)child.y; - else - child.y = curY; - if (child.height != 0) - curY += (int)(child.height + _lineGap); - } - if (!_percentReady) - UpdatePercent(); - } - - _updating &= 2; - } + _updating |= 1; + + if (_layout == GroupLayoutType.Horizontal) + { + float curX = float.NaN; + int cnt = parent.numChildren; + for (int i = 0; i < cnt; i++) + { + GObject child = parent.GetChildAt(i); + if (child.group != this) + continue; + + if (float.IsNaN(curX)) + curX = (int)child.xMin; + else + child.xMin = curX; + if (child.width != 0) + curX += child.width + _columnGap; + } + if (!_percentReady) + UpdatePercent(); + } + else if (_layout == GroupLayoutType.Vertical) + { + float curY = float.NaN; + int cnt = parent.numChildren; + for (int i = 0; i < cnt; i++) + { + GObject child = parent.GetChildAt(i); + if (child.group != this) + continue; + + if (float.IsNaN(curY)) + curY = (int)child.yMin; + else + child.yMin = curY; + if (child.height != 0) + curY += child.height + _lineGap; + } + if (!_percentReady) + UpdatePercent(); + } + + _updating &= 2; + } void UpdatePercent() { @@ -286,137 +288,75 @@ namespace FairyGUI internal void ResizeChildren(float dw, float dh) { - if (_layout == GroupLayoutType.None || (_updating & 2) != 0 || parent == null) - return; - - _updating |= 2; - - if (!_percentReady) - UpdatePercent(); - - int cnt = parent.numChildren; - int i; - int j; - GObject child; - int last = -1; - int numChildren = 0; - float lineSize = 0; - float remainSize = 0; - bool found = false; - - for (i = 0; i < cnt; i++) - { - child = parent.GetChildAt(i); - if (child.group != this) - continue; - - last = i; - numChildren++; - } - - if (_layout == GroupLayoutType.Horizontal) - { - remainSize = lineSize = this.width - (numChildren - 1) * _columnGap; - float curX = float.NaN; - float nw; - for (i = 0; i < cnt; i++) - { - child = parent.GetChildAt(i); - if (child.group != this) - continue; - - if (float.IsNaN(curX)) - curX = (int)child.x; - else - child.x = curX; - if (last == i) - nw = remainSize; - else - nw = (float)Math.Round(child._sizePercentInGroup * lineSize); - child.SetSize(nw, child._rawHeight + dh, true); - remainSize -= child.width; - if (last == i) - { - if (remainSize >= 1) //可能由于有些元件有宽度限制,导致无法铺满 - { - for (j = 0; j <= i; j++) - { - child = parent.GetChildAt(j); - if (child.group != this) - continue; - - if (!found) - { - nw = child.width + remainSize; - if ((child.maxWidth == 0 || nw < child.maxWidth) - && (child.minWidth == 0 || nw > child.minWidth)) - { - child.SetSize(nw, child.height, true); - found = true; - } - } - else - child.x += remainSize; - } - } - } - else - curX += (child.width + _columnGap); - } - } - else if (_layout == GroupLayoutType.Vertical) - { - remainSize = lineSize = this.height - (numChildren - 1) * _lineGap; - float curY = float.NaN; - float nh; - for (i = 0; i < cnt; i++) - { - child = parent.GetChildAt(i); - if (child.group != this) - continue; - - if (float.IsNaN(curY)) - curY = (int)child.y; - else - child.y = curY; - if (last == i) - nh = remainSize; - else - nh = (float)Math.Round(child._sizePercentInGroup * lineSize); - child.SetSize(child._rawWidth + dw, nh, true); - remainSize -= child.height; - if (last == i) - { - if (remainSize >= 1) //可能由于有些元件有宽度限制,导致无法铺满 - { - for (j = 0; j <= i; j++) - { - child = parent.GetChildAt(j); - if (child.group != this) - continue; - - if (!found) - { - nh = child.height + remainSize; - if ((child.maxHeight == 0 || nh < child.maxHeight) - && (child.minHeight == 0 || nh > child.minHeight)) - { - child.SetSize(child.width, nh, true); - found = true; - } - } - else - child.y += remainSize; - } - } - } - else - curY += (child.height + _lineGap); - } - } - - _updating &= 1; - } + if (_layout == GroupLayoutType.None || (_updating & 2) != 0 || parent == null) + return; + + if (!_percentReady) + UpdatePercent(); + + int cnt = parent.numChildren; + int i; + GObject child; + int numChildren = 0; + float remainSize = 0; + float remainPercent = 1; + + for (i = 0; i < cnt; i++) + { + child = parent.GetChildAt(i); + if (child.group != this) + continue; + + numChildren++; + } + + if (_layout == GroupLayoutType.Horizontal) + { + _updating |= 2; + remainSize = this.width - (numChildren - 1) * _columnGap; + float curX = float.NaN; + for (i = 0; i < cnt; i++) + { + child = parent.GetChildAt(i); + if (child.group != this) + continue; + + if (float.IsNaN(curX)) + curX = (int)child.xMin; + else + child.xMin = curX; + child.SetSize((float)Math.Round(child._sizePercentInGroup / remainPercent * remainSize), child._rawHeight + dh, true); + remainSize -= child.width; + remainPercent -= child._sizePercentInGroup; + curX += child.width + _columnGap; + } + _updating &= 1; + UpdateBounds(); + } + else if (_layout == GroupLayoutType.Vertical) + { + _updating |= 2; + remainSize = this.height - (numChildren - 1) * _lineGap; + float curY = float.NaN; + for (i = 0; i < cnt; i++) + { + child = parent.GetChildAt(i); + if (child.group != this) + continue; + + if (float.IsNaN(curY)) + curY = (int)child.yMin; + else + child.yMin = curY; + child.SetSize(child._rawWidth + dw, (float)Math.Round(child._sizePercentInGroup / remainPercent * remainSize), true); + remainSize -= child.height; + remainPercent -= child._sizePercentInGroup; + curY += child.height + _lineGap; + } + _updating &= 1; + UpdateBounds(); + } + } override protected void HandleAlphaChanged() { diff --git a/Engine/CLEngine.Core/gui/UI/GList.cs b/Engine/CLEngine.Core/gui/UI/GList.cs index 4b7329c..fb9d2e5 100644 --- a/Engine/CLEngine.Core/gui/UI/GList.cs +++ b/Engine/CLEngine.Core/gui/UI/GList.cs @@ -1931,8 +1931,8 @@ namespace FairyGUI if (deltaSize != 0 || firstItemDeltaSize != 0) this.scrollPane.ChangeContentSizeOnScrolling(0, deltaSize, 0, firstItemDeltaSize); - if (curIndex > 0 && this.numChildren > 0 && this.container.y < 0 && GetChildAt(0).y > -this.container.y)//最后一页没填满! - return true; + if (curIndex > 0 && this.numChildren > 0 && this.container.y <= 0 && GetChildAt(0).y > -this.container.y)//最后一页没填满! + return true; else return false; } @@ -2100,8 +2100,8 @@ namespace FairyGUI if (deltaSize != 0 || firstItemDeltaSize != 0) this.scrollPane.ChangeContentSizeOnScrolling(deltaSize, 0, firstItemDeltaSize, 0); - if (curIndex > 0 && this.numChildren > 0 && this.container.x < 0 && GetChildAt(0).x > -this.container.x)//最后一页没填满! - return true; + if (curIndex > 0 && this.numChildren > 0 && this.container.x <= 0 && GetChildAt(0).x > -this.container.x)//最后一页没填满! + return true; else return false; } @@ -2456,9 +2456,10 @@ namespace FairyGUI { float lineSize = 0; int lineStart = 0; - float ratio; + float remainSize; + float remainPercent; - for (i = 0; i < cnt; i++) + for (i = 0; i < cnt; i++) { child = GetChildAt(i); if (foldInvisibleItems && !child.visible) @@ -2468,7 +2469,8 @@ namespace FairyGUI j++; if (j == _columnCount || i == cnt - 1) { - ratio = (viewWidth - lineSize - (j - 1) * _columnGap) / lineSize; + remainSize = viewWidth - (j - 1) * _columnGap; + remainPercent = 1; curX = 0; for (j = lineStart; j <= i; j++) { @@ -2477,16 +2479,12 @@ namespace FairyGUI continue; child.SetPosition(curX, curY); + float perc = child.sourceWidth / lineSize; + child.SetSize((float)Math.Round(perc / remainPercent * remainSize), child.height, true); + remainSize -= child.width; + remainPercent -= perc; + curX += child.width + _columnGap; - if (j < i) - { - child.SetSize(child.sourceWidth + (float)Math.Round(child.sourceWidth * ratio), child.height, true); - curX += (int)Math.Ceiling(child.width) + _columnGap; - } - else - { - child.SetSize(viewWidth - curX, child.height, true); - } if (child.height > maxHeight) maxHeight = child.height; } @@ -2539,9 +2537,10 @@ namespace FairyGUI { float lineSize = 0; int lineStart = 0; - float ratio; + float remainSize; + float remainPercent; - for (i = 0; i < cnt; i++) + for (i = 0; i < cnt; i++) { child = GetChildAt(i); if (foldInvisibleItems && !child.visible) @@ -2551,8 +2550,9 @@ namespace FairyGUI j++; if (j == _lineCount || i == cnt - 1) { - ratio = (viewHeight - lineSize - (j - 1) * _lineGap) / lineSize; - curY = 0; + remainSize = viewHeight - (j - 1) * _lineGap; + remainPercent = 1; + curY = 0; for (j = lineStart; j <= i; j++) { child = GetChildAt(j); @@ -2561,15 +2561,12 @@ namespace FairyGUI child.SetPosition(curX, curY); - if (j < i) - { - child.SetSize(child.width, child.sourceHeight + (float)Math.Round(child.sourceHeight * ratio), true); - curY += (int)Math.Ceiling(child.height) + _lineGap; - } - else - { - child.SetSize(child.width, viewHeight - curY, true); - } + float perc = child.sourceHeight / lineSize; + child.SetSize(child.width, (float)Math.Round(perc / remainPercent * remainSize), true); + remainSize -= child.height; + remainPercent -= perc; + curY += child.height + _lineGap; + if (child.width > maxWidth) maxWidth = child.width; } @@ -2627,9 +2624,10 @@ namespace FairyGUI { float lineSize = 0; int lineStart = 0; - float ratio; + float remainSize; + float remainPercent; - for (i = 0; i < cnt; i++) + for (i = 0; i < cnt; i++) { child = GetChildAt(i); if (foldInvisibleItems && !child.visible) @@ -2648,8 +2646,9 @@ namespace FairyGUI j++; if (j == _columnCount || i == cnt - 1) { - ratio = (viewWidth - lineSize - (j - 1) * _columnGap) / lineSize; - curX = 0; + remainSize = viewWidth - (j - 1) * _columnGap; + remainPercent = 1; + curX = 0; for (j = lineStart; j <= i; j++) { child = GetChildAt(j); @@ -2658,16 +2657,12 @@ namespace FairyGUI child.SetPosition(page * viewWidth + curX, curY); - if (j < i) - { - child.SetSize(child.sourceWidth + (float)Math.Round(child.sourceWidth * ratio), - _lineCount > 0 ? eachHeight : child.height, true); - curX += (int)Math.Ceiling(child.width) + _columnGap; - } - else - { - child.SetSize(viewWidth - curX, _lineCount > 0 ? eachHeight : child.height, true); - } + float perc = child.sourceWidth / lineSize; + child.SetSize((float)Math.Round(perc / remainPercent * remainSize), _lineCount > 0 ? eachHeight : child.height, true); + remainSize -= child.width; + remainPercent -= perc; + curX += child.width + _columnGap; + if (child.height > maxHeight) maxHeight = child.height; } diff --git a/Engine/CLEngine.Core/gui/UI/GLoader.cs b/Engine/CLEngine.Core/gui/UI/GLoader.cs index adfd940..4e35f16 100644 --- a/Engine/CLEngine.Core/gui/UI/GLoader.cs +++ b/Engine/CLEngine.Core/gui/UI/GLoader.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using CLEngine.Core; using FairyGUI.Utils; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; @@ -9,647 +8,641 @@ using Rectangle = System.Drawing.RectangleF; namespace FairyGUI { - /// - /// GLoader class - /// - public class GLoader : GObject, IAnimationGear, IColorGear - { - /// - /// Display an error sign if the loader fails to load the content. - /// UIConfig.loaderErrorSign muse be set. - /// - public bool showErrorSign; - - string _url; - AlignType _align; - VertAlignType _verticalAlign; - bool _autoSize; - FillType _fill; - bool _shrinkOnly; - bool _updatingLayout; - PackageItem _contentItem; - float _contentWidth; - float _contentHeight; - float _contentSourceWidth; - float _contentSourceHeight; - - MovieClip _content; - GObject _errorSign; - GComponent _content2; - - static GObjectPool errorSignPool; - - public GLoader() - { - _url = string.Empty; - _align = AlignType.Left; - _verticalAlign = VertAlignType.Top; - showErrorSign = true; - } - - override protected void CreateDisplayObject() - { - displayObject = new Container(); - displayObject.gOwner = this; - _content = new MovieClip(); - ((Container)displayObject).AddChild(_content); - ((Container)displayObject).opaque = true; - } - - override public void Dispose() - { - if (_content.texture != null) - { - if (_contentItem == null) - FreeExternal(image.texture); - } - if (_errorSign != null) - _errorSign.Dispose(); - if (_content2 != null) - _content2.Dispose(); - _content.Dispose(); - base.Dispose(); - } - - /// - /// - /// - public string url - { - get { return _url; } - set - { - if (_url == value) - return; - - _url = value; - LoadContent(); - UpdateGear(7); - } - } - - override public string icon - { - get { return _url; } - set { this.url = value; } - } - - /// - /// - /// - public AlignType align - { - get { return _align; } - set - { - if (_align != value) - { - _align = value; - UpdateLayout(); - } - } - } - - /// - /// - /// - public VertAlignType verticalAlign - { - get { return _verticalAlign; } - set - { - if (_verticalAlign != value) - { - _verticalAlign = value; - UpdateLayout(); - } - } - } - - /// - /// - /// - public FillType fill - { - get { return _fill; } - set - { - if (_fill != value) - { - _fill = value; - UpdateLayout(); - } - } - } - - /// - /// - /// - public bool shrinkOnly - { - get { return _shrinkOnly; } - set - { - if (_shrinkOnly != value) - { - _shrinkOnly = value; - UpdateLayout(); - } - } - } - - /// - /// - /// - public bool autoSize - { - get { return _autoSize; } - set - { - if (_autoSize != value) - { - _autoSize = value; - UpdateLayout(); - } - } - } - - /// - /// - /// - public bool playing - { - get { return _content.playing; } - set - { - _content.playing = value; - UpdateGear(5); - } - } - - /// - /// - /// - public int frame - { - get { return _content.frame; } - set - { - _content.frame = value; - UpdateGear(5); - } - } - - /// - /// - /// - public float timeScale - { - get { return _content.timeScale; } - set { _content.timeScale = value; } - } - - /// - /// - /// - public bool ignoreEngineTimeScale - { - get { return _content.ignoreEngineTimeScale; } - set { _content.ignoreEngineTimeScale = value; } - } - - /// - /// - /// - /// - public void Advance(float time) - { - _content.Advance(time); - } - - /// - /// - /// - public Color color - { - get { return _content.color; } - set - { - _content.color = value; - UpdateGear(4); - } - } - - /// - /// - /// - public FillMethod fillMethod - { - get { return _content.fillMethod; } - set { _content.fillMethod = value; } - } - - /// - /// - /// - public int fillOrigin - { - get { return _content.fillOrigin; } - set { _content.fillOrigin = value; } - } - - /// - /// - /// - public bool fillClockwise - { - get { return _content.fillClockwise; } - set { _content.fillClockwise = value; } - } - - /// - /// - /// - public float fillAmount - { - get { return _content.fillAmount; } - set { _content.fillAmount = value; } - } - - /// - /// - /// - public Image image - { - get { return _content; } - } - - /// - /// - /// - public MovieClip movieClip - { - get { return _content; } - } - - /// - /// - /// - public GComponent component - { - get { return _content2; } - } - - /// - /// - /// - public NTexture texture - { - get - { - return _content.texture; - } - - set - { - this.url = null; - - _content.texture = value; - if (value != null) - { - _contentSourceWidth = value.width; - _contentSourceHeight = value.height; - } - else - { - _contentSourceWidth = _contentHeight = 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; } - } - - /// - /// - /// - 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.Load(); - - if (_contentItem.type == PackageItemType.Image) - { - _content.texture = _contentItem.texture; - _content.scale9Grid = _contentItem.scale9Grid; - _content.scaleByTile = _contentItem.scaleByTile; - _content.tileGridIndice = _contentItem.tileGridIndice; - - _contentSourceWidth = _contentItem.width; - _contentSourceHeight = _contentItem.height; - UpdateLayout(); - } - else if (_contentItem.type == PackageItemType.MovieClip) - { - _contentSourceWidth = _contentItem.width; - _contentSourceHeight = _contentItem.height; - - _content.interval = _contentItem.interval; - _content.swing = _contentItem.swing; - _content.repeatDelay = _contentItem.repeatDelay; - _content.frames = _contentItem.frames; - - UpdateLayout(); - } - else if (_contentItem.type == PackageItemType.Component) - { - _contentSourceWidth = _contentItem.width; - _contentSourceHeight = _contentItem.height; - - 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(); - } - } - else - SetErrorState(); - } - - virtual protected void LoadExternal() - { - try + /// + /// GLoader class + /// + public class GLoader : GObject, IAnimationGear, IColorGear + { + /// + /// Display an error sign if the loader fails to load the content. + /// UIConfig.loaderErrorSign muse be set. + /// + public bool showErrorSign; + + string _url; + AlignType _align; + VertAlignType _verticalAlign; + bool _autoSize; + FillType _fill; + bool _shrinkOnly; + bool _updatingLayout; + PackageItem _contentItem; + float _contentWidth; + float _contentHeight; + float _contentSourceWidth; + float _contentSourceHeight; + + MovieClip _content; + GObject _errorSign; + GComponent _content2; + + public GLoader() + { + _url = string.Empty; + _align = AlignType.Left; + _verticalAlign = VertAlignType.Top; + showErrorSign = true; + } + + override protected void CreateDisplayObject() + { + displayObject = new Container(); + displayObject.gOwner = this; + _content = new MovieClip(); + ((Container)displayObject).AddChild(_content); + ((Container)displayObject).opaque = true; + } + + override public void Dispose() + { + if (_content.texture != null) { - var localFile = Path.Combine(SceneManager.GameProject.ProjectPath, "Content", _url + ".png"); - var tex = TextureLoader.FromFile(localFile) ?? Stage.game.Content.Load(_url); + if (_contentItem == null) + FreeExternal(image.texture); + } + if (_errorSign != null) + _errorSign.Dispose(); + if (_content2 != null) + _content2.Dispose(); + _content.Dispose(); + base.Dispose(); + } + + /// + /// + /// + public string url + { + get { return _url; } + set + { + if (_url == value) + return; + + _url = value; + LoadContent(); + UpdateGear(7); + } + } + + override public string icon + { + get { return _url; } + set { this.url = value; } + } + + /// + /// + /// + public AlignType align + { + get { return _align; } + set + { + if (_align != value) + { + _align = value; + UpdateLayout(); + } + } + } + + /// + /// + /// + public VertAlignType verticalAlign + { + get { return _verticalAlign; } + set + { + if (_verticalAlign != value) + { + _verticalAlign = value; + UpdateLayout(); + } + } + } + + /// + /// + /// + public FillType fill + { + get { return _fill; } + set + { + if (_fill != value) + { + _fill = value; + UpdateLayout(); + } + } + } + + /// + /// + /// + public bool shrinkOnly + { + get { return _shrinkOnly; } + set + { + if (_shrinkOnly != value) + { + _shrinkOnly = value; + UpdateLayout(); + } + } + } + + /// + /// + /// + public bool autoSize + { + get { return _autoSize; } + set + { + if (_autoSize != value) + { + _autoSize = value; + UpdateLayout(); + } + } + } + + /// + /// + /// + public bool playing + { + get { return _content.playing; } + set + { + _content.playing = value; + UpdateGear(5); + } + } + + /// + /// + /// + public int frame + { + get { return _content.frame; } + set + { + _content.frame = value; + UpdateGear(5); + } + } + + /// + /// + /// + public float timeScale + { + get { return _content.timeScale; } + set { _content.timeScale = value; } + } + + /// + /// + /// + public bool ignoreEngineTimeScale + { + get { return _content.ignoreEngineTimeScale; } + set { _content.ignoreEngineTimeScale = value; } + } + + /// + /// + /// + /// + public void Advance(float time) + { + _content.Advance(time); + } + + /// + /// + /// + public Color color + { + get { return _content.color; } + set + { + _content.color = value; + UpdateGear(4); + } + } + + /// + /// + /// + public FillMethod fillMethod + { + get { return _content.fillMethod; } + set { _content.fillMethod = value; } + } + + /// + /// + /// + public int fillOrigin + { + get { return _content.fillOrigin; } + set { _content.fillOrigin = value; } + } + + /// + /// + /// + public bool fillClockwise + { + get { return _content.fillClockwise; } + set { _content.fillClockwise = value; } + } + + /// + /// + /// + public float fillAmount + { + get { return _content.fillAmount; } + set { _content.fillAmount = value; } + } + + /// + /// + /// + public Image image + { + get { return _content; } + } + + /// + /// + /// + public MovieClip movieClip + { + get { return _content; } + } + + /// + /// + /// + public GComponent component + { + get { return _content2; } + } + + /// + /// + /// + public NTexture texture + { + get + { + return _content.texture; + } + + set + { + this.url = null; + + _content.texture = value; + if (value != null) + { + _contentSourceWidth = value.width; + _contentSourceHeight = value.height; + } + else + { + _contentSourceWidth = _contentHeight = 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; } + } + + /// + /// + /// + 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.Load(); + + if (_contentItem.type == PackageItemType.Image) + { + _content.texture = _contentItem.texture; + _content.scale9Grid = _contentItem.scale9Grid; + _content.scaleByTile = _contentItem.scaleByTile; + _content.tileGridIndice = _contentItem.tileGridIndice; + + _contentSourceWidth = _contentItem.width; + _contentSourceHeight = _contentItem.height; + UpdateLayout(); + } + else if (_contentItem.type == PackageItemType.MovieClip) + { + _contentSourceWidth = _contentItem.width; + _contentSourceHeight = _contentItem.height; + + _content.interval = _contentItem.interval; + _content.swing = _contentItem.swing; + _content.repeatDelay = _contentItem.repeatDelay; + _content.frames = _contentItem.frames; + + UpdateLayout(); + } + else if (_contentItem.type == PackageItemType.Component) + { + _contentSourceWidth = _contentItem.width; + _contentSourceHeight = _contentItem.height; + + 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(); + + Log.Warning("Unsupported type of GLoader: " + _contentItem.type); + } + } + else + SetErrorState(); + } + + virtual protected void LoadExternal() + { + try + { + Texture2D tex = Stage.game.Content.Load(_url); _content.texture = new NTexture(tex); - } - catch (Exception e) - { - Log.Info("LoadExternal failed: " + e.Message); - } - } - - virtual protected void FreeExternal(NTexture texture) - { - } - - protected void onExternalLoadSuccess(NTexture texture) - { - _content.texture = texture; - _contentSourceWidth = texture.width; - _contentSourceHeight = texture.height; - _content.scale9Grid = null; - _content.scaleByTile = false; - UpdateLayout(); - } - - protected void onExternalLoadFailed() - { - SetErrorState(); - } - - private void SetErrorState() - { - if (!showErrorSign) - return; - - if (_errorSign == null) - { - if (UIConfig.loaderErrorSign != null) - { - if (errorSignPool == null) - errorSignPool = new GObjectPool(); - - _errorSign = errorSignPool.GetObject(UIConfig.loaderErrorSign); - } - else - return; - } - - if (_errorSign != null) - { - _errorSign.SetSize(this.width, this.height); - ((Container)displayObject).AddChild(_errorSign.displayObject); - } - } - - private void ClearErrorState() - { - if (_errorSign != null) - { - ((Container)displayObject).RemoveChild(_errorSign.displayObject); - errorSignPool.ReturnObject(_errorSign); - _errorSign = null; - } - } - - private void UpdateLayout() - { - if (_content2 == null && _content.texture == null && _content.frames == null) - { - if (_autoSize) - { - _updatingLayout = true; - this.SetSize(50, 30); - _updatingLayout = false; - } - return; - } - - _contentWidth = _contentSourceWidth; - _contentHeight = _contentSourceHeight; - - if (_autoSize) - { - _updatingLayout = true; - if (_contentWidth == 0) - _contentWidth = 50; - if (_contentHeight == 0) - _contentHeight = 30; - this.SetSize(_contentWidth, _contentHeight); - _updatingLayout = false; - - if (_width == _contentWidth && _height == _contentHeight) - { - if (_content2 != null) - { - _content2.SetPosition(0, 0); - _content2.SetScale(1, 1); - } - else - { - _content.SetPosition(0, 0); - _content.SetSize(_contentWidth, _contentHeight); - } - return; - } - //如果不相等,可能是由于大小限制造成的,要后续处理 - } - - float sx = 1, sy = 1; - if (_fill != FillType.None) - { - sx = this.width / _contentSourceWidth; - sy = this.height / _contentSourceHeight; - - 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 = (int)Math.Floor(_contentSourceWidth * sx); - _contentHeight = (int)Math.Floor(_contentSourceHeight * sy); - } - } - - if (_content2 != null) - _content2.SetScale(sx, sy); - else - _content.size = new Vector2(_contentWidth, _contentHeight); - - float nx; - float ny; - if (_align == AlignType.Center) - nx = (int)Math.Floor((this.width - _contentWidth) / 2); - else if (_align == AlignType.Right) - nx = (int)Math.Floor(this.width - _contentWidth); - else - nx = 0; - if (_verticalAlign == VertAlignType.Middle) - ny = (int)Math.Floor((this.height - _contentHeight) / 2); - else if (_verticalAlign == VertAlignType.Bottom) - ny = (int)Math.Floor(this.height - _contentHeight); - else - ny = 0; - if (_content2 != null) - _content2.SetPosition(nx, ny); - else - _content.SetPosition(nx, ny); - } - - private void ClearContent() - { - ClearErrorState(); - - if (_contentItem == null && _content.texture != null) - FreeExternal(image.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(); - } - } + } + catch (Exception e) + { + Log.Info("LoadExternal failed: " + e.Message); + } + } + + virtual protected void FreeExternal(NTexture texture) + { + } + + protected void onExternalLoadSuccess(NTexture texture) + { + _content.texture = texture; + _contentSourceWidth = texture.width; + _contentSourceHeight = texture.height; + _content.scale9Grid = null; + _content.scaleByTile = false; + UpdateLayout(); + } + + protected void onExternalLoadFailed() + { + SetErrorState(); + } + + private void SetErrorState() + { + if (!showErrorSign) + 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); + } + } + + private void ClearErrorState() + { + if (_errorSign != null && _errorSign.displayObject.parent != null) + ((Container)displayObject).RemoveChild(_errorSign.displayObject); + } + + private void UpdateLayout() + { + if (_content2 == null && _content.texture == null && _content.frames == null) + { + if (_autoSize) + { + _updatingLayout = true; + this.SetSize(50, 30); + _updatingLayout = false; + } + return; + } + + _contentWidth = _contentSourceWidth; + _contentHeight = _contentSourceHeight; + + if (_autoSize) + { + _updatingLayout = true; + if (_contentWidth == 0) + _contentWidth = 50; + if (_contentHeight == 0) + _contentHeight = 30; + this.SetSize(_contentWidth, _contentHeight); + _updatingLayout = false; + + if (_width == _contentWidth && _height == _contentHeight) + { + if (_content2 != null) + { + _content2.SetPosition(0, 0); + _content2.SetScale(1, 1); + } + else + { + _content.SetPosition(0, 0); + _content.SetSize(_contentWidth, _contentHeight); + } + return; + } + //如果不相等,可能是由于大小限制造成的,要后续处理 + } + + float sx = 1, sy = 1; + if (_fill != FillType.None) + { + sx = this.width / _contentSourceWidth; + sy = this.height / _contentSourceHeight; + + 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 = (int)Math.Floor(_contentSourceWidth * sx); + _contentHeight = (int)Math.Floor(_contentSourceHeight * sy); + } + } + + if (_content2 != null) + _content2.SetScale(sx, sy); + else + _content.size = new Vector2(_contentWidth, _contentHeight); + + float nx; + float ny; + if (_align == AlignType.Center) + nx = (int)Math.Floor((this.width - _contentWidth) / 2); + else if (_align == AlignType.Right) + nx = (int)Math.Floor(this.width - _contentWidth); + else + nx = 0; + if (_verticalAlign == VertAlignType.Middle) + ny = (int)Math.Floor((this.height - _contentHeight) / 2); + else if (_verticalAlign == VertAlignType.Bottom) + ny = (int)Math.Floor(this.height - _contentHeight); + else + ny = 0; + if (_content2 != null) + _content2.SetPosition(nx, ny); + else + _content.SetPosition(nx, ny); + } + + private void ClearContent() + { + ClearErrorState(); + + if (_content.texture != null) + { + if (_contentItem == null) + FreeExternal(image.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(); + } + } } diff --git a/Engine/CLEngine.Core/gui/UI/GObject.cs b/Engine/CLEngine.Core/gui/UI/GObject.cs index 25ddee4..1f11420 100644 --- a/Engine/CLEngine.Core/gui/UI/GObject.cs +++ b/Engine/CLEngine.Core/gui/UI/GObject.cs @@ -1530,7 +1530,14 @@ namespace FairyGUI RemoveFromParent(); RemoveEventListeners(); relations.Dispose(); - if (displayObject != null) + relations = null; + for (int i = 0; i < 8; i++) + { + GearBase gear = _gears[i]; + if (gear != null) + gear.Dispose(); + } + if (displayObject != null) { displayObject.gOwner = null; displayObject.Dispose(); diff --git a/Engine/CLEngine.Core/gui/UI/GProgressBar.cs b/Engine/CLEngine.Core/gui/UI/GProgressBar.cs index 757525d..b1d7319 100644 --- a/Engine/CLEngine.Core/gui/UI/GProgressBar.cs +++ b/Engine/CLEngine.Core/gui/UI/GProgressBar.cs @@ -23,7 +23,6 @@ namespace FairyGUI float _barMaxHeightDelta; float _barStartX; float _barStartY; - bool _tweening; public GProgressBar() { @@ -81,15 +80,10 @@ namespace FairyGUI } set { - if (_tweening) - { - GTween.Kill(this, TweenPropType.Progress, true); - _tweening = false; - } - if (_value != value) { - _value = value; + GTween.Kill(this, TweenPropType.Progress, false); + _value = value; Update(_value); } } @@ -109,9 +103,9 @@ namespace FairyGUI public GTweener TweenValue(double value, float duration) { double oldValule; - if (_tweening) - { - GTweener twener = GTween.GetTween(this, TweenPropType.Progress); + GTweener twener = GTween.GetTween(this, TweenPropType.Progress); + if (twener != null) + { oldValule = twener.value.d; twener.Kill(false); } @@ -119,12 +113,10 @@ namespace FairyGUI oldValule = _value; _value = value; - _tweening = true; return GTween.ToDouble(oldValule, _value, duration) .SetEase(EaseType.Linear) - .SetTarget(this, TweenPropType.Progress) - .OnComplete(() => { _tweening = false; }); + .SetTarget(this, TweenPropType.Progress); } /// @@ -270,12 +262,5 @@ namespace FairyGUI if (!this.underConstruct) Update(_value); } - - public override void Dispose() - { - if (_tweening) - GTween.Kill(this); - base.Dispose(); - } } } diff --git a/Engine/CLEngine.Core/gui/UI/Gears/GearBase.cs b/Engine/CLEngine.Core/gui/UI/Gears/GearBase.cs index 134e53b..97448ce 100644 --- a/Engine/CLEngine.Core/gui/UI/Gears/GearBase.cs +++ b/Engine/CLEngine.Core/gui/UI/Gears/GearBase.cs @@ -18,10 +18,19 @@ namespace FairyGUI _owner = owner; } - /// - /// Controller object. - /// - public Controller controller + public void Dispose() + { + if (_tweenConfig != null && _tweenConfig._tweener != null) + { + _tweenConfig._tweener.Kill(); + _tweenConfig._tweener = null; + } + } + + /// + /// Controller object. + /// + public Controller controller { get { diff --git a/Engine/CLEngine.Core/gui/UI/Transition.cs b/Engine/CLEngine.Core/gui/UI/Transition.cs index 02f012d..f32b004 100644 --- a/Engine/CLEngine.Core/gui/UI/Transition.cs +++ b/Engine/CLEngine.Core/gui/UI/Transition.cs @@ -403,7 +403,8 @@ namespace FairyGUI { int cnt = _items.Length; object value; - for (int i = 0; i < cnt; i++) + bool found = false; + for (int i = 0; i < cnt; i++) { TransitionItem item = _items[i]; if (item.label == label) @@ -412,11 +413,13 @@ namespace FairyGUI value = item.tweenConfig.startValue; else value = item.value; - } + found = true; + } else if (item.tweenConfig != null && item.tweenConfig.endLabel == label) { value = item.tweenConfig.endValue; - } + found = true; + } else continue; @@ -503,7 +506,10 @@ namespace FairyGUI break; } } - } + + if (!found) + throw new Exception("label not exists"); + } /// /// @@ -513,21 +519,27 @@ namespace FairyGUI public void SetHook(string label, TransitionHook callback) { int cnt = _items.Length; - for (int i = 0; i < cnt; i++) + bool found = false; + for (int i = 0; i < cnt; i++) { TransitionItem item = _items[i]; if (item.label == label) { item.hook = callback; - break; + found = true; + break; } else if (item.tweenConfig != null && item.tweenConfig.endLabel == label) { item.tweenConfig.endHook = callback; - break; + found = true; + break; } } - } + + if (!found) + throw new Exception("label not exists"); + } /// /// @@ -552,16 +564,29 @@ namespace FairyGUI public void SetTarget(string label, GObject newTarget) { int cnt = _items.Length; - for (int i = 0; i < cnt; i++) + bool found = false; + for (int i = 0; i < cnt; i++) { TransitionItem item = _items[i]; if (item.label == label) { - item.targetId = newTarget.id; - item.target = null; - } + item.targetId = (newTarget == _owner || newTarget == null) ? string.Empty : newTarget.id; + item.target = null; if (_playing) + { + if (item.targetId.Length > 0) + item.target = _owner.GetChildById(item.targetId); + else + item.target = _owner; + } + else + item.target = null; + found = true; + } } - } + + if (!found) + throw new Exception("label not exists"); + } /// /// @@ -571,13 +596,20 @@ namespace FairyGUI public void SetDuration(string label, float value) { int cnt = _items.Length; - for (int i = 0; i < cnt; i++) + bool found = false; + for (int i = 0; i < cnt; i++) { TransitionItem item = _items[i]; if (item.tweenConfig != null && item.label == label) - item.tweenConfig.duration = value; - } - } + { + item.tweenConfig.duration = value; item.tweenConfig.duration = value; + found = true; + } + } + + if (!found) + throw new Exception("label not exists or not a tween label"); + } /// /// diff --git a/Engine/CLEngine.Core/gui/UI/UIConfig.cs b/Engine/CLEngine.Core/gui/UI/UIConfig.cs index 734704b..02e9b21 100644 --- a/Engine/CLEngine.Core/gui/UI/UIConfig.cs +++ b/Engine/CLEngine.Core/gui/UI/UIConfig.cs @@ -150,5 +150,10 @@ namespace FairyGUI /// if RenderTexture using in paiting mode has depth support. /// public static bool depthSupportForPaintingMode = false; - } + + /// + /// + /// + public static VertAlignType richTextRowVerticalAlign = VertAlignType.Bottom; + } } diff --git a/Engine/CLEngine.Core/gui/Utils/Timers.cs b/Engine/CLEngine.Core/gui/Utils/Timers.cs index 899a950..49361cc 100644 --- a/Engine/CLEngine.Core/gui/Utils/Timers.cs +++ b/Engine/CLEngine.Core/gui/Utils/Timers.cs @@ -6,246 +6,252 @@ using Microsoft.Xna.Framework; namespace FairyGUI { - public delegate void TimerCallback(object param); - - /// - /// - /// - public class Timers - { - Dictionary _items; - Dictionary _toAdd; - List _toRemove; - List _pool; - - public static float time; - public static float deltaTime; - - private static Timers _inst; - public static Timers inst - { - get - { - if (_inst == null) - _inst = new Timers(); - return _inst; - } - } - - public Timers() - { - _inst = this; - - _items = new Dictionary(); - _toAdd = new Dictionary(); - _toRemove = new List(); - _pool = new List(100); - } - - public void Add(float interval, int repeat, TimerCallback callback) - { - Add(interval, repeat, callback, null); - } - - /** + public delegate void TimerCallback(object param); + + /// + /// + /// + public class Timers + { + public static bool catchCallbackExceptions = false; + + Dictionary _items; + Dictionary _toAdd; + List _toRemove; + List _pool; + + public static float time; + public static float deltaTime; + + private static Timers _inst; + public static Timers inst + { + get + { + if (_inst == null) + _inst = new Timers(); + return _inst; + } + } + + public Timers() + { + _inst = this; + + _items = new Dictionary(); + _toAdd = new Dictionary(); + _toRemove = new List(); + _pool = new List(100); + } + + public void Add(float interval, int repeat, TimerCallback callback) + { + Add(interval, repeat, callback, null); + } + + /** * @interval in seconds * @repeat 0 indicate loop infinitely, otherwise the run count **/ - public void Add(float interval, int repeat, TimerCallback callback, object callbackParam) - { - if (callback == null) - { - Log.Warning("timer callback is null, " + interval + "," + repeat); - return; - } - - Anymous_T t; - if (_items.TryGetValue(callback, out t)) - { - t.set(interval, repeat, callback, callbackParam); - t.elapsed = 0; - t.deleted = false; - return; - } - - if (_toAdd.TryGetValue(callback, out t)) - { - t.set(interval, repeat, callback, callbackParam); - return; - } - - t = GetFromPool(); - t.interval = interval; - t.repeat = repeat; - t.callback = callback; - t.param = callbackParam; - _toAdd[callback] = t; - } - - public void CallLater(TimerCallback callback) - { - Add(0.001f, 1, callback); - } - - public void CallLater(TimerCallback callback, object callbackParam) - { - Add(0.001f, 1, callback, callbackParam); - } - - public void AddUpdate(TimerCallback callback) - { - Add(0.001f, 0, callback); - } - - public void AddUpdate(TimerCallback callback, object callbackParam) - { - Add(0.001f, 0, callback, callbackParam); - } - - public bool Exists(TimerCallback callback) - { - if (_toAdd.ContainsKey(callback)) - return true; - - Anymous_T at; - if (_items.TryGetValue(callback, out at)) - return !at.deleted; - - return false; - } - - public void Remove(TimerCallback callback) - { - Anymous_T t; - if (_toAdd.TryGetValue(callback, out t)) - { - _toAdd.Remove(callback); - ReturnToPool(t); - } - - if (_items.TryGetValue(callback, out t)) - t.deleted = true; - } - - private Anymous_T GetFromPool() - { - Anymous_T t; - int cnt = _pool.Count; - if (cnt > 0) - { - t = _pool[cnt - 1]; - _pool.RemoveAt(cnt - 1); - t.deleted = false; - t.elapsed = 0; - } - else - t = new Anymous_T(); - return t; - } - - private void ReturnToPool(Anymous_T t) - { - t.callback = null; - _pool.Add(t); - } - - public void Update(GameTime gameTime) - { - time = (float)gameTime.TotalGameTime.TotalMilliseconds / 1000f; - deltaTime = (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000f; - - float elapsed = deltaTime; - - Dictionary.Enumerator iter; - - if (_items.Count > 0) - { - iter = _items.GetEnumerator(); - while (iter.MoveNext()) - { - Anymous_T i = iter.Current.Value; - if (i.deleted) - { - _toRemove.Add(i); - continue; - } - - i.elapsed += elapsed; - if (i.elapsed < i.interval) - continue; - - i.elapsed -= i.interval; - if (i.elapsed < 0 || i.elapsed > 0.03f) - i.elapsed = 0; - - if (i.repeat > 0) - { - i.repeat--; - if (i.repeat == 0) - { - i.deleted = true; - _toRemove.Add(i); - } - } - if (i.callback != null) - { - try - { - i.callback(i.param); - } - catch (System.Exception e) - { - i.deleted = true; - Log.Info("timer callback failed, " + i.interval + "," + i.repeat); - Log.Exception(e); - } - } - } - iter.Dispose(); - } - - int len = _toRemove.Count; - if (len > 0) - { - for (int k = 0; k < len; k++) - { - Anymous_T i = _toRemove[k]; - if (i.deleted && i.callback != null) - { - _items.Remove(i.callback); - ReturnToPool(i); - } - } - _toRemove.Clear(); - } - - if (_toAdd.Count > 0) - { - iter = _toAdd.GetEnumerator(); - while (iter.MoveNext()) - _items.Add(iter.Current.Key, iter.Current.Value); - iter.Dispose(); - _toAdd.Clear(); - } - } - } - - class Anymous_T - { - public float interval; - public int repeat; - public TimerCallback callback; - public object param; - - public float elapsed; - public bool deleted; - - public void set(float interval, int repeat, TimerCallback callback, object param) - { - this.interval = interval; - this.repeat = repeat; - this.callback = callback; - this.param = param; - } - } + public void Add(float interval, int repeat, TimerCallback callback, object callbackParam) + { + if (callback == null) + { + Log.Warning("timer callback is null, " + interval + "," + repeat); + return; + } + + Anymous_T t; + if (_items.TryGetValue(callback, out t)) + { + t.set(interval, repeat, callback, callbackParam); + t.elapsed = 0; + t.deleted = false; + return; + } + + if (_toAdd.TryGetValue(callback, out t)) + { + t.set(interval, repeat, callback, callbackParam); + return; + } + + t = GetFromPool(); + t.interval = interval; + t.repeat = repeat; + t.callback = callback; + t.param = callbackParam; + _toAdd[callback] = t; + } + + public void CallLater(TimerCallback callback) + { + Add(0.001f, 1, callback); + } + + public void CallLater(TimerCallback callback, object callbackParam) + { + Add(0.001f, 1, callback, callbackParam); + } + + public void AddUpdate(TimerCallback callback) + { + Add(0.001f, 0, callback); + } + + public void AddUpdate(TimerCallback callback, object callbackParam) + { + Add(0.001f, 0, callback, callbackParam); + } + + public bool Exists(TimerCallback callback) + { + if (_toAdd.ContainsKey(callback)) + return true; + + Anymous_T at; + if (_items.TryGetValue(callback, out at)) + return !at.deleted; + + return false; + } + + public void Remove(TimerCallback callback) + { + Anymous_T t; + if (_toAdd.TryGetValue(callback, out t)) + { + _toAdd.Remove(callback); + ReturnToPool(t); + } + + if (_items.TryGetValue(callback, out t)) + t.deleted = true; + } + + private Anymous_T GetFromPool() + { + Anymous_T t; + int cnt = _pool.Count; + if (cnt > 0) + { + t = _pool[cnt - 1]; + _pool.RemoveAt(cnt - 1); + t.deleted = false; + t.elapsed = 0; + } + else + t = new Anymous_T(); + return t; + } + + private void ReturnToPool(Anymous_T t) + { + t.callback = null; + _pool.Add(t); + } + + public void Update(GameTime gameTime) + { + time = (float)gameTime.TotalGameTime.TotalMilliseconds / 1000f; + deltaTime = (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000f; + + float elapsed = deltaTime; + + Dictionary.Enumerator iter; + + if (_items.Count > 0) + { + iter = _items.GetEnumerator(); + while (iter.MoveNext()) + { + Anymous_T i = iter.Current.Value; + if (i.deleted) + { + _toRemove.Add(i); + continue; + } + + i.elapsed += elapsed; + if (i.elapsed < i.interval) + continue; + + i.elapsed -= i.interval; + if (i.elapsed < 0 || i.elapsed > 0.03f) + i.elapsed = 0; + + if (i.repeat > 0) + { + i.repeat--; + if (i.repeat == 0) + { + i.deleted = true; + _toRemove.Add(i); + } + } + if (i.callback != null) + { + if (catchCallbackExceptions) + { + try + { + i.callback(i.param); + } + catch (System.Exception e) + { + i.deleted = true; + Log.Warning("FairyGUI: timer(internal=" + i.interval + ", repeat=" + i.repeat + ") callback error > " + e.Message); + } + } + else + i.callback(i.param); + } + } + iter.Dispose(); + } + + int len = _toRemove.Count; + if (len > 0) + { + for (int k = 0; k < len; k++) + { + Anymous_T i = _toRemove[k]; + if (i.deleted && i.callback != null) + { + _items.Remove(i.callback); + ReturnToPool(i); + } + } + _toRemove.Clear(); + } + + if (_toAdd.Count > 0) + { + iter = _toAdd.GetEnumerator(); + while (iter.MoveNext()) + _items.Add(iter.Current.Key, iter.Current.Value); + iter.Dispose(); + _toAdd.Clear(); + } + } + } + + class Anymous_T + { + public float interval; + public int repeat; + public TimerCallback callback; + public object param; + + public float elapsed; + public bool deleted; + + public void set(float interval, int repeat, TimerCallback callback, object param) + { + this.interval = interval; + this.repeat = repeat; + this.callback = callback; + this.param = param; + } + } } -- Gitee