akiyosi.goneovim/editor/scrollbar.go

178 lines
4 KiB
Go
Raw Normal View History

2018-09-16 21:48:17 +09:00
package editor
import (
2018-12-27 21:03:21 +09:00
"fmt"
2020-03-09 23:48:46 +09:00
"math"
2018-12-27 21:03:21 +09:00
2020-03-09 23:48:46 +09:00
"github.com/akiyosi/goneovim/util"
2018-09-16 21:48:17 +09:00
"github.com/therecipe/qt/widgets"
2020-03-09 23:48:46 +09:00
"github.com/therecipe/qt/core"
"github.com/therecipe/qt/gui"
2018-09-16 21:48:17 +09:00
)
// ScrollBar is
type ScrollBar struct {
2020-03-09 23:48:46 +09:00
ws *Workspace
widget *widgets.QWidget
thumb *widgets.QWidget
pos int
height int
isPressed bool
beginPosY int
2018-09-16 21:48:17 +09:00
}
func newScrollBar() *ScrollBar {
widget := widgets.NewQWidget(nil, 0)
widget.SetContentsMargins(0, 0, 0, 0)
2018-09-22 07:44:44 +09:00
widget.SetFixedWidth(10)
2018-09-16 21:48:17 +09:00
thumb := widgets.NewQWidget(widget, 0)
2020-03-09 23:48:46 +09:00
thumb.SetFixedWidth(6)
2018-09-16 21:48:17 +09:00
scrollBar := &ScrollBar{
widget: widget,
thumb: thumb,
}
scrollBar.widget.Hide()
2020-03-09 23:48:46 +09:00
scrollBar.thumb.ConnectMousePressEvent(scrollBar.mousePress)
scrollBar.thumb.ConnectMouseMoveEvent(scrollBar.mouseScroll)
scrollBar.thumb.ConnectMouseReleaseEvent(scrollBar.mouseRelease)
scrollBar.thumb.ConnectEnterEvent(scrollBar.mouseEnter)
scrollBar.thumb.ConnectLeaveEvent(scrollBar.mouseLeave)
2018-09-16 21:48:17 +09:00
return scrollBar
}
2020-03-09 23:48:46 +09:00
func (s *ScrollBar) mouseEnter(e *core.QEvent) {
color := editor.colors.selectedBg.String()
s.thumb.SetStyleSheet(fmt.Sprintf(" * { background: %s;}", color))
}
func (s *ScrollBar) mouseLeave(e *core.QEvent) {
color := editor.colors.scrollBarFg.String()
s.thumb.SetStyleSheet(fmt.Sprintf(" * { background: %s;}", color))
}
func (s *ScrollBar) mousePress(e *gui.QMouseEvent) {
s.beginPosY = e.GlobalPos().Y()
s.isPressed = true
}
func (s *ScrollBar) mouseScroll(e *gui.QMouseEvent) {
win, ok := s.ws.screen.getWindow(s.ws.cursor.gridid)
if !ok {
return
}
font := win.getFont()
ratio := float64(s.ws.maxLine * font.lineHeight) / float64(s.widget.Height())
v := s.beginPosY - e.GlobalPos().Y()
if v == 0 {
return
}
v2 := int(math.Ceil(float64(v) * ratio))
s.scroll(v2, 0)
s.beginPosY = e.GlobalPos().Y()
s.update()
}
func (s *ScrollBar) mouseRelease(e *gui.QMouseEvent) {
s.isPressed = false
s.scroll(0, 0)
}
// for smooth scroll, but it has some probrem
func (s *ScrollBar) scroll(v, h int) {
var vert int
var vertKey string
win, ok := s.ws.screen.getWindow(s.ws.cursor.gridid)
if !ok {
return
}
font := win.getFont()
isStopScroll := !s.isPressed
if int(math.Abs(float64(v))) >= font.lineHeight {
vert = v / font.lineHeight
} else {
vert, _ = win.smoothUpdate(v, h, isStopScroll)
}
if vert == 0 {
return
}
if vert > 0 {
vertKey = "Up"
} else {
vertKey = "Down"
}
// Detect current mode
mode := win.s.ws.mode
if mode != "normal" {
win.s.ws.nvim.Input(win.s.ws.escKeyInInsert)
} else if mode == "terminal-input" {
win.s.ws.nvim.Input(`<C-\><C-n>`)
}
if win.s.ws.isMappingScrollKey {
if vert != 0 {
win.s.ws.nvim.Input(fmt.Sprintf("<ScrollWheel%s>", vertKey))
}
} else {
if vert > 0 {
win.s.ws.nvim.Input(fmt.Sprintf("%v<C-y>", int(math.Abs(float64(vert)))))
} else if vert < 0 {
win.s.ws.nvim.Input(fmt.Sprintf("%v<C-e>", int(math.Abs(float64(vert)))))
}
}
}
2018-12-27 21:03:21 +09:00
func (s *ScrollBar) setColor() {
2019-02-17 18:00:09 +09:00
fg := editor.colors.scrollBarFg.String()
2018-12-27 21:03:21 +09:00
s.thumb.SetStyleSheet(fmt.Sprintf(" * { background: %s;}", fg))
2019-03-02 23:31:40 +09:00
s.widget.SetStyleSheet(" * { background: rgba(0, 0, 0, 0);}")
2018-12-27 21:03:21 +09:00
}
2018-09-16 21:48:17 +09:00
func (s *ScrollBar) update() {
2020-03-07 17:53:16 +09:00
win, ok := s.ws.screen.getWindow(s.ws.cursor.gridid)
if !ok {
return
}
top := win.scrollRegion[0]
bot := win.scrollRegion[1]
2018-09-16 21:48:17 +09:00
if top == 0 && bot == 0 {
2018-09-17 15:31:34 +09:00
top = 0
bot = s.ws.rows - 1
}
relativeCursorY := int(float64(s.ws.cursor.y) / float64(s.ws.font.lineHeight))
if s.ws.maxLine == 0 {
2018-09-30 23:43:21 +09:00
//s.ws.nvim.Eval("line('$')", &s.ws.maxLine)
lnITF, err := s.ws.nvimEval("line('$')")
if err != nil {
s.ws.maxLine = 0
} else {
2020-03-09 23:48:46 +09:00
s.ws.maxLine = util.ReflectToInt(lnITF)
2018-09-30 23:43:21 +09:00
}
2018-09-16 21:48:17 +09:00
}
2020-03-09 23:48:46 +09:00
2018-09-16 21:48:17 +09:00
if s.ws.maxLine > bot-top {
s.height = int(float64(bot-top) / float64(s.ws.maxLine) * float64(s.ws.screen.widget.Height()))
2020-03-09 23:48:46 +09:00
height := s.height
2018-09-22 07:44:44 +09:00
if s.height < 20 {
2020-03-09 23:48:46 +09:00
height = 20
2018-09-22 07:44:44 +09:00
}
2020-03-09 23:48:46 +09:00
s.thumb.SetFixedHeight(height)
2018-09-21 22:04:24 +09:00
s.pos = int(float64(s.ws.curLine-relativeCursorY) / float64(s.ws.maxLine) * float64(s.ws.screen.widget.Height()))
2018-09-17 15:31:34 +09:00
s.thumb.Move2(0, s.pos)
2018-09-16 21:48:17 +09:00
s.widget.Show()
} else {
s.widget.Hide()
}
}