Skip to content

Tab Menu Controllers

Daniel Colina edited this page Jul 14, 2020 · 19 revisions

Tab menu controllers are specialized entity controllers that a control group of tab page controllers and corresponding tabs, which are simply toggle controllers with specialized tab properties. For reference on the separate components of a tab menu, see the graphic below.

Eh

The default implementation of a tab menu controller is the ATabMenuController<ATabMenuProperties> class. The controller handles automatically populating tab pages and tabs based on properties given to it at runtime.

ATabMenuController<TTabMenuProperties> has a generic type constraint where TTabMenuProperties must implement ITabMenuProperties. The ITabMenuProperties interface has one member property, TabPageProperties, which returns a List<ITabPageProperties>, which allows the properties of the tab menu to store a list of ITabPageProperties to drive the population of its tab pages.

Tab Page Controllers

Tab Controllers

For an example of these controllers working hand-in-hand, see the ExampleTabPageController which supports receiving IntegerTabPageProperties and StringTabPageProperties and will spawn IntegerTabPageController and StringTabPageController objects as well as ExampleTabController objects to open them.

#region ExampleTabController
[System.Serializable]
public class ExampleTabProperties
{
    public string label;
    public ExampleTabProperties(string label)
    {
        this.label = label;
    }
}

// This is a simple tab that stores a label in its properties and displays
// that value on its TextMeshProUGUI component.
public class ExampleTabController : AToggleController<ExampleTabProperties>
{
    [SerializeField] private TextMeshProUGUI label;

    protected override void OnPropertiesSet()
    {
        base.OnPropertiesSet();
        label.text = Properties.label;
    }
}
#endregion

#region IntegerTabPageController
// Make sure your custom tab page properties implement ITabPageProperties.
[System.Serializable]
public class IntegerTabPageProperties : ITabPageProperties
{
    // Each tab page's properties must return the properties of the tab the menu
    // will spawn to open it. Then, the impelementation of the tab menu that uses
    // this tab page decides which prefab to spawn based on the type of properties.
    public object TabProperties => new ExampleTabProperties("Integer");
    public int value;
    public IntegerTabPageProperties(int value)
    {
        this.value = value;
    }
}

// This is a simple tab page that stores a integer in its properties.
public class IntegerTabPageController : ATabPageController<IntegerTabPageProperties>{}
#endregion

#region BooleanTabPageController
// Make sure your custom tab page properties implement ITabPageProperties.
public class BooleanTabPageProperties : ITabPageProperties
{
    // Each tab page's properties must return the properties of the tab the menu
    // will spawn to open it. Then, the impelementation of the tab menu that uses
    // this tab page decides which prefab to spawn based on the type of properties.
    public object TabProperties => new ExampleTabProperties("Boolean");
    public bool value;
    public BooleanTabPageProperties(bool value)
    {
        this.value = value;
    }
}

// This is a simple tab page that stores a boolean in its properties.
public class BooleanTabPageController : ATabPageController<BooleanTabPageProperties>{}
#endregion

#region ExampleTabMenuController
// IMPORTANT: Note that these properties are not marked [System.Serializable];
// this is because it stores a list of interfaces, which Unity cannot serialize.
// Make sure your custom tab menu properties implement ITabMenuProperties
public class ExampleTabMenuProperties : ITabMenuProperties.
{
    public List<ITabPageProperties> TabPageProperties { get; }
    public ExampleTabMenuProperties(List<ITabPageProperties> tabPageProperties)
    {
        TabPageProperties = tabPageProperties;
    }
}

public class ExampleTabMenuController : ATabMenuController<ExampleTabMenuProperties>
{
    [SerializeField] private ExampleTabController exampleTabPrefab;
    [SerializeField] private IntegerTabPageController integerTabPagePrefab;
    [SerializeField] private BooleanTabPageController booleanTabPagePrefab;

    protected override IToggleController GetTab(object tabProperties)
    {
        if (tabProperties is ExampleTabProperties exampleTabProperties)
        {
            ExampleTabController exampleTab = SpawnTab(exampleTabPrefab) as ExampleTabController;
            exampleTab.SetProperties(exampleTabProperties);
            exampleTab.name = $"[ExampleTab] {exampleTabProperties.label}";
            return exampleTab;
        }
        else
            return null;
    }

    protected override IViewController GetTabPage(ITabPageProperties tabPageProperties)
    {
        if (tabPageProperties is BooleanTabPageProperties booleanTabPageProperties)
        {
            BooleanTabPageController booleanTabPage = InstantiateTabPage(booleanTabPagePrefab) as BooleanTabPageController;
            booleanTabPage.SetProperties(booleanTabPageProperties);
            booleanTabPage.name = $"[BooleanTabPage] {booleanTabPageProperties.value}";
            booleanTabPage.UIView.ViewName = $"[BooleanTabPage] {booleanTabPageProperties.value}";
            return booleanTabPage;
        }
        else if (tabPageProperties is IntegerTabPageProperties integerTabPageProperties)
        {
            IntegerTabPageController integerTabPage = InstantiateTabPage(integerTabPagePrefab) as IntegerTabPageController;
            integerTabPage.SetProperties(integerTabPageProperties);
            integerTabPage.name = $"[IntegerTabPage] {integerTabPageProperties.value}";
            integerTabPage.UIView.ViewName = $"[IntegerTabPage] {integerTabPageProperties.value}";
            return integerTabPage;
        }
        else
            return null;
    }
}
#endregion