ErnSur / UI-Toolkit-Plus

Boilerplate Code Generation, Tabs, Reorderable Manipulator, Built-in USS Exporter
MIT License
192 stars 9 forks source link

Allow for generation of protected members #26

Open spaderdabomb opened 3 months ago

spaderdabomb commented 3 months ago

Would it be possible to add in an option to generate protected visual elements instead of always private? Feels like inheritance could be implemented more cleanly if this was allowed.

ErnSur commented 3 months ago

Hi @spaderdabomb, thanks for your interest in the library

I've never needed inheritance with these classes, and unless I have a good grasp on a problem I cannot create a solution. That's why I would be interested in seeing your workflow to better understand the use case.

I would also appreciate any ideas/proposals on how this new feature could work from the UX side (i.e., what does the user need to do to change a field from private to protected).

Thanks!

spaderdabomb commented 3 months ago

I'm sure you have deeper understanding of ui toolkit than me, so maybe you could instead advise a solution that wouldn't need protected member fields (or if you agree with my workflow, we can devise how to implement protected members)

I am designing an inventory system with a BaseSlot.uxml, containing a VisualElement and a Label. I then use UI Toolkit Plus to auto generate the fields and a class BaseSlot.cs. In BaseSlot.cs there are base methods for managing inventory slots.

I would like to then create a GearSlot.uxml with an additional VisualElement (backing icon), however, it would be nice to use the BaseSlot.uxml as a TemplateContainer in the GearSlot.uxml so that any changes to BaseSlot carry over to GearSlot. This works fine in UI Builder. Now I auto generate my C# and .gen files for both GearSlot and BaseSlot

Next, I make GearSlot a derived class of BaseSlot, allowing me to call BaseSlot methods on GearSlot instances. Great! Then comes the issue. Perhaps I want to override a method from BaseSlot and implement custom logic on GearSlot that changes the BaseSlot label's color. Since the field is private instead of protected, I do not have access to them in GearSlot.

I have made a workaround but it feels messy. I manually implement a protected property on BaseSlot such that I can have access to it, but this feels pretty awkward and messy.

protected VisualElement BaseLabel
{
    get { return baseLabel; }
}

If it helps, here is a boiled down version of the two classes I'm working with to make things more clear. Look forward to hearing your thoughts!

BaseSlot.cs

public partial class BaseSlot
{   
    public BaseSlot(VisualElement root)
    {
        AssignQueryResults(root);
    }

    public virtual void SetSlotLabel(string slotLabel)
    {
        baseLabel.text = slotLabel;
    }
}

GearSlot.cs

public partial class GearSlot : BaseSlot
{   
    public GearSlot(VisualElement root): base(root)
    {
        AssignQueryResults(root);
    }

    public override void SetSlotLabel(string slotLabel)
    {
        base.SetSlotLabel(slotLabel);
        baseSlotLabel.style.color = Color.white; // this error out, but can be fixed with the property solution mentioned above
    }
}