Increase dialogue modality, display keyboard dialogue
This commit is contained in:
@@ -38,6 +38,20 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (f *Flow) returnToLastDriver(from driverName) func() {
|
||||||
|
return func() {
|
||||||
|
to, ok := f.returns[from]
|
||||||
|
if !ok {
|
||||||
|
f.exit = fmt.Errorf("Couldn't work out where to return to from %v", from)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(f.returns, from)
|
||||||
|
|
||||||
|
f.setDriverNow(to)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// from is the child menu, to is the parent
|
// from is the child menu, to is the parent
|
||||||
func (f *Flow) returnToLastDriverNow(from driverName) error {
|
func (f *Flow) returnToLastDriverNow(from driverName) error {
|
||||||
to, ok := f.returns[from]
|
to, ok := f.returns[from]
|
||||||
|
@@ -4,6 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
|
|
||||||
@@ -233,6 +234,21 @@ func (f *Flow) playNextScenario(from driverName) func() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *Flow) showDialogue(driver driverName, id string) func() {
|
||||||
|
return func() {
|
||||||
|
f.drivers[driver].ShowDialogue(locator(driver, id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Flow) hideDialogue(driver driverName) func() {
|
||||||
|
return f.drivers[driver].HideDialogue
|
||||||
|
}
|
||||||
|
|
||||||
func (f *Flow) setExit() {
|
func (f *Flow) setExit() {
|
||||||
f.exit = ErrExit
|
f.exit = ErrExit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: convert all to locators
|
||||||
|
func locator(d driverName, id string) string {
|
||||||
|
return fmt.Sprintf("%v:%v", strings.ToLower(string(d)), id)
|
||||||
|
}
|
||||||
|
25
internal/flow/keyboard.go
Normal file
25
internal/flow/keyboard.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package flow
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (f *Flow) linkKeyboard() {
|
||||||
|
// Keyboard settings
|
||||||
|
// TODO: implement keybindings save/load behaviour
|
||||||
|
f.onClick(kbd, "3.1", f.returnToLastDriver(kbd)) // Done button
|
||||||
|
f.onClick(kbd, "3.2", f.returnToLastDriver(kbd)) // Cancel button
|
||||||
|
f.onClick(kbd, "3.4", func() {}) // TODO: Reset to defaults button
|
||||||
|
|
||||||
|
for i := 1; i <= 13; i++ {
|
||||||
|
f.onClick(kbd, fmt.Sprintf("2.%v", i), f.captureKeybinding(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Flow) captureKeybinding(forLine int) func() {
|
||||||
|
return func() {
|
||||||
|
log.Printf("HELLO %v", forLine)
|
||||||
|
f.showDialogue(kbd, "4")()
|
||||||
|
}
|
||||||
|
}
|
@@ -5,7 +5,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (f *Flow) linkOptions() {
|
func (f *Flow) linkOptions() {
|
||||||
f.onClick(options, "2.8", f.setDriver(kbd)) // Keyboard settings button
|
f.onClick(options, "2.8", f.setReturningDriver(options, kbd)) // Keyboard settings button
|
||||||
|
|
||||||
f.configureSlider(options, "2.9", h3Slider) // Resolution slider
|
f.configureSlider(options, "2.9", h3Slider) // Resolution slider
|
||||||
f.configureSlider(options, "2.10", v10Slider) // Music volume slider
|
f.configureSlider(options, "2.10", v10Slider) // Music volume slider
|
||||||
@@ -17,11 +17,7 @@ func (f *Flow) linkOptions() {
|
|||||||
f.configureSlider(options, "2.26", h9Slider) // Unit speed slider
|
f.configureSlider(options, "2.26", h9Slider) // Unit speed slider
|
||||||
f.configureSlider(options, "2.27", h9Slider) // Animation speed slider
|
f.configureSlider(options, "2.27", h9Slider) // Animation speed slider
|
||||||
|
|
||||||
// Keyboard settings
|
f.linkKeyboard()
|
||||||
// TODO: implement keybindings save/load behaviour
|
|
||||||
f.onClick(kbd, "3.1", f.setDriver(options)) // Done button
|
|
||||||
f.onClick(kbd, "3.2", f.setDriver(options)) // Cancel button
|
|
||||||
f.onClick(kbd, "3.4", func() {}) // TODO: Reset to defaults button
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: exiting is a bit OTT. Perhaps display "save failed"?
|
// FIXME: exiting is a bit OTT. Perhaps display "save failed"?
|
||||||
|
@@ -94,7 +94,7 @@ func (d *Driver) Update(screenX, screenY int) error {
|
|||||||
d.cursorOrig = image.Pt(int(mnX), int(mnY))
|
d.cursorOrig = image.Pt(int(mnX), int(mnY))
|
||||||
|
|
||||||
// Dispatch notifications to our widgets
|
// Dispatch notifications to our widgets
|
||||||
for _, hoverable := range d.hoverables() {
|
for _, hoverable := range d.activeHoverables() {
|
||||||
inBounds := d.cursorOrig.In(hoverable.bounds())
|
inBounds := d.cursorOrig.In(hoverable.bounds())
|
||||||
|
|
||||||
d.hoverStartEvent(hoverable, inBounds)
|
d.hoverStartEvent(hoverable, inBounds)
|
||||||
@@ -106,7 +106,7 @@ func (d *Driver) Update(screenX, screenY int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mouseIsDown := ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft)
|
mouseIsDown := ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft)
|
||||||
for _, clickable := range d.clickables() {
|
for _, clickable := range d.activeClickables() {
|
||||||
inBounds := d.cursorOrig.In(clickable.bounds())
|
inBounds := d.cursorOrig.In(clickable.bounds())
|
||||||
mouseWasDown := clickable.mouseDownState()
|
mouseWasDown := clickable.mouseDownState()
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ func (d *Driver) Update(screenX, screenY int) error {
|
|||||||
d.mouseUpEvent(clickable, inBounds, mouseWasDown, mouseIsDown)
|
d.mouseUpEvent(clickable, inBounds, mouseWasDown, mouseIsDown)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, mouseable := range d.mouseables() {
|
for _, mouseable := range d.activeMouseables() {
|
||||||
mouseable.registerMousePosition(d.cursorOrig)
|
mouseable.registerMousePosition(d.cursorOrig)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ func (d *Driver) Draw(screen *ebiten.Image) error {
|
|||||||
|
|
||||||
var do ebiten.DrawImageOptions
|
var do ebiten.DrawImageOptions
|
||||||
|
|
||||||
for _, paint := range d.paintables() {
|
for _, paint := range d.activePaintables() {
|
||||||
for _, region := range paint.regions(d.ticks) {
|
for _, region := range paint.regions(d.ticks) {
|
||||||
x, y := d.orig2native.Apply(float64(region.offset.X), float64(region.offset.Y))
|
x, y := d.orig2native.Apply(float64(region.offset.X), float64(region.offset.Y))
|
||||||
|
|
||||||
@@ -165,29 +165,66 @@ func (d *Driver) Cursor() (*ebiten.Image, *ebiten.DrawImageOptions, error) {
|
|||||||
return cursor.Image, op, nil
|
return cursor.Image, op, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) clickables() []clickable {
|
func (d *Driver) allClickables() []clickable {
|
||||||
var out []clickable
|
var out []clickable
|
||||||
|
|
||||||
for _, widget := range d.widgets {
|
for _, widget := range d.widgets {
|
||||||
out = append(out, widget.clickables()...)
|
out = append(out, widget.clickables()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, widget := range d.dialogues {
|
||||||
|
out = append(out, widget.clickables()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Driver) allFreezables() []freezable {
|
||||||
|
var out []freezable
|
||||||
|
for _, widget := range d.widgets {
|
||||||
|
out = append(out, widget.freezables()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, widget := range d.dialogues {
|
||||||
|
out = append(out, widget.freezables()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Driver) allValueables() []valueable {
|
||||||
|
var out []valueable
|
||||||
|
|
||||||
|
for _, widget := range d.widgets {
|
||||||
|
out = append(out, widget.valueables()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, widget := range d.dialogues {
|
||||||
|
out = append(out, widget.valueables()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Driver) activeClickables() []clickable {
|
||||||
|
if d.activeDialogue != nil {
|
||||||
|
return d.activeDialogue.clickables()
|
||||||
|
}
|
||||||
|
|
||||||
|
var out []clickable
|
||||||
|
for _, widget := range d.widgets {
|
||||||
|
out = append(out, widget.clickables()...)
|
||||||
|
}
|
||||||
|
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) freezables() []freezable {
|
func (d *Driver) activeHoverables() []hoverable {
|
||||||
var out []freezable
|
if d.activeDialogue != nil {
|
||||||
|
return d.activeDialogue.hoverables()
|
||||||
for _, widget := range d.widgets {
|
|
||||||
out = append(out, widget.freezables()...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Driver) hoverables() []hoverable {
|
|
||||||
var out []hoverable
|
var out []hoverable
|
||||||
|
|
||||||
for _, widget := range d.widgets {
|
for _, widget := range d.widgets {
|
||||||
out = append(out, widget.hoverables()...)
|
out = append(out, widget.hoverables()...)
|
||||||
}
|
}
|
||||||
@@ -195,9 +232,12 @@ func (d *Driver) hoverables() []hoverable {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) mouseables() []mouseable {
|
func (d *Driver) activeMouseables() []mouseable {
|
||||||
var out []mouseable
|
if d.activeDialogue != nil {
|
||||||
|
return d.activeDialogue.mouseables()
|
||||||
|
}
|
||||||
|
|
||||||
|
var out []mouseable
|
||||||
for _, widget := range d.widgets {
|
for _, widget := range d.widgets {
|
||||||
out = append(out, widget.mouseables()...)
|
out = append(out, widget.mouseables()...)
|
||||||
}
|
}
|
||||||
@@ -205,7 +245,7 @@ func (d *Driver) mouseables() []mouseable {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) paintables() []paintable {
|
func (d *Driver) activePaintables() []paintable {
|
||||||
var out []paintable
|
var out []paintable
|
||||||
|
|
||||||
for _, widget := range d.widgets {
|
for _, widget := range d.widgets {
|
||||||
@@ -218,13 +258,3 @@ func (d *Driver) paintables() []paintable {
|
|||||||
|
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) valueables() []valueable {
|
|
||||||
var out []valueable
|
|
||||||
|
|
||||||
for _, widget := range d.widgets {
|
|
||||||
out = append(out, widget.valueables()...)
|
|
||||||
}
|
|
||||||
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
@@ -14,6 +14,8 @@ import (
|
|||||||
//
|
//
|
||||||
// TODO: multi-select functionality? Is it needed?
|
// TODO: multi-select functionality? Is it needed?
|
||||||
type listBox struct {
|
type listBox struct {
|
||||||
|
locator string
|
||||||
|
|
||||||
upBtn *button
|
upBtn *button
|
||||||
downBtn *button
|
downBtn *button
|
||||||
|
|
||||||
@@ -52,6 +54,7 @@ func (d *Driver) buildListBox(group *menus.Group, up, down, thumb *menus.Record,
|
|||||||
}
|
}
|
||||||
|
|
||||||
element := &listBox{
|
element := &listBox{
|
||||||
|
locator: group.Locator,
|
||||||
// TODO: upBtn needs to be frozen when offset == 0; downBtn when offset == max
|
// TODO: upBtn needs to be frozen when offset == 0; downBtn when offset == max
|
||||||
upBtn: upElem,
|
upBtn: upElem,
|
||||||
downBtn: downElem,
|
downBtn: downElem,
|
||||||
@@ -75,6 +78,7 @@ func (d *Driver) buildListBox(group *menus.Group, up, down, thumb *menus.Record,
|
|||||||
widget := &Widget{
|
widget := &Widget{
|
||||||
Children: []*Widget{upWidget, downWidget},
|
Children: []*Widget{upWidget, downWidget},
|
||||||
ownPaintables: []paintable{element},
|
ownPaintables: []paintable{element},
|
||||||
|
ownValueables: []valueable{element},
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: we should be able to freeze/unfreeze as a group.
|
// FIXME: we should be able to freeze/unfreeze as a group.
|
||||||
@@ -86,6 +90,7 @@ func (d *Driver) buildListBox(group *menus.Group, up, down, thumb *menus.Record,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
niWidget.ownClickables = append(niWidget.ownClickables, ni)
|
||||||
|
|
||||||
// TODO: pick the correct font
|
// TODO: pick the correct font
|
||||||
ni.label = &label{
|
ni.label = &label{
|
||||||
@@ -102,6 +107,17 @@ func (d *Driver) buildListBox(group *menus.Group, up, down, thumb *menus.Record,
|
|||||||
return element, widget, nil
|
return element, widget, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *listBox) id() string {
|
||||||
|
return l.locator
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *listBox) value() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *listBox) setValue(s string) {
|
||||||
|
}
|
||||||
|
|
||||||
func (l *listBox) SetStrings(to []string) {
|
func (l *listBox) SetStrings(to []string) {
|
||||||
if len(to) < len(l.strings) {
|
if len(to) < len(l.strings) {
|
||||||
l.offset = 0 // FIXME: unconditional? Trim to max?
|
l.offset = 0 // FIXME: unconditional? Trim to max?
|
||||||
|
@@ -10,7 +10,7 @@ func (d *Driver) realId(id string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) Value(id string, into *string) error {
|
func (d *Driver) Value(id string, into *string) error {
|
||||||
for _, valueable := range d.valueables() {
|
for _, valueable := range d.allValueables() {
|
||||||
if valueable.id() == d.realId(id) {
|
if valueable.id() == d.realId(id) {
|
||||||
*into = valueable.value()
|
*into = valueable.value()
|
||||||
return nil
|
return nil
|
||||||
@@ -21,7 +21,7 @@ func (d *Driver) Value(id string, into *string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) SetValue(id, value string) error {
|
func (d *Driver) SetValue(id, value string) error {
|
||||||
for _, valueable := range d.valueables() {
|
for _, valueable := range d.allValueables() {
|
||||||
if valueable.id() == d.realId(id) {
|
if valueable.id() == d.realId(id) {
|
||||||
valueable.setValue(value)
|
valueable.setValue(value)
|
||||||
return nil
|
return nil
|
||||||
@@ -51,7 +51,7 @@ func (d *Driver) SetValueBool(id string, value bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) SetFreeze(id string, value bool) error {
|
func (d *Driver) SetFreeze(id string, value bool) error {
|
||||||
for _, freezable := range d.freezables() {
|
for _, freezable := range d.allFreezables() {
|
||||||
if freezable.id() == d.realId(id) {
|
if freezable.id() == d.realId(id) {
|
||||||
freezable.setFreezeState(value)
|
freezable.setFreezeState(value)
|
||||||
return nil
|
return nil
|
||||||
@@ -62,30 +62,19 @@ func (d *Driver) SetFreeze(id string, value bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) OnClick(id string, f func()) error {
|
func (d *Driver) OnClick(id string, f func()) error {
|
||||||
for _, clickable := range d.clickables() {
|
for _, clickable := range d.allClickables() {
|
||||||
if clickable.id() == d.realId(id) {
|
if clickable.id() == d.realId(id) {
|
||||||
clickable.onClick(f)
|
clickable.onClick(f)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to be able to wire up items inside dialogues too
|
|
||||||
for _, dialogue := range d.dialogues {
|
|
||||||
for _, clickable := range dialogue.clickables() {
|
|
||||||
if clickable.id() == d.realId(id) {
|
|
||||||
clickable.onClick(f)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Errorf("Couldn't find clickable widget %v:%v", d.menu.Name, id)
|
return fmt.Errorf("Couldn't find clickable widget %v:%v", d.menu.Name, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: HURK. Surely I'm missing something? steps is value:offset
|
// FIXME: HURK. Surely I'm missing something? steps is value:offset
|
||||||
func (d *Driver) ConfigureSlider(id string, steps map[int]int) error {
|
func (d *Driver) ConfigureSlider(id string, steps map[int]int) error {
|
||||||
|
for _, clickable := range d.activeClickables() {
|
||||||
for _, clickable := range d.clickables() {
|
|
||||||
if slider, ok := clickable.(*slider); ok && slider.id() == d.realId(id) {
|
if slider, ok := clickable.(*slider); ok && slider.id() == d.realId(id) {
|
||||||
slider.steps = steps
|
slider.steps = steps
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user