# 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.

![PlayCell layout](cell-contents.png)<br>
_Layout of PlayCell_

:::{important}
This image is a little out of date. The text size is
2*base_size - 6.
:::

:::{important}
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

* [ ] The guess is centered vertically in the label. When we have
      rebus answers, this looks a little odd. We should 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 render
      correctly with multiple unicode numerical entries in rebus mode.
