Monthly Archives: November 2013

Rebuilt bits

** Many of the changes in this update will improve performance and robustness. If I did them correctly. If not, we could see data corruption and/or an increase in odd behavior and crashes. **

I have changed how trait handling, tag lists, and the rollback of changes, are handled in the Edit Items, Advanced Edit Items, and Modifiers windows. This should make things more robust and less prone to damage from bad data.

I have adjusted the code that determines relationships between traits (which is what determines which traits are recalculated when you change something). Relationship determination should be done a bit more quickly now.

I have rebuilt a number of the parser routines to be more robust, which should reduce (hopefully eliminate) the instances where an errant open or close paren within braces or quotes was still being counted as a valid part of another container pair.

Given the change above, the %closeparen, %openparen, %closebrace, and %openbrace special variables mentioned in b for @EndsWith and @StartsWith should no longer be necessary, if the corresponding characters are enclosed within quotes in the function, such as @endswith(“)”). The %quotes variable is still required, as there is no way to enclose the double quote character safely, but it’s also the least likely to be needed for anything. I’m leaving all of the variables available, though.

Vars are now run through the Text Function Solver during the trait’s calculation phase. This should speed things up when they’re used.

GCA will now read tag help information, for use in edit windows, from the tagdefs.xml file.

I changed a few things in various support routines to use certain Enums rather than Integers, which broke binary compatibility.

Overhauled bits

* Because I can’t get the long-press on touch screens to work inside the listboxes, and my potential work-around isn’t working to my satisfaction, I have currently made it so that double-clicking the title area (above the sub-heads, because those do OrderBy) of the character list in Compact and Classic view will call up the context menu for that list–IF you have selected items in the list box.

* Addressed font scaling issue in Advanced Edit display grid.

* GCA should now create a default library on startup if none exists.

* Addressed misplaced options button issue in Portrait box.

* The Protection box will no longer display information when no character is loaded.

* Updated the handling of some things in the Colors & Layout dialog.

* Overhauled the look of the Options window.

* Added a ‘Getting Started’ box to the Compact view, which offers some suggestions as to what to do once GCA has started up. This only displays if no character is loaded.

* Added support for a displaynameformula() tag. When using the DisplayName property of a Trait (which most trait lists inside GCA use), if displaynameformula() exists, GCA will use that to generate the name beging returned, instead of the built-in functions. In conjunction, the BaseDisplayName() function, or “me::basedisplayname” will return the same info as DisplayName, but will not use the formula, so it can be used within formulas to alter the output that GCA would have generated.

* Added functions to Solver:

@Len(<text>) returns the length of the given text.
@EndsWith(<text>, <check value>) returns 1 if <text> ends with <check value>, 0 if not. Case is ignored.
@StartsWith(<text>, <check value>) returns 1 if <text> starts with <check value>, 0 if not. Case is ignored.

@EndsWith and @StartsWith both use a few specialty variables instead of a few characters that GCA uses internally for parsing purposes. So, if you want to check for parens (), braces {}, or quotes “, you should instead use these variables as needed: %closeparen, %openparen, %closebrace, %openbrace, %quotes.

* Added to Text Function Solver:

$InsertInto( <target string>, <insert string>, <at position> ) which puts some text inside other text.

* The special case substitution $val() has been added to the Text Function Solver. This is identical in function to $textvalue(), just shorter.

* GCA will now support defining variables at the trait level. Variables are defined using the vars() tag, with the format vars(<name1>=<value1> [, <name2>=<value2>] [, <more name value pairs as needed>]). This allows for greatly reducing the complexity of certain types of formulas, such as the new displaynameformula() mentioned above. These are simple substitution variables; if you use vars(%name% = me::name), then the %name% variable stores the text “me::name”, not the actual name of the trait.

For example, to create a DisplayName that uses the same name that GCA would generate, but adds additional text of “Bonus Text” *within* the parenthetical information (if any), the straight formula might look like this:

displaynameformula($if(@endswith($val(me::basedisplayname), %closeparen) then $insertinto($val(me::basedisplayname), “; Bonus Text”, @len($val(me::basedisplayname))-1) else “(Bonus Text)” ))

Notice that we have to keep repeating the ‘$val(me::basedisplayname)’ bit over and over again (And $val() is necessary, because the Text Function Solver won’t replace any value references unless explicitly told to do so with the $val() or $textvalue() functions). And imagine the additional complexity if we wanted to include a trait value or tag reference instead of the simple constant “Bonus Text”.

So, we can simplify with a variable:

vars(%name% = $val(me::basedisplayname))

and the new displaynameformula() that makes use of it:

displaynameformula($if(@endswith(%name%, %closeparen) then $insertinto(%name%, “; Bonus Text”, @len(%name%)-1) else “%name% (Bonus Text)” ))

In this case, not drastically shorter as text goes, but much more readable.

Note that because GCA will replace the variable name indiscriminately within the target area, as the first step of evaluating an expression, you should ensure that your variable names are unlikely to conflict with other types of text. I recommend using a percent sign % at the beginning and end of each variable name, to ensure no accidents are likely to occur.

* It’s now possible to copy one or more tag/value pairs from inside the Advanced Edit window as an XML fragment, and to paste that fragment into another Advanced Edit window, in order to copy specific tags from one trait to another. To copy tags, select each of the tags you want to copy in the grid, then press CTRL+SHIFT+C to copy them (CTRL+C just copies the text value of those cells). You’ll now have an XML fragment which you can paste anywhere that accepts text. To paste such a fragment into GCA as tags, click on the edit grid in Advanced Edit to ensure that it’s active (but you don’t want to be editing a value, or the paste will go into that field as text), then press CTRL+V to insert the tags.

Dropped bits

I have updated children to be kept as references in a SortedTraitCollection. This is a significant change, and may cause things to explode. Importantly, this change allows for more easily feeding through OrderBy requests, and for customizing the display order of child items in the future. However, this does create some additional hoops to jump through when loading characters, because not everything being referenced will exist yet.

ChildKeyList() and ParentKey() will no longer be returned when a TagList is requested. They will no longer appear in the Advanced Edit Traits window.

I apparently broke binary compatibility for plugins again, by changing the ChildKeyList property to allow an optional parameter.

I also updated the versions on the included plugins, and on the Interfaces assembly, while attempting to fix an issue with the setup program not correctly updating things.

When changing the OrderBy by double-clicking the header of a trait list, GCA will now apply the new order to the children being displayed in the list. Of course, children will still be listed under their parents, so the ordering will only affect how they’re shown within their own block.

Drag and drop visual indicators should display correctly now, even when the listbox has been scrolled.

Drag and drop in the lists should now allow dropping items to become children of other items, although it does currently require dropping onto an existing child of the intended parent.

Dragging a child item onto a non-child item will remove that child from its current parent.

Dragging a trait over a parent item should now also display a ‘drop zone’ indicator labeled “Make child of” on the right-hand side of the list box. Dropping onto that ‘drop zone’ should make the trait a child of the parent.

I have added a button, called “Easier Dragging”, to the third toolbar. When active, this option makes it simpler to begin a drag and drop operation in the trait boxes, but makes it harder to select traits by dragging. I don’t know if I’ll leave it there, but for now that’s where it is.