/// <summary>
        /// Determine the actual plane matrix from the selected plane of this behavior
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        protected Matrix4x4 GetUsedPlane(NotuiElement element)
        {
            ActualPlaneSelection = UseSelectedPlane == SelectedPlane.ParentPlane ?
                                   (element.Parent != null ? SelectedPlane.ParentPlane : SelectedPlane.ViewAligned) :
                                   UseSelectedPlane;

            Matrix4x4 usedplane;

            switch (ActualPlaneSelection)
            {
            case SelectedPlane.ParentPlane:
                usedplane = element.Parent.DisplayMatrix;
                break;

            case SelectedPlane.OwnPlane:
                usedplane = element.DisplayMatrix;
                break;

            case SelectedPlane.ViewAligned:
                usedplane = Matrix4x4.CreateFromQuaternion(element.Context.ViewOrientation) *
                            Matrix4x4.CreateTranslation(element.DisplayMatrix.Translation);
                break;

            default:
                usedplane = Matrix4x4.CreateFromQuaternion(element.Context.ViewOrientation) *
                            Matrix4x4.CreateTranslation(element.DisplayMatrix.Translation);
                break;
            }

            return(usedplane);
        }
Example #2
0
        public VEnvironmentData(NotuiElement element)
        {
            _element               = element;
            TypeCSharpName         = element.GetType().GetCSharpName();
            element.OnMainLoopEnd += (sender, args) =>
            {
                Touches.AssignFrom(_element.Touching.Keys);
                TouchesHitting.AssignFrom(_element.Touching.Values.Select(t => t != null));
                TouchingIntersections.AssignFrom(_element.Touching.Values.Where(t => t != null));
                HittingTouches.AssignFrom(_element.Hitting.Keys);
                HittingIntersections.AssignFrom(_element.Hitting.Values);
                Mice.AssignFrom(_element.Mice.Select(t => t.AttachadMouse));
                Children.AssignFrom(_element.Children.Values);
                Behaviors.AssignFrom(_element.Behaviors);

                if (_element.Parent == null)
                {
                    Parent.SliceCount = 0;
                }
                else
                {
                    Parent.SliceCount = 1;
                    Parent[0]         = element.Parent;
                }

                VDispTr = _element.DisplayMatrix.AsVMatrix4X4();
            };
        }
 /// <inheritdoc cref="ElementPrototype"/>
 public override void UpdateFrom(NotuiElement other)
 {
     base.UpdateFrom(other);
     if (other is PolygonElement element)
     {
         Vertices = element.Vertices.ToList();
     }
 }
 /// <inheritdoc cref="NotuiElement"/>
 public PolygonElement(ElementPrototype prototype, NotuiContext context, NotuiElement parent = null) :
     base(prototype, context, parent)
 {
     if (prototype is PolygonElementPrototype prot)
     {
         Vertices = prot.Vertices.ToList();
     }
 }
Example #5
0
 /// <inheritdoc cref="NotuiElement"/>
 public BoxElement(ElementPrototype prototype, NotuiContext context, NotuiElement parent = null) :
     base(prototype, context, parent)
 {
     if (prototype is BoxElementPrototype prot)
     {
         Size = prot.Size;
     }
 }
 private void RecursiveInteracted(NotuiElement element)
 {
     element.OnTouchBegin += (sender, args) => Interacted = true;
     foreach (var child in element.Children.Values)
     {
         RecursiveInteracted(child);
     }
 }
Example #7
0
 /// <inheritdoc cref="ElementPrototype"/>
 public override void UpdateFrom(NotuiElement other)
 {
     base.UpdateFrom(other);
     if (other is BoxElement element)
     {
         Size = element.Size;
     }
 }
 /// <summary>
 /// Recursive function which adds touches interacting with the children to this behavior
 /// </summary>
 /// <param name="element"></param>
 /// <param name="touches"></param>
 /// <param name="touchsrc"></param>
 protected void AddChildrenTouches(NotuiElement element, List <Touch> touches, InteractingTouchSource touchsrc = InteractingTouchSource.Touching)
 {
     foreach (var child in element.Children.Values)
     {
         touches.AddRange(GetTouchesFromSource(child, touchsrc));
         AddChildrenTouches(child, touches, touchsrc);
     }
 }
 /// <inheritdoc cref="NotuiElement"/>
 public SegmentElement(ElementPrototype prototype, NotuiContext context, NotuiElement parent = null) :
     base(prototype, context, parent)
 {
     if (prototype is SegmentElementPrototype seprot)
     {
         HoleRadius = seprot.HoleRadius;
         Cycles     = seprot.Cycles;
         Phase      = seprot.Phase;
     }
 }
Example #10
0
 /// <inheritdoc cref="ElementPrototype"/>
 public override void UpdateFrom(NotuiElement other)
 {
     base.UpdateFrom(other);
     if (other is SegmentElement element)
     {
         HoleRadius = element.HoleRadius;
         Cycles     = element.Cycles;
         Phase      = element.Phase;
     }
 }
Example #11
0
        private void Move(NotuiElement element, BehaviorState state, Matrix4x4 usedplane)
        {
            var disptr   = element.DisplayTransformation;
            var worldvel = Vector4.Transform(new Vector4(state.DeltaPos * Coeffitient * 0.5f, 0, 0), usedplane).xyz();

            if (element.Parent != null)
            {
                Matrix4x4.Invert(element.Parent.DisplayMatrix, out var invparenttr);
                worldvel = Vector4.Transform(new Vector4(worldvel, 0), invparenttr).xyz();
            }

            disptr.Translate(worldvel);
            disptr.Position = Intersections.BoxPointLimit(BoundingBoxMin, BoundingBoxMax, disptr.Position);
        }
Example #12
0
        private void Move(NotuiElement element, BehaviorState state, Matrix4x4 usedplane)
        {
            var disptr = element.DisplayTransformation;

            if (Draggable)
            {
                var worldvel = Vector4.Transform(new Vector4(state.DeltaPos * DraggingCoeffitient * 0.5f, 0, 0), usedplane).xyz();
                if (element.Parent != null)
                {
                    Matrix4x4.Invert(element.Parent.DisplayMatrix, out var invparenttr);
                    worldvel = Vector4.Transform(new Vector4(worldvel, 0), invparenttr).xyz();
                }

                disptr.Translate(worldvel);
                if (LimitTranslation)
                {
                    disptr.Position = Intersections.BoxPointLimit(BoundingBoxMin, BoundingBoxMax, disptr.Position);
                }
            }
            if (Scalable)
            {
                var sclvel = state.DeltaSize * ScalingCoeffitient * 0.5f;
                disptr.Scale = Vector3.Max(
                    new Vector3(ScaleMinMax.X),
                    Vector3.Min(
                        new Vector3(ScaleMinMax.Y),
                        disptr.Scale * new Vector3(1 + sclvel)
                        )
                    );
            }
            if (Pivotable)
            {
                // see if rotation is still inside boundaries
                var targetrot = state.TotalAngle + state.DeltaAngle * RotationCoeffitient * 0.5f * (1 / disptr.Scale.Length());
                if (!LimitRotation || RotationMinMax.X <= targetrot && targetrot <= RotationMinMax.Y)
                {
                    state.TotalAngle = targetrot;

                    var worldaxis = Vector3.TransformNormal(Vector3.UnitZ, usedplane);
                    if (element.Parent != null)
                    {
                        Matrix4x4.Invert(element.Parent.DisplayMatrix, out var invparenttr);
                        worldaxis = Vector3.TransformNormal(worldaxis, invparenttr);
                    }
                    var worldrot = Quaternion.CreateFromAxisAngle(worldaxis, state.DeltaAngle * RotationCoeffitient);
                    disptr.LocalRotate(worldrot);
                }
            }
            state.Mainloop(element.Context.DeltaTime);
        }
Example #13
0
        protected override void Filter(int ei, NotuiElement element, ISpread <string> filter)
        {
            bool CompareType(NotuiElement el)
            {
                var res = false;

                foreach (var f in filter)
                {
                    if (string.IsNullOrWhiteSpace(f))
                    {
                        continue;
                    }
                    if (el.EnvironmentObject is VEnvironmentData venvdat)
                    {
                        res = FContains[ei] ? venvdat.TypeCSharpName.Contains(f) : venvdat.TypeCSharpName == f;
                    }
                    else
                    {
                        res = FContains[ei]
                        ? el.GetType().GetCSharpName().Contains(f)
                        : el.GetType().GetCSharpName() == f;
                    }

                    if (!res)
                    {
                        continue;
                    }
                    break;
                }
                return(FExclude[ei] ? !res : res);
            };

            if (FContains.SliceCount == 0 || FExclude.SliceCount == 0)
            {
                return;
            }
            else
            {
                if (FOut.SliceCount == 0)
                {
                    return;
                }
                FOut[ei].AddRange(element.Children.Values.Where(CompareType));
            }
        }
Example #14
0
 public static void AttachManagementObject(this NotuiElement element, string nodepath, object obj)
 {
     if (element.EnvironmentObject == null)
     {
         element.EnvironmentObject = new VEnvironmentData(element);
     }
     if (element.EnvironmentObject is VEnvironmentData venvdat)
     {
         if (venvdat.NodeSpecific.ContainsKey(nodepath))
         {
             venvdat.NodeSpecific[nodepath] = obj;
         }
         else
         {
             venvdat.NodeSpecific.Add(nodepath, obj);
         }
     }
 }
        /// <summary>
        /// Get touches from the selected source list
        /// </summary>
        protected IEnumerable <Touch> GetTouchesFromSource(NotuiElement element,
                                                           InteractingTouchSource touchsrc = InteractingTouchSource.Touching)
        {
            switch (touchsrc)
            {
            case InteractingTouchSource.Touching:
                return(element.Touching.Keys);

            case InteractingTouchSource.Hitting:
                return(element.Hitting.Keys);

            case InteractingTouchSource.Mice:
                return(element.Mice);

            default:
                return(Enumerable.Empty <Touch>());
            }
        }
Example #16
0
 protected override void Filter(int ei, NotuiElement element, ISpread <string> filter)
 {
     if (FUseName.SliceCount == 0 || FSeparator.SliceCount == 0)
     {
         return;
     }
     foreach (var f in filter)
     {
         if (string.IsNullOrWhiteSpace(f))
         {
             continue;
         }
         if (FOut.SliceCount == 0)
         {
             return;
         }
         FOut[ei].AddRange(element.Opaq(f, FSeparator[ei], FUseName[ei]));
     }
 }
Example #17
0
        public void Subscribe(NotuiElement element)
        {
            try
            {
                element.OnInteractionBegin -= _OnInteractionBeginHandler;
                element.OnInteractionEnd   -= _OnInteractionEndHandler;
                element.OnTouchBegin       -= _OnTouchBeginHandler;
                element.OnTouchEnd         -= _OnTouchEndHandler;
                element.OnHitBegin         -= _OnHitBeginHandler;
                element.OnHitEnd           -= _OnHitEndHandler;
                element.OnInteracting      -= _OnInteractingHandler;
                element.OnChildrenUpdated  -= _OnChildrenUpdatedHandler;
                element.OnDeletionStarted  -= _OnDeletionStartedHandler;
                element.OnDeleting         -= _OnDeletingHandler;
                element.OnFadedIn          -= _OnFadedInHandler;

                element.OnMouseButtonPressed         -= _OnMouseButtonPressed;
                element.OnMouseButtonReleased        -= _OnMouseButtonReleased;
                element.OnHorizontalMouseWheelChange -= _OnHorizontalMouseWheelChange;
                element.OnVerticalMouseWheelChange   -= _OnVerticalMouseWheelChange;
            }
            catch { }

            element.OnInteractionBegin += _OnInteractionBeginHandler;
            element.OnInteractionEnd   += _OnInteractionEndHandler;
            element.OnTouchBegin       += _OnTouchBeginHandler;
            element.OnTouchEnd         += _OnTouchEndHandler;
            element.OnHitBegin         += _OnHitBeginHandler;
            element.OnHitEnd           += _OnHitEndHandler;
            element.OnInteracting      += _OnInteractingHandler;
            element.OnChildrenUpdated  += _OnChildrenUpdatedHandler;
            element.OnDeletionStarted  += _OnDeletionStartedHandler;
            element.OnDeleting         += _OnDeletingHandler;
            element.OnFadedIn          += _OnFadedInHandler;

            element.OnMouseButtonPressed         += _OnMouseButtonPressed;
            element.OnMouseButtonReleased        += _OnMouseButtonReleased;
            element.OnHorizontalMouseWheelChange += _OnHorizontalMouseWheelChange;
            element.OnVerticalMouseWheelChange   += _OnVerticalMouseWheelChange;
        }
        /// <inheritdoc cref="InteractionBehavior"/>
        public override void Behave(NotuiElement element)
        {
            var currstate = IsStateAvailable(element) ? GetState <BehaviorState>(element) : new BehaviorState(element);

            SetState(element, currstate);
            if (currstate.Interacted)
            {
                var restsrc = element.Parent?.Children.Values ?? element.Context.RootElements.Values;

                if (restsrc.Count == 1)
                {
                    return;
                }

                var rest = element.Parent?.Children.Values.Where(rel => rel.Id != element.Id) ??
                           element.Context.RootElements.Values.Where(rel => rel.Id != element.Id);

                var ordered = rest.OrderBy(rel => rel.DisplayTransformation.Position.Z);

                var depth = Distance + Top;

                var currp = element.DisplayTransformation.Position;
                element.DisplayTransformation.Position = new Vector3(currp.xy(), Top);
                var currtp = element.TargetTransformation.Position;
                element.TargetTransformation.Position = new Vector3(currtp.xy(), Top);

                foreach (var el in ordered)
                {
                    var elp = el.DisplayTransformation.Position;
                    el.DisplayTransformation.Position = new Vector3(elp.xy(), depth);
                    var eltp = el.TargetTransformation.Position;
                    el.TargetTransformation.Position = new Vector3(eltp.xy(), depth);
                    depth += Distance;
                }

                currstate.Interacted = false;
            }
        }
Example #19
0
        /// <inheritdoc cref="InteractionBehavior"/>
        public override void Behave(NotuiElement element)
        {
            var usedplane = GetUsedPlane(element);

            var currstate = IsStateAvailable(element) ? GetState <BehaviorState>(element) : new BehaviorState();

            var touches = GetBehavingTouches(element, InteractingTouchSource.Mice);

            if (touches.Count >= 1)
            {
                var allscroll = touches.Aggregate(Vector2.Zero, (v, touch) => v + new Vector2(
                                                      (float)touch.MouseDelta.AccumulatedHorizontalWheelDelta / 120,
                                                      (float)touch.MouseDelta.AccumulatedWheelDelta / 120)
                                                  );
                if (allscroll.Length() > 0)
                {
                    currstate.DeltaPos = allscroll;
                }
            }
            Move(element, currstate, usedplane);
            FlickProgress(currstate, element.Context);
            SetState(element, currstate);
        }
        /// <summary>
        /// Get all the touches which can act on this behavior
        /// </summary>
        /// <param name="element"></param>
        /// <param name="touchsrc"></param>
        /// <returns></returns>
        protected List <Touch> GetBehavingTouches(NotuiElement element, InteractingTouchSource touchsrc = InteractingTouchSource.Touching)
        {
            List <Touch> touches;

            if (UseOnlyWithSpecificChildren == null)
            {
                touches = GetTouchesFromSource(element, touchsrc).ToList();
                if (UseChildrenInteracting)
                {
                    AddChildrenTouches(element, touches, touchsrc);
                }
            }
            else
            {
                touches = new List <Touch>();
                var selectedChildren = UseOnlyWithSpecificChildren(element);
                foreach (var child in selectedChildren)
                {
                    touches.AddRange(GetTouchesFromSource(child, touchsrc));
                }
            }

            return(touches);
        }
Example #21
0
        protected void AssignElementOutputs(NotuiElement element, int i)
        {
            if (element == null)
            {
                return;
            }
            if (element.EnvironmentObject is VEnvironmentData venvdat)
            {
                TouchesOut[i]               = venvdat.Touches;
                TouchesHittingOut[i]        = venvdat.TouchesHitting;
                TouchingIntersectionsOut[i] = venvdat.TouchingIntersections;
                HittingTouchesOut[i]        = venvdat.HittingTouches;
                HittingIntersectionsOut[i]  = venvdat.HittingIntersections;
                MiceOut[i]      = venvdat.Mice;
                ChildrenOut[i]  = venvdat.Children;
                BehavsOut[i]    = venvdat.Behaviors;
                ParentOut[i]    = venvdat.Parent;
                DisplayTrOut[i] = venvdat.VDispTr;
                TypeOut[i]      = venvdat.TypeCSharpName;
            }
            ElementOut[i]   = element;
            NameOut[i]      = element.Name;
            PrototypeOut[i] = element.Prototype;

            IdOut[i]          = element.Id;
            HitOut[i]         = element.Hit;
            TouchedOut[i]     = element.Touched;
            ActiveOut[i]      = element.Active;
            TransparentOut[i] = element.Transparent;
            FadeStateOut[i]   = element.FadingState;
            ElementFadeOut[i] = element.ElementFade;
            AgeOut[i]         = element.Age.Elapsed.TotalSeconds;
            DyingOut[i]       = element.Dying;
            LocDisplayOut[i]  = element.DisplayTransformation;
            ContextOut[i]     = element.Context;
        }
Example #22
0
 protected abstract void Filter(int ei, NotuiElement element, ISpread <string> filter);
Example #23
0
        protected override void Filter(int ei, NotuiElement element, ISpread <string> filter)
        {
            bool NameCompare(NotuiElement el)
            {
                var res = false;

                foreach (var f in filter)
                {
                    if (string.IsNullOrWhiteSpace(f))
                    {
                        continue;
                    }
                    res = FContains[ei]
                        ? el.Name.Contains(f)
                        : el.Name.Equals(f, StringComparison.InvariantCulture);

                    if (!res)
                    {
                        continue;
                    }
                    break;
                }
                return(FExclude[ei] ? !res : res);
            };
            bool IdCompare(NotuiElement el)
            {
                var res = false;

                foreach (var f in filter)
                {
                    if (string.IsNullOrWhiteSpace(f))
                    {
                        continue;
                    }
                    res = FContains[ei]
                        ? el.Id.Contains(f)
                        : el.Id.Equals(f, StringComparison.InvariantCulture);

                    if (!res)
                    {
                        continue;
                    }
                    break;
                }
                return(FExclude[ei] ? !res : res);
            };

            if (FContains.SliceCount == 0 || FUseName.SliceCount == 0 || FExclude.SliceCount == 0)
            {
                return;
            }
            else
            {
                if (FOut.SliceCount == 0)
                {
                    return;
                }
                FOut[ei].AddRange(FUseName[ei]
                    ? element.Children.Values.Where(NameCompare)
                    : element.Children.Values.Where(IdCompare));
            }
        }
Example #24
0
 /// <summary>
 /// Construct based on an instance
 /// </summary>
 /// <param name="fromInstance">The element instance</param>
 /// <param name="newId">Generate a new ID?</param>
 /// <remarks>Static function ElementPrototype.CreateFromInstance(...) is recommended to be used instead of this</remarks>
 public SphereElementPrototype(NotuiElement fromInstance, bool newId = true) : base(fromInstance, newId)
 {
 }
Example #25
0
 /// <inheritdoc cref="NotuiElement"/>
 public SphereElement(ElementPrototype prototype, NotuiContext context, NotuiElement parent = null) :
     base(prototype, context, parent)
 {
 }
Example #26
0
        /// <inheritdoc cref="InteractionBehavior"/>
        public override void Behave(NotuiElement element)
        {
            if (element.Value == null)
            {
                element.Value = new AttachedValues();
            }

            var stateAvailable = IsStateAvailable(element);
            var values         = element.Value.Values;

            if (!stateAvailable)
            {
                SetState(element, new BehaviorState());
                element.Value.Values = new float[Max(VerticalOffs, HorizontalOffs) + 1];
                element.Value.Values.Fill(values);
                values = element.Value.Values;
                values[HorizontalOffs] = Default.X;
                values[VerticalOffs]   = Default.Y;
            }

            if (AxisCoeff.Length() < 0.00001)
            {
                return;
            }
            if (Constrain && Vector2.Distance(LimitMin, LimitMax) < 0.00001)
            {
                return;
            }
            if (element.Touching.IsEmpty)
            {
                return;
            }

            KeyValuePair <Touch, IntersectionPoint> fastesttouch;

            try
            {
                if (MouseMask.Length == 0)
                {
                    fastesttouch = element.Touching.OrderByDescending(t => t.Key.Velocity.LengthSquared()).First();
                }
                else if (MouseMask.Length == 1 && MouseMask[0] == MouseButtons.Left)
                {
                    fastesttouch = (from touch in element.Touching
                                    where touch.Key.AttachadMouse == null || touch.Key.MouseDelta.MouseClicks.Values.Where(mc => mc.Button != MouseButtons.Left).All(mc => !mc.Pressed)
                                    select touch)
                                   .OrderByDescending(t => t.Key.Velocity.LengthSquared()).First();
                }
                else
                {
                    fastesttouch = (from touch in element.Touching
                                    where touch.Key.AttachadMouse != null
                                    where touch.Key.MouseDelta.MouseClicks.Values.Where(mc => mc.Pressed).All(mc => MouseMask.Contains(mc.Button))
                                    select touch)
                                   .OrderByDescending(t => t.Key.Velocity.LengthSquared()).First();
                }
            }
            catch
            {
                return;
            }

            if (values.Length <= Max(VerticalOffs, HorizontalOffs))
            {
                element.Value.Values = new float[Max(VerticalOffs, HorizontalOffs) + 1];
                element.Value.Values.Fill(values);
                values = element.Value.Values;
            }

            Vector3 vel;

            if (UseSurfaceSpace)
            {
                var origis = fastesttouch.Value;
                if (origis == null)
                {
                    return;
                }
                element.PureHitTest(fastesttouch.Key, true, out var previs);
                if (previs == null)
                {
                    return;
                }
                vel = (origis.SurfaceSpace - previs.SurfaceSpace) * 0.5f;
            }
            else
            {
                vel = fastesttouch.Key.GetPlanarVelocity(element.DisplayMatrix, element.Context, out var cpos, out var ppos);
            }

            if (Constrain)
            {
                values[HorizontalOffs] = Max(LimitMin.X, Min(LimitMax.X, values[HorizontalOffs] + vel.X * AxisCoeff.X * 0.5f));
                values[VerticalOffs]   = Max(LimitMin.Y, Min(LimitMax.Y, values[VerticalOffs] + vel.Y * AxisCoeff.Y * 0.5f));
            }
            else
            {
                values[HorizontalOffs] += vel.X * AxisCoeff.X * 0.5f;
                values[VerticalOffs]   += vel.Y * AxisCoeff.Y * 0.5f;
            }
        }
Example #27
0
 /// <inheritdoc cref="NotuiElement"/>
 public InfinitePlaneElement(ElementPrototype prototype, NotuiContext context, NotuiElement parent = null) :
     base(prototype, context, parent)
 {
 }
Example #28
0
 /// <summary>
 /// Construct based on an instance
 /// </summary>
 /// <param name="fromInstance">The element instance</param>
 /// <param name="newId">Generate a new ID?</param>
 /// <remarks>Static function ElementPrototype.CreateFromInstance(...) is recommended to be used instead of this</remarks>
 public PolygonElementPrototype(NotuiElement fromInstance, bool newId = true) : base(fromInstance, newId)
 {
 }
Example #29
0
 public static void AttachSliceId(this NotuiElement element, string nodepath, int id)
 {
     element.AttachManagementObject(nodepath, id);
 }
Example #30
0
 /// <summary></summary>
 /// <param name="prototype"></param>
 /// <param name="context"></param>
 /// <param name="parent"></param>
 protected PlanarElement(ElementPrototype prototype, NotuiContext context, NotuiElement parent = null) :
     base(prototype, context, parent)
 {
 }