PlayXwordColumn
Status: Implemented | 2022
For better or worse, we cannot get the layout we want with stock GTK widgets with gtk4. The main problem is that there’s no way to have the grid swindow expand vertically to a maximum size, but no more. As a result, we need a custom widget to handle the sizing of the grid on the left. See this diagram for an illustration of this:
The expansion that requires a custom widget
This is what the PlayXwordColumn
widget is for. Note, that despite
the name, it’s more than just a column, but contains essentially the
full widgetry for the Crossword playing area.
As we started adding more animations to handle multiple sizes better, this widget became a lot more complex, and increasingly specialized. We’ve made a conscious decision to lose the generality of gtk containers. Instead, we are focusing on precise control over the layout and behaviours (and animations).
Here’s a sketch as how it is laid out:
sketch of PlayXwordColumn
Sizing
The only size that matters in the PlayXwordColumn
is the width of
the grid. That (plus any spacing) sets the minimum size of the
game. The intro
, notes
, and clue
labels are all
height-for-width, and are anchored to this width.
Not surprisingly, the majority of the widget code is in the
::size_allocate
method. Be careful when touching it.
Animations
We have two animations we run, primary and secondary. They are both triggered by the horizontal sizing. We don’t do animations based on the internal state of the crossword (yet — see below), and we don’t do animations based on any changes in vertical sizing. Events that can cause these are window resize events, or font / css changes (aka, zooming, but also system-wide ones).
Both animations are tracked by a float who’s value ranges between 0.0 and 1.0:
primary_value
secondary_value
The animation will just queue and allocation, which will update below as appropriate
Primary Animation
Affects: primary, clue, grid-swindow, notes
primary_value
== 0.0: clue is visible; opacity is 1.0primary_value
== 0.0: primary is hidden; opacity is 0.0primary_value
== 0.0: grid-swindow and notes allocation ends below clue.primary_value
== 1.0: clue is hidden; opacity is 0.0primary_value
== 1.0: primary is visible; opacity is 1.0primary_value
== 1.0: grid-swindow and notes allocation extends into clue, if necessary
Secondary Animation
Affects: secondary
secondary_value
== 0.0: secondary is hidden; opacity is 0.0secondary_value
== 1.0: secondary is visible; opacity is 1.0