Should changing a style% update derived style%'s?

I have some code to increase the font size in my application:

(define (change-canvas-font-size canvas amount)
    (define standard (send (send canvas get-style-list) find-named-style "Standard"))
    (when standard
      (define delta (make-object style-delta%))
      (send standard get-delta delta)
      (send delta set-delta 'change-size (+ (send standard get-size) amount))
      (send standard set-delta delta)
      (send canvas redo-layout)))

This works but it doesn't update the size of other style% objects derived from Standard, ie styles that have Standard as their base style. Am I misunderstanding the docs here? It seems like the point of having a hierarchy of styles is so that you don't have to walk down the tree manually updating styles.

Here is an example of how I have some of my styles defined:

(define standard (send style-list find-named-style "Standard"))
(define standard-delta (make-object style-delta%))
(send* standard-delta
  (set-family 'modern)
  ;(set-face font-name)
  (set-delta 'change-size 12)
  (set-delta-foreground text-fg-color)
  (set-delta-background canvas-bg-color))
(send standard set-delta standard-delta)

(define (make-color-style name color)
  ;; Each style created with this procedure copies "Standard" style
  ;; and creates a new style by name 'name' and with the foreground
  ;; color 'color'.
  (send (send style-list new-named-style name standard)
        set-delta (send* (make-object style-delta%)
                    (copy standard-delta)
                    (set-delta-foreground color))))
   
(make-color-style "Link" link-color)
(make-color-style "Link Highlight" link-highlight-color)

Link and Link Highlight are derived from Standard so it would be nice if their size changed to match Standard. I was thinking that perhaps it has something to do with the fact that the style-delta% I use for the derived styles is copying the change-size delta from standard-delta but removing change-size from standard-delta didn't change anything.

I probably need to do something with the additive or multiplicative style size parameters(instead of just using change-size, but my experiments with those haven't gone well.

The new-named-style method makes a new style that is essentially a copy of a given one, while find-or-create-style creates one that is linked to an existing style. So, I think you want to use both of those:

(define (make-color-style name color)
  (send style-list new-named-style name
        (send style-list find-or-create-style standard
              (send (make-object style-delta%)
                    set-delta-foreground color))))
1 Like

Ah, this does seem to help. With your version, the style size change is propagating.

I do see a weird problem that is most likely an issue with my code somewhere, which I'll look into further. When I calculate the extent of string-snip%s, the height is updating but not the width. For regular strings both the width and height are updated correctly.

If I can't fix this but can reproduce it in a simple example, I'll post back here. But for now I'll assume this is a "me" problem. Thanks for your help!

Calling the size-cache-invalid method on string-snip%s when I change the font size fixes my problem with only the height of string-snip%s updating. It looks like the string-snip% code has an optimization to reduce how often it recalculates the extent of the snip.

This probably wouldn't be an issue for anyone using a standard canvas, but I needed to fix this in my custom canvas%.