예제 #1
0
        private static string GetClassNameForType(string gumType, VisualApi visualApi)
        {
            string className          = null;
            var    specialHandledCase = false;

            if (visualApi == VisualApi.XamarinForms)
            {
                switch (gumType)
                {
                case "Text":
                    className          = "Label";
                    specialHandledCase = true;
                    break;
                }
            }

            if (!specialHandledCase)
            {
                var strippedType = gumType;
                if (strippedType.Contains("/"))
                {
                    strippedType = strippedType.Substring(strippedType.LastIndexOf("/") + 1);
                }

                string suffix = visualApi == VisualApi.Gum ? "Runtime" : "";
                className = $"{strippedType}{suffix}";
            }
            return(className);
        }
예제 #2
0
        private static void FillWithVariableAssignments(ElementSave element, VisualApi visualApi, StringBuilder stringBuilder, int tabCount = 0)
        {
            #region Get variables to consider
            var defaultState = SelectedState.Self.SelectedElement.DefaultState;

            var baseElement = ObjectFinder.Self.GetElementSave(element.BaseType);
            RecursiveVariableFinder recursiveVariableFinder = null;

            // This is null if it's a screen, or there's some bad reference
            if (baseElement != null)
            {
                recursiveVariableFinder = new RecursiveVariableFinder(baseElement.DefaultState);
            }


            var variablesToConsider = defaultState.Variables
                                      .Where(item =>
            {
                var shouldInclude =
                    item.Value != null &&
                    item.SetsValue &&
                    string.IsNullOrEmpty(item.SourceObject);

                if (shouldInclude && recursiveVariableFinder != null)
                {
                    // We want to make sure that the variable is defined in the base object. If it isn't, then
                    // it could be a leftover variable caused by having this object be of one type, using a variable
                    // specific to that type, then changing it to another type. Gum holds on to these varibles in case
                    // the type change was accidental, but it means we have to watch for these orphan variables when generating.
                    var foundVariable = recursiveVariableFinder.GetVariable(item.Name);
                    shouldInclude     = foundVariable != null;
                }

                return(shouldInclude);
            })
                                      .ToList();

            #endregion

            var tabs = new String(' ', 4 * tabCount);

            ProcessVariableGroups(variablesToConsider, defaultState, null, element, visualApi, stringBuilder, tabCount);

            foreach (var variable in variablesToConsider)
            {
                var codeLine = GetCodeLine(null, variable, element, visualApi, defaultState);
                stringBuilder.AppendLine(tabs + codeLine);

                var suffixCodeLine = GetSuffixCodeLine(null, variable, visualApi);
                if (!string.IsNullOrEmpty(suffixCodeLine))
                {
                    stringBuilder.AppendLine(tabs + suffixCodeLine);
                }
            }
        }
예제 #3
0
        private static void FillWithInstanceDeclaration(InstanceSave instance, ElementSave container, StringBuilder stringBuilder, int tabCount = 0)
        {
            VisualApi visualApi = VisualApi.Gum;

            var defaultState = container.DefaultState;
            var isXamForms   = defaultState.GetValueRecursive($"{instance.Name}.IsXamarinFormsControl") as bool?;

            if (isXamForms == true)
            {
                visualApi = VisualApi.XamarinForms;
            }

            var tabs = new String(' ', 4 * tabCount);

            string className = GetClassNameForType(instance.BaseType, visualApi);

            bool   isPublic     = true;
            string accessString = isPublic ? "public " : "";

            stringBuilder.AppendLine($"{tabs}{accessString}{className} {instance.Name} {{ get; private set; }}");
        }
예제 #4
0
        private static void FillWithInstanceInstantiation(InstanceSave instance, ElementSave element, StringBuilder stringBuilder, int tabCount = 0)
        {
            var strippedType = instance.BaseType;

            if (strippedType.Contains("/"))
            {
                strippedType = strippedType.Substring(strippedType.LastIndexOf("/") + 1);
            }
            var tabs = new String(' ', 4 * tabCount);

            VisualApi visualApi = VisualApi.Gum;

            var defaultState = element.DefaultState;
            var isXamForms   = defaultState.GetValueRecursive($"{instance.Name}.IsXamarinFormsControl") as bool?;

            if (isXamForms == true)
            {
                visualApi = VisualApi.XamarinForms;
            }

            stringBuilder.AppendLine($"{tabs}{instance.Name} = new {GetClassNameForType(instance.BaseType, visualApi)}();");
        }
예제 #5
0
        private static string GetCodeLine(InstanceSave instance, VariableSave variable, ElementSave container, VisualApi visualApi, StateSave state)
        {
            string instancePrefix = instance != null ? $"{instance.Name}." : "this.";

            if (visualApi == VisualApi.Gum)
            {
                var fullLineReplacement = TryGetFullGumLineReplacement(instance, variable);

                if (fullLineReplacement != null)
                {
                    return(fullLineReplacement);
                }
                else
                {
                    return($"{instancePrefix}{GetGumVariableName(variable, container)} = {VariableValueToGumCodeValue(variable, container)};");
                }
            }
            else // xamarin forms
            {
                var fullLineReplacement = TryGetFullXamarinFormsLineReplacement(instance, container, variable, state);
                if (fullLineReplacement != null)
                {
                    return(fullLineReplacement);
                }
                else
                {
                    return($"{instancePrefix}{GetXamarinFormsVariableName(variable)} = {VariableValueToXamarinFormsCodeValue(variable, container)};");
                }
            }
        }
예제 #6
0
        private static string GetSuffixCodeLine(InstanceSave instance, VariableSave variable, VisualApi visualApi)
        {
            if (visualApi == VisualApi.XamarinForms)
            {
                var rootName = variable.GetRootName();

                //switch(rootName)
                //{
                // We don't do this anymore now that we are stuffing forms objects in absolute layouts
                //case "Width": return $"{instance.Name}.HorizontalOptions = LayoutOptions.Start;";
                //case "Height": return $"{instance.Name}.VerticalOptions = LayoutOptions.Start;";
                //}
            }

            return(null);
        }
예제 #7
0
        private static void ProcessVariableGroups(List <VariableSave> variablesToConsider, StateSave defaultState, InstanceSave instance, ElementSave container, VisualApi visualApi, StringBuilder stringBuilder, int tabCount)
        {
            if (visualApi == VisualApi.XamarinForms)
            {
                string baseType = null;
                if (instance != null)
                {
                    baseType = instance.BaseType;
                }
                else
                {
                    baseType = container.BaseType;
                }
                switch (baseType)
                {
                case "Text":
                    ProcessColorForLabel(variablesToConsider, defaultState, instance, stringBuilder);
                    ProcessPositionAndSize(variablesToConsider, defaultState, instance, stringBuilder, tabCount);
                    break;

                default:
                    ProcessPositionAndSize(variablesToConsider, defaultState, instance, stringBuilder, tabCount);
                    break;
                }
            }
        }
예제 #8
0
        private static void FillWithVariableAssignments(InstanceSave instance, ElementSave container, StringBuilder stringBuilder, int tabCount = 0)
        {
            #region Get variables to consider

            var variablesToConsider = GetVariablesToConsider(instance)
                                      // make "Parent" first
                                      // .. actually we need to make parent last so that it can properly assign parent on scrollables
                                      .OrderBy(item => item.GetRootName() == "Parent")
                                      .ToList();

            #endregion

            #region Determine visual API (Gum or Forms)

            VisualApi visualApi = VisualApi.Gum;

            var defaultState = container.DefaultState;
            var isXamForms   = defaultState.GetValueRecursive($"{instance.Name}.IsXamarinFormsControl") as bool?;
            if (isXamForms == true)
            {
                visualApi = VisualApi.XamarinForms;
            }

            #endregion

            var tabs = new String(' ', 4 * tabCount);

            #region Name/Automation Id

            if (visualApi == VisualApi.Gum)
            {
                stringBuilder.AppendLine($"{tabs}{instance.Name}.Name = \"{instance.Name}\";");
            }
            else
            {
                // If defined by base, then the automation ID will already be set there, and
                // Xamarin.Forms doesn't like an automation ID being set 2x
                if (instance.DefinedByBase == false)
                {
                    stringBuilder.AppendLine($"{tabs}{instance.Name}.AutomationId = \"{instance.Name}\";");
                }
            }

            #endregion


            // sometimes variables have to be processed in groups. For example, RGB values
            // have to be assigned all at once in a Color value in XamForms;
            ProcessVariableGroups(variablesToConsider, container.DefaultState, instance, container, visualApi, stringBuilder, tabCount);

            foreach (var variable in variablesToConsider)
            {
                var codeLine = GetCodeLine(instance, variable, container, visualApi, defaultState);

                // the line of code could be " ", a string with a space. This happens
                // if we want to skip a variable so we dont return null or empty.
                // But we also don't want a ton of spaces generated.
                if (!string.IsNullOrWhiteSpace(codeLine))
                {
                    stringBuilder.AppendLine(tabs + codeLine);
                }

                var suffixCodeLine = GetSuffixCodeLine(instance, variable, visualApi);
                if (!string.IsNullOrEmpty(suffixCodeLine))
                {
                    stringBuilder.AppendLine(tabs + suffixCodeLine);
                }
            }

            // For scrollable GumContainers we need to have the parent assigned *after* the AbsoluteLayout rectangle:
            #region Assign Parent

            var hasParent = variablesToConsider.Any(item => item.GetRootName() == "Parent");

            if (!hasParent && !instance.DefinedByBase)
            {
                if (visualApi == VisualApi.Gum)
                {
                    // add it to "this"
                    stringBuilder.AppendLine($"{tabs}this.Children.Add({instance.Name});");
                }
                else // forms
                {
                    var instanceBaseType    = instance.BaseType;
                    var isGumCollectionView = instanceBaseType.EndsWith("/GumCollectionView");

                    if (isGumCollectionView)
                    {
                        stringBuilder.AppendLine($"{tabs}var tempFor{instance.Name} = GumScrollBar.CreateScrollableAbsoluteLayout({instance.Name}, ScrollableLayoutParentPlacement.Free);");
                        stringBuilder.AppendLine($"{tabs}MainLayout.Children.Add(tempFor{instance.Name});");
                    }
                    else
                    {
                        stringBuilder.AppendLine($"{tabs}MainLayout.Children.Add({instance.Name});");
                    }
                }
            }

            #endregion
        }
예제 #9
0
        public static string GetCodeForInstance(InstanceSave instance, ElementSave element, VisualApi visualApi)
        {
            var stringBuilder = new StringBuilder();

            FillWithInstanceDeclaration(instance, element, stringBuilder);

            FillWithInstanceInstantiation(instance, element, stringBuilder);

            FillWithVariableAssignments(instance, element, stringBuilder);

            var code = stringBuilder.ToString();

            return(code);
        }
예제 #10
0
        private static void FillWithExposedVariables(ElementSave element, StringBuilder stringBuilder, VisualApi visualApi, int tabCount)
        {
            var exposedVariables = element.DefaultState.Variables
                                   .Where(item => !string.IsNullOrEmpty(item.ExposedAsName))
                                   .ToArray();

            foreach (var exposedVariable in exposedVariables)
            {
                FillWithExposedVariable(exposedVariable, element, stringBuilder, tabCount);
                stringBuilder.AppendLine();
            }
        }
예제 #11
0
        private static void FillWithVariablesInState(ElementSave container, StateSave stateSave, StringBuilder stringBuilder, int tabCount)
        {
            VariableSave[] variablesToConsider = stateSave.Variables
                                                 // make "Parent" first
                                                 .Where(item => item.GetRootName() != "Parent")
                                                 .ToArray();

            var variableGroups = variablesToConsider.GroupBy(item => item.SourceObject);


            foreach (var group in variableGroups)
            {
                InstanceSave instance     = null;
                var          instanceName = group.Key;

                if (instanceName != null)
                {
                    instance = container.GetInstance(instanceName);
                }

                #region Determine visual API (Gum or Forms)

                VisualApi visualApi = VisualApi.Gum;

                var  defaultState = container.DefaultState;
                bool?isXamForms   = false;
                if (instance == null)
                {
                    isXamForms = defaultState.GetValueRecursive($"IsXamarinFormsControl") as bool?;
                }
                else
                {
                    isXamForms = defaultState.GetValueRecursive($"{instance.Name}.IsXamarinFormsControl") as bool?;
                }
                if (isXamForms == true)
                {
                    visualApi = VisualApi.XamarinForms;
                }

                #endregion

                ElementSave baseElement = null;
                if (instance == null)
                {
                    baseElement = Gum.Managers.ObjectFinder.Self.GetElementSave(container.BaseType) ?? container;
                }
                else
                {
                    baseElement = Gum.Managers.ObjectFinder.Self.GetElementSave(instance?.BaseType);
                }
                var baseDefaultState = baseElement?.DefaultState;
                RecursiveVariableFinder baseRecursiveVariableFinder = new RecursiveVariableFinder(baseDefaultState);


                List <VariableSave> variablesForThisInstance = group
                                                               .Where(item => GetIfVariableShouldBeIncludedForInstance(instance, item, baseRecursiveVariableFinder))
                                                               .ToList();


                ProcessVariableGroups(variablesForThisInstance, stateSave, instance, container, visualApi, stringBuilder, tabCount);

                // Now that they've been processed, we can process the remainder regularly
                foreach (var variable in variablesForThisInstance)
                {
                    var codeLine = GetCodeLine(instance, variable, container, visualApi, stateSave);
                    stringBuilder.AppendLine(ToTabs(tabCount) + codeLine);
                    var suffixCodeLine = GetSuffixCodeLine(instance, variable, visualApi);
                    if (!string.IsNullOrEmpty(suffixCodeLine))
                    {
                        stringBuilder.AppendLine(ToTabs(tabCount) + suffixCodeLine);
                    }
                }
            }
        }
예제 #12
0
        public static string GetCodeForState(ElementSave container, StateSave stateSave, VisualApi visualApi)
        {
            var stringBuilder = new StringBuilder();

            FillWithVariablesInState(container, stateSave, stringBuilder, 0);

            var code = stringBuilder.ToString();

            return(code);
        }
예제 #13
0
        private static void GenerateConstructor(ElementSave element, VisualApi visualApi, int tabCount, StringBuilder stringBuilder)
        {
            var elementName = GetClassNameForType(element.Name, visualApi);

            if (visualApi == VisualApi.Gum)
            {
                #region Constructor Header

                stringBuilder.AppendLine(ToTabs(tabCount) + $"public {elementName}(bool fullInstantiation = true)");

                stringBuilder.AppendLine(ToTabs(tabCount) + "{");
                tabCount++;

                #endregion

                #region Gum-required constructor code

                stringBuilder.AppendLine(ToTabs(tabCount) + "if(fullInstantiation)");
                stringBuilder.AppendLine(ToTabs(tabCount) + "{");
                tabCount++;

                if (element.BaseType == "Container")
                {
                    stringBuilder.AppendLine(ToTabs(tabCount) + "this.SetContainedObject(new InvisibleRenderable());");
                }

                stringBuilder.AppendLine();
                #endregion
            }
            else // xamarin forms
            {
                #region Constructor Header
                stringBuilder.AppendLine(ToTabs(tabCount) + $"public {elementName}()");

                stringBuilder.AppendLine(ToTabs(tabCount) + "{");
                tabCount++;

                #endregion


                stringBuilder.AppendLine(ToTabs(tabCount) + "var wasSuspended = GraphicalUiElement.IsAllLayoutSuspended;");
                stringBuilder.AppendLine(ToTabs(tabCount) + "GraphicalUiElement.IsAllLayoutSuspended = true;");

                var elementBaseType      = element?.BaseType;
                var isThisAbsoluteLayout = elementBaseType?.EndsWith("/AbsoluteLayout") == true;

                var isSkiaCanvasView = elementBaseType?.EndsWith("/SkiaGumCanvasView") == true;

                if (isThisAbsoluteLayout)
                {
                    stringBuilder.AppendLine(ToTabs(tabCount) + "var MainLayout = this;");
                }
                else if (!isSkiaCanvasView)
                {
                    var shouldAddMainLayout = true;
                    if (element is ScreenSave && !string.IsNullOrEmpty(element.BaseType))
                    {
                        shouldAddMainLayout = false;
                    }

                    if (shouldAddMainLayout)
                    {
                        stringBuilder.AppendLine(ToTabs(tabCount) + "MainLayout = new AbsoluteLayout();");
                        stringBuilder.AppendLine(ToTabs(tabCount) + "BaseGrid.Children.Add(MainLayout);");
                    }
                }
            }

            FillWithVariableAssignments(element, visualApi, stringBuilder, tabCount);

            stringBuilder.AppendLine();

            foreach (var instance in element.Instances.Where(item => item.DefinedByBase == false))
            {
                FillWithInstanceInstantiation(instance, element, stringBuilder, tabCount);
            }
            stringBuilder.AppendLine();

            foreach (var instance in element.Instances)
            {
                FillWithVariableAssignments(instance, element, stringBuilder, tabCount);
                stringBuilder.AppendLine();
            }

            stringBuilder.AppendLine(ToTabs(tabCount) + "CustomInitialize();");

            if (visualApi == VisualApi.Gum)
            {
                // close the if check
                tabCount--;
                stringBuilder.AppendLine(ToTabs(tabCount) + "}");
            }
            else
            {
                stringBuilder.AppendLine(ToTabs(tabCount) + "GraphicalUiElement.IsAllLayoutSuspended = wasSuspended;");
            }


            tabCount--;
            stringBuilder.AppendLine(ToTabs(tabCount) + "}");
        }