sloshConfiguring it slosh.foo

Chrome shaders#

A frame is a rect too, so it is a pass too. where="chrome" on any entry in shaders or in a states block runs that pass over a pane's frame (border, padding, title, buttons) instead of its contents.

states {
    // a bell nobody has answered: a quarter-second flash, then gone
    bell { tint where="chrome" channel="fg" color="#ffcc00" amount="(since < 250) * 255" }
}

Nothing else changes: same shaders, same amount, same expressions, same chain order. One new word.

Positions are the whole frame's#

x/y are counted from the frame's top-left corner, with cols/rows the size of the pane's rect, not of one side. One pass over the whole ring, so an effect can travel round a border instead of restarting at every corner.

For anything that _travels_, though, the coordinate you want is distance along the ring, which the language can work out. Clockwise from the top-left:

(y == 0 ? x : x == cols-1 ? cols - 1 + y
 : y == rows-1 ? 2 * cols + rows - 3 - x : 2 * cols + 2 * rows - 4 - y)

There is no way to name a subexpression, so the formula is written out in full, which is why a small effect is a long line.

Thirteen of them are ready to paste in contrib/chrome: a shine running round the border, a sine comet with softer shoulders, marching ants, a standing wave, drifting sparkles, ripples leaving a corner in both directions, etc.

A border that says something#

Depending on a pane's state, we can visually communicate through it's chrome:

states {
    // a dead pane's frame breathes red until you deal with it
    dead { tint where="chrome" channel="fg" color="#ff0033" amount="abs(t/8%510-255)" }
    // one that has not started yet is outlined, not filled
    suspended { tint where="chrome" channel="fg" color="#8a8a95" amount=160 }
    // and the panes you are not in recede, frame and contents together
    unfocused { dim amount=60; dim where="chrome" channel="fg" amount=90 }
}

since is what makes a _flash_ possible: it is how long the pane has been in this state, where t only knows what time it is. The bell state ends when you look at the pane, because that is what answering a bell is. :-)

Animation costs a clock#

Anything that reads t or since asks the session to keep painting, at anim_ms (50ms, so 20fps) and only while such a pass is actually on screen.

anim_ms 0 turns the clock off, which leaves an animated shader advancing only when something else causes a frame.