-
-
Notifications
You must be signed in to change notification settings - Fork 4
Description
This is a hitch point for a few pretty useful features.
I think it’d take some doing, and I’m not quite sure the best way.
As I think about it, the best way to do it might be to re-separate the PCUI controls/data relationship a bit.
“Interpose” might be a more appropriate term: currently, data is sent directly to the PCUI underlying object, and only then is the update handler fired.
This has the unfortunate side effect of validation being a double-edit operation, which is noticeable on some platforms and particularly slower systems, not efficient in any case (since both changes are propagated back to the UI regardless of validity), and means there’s no way to track changes currently without hooking everything manually.
wxWidgets has a validator system, but that requires using the widgets. Ideally the interposer goes into the mutator functions/operators. Once data is validated then it’s stored and pushed up into the modification list.
PCUI’s lists/choice data needs a rework then. There’s lists which actually hold data (which should provide operations to add/remove, move, duplicate, etc. so long as the held type allows, and would need to use member ptrs to know where to find the data to display. Probably best for those to be function ptrs to allow computed display values…), there’s lists which contain non-uniform data (props handling is ugly right now, I’d like to make it nicer), and lists which are purely selective (selecting from some other source of truth or some internal list of options (e.g. blade ID type)
All of these are shoehorned into the current pcui::ChoiceData, and need their use cases split.
Rather than the current proxy-based system, which expects uniform data and one-time mass UI creation, contentful choices (what I classify the former two listed as) should probably require a virtual interface to be implemented by an arbitrary class in the UI-side code to build things on demand. This would allow a hierarchy that feels more natural to UI I think. Lists were implemented suboptimally before because I couldn’t decide how I actually wanted this to work.
The undo/redo tree (not that the undo/redos are a tree but that the controls which may have undo/redo actions done on them form a tree) would need both a parent level generic object for tracking changes, and nodes which dynamically attach to the tree to implement traversal from dynamically created leaf objects back to the parent for storage (and vice versa.
When a change is made, the changing child needs to have a unique ID in the tree and a data object storing the change info so it knows how to reverse it if the data is sent back down the chain upon undo (or redo!)
At this point, the operations of the children can be seen as necessarily being represented by their self-described undo/redo data structure, so internally all changes should be made through a member function accepting such an object. External methods (including/same as those invoked by UI event handlers) then would only differ in performing validation, (which may be comprised of both intrinsic requirements and a callback provided for context-specific checks) and generating the structure. The actual modification would be sent in as if it were a redo operation, and then the “wrapper” sends it up to the parent.
For initial creation the undo list can simply be discarded (more optimally probably just suppressed altogether).
It would also be beneficial for the aforementioned nodes and parent to require a hashing operation of their children, so that the pseudo-state of the tree at any given time is known and can be stored for record keeping (e.g. already-compiled binaries)