コード例 #1
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);
        }
コード例 #2
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);
        }
コード例 #3
0
        /// <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);
                }