micro/internal/display/tabwindow.go

159 lines
2.8 KiB
Go
Raw Normal View History

2019-01-10 03:13:50 +00:00
package display
import (
2019-06-15 20:54:53 +00:00
runewidth "github.com/mattn/go-runewidth"
2020-05-04 14:16:15 +00:00
"github.com/zyedidia/micro/v2/internal/buffer"
"github.com/zyedidia/micro/v2/internal/config"
"github.com/zyedidia/micro/v2/internal/screen"
"github.com/zyedidia/micro/v2/internal/util"
2019-01-10 03:13:50 +00:00
)
type TabWindow struct {
Names []string
2019-01-10 04:44:53 +00:00
active int
2019-01-10 03:13:50 +00:00
Y int
Width int
2019-01-10 03:13:50 +00:00
hscroll int
}
func NewTabWindow(w int, y int) *TabWindow {
tw := new(TabWindow)
tw.Width = w
2019-01-10 03:13:50 +00:00
tw.Y = y
return tw
}
2020-01-26 05:44:34 +00:00
func (w *TabWindow) Resize(width, height int) {
w.Width = width
2020-01-26 05:44:34 +00:00
}
2019-12-24 21:01:08 +00:00
func (w *TabWindow) LocFromVisual(vloc buffer.Loc) int {
2019-01-10 03:13:50 +00:00
x := -w.hscroll
for i, n := range w.Names {
x++
2020-05-20 20:47:08 +00:00
s := util.CharacterCountInString(n)
2019-01-10 03:13:50 +00:00
if vloc.Y == w.Y && vloc.X < x+s {
return i
}
x += s
x += 3
if x >= w.Width {
2019-01-10 03:13:50 +00:00
break
}
}
return -1
}
func (w *TabWindow) Scroll(amt int) {
w.hscroll += amt
s := w.TotalSize()
w.hscroll = util.Clamp(w.hscroll, 0, s-w.Width)
if s-w.Width <= 0 {
w.hscroll = 0
}
2019-01-10 03:13:50 +00:00
}
func (w *TabWindow) TotalSize() int {
sum := 2
for _, n := range w.Names {
sum += runewidth.StringWidth(n) + 4
2019-01-10 03:13:50 +00:00
}
return sum - 4
}
2019-01-10 04:44:53 +00:00
func (w *TabWindow) Active() int {
return w.active
}
func (w *TabWindow) SetActive(a int) {
w.active = a
x := 2
s := w.TotalSize()
2019-01-10 04:44:53 +00:00
for i, n := range w.Names {
2020-05-20 20:47:08 +00:00
c := util.CharacterCountInString(n)
2019-01-10 04:44:53 +00:00
if i == a {
if x+c >= w.hscroll+w.Width {
w.hscroll = util.Clamp(x+c+1-w.Width, 0, s-w.Width)
2019-01-10 04:44:53 +00:00
} else if x < w.hscroll {
w.hscroll = util.Clamp(x-4, 0, s-w.Width)
2019-01-10 04:44:53 +00:00
}
break
}
x += c + 4
}
if s-w.Width <= 0 {
w.hscroll = 0
}
2019-01-10 04:44:53 +00:00
}
2019-01-10 03:13:50 +00:00
func (w *TabWindow) Display() {
x := -w.hscroll
done := false
tabBarStyle := config.DefStyle.Reverse(true)
if style, ok := config.Colorscheme["tabbar"]; ok {
tabBarStyle = style
}
tabBarActiveStyle := tabBarStyle
if style, ok := config.Colorscheme["tabbar.active"]; ok {
tabBarActiveStyle = style
}
draw := func(r rune, n int, active bool) {
style := tabBarStyle
if active {
style = tabBarActiveStyle
}
2019-01-10 03:13:50 +00:00
for i := 0; i < n; i++ {
2019-06-15 20:54:53 +00:00
rw := runewidth.RuneWidth(r)
for j := 0; j < rw; j++ {
c := r
if j > 0 {
c = ' '
}
if x == w.Width-1 && !done {
screen.SetContent(w.Width-1, w.Y, '>', nil, tabBarStyle)
2019-06-15 20:54:53 +00:00
x++
break
} else if x == 0 && w.hscroll > 0 {
screen.SetContent(0, w.Y, '<', nil, tabBarStyle)
} else if x >= 0 && x < w.Width {
screen.SetContent(x, w.Y, c, nil, style)
2019-06-15 20:54:53 +00:00
}
2019-01-10 03:13:50 +00:00
x++
}
}
}
for i, n := range w.Names {
2019-01-10 04:44:53 +00:00
if i == w.active {
draw('[', 1, true)
2019-01-10 03:13:50 +00:00
} else {
draw(' ', 1, false)
2019-01-10 03:13:50 +00:00
}
for _, c := range n {
draw(c, 1, i == w.active)
2019-01-10 03:13:50 +00:00
}
if i == len(w.Names)-1 {
done = true
}
2019-01-10 04:44:53 +00:00
if i == w.active {
draw(']', 1, true)
draw(' ', 2, true)
2019-01-10 03:13:50 +00:00
} else {
draw(' ', 3, false)
2019-01-10 03:13:50 +00:00
}
if x >= w.Width {
2019-01-10 03:13:50 +00:00
break
}
}
if x < w.Width {
draw(' ', w.Width-x, false)
2019-01-10 03:13:50 +00:00
}
}