mirror of
https://git.sr.ht/~rjarry/aerc
synced 2026-03-02 18:23:33 +01:00
Go has evolved significantly over the years and has introduced some handy helper functions that make the code easier to read. Use helper functions like slices.Contains, map.Copy, and strings.CutPrefix, when appropriate. Signed-off-by: Moritz Poldrack <git@moritz.sh> Acked-by: Robin Jarry <robin@jarry.cc>
99 lines
1.6 KiB
Go
99 lines
1.6 KiB
Go
package app
|
|
|
|
// Scrollable implements vertical scrolling
|
|
type Scrollable struct {
|
|
scroll int
|
|
offset int
|
|
height int
|
|
elems int
|
|
}
|
|
|
|
func (s *Scrollable) Scroll() int {
|
|
return s.scroll
|
|
}
|
|
|
|
func (s *Scrollable) SetOffset(offset int) {
|
|
s.offset = offset
|
|
}
|
|
|
|
func (s *Scrollable) ScrollOffset() int {
|
|
return s.offset
|
|
}
|
|
|
|
func (s *Scrollable) PercentVisible() float64 {
|
|
if s.elems <= 0 {
|
|
return 1.0
|
|
}
|
|
return float64(s.height) / float64(s.elems)
|
|
}
|
|
|
|
func (s *Scrollable) PercentScrolled() float64 {
|
|
if s.elems <= 0 {
|
|
return 1.0
|
|
}
|
|
return float64(s.scroll) / float64(s.elems)
|
|
}
|
|
|
|
func (s *Scrollable) NeedScrollbar() bool {
|
|
needScrollbar := true
|
|
if s.PercentVisible() >= 1.0 {
|
|
needScrollbar = false
|
|
}
|
|
return needScrollbar
|
|
}
|
|
|
|
func (s *Scrollable) UpdateScroller(height, elems int) {
|
|
s.height = height
|
|
s.elems = elems
|
|
}
|
|
|
|
func (s *Scrollable) EnsureScroll(idx int) {
|
|
if idx < 0 {
|
|
return
|
|
}
|
|
|
|
middle := s.height / 2
|
|
switch {
|
|
case s.offset > middle:
|
|
s.scroll = idx - middle
|
|
case idx < s.scroll+s.offset:
|
|
s.scroll = idx - s.offset
|
|
case idx >= s.scroll-s.offset+s.height:
|
|
s.scroll = idx + s.offset - s.height + 1
|
|
}
|
|
|
|
s.checkBounds()
|
|
}
|
|
|
|
func (s *Scrollable) checkBounds() {
|
|
maxScroll := max(s.elems-s.height, 0)
|
|
|
|
if s.scroll > maxScroll {
|
|
s.scroll = maxScroll
|
|
}
|
|
|
|
if s.scroll < 0 {
|
|
s.scroll = 0
|
|
}
|
|
}
|
|
|
|
type AlignPosition uint
|
|
|
|
const (
|
|
AlignTop AlignPosition = iota
|
|
AlignCenter
|
|
AlignBottom
|
|
)
|
|
|
|
func (s *Scrollable) Align(idx int, pos AlignPosition) {
|
|
switch pos {
|
|
case AlignTop:
|
|
s.scroll = idx
|
|
case AlignCenter:
|
|
s.scroll = idx - s.height/2
|
|
case AlignBottom:
|
|
s.scroll = idx - s.height + 1
|
|
}
|
|
s.checkBounds()
|
|
}
|