Reset everything from a held on-screen button or space
This commit is contained in:
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -9,6 +10,7 @@ var (
|
||||
uiBg = rgb{0x12, 0x14, 0x18}
|
||||
uiPanel = rgb{0x1c, 0x20, 0x26}
|
||||
uiRule = rgb{0x2e, 0x34, 0x3c}
|
||||
uiButton = rgb{0x25, 0x2b, 0x33}
|
||||
uiFg = rgb{0xe6, 0xe8, 0xea}
|
||||
uiDim = rgb{0x7a, 0x82, 0x8c}
|
||||
uiCyan = rgb{0x5c, 0xc8, 0xe0}
|
||||
@@ -37,14 +39,31 @@ const (
|
||||
colLateEnd = 46
|
||||
colCRCEnd = 53
|
||||
colKdropEnd = 62
|
||||
|
||||
btnW = 200
|
||||
btnH = 64
|
||||
holdDuration = time.Second
|
||||
)
|
||||
|
||||
type rect struct {
|
||||
x, y, w, h int
|
||||
}
|
||||
|
||||
func (r rect) contains(x, y int) bool {
|
||||
return x >= r.x && x < r.x+r.w && y >= r.y && y < r.y+r.h
|
||||
}
|
||||
|
||||
type display struct {
|
||||
fb *framebuffer
|
||||
huge *textFace
|
||||
grid *textFace
|
||||
gridB *textFace
|
||||
small *textFace
|
||||
|
||||
resetBtn rect
|
||||
holdStart time.Time
|
||||
holdFrac float64
|
||||
fired bool
|
||||
}
|
||||
|
||||
func newDisplay() (*display, error) {
|
||||
@@ -75,9 +94,71 @@ func newDisplay() (*display, error) {
|
||||
return nil, fmt.Errorf("grid faces disagree on cell width: %d vs %d",
|
||||
d.grid.cellW, d.gridB.cellW)
|
||||
}
|
||||
d.resetBtn = rect{
|
||||
x: fb.w - uiMargin - btnW,
|
||||
y: fb.h - uiMargin - btnH,
|
||||
w: btnW,
|
||||
h: btnH,
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// Tracks a press and hold on the reset button, returning true once it has been
|
||||
// held long enough. Lifting or sliding off cancels, and the press has to be
|
||||
// released before it can arm again.
|
||||
func (d *display) holdReset(x, y int, down bool, now time.Time) bool {
|
||||
if !down {
|
||||
d.holdStart, d.holdFrac, d.fired = time.Time{}, 0, false
|
||||
return false
|
||||
}
|
||||
if d.fired || !d.resetBtn.contains(x, y) {
|
||||
d.holdStart, d.holdFrac = time.Time{}, 0
|
||||
return false
|
||||
}
|
||||
if d.holdStart.IsZero() {
|
||||
d.holdStart = now
|
||||
}
|
||||
d.holdFrac = now.Sub(d.holdStart).Seconds() / holdDuration.Seconds()
|
||||
if d.holdFrac < 1 {
|
||||
return false
|
||||
}
|
||||
d.holdFrac, d.fired, d.holdStart = 0, true, time.Time{}
|
||||
return true
|
||||
}
|
||||
|
||||
func (d *display) drawResetButton() {
|
||||
r := d.resetBtn
|
||||
d.fb.rect(r.x, r.y, r.w, r.h, uiButton)
|
||||
|
||||
if d.holdFrac > 0 {
|
||||
w := int(float64(r.w) * math.Min(d.holdFrac, 1))
|
||||
d.fb.rect(r.x, r.y, w, r.h, uiCyan)
|
||||
}
|
||||
for _, e := range []rect{
|
||||
{r.x, r.y, r.w, 2},
|
||||
{r.x, r.y + r.h - 2, r.w, 2},
|
||||
{r.x, r.y, 2, r.h},
|
||||
{r.x + r.w - 2, r.y, 2, r.h},
|
||||
} {
|
||||
d.fb.rect(e.x, e.y, e.w, e.h, uiCyan)
|
||||
}
|
||||
|
||||
label := "RESET"
|
||||
lx := r.x + (r.w-len(label)*d.gridB.cellW)/2
|
||||
ly := r.y + (r.h-d.gridB.cellH)/2
|
||||
// The label straddles the fill, so each glyph takes the colour that reads
|
||||
// against whatever is behind it.
|
||||
split := r.x + int(float64(r.w)*math.Min(d.holdFrac, 1))
|
||||
for i, c := range label {
|
||||
gx := lx + i*d.gridB.cellW
|
||||
col := uiFg
|
||||
if gx+d.gridB.cellW/2 < split {
|
||||
col = uiBg
|
||||
}
|
||||
d.gridB.draw(d.fb, gx, ly, string(c), col)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *display) close() {
|
||||
d.fb.close()
|
||||
}
|
||||
@@ -164,7 +245,7 @@ func (d *display) render(dirs []*direction, views []view, elapsed time.Duration,
|
||||
lineH := d.grid.cellH + 4
|
||||
sectionH := d.small.cellH + 10 + (1+len(dirs))*lineH
|
||||
gap := 30
|
||||
avail := fb.h - (bandY + bandH) - 16
|
||||
avail := fb.h - (bandY + bandH) - btnH - 2*uiMargin
|
||||
y := bandY + bandH + 8 + (avail-2*sectionH-gap)/2
|
||||
|
||||
y = d.section(y, "RATE")
|
||||
@@ -204,6 +285,7 @@ func (d *display) render(dirs []*direction, views []view, elapsed time.Duration,
|
||||
y += lineH
|
||||
}
|
||||
|
||||
d.drawResetButton()
|
||||
fb.flush()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user