예제 #1
0
        /// <summary>
        /// Create next UI layer and set it as active.
        /// </summary>
        /// <param name="nextLayerRoot">Element that will be root of the new layer.</param>
        public LayoutLayer GoDeeper(IAddChild nextLayerRoot)
        {
            // Validate shared reference.
            if (nextLayerRoot == null)
            {
                throw new NullReferenceException("Root element can't be null.");
            }

            // Add shared root as child on current layer.
            root.AddChild(nextLayerRoot);

            // Configurate new layer.
            var newLayer = new LayoutLayer()
            {
                root   = nextLayerRoot, // Set shared element as root
                Parent = this           // Set reference to current active layer like on the parent.
            };

            // Define orientation of the layout group.
            if (nextLayerRoot is StackPanel)
            {
                newLayer.orientation = Orientation.Vertical;
            }
            else
            {
                newLayer.orientation = Orientation.Horizontal;
            }

            // Return new layer.
            return(newLayer);
        }
예제 #2
0
        /// <summary>
        /// Insiniate UI by descriptor's attributes map and add it as child to parent element.
        /// </summary>
        /// <param name="root">UI element that would contain instiniated UI elemets.</param>
        public void BindTo(Panel root)
        {
            // Instiniate first UILayer.
            var layer = new LayoutLayer()
            {
                root = root // Thet binding target as root for cuurent layer.
            };

            BindTo(layer);
        }
        /// <summary>
        /// Insiniate UI by descriptor's attributes map and add it as child to parent element.
        /// </summary>
        /// <param name="root">UI element that would contain instiniated UI elemets.</param>
        public async Task BindToAsync(Panel root)
        {
            // Instiniate first UILayer.
            var layer = new LayoutLayer()
            {
                root = root // Thet binding target as root for cuurent layer.
            };

            await BindToAsync(layer);
        }
예제 #4
0
        /// <summary>
        /// Returns an UI field binded to the member.
        /// </summary>
        /// <param name="member">The member from the source descriptor.</param>
        /// <returns>A GUI Field binded to the member.</returns>
        public IGUIField GetField(MemberInfo member)
        {
            if (IsVirtualized)
            {
                if (RegistredFields[member] is IGUIField field)
                {
                    return(field);
                }
                else
                {
                    // Creating virtual layer.
                    var virtualLayer = new LayoutLayer()
                    {
                        root = new VirtualizingStackPanel()
                    };

                    // Getting options applied to the descriptor.
                    var globalOptions = Attribute.GetCustomAttributes(GetType(), typeof(Attribute)).Where
                                            (f => f.GetType().GetInterface(typeof(IGUILayoutOption).FullName) != null);

                    // Virtualizing field.
                    var element = InstantiateMember(ref virtualLayer, member, globalOptions);

                    // Generating metadata.
                    var meta = new Virtualization.VirtualizedItemMeta(element, ref virtualLayer, member);

                    // Registring via the virtualized elements.
                    VirtualizedElements.Add(meta);

                    return(meta.Field);
                }
            }
            else
            {
                return(RegistredFields[member] as IGUIField);
            }
        }
예제 #5
0
        /// <summary>
        /// Instantiating member of descriptor.
        /// </summary>
        /// <param name="layer">Layer that will be shared to the elemen OnLayout handler.</param>
        /// <param name="memberMeta">Target member.</param>
        /// <param name="globalOptions">Options of the descriptor.</param>
        /// <returns></returns>
        private object InstantiateMember(ref LayoutLayer layer,
                                         MembersHandler.MemberMeta memberMeta,
                                         IEnumerable <Attribute> globalOptions)
        {
            #region Definig handler
            // The handler that will apply options to the element.
            void ApplyOptionsHandler(
                FrameworkElement element,
                IEnumerable <Attribute> localAttributes)
            {
                if (element == null)
                {
                    return;
                }

                // Applying global options
                foreach (IGUILayoutOption option in globalOptions)
                {
                    option.ApplyLayoutOption(element);
                }

                // Perform options attributes.
                foreach (Attribute attr in localAttributes)
                {
                    // Skip if not an option.
                    if (!(attr is IGUILayoutOption option))
                    {
                        continue;
                    }

                    // Applying option to the element.
                    option.ApplyLayoutOption(element);
                }

                // Applying the shared options.
                foreach (ISharableGUILayoutOption option in SharedLayoutOptions)
                {
                    // Applying option to the element.
                    option.ApplyLayoutOption(element);
                }
            }

            #endregion

            // Getting all attributes.
            IEnumerable <Attribute> attributes = memberMeta.Member.GetCustomAttributes <Attribute>(true);

            #region Perform general layout attributes
            // Perform general attributes.
            foreach (Attribute attr in attributes)
            {
                // Skip if an option.
                if (attr is IGUILayoutOption)
                {
                    continue;
                }

                // Apply layout control to GUI.
                if (attr is IGUIElement attrControl)
                {
                    attrControl.OnLayout(ref layer, this, memberMeta);
                }
            }
            #endregion


            #region Defining UI field type
            // Check if default control was overrided by custom one.
            var  customControlDesc = memberMeta.Member.GetCustomAttribute <CustomControlAttribute>();
            Type controlType;
            if (customControlDesc != null &&           // Is overriding requested?
                customControlDesc.ControlType != null) // Is target type is not null
            {
                // Set redefined control like target to instinitation.
                controlType = customControlDesc.ControlType;
            }
            else
            {
                //// Looking for the certain control only for derect defined descriptors.
                //if (memberMeta.SourceType.IsSubclassOf(typeof(UIDescriptor)))
                //{
                //    // Set binded type like target to instiniation.
                //    controlType = LayoutHandler.GetBindedControl(memberMeta.SourceType, false);
                //}
                //else
                {
                    // Set binded type like target to instiniation.
                    controlType = LayoutHandler.GetBindedControl(memberMeta.SourceType, true);
                }
            }
            #endregion

            // Is control defined to that member?
            if (controlType != null)
            {
                // Instiniating target control by the type.
                var control = (IGUIField)Activator.CreateInstance(controlType);

                #region Set prefix label
                // Is spawned elelment has a label.
                if (control is UI.Controls.ILabel label)
                {
                    // Instiniating handle that will provide managmend of the control.
                    ContentAttribute localizationHandler;

                    // Try to get described one.
                    if (UniformDataOperator.AssembliesManagement.MembersHandler.
                        TryToGetAttribute(memberMeta.Member, out ContentAttribute attribute))
                    {
                        // Buferize if found.
                        localizationHandler = attribute;
                    }
                    else
                    {
                        // Initialize new one.
                        localizationHandler = ContentAttribute.Empty;
                    }

                    // Binding spawned element to the conent.
                    localizationHandler.BindToLabel(label, memberMeta.Member);
                }
                #endregion

                #region Perform Layout options
                // Check if spawned control is framework element.
                if (control is FrameworkElement fEl)
                {
                    // Applying options to the element.
                    ApplyOptionsHandler(fEl, attributes);
                }
                #endregion

                #region Binding to a layout
                // Sign up this control on desctiptor events.
                TryToBindControl(control, this, memberMeta.Member);

                // Adding instiniated element to the layout.
                //activeLayer?.ApplyControl(control as FrameworkElement);

                // Initialize control.
                control.OnLayout(ref layer, this, memberMeta.Member, globalOptions, attributes);

                // Adding field to the registration table.
                RegistredFields.Add(memberMeta.Member, control);
                #endregion

                return(control);
            }
            else
            {
                // Check if that just other descriptor.
                if (memberMeta.SourceType.IsSubclassOf(typeof(UIDescriptor)))
                {
                    //#region Configurating layout
                    //// Add horizontal shift for sub descriptor.
                    //new BeginHorizontalGroupAttribute().OnLayout(ref activeLayer);
                    //new Controls.SpaceAttribute().OnLayout(ref activeLayer);

                    // Add vertical group.
                    var vertGroup = new BeginVerticalGroupAttribute();
                    vertGroup.OnLayout(ref layer, this, memberMeta);
                    //#endregion

                    #region Applying options to the new root
                    // Applying options to the element.
                    ApplyOptionsHandler(vertGroup.Layer.root as FrameworkElement, attributes);

                    #endregion

                    #region Looking for descriptor object.
                    // Bufer that will contain value of the descriptor.
                    // Trying to get value via reflection.
                    UIDescriptor subDesc = memberMeta.Property != null?
                                           memberMeta.Property.GetValue(this) as UIDescriptor:// Operate like property.
                                           memberMeta.Field.GetValue(this) as UIDescriptor;

                    // Instiniate default in case if value is null.
                    if (subDesc == null)
                    {
                        try
                        {
                            // Insiniate empty constructor.
                            subDesc = Activator.CreateInstance(memberMeta.SourceType) as UIDescriptor;
                        }
                        catch (Exception ex)
                        {
                            // Log error.
                            MessageBox.Show("UIDescriptor must contain empty constructor, " +
                                            "or be instiniated before calling into UI." +
                                            "\n\nDetails:\n" + ex.Message);

                            // Skip to the next member.
                            return(null);
                        }

                        // Updating stored value for current member.
                        if (memberMeta.Property != null)
                        {
                            memberMeta.Property.SetValue(this, subDesc);
                        }
                        else
                        {
                            memberMeta.Field.SetValue(this, subDesc);
                        }
                    }

                    // Defining the sharable options.
                    var sharableOption = InsertSharableOptions(SharedLayoutOptions, attributes, true);
                    sharableOption = InsertSharableOptions(sharableOption, globalOptions, false);
                    subDesc.SharedLayoutOptions = sharableOption.ToArray();
                    #endregion

                    // Binding descriptor to the UI.
                    Panel subPanel = (Panel)layer.root;

                    if (subDesc.IsVirtualized)
                    {
                        _ = subDesc.BindToAsync(subPanel);
                    }
                    else
                    {
                        subDesc.BindTo(subPanel);
                    }

                    // End descriptor layer.
                    new EndGroupAttribute().OnLayout(ref layer);

                    // Subscribing on the sub descriptor changed update.
                    subDesc.ValueChanged += OnValueChangedCallback;

                    return(subPanel);
                }
            }

            return(null);
        }
예제 #6
0
 /// <summary>
 /// Instantiating member of descriptor.
 /// </summary>
 /// <param name="layer">Layer that will be shared to the elemen OnLayout handler.</param>
 /// <param name="member">Target member.</param>
 /// <param name="globalOptions">Options of the descriptor.</param>
 /// <returns></returns>
 private object InstantiateMember(ref LayoutLayer layer,
                                  MemberInfo member,
                                  IEnumerable <Attribute> globalOptions)
 {
     return(InstantiateMember(ref layer, new MembersHandler.MemberMeta(member), globalOptions));
 }
예제 #7
0
        /// <summary>
        /// Insiniate UI by descriptor's attributes map and add it as child to parent element.
        /// </summary>
        /// <param name="root">UI element that would contain instiniated UI elemets.</param>
        public void BindTo(Panel root)
        {
            #region Getting descripting data
            // Getting relevant type.
            var selfType = this.GetType();

            // Getting options applied to every memeber.
            var globalOptions = Attribute.GetCustomAttributes(selfType, typeof(Attribute)).Where
                                    (f => f.GetType().GetInterface(typeof(IGUILayoutOption).FullName) != null);

            // Get all memebers.
            var members = selfType.GetMembers();

            // Sorting by order.
            var orderedMembers = members.Where(f => f.GetCustomAttribute <OrderAttribute>() != null).
                                 OrderBy(f => f.GetCustomAttribute <OrderAttribute>().Order);

            // Sorting disordered members by metadata.
            var disorderedMembers = members.Where(f => f.GetCustomAttribute <OrderAttribute>() == null).
                                    OrderBy(f => f.MetadataToken);
            #endregion

            // Sort in declaretion order.
            members = orderedMembers.Concat(disorderedMembers).ToArray();

            // Instiniate first UILayer.
            activeLayer = new LayoutLayer()
            {
                root = root // Thet binding target as root for cuurent layer.
            };

            // Perform all descriptor map.
            foreach (MemberInfo member in members)
            {
                #region Validation
                // Skip if the member is not field or property.
                if (!MembersHandler.GetSpecifiedMemberInfo(
                        member, out PropertyInfo prop, out FieldInfo field))
                {
                    continue;
                }

                // Skip if member excluded from instpector.
                if (member.GetCustomAttribute <HideInInspectorAttribute>() != null)
                {
                    continue;
                }
                #endregion

                // Getting all attributes.
                var attributes = member.GetCustomAttributes <Attribute>(true);

                // Allocating and defining types.
                var  memberType  = MembersHandler.GetSpecifiedMemberType(member);
                Type controlType = null;

                #region Perform general layout attributes
                // Perform general attributes.
                foreach (Attribute attr in attributes)
                {
                    // Skip if an option.
                    if (attr is IGUILayoutOption)
                    {
                        continue;
                    }

                    // Apply layout control to GUI.
                    if (attr is IGUIElement attrControl)
                    {
                        attrControl.OnLayout(ref activeLayer, this, member);
                    }
                }
                #endregion


                #region Defining UI field type
                // Check if default control was overrided by custom one.
                var customControlDesc = member.GetCustomAttribute <CustomControlAttribute>();
                if (customControlDesc != null &&                                   // Is overriding requested?
                    customControlDesc.ControlType != null &&                       // Is target type is not null?
                    customControlDesc.ControlType.IsSubclassOf(typeof(IGUIField))) // Is target type has correct inherience
                {
                    // Set redefined control like target to instinitation.
                    controlType = customControlDesc.ControlType;
                }
                else
                {
                    // Set binded type like target to instiniation.
                    controlType = LayoutHandler.GetBindedControl(memberType, true);
                }
                #endregion

                // Is control defined to that member?
                if (controlType != null)
                {
                    #region Insiniation UI field
                    // Instiniating target type.
                    var control = (IGUIField)Activator.CreateInstance(controlType);

                    // Sing up this control on desctiptor events.
                    TryToBindControl(control, this, member);

                    // Initialize control.
                    control.OnLayout(ref activeLayer, this, member);

                    // Adding field to the registration table.
                    RegistredFields.Add(member, control);
                    #endregion

                    #region Set prefix label
                    // Is spawned elelment has a label.
                    if (control is UI.Controls.ILabel label)
                    {
                        // Instiniating handle that will provide managmend of the control.
                        ContentAttribute localizationHandler = null;

                        // Try to get described one.
                        if (UniformDataOperator.AttributesHandler.
                            TryToGetAttribute(member, out ContentAttribute attribute))
                        {
                            // Buferize if found.
                            localizationHandler = attribute;
                        }
                        else
                        {
                            // Initialize new one.
                            localizationHandler = ContentAttribute.Empty;
                        }

                        // Binding spawned element to the conent.
                        localizationHandler.BindToLable(label, member);
                    }
                    #endregion

                    #region Perform Layout options
                    // Check if spawned control is framework element.
                    if (control is FrameworkElement fEl)
                    {
                        // Applying global options
                        foreach (IGUILayoutOption option in globalOptions)
                        {
                            option.ApplyLayoutOption(fEl);
                        }

                        // Perform options attributes.
                        foreach (Attribute attr in attributes)
                        {
                            // Skip if not an option.
                            if (!(attr is IGUILayoutOption option))
                            {
                                continue;
                            }

                            // Applying option to the element.
                            option.ApplyLayoutOption(fEl);
                        }
                    }
                    #endregion
                }
                else
                {
                    // Check if that just other descriptor.
                    if (memberType.IsSubclassOf(typeof(UIDescriptor)))
                    {
                        #region Configurating layout
                        // Add horizontal shift for sub descriptor.
                        new BeginHorizontalGroupAttribute().OnLayout(ref activeLayer);
                        new Controls.SpaceAttribute(10).OnLayout(ref activeLayer);

                        // Add vertical group.
                        var vertGroup = new BeginVerticalGroupAttribute();
                        vertGroup.OnLayout(ref activeLayer);
                        #endregion

                        #region Looking for descriptor object.
                        // Bufer that will contain value of the descriptor.
                        UIDescriptor subDesc = null;

                        // Trying to get value via reflection.
                        subDesc = prop != null?
                                  prop.GetValue(this) as UIDescriptor:  // Operate like property.
                                  field.GetValue(this) as UIDescriptor; // Operate like fields.

                        // Instiniate default in case if value is null.
                        if (subDesc == null)
                        {
                            try
                            {
                                // Insiniate empty constructor.
                                subDesc = Activator.CreateInstance(memberType) as UIDescriptor;
                            }
                            catch (Exception ex)
                            {
                                // Log error.
                                MessageBox.Show("UIDescriptor must contain empty constructor, " +
                                                "or be instiniated before calling into UI." +
                                                "\n\nDetails:\n" + ex.Message);

                                // Skip to the next member.
                                continue;
                            }

                            // Updating stored value for current member.
                            if (prop != null)
                            {
                                prop.SetValue(this, subDesc);
                            }
                            else
                            {
                                field.SetValue(this, subDesc);
                            }
                        }
                        #endregion

                        // Binding descriptor to the UI.
                        subDesc.BindTo((Panel)activeLayer.root);
                    }
                }
            }

            // Marking as loaded.
            IsLoaded = true;

            // Inform subscribers.
            Loaded?.Invoke(this);
        }
예제 #8
0
        /// <summary>
        /// Insiniate UI by descriptor's attributes map and add it as child to parent element.
        /// </summary>
        /// <param name="layer">UI layer that will used as a root for the descriptor's elements.</param>
        public void BindTo(LayoutLayer layer)
        {
            // Storing layer.
            RootLayer   = layer;
            activeLayer = layer;

            #region Getting descripting data
            // Getting relevant type.
            var selfType = this.GetType();

            // Getting options applied to every memeber.
            var globalOptions = Attribute.GetCustomAttributes(selfType, typeof(Attribute)).Where
                                    (f => f.GetType().GetInterface(typeof(IGUILayoutOption).FullName) != null);

            // Get all memebers.
            var members = selfType.GetMembers();

            // Sorting by order.
            var orderedMembers = members.Where(f => f.GetCustomAttribute <OrderAttribute>() != null).
                                 OrderBy(f => f.GetCustomAttribute <OrderAttribute>().Order);

            // Sorting disordered members by metadata.
            var disorderedMembers = members.Where(f => f.GetCustomAttribute <OrderAttribute>() == null).
                                    OrderBy(f => f.MetadataToken);
            #endregion

            // Sort in declaretion order.
            members = orderedMembers.Concat(disorderedMembers).ToArray();

            // Perform all descriptor map.
            foreach (MemberInfo member in members)
            {
                var memberMeta = new MembersHandler.MemberMeta(member);

                #region Validation
                // Skip if the member is not field or property.
                if (!memberMeta.IsValue)
                {
                    continue;
                }

                // Skip if member excluded from instpector.
                if (member.GetCustomAttribute <HideInInspectorAttribute>() != null)
                {
                    continue;
                }
                #endregion

                // Instantiating a field from member.
                var field = InstantiateMember(ref activeLayer, memberMeta, globalOptions);

                // Skip in case if not instantiated.
                if (field == null)
                {
                    continue;
                }

                // Applying to the layout.
                activeLayer?.ApplyControl(field as FrameworkElement);
            }

            // Marking as loaded.
            IsLoaded = true;

            // Calling the local handler.
            OnLoaded();

            // Inform subscribers.
            Loaded?.Invoke(this);
        }
        /// <summary>
        /// Binding UIDescriptor content to the layer's root.
        /// </summary>
        /// <param name="layer">Target layer.</param>
        public async Task BindToAsync(LayoutLayer layer)
        {
            // Storing layer.
            RootLayer   = layer;
            activeLayer = layer;

            #region Getting descripting data
            // Getting relevant type.
            var selfType = this.GetType();

            // Getting options applied to every memeber.
            var globalOptions = Attribute.GetCustomAttributes(selfType, typeof(Attribute)).Where
                                    (f => f.GetType().GetInterface(typeof(IGUILayoutOption).FullName) != null);

            // Get all memebers.
            var members = selfType.GetMembers();

            // Sorting by order.
            var orderedMembers = members.Where(f => f.GetCustomAttribute <OrderAttribute>() != null).
                                 OrderBy(f => f.GetCustomAttribute <OrderAttribute>().Order);

            // Sorting disordered members by metadata.
            var disorderedMembers = members.Where(f => f.GetCustomAttribute <OrderAttribute>() == null).
                                    OrderBy(f => f.MetadataToken);
            #endregion

            // Sort in declaretion order.
            members = orderedMembers.Concat(disorderedMembers).ToArray();

            // Perform all descriptor map.
            foreach (MemberInfo member in members)
            {
                var memberMeta = new MembersHandler.MemberMeta(member);

                #region Validation
                // Skip if the member is not field or property.
                if (!memberMeta.IsValue)
                {
                    continue;
                }

                // Skip if member excluded from instpector.
                if (member.GetCustomAttribute <HideInInspectorAttribute>() != null)
                {
                    continue;
                }
                #endregion

                #region Virtualization
                // Suspending virtualization
                if (IsVirtualized &&
                    virtualizedPackCounter == VirtualizedItemsPack)
                {
                    // Droping the counter.
                    virtualizedPackCounter = 0;

                    // Waiting till loading.
                    while (!lastVirtualizedElement.IsLoaded)
                    {
                        await Task.Delay(5);
                    }

                    Panel rootPanel = (Panel)RootLayer.root;

                    // Checking if the last element still in the visible bounds.
                    bool isVisible = LayoutHandler.IsUserVisible(lastVirtualizedElement, Window.GetWindow(lastVirtualizedElement));

                    // Suspending if the last not visible till view update.
                    if (!isVisible)
                    {
                        // Marker that using for blocking the thread.
                        bool unlocked = false;

                        var window = Window.GetWindow(lastVirtualizedElement);

                        // Waiting till the root will change a size/
                        window.Activated      += Activated;
                        rootPanel.SizeChanged += SizeChanged;

                        void Activated(object sender, EventArgs e)
                        {
                            VirtValHandler();
                        };

                        void SizeChanged(object sender, SizeChangedEventArgs e)
                        {
                            VirtValHandler();
                        };

                        void VirtValHandler()
                        {
                            // Checking if the last element is already visible.
                            isVisible = LayoutHandler.IsUserVisible(lastVirtualizedElement, window);
                            if (isVisible)
                            {
                                // Unsubscribing from event.
                                window.Activated      -= Activated;
                                rootPanel.SizeChanged -= SizeChanged;

                                // Unblocking the thread.
                                unlocked = true;
                            }
                        }

                        // Unblocking instantiation of next group of elements.
                        while (!unlocked)
                        {
                            await Task.Delay(5);
                        }
                    }
                }

                #endregion

                if (!(RegistredFields[member] is IGUIField virtualizedElement))
                {
                    // Instantiating a member.
                    var field = InstantiateMember(ref activeLayer, memberMeta, globalOptions);

                    // Skip in case if not instantiated.
                    if (field == null)
                    {
                        continue;
                    }

                    // Storing in virtualization meta.
                    var meta = new VirtualizedItemMeta(
                        field,
                        ref activeLayer,
                        member);

                    // Settup into virtualization system.
                    lastVirtualizedElement = meta.Element ?? lastVirtualizedElement;
                    //VirtualizedElements.Add(meta);

                    // Applying to the layout.
                    activeLayer?.ApplyControl(field as FrameworkElement);
                }