]> git.lizzy.rs Git - micro.git/blob - internal/display/tabwindow.go
Merge pull request #1386 from jncraton/docfix
[micro.git] / internal / display / tabwindow.go
1 package display
2
3 import (
4         "unicode/utf8"
5
6         runewidth "github.com/mattn/go-runewidth"
7         "github.com/zyedidia/micro/internal/buffer"
8         "github.com/zyedidia/micro/internal/config"
9         "github.com/zyedidia/micro/internal/screen"
10         "github.com/zyedidia/micro/internal/util"
11 )
12
13 type TabWindow struct {
14         Names   []string
15         active  int
16         Y       int
17         width   int
18         hscroll int
19 }
20
21 func NewTabWindow(w int, y int) *TabWindow {
22         tw := new(TabWindow)
23         tw.width = w
24         tw.Y = y
25         return tw
26 }
27
28 func (w *TabWindow) LocFromVisual(vloc buffer.Loc) int {
29         x := -w.hscroll
30
31         for i, n := range w.Names {
32                 x++
33                 s := utf8.RuneCountInString(n)
34                 if vloc.Y == w.Y && vloc.X < x+s {
35                         return i
36                 }
37                 x += s
38                 x += 3
39                 if x >= w.width {
40                         break
41                 }
42         }
43         return -1
44 }
45
46 func (w *TabWindow) Scroll(amt int) {
47         w.hscroll += amt
48         w.hscroll = util.Clamp(w.hscroll, 0, w.TotalSize()-w.width)
49 }
50
51 func (w *TabWindow) TotalSize() int {
52         sum := 2
53         for _, n := range w.Names {
54                 sum += utf8.RuneCountInString(n) + 4
55         }
56         return sum - 4
57 }
58
59 func (w *TabWindow) Active() int {
60         return w.active
61 }
62
63 func (w *TabWindow) SetActive(a int) {
64         w.active = a
65         x := 2
66         s := w.TotalSize()
67         for i, n := range w.Names {
68                 c := utf8.RuneCountInString(n)
69                 if i == a {
70                         if x+c >= w.hscroll+w.width {
71                                 w.hscroll = util.Clamp(x+c+1-w.width, 0, s-w.width)
72                         } else if x < w.hscroll {
73                                 w.hscroll = util.Clamp(x-4, 0, s-w.width)
74                         }
75                         break
76                 }
77                 x += c + 4
78         }
79 }
80
81 func (w *TabWindow) Display() {
82         x := -w.hscroll
83         done := false
84
85         draw := func(r rune, n int) {
86                 for i := 0; i < n; i++ {
87                         rw := runewidth.RuneWidth(r)
88                         for j := 0; j < rw; j++ {
89                                 c := r
90                                 if j > 0 {
91                                         c = ' '
92                                 }
93                                 if x == w.width-1 && !done {
94                                         screen.Screen.SetContent(w.width-1, w.Y, '>', nil, config.DefStyle.Reverse(true))
95                                         x++
96                                         break
97                                 } else if x == 0 && w.hscroll > 0 {
98                                         screen.Screen.SetContent(0, w.Y, '<', nil, config.DefStyle.Reverse(true))
99                                 } else if x >= 0 && x < w.width {
100                                         screen.Screen.SetContent(x, w.Y, c, nil, config.DefStyle.Reverse(true))
101                                 }
102                                 x++
103                         }
104                 }
105         }
106
107         for i, n := range w.Names {
108                 if i == w.active {
109                         draw('[', 1)
110                 } else {
111                         draw(' ', 1)
112                 }
113                 for _, c := range n {
114                         draw(c, 1)
115                 }
116                 if i == len(w.Names)-1 {
117                         done = true
118                 }
119                 if i == w.active {
120                         draw(']', 1)
121                         draw(' ', 2)
122                 } else {
123                         draw(' ', 3)
124                 }
125                 if x >= w.width {
126                         break
127                 }
128         }
129
130         if x < w.width {
131                 draw(' ', w.width-x)
132         }
133 }