diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2022-07-17 20:26:28 +0200 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2022-07-17 20:26:28 +0200 |
| commit | 9d786ab096ed36ea384e03ee5cea498790e31eec (patch) | |
| tree | adee54b5b90a35238d5794e9ffd3ebcf65798a06 /Samples | |
| parent | 57daad000aa31c7bcfa1f76b90d40da5a21da041 (diff) | |
wip
Diffstat (limited to 'Samples')
25 files changed, 1422 insertions, 14 deletions
diff --git a/Samples/AnimTest/AnimTest.csproj b/Samples/AnimTest/AnimTest.csproj new file mode 100644 index 00000000..178d4537 --- /dev/null +++ b/Samples/AnimTest/AnimTest.csproj @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>netcoreapp3.1</TargetFramework> + <OutputType>Exe</OutputType> + </PropertyGroup> + <ItemGroup> + <PackageReference Include="Crow" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Samples/AnimTest/Animation/AngleAnimation.cs b/Samples/AnimTest/Animation/AngleAnimation.cs new file mode 100644 index 00000000..02faef76 --- /dev/null +++ b/Samples/AnimTest/Animation/AngleAnimation.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2015-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using System; + +namespace vke +{ + public class AngleAnimation : FloatAnimation2 + { + #region CTOR + public AngleAnimation(Object instance, string PropertyName, float Target, int stepCount = 20) : + base (instance,PropertyName,MathHelper.NormalizeAngle(Target),stepCount) { + initialValue = MathHelper.NormalizeAngle (initialValue); + } + #endregion + } +} + diff --git a/Samples/AnimTest/Animation/Animation.cs b/Samples/AnimTest/Animation/Animation.cs new file mode 100644 index 00000000..6ca7af8c --- /dev/null +++ b/Samples/AnimTest/Animation/Animation.cs @@ -0,0 +1,155 @@ +// Copyright (c) 2015-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Diagnostics; + +namespace vke +{ + public delegate void AnimationEventHandler(Animation a); + + public delegate float GetterDelegate(); + public delegate void SetterDelegate(float value); + + public class Animation + { + public event AnimationEventHandler AnimationFinished; + + public static Random random = new Random (); + public static int DelayMs = 0; + + protected GetterDelegate getValue; + protected SetterDelegate setValue; + + public string propertyName; + + protected Stopwatch timer = new Stopwatch(); + protected int delayStartMs = 0; + /// <summary> + /// Delay before firing ZnimationFinished event. + /// </summary> + protected int delayFinishMs = 0; + public static List<Animation> AnimationList = new List<Animation>(); + public static bool HasAnimations => AnimationList.Count > 0; + //public FieldInfo member; + public Object AnimatedInstance; + + #region CTOR + public Animation (){} + public Animation(Object instance, string _propertyName) + { + propertyName = _propertyName; + AnimatedInstance = instance; + PropertyInfo pi = instance.GetType().GetProperty(propertyName); + try { + getValue = (GetterDelegate)Delegate.CreateDelegate(typeof(GetterDelegate), instance, pi.GetGetMethod()); + setValue = (SetterDelegate)Delegate.CreateDelegate(typeof(SetterDelegate), instance, pi.GetSetMethod()); + } catch (Exception ex) { + Debug.WriteLine (ex.ToString ()); + } + } + #endregion + + public static void StartAnimation(Animation a, int delayMs = 0, AnimationEventHandler OnEnd = null) + { + lock (AnimationList) { + Animation aa = null; + if (Animation.GetAnimation (a.AnimatedInstance, a.propertyName, ref aa)) { + aa.CancelAnimation (); + } + + //a.AnimationFinished += onAnimationFinished; + + a.AnimationFinished += OnEnd; + a.delayStartMs = delayMs + DelayMs; + + + if (a.delayStartMs > 0) + a.timer.Start (); + + AnimationList.Add (a); + } + + } + + static Stack<Animation> anims = new Stack<Animation>(); + static int frame = 0; + public static void ProcessAnimations() + { + frame++; + +// #region FLYING anim +// if (frame % 20 == 0){ +// foreach (Player p in MagicEngine.CurrentEngine.Players) { +// foreach (CardInstance c in p.InPlay.Cards.Where(ci => ci.HasAbility(AbilityEnum.Flying) && ci.z < 0.4f)) { +// +// } +// } +// } +// #endregion + //Stopwatch animationTime = new Stopwatch(); + //animationTime.Start(); + + const int maxAnim = 200000; + int count = 0; + + + lock (AnimationList) { + if (anims.Count == 0) + anims = new Stack<Animation> (AnimationList); + } + + while (anims.Count > 0 && count < maxAnim) { + Animation a = anims.Pop (); + if (a == null) + continue; + if (a.timer.IsRunning) { + if (a.timer.ElapsedMilliseconds > a.delayStartMs) + a.timer.Stop (); + else + continue; + } + + a.Process (); + count++; + } + + //animationTime.Stop(); + //Debug.WriteLine("animation: {0} ticks \t {1} ms ", animationTime.ElapsedTicks,animationTime.ElapsedMilliseconds); + } + public static bool GetAnimation(object instance, string PropertyName, ref Animation a) + { + for (int i = 0; i < AnimationList.Count; i++) { + Animation anim = AnimationList [i]; + if (anim == null) { + continue; + } + if (anim.AnimatedInstance == instance && anim.propertyName == PropertyName) { + a = anim; + return true; + } + } + + return false; + } + public virtual void Process () {} + public void CancelAnimation() + { + //Debug.WriteLine("Cancel anim: " + this.ToString()); + AnimationList.Remove(this); + } + public void RaiseAnimationFinishedEvent() + { + if (AnimationFinished != null) + AnimationFinished (this); + } + + public static void onAnimationFinished(Animation a) + { + Debug.WriteLine ("\t\tAnimation finished: " + a.ToString ()); + } + } +} diff --git a/Samples/AnimTest/Animation/AnimationTemplate.cs b/Samples/AnimTest/Animation/AnimationTemplate.cs new file mode 100644 index 00000000..d5c784c3 --- /dev/null +++ b/Samples/AnimTest/Animation/AnimationTemplate.cs @@ -0,0 +1,110 @@ +// Copyright (c) 2015-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using System; +using MiscUtil; +using System.Reflection; + +namespace vke +{ + public class Animation<T> : Animation + { + public delegate T GetterDelegate(); + public delegate void SetterDelegate(T value); + + public T TargetValue; + T initialValue; + T zero; + public T Step; + public bool Cycle; + + protected GetterDelegate getValue; + protected SetterDelegate setValue; + + #region CTOR + public Animation(Object instance, string _propertyName) + { + propertyName = _propertyName; + AnimatedInstance = instance; + PropertyInfo pi = instance.GetType().GetProperty(propertyName); + getValue = (GetterDelegate)Delegate.CreateDelegate(typeof(GetterDelegate), instance, pi.GetGetMethod()); + setValue = (SetterDelegate)Delegate.CreateDelegate(typeof(SetterDelegate), instance, pi.GetSetMethod()); + } + public Animation(Object instance, string _propertyName, T Target, T step) + { + propertyName = _propertyName; + AnimatedInstance = instance; + PropertyInfo pi = instance.GetType().GetProperty(propertyName); + getValue = (GetterDelegate)Delegate.CreateDelegate(typeof(GetterDelegate), instance, pi.GetGetMethod()); + setValue = (SetterDelegate)Delegate.CreateDelegate(typeof(SetterDelegate), instance, pi.GetSetMethod()); + + TargetValue = Target; + + T value = getValue(); + initialValue = value; + Type t = typeof(T); + + if (t.IsPrimitive) { + Step = (T)Convert.ChangeType (step, t); + zero = (T)Convert.ChangeType (0, t); + }else { + Step = (T)Activator.CreateInstance (typeof(T), new Object[] { step }); + zero = (T)Activator.CreateInstance (typeof(T), 0f); + } + T test = (T)Operator.SubtractAlternative (value, TargetValue); + + if (Operator.LessThan(test, zero)) + { + if (Operator.LessThan (Step, zero)) + Step = Operator.Negate (Step); + } + else if (Operator.GreaterThan(Step, zero)) + Step = Operator.Negate (Step); + } + #endregion + + public override void Process() + { + T value = getValue(); + + //Debug.WriteLine ("Anim: {0} <= {1}", value, this.ToString ()); + + if (Operator.GreaterThan(Step, zero)) + { + value = Operator.Add (value, Step); + setValue(value); + //Debug.WriteLine(value); + if (Operator.GreaterThan(Operator.Subtract(TargetValue, value), zero)) + return; + } + else + { + value = Operator.Add (value, Step); + setValue(value); + + if (Operator.LessThan(Operator.Subtract(TargetValue, value), zero)) + return; + } + + if (Cycle) { + Step = Operator.Negate (Step); + TargetValue = initialValue; + Cycle = false; + return; + } + + setValue(TargetValue); + AnimationList.Remove(this); + + RaiseAnimationFinishedEvent (); + } + + public override string ToString () + { + return string.Format ("{0}:->{1}:{2}",base.ToString(),TargetValue,Step); + } + } + +} + diff --git a/Samples/AnimTest/Animation/BezierPath.cs b/Samples/AnimTest/Animation/BezierPath.cs new file mode 100644 index 00000000..a3126e3e --- /dev/null +++ b/Samples/AnimTest/Animation/BezierPath.cs @@ -0,0 +1,34 @@ +// Copyright (c) 2015-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using System; +using System.Numerics; + +namespace vke +{ + public class BezierPath : Path + { + public Vector3 ControlPointStart; + public Vector3 ControlPointEnd; + + public BezierPath (Vector3 startPos, Vector3 controlPointStart, + Vector3 controlPointEnd, Vector3 endPos) + :base(startPos, endPos) + { + ControlPointStart = controlPointStart; + ControlPointEnd = controlPointEnd; + } + public BezierPath (Vector3 startPos, Vector3 endPos, Vector3 vUp) + :base(startPos, endPos) + { + ControlPointStart = startPos + vUp; + ControlPointEnd = endPos + vUp; + } + public override Vector3 GetStep (float pos) + { + return Path.CalculateBezierPoint (pos, Start, ControlPointStart, ControlPointEnd, End); + } + } +} + diff --git a/Samples/AnimTest/Animation/FloatAnimation.cs b/Samples/AnimTest/Animation/FloatAnimation.cs new file mode 100644 index 00000000..a7e4bf7c --- /dev/null +++ b/Samples/AnimTest/Animation/FloatAnimation.cs @@ -0,0 +1,83 @@ +// Copyright (c) 2015-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using System; + +namespace vke +{ + public class FloatAnimation : Animation + { + + public float TargetValue; + float initialValue; + public float Step; + public bool Cycle; + + #region CTOR + public FloatAnimation(Object instance, string _propertyName, float Target, float step = 0.2f) + : base(instance, _propertyName) + { + + TargetValue = Target; + + float value = getValue(); + initialValue = value; + + Step = step; + + if (value < TargetValue) + { + if (Step < 0) + Step = -Step; + } + else if (Step > 0) + Step = -Step; + } + #endregion + + public override void Process() + { + float value = getValue(); + + //Debug.WriteLine ("Anim: {0} <= {1}", value, this.ToString ()); + + if (Step > 0f) + { + value += Step; + setValue(value); + //Debug.WriteLine(value); + if (TargetValue > value) + return; + } + else + { + value += Step; + setValue(value); + + if (TargetValue < value) + return; + } + + if (Cycle) { + Step = -Step; + TargetValue = initialValue; + Cycle = false; + return; + } + + setValue(TargetValue); + lock(AnimationList) + AnimationList.Remove(this); + + RaiseAnimationFinishedEvent (); + } + + public override string ToString () + { + return string.Format ("{0}:->{1}:{2}",base.ToString(),TargetValue,Step); + } + } + +} + diff --git a/Samples/AnimTest/Animation/FloatAnimation2.cs b/Samples/AnimTest/Animation/FloatAnimation2.cs new file mode 100644 index 00000000..1d5c9193 --- /dev/null +++ b/Samples/AnimTest/Animation/FloatAnimation2.cs @@ -0,0 +1,60 @@ +// Copyright (c) 2015-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using System; + +namespace vke +{ + public class FloatAnimation2 : Animation + { + + public float TargetValue; + protected float initialValue; + int stepCount, currentStep; + + #region CTOR + public FloatAnimation2(Object instance, string _propertyName, float Target, int _stepCount = 20) + : base(instance, _propertyName) + { + + TargetValue = Target; + + float value = getValue(); + initialValue = value; + + stepCount = _stepCount; + } + #endregion + + bool smooth = true; + + float smoothedStep (float step) => (-MathF.Cos (step * MathF.PI) + 1)/2.0f; + + public override void Process() + { + + currentStep++; + + float t = (float)currentStep / (float)stepCount; + if (smooth) + t = smoothedStep (t); + + setValue (initialValue + t * (TargetValue - initialValue)); + + if (currentStep < stepCount) + return; + + setValue(TargetValue); + AnimationList.Remove(this); + RaiseAnimationFinishedEvent (); + } + + public override string ToString () + { + return string.Format ("{0}:->{1}:{2}",base.ToString(),TargetValue,stepCount); + } + } + +} + diff --git a/Samples/AnimTest/Animation/MathHelper.cs b/Samples/AnimTest/Animation/MathHelper.cs new file mode 100644 index 00000000..35a3009f --- /dev/null +++ b/Samples/AnimTest/Animation/MathHelper.cs @@ -0,0 +1,16 @@ +// Copyright (c) 2019-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +using System; +namespace vke { + public static class MathHelper { + public const float Pi = (float)Math.PI; + public const float TwoPi = (float)Math.PI * 2; + public static float NormalizeAngle (float a) { + float tmp = a % MathHelper.TwoPi; + if (tmp < 0) + tmp += MathHelper.TwoPi; + return tmp; + } + } +} diff --git a/Samples/AnimTest/Animation/Path.cs b/Samples/AnimTest/Animation/Path.cs new file mode 100644 index 00000000..1f04e090 --- /dev/null +++ b/Samples/AnimTest/Animation/Path.cs @@ -0,0 +1,51 @@ +// Copyright (c) 2015-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +using System.Numerics; + +namespace vke { + public class Path + { + public Vector3 Start; + public Vector3 End; + + float length; + Vector3 vDir; + + public Path(Vector3 startPos, Vector3 endPos){ + Start = startPos; + End = endPos; + initialComputations (); + } + protected void initialComputations(){ + Vector3 vPath = End - Start; + vDir = Vector3.Normalize (vPath); + length = vPath.Length(); + } + /// <summary> + /// Get single step on the path + /// </summary> + /// <returns>return position on the path</returns> + /// <param name="pos">Position expressed as percentage of total length</param> + public virtual Vector3 GetStep(float pos){ + return Start + vDir * length * pos; + } + + public static Vector3 CalculateBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3) + { + float u = 1 - t; + float tt = t * t; + float uu = u * u; + float uuu = uu * u; + float ttt = tt * t; + + Vector3 p = uuu * p0; + p += 3 * uu * t * p1; + p += 3 * u * tt * p2; + p += ttt * p3; + + return p; + } + } + +} diff --git a/Samples/AnimTest/Animation/PathAnimation.cs b/Samples/AnimTest/Animation/PathAnimation.cs new file mode 100644 index 00000000..54c30e9a --- /dev/null +++ b/Samples/AnimTest/Animation/PathAnimation.cs @@ -0,0 +1,53 @@ +// Copyright (c) 2015-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using System; +using System.Numerics; + +namespace vke +{ + public class PathAnimation : Animation<Vector3> + { + Path path; + int stepCount, currentStep; + + #region CTOR + public PathAnimation(Object instance, string _propertyName, Path _path, int _stepCount = 20) + : base(instance, _propertyName) + { + path = _path; + stepCount = _stepCount; + } + + #endregion + + bool smooth = true; + + float smoothedStep (float step) => (-MathF.Cos (step * MathF.PI) + 1)/2.0f; + + public override void Process() + { + currentStep++; + + float t = (float)currentStep / (float)stepCount; + if (smooth) + t = smoothedStep (t); + + Vector3 pos = path.GetStep (t); + setValue(pos); + + if (currentStep < stepCount) + return; + + AnimationList.Remove(this); + RaiseAnimationFinishedEvent (); + } + + public override string ToString () + { + return string.Format ("{0}:->{1}:{2}",base.ToString(),TargetValue,Step); + } + } +} + diff --git a/Samples/AnimTest/Animation/ShakeAnimation.cs b/Samples/AnimTest/Animation/ShakeAnimation.cs new file mode 100644 index 00000000..37a089bd --- /dev/null +++ b/Samples/AnimTest/Animation/ShakeAnimation.cs @@ -0,0 +1,60 @@ +// Copyright (c) 2015-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using System; + +namespace vke +{ + public class ShakeAnimation : Animation + { + const float stepMin = 0.001f, stepMax = 0.005f; + bool rising = true; + + public float LowBound; + public float HighBound; + + #region CTOR + public ShakeAnimation( + Object instance, + string _propertyName, + float lowBound, float highBound) + : base(instance, _propertyName) + { + + LowBound = Math.Min (lowBound, highBound); + HighBound = Math.Max (lowBound, highBound); + + float value = getValue (); + + if (value > HighBound) + rising = false; + } + #endregion + + public override void Process () + { + float value = getValue (); + float step = stepMin + (float)random.NextDouble () * stepMax; + + if (rising) { + value += step; + if (value > HighBound) { + value = HighBound; + rising = false; + } + } else { + value -= step; + if (value < LowBound) { + value = LowBound; + rising = true; + } else if (value > HighBound) + value -= step * 10f; + } + setValue (value); + } + + } + +} + diff --git a/Samples/AnimTest/MiscUtil/ExpressionUtil.cs b/Samples/AnimTest/MiscUtil/ExpressionUtil.cs new file mode 100644 index 00000000..8f9ca4e6 --- /dev/null +++ b/Samples/AnimTest/MiscUtil/ExpressionUtil.cs @@ -0,0 +1,99 @@ +using System; +using System.Linq.Expressions; + +namespace MiscUtil.Linq +{ + /// <summary> + /// General purpose Expression utilities + /// </summary> + public static class ExpressionUtil + { + /// <summary> + /// Create a function delegate representing a unary operation + /// </summary> + /// <typeparam name="TArg1">The parameter type</typeparam> + /// <typeparam name="TResult">The return type</typeparam> + /// <param name="body">Body factory</param> + /// <returns>Compiled function delegate</returns> + public static Func<TArg1, TResult> CreateExpression<TArg1, TResult>( + Func<Expression, UnaryExpression> body) + { + ParameterExpression inp = Expression.Parameter(typeof(TArg1), "inp"); + try + { + return Expression.Lambda<Func<TArg1, TResult>>(body(inp), inp).Compile(); + } + catch (Exception ex) + { + string msg = ex.Message; // avoid capture of ex itself + return delegate { throw new InvalidOperationException(msg); }; + } + } + + /// <summary> + /// Create a function delegate representing a binary operation + /// </summary> + /// <typeparam name="TArg1">The first parameter type</typeparam> + /// <typeparam name="TArg2">The second parameter type</typeparam> + /// <typeparam name="TResult">The return type</typeparam> + /// <param name="body">Body factory</param> + /// <returns>Compiled function delegate</returns> + public static Func<TArg1, TArg2, TResult> CreateExpression<TArg1, TArg2, TResult>( + Func<Expression, Expression, BinaryExpression> body) + { + return CreateExpression<TArg1, TArg2, TResult>(body, false); + } + + /// <summary> + /// Create a function delegate representing a binary operation + /// </summary> + /// <param name="castArgsToResultOnFailure"> + /// If no matching operation is possible, attempt to convert + /// TArg1 and TArg2 to TResult for a match? For example, there is no + /// "decimal operator /(decimal, int)", but by converting TArg2 (int) to + /// TResult (decimal) a match is found. + /// </param> + /// <typeparam name="TArg1">The first parameter type</typeparam> + /// <typeparam name="TArg2">The second parameter type</typeparam> + /// <typeparam name="TResult">The return type</typeparam> + /// <param name="body">Body factory</param> + /// <returns>Compiled function delegate</returns> + public static Func<TArg1, TArg2, TResult> CreateExpression<TArg1, TArg2, TResult>( + Func<Expression, Expression, BinaryExpression> body, bool castArgsToResultOnFailure) + { + ParameterExpression lhs = Expression.Parameter(typeof(TArg1), "lhs"); + ParameterExpression rhs = Expression.Parameter(typeof(TArg2), "rhs"); + try + { + try + { + return Expression.Lambda<Func<TArg1, TArg2, TResult>>(body(lhs, rhs), lhs, rhs).Compile(); + } + catch (InvalidOperationException) + { + if (castArgsToResultOnFailure && !( // if we show retry + typeof(TArg1) == typeof(TResult) && // and the args aren't + typeof(TArg2) == typeof(TResult))) + { // already "TValue, TValue, TValue"... + // convert both lhs and rhs to TResult (as appropriate) + Expression castLhs = typeof(TArg1) == typeof(TResult) ? + (Expression)lhs : + (Expression)Expression.Convert(lhs, typeof(TResult)); + Expression castRhs = typeof(TArg2) == typeof(TResult) ? + (Expression)rhs : + (Expression)Expression.Convert(rhs, typeof(TResult)); + + return Expression.Lambda<Func<TArg1, TArg2, TResult>>( + body(castLhs, castRhs), lhs, rhs).Compile(); + } + else throw; + } + } + catch (Exception ex) + { + string msg = ex.Message; // avoid capture of ex itself + return delegate { throw new InvalidOperationException(msg); }; + } + } + } +}
\ No newline at end of file diff --git a/Samples/AnimTest/MiscUtil/NullOp.cs b/Samples/AnimTest/MiscUtil/NullOp.cs new file mode 100644 index 00000000..7bb8790a --- /dev/null +++ b/Samples/AnimTest/MiscUtil/NullOp.cs @@ -0,0 +1,59 @@ + +namespace MiscUtil +{ + interface INullOp<T> + { + bool HasValue(T value); + bool AddIfNotNull(ref T accumulator, T value); + } + sealed class StructNullOp<T> + : INullOp<T>, INullOp<T?> + where T : struct + { + public bool HasValue(T value) + { + return true; + } + public bool AddIfNotNull(ref T accumulator, T value) + { + accumulator = Operator<T>.Add(accumulator, value); + return true; + } + public bool HasValue(T? value) + { + return value.HasValue; + } + public bool AddIfNotNull(ref T? accumulator, T? value) + { + if (value.HasValue) + { + accumulator = accumulator.HasValue ? + Operator<T>.Add( + accumulator.GetValueOrDefault(), + value.GetValueOrDefault()) + : value; + return true; + } + return false; + } + } + sealed class ClassNullOp<T> + : INullOp<T> + where T : class + { + public bool HasValue(T value) + { + return value != null; + } + public bool AddIfNotNull(ref T accumulator, T value) + { + if (value != null) + { + accumulator = accumulator == null ? + value : Operator<T>.Add(accumulator, value); + return true; + } + return false; + } + } +}
\ No newline at end of file diff --git a/Samples/AnimTest/MiscUtil/Operator.cs b/Samples/AnimTest/MiscUtil/Operator.cs new file mode 100644 index 00000000..ee1168cf --- /dev/null +++ b/Samples/AnimTest/MiscUtil/Operator.cs @@ -0,0 +1,449 @@ +using System; +using System.Linq.Expressions; +using MiscUtil.Linq; + +namespace MiscUtil +{ + /// <summary> + /// The Operator class provides easy access to the standard operators + /// (addition, etc) for generic types, using type inference to simplify + /// usage. + /// </summary> + public static class Operator + { + + /// <summary> + /// Indicates if the supplied value is non-null, + /// for reference-types or Nullable<T> + /// </summary> + /// <returns>True for non-null values, else false</returns> + public static bool HasValue<T>(T value) + { + return Operator<T>.NullOp.HasValue(value); + } + /// <summary> + /// Increments the accumulator only + /// if the value is non-null. If the accumulator + /// is null, then the accumulator is given the new + /// value; otherwise the accumulator and value + /// are added. + /// </summary> + /// <param name="accumulator">The current total to be incremented (can be null)</param> + /// <param name="value">The value to be tested and added to the accumulator</param> + /// <returns>True if the value is non-null, else false - i.e. + /// "has the accumulator been updated?"</returns> + public static bool AddIfNotNull<T>(ref T accumulator, T value) + { + return Operator<T>.NullOp.AddIfNotNull(ref accumulator, value); + } + + /// <summary> + /// Evaluates unary negation (-) for the given type; this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static T Negate<T>(T value) + { + return Operator<T>.Negate(value); + } + /// <summary> + /// Evaluates bitwise not (~) for the given type; this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static T Not<T>(T value) + { + return Operator<T>.Not(value); + } + /// <summary> + /// Evaluates bitwise or (|) for the given type; this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static T Or<T>(T value1, T value2) + { + return Operator<T>.Or(value1, value2); + } + /// <summary> + /// Evaluates bitwise and (&) for the given type; this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static T And<T>(T value1, T value2) + { + return Operator<T>.And(value1, value2); + } + /// <summary> + /// Evaluates bitwise xor (^) for the given type; this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static T Xor<T>(T value1, T value2) + { + return Operator<T>.Xor(value1, value2); + } + /// <summary> + /// Performs a conversion between the given types; this will throw + /// an InvalidOperationException if the type T does not provide a suitable cast, or for + /// Nullable<TInner> if TInner does not provide this cast. + /// </summary> + public static TTo Convert<TFrom, TTo>(TFrom value) + { + return Operator<TFrom, TTo>.Convert(value); + } + /// <summary> + /// Evaluates binary addition (+) for the given type; this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static T Add<T>(T value1, T value2) + { + return Operator<T>.Add(value1, value2); + } + /// <summary> + /// Evaluates binary addition (+) for the given type(s); this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static TArg1 AddAlternative<TArg1, TArg2>(TArg1 value1, TArg2 value2) + { + return Operator<TArg2, TArg1>.Add(value1, value2); + } + /// <summary> + /// Evaluates binary subtraction (-) for the given type; this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static T Subtract<T>(T value1, T value2) + { + return Operator<T>.Subtract(value1, value2); + } + /// <summary> + /// Evaluates binary subtraction(-) for the given type(s); this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static TArg1 SubtractAlternative<TArg1, TArg2>(TArg1 value1, TArg2 value2) + { + return Operator<TArg2, TArg1>.Subtract(value1, value2); + } + /// <summary> + /// Evaluates binary multiplication (*) for the given type; this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static T Multiply<T>(T value1, T value2) + { + return Operator<T>.Multiply(value1, value2); + } + /// <summary> + /// Evaluates binary multiplication (*) for the given type(s); this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static TArg1 MultiplyAlternative<TArg1, TArg2>(TArg1 value1, TArg2 value2) + { + return Operator<TArg2, TArg1>.Multiply(value1, value2); + } + /// <summary> + /// Evaluates binary division (/) for the given type; this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static T Divide<T>(T value1, T value2) + { + return Operator<T>.Divide(value1, value2); + } + /// <summary> + /// Evaluates binary division (/) for the given type(s); this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static TArg1 DivideAlternative<TArg1, TArg2>(TArg1 value1, TArg2 value2) + { + return Operator<TArg2, TArg1>.Divide(value1, value2); + } + /// <summary> + /// Evaluates binary equality (==) for the given type; this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static bool Equal<T>(T value1, T value2) + { + return Operator<T>.Equal(value1, value2); + } + /// <summary> + /// Evaluates binary inequality (!=) for the given type; this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static bool NotEqual<T>(T value1, T value2) + { + return Operator<T>.NotEqual(value1, value2); + } + /// <summary> + /// Evaluates binary greater-than (>) for the given type; this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static bool GreaterThan<T>(T value1, T value2) + { + return Operator<T>.GreaterThan(value1, value2); + } + /// <summary> + /// Evaluates binary less-than (<) for the given type; this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static bool LessThan<T>(T value1, T value2) + { + return Operator<T>.LessThan(value1, value2); + } + /// <summary> + /// Evaluates binary greater-than-on-eqauls (>=) for the given type; this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static bool GreaterThanOrEqual<T>(T value1, T value2) + { + return Operator<T>.GreaterThanOrEqual(value1, value2); + } + /// <summary> + /// Evaluates binary less-than-or-equal (<=) for the given type; this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static bool LessThanOrEqual<T>(T value1, T value2) + { + return Operator<T>.LessThanOrEqual(value1, value2); + } + /// <summary> + /// Evaluates integer division (/) for the given type; this will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary><remarks> + /// This operation is particularly useful for computing averages and + /// similar aggregates. + /// </remarks> + public static T DivideInt32<T>(T value, int divisor) + { + return Operator<int,T>.Divide(value, divisor); + } + public static T Max<T>(T v1, T v2) + { + return Operator.GreaterThanOrEqual (v1, v2) ? v1 : v2; + } + public static T Min<T>(T v1, T v2) + { + return Operator.LessThanOrEqual (v1, v2) ? v1 : v2; + } + } + /// <summary> + /// Provides standard operators (such as addition) that operate over operands of + /// different types. For operators, the return type is assumed to match the first + /// operand. + /// </summary> + /// <seealso cref="Operator<T>"/> + /// <seealso cref="Operator"/> + public static class Operator<TValue, TResult> + { + private static readonly Func<TValue, TResult> convert; + /// <summary> + /// Returns a delegate to convert a value between two types; this delegate will throw + /// an InvalidOperationException if the type T does not provide a suitable cast, or for + /// Nullable<TInner> if TInner does not provide this cast. + /// </summary> + public static Func<TValue, TResult> Convert { get { return convert; } } + static Operator() + { + convert = ExpressionUtil.CreateExpression<TValue, TResult>(body => Expression.Convert(body, typeof(TResult))); + add = ExpressionUtil.CreateExpression<TResult, TValue, TResult>(Expression.Add, true); + subtract = ExpressionUtil.CreateExpression<TResult, TValue, TResult>(Expression.Subtract, true); + multiply = ExpressionUtil.CreateExpression<TResult, TValue, TResult>(Expression.Multiply, true); + divide = ExpressionUtil.CreateExpression<TResult, TValue, TResult>(Expression.Divide, true); + } + + private static readonly Func<TResult, TValue, TResult> add, subtract, multiply, divide; + /// <summary> + /// Returns a delegate to evaluate binary addition (+) for the given types; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<TResult, TValue, TResult> Add { get { return add; } } + /// <summary> + /// Returns a delegate to evaluate binary subtraction (-) for the given types; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<TResult, TValue, TResult> Subtract { get { return subtract; } } + /// <summary> + /// Returns a delegate to evaluate binary multiplication (*) for the given types; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<TResult, TValue, TResult> Multiply { get { return multiply; } } + /// <summary> + /// Returns a delegate to evaluate binary division (/) for the given types; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<TResult, TValue, TResult> Divide { get { return divide; } } + } + + /// <summary> + /// Provides standard operators (such as addition) over a single type + /// </summary> + /// <seealso cref="Operator"/> + /// <seealso cref="Operator<TValue,TResult>"/> + public static class Operator<T> + { + static readonly INullOp<T> nullOp; + internal static INullOp<T> NullOp { get { return nullOp; } } + + static readonly T zero; + /// <summary> + /// Returns the zero value for value-types (even full Nullable<TInner>) - or null for reference types + /// </summary> + public static T Zero { get { return zero;} } + + static readonly Func<T, T> negate, not; + static readonly Func<T, T, T> or, and, xor; + /// <summary> + /// Returns a delegate to evaluate unary negation (-) for the given type; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<T, T> Negate { get { return negate; } } + /// <summary> + /// Returns a delegate to evaluate bitwise not (~) for the given type; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<T, T> Not { get { return not; } } + /// <summary> + /// Returns a delegate to evaluate bitwise or (|) for the given type; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<T, T, T> Or { get { return or; } } + /// <summary> + /// Returns a delegate to evaluate bitwise and (&) for the given type; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<T, T, T> And { get { return and; } } + /// <summary> + /// Returns a delegate to evaluate bitwise xor (^) for the given type; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<T, T, T> Xor { get { return xor; } } + + static readonly Func<T, T, T> add, subtract, multiply, divide; + /// <summary> + /// Returns a delegate to evaluate binary addition (+) for the given type; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<T, T, T> Add { get { return add; } } + /// <summary> + /// Returns a delegate to evaluate binary subtraction (-) for the given type; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<T, T, T> Subtract { get { return subtract; } } + /// <summary> + /// Returns a delegate to evaluate binary multiplication (*) for the given type; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<T, T, T> Multiply { get { return multiply; } } + /// <summary> + /// Returns a delegate to evaluate binary division (/) for the given type; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<T, T, T> Divide { get { return divide; } } + + + static readonly Func<T, T, bool> equal, notEqual, greaterThan, lessThan, greaterThanOrEqual, lessThanOrEqual; + /// <summary> + /// Returns a delegate to evaluate binary equality (==) for the given type; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<T, T, bool> Equal { get { return equal; } } + /// <summary> + /// Returns a delegate to evaluate binary inequality (!=) for the given type; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<T, T, bool> NotEqual { get { return notEqual; } } + /// <summary> + /// Returns a delegate to evaluate binary greater-then (>) for the given type; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<T, T, bool> GreaterThan { get { return greaterThan; } } + /// <summary> + /// Returns a delegate to evaluate binary less-than (<) for the given type; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<T, T, bool> LessThan { get { return lessThan; } } + /// <summary> + /// Returns a delegate to evaluate binary greater-than-or-equal (>=) for the given type; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<T, T, bool> GreaterThanOrEqual { get { return greaterThanOrEqual; } } + /// <summary> + /// Returns a delegate to evaluate binary less-than-or-equal (<=) for the given type; this delegate will throw + /// an InvalidOperationException if the type T does not provide this operator, or for + /// Nullable<TInner> if TInner does not provide this operator. + /// </summary> + public static Func<T, T, bool> LessThanOrEqual { get { return lessThanOrEqual; } } + + static Operator() + { + add = ExpressionUtil.CreateExpression<T, T, T>(Expression.Add); + subtract = ExpressionUtil.CreateExpression<T, T, T>(Expression.Subtract); + divide = ExpressionUtil.CreateExpression<T, T, T>(Expression.Divide); + multiply = ExpressionUtil.CreateExpression<T, T, T>(Expression.Multiply); + + greaterThan = ExpressionUtil.CreateExpression<T, T, bool>(Expression.GreaterThan); + greaterThanOrEqual = ExpressionUtil.CreateExpression<T, T, bool>(Expression.GreaterThanOrEqual); + lessThan = ExpressionUtil.CreateExpression<T, T, bool>(Expression.LessThan); + lessThanOrEqual = ExpressionUtil.CreateExpression<T, T, bool>(Expression.LessThanOrEqual); + equal = ExpressionUtil.CreateExpression<T, T, bool>(Expression.Equal); + notEqual = ExpressionUtil.CreateExpression<T, T, bool>(Expression.NotEqual); + + negate = ExpressionUtil.CreateExpression<T, T>(Expression.Negate); + and = ExpressionUtil.CreateExpression<T, T, T>(Expression.And); + or = ExpressionUtil.CreateExpression<T, T, T>(Expression.Or); + not = ExpressionUtil.CreateExpression<T, T>(Expression.Not); + xor = ExpressionUtil.CreateExpression<T, T, T>(Expression.ExclusiveOr); + + Type typeT = typeof(T); + if(typeT.IsValueType && typeT.IsGenericType && (typeT.GetGenericTypeDefinition() == typeof(Nullable<>))) { + // get the *inner* zero (not a null Nullable<TValue>, but default(TValue)) + Type nullType = typeT.GetGenericArguments()[0]; + zero = (T)Activator.CreateInstance(nullType); + nullOp = (INullOp<T>)Activator.CreateInstance( + typeof(StructNullOp<>).MakeGenericType(nullType)); + } else { + zero = default(T); + if (typeT.IsValueType) + { + nullOp = (INullOp<T>)Activator.CreateInstance( + typeof(StructNullOp<>).MakeGenericType(typeT)); + } + else + { + nullOp = (INullOp<T>)Activator.CreateInstance( + typeof(ClassNullOp<>).MakeGenericType(typeT)); + } + } + } + } +} diff --git a/Samples/AnimTest/main.cs b/Samples/AnimTest/main.cs new file mode 100644 index 00000000..6dd0b525 --- /dev/null +++ b/Samples/AnimTest/main.cs @@ -0,0 +1,28 @@ +using System; +using Crow; +using Glfw; +using Samples; + +namespace HelloWorld +{ + class Program : Interface { + Program() : base (800, 600, true) {} + static void Main (string[] args) { + //Interface.PreferedBackendType = Drawing2D.BackendType.Egl; + using (Program app = new Program ()) { + //app.Initialized += (sender, e) => app.LoadIMLFragment (@"<Label Text='Hello World' Background='Red' Top='50' Margin='0'/>"); + //app.Initialized += (sender, e) => app.LoadIMLFragment (@"<Window Caption='hello world'/>"); + app.Run (); + } + } + protected override void OnInitialized() + { + Load ("/mnt/devel/crow/Samples/AnimTest/ui/anim.crow"); + } + + public override void UpdateFrame() + { + base.UpdateFrame(); + } + } +} diff --git a/Samples/AnimTest/ui/anim.crow b/Samples/AnimTest/ui/anim.crow new file mode 100644 index 00000000..f3fa6c6f --- /dev/null +++ b/Samples/AnimTest/ui/anim.crow @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<Container Margin="10" Width="500" Background="/mnt/devel/crow/Samples/AnimTest/ui/background.jpg"> +<!-- <Image Path="/mnt/devel/crow/Samples/AnimTest/ui/background.jpg" SvgSub="True" Height="200"/>--> + <HorizontalStack Height="Fit" Width="Fit" Spacing="10" VerticalAlignment="Bottom" > + <Label Background="Teal" Width="30%" Margin="10" CornerRadius="10" Font="bold, 14" TextAlignment="Center"/> + <Label Background="Teal" Width="30%" Margin="10" CornerRadius="10" Font="bold, 14" TextAlignment="Center"/> + <Label Background="Teal" Width="30%" Margin="10" CornerRadius="10" Font="bold, 14" TextAlignment="Center"/> + </HorizontalStack> +</Container> + diff --git a/Samples/AnimTest/ui/background.crow b/Samples/AnimTest/ui/background.crow new file mode 100644 index 00000000..a0881df6 --- /dev/null +++ b/Samples/AnimTest/ui/background.crow @@ -0,0 +1,4 @@ +<?xml version="1.0"?> +<Widget Height="400" Width="260" Background="/mnt/devel/crow/Samples/AnimTest/ui/background.jpg"/> +<!--<Widget Height="100" Width="100" Background="#Crow.Icons.checkbox.svg"/>--> + diff --git a/Samples/AnimTest/ui/background.jpg b/Samples/AnimTest/ui/background.jpg Binary files differnew file mode 100644 index 00000000..50ebfbf0 --- /dev/null +++ b/Samples/AnimTest/ui/background.jpg diff --git a/Samples/BasicTests/BasicTests.cs b/Samples/BasicTests/BasicTests.cs index 130171aa..7506d27d 100644 --- a/Samples/BasicTests/BasicTests.cs +++ b/Samples/BasicTests/BasicTests.cs @@ -12,19 +12,19 @@ namespace Samples static void Main () { using (BasicTests app = new BasicTests ()) { - app.SolidBackground = false; + //app.SolidBackground = false; app.Run (); } } protected override void OnInitialized () { - Commands = new CommandGroup ( + /*Commands = new CommandGroup ( new Crow.Command("command1", new Action(() => Console.WriteLine ("command1 triggered"))), new Crow.Command("command2", new Action(() => Console.WriteLine ("command2 triggered"))), new Crow.Command("command3", new Action(() => Console.WriteLine ("command3 triggered"))), new Crow.Command("command4", new Action(() => Console.WriteLine ("command4 triggered"))) - ); + );*/ // += KeyboardKeyDown1; @@ -55,12 +55,10 @@ namespace Samples int idx = 0; string [] testFiles; - - - public override bool OnKeyDown (Key key) + public override bool OnKeyDown (KeyEventArgs e) { try { - switch (key) { + switch (e.Key) { case Key.Escape: Quit (); break; @@ -75,7 +73,7 @@ namespace Samples NotifyValueChanged ("TestList", TestList); break; default: - return base.OnKeyDown (key); + return base.OnKeyDown (e); } ClearInterface (); diff --git a/Samples/HelloWorld/main.cs b/Samples/HelloWorld/main.cs index fd70a2b9..fdf75a8d 100644 --- a/Samples/HelloWorld/main.cs +++ b/Samples/HelloWorld/main.cs @@ -8,6 +8,7 @@ namespace HelloWorld class Program : Interface { Program() : base (800, 600, true) {} static void Main (string[] args) { + //Interface.PreferedBackendType = Drawing2D.BackendType.Egl; using (Program app = new Program ()) { //app.Initialized += (sender, e) => app.LoadIMLFragment (@"<Label Text='Hello World' Background='Red' Top='50' Margin='0'/>"); //app.Initialized += (sender, e) => app.LoadIMLFragment (@"<Window Caption='hello world'/>"); diff --git a/Samples/HelloWorld/ui/helloworld.crow b/Samples/HelloWorld/ui/helloworld.crow index d1c30b0f..874667c2 100644 --- a/Samples/HelloWorld/ui/helloworld.crow +++ b/Samples/HelloWorld/ui/helloworld.crow @@ -1,2 +1,9 @@ <?xml version="1.0"?> -<Label Text="Hello World"/> + + <!--<Widget Background="hgradient|0:Black|0.5:Blue|1:Red" Margin="100" />--> + <VerticalStack> + <Image Path="#Crow.Icons.checkbox.svg" SvgSub="True" Height="200"/> + <CheckBox/> + + </VerticalStack> + <!--<ColorPicker/>--> diff --git a/Samples/ShowCase/ShowCase.cs b/Samples/ShowCase/ShowCase.cs index 958a6b13..92a71e9f 100644 --- a/Samples/ShowCase/ShowCase.cs +++ b/Samples/ShowCase/ShowCase.cs @@ -14,6 +14,7 @@ using Crow.Text; using System.Collections.Generic; using Encoding = System.Text.Encoding; using Samples; +using System.Threading; namespace ShowCase { @@ -30,6 +31,8 @@ namespace ShowCase }; static void Main () { + //Interface.PreferedBackendType = Drawing2D.BackendType.Egl; + initDebugLog (); Environment.SetEnvironmentVariable ("FONTCONFIG_PATH", @"C:\Users\Jean-Philippe\source\vcpkg\installed\x64-windows\tools\fontconfig\fonts"); @@ -44,6 +47,40 @@ namespace ShowCase app.Run (); } } + public override void Run () { + initBackend (); + + if (!SingleThreaded) { + Thread t = new Thread (InterfaceThread) { + IsBackground = true + }; + t.Start (); + } + + Init (); + + if (SingleThreaded) { + while (!Glfw3.WindowShouldClose (WindowHandle)) { + Glfw3.PollEvents (); + try { + Update(); + UpdateFrame (); + } catch (Exception ex) { + showError (ex); + crowContainer.SetChild (null); + } + Thread.Sleep (UPDATE_INTERVAL); + } + } else { + while (!Glfw3.WindowShouldClose (hWin)) { + Glfw3.PollEvents (); + UpdateFrame (); + Thread.Sleep (POLLING_INTERVAL); + } + } + + Terminate (); + } public Container crowContainer; Stopwatch reloadChrono = new Stopwatch (); diff --git a/Samples/ShowCase/ui/showcase.crow b/Samples/ShowCase/ui/showcase.crow index 298c8797..b1d6fb88 100644 --- a/Samples/ShowCase/ui/showcase.crow +++ b/Samples/ShowCase/ui/showcase.crow @@ -77,7 +77,7 @@ <Container Name="CrowContainer" Height="60%" Background="Black"/> <Splitter/> <VerticalStack CacheEnabled="true"> - <Menu Data="{EditorAllCommands}" Height="Fit" Width="Stretched"> + <!--<Menu Data="{EditorAllCommands}" Height="Fit" Width="Stretched"> <ItemTemplate DataType="Crow.Command" Path="Interfaces/menuCommand.itmp"/> <ItemTemplate DataType="Crow.CommandGroup" > <MenuItem Data="{Commands}" Width="Fit" IsEnabled="{CanExecute}" @@ -85,8 +85,8 @@ ItemTemplate="Interfaces/menuItem.itmp"> </MenuItem> </ItemTemplate> - </Menu> - <!-- <Wrapper Orientation="Vertical" Height="Fit"> + </Menu>--> + <Wrapper Orientation="Vertical" Height="Fit"> <Button Style="IcoButton" Command="{CMDNew}" /> <Button Style="IcoButton" Command="{CMDSave}" /> <Button Style="IcoButton" Command="{CMDSaveAs}" /> @@ -160,11 +160,11 @@ Tooltip="Add '*source* where you want to load the source in the editor."/> </VerticalStack> </Popper> - </Wrapper>--> + </Wrapper> <HorizontalStack> <Editor Name="tb" Text="{Source}" Multiline="true" Font="consolas, 12" Focusable="true" Height="Stretched" Width="Stretched" TextChanged="onTextChanged" KeyDown="textView_KeyDown" ContextCommands="{EditorEditCommands}" - SelectionChanged="onEditorSelectionChanged" + SelectionChanged="onEditorSelectionChanged" ClipToClientRect="true" Foreground="DarkGrey" Background="White" MouseWheelSpeed="20"/> <ScrollBar Value="{²../tb.ScrollY}" LargeIncrement="{../tb.PageHeight}" SmallIncrement="1" diff --git a/Samples/common/ui/Interfaces/Experimental/svg.crow b/Samples/common/ui/Interfaces/Experimental/svg.crow new file mode 100644 index 00000000..7a935032 --- /dev/null +++ b/Samples/common/ui/Interfaces/Experimental/svg.crow @@ -0,0 +1,2 @@ +<?xml version="1.0"?> +<Image Path="/usr/share/icons/breeze/categories/32/applications-education.svg"/>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/TemplatedContainer/buttons.crow b/Samples/common/ui/Interfaces/TemplatedContainer/buttons.crow new file mode 100644 index 00000000..32a5b83f --- /dev/null +++ b/Samples/common/ui/Interfaces/TemplatedContainer/buttons.crow @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<VerticalStack Margin="10" Background="Grey"> + <Button + Foreground="LightGrey" + MouseEnter="{Foreground=White}" + MouseLeave="{Foreground=LightGrey}" + Background="vgradient|0:LightGrey|0.1:Grey|0.9:Grey|1:Jet" + MouseUp="{Background=vgradient|0:LightGrey|0.1:Grey|0.9:Grey|1:Jet}" + MouseDown="{Background=vgradient|0:Jet|0.1:Grey|0.9:Grey|1:LightGrey}"> + <Template> + <Border Foreground="Black" CornerRadius="10" Background="{./Background}" Margin="7"> + <Label Foreground="{./Foreground}" Text="{./Caption}"/> + </Border> + </Template> + </Button > + <CheckBox Width="200" + Foreground="Black" + Background="vgradient|0:LightGrey|0.1:Grey|0.9:Grey|1:Jet" + Unchecked="{Background=vgradient|0:LightGrey|0.1:Grey|0.9:Grey|1:Jet};{Foreground=Black}" + Checked="{Background=vgradient|0:Jet|0.1:Grey|0.9:Grey|1:LightGrey};{Foreground=DodgerBlue}"> + <Template> + <Border Foreground="{./Foreground}" CornerRadius="10" Background="{./Background}" Margin="7"> + <Label Text="{./Caption}"/> + </Border> + </Template> + </CheckBox > + <HorizontalStack Height="Fit" Width="Fit"> + <RadioButton Width="200" + Foreground="Black" + Background="vgradient|0:LightGrey|0.1:Grey|0.9:Grey|1:Jet" + Unchecked="{Background=vgradient|0:LightGrey|0.1:Grey|0.9:Grey|1:Jet};{Foreground=Black}" + Checked="{Background=vgradient|0:Jet|0.1:Grey|0.9:Grey|1:LightGrey};{Foreground=DodgerBlue}"> + <Template> + <Border Foreground="{./Foreground}" CornerRadius="10" Background="{./Background}" Margin="7"> + <Label Text="{./Caption}"/> + </Border> + </Template> + </RadioButton > + <RadioButton Width="200" + Foreground="Black" + Background="vgradient|0:LightGrey|0.1:Grey|0.9:Grey|1:Jet" + Unchecked="{Background=vgradient|0:LightGrey|0.1:Grey|0.9:Grey|1:Jet};{Foreground=Black}" + Checked="{Background=vgradient|0:Jet|0.1:Grey|0.9:Grey|1:LightGrey};{Foreground=DodgerBlue}"> + <Template> + <Border Foreground="{./Foreground}" CornerRadius="10" Background="{./Background}" Margin="7"> + <Label Text="{./Caption}"/> + </Border> + </Template> + </RadioButton > + <RadioButton Width="200" + Foreground="Black" + Background="vgradient|0:LightGrey|0.1:Grey|0.9:Grey|1:Jet" + Unchecked="{Background=vgradient|0:LightGrey|0.1:Grey|0.9:Grey|1:Jet};{Foreground=Black}" + Checked="{Background=vgradient|0:Jet|0.1:Grey|0.9:Grey|1:LightGrey};{Foreground=DodgerBlue}"> + <Template> + <Border Foreground="{./Foreground}" CornerRadius="10" Background="{./Background}" Margin="7"> + <Label Text="{./Caption}"/> + </Border> + </Template> + </RadioButton > + </HorizontalStack> +</VerticalStack>
\ No newline at end of file |