Skip to content

Avoid need to manually set increments field when setting up Multiple Images bars - #6069

Open
kwvanderlinde wants to merge 9 commits into
RPTools:developfrom
kwvanderlinde:bugfix/6068-bar-increment-refactor
Open

kwvanderlinde wants to merge 9 commits into
RPTools:developfrom
kwvanderlinde:bugfix/6068-bar-increment-refactor

Conversation

@kwvanderlinde

@kwvanderlinde kwvanderlinde commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Identify the Bug or Feature request

Resolves #6068

Description of the Change

The main feature in this PR is that the Increments field for the States tab is now disabled when editing a Mutiple Images bar:
image

When the bar is saved (Add'ed or Update'd), the increments for the bar is set to the number of images, ignoring the Increments field altogether. It is no longer required for the Increments to be manually set to the number of images before the bar can be saved. As a result, there is no more need for the "Unneeded" label for any images, since all images naturally always contribute. The other labels ("Empty Bar", "Full Bar", "Increment #") now have i18n keys rather than hardcoded the English text.

Also included is a performance improvement for image-based bars (and states). Rendering these no longer call ImageManager.getImageAndWait(...) (blocking the main thread), but instead pass an ImageObserver to ImageManager.getImage(...) for non-blocking behaviour. Until an image loads, it will be displayed as the "?" transferring image.

Some refactoring was also done to make bars a bit more robust and obvious:

  • MultipleImageBarTokenOverlay now guarantees that its #getIncrements() returns the same as the number of assets it contains. Any #setIncrements() call is ignored now.
  • Bar increment lookups are more robust now. There is no risk of returning out-of-bounds results when provided a value that is too small or large, or when the increments are set to 0. In particular, BarTokenOverlay#findIncrement() and BarTokenOverlay#calcBarSize() are both now internal to the bar hierarchy, where preconditions can be better ensured.
  • The implementation of the getBarImage() is no longer responsible for indexing into a MultipleImageBarTokenOverlay asset array. Instead, the bar can safely do its own lookup, while keeping the macro code simpler as well.
  • TwoToneBarTokenOverlay no longer inherits from DrawnBarTokenOverlay since it had to override all the meaningful behaviour anyways, and all they really shared was two fields. This also makes the instanceof logic in TokenBarController a little more obvious.
  • Common bar DTO logic is handled entirely within BarTokenOverlay now. Child classes must set their type and custom fields in #toDtoImpl(), and must read their custom fields back in #fromDtoImpl(), while all common logic is handled in #toDto() and #fromDto().
  • The default constructors for concrete bar classes have been removed as they aren't really needed, and sometimes created objects in invalid states.

Possible Drawbacks

Should be none.

Documentation Notes

N/A

Release Notes

  • Improved the States tab of the Campaign Properties so that the increment field does not have to be manually matched to the number of images in a Multiple Images bar.

This change is Reviewable

@kwvanderlinde kwvanderlinde self-assigned this Oct 15, 2026
@github-actions github-actions Bot added code-maintenance Adding/editing javadocs, unit tests, formatting. feature Adding functionality that adds value labels Oct 15, 2026
@kwvanderlinde kwvanderlinde moved this from Todo to Awaiting Review in MapTool 1.20 Oct 15, 2026
@kwvanderlinde kwvanderlinde changed the title Avoid manually setting increment field when setting up Multiple Images bars Avoid need to manually set increments field when setting up Multiple Images bars Nov 7, 2026
@kwvanderlinde
kwvanderlinde force-pushed the bugfix/6068-bar-increment-refactor branch from 7622698 to 5e9ac27 Compare November 7, 2026 16:24
In particular, remove the noisy and useless doc comments that say nothing but "`@see` the parent."
When converting any `BarTokenOverlay` to a DTO, all common properties are set directly in `BarTokenOverlay#toDto()`
rather than requiring every child class to remember to do so. Child classes override `#toDtoImpl()` to set their type
and custom fields while keeping the common stuff in `BarTokenOverlay#toDto()`.

Similarly for `BarTokenOverlay#fromDto()`, child classes provide their customized deserialization in `#fromDtoImpl()`
while all the common logic lives in `BarTokenOverlay#fromDto()`.
The two did not share any behaviour, just two fields. In fact, `TwoToneBarTokenOverlay` had overrides for all the
behaviour in `DrawnBarTokenOverlay`.

To simplify the understanding of these classes, while also avoiding issues like properly ordering `if`+`instanceof`
checks or `switch` statements, these classes are now completely separate. `TokenBarController` is the only place that
was dependent on this structure, and it has also been updated.
The increments for Multiple Images bar is now taken from the number of supplied images, not the *Increments* spinner.
The spinner is now disabled when editing a Multiple Images bar.

The `"Uneeded"` labels are no longer meaningful for images in these bars (not that they ever really were), so support
for them has been removed. The other labels (`"Empty Bar"`, `"Full Bar"`, `"Increment #"`) are now provided by i18n
instead of hardcoding the English keys.
Since it does not support arbitrary increments (unlike other bars), it is no longer possible to directly modify the
number of increments. Instead, the class guarantees that the number of increments always match the number of images.
Because it had a meaningless return value (-1) in the case of no increments, all callers to
`BarTokenOverlay#findIncrement()` needed to be sure they handled that case specially. They could do this be handling the
special result, or checking the inputs. This is too much to ask for external callers, so the method is now constrained
to the bar hierarchy (`protected`).

There was only one external caller: the implementation of the `getBarImage()` macro function, specifically pertaining to
multiple images bars. `MultipleImageBarTokenOverlay` now provides direct (and safe) access to the correct asset provided
only a value, with out-of-bounds values being clamped. This fixes an existing out-of-bounds error that would be shown in
chat if `getBarImage()` was provided a value greater than 1.

`#findIncrement()` itself has also be made much safer:
- It can handle any value, even out-of-bounds ones
- It has a precondition to only be called with positive increments
- It guarantees the result is within the bounds [0, increments), with no special cases to consider.

Both `MultipleImageBarTokenOverlay#getAssetForValue(double)` and `BarTokenOverlay#calcBarSize(int, double)` enjoy the
benefits of this more well-behaved version of `#findIncrement()`.
This allows non-blocking rendering for image-based overlays.
@kwvanderlinde
kwvanderlinde force-pushed the bugfix/6068-bar-increment-refactor branch from 5e9ac27 to 9c9c0c8 Compare November 7, 2026 17:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

code-maintenance Adding/editing javadocs, unit tests, formatting. feature Adding functionality that adds value

Projects

Status: Awaiting Review

Development

Successfully merging this pull request may close these issues.

[Feature]: Don't require the user to set the right number of increments for multiple image bars

1 participant