vchelaru / Gum

Flexible layout tool for creating UI on any platform

Home Page:http://gumui.net/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add the ability for the user to create arbitrary variables

vchelaru opened this issue · comments

Overview

Users should be able to add arbitrary variables to their Components. New variables will behave as if they are part of the component natively (such as X and X Units). This means that they should appear:

  • On the component when the component is selected
  • On instances of the component when an instance of the component is selected
  • On derived components
  • On instances of derived components
  • In states of the component
  • As variables which can be propagated in state categories
  • On either side of a variable reference, and should push changes to other components on changes

Screens and Standard Elements

We should not (currently) allow users to add new variables to Standard Elements as this may conflict with the Standard Elements Manager. Additional variables to Standard Elements may be added in the future if needed. Variables in Screens may be added here too, but I don't know if they are needed, so we'll do whatever is easiest.

Details

The idea for arbitrary variables was originally explored in this issue:

#103

The original idea was to create a set of global variables which can be referenced. This is extra work which is not necessary because variable references on components is already working fine.

For reference: https://flatredball.gitbook.io/gum/gum-elements/general-properties/variable-references

Variable References have been used on a number of projects so far, including at Tula for styling, so they have been proven out.

Currently variables in components originate from a default state in some base Standard Element. Since all Components ultimately derive from a Standard Element type, then most variables that appear in Gum for any instance ultimately come from a Standard Element definition.

If a component changes its base type, old variables are still stored on the component in data, but do not appear in the variable grid. Gum knows whether a variable should be shown or not depending on whether a variable is ultimately defined in one of these default states.

Note this is also the case for exposed variables, which ultimately come from a Standard Element as well.

Therefore, when a new variable is added, it must have a dedicated flag to indicate that this variable should be shown in the UI, even though it is not defined in the base standard element. Hopefully this does not require too much extra code.

Currently variables on components are saved as shown in the following XML:

    <Variable>
      <Type>float</Type>
      <Name>Y</Name>
      <Value xsi:type="xsd:float">14</Value>
      <SetsValue>true</SetsValue>
    </Variable>

The new property will be called IsCustomVariable which will be true if the user added the variable to the component at the current level.

    <Variable>
      <Type>float</Type>
      <Name>MyCustomVariable</Name>
      <Value xsi:type="xsd:float">14</Value>
      <IsCustomVariable>true</IsCustomVariable>
      <SetsValue>true</SetsValue>
    </Variable>

This value will not appear on derived components or instances, only on the Component which defined the variable. To prevent XML bloat and huge diffs, this value should only serialize if true (use the ShouldSerializeXXXXX method).

UI

Components will have an Add Variable button on their Variables tab, just like Behaviors.

image

New variables will appear as normal in the UI. They have all of the same right-click options as other variables, but also have a right-click option to remove the variable.

Should removal of the variables also remove them from all instances? Or should it keep them there as orphaned variables, the way variables are kept when a type changes? I suppose since we already have this concept for variables that are orphaned by type changes, we should do the same here. Hidden variable cleanup can be a separate Github issue if it becomes a problem.

Codegen Considerations

FlatRedBall, Xamarin.Forms, and MAUI plugins have their own logic for determining whether a variable should be generated. After this feature is implemented, all codegen systems should be inspected to handle these variables. The easiest way is to exclude these variables completely, but over time we will want to support this through codegen as well.