In effect, this is a combination of two of the previous pickers:
the location picker, and the editable string picker.
This required quite a significant rework of how the tilemap places its children.
Currently it's only used in special node editing.
I plan to add its use in many other places too though.
All controls now store a reference to their direct parent,
whether it be the dialog itself or a container control.
Every dialog control now has a guaranteed parent, which abstracts away
the three possible types of parents (dialog, container, and plain window).
The control name is now stored in the control from the moment it is parsed from the XML.
This means that it's set before the parseContent function, though after parseAttribute.
This just implements the guts of the dialog, without using it for anything yet.
It also fixes a bug that caused a blank page to appear in the string picker if the total number of strings was an exact multiple of 40.
Closes#563
Better editing for talk node keys
* The fields start out empty, and it is *allowed* to keep *one of them* empty. (A node only needs one key to be useful, right?
* When the node is saved, empty strings are replaced with `" "`. If this is not harmless to the game logic, then I'll need to make the game aware that either key might be `" "`.
* You cannot type more than 4 characters in these fields (unless there's a way to insert characters I'm not aware of).
* If you put 'buy' in a field, it automatically becomes 'purc'.
* There is a note next to the response keys (kind of squished in the corner) enumerating the special logic of the in-game Buy and Sell buttons.
Quality of life: Spellcasting
This makes changes to the spellcasting UI.
* M or P to recast will no longer default to Light or Minor Bless/Minor Heal. You need to cast something before recast becomes available. This fixes#535 and I think it's disorienting when I've just started the game and M casts Light in a town that's fully lit, so the change is generally good I'd say.
* I implemented a recasting hint in the text bar, which was one of the things I mentioned in my quality-of-life checklist https://github.com/NQNStudios/cboe/issues/16. It replaces the status icons in combat mode.
* Sometimes when my eyes glaze over, I think I'm casting the spell on the wrong side of the LED. I thought there was a bug when I cast Long Light instead of Dumbfound (even though I know the distance between the two is pretty large -- I wasn't paying much attention). I thought it would be nice to highlight the name of the selected spell. Light green seemed to make more sense than red for that, because the LED turns green. Then I made the caster/target selection texts also use light green instead of red, to match. Uncastable spells are grey.
parseColor() was doing a big if-else with string comparisons,
and returning values that differed from our Colours constants.
Since I couldn't find an instance of the colour attribute in our
existing xml, it should be safe to do away with those conflicting
values and refactor parseColor() to match the constants
and use cleaner code.