package main import ( "image/color" "time" "tinygo.org/x/tinydraw" "tinygo.org/x/tinyfont" ) var ( maxOpts int16 offset int16 menuX, menuY int16 numOpts int16 ) func runMenuOption(selected int16) { switch menuOptions[selected] { case modeBadge: Badge() case modeSchedule: schedule(0, 0) case modeAdventure: adventure() case modeLEDs: Leds() case modeAccelerometer: Accel3D() case modeMusic: Music() case modeGameSnake: snakeGame.Loop() case modeGameLife: GameOfLife() case modeGameColors: ColorGame() case modeInfo: Info() } } func menu() int16 { display.FillScreen(color.RGBA{0, 0, 0, 255}) bgColor := color.RGBA{109, 0, 140, 255} display.FillScreen(bgColor) selected := int16(0) numOpts = int16(len(menuOptions)) menuX = int16(0) for i := int16(0); i < numOpts; i++ { w32, _ := tinyfont.LineWidth(defaultFont, options[menuOptions[i]]) if int16(w32) > menuX && w32 <= displayWidth { menuX = int16(w32) } } maxOpts = int16((displayHeight - 15) / menuItemSpace) if numOpts > maxOpts { maxOpts = (displayHeight - 30) / menuItemSpace } else { maxOpts = numOpts } offset = 0 menuX = (displayWidth - menuX) / 2 menuY = int16((displayHeight - ((maxOpts - 1) * menuItemSpace)) / 2) menuDrawOffset() tinydraw.FilledCircle(&display, menuX-2*menuCircleR, menuY-(menuCircleR/2), menuCircleR-2, color.RGBA{200, 200, 0, 255}) for { getInput() if !buttonsOldState[buttonUp] && buttonsState[buttonUp] { selected-- if selected < 0 { offset = (numOpts + offset - maxOpts) % numOpts selected = maxOpts - 1 menuDrawOffset() } tinydraw.FilledCircle(&display, menuX-2*menuCircleR, menuY-(menuCircleR/2)+menuItemSpace*selected, menuCircleR-2, color.RGBA{200, 200, 0, 255}) tinydraw.FilledCircle(&display, menuX-2*menuCircleR, menuY-(menuCircleR/2)+menuItemSpace*(selected+1), menuCircleR-2, bgColor) } if !buttonsOldState[buttonDown] && buttonsState[buttonDown] { selected++ if selected >= maxOpts { offset = (offset + maxOpts) % numOpts selected = 0 menuDrawOffset() } tinydraw.FilledCircle(&display, menuX-2*menuCircleR, menuY-(menuCircleR/2)+menuItemSpace*selected, menuCircleR-2, color.RGBA{200, 200, 0, 255}) tinydraw.FilledCircle(&display, menuX-2*menuCircleR, menuY-(menuCircleR/2)+menuItemSpace*(selected-1), menuCircleR-2, bgColor) } if !buttonsOldState[buttonA] && buttonsState[buttonA] { break } time.Sleep(50 * time.Millisecond) } return (selected + offset) % numOpts } func menuDrawOffset() { bgColor := color.RGBA{109, 0, 140, 255} display.FillScreen(bgColor) for i := int16(0); i < maxOpts; i++ { tinydraw.Circle(&display, menuX-2*menuCircleR, menuY-menuCircleR/2+menuItemSpace*i, int16(menuCircleR), color.RGBA{0, 0, 0, 255}) tinyfont.WriteLine(&display, defaultFont, menuX, menuY+menuItemSpace*i, options[menuOptions[(offset+i)%numOpts]], color.RGBA{0, 0, 0, 255}) tinyfont.WriteLine(&display, defaultFont, menuX, menuY+1+menuItemSpace*i, options[menuOptions[(offset+i)%numOpts]], color.RGBA{0, 0, 0, 255}) tinyfont.WriteLine(&display, defaultFont, menuX, menuY+2+menuItemSpace*i, options[menuOptions[(offset+i)%numOpts]], color.RGBA{0, 0, 0, 255}) tinyfont.WriteLine(&display, defaultFont, menuX+1, menuY+2+menuItemSpace*i, options[menuOptions[(offset+i)%numOpts]], color.RGBA{0, 0, 0, 255}) tinyfont.WriteLine(&display, defaultFont, menuX+2, menuY+2+menuItemSpace*i, options[menuOptions[(offset+i)%numOpts]], color.RGBA{0, 0, 0, 255}) tinyfont.WriteLine(&display, defaultFont, menuX+2, menuY+1+menuItemSpace*i, options[menuOptions[(offset+i)%numOpts]], color.RGBA{0, 0, 0, 255}) tinyfont.WriteLine(&display, defaultFont, menuX+2, menuY+menuItemSpace*i, options[menuOptions[(offset+i)%numOpts]], color.RGBA{0, 0, 0, 255}) tinyfont.WriteLine(&display, defaultFont, menuX+1, menuY+menuItemSpace*i, options[menuOptions[(offset+i)%numOpts]], color.RGBA{0, 0, 0, 255}) tinyfont.WriteLine(&display, defaultFont, menuX+1, menuY+1+menuItemSpace*i, options[menuOptions[(offset+i)%numOpts]], color.RGBA{250, 250, 0, 255}) } }