source_utils_dialogResult.bs
' The ONE definition of the standard dialog result shape.
'
' Every dialog in the JRDialog family resolves by writing this assoc array to its
' own per-instance `result` field. Callers read the same six keys no matter which
' dialog ran, which is what lets a call site swap presentation (button row <->
' scrollable list, as showChoiceDialog does) without touching its handler.
'
' These builders exist so the shape has exactly one producer. Hand-building the
' assoc array in each component is how the three copies drifted apart before
' (JRListDialog hardcoding `confirmed: false`, JRKeyboardDialog hardcoding
' `buttonIndex: -1`) — and the mapping from "what the user did" to
' cancelled/confirmed is the part every call site depends on, so it belongs in
' pure functions that can be unit-tested without a scene.
'
' Keys:
' cancelled - user backed out (back / Cancel); no selection was made
' confirmed - user chose the affirmative action
' buttonIndex - index into `buttons`, or -1 when the dialog has no button row
' optionIndex - index of the chosen option, or -1 when nothing was chosen
' buttonText - label of the chosen button ("" when none)
' value - entered text (keyboard dialogs only; "" otherwise)
import "pkg:/source/utils/misc.bs"
' Result for a button-row dialog (JRDialog). index = -1 means cancelled.
' confirmIndex is the button that counts as the affirmative action (-1 = none),
' which is what `showConfirmDialog` sets so callers can read result.confirmed.
function buttonDialogResult(index as integer, confirmIndex as integer, buttons as object) as object
buttonText = ""
if index >= 0 and isValid(buttons) and index < buttons.count()
buttonText = toString(buttons[index])
end if
' optionIndex mirrors buttonIndex: for choice dialogs the buttons ARE the
' options, so showChoiceDialog callers read result.optionIndex on both routes.
return makeDialogResult(index < 0, index >= 0 and index = confirmIndex, index, index, buttonText, "")
end function
' Result for a selection-list dialog (JRListDialog). index = -1 means dismissed
' without choosing. A list dialog has NO buttons at all — its rows are the only
' focusable thing in it and Back is the exit — so both button fields stay empty
' and callers branch on optionIndex / cancelled.
'
' It used to take a `cancelText` and report it as buttonText on dismissal, from
' when the dialog had a Cancel button. Keeping that would have meant a result
' naming a control the user was never shown.
function listDialogResult(index as integer) as object
return makeDialogResult(index < 0, false, -1, index, "", "")
end function
' Result for a text-entry dialog (JRKeyboardDialog). `cancelled` distinguishes a
' cancel/back from an intentionally empty entry, so callers can tell them apart.
function textDialogResult(cancelled as boolean, enteredText as string) as object
value = ""
if not cancelled then value = enteredText
return makeDialogResult(cancelled, not cancelled, -1, -1, "", value)
end function
function makeDialogResult(cancelled as boolean, confirmed as boolean, buttonIndex as integer, optionIndex as integer, buttonText as string, value as string) as object
return {
cancelled: cancelled,
confirmed: confirmed,
buttonIndex: buttonIndex,
optionIndex: optionIndex,
buttonText: buttonText,
value: value
}
end function