2019-01-10 06:13:50 +03:00
|
|
|
package display
|
|
|
|
|
|
|
|
import (
|
|
|
|
"unicode/utf8"
|
|
|
|
|
2019-06-15 23:54:53 +03:00
|
|
|
runewidth "github.com/mattn/go-runewidth"
|
2019-02-04 07:17:24 +03:00
|
|
|
"github.com/zyedidia/micro/internal/buffer"
|
|
|
|
"github.com/zyedidia/micro/internal/config"
|
|
|
|
"github.com/zyedidia/micro/internal/screen"
|
|
|
|
"github.com/zyedidia/micro/internal/util"
|
2019-01-10 06:13:50 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
type TabWindow struct {
|
|
|
|
Names []string
|
2019-01-10 07:44:53 +03:00
|
|
|
active int
|
2019-01-10 06:13:50 +03:00
|
|
|
Y int
|
|
|
|
width int
|
|
|
|
hscroll int
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewTabWindow(w int, y int) *TabWindow {
|
|
|
|
tw := new(TabWindow)
|
|
|
|
tw.width = w
|
|
|
|
tw.Y = y
|
|
|
|
return tw
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *TabWindow) GetMouseLoc(vloc buffer.Loc) int {
|
|
|
|
x := -w.hscroll
|
|
|
|
|
|
|
|
for i, n := range w.Names {
|
|
|
|
x++
|
|
|
|
s := utf8.RuneCountInString(n)
|
|
|
|
if vloc.Y == w.Y && vloc.X < x+s {
|
|
|
|
return i
|
|
|
|
}
|
|
|
|
x += s
|
|
|
|
x += 3
|
|
|
|
if x >= w.width {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *TabWindow) Scroll(amt int) {
|
|
|
|
w.hscroll += amt
|
|
|
|
w.hscroll = util.Clamp(w.hscroll, 0, w.TotalSize()-w.width)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *TabWindow) TotalSize() int {
|
|
|
|
sum := 2
|
|
|
|
for _, n := range w.Names {
|
|
|
|
sum += utf8.RuneCountInString(n) + 4
|
|
|
|
}
|
|
|
|
return sum - 4
|
|
|
|
}
|
|
|
|
|
2019-01-10 07:44:53 +03:00
|
|
|
func (w *TabWindow) Active() int {
|
|
|
|
return w.active
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *TabWindow) SetActive(a int) {
|
|
|
|
w.active = a
|
|
|
|
x := 2
|
|
|
|
s := w.TotalSize()
|
|
|
|
for i, n := range w.Names {
|
|
|
|
c := utf8.RuneCountInString(n)
|
|
|
|
if i == a {
|
|
|
|
if x+c >= w.hscroll+w.width {
|
|
|
|
w.hscroll = util.Clamp(x+c+1-w.width, 0, s-w.width)
|
|
|
|
} else if x < w.hscroll {
|
|
|
|
w.hscroll = util.Clamp(x-4, 0, s-w.width)
|
|
|
|
}
|
|
|
|
break
|
|
|
|
}
|
|
|
|
x += c + 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-10 06:13:50 +03:00
|
|
|
func (w *TabWindow) Display() {
|
|
|
|
x := -w.hscroll
|
|
|
|
done := false
|
|
|
|
|
|
|
|
draw := func(r rune, n int) {
|
|
|
|
for i := 0; i < n; i++ {
|
2019-06-15 23:54:53 +03:00
|
|
|
rw := runewidth.RuneWidth(r)
|
|
|
|
for j := 0; j < rw; j++ {
|
|
|
|
c := r
|
|
|
|
if j > 0 {
|
|
|
|
c = ' '
|
|
|
|
}
|
|
|
|
if x == w.width-1 && !done {
|
|
|
|
screen.Screen.SetContent(w.width-1, w.Y, '>', nil, config.DefStyle.Reverse(true))
|
|
|
|
x++
|
|
|
|
break
|
|
|
|
} else if x == 0 && w.hscroll > 0 {
|
|
|
|
screen.Screen.SetContent(0, w.Y, '<', nil, config.DefStyle.Reverse(true))
|
|
|
|
} else if x >= 0 && x < w.width {
|
|
|
|
screen.Screen.SetContent(x, w.Y, c, nil, config.DefStyle.Reverse(true))
|
|
|
|
}
|
2019-01-10 06:13:50 +03:00
|
|
|
x++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, n := range w.Names {
|
2019-01-10 07:44:53 +03:00
|
|
|
if i == w.active {
|
2019-01-10 06:13:50 +03:00
|
|
|
draw('[', 1)
|
|
|
|
} else {
|
|
|
|
draw(' ', 1)
|
|
|
|
}
|
|
|
|
for _, c := range n {
|
|
|
|
draw(c, 1)
|
|
|
|
}
|
|
|
|
if i == len(w.Names)-1 {
|
|
|
|
done = true
|
|
|
|
}
|
2019-01-10 07:44:53 +03:00
|
|
|
if i == w.active {
|
2019-01-10 06:13:50 +03:00
|
|
|
draw(']', 1)
|
|
|
|
draw(' ', 2)
|
|
|
|
} else {
|
|
|
|
draw(' ', 3)
|
|
|
|
}
|
|
|
|
if x >= w.width {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if x < w.width {
|
|
|
|
draw(' ', w.width-x)
|
|
|
|
}
|
|
|
|
}
|