Пример #1
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);
        }
Пример #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)
        {
            #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);
        }