A class that provides context to code that is building a visual tree from markup and binding it to a view model
Esempio n. 1
0
        public static ConsolePanel ParsePanel(string markup, object viewModel = null)
        {
            ParserContext context = new ParserContext()
            {
                RootElement = new XmlElement(markup),
                RootViewModel = viewModel,
                CurrentViewModel = viewModel,
            };

            var panel = new ConsolePanel();
            ParsePanel(context, panel);
            return panel;
        }
Esempio n. 2
0
        public static ConsoleApp Parse(string markup, object viewModel = null)
        {
            ParserContext context = new ParserContext()
            {
                RootElement = new XmlElement(markup),
                RootViewModel = viewModel,
                CurrentViewModel = viewModel,
            };

            var app = ParseApp(context);

            return app;
        }
        public void Process(ParserContext context)
        {
            var button = context.CurrentControl as Button;
            var textValue = context.CurrentElement["Shortcut"];
            var key = (ConsoleKey)Enum.Parse(typeof(ConsoleKey), textValue);

            ConsoleModifiers? modifier = null;

            if(context.CurrentElement["Shortcut-Modifier"] != null)
            {
                modifier = (ConsoleModifiers)Enum.Parse(typeof(ConsoleModifiers),context.CurrentElement["Shortcut-Modifier"]);
            }

            button.Shortcut = new KeyboardShortcut(key, modifier);
        }
 public void Process(ParserContext context)
 {
 }
Esempio n. 5
0
 public void Process(ParserContext context)
 {
 }
Esempio n. 6
0
        private static ConsoleApp ParseApp(ParserContext context)
        {
            context.CurrentElement = context.RootElement;

            var x = context.CurrentElement.Attribute<int>("X");
            var y = context.CurrentElement.Attribute<int>("Y");
            var w = context.CurrentElement.Attribute<int>("Width");
            var h = context.CurrentElement.Attribute<int>("Height");

            ConsoleApp app;
            if (x.HasValue | y.HasValue | w.HasValue | h.HasValue)
            {
                var xV = x.HasValue ? x.Value : 0;
                var yV = y.HasValue ? y.Value : 0;
                var wV = w.HasValue ? w.Value : ConsoleProvider.Current.BufferWidth - xV;
                var hV = h.HasValue ? h.Value : ConsoleProvider.Current.WindowHeight - yV;
                app = new ConsoleApp(xV, yV, wV, hV);
            }
            else
            {
                app = new ConsoleApp();
            }

            ParsePanel(context, app.LayoutRoot);
            return app;
        }
Esempio n. 7
0
 private static ConsoleControl CreateControl(ParserContext context)
 {
     var controlTypeName = context.CurrentElement.Name;
     var controlFullTypeName = $"PowerArgs.Cli.{controlTypeName}";
     var controlType = typeof(Args).Assembly.GetType(controlFullTypeName);
     var control = (ConsoleControl)Activator.CreateInstance(controlType);
     return control;
 }
Esempio n. 8
0
        private static void SetPropertyFromTextValue(ParserContext context, ConsoleControl control, PropertyInfo property, string textValue)
        {
            bool isObservable = textValue.StartsWith("{") && textValue.EndsWith("}");

            if (isObservable)
            {
                var observablePropertyName = textValue.Substring(1, textValue.Length - 2);
                var viewModelObservable = context.CurrentViewModel as ObservableObject;
                if (viewModelObservable == null) throw new InvalidOperationException("View model is not observable");
                new ViewModelBinding(control, property, viewModelObservable, observablePropertyName);
            }
            else if(property.HasAttr<MarkupPropertyAttribute>())
            {
                property.Attr<MarkupPropertyAttribute>().Processor.Process(context);
            }
            else if (property.PropertyType == typeof(string))
            {
                property.SetValue(control, textValue);
            }
            else if (property.PropertyType == typeof(ConsoleString))
            {
                property.SetValue(control, new ConsoleString(textValue));
            }
            else if (property.PropertyType.IsEnum)
            {
                var enumVal = Enum.Parse(property.PropertyType, textValue);
                property.SetValue(control, enumVal);
            }
            else if (property.PropertyType == typeof(Event))
            {
                Event ev = property.GetValue(control) as Event;
                var target = context.CurrentViewModel;
                Action handler = () =>
                {
                    var method = target.GetType().GetMethod(textValue, new Type[0]);
                    if (method != null)
                    {
                        method.Invoke(target, new object[0]);
                    }
                    else
                    {
                        var action = target.GetType().GetProperty(textValue);
                        if (action == null || action.PropertyType != typeof(Action))
                        {
                            throw new InvalidOperationException("Not a method or action");
                        }

                        ((Action)action.GetValue(target)).Invoke();
                    }
                };

                ev.SubscribeForLifetime(handler, control.LifetimeManager);
            }
            else
            {
                var parseMethod = property.PropertyType.GetMethod("Parse", new Type[] { typeof(string) });
                var parsed = parseMethod.Invoke(null, new object[] { textValue });
                property.SetValue(control, parsed);
            }
        }
Esempio n. 9
0
        private static void ParsePanel(ParserContext context, ConsolePanel panel)
        {
            var myElement = context.CurrentElement;
            context.CurrentControl = panel;
            ParseControlAttributes(panel, context);

            foreach (var childElement in context.CurrentElement.Elements)
            {
                context.CurrentElement = childElement;
                var childControl = CreateControl(context);
                context.CurrentControl = childControl;
                panel.Add(childControl);

                if (childControl is ConsolePanel)
                {
                    ParsePanel(context, childControl as ConsolePanel);
                }
                else
                {
                    ParseControlAttributes(childControl, context);
                }
            }

            context.CurrentElement = myElement;
            context.CurrentControl = panel;
        }
Esempio n. 10
0
        private static void ParseControlAttributes(ConsoleControl control, ParserContext context)
        {
            foreach (var attribute in context.CurrentElement.Attributes)
            {
                var extensions = control.GetType().Attrs<MarkupExtensionAttribute>().Where(a => a.AttributeName == attribute.Name);

                if(extensions.Count() > 1)
                {
                    throw new InvalidOperationException("More than 1 extension registered for property "+attribute.Name);
                }
                else if(extensions.Count() == 1)
                {
                    extensions.First().Processor.Process(context);
                }
                else
                {
                    var propertyInfo = control.GetType().GetProperty(attribute.Name);
                    var methodInfo = control.GetType().GetMethod(attribute.Name);
                    if (propertyInfo.GetGetMethod() == null || propertyInfo.GetSetMethod() == null)
                    {
                        if (propertyInfo.PropertyType == typeof(Event))
                        {
                            // there is special handling for events downstream so let this through
                        }
                        else
                        {
                            throw new InvalidOperationException($"Property {control.GetType().FullName}.{attribute.Name} does not have a public getter and setter");
                        }
                    }

                    SetPropertyFromTextValue(context, control, propertyInfo, attribute.Value);
                }
            }
        }