package screens import ( "fmt" "lab.zaar.be/thefish/alchemyst-go/engine/ecs" "lab.zaar.be/thefish/alchemyst-go/engine/items" "lab.zaar.be/thefish/alchemyst-go/engine/types" blt "lab.zaar.be/thefish/bearlibterminal" "strings" ) type InventoryScreen struct { *MenuScreen who ecs.Entity cursor int offset int pageSize int selected []int prepared preparedList } type displayItem struct { Entity ecs.Entity Name string Index string Selected bool } type preparedList []displayItem func (p *preparedList) Prepare(is *InventoryScreen) { //fixme add item class sorting bp := items.Controller.GetComponent(is.who, ecs.BackpackComponent).(items.Backpack) is.prepared = make([]displayItem, len(bp.GetItems())) //prepare item list for i, ent := range bp.GetItems() { namec := items.Controller.GetComponent(ent, ecs.Named{}.Type()).(ecs.Named) is.prepared[i] = displayItem{ Entity: ent, Name: namec.Name, Index: string(runeIndex[i]), } } } func (is *InventoryScreen) MakeInverntory(who ecs.Entity) *InventoryScreen { is.drawFunc = is.InventoryRender is.inputFunc = is.HandleInput is.who = who return is } func (is *InventoryScreen) Enter() { is.redraw = true is.offset = 0 is.cursor = 0 is.prepared = preparedList{} is.prepared.Prepare(is) } //fixme key names to action constants! //fixme unify scrolling controls! func (is *InventoryScreen) HandleInput(input string) { if strings.Contains(string(runeIndex), strings.Replace(input, "Shift+", "", -1)) { if strings.Contains("Shift+", input) { input = strings.ToUpper(input) } for i, _ := range is.prepared { if is.prepared[i].Index == input { is.prepared[i].Selected = !is.prepared[i].Selected } } return } switch input { case "Up", "k": is.cursor = is.cursor - 1 if is.cursor < 0 { is.cursor = 0 } if is.cursor < is.offset { is.offset = is.offset - 1 if is.offset < 0 { is.offset = 0 } } break case "Down", "j": is.cursor = is.cursor + 1 if is.cursor >= len(is.prepared) { is.cursor = len(is.prepared) - 1 } if is.cursor > is.offset { is.offset = is.offset + 1 if is.offset*is.pageSize > len(is.prepared) { is.offset = len(is.prepared) / is.pageSize } } break case "Left": is.prepared[is.cursor].Selected = false break case "Right": is.prepared[is.cursor].Selected = true break case "PageUp": is.offset = is.offset - 1 if is.offset < 0 { is.offset = 0 } break case "PageDown": is.offset = is.offset + 1 if is.offset > len(is.prepared)-1 { is.offset = len(is.prepared) - 1 } break case "enter": //show actions menu for item under cursor //fixme implement break; case "Escape": fallthrough case "Space": is.scm.SetScreen(is.scm.PreviousScreen) break } } func (is *InventoryScreen) InventoryRender() { menuLayer := is.mw.GetLayer("menu") menuLayer.ClearRect(is.Rect) bgLayer := is.mw.GetLayer("menubg") bgLayer.ClearRect(is.Rect) bgLayer.WithColor(is.bgColor).NewWindow(is.Rect).Splash() menuLayer.WithColor(is.fgColor).NewWindow(is.Rect).DoubleBordered(is.title) menuLayer.Print(is.X+(is.W/2)-7, is.Y+is.H-1, "╡"+"[color=green]Space[/color] to close"+"╞") footerHeight := 0 if is.footer != "" { _, footerHeight = menuLayer.PrintInside(is.Rect, is.footer, 9) footerHeight = footerHeight + 2 } _, headerHeight := menuLayer.PrintInside(is.Rect, is.header, blt.TK_ALIGN_LEFT) itemField := types.Rect{is.X, is.Y + headerHeight + 1, is.W, is.H - headerHeight - footerHeight} _ = itemField is.pageSize = itemField.H - 2 if (len(is.prepared) > 0) { for i := is.offset; i < itemField.H; i++ { if i < len(is.prepared) { selectedColor := "white" selectedDash := "-" if is.prepared[i].Selected { selectedColor = "green" selectedDash = "+" } if is.cursor == i { menuLayer.WithColor("yellow") } else { menuLayer.WithColor("white") } menuStr := fmt.Sprintf("[color=%s]%s[/color] %s %s", selectedColor, is.prepared[i].Index, selectedDash, is.prepared[i].Name) if len(menuStr) > itemField.W - 2 { menuStr = menuStr[0:itemField.W - 2] } menuLayer.PutStringInto(itemField,i,menuStr,1) } } } if is.cursor < len(is.prepared) { is.drawScrollBar(menuLayer, itemField) } } //func (ms *InventoryScreen) UseEcs() bool {return true} //func (ms *InventoryScreen) Enter() {} //func (ms *InventoryScreen) Exit() {} //func (ms *InventoryScreen) Render() {}