akiyosi.goneovim/editor/popupmenu.go

331 lines
8.1 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 (
2017-06-07 11:24:42 +01:00
"fmt"
2017-03-14 02:40:16 +00:00
2017-06-07 11:24:42 +01:00
"github.com/therecipe/qt/gui"
"github.com/therecipe/qt/widgets"
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
layout *widgets.QGridLayout
items []*PopupItem
rawItems []interface{}
total int
showTotal int
selected int
hidden bool
top int
scrollBar *widgets.QWidget
scrollBarPos int
scrollBarHeight int
scrollCol *widgets.QWidget
x int
y int
2017-03-14 01:52:44 +00:00
}
// PopupItem is
type PopupItem struct {
2018-05-05 08:51:46 +09:00
kindLabel *widgets.QLabel
kindText string
detailText string
2018-05-04 22:44:42 +09:00
menuLabel *widgets.QLabel
2017-06-15 15:54:27 +01:00
menuText string
menuTextRequest string
2018-05-04 22:44:42 +09:00
2018-05-05 08:51:46 +09:00
detailLabel *widgets.QLabel
detailTextRequest 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
2018-05-05 08:51:46 +09:00
kindColor *RGBA
kindBg *RGBA
hidden bool
2017-06-07 11:24:42 +01:00
}
2017-06-07 11:31:10 +01:00
func initPopupmenuNew(font *Font) *PopupMenu {
2017-06-07 11:24:42 +01:00
layout := widgets.NewQGridLayout2()
layout.SetSpacing(0)
layout.SetContentsMargins(0, 0, 0, 0)
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)
//scrollBar.SetStyleSheet("background-color: #3c3c3c;")
2017-06-07 15:52:17 +01:00
mainLayout := widgets.NewQHBoxLayout()
mainLayout.AddLayout(layout, 0)
mainLayout.AddWidget(scrollCol, 0, 0)
mainLayout.SetContentsMargins(0, 0, 0, 0)
mainLayout.SetSpacing(0)
2017-06-07 11:24:42 +01:00
widget := widgets.NewQWidget(nil, 0)
2017-06-07 15:52:17 +01:00
widget.SetLayout(mainLayout)
2017-06-28 07:32:14 +01:00
widget.SetContentsMargins(1, 1, 1, 1)
//widget.SetStyleSheet("* {background-color: rgba(24, 29, 34, 1); color: rgba(205, 211, 222, 1);}")
2017-06-07 11:24:42 +01:00
max := 15
var popupItems []*PopupItem
2018-05-04 22:44:42 +09:00
margin := editor.config.Editor.Linespace
2017-06-07 11:24:42 +01:00
for i := 0; i < max; i++ {
kind := widgets.NewQLabel(nil, 0)
kind.SetContentsMargins(margin, margin, margin, margin)
2017-06-07 11:31:10 +01:00
kind.SetFont(font.fontNew)
2017-06-07 11:24:42 +01:00
menu := widgets.NewQLabel(nil, 0)
menu.SetContentsMargins(margin, margin, margin, margin)
2017-06-07 11:31:10 +01:00
menu.SetFont(font.fontNew)
2018-05-04 22:44:42 +09:00
detail := widgets.NewQLabel(nil, 0)
detail.SetContentsMargins(margin, margin, margin, margin)
2018-05-04 22:44:42 +09:00
detail.SetFont(font.fontNew)
2018-05-05 08:51:46 +09:00
detail.SetObjectName("detailpopup")
2018-05-04 22:44:42 +09:00
2017-06-07 11:24:42 +01:00
layout.AddWidget(kind, i, 0, 0)
layout.AddWidget(menu, i, 1, 0)
2018-05-04 22:44:42 +09:00
layout.AddWidget(detail, i, 2, 0)
2017-06-07 11:24:42 +01:00
popupItem := &PopupItem{
2018-05-05 08:51:46 +09:00
kindLabel: kind,
menuLabel: menu,
2018-05-04 22:44:42 +09:00
detailLabel: detail,
2017-06-07 11:24:42 +01:00
}
popupItems = append(popupItems, popupItem)
}
2017-06-15 09:06:45 +01:00
popup := &PopupMenu{
2017-06-07 15:52:17 +01:00
widget: widget,
layout: layout,
items: popupItems,
total: max,
scrollBar: scrollBar,
scrollCol: scrollCol,
2017-06-07 11:24:42 +01:00
}
2018-05-06 14:49:45 +09:00
shadow := widgets.NewQGraphicsDropShadowEffect(nil)
shadow.SetBlurRadius(28)
shadow.SetColor(gui.NewQColor3(0, 0, 0, 80))
shadow.SetOffset3(0, 6)
popup.widget.SetGraphicsEffect(shadow)
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) {
for i := 0; i < p.total; i++ {
popupItem := p.items[i]
2018-05-04 22:44:42 +09:00
popupItem.kindLabel.SetFont(font.fontNew)
popupItem.menuLabel.SetFont(font.fontNew)
popupItem.detailLabel.SetFont(font.fontNew)
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()
inactiveFg := editor.colors.inactiveFg.String()
bg := editor.colors.widgetBg.String()
sbg := editor.colors.scrollBarBg.String()
p.scrollBar.SetStyleSheet(fmt.Sprintf("background-color: %s;", sbg))
p.widget.SetStyleSheet(fmt.Sprintf("* {background-color: %s; color: %s;} #detailpopup { color: %s; }", bg, fg, inactiveFg))
}
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{})
selected := reflectToInt(arg[1])
row := reflectToInt(arg[2])
col := reflectToInt(arg[3])
2017-06-07 11:24:42 +01:00
p.rawItems = items
p.selected = selected
p.top = 0
2017-03-14 01:52:44 +00:00
popupItems := p.items
2018-01-05 08:07:29 +00:00
itemHeight := p.ws.font.height + 20
heightLeft := p.ws.screen.height - (row+1)*p.ws.font.lineHeight
2017-06-07 11:24:42 +01:00
total := heightLeft / itemHeight
if total < p.total {
p.showTotal = total
} else {
p.showTotal = p.total
}
for i := 0; i < p.total; i++ {
2017-03-14 01:52:44 +00:00
popupItem := popupItems[i]
2017-06-07 11:24:42 +01:00
if i >= len(items) || i >= total {
2017-06-15 09:06:45 +01:00
popupItem.hide()
2017-03-14 01:52:44 +00:00
continue
}
item := items[i].([]interface{})
popupItem.setItem(item, selected == i)
2017-06-15 09:06:45 +01:00
popupItem.show()
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
2017-06-16 08:43:05 +01:00
p.widget.Move2(
2018-05-04 22:44:42 +09:00
int(float64(col)*p.ws.font.truewidth)-popupItems[0].kindLabel.Width()-8,
2018-01-05 08:07:29 +00:00
(row+1)*p.ws.font.lineHeight,
2017-06-15 15:54:27 +01:00
)
p.show()
}
func (p *PopupMenu) show() {
2017-06-16 08:43:05 +01:00
p.widget.Show()
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{}) {
selected := 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
}
if selected-p.top >= p.showTotal {
p.scroll(selected - p.top - p.showTotal + 1)
}
if selected >= 0 && selected-p.top < 0 {
p.scroll(-1)
}
for i := 0; i < p.showTotal; i++ {
2017-03-14 01:52:44 +00:00
popupItem := p.items[i]
2017-06-15 15:54:27 +01:00
popupItem.setSelected(selected == i+p.top)
2017-06-07 11:24:42 +01:00
}
}
func (p *PopupMenu) scroll(n int) {
2017-06-15 09:06:45 +01:00
// fmt.Println(len(p.rawItems), p.top, n)
2017-06-07 11:24:42 +01:00
p.top += n
items := p.rawItems
popupItems := p.items
for i := 0; i < p.showTotal; i++ {
popupItem := popupItems[i]
item := items[i+p.top].([]interface{})
popupItem.setItem(item, false)
2017-03-14 01:52:44 +00:00
}
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)
2017-06-15 15:54:27 +01:00
p.hide()
p.show()
2017-03-14 01:52:44 +00:00
}
2017-06-15 15:54:27 +01:00
func (p *PopupItem) updateKind() {
2018-05-04 22:44:42 +09:00
p.kindLabel.SetStyleSheet(fmt.Sprintf("background-color: %s; color: %s;", p.kindBg.String(), p.kindColor.String()))
p.kindLabel.SetText(p.kindText)
2017-06-15 15:54:27 +01:00
}
2017-03-14 01:52:44 +00:00
2017-06-15 15:54:27 +01:00
func (p *PopupItem) updateMenu() {
if p.selected != p.selectedRequest {
p.selected = p.selectedRequest
2017-06-08 16:03:55 +01:00
if p.selected {
2018-12-27 12:38:42 +09:00
p.menuLabel.SetStyleSheet(fmt.Sprintf("background-color: %s;", editor.colors.selectedBg.String()))
p.detailLabel.SetStyleSheet(fmt.Sprintf("background-color: %s;", editor.colors.selectedBg.String()))
2017-06-15 15:54:27 +01:00
} else {
2018-05-04 22:44:42 +09:00
p.menuLabel.SetStyleSheet("")
p.detailLabel.SetStyleSheet("")
2017-06-08 16:03:55 +01:00
}
2017-03-14 01:52:44 +00:00
}
2017-06-15 15:54:27 +01:00
if p.menuTextRequest != p.menuText {
p.menuText = p.menuTextRequest
2018-05-04 22:44:42 +09:00
p.menuLabel.SetText(p.menuText)
p.detailText = p.detailTextRequest
p.detailLabel.SetText(p.detailText)
2017-06-15 15:54:27 +01:00
}
}
func (p *PopupItem) setSelected(selected bool) {
p.selectedRequest = selected
2017-06-16 08:43:05 +01:00
p.updateMenu()
2017-06-15 15:54:27 +01:00
}
func (p *PopupItem) setItem(item []interface{}, selected bool) {
text := item[0].(string)
kindText := item[1].(string)
2018-05-04 22:44:42 +09:00
detail := fmt.Sprintf("%s", item[2:])
2017-06-15 15:54:27 +01:00
p.setKind(kindText, selected)
p.menuTextRequest = text
2018-05-05 08:51:46 +09:00
p.detailTextRequest = detail[1 : len(detail)-1] // cut "[" and "]"
2017-06-15 15:54:27 +01:00
p.setSelected(selected)
2017-03-14 01:52:44 +00:00
}
func (p *PopupItem) setKind(kindText string, selected bool) {
2017-03-14 02:40:16 +00:00
color := newRGBA(151, 195, 120, 1)
bg := newRGBA(151, 195, 120, 0.2)
2017-03-14 01:52:44 +00:00
switch kindText {
2017-03-14 07:37:15 +00:00
case "function", "func":
2017-03-14 02:40:16 +00:00
kindText = "f"
color = newRGBA(97, 174, 239, 1)
bg = newRGBA(97, 174, 239, 0.2)
2017-03-14 07:37:15 +00:00
case "var", "statement", "instance", "param", "import":
kindText = "v"
color = newRGBA(223, 106, 115, 1)
bg = newRGBA(223, 106, 115, 0.2)
case "const":
kindText = "c"
color = newRGBA(223, 106, 115, 1)
bg = newRGBA(223, 106, 115, 0.2)
case "class":
kindText = "c"
color = newRGBA(229, 193, 124, 1)
bg = newRGBA(229, 193, 124, 0.2)
case "type":
kindText = "t"
color = newRGBA(229, 193, 124, 1)
bg = newRGBA(229, 193, 124, 0.2)
case "module":
kindText = "m"
color = newRGBA(42, 161, 152, 1)
bg = newRGBA(42, 161, 152, 0.2)
case "keyword":
kindText = "k"
color = newRGBA(42, 161, 152, 1)
bg = newRGBA(42, 161, 152, 0.2)
case "package":
kindText = "p"
color = newRGBA(42, 161, 152, 1)
bg = newRGBA(42, 161, 152, 0.2)
2017-03-14 01:52:44 +00:00
default:
kindText = "b"
}
2017-06-15 15:54:27 +01:00
if kindText != p.kindText {
p.kindText = kindText
p.kindColor = color
p.kindBg = bg
2017-06-16 08:43:05 +01:00
p.updateKind()
2017-06-15 15:54:27 +01:00
}
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
2018-05-04 22:44:42 +09:00
p.kindLabel.Hide()
p.menuLabel.Hide()
p.detailLabel.Hide()
2017-06-15 09:06:45 +01:00
}
func (p *PopupItem) show() {
if !p.hidden {
return
}
p.hidden = false
2018-05-04 22:44:42 +09:00
p.kindLabel.Show()
p.menuLabel.Show()
p.detailLabel.Show()
2017-03-14 01:52:44 +00:00
}