akiyosi.goneovim/editor/popupmenu.go

856 lines
21 KiB
Go
Raw Normal View History

2017-11-09 02:11:05 +00:00
package editor
2017-03-14 01:52:44 +00:00
2017-03-14 02:40:16 +00:00
import (
2019-02-07 17:33:55 +09:00
"errors"
2017-06-07 11:24:42 +01:00
"fmt"
2019-11-07 21:46:22 +09:00
"math"
2019-11-21 23:26:29 +09:00
"sort"
2019-11-04 16:14:51 -06:00
"strings"
2017-03-14 02:40:16 +00:00
2019-02-07 17:33:55 +09:00
"github.com/therecipe/qt/core"
2019-02-05 20:21:55 +09:00
"github.com/therecipe/qt/svg"
2019-02-07 17:33:55 +09:00
"github.com/therecipe/qt/widgets"
2019-03-05 23:09:22 +09:00
2019-11-02 10:54:41 +09:00
"github.com/akiyosi/goneovim/util"
2017-03-14 02:40:16 +00:00
)
2017-03-14 01:52:44 +00:00
// PopupMenu is the popupmenu
type PopupMenu struct {
2018-01-05 08:07:29 +00:00
ws *Workspace
2017-06-15 15:54:27 +01:00
widget *widgets.QWidget
2021-01-31 14:05:03 +09:00
gridid int
2019-11-07 21:46:22 +09:00
itemLayout *widgets.QGridLayout
2017-06-15 15:54:27 +01:00
items []*PopupItem
rawItems []interface{}
total int
showTotal int
selected int
top int
2019-11-21 23:26:29 +09:00
completeMode string
2017-06-15 15:54:27 +01:00
scrollBar *widgets.QWidget
scrollBarPos int
scrollBarHeight int
scrollCol *widgets.QWidget
detailLabel *widgets.QLabel
2019-11-08 23:22:32 +09:00
hideItemIdx [2]bool
2017-03-14 01:52:44 +00:00
}
// PopupItem is
type PopupItem struct {
p *PopupMenu
2019-11-05 07:57:32 -06:00
wordLabel *widgets.QLabel
word string
wordRequest string
2021-01-23 14:00:23 +09:00
digitLabel *widgets.QLabel
kind string
2020-02-08 22:38:30 +09:00
kindwidget *widgets.QWidget
2020-09-26 12:04:36 +09:00
kindIcon *svg.QSvgWidget
2018-05-04 22:44:42 +09:00
menuLabel *widgets.QLabel
menu string
menuRequest string
2018-05-04 22:44:42 +09:00
infoLabel *widgets.QLabel
info string
infoRequest string
2018-05-04 22:44:42 +09:00
2017-06-15 15:54:27 +01:00
selected bool
selectedRequest bool
2018-05-04 22:44:42 +09:00
2020-09-26 12:04:36 +09:00
hidden bool
detailText string
2017-06-07 11:24:42 +01:00
}
2019-10-09 01:22:00 +09:00
func initPopupmenuNew() *PopupMenu {
layout := widgets.NewQHBoxLayout()
layout.SetContentsMargins(0, 0, 0, 0)
2021-03-03 23:15:16 +09:00
layout.SetSpacing(0)
widget := widgets.NewQWidget(nil, 0)
widget.SetLayout(layout)
2019-11-07 23:08:08 +09:00
widget.SetContentsMargins(editor.iconSize/5, 0, 0, editor.iconSize/5)
widget.SetMaximumSize2(editor.width, editor.height)
2019-11-07 21:11:47 +09:00
margin := editor.config.Editor.Linespace/2 + 2
itemLayout := widgets.NewQGridLayout2()
itemLayout.SetSpacing(0)
2019-11-07 23:08:08 +09:00
itemLayout.SetContentsMargins(0, editor.iconSize/5, 0, editor.iconSize/5)
2019-11-04 16:14:51 -06:00
2017-06-07 15:52:17 +01:00
scrollCol := widgets.NewQWidget(nil, 0)
scrollCol.SetContentsMargins(0, 0, 0, 0)
scrollCol.SetFixedWidth(5)
scrollBar := widgets.NewQWidget(scrollCol, 0)
scrollBar.SetFixedWidth(5)
2019-11-04 16:14:51 -06:00
2019-11-07 23:08:08 +09:00
detailLabel := widgets.NewQLabel(widget, 0)
2019-11-07 21:11:47 +09:00
detailLabel.SetContentsMargins(margin, margin, margin, margin)
2019-11-07 23:08:08 +09:00
detailLabel.SetObjectName("detailText")
detailLabel.SetWordWrap(true)
2020-02-08 22:38:30 +09:00
detailLabel.SetAlignment(core.Qt__AlignTop)
2019-11-05 07:57:32 -06:00
layout.AddLayout(itemLayout, 0)
2019-11-21 12:10:16 +09:00
layout.AddWidget(detailLabel, 0, core.Qt__AlignTop|core.Qt__AlignLeft)
2019-11-07 23:08:08 +09:00
layout.AddWidget(scrollCol, 0, 0)
2019-11-04 16:14:51 -06:00
2020-02-08 22:38:30 +09:00
total := editor.config.Popupmenu.Total
2018-05-04 22:44:42 +09:00
popup := &PopupMenu{
widget: widget,
2019-11-07 21:46:22 +09:00
itemLayout: itemLayout,
detailLabel: detailLabel,
2020-02-08 22:38:30 +09:00
total: total,
scrollBar: scrollBar,
scrollCol: scrollCol,
}
2019-11-05 07:57:32 -06:00
var popupItems []*PopupItem
2020-02-08 22:38:30 +09:00
for i := 0; i < total; i++ {
iconwidget := widgets.NewQWidget(nil, 0)
iconlayout := widgets.NewQHBoxLayout()
iconlayout.SetContentsMargins(0, 0, 0, 0)
iconwidget.SetLayout(iconlayout)
2019-02-05 20:21:55 +09:00
kindIcon := svg.NewQSvgWidget(nil)
kindIcon.SetFixedSize2(editor.iconSize, editor.iconSize)
2020-02-08 22:38:30 +09:00
iconlayout.AddWidget(kindIcon, 0, 0)
iconwidget.SetContentsMargins(margin, margin, margin, margin)
2019-02-05 20:21:55 +09:00
word := widgets.NewQLabel(widget, 0)
2020-02-08 22:38:30 +09:00
word.SetContentsMargins(margin, margin, margin*2, margin)
2019-11-07 23:08:08 +09:00
word.SetObjectName("wordlabel")
2019-03-20 23:02:47 +09:00
2021-01-23 14:00:23 +09:00
digit := widgets.NewQLabel(widget, 0)
digit.SetContentsMargins(margin, margin, margin*2, margin)
digit.SetObjectName("digitlabel")
menu := widgets.NewQLabel(widget, 0)
menu.SetContentsMargins(margin, margin, margin, margin)
2018-05-04 22:44:42 +09:00
info := widgets.NewQLabel(widget, 0)
info.SetContentsMargins(margin, margin, margin, margin)
itemLayout.AddWidget2(iconwidget, i, 0, 0)
itemLayout.AddWidget2(word, i, 1, 0)
2021-03-03 23:15:16 +09:00
itemLayout.AddWidget2(digit, i, 2, 0)
itemLayout.AddWidget2(menu, i, 3, 0)
itemLayout.AddWidget2(info, i, 4, 0)
2017-06-07 11:24:42 +01:00
popupItem := &PopupItem{
2020-09-26 12:04:36 +09:00
p: popup,
kindIcon: kindIcon,
kindwidget: iconwidget,
wordLabel: word,
2021-01-23 14:00:23 +09:00
digitLabel: digit,
2020-09-26 12:04:36 +09:00
menuLabel: menu,
infoLabel: info,
2017-06-07 11:24:42 +01:00
}
popupItems = append(popupItems, popupItem)
}
popup.items = popupItems
2018-05-06 14:49:45 +09:00
2019-09-11 16:11:02 +09:00
popup.widget.SetGraphicsEffect(util.DropShadow(-2, 6, 40, 200))
2018-05-06 14:49:45 +09:00
2017-06-15 09:06:45 +01:00
return popup
2017-03-14 01:52:44 +00:00
}
2017-06-07 11:31:10 +01:00
func (p *PopupMenu) updateFont(font *Font) {
p.detailLabel.SetFont(font.fontNew)
2017-06-07 11:31:10 +01:00
for i := 0; i < p.total; i++ {
popupItem := p.items[i]
popupItem.wordLabel.SetFont(font.fontNew)
2021-01-23 14:00:23 +09:00
popupItem.digitLabel.SetFont(font.fontNew)
2018-05-04 22:44:42 +09:00
popupItem.menuLabel.SetFont(font.fontNew)
popupItem.infoLabel.SetFont(font.fontNew)
2020-02-08 22:38:30 +09:00
popupItem.kindIcon.SetFixedSize2(font.lineHeight, font.lineHeight)
2020-09-26 12:04:36 +09:00
popupItem.kindwidget.SetFixedWidth(font.lineHeight + editor.config.Editor.Linespace*2)
2017-06-07 11:31:10 +01:00
}
}
2018-12-27 21:03:21 +09:00
func (p *PopupMenu) setColor() {
fg := editor.colors.widgetFg.String()
2019-11-07 23:08:08 +09:00
detail := warpColor(editor.colors.widgetFg, 10).String()
2018-12-27 21:03:21 +09:00
inactiveFg := editor.colors.inactiveFg.String()
2019-02-17 18:00:09 +09:00
bg := editor.colors.widgetBg
transparent := transparent()
2019-02-06 00:04:35 +09:00
p.scrollBar.SetStyleSheet(fmt.Sprintf("background-color: %s;", inactiveFg))
2019-11-07 23:08:08 +09:00
p.widget.SetStyleSheet(
2019-11-14 00:45:01 +09:00
fmt.Sprintf(`
2019-11-07 23:08:08 +09:00
* { background-color: rgba(%d, %d, %d, %f); color: %s; }
.QLabel { background-color: rgba(0, 0, 0, 0.0); color: %s; }
#wordlabel { color: %s; }
`,
bg.R, bg.G, bg.B, transparent, fg, inactiveFg, fg,
),
)
p.detailLabel.SetStyleSheet(
fmt.Sprintf(
"* { background-color: rgba(0, 0, 0, 0.0); color: %s; }",
detail,
),
)
2018-12-27 21:03:21 +09:00
}
2020-07-19 03:40:38 +09:00
func (p *PopupMenu) setPumblend(pumblend int) {
2019-05-27 14:20:31 +09:00
alpha := float64(100-pumblend) / float64(100)
2019-03-18 00:09:49 +09:00
if alpha < 0 {
alpha = 0
}
fg := editor.colors.widgetFg.String()
2019-11-07 23:08:08 +09:00
detail := warpColor(editor.colors.widgetFg, 10).String()
2019-03-18 00:09:49 +09:00
inactiveFg := editor.colors.inactiveFg.String()
bg := editor.colors.widgetBg
p.scrollBar.SetStyleSheet(fmt.Sprintf("background-color: %s;", inactiveFg))
2019-11-07 23:08:08 +09:00
p.widget.SetStyleSheet(
2019-11-14 00:45:01 +09:00
fmt.Sprintf(`
2019-11-07 23:08:08 +09:00
* { background-color: rgba(%d, %d, %d, %f); color: %s; }
.QLabel { background-color: rgba(0, 0, 0, 0.0); color: %s; }
#wordlabel { color: %s; }
`,
bg.R, bg.G, bg.B, alpha, fg, inactiveFg, fg,
),
)
p.detailLabel.SetStyleSheet(
fmt.Sprintf(
"* { background-color: rgba(0, 0, 0, 0.0); color: %s; }",
detail,
),
)
2018-12-27 21:03:21 +09:00
}
2017-06-15 15:54:27 +01:00
func (p *PopupMenu) showItems(args []interface{}) {
2017-03-14 01:52:44 +00:00
arg := args[0].([]interface{})
items := arg[0].([]interface{})
2019-03-05 23:09:22 +09:00
selected := util.ReflectToInt(arg[1])
row := util.ReflectToInt(arg[2])
2019-06-01 14:14:42 +09:00
col := util.ReflectToInt(arg[3])
gridid := util.ReflectToInt(arg[4])
2017-06-07 11:24:42 +01:00
p.rawItems = items
p.selected = selected
p.top = 0
2021-01-31 14:05:03 +09:00
p.gridid = gridid
2017-03-14 01:52:44 +00:00
x, y, lineHeight, isCursorBelowTheCenter := p.ws.getPointInWidget(col, row, gridid)
2019-11-21 23:26:29 +09:00
// Detect vim complete mode
2021-01-23 14:00:23 +09:00
completeMode, err := p.detectVimCompleteMode()
2019-11-21 23:26:29 +09:00
if err == nil {
p.completeMode = completeMode
}
p.detailLabel.SetText("")
2017-03-14 01:52:44 +00:00
popupItems := p.items
2020-09-26 12:04:36 +09:00
itemHeight := (lineHeight) + (editor.config.Editor.Linespace + 4)
2019-11-07 21:46:22 +09:00
// Calc the maximum completion items
// where,
// `row` is the anchor position, where the first character of the completed word will be
// `p.ws.screen.height` is the entire screen height
heightLeft := 0
if isCursorBelowTheCenter {
2020-09-26 12:04:36 +09:00
heightLeft = row * lineHeight
} else {
heightLeft = p.ws.screen.height - (row+1)*lineHeight
}
2017-06-07 11:24:42 +01:00
total := heightLeft / itemHeight
if total < p.total {
p.showTotal = total
} else {
p.showTotal = p.total
}
2020-02-08 22:38:30 +09:00
startNum := 0
2020-09-26 12:04:36 +09:00
if selected >= len(items)-p.showTotal && len(items) > p.total {
2020-02-08 22:38:30 +09:00
startNum = len(items) - p.showTotal
}
2019-11-08 23:22:32 +09:00
itemNum := 0
maxItemLen := 0
2020-02-08 22:38:30 +09:00
for i := startNum; i < p.total+startNum; i++ {
j := i - startNum
popupItem := popupItems[j]
if i >= len(items) || j >= total {
2017-06-15 09:06:45 +01:00
popupItem.hide()
2017-03-14 01:52:44 +00:00
continue
}
item := items[i].([]interface{})
2019-11-08 23:22:32 +09:00
itemLen := p.detectItemLen(item)
if itemLen > maxItemLen {
maxItemLen = itemLen
}
2020-02-08 22:38:30 +09:00
2017-03-14 01:52:44 +00:00
popupItem.setItem(item, selected == i)
2021-01-23 14:00:23 +09:00
popupItem.setDigit(i+1, gridid)
2020-02-08 22:38:30 +09:00
popupItem.hide()
2017-06-15 09:06:45 +01:00
popupItem.show()
2021-01-23 14:00:23 +09:00
2019-11-08 23:22:32 +09:00
itemNum++
}
switch maxItemLen {
case 3:
p.hideItemIdx = [2]bool{false, true}
case 4:
p.hideItemIdx = [2]bool{false, false}
default:
p.hideItemIdx = [2]bool{true, true}
2017-06-07 11:24:42 +01:00
}
2017-03-14 01:52:44 +00:00
2017-06-07 15:52:17 +01:00
if len(items) > p.showTotal {
2017-06-15 15:54:27 +01:00
p.scrollBarHeight = int(float64(p.showTotal) / float64(len(items)) * float64(itemHeight*p.showTotal))
2017-06-15 09:06:45 +01:00
p.scrollBarPos = 0
2017-06-16 08:43:05 +01:00
p.scrollBar.SetFixedHeight(p.scrollBarHeight)
p.scrollBar.Move2(0, p.scrollBarPos)
p.scrollCol.Show()
2017-06-07 15:52:17 +01:00
} else {
2017-06-16 08:43:05 +01:00
p.scrollCol.Hide()
2017-06-07 15:52:17 +01:00
}
2017-06-09 06:54:41 +01:00
2021-03-10 23:53:20 +09:00
// if gridid == 1 {
// for _, item := range p.items {
// if item.selected {
// item.digitLabel.SetStyleSheet(fmt.Sprintf("background-color: %s; color: rgba(0,0,0,0);", editor.colors.selectedBg.StringTransparent()))
// } else {
// item.digitLabel.SetStyleSheet("color: rgba(0,0,0,0);")
// }
// }
// } else {
// for _, item := range p.items {
// fg := editor.colors.inactiveFg
// if item.selected {
// item.digitLabel.SetStyleSheet(fmt.Sprintf("background-color: %s; color: rgba(%d,%d,%d,%f);", editor.colors.selectedBg.StringTransparent(), fg.R, fg.G, fg.B, 1.0))
// } else {
// item.digitLabel.SetStyleSheet(fmt.Sprintf("color: rgba(%d,%d,%d,%f);", fg.R, fg.G, fg.B, 1.0))
// }
// }
// }
2021-01-30 21:42:53 +09:00
2021-01-23 14:00:23 +09:00
// p.hide()
2017-06-15 15:54:27 +01:00
p.show()
2021-01-23 14:00:23 +09:00
2020-02-08 22:38:30 +09:00
p.setWidgetWidth()
2021-01-23 14:00:23 +09:00
p.moveWidget(x, y, lineHeight, isCursorBelowTheCenter, itemNum)
2021-01-23 14:00:23 +09:00
2017-06-15 15:54:27 +01:00
}
2019-11-08 23:22:32 +09:00
func (p *PopupMenu) detectItemLen(item []interface{}) int {
itemlen := 0
for _, i := range item {
if i.(string) == "" {
continue
}
itemlen++
}
return itemlen
}
2017-06-15 15:54:27 +01:00
func (p *PopupMenu) show() {
p.widget.Raise()
2017-06-16 08:43:05 +01:00
p.widget.Show()
2020-02-08 22:38:30 +09:00
}
2019-11-08 23:22:32 +09:00
2020-02-08 22:38:30 +09:00
func (p *PopupMenu) setWidgetWidth() {
2019-11-08 23:22:32 +09:00
isMenuHidden := p.hideItemIdx[0]
isInfoHidden := p.hideItemIdx[1]
2021-03-03 00:42:50 +09:00
maxWordLabelLen := 0
menuStrLen := 0
infoStrLen := 0
2021-03-03 23:15:16 +09:00
margin := editor.config.Editor.Linespace/2 + 2
2019-11-08 23:22:32 +09:00
for _, item := range p.items {
if item.hidden {
continue
}
if isMenuHidden {
item.menuLabel.Hide()
} else {
item.menuLabel.Show()
2021-03-03 00:42:50 +09:00
len := len(item.menu) + 1
if menuStrLen <= len {
menuStrLen = len
}
2019-11-08 23:22:32 +09:00
}
if isInfoHidden {
item.infoLabel.Hide()
} else {
item.infoLabel.Show()
2021-03-03 00:42:50 +09:00
len := len(item.info) + 1
if infoStrLen <= len {
infoStrLen = len
}
2019-11-08 23:22:32 +09:00
}
2021-03-03 00:42:50 +09:00
wordLabelLen := int(math.Ceil(p.ws.screen.runeTextWidth(p.ws.font, item.wordLabel.Text())))
2019-11-08 23:22:32 +09:00
if wordLabelLen > maxWordLabelLen {
maxWordLabelLen = wordLabelLen
2021-03-03 00:42:50 +09:00
maxWordLabelLen += int(p.ws.font.truewidth) + 1
2021-03-03 23:15:16 +09:00
maxWordLabelLen += margin * 3
2019-11-08 23:22:32 +09:00
}
}
if isMenuHidden && isInfoHidden {
p.detailLabel.Hide()
} else {
p.detailLabel.Show()
}
menuWidth := 0
if !isMenuHidden {
2021-03-03 00:42:50 +09:00
menuWidth = int(p.ws.font.truewidth*float64(menuStrLen)) + margin*2 + 1
if menuWidth > editor.config.Popupmenu.MenuWidth {
menuWidth = editor.config.Popupmenu.MenuWidth
}
2019-11-08 23:22:32 +09:00
}
2021-03-03 00:42:50 +09:00
digitLabel := p.items[0].digitLabel.Width() + margin*3
2021-01-31 14:41:29 +09:00
2019-11-08 23:22:32 +09:00
infoWidth := 0
if !isInfoHidden {
2021-03-03 00:42:50 +09:00
infoWidth = int(p.ws.font.truewidth*float64(infoStrLen)) + margin*2 + 1
if infoWidth > editor.config.Popupmenu.InfoWidth {
infoWidth = editor.config.Popupmenu.InfoWidth
}
2019-11-08 23:22:32 +09:00
}
detailWidth := 0
if editor.config.Popupmenu.ShowDetail && !isMenuHidden && !isInfoHidden {
detailWidth = editor.config.Popupmenu.DetailWidth
}
2021-03-03 23:15:16 +09:00
baseWidth := editor.iconSize/5*2 + 5
2019-11-08 23:22:32 +09:00
p.widget.SetFixedWidth(
2021-03-03 23:15:16 +09:00
editor.iconSize + margin*2 + maxWordLabelLen + menuWidth + digitLabel + infoWidth + detailWidth + baseWidth,
2019-11-08 23:22:32 +09:00
)
2017-06-15 15:54:27 +01:00
}
func (p *PopupMenu) moveWidget(x int, y int, lineHeight int, isCursorBelowTheCenter bool, itemNum int) {
2020-02-08 22:38:30 +09:00
popupWidth := p.widget.Width()
// x, y, lineHeight, isCursorBelowTheCenter := p.ws.getPointInWidget(col, row, gridid)
y += lineHeight
2020-02-08 22:38:30 +09:00
if x+popupWidth >= p.ws.screen.widget.Width() {
x = p.ws.screen.widget.Width() - popupWidth - 5
}
popupHeight := itemNum*(lineHeight+editor.config.Editor.Linespace+2) + 2 + editor.iconSize*2/5
p.widget.SetFixedHeight(popupHeight)
if isCursorBelowTheCenter {
y = y - (lineHeight + popupHeight)
p.widget.SetGraphicsEffect(util.DropShadow(-2, -6, 40, 200))
}
2020-02-08 22:38:30 +09:00
p.widget.Move2(x, y)
}
2017-06-15 15:54:27 +01:00
func (p *PopupMenu) hide() {
2017-06-16 08:43:05 +01:00
p.widget.Hide()
2017-03-14 01:52:44 +00:00
}
func (p *PopupMenu) selectItem(args []interface{}) {
2019-03-05 23:09:22 +09:00
selected := util.ReflectToInt(args[0].([]interface{})[0])
2017-06-16 10:35:53 +01:00
if selected == -1 && p.top > 0 {
2017-06-15 09:06:45 +01:00
p.scroll(-p.top)
2017-06-07 11:24:42 +01:00
}
2017-06-07 11:24:42 +01:00
if selected-p.top >= p.showTotal {
p.scroll(selected - p.top - p.showTotal + 1)
}
2017-06-07 11:24:42 +01:00
if selected >= 0 && selected-p.top < 0 {
p.scroll(-1)
}
2019-11-08 23:22:32 +09:00
isMenuHidden := p.hideItemIdx[0]
isInfoHidden := p.hideItemIdx[1]
for i := 0; i < p.showTotal; i++ {
popupItem := p.items[i]
isSelected := selected == i+p.top
2020-02-08 22:38:30 +09:00
popupItem.setSelected(isSelected)
if isSelected {
if editor.config.Popupmenu.ShowDetail {
2019-11-08 23:22:32 +09:00
if !(isMenuHidden && isInfoHidden) {
popupItem.p.detailLabel.SetText(popupItem.detailText)
popupItem.p.detailLabel.Show()
}
} else {
popupItem.p.detailLabel.Hide()
}
}
}
2017-06-07 11:24:42 +01:00
}
func (p *PopupMenu) scroll(n int) {
p.top += n
items := p.rawItems
popupItems := p.items
2019-11-08 23:22:32 +09:00
maxItemLen := 0
2017-06-07 11:24:42 +01:00
for i := 0; i < p.showTotal; i++ {
popupItem := popupItems[i]
item := items[i+p.top].([]interface{})
2019-11-08 23:22:32 +09:00
itemLen := p.detectItemLen(item)
if itemLen > maxItemLen {
maxItemLen = itemLen
}
2017-06-07 11:24:42 +01:00
popupItem.setItem(item, false)
2017-03-14 01:52:44 +00:00
}
2019-11-08 23:22:32 +09:00
switch maxItemLen {
case 3:
p.hideItemIdx = [2]bool{false, true}
case 4:
p.hideItemIdx = [2]bool{false, false}
default:
p.hideItemIdx = [2]bool{true, true}
}
2017-06-15 09:06:45 +01:00
p.scrollBarPos = int((float64(p.top) / float64(len(items))) * float64(p.widget.Height()))
2017-06-16 08:43:05 +01:00
p.scrollBar.Move2(0, p.scrollBarPos)
2021-01-23 14:00:23 +09:00
// p.hide()
// p.show()
2020-02-08 22:38:30 +09:00
p.setWidgetWidth()
2017-03-14 01:52:44 +00:00
}
func (p *PopupItem) setDigit(num int, gridid int) {
2021-01-23 14:00:23 +09:00
if !editor.config.Popupmenu.ShowDigit {
return
}
if num == 10 {
num = 0
}
if num >= 11 {
return
}
p.digitLabel.SetText(fmt.Sprintf("%d", num))
}
func (p *PopupItem) updateContent() {
2017-06-15 15:54:27 +01:00
if p.selected != p.selectedRequest {
p.selected = p.selectedRequest
2021-01-31 14:05:03 +09:00
kindStyle := ""
wordStyle := ""
digitStyle := ""
menuStyle := ""
infoStyle := ""
fg := editor.colors.inactiveFg
2017-06-08 16:03:55 +01:00
if p.selected {
2021-01-31 14:05:03 +09:00
kindStyle = fmt.Sprintf("background-color: %s;", editor.colors.selectedBg.StringTransparent())
wordStyle = fmt.Sprintf("background-color: %s;", editor.colors.selectedBg.StringTransparent())
digitStyle = ""
if p.p.gridid == 1 {
digitStyle = fmt.Sprintf("background-color: %s; color: rgba(0,0,0,0);", editor.colors.selectedBg.StringTransparent())
} else {
digitStyle = fmt.Sprintf("background-color: %s; color: rgba(%d,%d,%d,%f);", editor.colors.selectedBg.StringTransparent(), fg.R, fg.G, fg.B, 1.0)
2021-01-23 14:00:23 +09:00
}
2021-01-31 14:05:03 +09:00
menuStyle = fmt.Sprintf("background-color: %s;", editor.colors.selectedBg.StringTransparent())
infoStyle = fmt.Sprintf("background-color: %s;", editor.colors.selectedBg.StringTransparent())
2017-06-15 15:54:27 +01:00
} else {
2021-01-31 14:05:03 +09:00
kindStyle = fmt.Sprintf("background-color: rgba(0, 0, 0, 0);")
wordStyle = fmt.Sprintf("background-color: rgba(0, 0, 0, 0);")
digitStyle = ""
if p.p.gridid == 1 {
digitStyle = fmt.Sprintf("background-color: rgba(0,0,0,0); color: rgba(0,0,0,0);")
} else {
digitStyle = fmt.Sprintf("background-color: rgba(0,0,0,0); color: rgba(%d,%d,%d,1.0);", fg.R, fg.G, fg.B)
2021-01-23 14:00:23 +09:00
}
2021-01-31 14:05:03 +09:00
menuStyle = fmt.Sprintf("background-color: rgba(0, 0, 0, 0);")
infoStyle = fmt.Sprintf("background-color: rgba(0, 0, 0, 0);")
}
if p.kindwidget.StyleSheet() != kindStyle {
p.kindwidget.SetStyleSheet(kindStyle)
}
if p.wordLabel.StyleSheet() != wordStyle {
p.wordLabel.SetStyleSheet(wordStyle)
}
if p.digitLabel.StyleSheet() != digitStyle {
p.digitLabel.SetStyleSheet(digitStyle)
}
if p.menuLabel.StyleSheet() != menuStyle {
p.menuLabel.SetStyleSheet(menuStyle)
}
if p.infoLabel.StyleSheet() != infoStyle {
p.infoLabel.SetStyleSheet(infoStyle)
2017-06-08 16:03:55 +01:00
}
2017-03-14 01:52:44 +00:00
}
if p.wordRequest != p.word {
p.word = p.wordRequest
p.menu = p.menuRequest
p.info = p.infoRequest
p.wordLabel.SetText(p.word)
2019-11-07 21:11:47 +09:00
menuLines := strings.Split(p.menuRequest, "\n")
infoLines := strings.Split(p.infoRequest, "\n")
p.menuLabel.SetText(menuLines[0])
p.infoLabel.SetText(infoLines[0])
menuLabelTextLen := math.Ceil(p.p.ws.screen.runeTextWidth(p.p.ws.screen.font, menuLines[0]))
2019-11-07 21:11:47 +09:00
if len(menuLines) > 1 || len(infoLines) > 1 || menuLabelTextLen > float64(editor.config.Popupmenu.MenuWidth) {
p.detailText = p.menuRequest + "\n" + p.infoRequest
} else {
p.detailText = ""
}
2017-06-15 15:54:27 +01:00
}
2021-03-03 23:15:16 +09:00
// p.kindwidget.AdjustSize()
margin := editor.config.Editor.Linespace/2 + 2
p.kindwidget.SetFixedWidth(editor.iconSize + margin*2)
// p.wordLabel.AdjustSize()
// p.menuLabel.AdjustSize()
// p.infoLabel.AdjustSize()
2021-03-03 23:15:16 +09:00
// p.digitLabel.SetFixedWidth(editor.config.Popupmenu.MenuWidth)
// p.menuLabel.SetFixedWidth(editor.config.Popupmenu.MenuWidth)
// p.infoLabel.SetFixedWidth(editor.config.Popupmenu.InfoWidth)
2017-06-15 15:54:27 +01:00
}
func (p *PopupItem) setSelected(selected bool) {
p.selectedRequest = selected
p.updateContent()
2017-06-15 15:54:27 +01:00
}
func (p *PopupItem) setItem(item []interface{}, selected bool) {
word := item[0].(string)
kind := item[1].(string)
menu := item[2].(string)
info := item[3].(string)
p.wordRequest = word
p.menuRequest = menu
p.infoRequest = info
p.setKind(kind, selected)
2017-06-15 15:54:27 +01:00
p.setSelected(selected)
2017-03-14 01:52:44 +00:00
}
2021-01-23 14:00:23 +09:00
func (p *PopupMenu) detectVimCompleteMode() (string, error) {
2019-11-21 23:26:29 +09:00
ws := editor.workspaces[editor.active]
2019-02-05 20:21:55 +09:00
2021-01-23 14:00:23 +09:00
var hasCompleteMode int
err := ws.nvim.Eval("exists('*complete_info')", &hasCompleteMode)
2019-11-21 23:26:29 +09:00
if err != nil {
return "vim_unknown", errors.New("complete_info does not exists")
}
2021-01-23 14:00:23 +09:00
if hasCompleteMode == 1 {
2019-11-21 23:26:29 +09:00
var info map[string]interface{}
ws.nvim.Eval("complete_info()", &info)
kind, ok := info["mode"]
if !ok {
2019-02-07 17:33:55 +09:00
return "", nil
}
2019-11-21 23:26:29 +09:00
return kind.(string), nil
2019-02-07 17:33:55 +09:00
}
2019-11-21 23:26:29 +09:00
2020-01-18 22:35:26 +09:00
return "", errors.New("does not exits complete_mode()")
2019-02-07 17:33:55 +09:00
}
func (p *PopupItem) setKind(kind string, selected bool) {
2021-01-23 14:00:23 +09:00
if p.kind == kind && kind != "" {
return
}
p.kind = kind
var colorOfFunc, colorOfStatement, colorOfType, colorOfKeyword *RGBA
2019-11-21 23:26:29 +09:00
hiAttrDef := editor.workspaces[editor.active].screen.hlAttrDef
2019-11-21 23:26:29 +09:00
var keys []int
for k := range hiAttrDef {
keys = append(keys, k)
}
sort.Ints(keys)
for _, k := range keys {
hi := hiAttrDef[k]
switch hi.hlName {
case "Function":
colorOfFunc = hi.fg()
case "Statement":
colorOfStatement = hi.fg()
case "Type":
colorOfType = hi.fg()
case "String":
colorOfKeyword = hi.fg()
default:
continue
}
}
2019-11-21 23:26:29 +09:00
formattedKind := normalizeKind(kind)
icon := ""
switch formattedKind {
2020-09-26 12:04:36 +09:00
case "text":
icon = editor.getSvg("lsp_"+formattedKind, colorOfKeyword)
2020-09-26 12:04:36 +09:00
case "method", "function", "constructor":
icon = editor.getSvg("lsp_function", colorOfFunc)
2020-09-26 12:04:36 +09:00
case "field", "variable", "property":
icon = editor.getSvg("lsp_variable", colorOfFunc)
2020-09-26 12:04:36 +09:00
case "class":
icon = editor.getSvg("lsp_"+formattedKind, colorOfFunc)
2020-09-26 12:04:36 +09:00
case "interface":
icon = editor.getSvg("lsp_"+formattedKind, colorOfFunc)
2020-09-26 12:04:36 +09:00
case "module":
icon = editor.getSvg("lsp_"+formattedKind, colorOfKeyword)
2020-09-26 12:04:36 +09:00
case "unit":
icon = editor.getSvg("lsp_"+formattedKind, colorOfStatement)
2020-09-26 12:04:36 +09:00
case "value":
icon = editor.getSvg("lsp_"+formattedKind, colorOfKeyword)
2020-09-26 12:04:36 +09:00
case "enum":
icon = editor.getSvg("lsp_"+formattedKind, colorOfType)
2020-09-26 12:04:36 +09:00
case "keyword":
icon = editor.getSvg("lsp_"+formattedKind, colorOfKeyword)
2020-09-26 12:04:36 +09:00
case "snippet":
icon = editor.getSvg("lsp_"+formattedKind, colorOfKeyword)
2020-09-26 12:04:36 +09:00
case "color":
icon = editor.getSvg("lsp_"+formattedKind, colorOfKeyword)
2020-09-26 12:04:36 +09:00
case "file":
icon = editor.getSvg("lsp_"+formattedKind, colorOfType)
2020-09-26 12:04:36 +09:00
case "reference":
icon = editor.getSvg("lsp_"+formattedKind, colorOfType)
2020-09-26 12:04:36 +09:00
case "folder":
icon = editor.getSvg("lsp_"+formattedKind, colorOfType)
2020-09-26 12:04:36 +09:00
case "enummember":
icon = editor.getSvg("lsp_"+formattedKind, colorOfKeyword)
2020-09-26 12:04:36 +09:00
case "constant":
icon = editor.getSvg("lsp_"+formattedKind, colorOfKeyword)
2020-09-26 12:04:36 +09:00
case "struct":
icon = editor.getSvg("lsp_"+formattedKind, colorOfStatement)
2020-09-26 12:04:36 +09:00
case "event":
icon = editor.getSvg("lsp_"+formattedKind, colorOfStatement)
2020-09-26 12:04:36 +09:00
case "operato":
icon = editor.getSvg("lsp_"+formattedKind, colorOfStatement)
2020-09-26 12:04:36 +09:00
case "typeparameter":
icon = editor.getSvg("lsp_"+formattedKind, colorOfType)
2019-02-06 00:04:35 +09:00
default:
2020-02-08 22:38:30 +09:00
iconColor := warpColor(editor.colors.fg, -45)
2019-11-21 23:26:29 +09:00
switch p.p.completeMode {
2019-02-07 17:33:55 +09:00
case "keyword",
"whole_line",
"files",
"tags",
"path_defines",
"path_patterns",
2019-11-21 23:26:29 +09:00
"dictionary",
"thesaurus",
"cmdline",
"function",
"omni",
"spell",
"eval":
icon = editor.getSvg("vim_"+p.p.completeMode, iconColor)
2019-02-06 00:04:35 +09:00
p.kindIcon.Load2(core.NewQByteArray2(icon, len(icon)))
default:
icon = editor.getSvg("vim_unknown", iconColor)
2019-02-06 00:04:35 +09:00
p.kindIcon.Load2(core.NewQByteArray2(icon, len(icon)))
}
2017-06-15 15:54:27 +01:00
}
p.kindIcon.Load2(core.NewQByteArray2(icon, len(icon)))
}
func normalizeKind(kind string) string {
2020-09-26 12:04:36 +09:00
// Completion kinds is
// Text
// Method
// Function
// Constructor
// Field
// Variable
// Class
// Interface
// Module
// Property
// Unit
// Value
// Enum
// Keyword
// Snippet
// Color
// File
// Reference
// Folder
// EnumMember
// Constant
// Struct
// Event
// Operator
// TypeParameter
if len(kind) == 1 {
switch kind {
case "v":
return "variable" // equate with "text", "value", "color", "constant"
case "f":
return "function" // equate with "method", "constructor"
case "m":
2020-09-26 12:04:36 +09:00
return "field" // equate with "property", "enumMember"
case "C":
return "class"
case "I":
return "interface"
case "M":
return "module"
case "U":
return "unit"
case "E":
2020-09-26 12:04:36 +09:00
return "enum" // equate with "event"??
case "k":
return "keyword"
case "S":
2020-09-26 12:04:36 +09:00
return "snippet" // equate with "struct"??
case "F":
2020-09-26 12:04:36 +09:00
return "file" // equate with "folder"
case "r":
return "reference"
case "O":
return "operator"
case "T":
return "typeparameter"
}
}
lowerKindText := strings.ToLower(kind)
switch lowerKindText {
2020-09-26 12:04:36 +09:00
case "func", "instance":
return "function"
case "var", "statement", "param", "const":
return "variable"
}
return lowerKindText
2017-03-14 01:52:44 +00:00
}
func (p *PopupItem) hide() {
2017-06-15 09:06:45 +01:00
if p.hidden {
return
}
p.hidden = true
2020-02-08 22:38:30 +09:00
p.kindwidget.Hide()
p.wordLabel.Hide()
2021-01-23 14:00:23 +09:00
p.digitLabel.Hide()
2018-05-04 22:44:42 +09:00
p.menuLabel.Hide()
p.infoLabel.Hide()
2017-06-15 09:06:45 +01:00
}
func (p *PopupItem) show() {
if !p.hidden {
return
}
p.hidden = false
2020-02-08 22:38:30 +09:00
p.kindwidget.Show()
p.wordLabel.Show()
2021-01-23 14:00:23 +09:00
p.digitLabel.Show()
2018-05-04 22:44:42 +09:00
p.menuLabel.Show()
p.infoLabel.Show()
2017-03-14 01:52:44 +00:00
}