aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/scrollable.go
diff options
context:
space:
mode:
authorKoni Marti <koni.marti@gmail.com>2022-02-25 17:53:33 +0100
committerRobin Jarry <robin@jarry.cc>2022-03-03 21:11:05 +0100
commit515a8b56f6e9b4e6efaf6a6a29c851dadf4b4a56 (patch)
tree773eb7af099ea985087d76db41c40d36f81cc153 /widgets/scrollable.go
parentbd65ce1010a78eec38ba9c70d9fc23f85cd087a1 (diff)
downloadaerc-515a8b56f6e9b4e6efaf6a6a29c851dadf4b4a56.tar.gz
scrollable: extract scrolling behavior for reuse
Extract the vertical scrolling ability into its own Scrollable struct that can be embedded and reused across any ui element that relies on scrolling. Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
Diffstat (limited to 'widgets/scrollable.go')
-rw-r--r--widgets/scrollable.go68
1 files changed, 68 insertions, 0 deletions
diff --git a/widgets/scrollable.go b/widgets/scrollable.go
new file mode 100644
index 00000000..0e8bb5a8
--- /dev/null
+++ b/widgets/scrollable.go
@@ -0,0 +1,68 @@
+package widgets
+
+// Scrollable implements vertical scrolling
+type Scrollable struct {
+ scroll int
+ height int
+ elems int
+}
+
+func (s *Scrollable) Scroll() int {
+ return s.scroll
+}
+
+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(selectingIdx int) {
+ if selectingIdx < 0 {
+ return
+ }
+
+ maxScroll := s.elems - s.height
+ if maxScroll < 0 {
+ maxScroll = 0
+ }
+
+ if selectingIdx >= s.scroll && selectingIdx < s.scroll+s.height {
+ if s.scroll > maxScroll {
+ s.scroll = maxScroll
+ }
+ return
+ }
+
+ if selectingIdx >= s.scroll+s.height {
+ s.scroll = selectingIdx - s.height + 1
+ } else if selectingIdx < s.scroll {
+ s.scroll = selectingIdx
+ }
+
+ if s.scroll > maxScroll {
+ s.scroll = maxScroll
+ }
+
+}