adafruit/Adafruit_CircuitPython_Display_Button

Minimum button width depends on maximum glyph width

Closed this issue · 1 comments

This may be intentional fault-tolerant behavior (or for simplicity or performance), but since the check for button width uses the widest possible glyph width (bounding_box), the minimum button width using a non-monospace font is often much wider than needed for the actual button text. For some applications, dynamic button dimensions and / or minimum button dimensions are desirable.

            button_label = "Some skiiiiiiiiiiny striiiiiiiiiiiiing"
            button_label_bytes = button_label.encode()
            button_width = 0
            for _ in button_label_bytes:
                button_width += font.get_glyph(_).width

Results in RuntimeError: Button not large enough for label

Using 'len(button_label) * font.get_bounding_box()[0]' instead with a non-monospace font works, but can yield a button width easily twice as wide or more than the text.

Oddly, using a monospace font like terminalio.FONT with the expected method of calculating button width len(button_label) * font.get_bounding_box()[0] also results in Button not large enough for label. There may be an implicit margin assumption.

On further inspection, bounding_box is calculated per-character in the Button / Label libraries, and the total width of the Button or Label text must be strictly less than (not equal to) the bounding box. The .bdf spec appears to allow individual characters to override the overall font bounding box, so character-by-character does seem to be the most accurate approach. It's a bit of a catch-22: can't make a label unless you know its dims, but you may not know its dims up front.

After much exploration, I settled on creating a dummy Label to get the bounding box of the dynamic text, then using those dims to create the actual Label or Button with the proper minimum width and height. I'm closing this issue, since there are methods to determine dynamic / minimum button or label dimensions.