2019-11-12 14:52:17 +03:00

167 lines
4.1 KiB
Go

package screens
import (
"fmt"
"lab.zaar.be/thefish/alchemyst-go/engine/types"
"lab.zaar.be/thefish/alchemyst-go/ui/mainwindow"
blt "lab.zaar.be/thefish/bearlibterminal"
"strings"
)
const runeIndex = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
type MenuScreen struct {
types.Rect
mw *mainwindow.MainWindow
scm *types.ScreenManager
renderParent bool
items []interface{}
offset int
drawFunc func()
inputFunc func(string)
title string
header string
footer string
redraw bool
bgColor string
fgColor string
}
func NewMenuScreen(mw *mainwindow.MainWindow, scm *types.ScreenManager, title, header, footer string, rect types.Rect, renderParent bool) *MenuScreen {
return &MenuScreen{
title: title,
header: header,
footer: footer,
Rect: rect,
mw: mw,
scm: scm,
renderParent: renderParent,
}
}
func (ms *MenuScreen) MakeList() *MenuScreen {
ms.drawFunc = ms.ListRender
ms.inputFunc = ms.ListHandleInput
return ms
}
func (ms *MenuScreen) SetBgColor(color string) *MenuScreen {
ms.bgColor = color
return ms
}
func (ms *MenuScreen) SetFgColor(color string) *MenuScreen {
ms.fgColor = color
return ms
}
//fixme!!
func (ms *MenuScreen) SetItems(items []interface{}) *MenuScreen {
ms.items = items
return ms
}
func (ms *MenuScreen) UseEcs() bool { return false }
func (ms *MenuScreen) Enter() {
ms.redraw = true
ms.offset = 0
}
func (ms *MenuScreen) HandleInput(input string) {
ms.inputFunc(input)
}
func (ms *MenuScreen) Exit() {
menuLayer := ms.mw.GetLayer("menu")
menuLayer.ClearRect(ms.Rect)
bgLayer := ms.mw.GetLayer("menubg")
bgLayer.ClearRect(ms.Rect)
}
func (ms *MenuScreen) Render() {
if ms.renderParent {
ms.scm.PreviousScreen.Render()
}
if (ms.redraw || ms.renderParent) {
ms.redraw = false
ms.drawFunc()
}
}
func (ms *MenuScreen) ListHandleInput(input string) {
switch input {
case "Up":
ms.offset = ms.offset - 1
if ms.offset < 0 {
ms.offset = 0
}
break
case "Down":
ms.offset = ms.offset + 1
if ms.offset > len(ms.items)-1 {
ms.offset = len(ms.items) - 1
}
break
case "Escape":
fallthrough
case "Space":
ms.scm.SetScreen(ms.scm.PreviousScreen)
break
}
}
func (ms *MenuScreen) ListRender() {
menuLayer := ms.mw.GetLayer("menu")
menuLayer.ClearRect(ms.Rect)
bgLayer := ms.mw.GetLayer("menubg")
bgLayer.ClearRect(ms.Rect)
bgLayer.WithColor(ms.bgColor).NewWindow(ms.Rect).Splash()
menuLayer.WithColor(ms.fgColor).NewWindow(ms.Rect).DoubleBordered(ms.title)
menuLayer.Print(ms.X+(ms.W/2)-7, ms.Y+ms.H-1, "╡"+"[color=green]Space[/color] to close"+"╞")
footerHeight := 0
if ms.footer != "" {
_, footerHeight = menuLayer.PrintInside(ms.Rect, ms.footer, 9)
footerHeight = footerHeight + 2
}
_, headerHeight := menuLayer.PrintInside(ms.Rect, ms.header, blt.TK_ALIGN_LEFT)
itemField := types.Rect{ms.X, ms.Y + headerHeight + 1, ms.W, ms.H - headerHeight - footerHeight}
_ = itemField
var ilw, ilh int
if (len(ms.items) > 0) {
//fixme itemfield object, scroller, inputhandler, current selected item
menuItems := make([]string, 0)
for i := ms.offset; i < len(ms.items); i++ {
if string(ms.items[i].(string)) != "" {
menuItems = append(menuItems, ms.items[i].(string))
}
}
ilw, ilh = menuLayer.PrintInside(itemField, strings.Join(menuItems, "\n"), blt.TK_ALIGN_LEFT)
}
if ilh < len(ms.items) {
ms.drawScrollBar(menuLayer, itemField)
}
if ilw > itemField.W-4 {
fmt.Printf("Excess width of item names found! Need h-scroll of certain names")
}
}
func (ms *MenuScreen) drawScrollBar(menuLayer *mainwindow.Layer, itemField types.Rect) {
scrollbarBg := types.NewRect(itemField.X+itemField.W-2, itemField.Y + 1, 1, itemField.H - 4)
menuLayer.WithColor("#77000000").NewWindow(scrollbarBg).Splash()
//tick
menuLayer.WithColor(ms.fgColor).Put(
scrollbarBg.X,
scrollbarBg.Y + int(float64(ms.offset) / float64(len(ms.items)) * float64(scrollbarBg.H)),
"⏹",
)
menuLayer.WithColor(ms.fgColor).Put(itemField.X+itemField.W-2, itemField.Y+scrollbarBg.H + 1, "↓")
menuLayer.WithColor(ms.fgColor).Put(itemField.X+itemField.W-2, itemField.Y, "↑")
}