Play Cell
Status: Implemented | May 2025
Author: Jonathan Blandford
This doc covers the details of the PlayCell
widget, and some of the
sizing tradeoffs.
Overall Approach
Play Cell is surprisingly complex. This is due to the size calculations and the need to aggressively optimize it so that subsequent updates don’t cause a redraw if nothing changed. This means that we’re even more careful with keeping the anti-hysteresis properties valid then other widgets.
Layout
Internally, the PlayCell
has two labels who are allocated the full
size of the cell. They are for the main text, as well as the cluenum
label.
Layout of PlayCell
NOTE: This image is a little out of date. The text size is 2*base_size - 6.
NOTE: Blocks in arrowword puzzles have a different layout, and use a secondary label.
The PlayCell
uses GtkLabel
s to display text. This is a compromise
between using a PangoLayout
or a GtkEntry
instead. The use of the
label gets us relatively good control over the location of the text in
a way that’s hard to do with a GtkEntry
. It also provides full use
of CSS, which can’t be done outside of GTK with GTK4, which can’t be
done with a PangoLayout
approach.
The ramification of this approach is that we have to change the
font-size of the label in order to find one that fits within the
allocation. That’s done in play_cell_update_main_label()
.
If we shrink the label below a certain point, we replace the text with
the OVERRUN_CHARACTER
(currently "�"
).
Update handling
We’re very careful to only queue a redraw when there are changes to the cell. This is done through a comparison of the existing values and the ones currently being displayed. If there are no changes, we don’t queue a redraw on update.
Areas for Improvement
[ ] There’s only one cluenum cell per-cell. The spec might imply you can have multiple cluenums. If that’s posisble, we need to add more labels.
[ ] The guess is centered vertically in the label. When we have rebus answers, this looks a little odd. We should consider aligning it so all cells share a common baseline. This is probably best done by setting the valign to 1.0 and raising the bottom of the allocation.
[ ] It’s unlikely to appear in a real puzzle, but we don’t work well with multiple unicode numerical entries in rebus mode.