Files
five/examples/menuto_five.prg
Charles KWON OhJun 59568f3301 Five v0.9 — Harbour + Go fusion language
- Compiler: PP → Lexer → Parser → Analyzer → Gengo pipeline
- Parser: 232/236 (98%) Harbour compatibility, registry-based dispatch
- RTL: 351 Harbour-compatible functions
- RDD: DBF/NTX/CDX engines with Rushmore bitmap optimization
- Go Interop: IMPORT + pkg.Func() + obj:Method() with FastPath (15M calls/sec)
- HB_FUNC API: Full Harbour C API compatible Go bridge
- Concurrency: SPAWN/LAUNCH/GOROUTINE, <-, WATCH, PARALLEL FOR, ASYNC/AWAIT
- Extensions: Multi-return, DEFER, Slice, f-string, Nil-safe ?:, CONST
- Macro Compiler: Runtime AST parsing and evaluation
- Debugger: TUI debugger with source display, breakpoints, stepping
- FRB: Native + Pcode dual mode runtime binary
- Tests: 13 packages ALL PASS

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 09:41:50 +09:00

173 lines
3.7 KiB
Plaintext

// Five MENU TO — simplified port of Harbour menuto.prg
// Compiles via gengo to native binary
STATIC aPrompts := {}
// @row, col PROMPT text → collects menu items
FUNCTION __AtPrompt(nRow, nCol, cPrompt, cMsg)
AAdd(aPrompts, {nRow, nCol, cPrompt, cMsg})
SetPos(nRow, nCol)
DevOut(cPrompt)
RETURN .F.
// MENU TO nChoice → displays menu, returns selection
FUNCTION __MenuTo(nStart)
LOCAL n, nKey, nLen, q, lExit
nLen := Len(aPrompts)
IF nLen = 0
RETURN 0
ENDIF
n := nStart
IF n < 1
n := 1
ENDIF
IF n > nLen
n := nLen
ENDIF
SetCursor(0)
lExit := .F.
DO WHILE !lExit
// Highlight current item (reverse video)
SetPos(aPrompts[n][1], aPrompts[n][2])
DevOut(Chr(27) + "[7m" + aPrompts[n][3] + Chr(27) + "[0m")
// Show message if any
IF aPrompts[n][4] != NIL .AND. Len(aPrompts[n][4]) > 0
SetPos(MaxRow(), 0)
DevOut(PadR(aPrompts[n][4], MaxCol() + 1))
ENDIF
// Wait for key
nKey := Inkey(0)
// Unhighlight current
q := n
SetPos(aPrompts[q][1], aPrompts[q][2])
DevOut(aPrompts[q][3])
DO CASE
CASE nKey = 24 .OR. nKey = 4 // Down or Right
n++
IF n > nLen
n := 1
ENDIF
CASE nKey = 5 .OR. nKey = 19 // Up or Left
n--
IF n < 1
n := nLen
ENDIF
CASE nKey = 1 // Home
n := 1
CASE nKey = 6 // End
n := nLen
CASE nKey = 13 .OR. nKey = 10 // Enter (CR or LF)
lExit := .T.
CASE nKey = 27 // ESC
n := 0
lExit := .T.
ENDCASE
ENDDO
// Clear message line
SetPos(MaxRow(), 0)
DevOut(Space(MaxCol() + 1))
SetCursor(1)
// Clear prompts for next use
aPrompts := {}
RETURN n
// AChoice — array-based menu selection
FUNCTION AChoice(nTop, nLeft, nBottom, nRight, aItems)
LOCAL n := 1, nKey, nLen, nVisible, nOffset, r, i, lExit
nLen := Len(aItems)
IF nLen = 0
RETURN 0
ENDIF
nVisible := nBottom - nTop + 1
nOffset := 0
lExit := .F.
SetCursor(0)
DO WHILE !lExit
// Draw visible items
FOR r := 1 TO nVisible
i := nOffset + r
SetPos(nTop + r - 1, nLeft)
IF i <= nLen
IF i = n
DevOut(Chr(27) + "[7m" + PadR(aItems[i], nRight - nLeft + 1) + Chr(27) + "[0m")
ELSE
DevOut(PadR(aItems[i], nRight - nLeft + 1))
ENDIF
ELSE
DevOut(Space(nRight - nLeft + 1))
ENDIF
NEXT
nKey := Inkey(0)
DO CASE
CASE nKey = 24 // Down
IF n < nLen
n++
IF n > nOffset + nVisible
nOffset++
ENDIF
ENDIF
CASE nKey = 5 // Up
IF n > 1
n--
IF n <= nOffset
nOffset := n - 1
ENDIF
ENDIF
CASE nKey = 3 // PgDn
n += nVisible
IF n > nLen
n := nLen
ENDIF
nOffset := n - nVisible
IF nOffset < 0
nOffset := 0
ENDIF
CASE nKey = 18 // PgUp
n -= nVisible
IF n < 1
n := 1
ENDIF
nOffset := n - 1
IF nOffset < 0
nOffset := 0
ENDIF
CASE nKey = 1 // Home
n := 1
nOffset := 0
CASE nKey = 6 // End
n := nLen
nOffset := nLen - nVisible
IF nOffset < 0
nOffset := 0
ENDIF
CASE nKey = 13 // Enter
lExit := .T.
CASE nKey = 27 // ESC
n := 0
lExit := .T.
ENDCASE
ENDDO
SetCursor(1)
RETURN n