Display listbox text
This commit is contained in:
@@ -2,8 +2,9 @@ package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"image"
|
||||
|
||||
"code.ur.gs/lupine/ordoor/internal/assetstore"
|
||||
"code.ur.gs/lupine/ordoor/internal/menus"
|
||||
)
|
||||
|
||||
@@ -25,7 +26,9 @@ type listBox struct {
|
||||
upBtn *button
|
||||
downBtn *button
|
||||
|
||||
// TODO: can we reuse the slider element for the thumb?
|
||||
// FIXME: can we share code between slider and this element?
|
||||
thumbBase *assetstore.Sprite // Bounds are given by this
|
||||
thumbImg *assetstore.Sprite // This is displayed at offset * (height / steps)
|
||||
|
||||
base *noninteractive // The menu itself has a sprite to display
|
||||
lines []*noninteractive // We display to these
|
||||
@@ -40,7 +43,7 @@ type listBox struct {
|
||||
func registerListBox(d *Driver, menu *menus.Record) ([]*menus.Record, error) {
|
||||
var upBtn *menus.Record
|
||||
var downBtn *menus.Record
|
||||
var slider *menus.Record
|
||||
var thumb *menus.Record
|
||||
var items []*menus.Record
|
||||
|
||||
for _, rec := range menu.Children {
|
||||
@@ -58,20 +61,25 @@ func registerListBox(d *Driver, menu *menus.Record) ([]*menus.Record, error) {
|
||||
case menus.TypeLineKbd, menus.TypeLineBriefing:
|
||||
items = append(items, rec)
|
||||
case menus.TypeThumb:
|
||||
if slider != nil {
|
||||
if thumb != nil {
|
||||
return nil, fmt.Errorf("Duplicate thumbs in menu %v", menu.Locator())
|
||||
}
|
||||
slider = rec
|
||||
thumb = rec
|
||||
default:
|
||||
return nil, fmt.Errorf("Unrecognised child in listbox menu: %v", rec.Locator())
|
||||
}
|
||||
}
|
||||
|
||||
if len(items) == 0 || slider == nil || upBtn == nil || downBtn == nil {
|
||||
if len(items) == 0 || thumb == nil || upBtn == nil || downBtn == nil {
|
||||
return nil, fmt.Errorf("Missing items in menu %v", menu.Locator())
|
||||
}
|
||||
|
||||
// Now build the wonderful thing
|
||||
baseElem, err := registerNoninteractive(d, menu)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
elemUp, err := registerButton(d, upBtn, upBtn.SpriteId[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -82,18 +90,25 @@ func registerListBox(d *Driver, menu *menus.Record) ([]*menus.Record, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
element := &listBox{
|
||||
upBtn: elemUp,
|
||||
downBtn: elemDown,
|
||||
thumbBaseSpr, err := d.menu.Sprite(thumb.Share)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, rec := range items {
|
||||
ni, err := registerNoninteractive(d, rec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
thumbImgSpr, err := d.menu.Sprite(thumb.SpriteId[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
element.lines = append(element.lines, ni)
|
||||
element := &listBox{
|
||||
base: baseElem,
|
||||
// TODO: upBtn needs to be frozen when offset == 0; downBtn when offset == max
|
||||
upBtn: elemUp,
|
||||
downBtn: elemDown,
|
||||
|
||||
// TODO: need to be able to drag the thumb
|
||||
thumbBase: thumbBaseSpr,
|
||||
thumbImg: thumbImgSpr,
|
||||
}
|
||||
|
||||
// Internal wiring-up
|
||||
@@ -105,8 +120,30 @@ func registerListBox(d *Driver, menu *menus.Record) ([]*menus.Record, error) {
|
||||
element.strings = append(element.strings, fmt.Sprintf("FOO %v", i))
|
||||
}
|
||||
|
||||
// Register everything
|
||||
// FIXME: we should be able to freeze/unfreeze as a group. The buttons register themselves though...
|
||||
// Register everything. Since we're a composite of other controls, they are
|
||||
// mostly self-registered at the moment.
|
||||
d.paintables = append(d.paintables, element)
|
||||
|
||||
// FIXME: we should be able to freeze/unfreeze as a group.
|
||||
|
||||
// HURK: These need to be registered after the other elements so they are
|
||||
// drawn in the correct order to be visible
|
||||
for _, rec := range items {
|
||||
ni, err := registerNoninteractive(d, rec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// TODO: pick the correct font
|
||||
ni.label = &label{
|
||||
align: AlignModeLeft,
|
||||
font: d.menu.Font(0),
|
||||
rect: ni.rect,
|
||||
}
|
||||
|
||||
element.lines = append(element.lines, ni)
|
||||
}
|
||||
|
||||
element.refresh()
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -148,11 +185,31 @@ func (l *listBox) refresh() {
|
||||
for i, ni := range l.lines {
|
||||
// FIXME: noninteractive isn't set up for dynamic text yet. Need to
|
||||
// generate textImg on demand instead of once at start.
|
||||
ni.hoverImpl.text = ""
|
||||
if len(l.strings) > l.offset+i {
|
||||
ni.hoverImpl.text = l.strings[l.offset+i]
|
||||
if ni.label != nil {
|
||||
ni.label.text = ""
|
||||
if len(l.strings) > l.offset+i {
|
||||
ni.label.text = l.strings[l.offset+i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("Listbox offset: %v", l.offset)
|
||||
}
|
||||
|
||||
func (l *listBox) thumbPos() image.Point {
|
||||
pos := l.thumbImg.Rect.Min
|
||||
if len(l.strings) == 0 {
|
||||
return pos
|
||||
}
|
||||
|
||||
pixPerLine := (l.thumbBase.Rect.Dy()) / (len(l.strings) - len(l.lines))
|
||||
pos.Y += pixPerLine * l.offset
|
||||
|
||||
return pos
|
||||
}
|
||||
|
||||
func (l *listBox) regions(tick int) []region {
|
||||
// Draw the slider at the appropriate point
|
||||
out := oneRegion(l.thumbBase.Rect.Min, l.thumbBase.Image)
|
||||
out = append(out, oneRegion(l.thumbPos(), l.thumbImg.Image)...)
|
||||
|
||||
return out
|
||||
}
|
||||
|
Reference in New Issue
Block a user