~whereswaldon/chipalee

7c1d363012e3256b44f815ab4635ce956a2915d4 — Chris Waldon 2 years ago bbaabdf
main: prevent keys from getting stuck easily

Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
1 files changed, 80 insertions(+), 31 deletions(-)

M main.go
M main.go => main.go +80 -31
@@ 25,6 25,7 @@ import (
	"io"
	"log"
	"math"
	"os"
	"runtime"
	"strings"
	"time"


@@ 281,14 282,19 @@ var keyToIdx = map[string]int{

func keySet() key.Set {
	baseKeys := maps.Keys(keyToIdx)
	chords := []string{}
	chords = append(chords, baseKeys...)
	modifiers := []string{"Shift", "Ctrl", "Alt"}
	modded := []string{}
	for _, key := range modifiers {
		baseKeys = append(baseKeys, key)
	}
	for _, key := range baseKeys {
		chords = append(chords, "Shift-"+key)
		chords = append(chords, "Ctrl-"+key)
		chords = append(chords, "Alt-"+key)
		for _, mod := range modifiers {
			modded = append(modded, mod+"-"+key)
		}
	}
	return key.Set(strings.Join(chords, "|"))
	baseKeys = append(baseKeys, modded...)

	return key.Set(strings.Join(baseKeys, "|"))

}



@@ 322,16 328,50 @@ func run(w *app.Window) error {
	if err != nil {
		return err
	}
	// Modifier key state
	var (
		shifted, ctrled, alted bool
	)

	players := make([]Pipe, len(freqs))
	toggleIndex := func(idx int, event key.Event, now time.Time) {

	playing := make(map[string][]int)
	startPlaying := make(map[string][]int)
	stopPlaying := make(map[string]struct{})

	toggleKey := func(event key.Event, now time.Time) {
		var playingFrom [][]int
		switch {
		case shifted:
			playingFrom = majChords
		case ctrled:
			playingFrom = majExtChords
		case alted:
			playingFrom = halfStepUp
		default:
			playingFrom = notes
		}
		idx, ok := keyToIdx[event.Name]
		if !ok {
			return
		}

		if idx >= len(playingFrom) {
			return
		}
		if idx >= len(players) {
			return
		}
		if event.State == key.Press {
			players[idx].Play(now)
			if _, ok := stopPlaying[event.Name]; !ok {
				if _, ok := playing[event.Name]; !ok {
					startPlaying[event.Name] = playingFrom[idx]
				}
			}
		} else {
			players[idx].Pause(now)
			if _, ok := startPlaying[event.Name]; !ok {
				stopPlaying[event.Name] = struct{}{}
			}
		}
	}



@@ 372,29 412,35 @@ func run(w *app.Window) error {
						default:
							log.Printf("%#+v", event)
						case key.Event:
							idx, ok := keyToIdx[event.Name]
							if !ok {
								continue
							}
							var playingFrom [][]int
							switch {
							case event.Modifiers.Contain(key.ModShift):
								playingFrom = majChords
							case event.Modifiers.Contain(key.ModCtrl):
								playingFrom = majExtChords
							case event.Modifiers.Contain(key.ModAlt):
								playingFrom = halfStepUp
							default:
								playingFrom = notes
							}
							if idx >= len(playingFrom) {
								continue
							}
							for _, idx := range playingFrom[idx] {
								toggleIndex(idx, event, gtx.Now)
							case event.Name == key.NameShift:
								shifted = event.State == key.Press
							case event.Name == key.NameCtrl:
								ctrled = event.State == key.Press
							case event.Name == key.NameAlt:
								alted = event.State == key.Press
							}
							toggleKey(event, gtx.Now)
						}
					}
					for key, indices := range startPlaying {
						delete(startPlaying, key)
						playing[key] = indices
						for _, idx := range indices {
							players[idx].Play(gtx.Now)
						}
					}
					for key := range stopPlaying {
						delete(stopPlaying, key)
						indices, ok := playing[key]
						if !ok {
							continue
						}
						for _, idx := range indices {
							players[idx].Pause(gtx.Now)
						}
						delete(playing, key)
					}
					key.InputOp{
						Tag:  w,
						Keys: keySet,


@@ 477,8 523,11 @@ func run(w *app.Window) error {

func main() {
	flag.Parse()
	if err := run(app.NewWindow(app.Title("Chipalee - Silly Chiptune Organ"))); err != nil {
		panic(err)
	}
	go func() {
		if err := run(app.NewWindow(app.Title("Chipalee - Silly Chiptune Organ"))); err != nil {
			panic(err)
		}
		os.Exit(0)
	}()
	app.Main()
}