mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-28 22:08:12 +09:00
Add tabbar and tab mouse support
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
package action
|
package action
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/zyedidia/micro/cmd/micro/buffer"
|
"github.com/zyedidia/micro/cmd/micro/buffer"
|
||||||
@@ -206,7 +205,6 @@ func VSplit(args []string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("loaded")
|
|
||||||
MainTab().CurPane().vsplit(buf)
|
MainTab().CurPane().vsplit(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ import (
|
|||||||
|
|
||||||
type TabList struct {
|
type TabList struct {
|
||||||
*display.TabWindow
|
*display.TabWindow
|
||||||
List []*TabPane
|
List []*TabPane
|
||||||
Active int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTabList(bufs []*buffer.Buffer) *TabList {
|
func NewTabList(bufs []*buffer.Buffer) *TabList {
|
||||||
@@ -50,14 +49,28 @@ func (t *TabList) HandleEvent(event tcell.Event) {
|
|||||||
p.Resize()
|
p.Resize()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
t.List[0].Node.Resize(w, h-2)
|
t.List[0].Node.Resize(w, h-1)
|
||||||
t.List[0].Resize()
|
t.List[0].Resize()
|
||||||
}
|
}
|
||||||
case *tcell.EventMouse:
|
case *tcell.EventMouse:
|
||||||
|
mx, my := e.Position()
|
||||||
switch e.Buttons() {
|
switch e.Buttons() {
|
||||||
case tcell.Button1:
|
case tcell.Button1:
|
||||||
|
ind := t.GetMouseLoc(buffer.Loc{mx, my})
|
||||||
|
if ind != -1 {
|
||||||
|
t.Active = ind
|
||||||
|
}
|
||||||
|
case tcell.WheelUp:
|
||||||
|
if my == t.Y {
|
||||||
|
t.Scroll(4)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case tcell.WheelDown:
|
||||||
|
if my == t.Y {
|
||||||
|
t.Scroll(-4)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
t.List[t.Active].HandleEvent(event)
|
t.List[t.Active].HandleEvent(event)
|
||||||
}
|
}
|
||||||
@@ -99,10 +112,9 @@ type TabPane struct {
|
|||||||
func (t *TabPane) HandleEvent(event tcell.Event) {
|
func (t *TabPane) HandleEvent(event tcell.Event) {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *tcell.EventMouse:
|
case *tcell.EventMouse:
|
||||||
|
mx, my := e.Position()
|
||||||
switch e.Buttons() {
|
switch e.Buttons() {
|
||||||
case tcell.Button1:
|
case tcell.Button1:
|
||||||
mx, my := e.Position()
|
|
||||||
|
|
||||||
resizeID := t.GetMouseSplitID(buffer.Loc{mx, my})
|
resizeID := t.GetMouseSplitID(buffer.Loc{mx, my})
|
||||||
if t.resizing != nil {
|
if t.resizing != nil {
|
||||||
var size int
|
var size int
|
||||||
@@ -133,6 +145,15 @@ func (t *TabPane) HandleEvent(event tcell.Event) {
|
|||||||
}
|
}
|
||||||
case tcell.ButtonNone:
|
case tcell.ButtonNone:
|
||||||
t.resizing = nil
|
t.resizing = nil
|
||||||
|
default:
|
||||||
|
for _, p := range t.Panes {
|
||||||
|
v := p.GetView()
|
||||||
|
inpane := mx >= v.X && mx < v.X+v.Width && my >= v.Y && my < v.Y+v.Height
|
||||||
|
if inpane {
|
||||||
|
p.HandleEvent(event)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -170,11 +191,11 @@ func (t *TabPane) RemovePane(i int) {
|
|||||||
|
|
||||||
// Resize resizes all panes according to their corresponding split nodes
|
// Resize resizes all panes according to their corresponding split nodes
|
||||||
func (t *TabPane) Resize() {
|
func (t *TabPane) Resize() {
|
||||||
for i, p := range t.Panes {
|
for _, p := range t.Panes {
|
||||||
n := t.GetNode(p.splitID)
|
n := t.GetNode(p.splitID)
|
||||||
pv := p.GetView()
|
pv := p.GetView()
|
||||||
offset := 0
|
offset := 0
|
||||||
if i != 0 {
|
if n.X != 0 {
|
||||||
offset = 1
|
offset = 1
|
||||||
}
|
}
|
||||||
pv.X, pv.Y = n.X+offset, n.Y
|
pv.X, pv.Y = n.X+offset, n.Y
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
package display
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/zyedidia/micro/cmd/micro/config"
|
|
||||||
"github.com/zyedidia/micro/cmd/micro/screen"
|
|
||||||
)
|
|
||||||
|
|
||||||
type TabWindow struct {
|
|
||||||
Names []string
|
|
||||||
Active int
|
|
||||||
width int
|
|
||||||
hscroll int
|
|
||||||
y int
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewTabWindow(w int, y int) *TabWindow {
|
|
||||||
tw := new(TabWindow)
|
|
||||||
tw.width = w
|
|
||||||
tw.y = y
|
|
||||||
return tw
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *TabWindow) Display() {
|
|
||||||
x := -w.hscroll
|
|
||||||
|
|
||||||
draw := func(r rune, n int) {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
screen.Screen.SetContent(x, w.y, r, nil, config.DefStyle.Reverse(true))
|
|
||||||
x++
|
|
||||||
log.Println(x)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, n := range w.Names {
|
|
||||||
if i == w.Active {
|
|
||||||
draw('[', 1)
|
|
||||||
}
|
|
||||||
for _, c := range n {
|
|
||||||
draw(c, 1)
|
|
||||||
}
|
|
||||||
if i == w.Active {
|
|
||||||
draw(']', 1)
|
|
||||||
draw(' ', 3)
|
|
||||||
} else {
|
|
||||||
draw(' ', 4)
|
|
||||||
}
|
|
||||||
if x >= w.width {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if x < w.width {
|
|
||||||
draw(' ', w.width-x)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
105
cmd/micro/display/tabwindow.go
Normal file
105
cmd/micro/display/tabwindow.go
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
package display
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/zyedidia/micro/cmd/micro/buffer"
|
||||||
|
"github.com/zyedidia/micro/cmd/micro/config"
|
||||||
|
"github.com/zyedidia/micro/cmd/micro/screen"
|
||||||
|
"github.com/zyedidia/micro/cmd/micro/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TabWindow struct {
|
||||||
|
Names []string
|
||||||
|
Active int
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: handle files with character width >=2
|
||||||
|
|
||||||
|
func (w *TabWindow) Display() {
|
||||||
|
x := -w.hscroll
|
||||||
|
done := false
|
||||||
|
|
||||||
|
draw := func(r rune, n int) {
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
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, r, nil, config.DefStyle.Reverse(true))
|
||||||
|
}
|
||||||
|
x++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, n := range w.Names {
|
||||||
|
if i == w.Active {
|
||||||
|
draw('[', 1)
|
||||||
|
} else {
|
||||||
|
draw(' ', 1)
|
||||||
|
}
|
||||||
|
for _, c := range n {
|
||||||
|
draw(c, 1)
|
||||||
|
}
|
||||||
|
if i == len(w.Names)-1 {
|
||||||
|
done = true
|
||||||
|
}
|
||||||
|
if i == w.Active {
|
||||||
|
draw(']', 1)
|
||||||
|
draw(' ', 2)
|
||||||
|
} else {
|
||||||
|
draw(' ', 3)
|
||||||
|
}
|
||||||
|
if x >= w.width {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if x < w.width {
|
||||||
|
draw(' ', w.width-x)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -225,7 +225,7 @@ func main() {
|
|||||||
if action.InfoBar.HasPrompt {
|
if action.InfoBar.HasPrompt {
|
||||||
action.InfoBar.HandleEvent(event)
|
action.InfoBar.HandleEvent(event)
|
||||||
} else {
|
} else {
|
||||||
action.MainTab().HandleEvent(event)
|
action.Tabs.HandleEvent(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package util
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
@@ -17,9 +16,7 @@ import (
|
|||||||
// This will write the message, and wait for the user
|
// This will write the message, and wait for the user
|
||||||
// to press and key to continue
|
// to press and key to continue
|
||||||
func TermMessage(msg ...interface{}) {
|
func TermMessage(msg ...interface{}) {
|
||||||
log.Println(msg)
|
|
||||||
screen.TempFini()
|
screen.TempFini()
|
||||||
log.Println("fini")
|
|
||||||
|
|
||||||
fmt.Println(msg...)
|
fmt.Println(msg...)
|
||||||
fmt.Print("\nPress enter to continue")
|
fmt.Print("\nPress enter to continue")
|
||||||
|
|||||||
Reference in New Issue
Block a user