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); }
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); } } }
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; }}"); }
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)}();"); }
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)};"); } } }
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); }
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; } } }
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 }
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); }
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(); } }
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); } } } }
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); }
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) + "}"); }