Experimental: use yad for graphical menus that should work better with orca and Cthulhu screen readers.
This commit is contained in:
@ -44,6 +44,158 @@ EOF
|
|||||||
# Dialog accessibility
|
# Dialog accessibility
|
||||||
export DIALOGOPTS='--no-lines --visit-items'
|
export DIALOGOPTS='--no-lines --visit-items'
|
||||||
|
|
||||||
|
# UI wrapper functions for dialog/yad switching
|
||||||
|
# Automatically switches between dialog (console) and yad (GUI) based on DISPLAY environment
|
||||||
|
|
||||||
|
# Wrapper function for menu selection
|
||||||
|
# Usage: ui_menu "title" "backtitle" "text" option1 "description1" option2 "description2" ...
|
||||||
|
ui_menu() {
|
||||||
|
local title="$1"
|
||||||
|
local back_title="$2"
|
||||||
|
local text="$3"
|
||||||
|
shift 3
|
||||||
|
|
||||||
|
if [[ "$dialog_type" == "yad" ]]; then
|
||||||
|
# Build yad list format: Display only, then map back to value
|
||||||
|
local yad_list=""
|
||||||
|
declare -A value_map
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
local option="$1"
|
||||||
|
local description="$2"
|
||||||
|
value_map["$description"]="$option"
|
||||||
|
if [[ -n "$yad_list" ]]; then
|
||||||
|
yad_list="$yad_list\n"
|
||||||
|
fi
|
||||||
|
yad_list="${yad_list}${description}"
|
||||||
|
shift 2
|
||||||
|
done
|
||||||
|
|
||||||
|
local selected_description
|
||||||
|
selected_description=$(echo -e "$yad_list" | yad --list \
|
||||||
|
--title="$title" \
|
||||||
|
--text="$text" \
|
||||||
|
--column="Option" \
|
||||||
|
--no-headers \
|
||||||
|
--selectable-labels \
|
||||||
|
--search-column=1 \
|
||||||
|
--height=400 \
|
||||||
|
--width=600)
|
||||||
|
# Strip trailing newline, pipe, and any other whitespace
|
||||||
|
selected_description=$(echo "$selected_description" | tr -d '\n\r' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/|$//')
|
||||||
|
|
||||||
|
# Return the mapped value
|
||||||
|
if [[ -n "$selected_description" ]]; then
|
||||||
|
echo "${value_map["$selected_description"]}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Build dialog menu format with mapping (same approach as yad)
|
||||||
|
local dialog_args=()
|
||||||
|
declare -A value_map
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
local option="$1"
|
||||||
|
local description="$2"
|
||||||
|
value_map["$description"]="$option"
|
||||||
|
dialog_args+=("$description" "$description")
|
||||||
|
shift 2
|
||||||
|
done
|
||||||
|
|
||||||
|
local selected_description
|
||||||
|
selected_description=$(dialog --backtitle "$back_title" \
|
||||||
|
--title "$title" \
|
||||||
|
--no-tags \
|
||||||
|
--menu "$text" 0 0 0 \
|
||||||
|
"${dialog_args[@]}" \
|
||||||
|
--stdout)
|
||||||
|
|
||||||
|
# Return the mapped value
|
||||||
|
if [[ -n "$selected_description" ]]; then
|
||||||
|
echo "${value_map["$selected_description"]}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wrapper function for message box
|
||||||
|
# Usage: ui_msgbox "title" "backtitle" "text"
|
||||||
|
ui_msgbox() {
|
||||||
|
local title="$1"
|
||||||
|
local back_title="$2"
|
||||||
|
local text="$3"
|
||||||
|
|
||||||
|
if [[ "$dialog_type" == "yad" ]]; then
|
||||||
|
yad --info \
|
||||||
|
--title="$title" \
|
||||||
|
--text="$text" \
|
||||||
|
--selectable-labels \
|
||||||
|
--show-cursor \
|
||||||
|
--width=400
|
||||||
|
else
|
||||||
|
dialog --backtitle "$back_title" \
|
||||||
|
--title "$title" \
|
||||||
|
--msgbox "$text" 0 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wrapper function for yes/no dialog
|
||||||
|
# Usage: ui_yesno "title" "backtitle" "text"
|
||||||
|
ui_yesno() {
|
||||||
|
local title="$1"
|
||||||
|
local back_title="$2"
|
||||||
|
local text="$3"
|
||||||
|
|
||||||
|
if [[ "$dialog_type" == "yad" ]]; then
|
||||||
|
yad --form \
|
||||||
|
--title="$title" \
|
||||||
|
--field="$text:LBL" \
|
||||||
|
--selectable-labels \
|
||||||
|
--button="Yes:0" \
|
||||||
|
--button="No:1" \
|
||||||
|
--width=400
|
||||||
|
else
|
||||||
|
dialog --backtitle "$back_title" \
|
||||||
|
--title "$title" \
|
||||||
|
--yesno "$text" 0 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wrapper function for info box (non-blocking message)
|
||||||
|
# Usage: ui_infobox "title" "backtitle" "text"
|
||||||
|
ui_infobox() {
|
||||||
|
local title="$1"
|
||||||
|
local back_title="$2"
|
||||||
|
local text="$3"
|
||||||
|
|
||||||
|
if [[ "$dialog_type" == "yad" ]]; then
|
||||||
|
# For yad, we'll use a notification since infobox is non-blocking
|
||||||
|
yad --notification \
|
||||||
|
--text="$text" \
|
||||||
|
--timeout=3
|
||||||
|
else
|
||||||
|
dialog --backtitle "$back_title" \
|
||||||
|
--title "$title" \
|
||||||
|
--infobox "$text" 0 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wrapper function for progress box
|
||||||
|
# Usage: command | ui_progressbox "title" "text"
|
||||||
|
ui_progressbox() {
|
||||||
|
local title="$1"
|
||||||
|
local text="$2"
|
||||||
|
|
||||||
|
if [[ "$dialog_type" == "yad" ]]; then
|
||||||
|
yad --progress \
|
||||||
|
--title="$title" \
|
||||||
|
--text="$text" \
|
||||||
|
--pulsate \
|
||||||
|
--auto-close \
|
||||||
|
--no-buttons \
|
||||||
|
--show-cursor \
|
||||||
|
--width=400
|
||||||
|
else
|
||||||
|
dialog --title "$title" \
|
||||||
|
--progressbox "$text" 20 70
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Check for updates
|
# Check for updates
|
||||||
check_update() {
|
check_update() {
|
||||||
@ -58,8 +210,7 @@ check_update() {
|
|||||||
if [[ "$home" == "$remote" ]]; then
|
if [[ "$home" == "$remote" ]]; then
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
dialog --backtitle "Linux Game manager" \
|
ui_yesno "Linux Game Manager" "Linux Game manager" "Updates are available. Would you like to update now?" || return
|
||||||
--yesno "Updates are available. Would you like to update now?" -1 -1 --stdout || return
|
|
||||||
# Store the current commit before pulling
|
# Store the current commit before pulling
|
||||||
local beforePull=$(git rev-parse HEAD)
|
local beforePull=$(git rev-parse HEAD)
|
||||||
git pull
|
git pull
|
||||||
@ -81,8 +232,7 @@ check_architecture() {
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
dialog --backtitle "Linux Game Manager" \
|
ui_infobox "Linux Game Manager" "Linux Game Manager" "This game is not compatible with $architecture architecture."
|
||||||
--infobox "This game is not compatible with $architecture architecture." -1 -1
|
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,18 +365,15 @@ download() {
|
|||||||
{ if ! curl -L4 -C - --retry 10 --output "${cache}/${dest}" "${i}" ; then
|
{ if ! curl -L4 -C - --retry 10 --output "${cache}/${dest}" "${i}" ; then
|
||||||
echo "Could not download \"$i\"..."
|
echo "Could not download \"$i\"..."
|
||||||
exit 1
|
exit 1
|
||||||
fi; } | dialog --backtitle "Linux Game Manager" \
|
fi; } | ui_progressbox "Linux Game Manager" "Downloading \"$dest\" from \"$i\""
|
||||||
--progressbox "Downloading \"$dest\" from \"$i\"" -1 -1
|
|
||||||
local downloadError=1
|
local downloadError=1
|
||||||
case "${dest##*.}" in
|
case "${dest##*.}" in
|
||||||
"pk3"|"zip")
|
"pk3"|"zip")
|
||||||
unzip -tq "${cache}/${dest}" | dialog --backtitle "Linux Game Manager" \
|
unzip -tq "${cache}/${dest}" | ui_progressbox "Linux Game Manager" "Validating ${dest##*.} file"
|
||||||
--progressbox "Validating ${dest##*.} file" -1 -1 --stdout
|
|
||||||
downloadError=$?
|
downloadError=$?
|
||||||
;;
|
;;
|
||||||
"7z")
|
"7z")
|
||||||
7z t "${cache}/${dest}" | dialog --backtitle "Linux Game Manager" \
|
7z t "${cache}/${dest}" | ui_progressbox "Linux Game Manager" "Validating 7z file"
|
||||||
--progressbox "Validating 7z file" -1 -1 --stdout
|
|
||||||
downloadError=$?
|
downloadError=$?
|
||||||
;;
|
;;
|
||||||
"exe")
|
"exe")
|
||||||
@ -249,8 +396,7 @@ download() {
|
|||||||
esac
|
esac
|
||||||
if [[ $downloadError -ne 0 ]]; then
|
if [[ $downloadError -ne 0 ]]; then
|
||||||
rm -fv "${cache}/${dest}"
|
rm -fv "${cache}/${dest}"
|
||||||
dialog --backtitle "Linux Game Manager" \
|
ui_infobox "Linux Game Manager" "Linux Game Manager" "Error downloading \"${dest}\". Installation cannot continue."
|
||||||
--infobox "Error downloading \"${dest}\". Installation cannot continue." -1 -1 --stdout
|
|
||||||
alert
|
alert
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@ -292,9 +438,7 @@ get_installer() {
|
|||||||
fi
|
fi
|
||||||
echo "Manual intervention required..."
|
echo "Manual intervention required..."
|
||||||
alert
|
alert
|
||||||
dialog --ok-label "Continue" \
|
ui_msgbox "Linux Game Manager" "Linux Game Manager" "$message"
|
||||||
--backtitle "Linux Game Manager" \
|
|
||||||
--msgbox "$message" -1 -1
|
|
||||||
# Search the Desktop and Downloads directories for the installation file
|
# Search the Desktop and Downloads directories for the installation file
|
||||||
for i in ~/Downloads ~/Desktop ; do
|
for i in ~/Downloads ~/Desktop ; do
|
||||||
find $i -type f -name "$1" -exec mv -v {} "${cache}/" \;
|
find $i -type f -name "$1" -exec mv -v {} "${cache}/" \;
|
||||||
@ -369,10 +513,7 @@ game_installer() {
|
|||||||
# Add donation option at the end
|
# Add donation option at the end
|
||||||
menuList+=("Donate" "Donate")
|
menuList+=("Donate" "Donate")
|
||||||
# Show game selection dialog
|
# Show game selection dialog
|
||||||
game="$(dialog --backtitle "Game Installer" \
|
game="$(ui_menu "Game Installer" "Game Installer" "Please select a game to install" "${menuList[@]}")"
|
||||||
--clear \
|
|
||||||
--no-tags \
|
|
||||||
--menu "Please select a game to install" 0 0 0 "${menuList[@]}" --stdout)"
|
|
||||||
# Handle selection
|
# Handle selection
|
||||||
if [[ -n "$game" ]]; then
|
if [[ -n "$game" ]]; then
|
||||||
if [[ "$game" == "Donate" ]]; then
|
if [[ "$game" == "Donate" ]]; then
|
||||||
@ -386,8 +527,7 @@ game_installer() {
|
|||||||
# Source and execute the install script
|
# Source and execute the install script
|
||||||
source "$installScript"
|
source "$installScript"
|
||||||
else
|
else
|
||||||
dialog --backtitle "Game Installer" \
|
ui_msgbox "Game Installer" "Game Installer" "Installation script not found for ${game}"
|
||||||
--msgbox "Installation script not found for ${game}" -1 -1
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@ -412,18 +552,19 @@ game_removal() {
|
|||||||
fi
|
fi
|
||||||
)
|
)
|
||||||
if [[ ${#menuList} -eq 0 ]]; then
|
if [[ ${#menuList} -eq 0 ]]; then
|
||||||
dialog --backtitle "Linux Game Manager" \
|
ui_msgbox "Linux Game Manager" "Linux Game Manager" "No games found."
|
||||||
--msgbox "No games found." -1 -1
|
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
# Create the menu of installed games
|
# Create the menu of installed games
|
||||||
|
# menuList has alternating full_path, display_name pairs
|
||||||
|
declare -a menuArgs
|
||||||
|
for ((i=0; i<${#menuList[@]}; i+=2)); do
|
||||||
|
menuArgs+=("${menuList[i]}" "${menuList[i+1]}")
|
||||||
|
done
|
||||||
local selectedGame
|
local selectedGame
|
||||||
selectedGame=$(dialog --backtitle "Linux Game Manager" \
|
selectedGame=$(ui_menu "Linux Game Manager" "Linux Game Manager" "Please select a game to delete" "${menuArgs[@]}")
|
||||||
--clear \
|
|
||||||
--no-tags \
|
|
||||||
--menu "Please select a game to delete" 0 0 0 "${menuList[@]}" --stdout)
|
|
||||||
exitCode=$?
|
exitCode=$?
|
||||||
[[ $exitCode -ne 0 ]] && exit 0
|
[[ $exitCode -ne 0 ]] || [[ -z "$selectedGame" ]] && exit 0
|
||||||
# Get the actual game file paths
|
# Get the actual game file paths
|
||||||
local gameName="${selectedGame##*/}"
|
local gameName="${selectedGame##*/}"
|
||||||
gameName="${gameName%.sh}"
|
gameName="${gameName%.sh}"
|
||||||
@ -435,21 +576,17 @@ game_removal() {
|
|||||||
gameInstallPath="${installPath}/${gameInstallPath%/*}"
|
gameInstallPath="${installPath}/${gameInstallPath%/*}"
|
||||||
if [[ -z "$gameInstallPath" ]] || [[ "${gameInstallPath%%/}" == "$installPath" ]]; then
|
if [[ -z "$gameInstallPath" ]] || [[ "${gameInstallPath%%/}" == "$installPath" ]]; then
|
||||||
# No install path found, just remove from list
|
# No install path found, just remove from list
|
||||||
dialog --backtitle "Linux Game Manager" \
|
ui_yesno "Linux Game Manager" "Linux Game Manager" "This will remove the game from your game list, but will not remove any files. Do you want to continue?" || exit 0
|
||||||
--yesno "This will remove the game from your game list, but will not remove any files. Do you want to continue?" -1 -1 || exit 0
|
|
||||||
# Remove only the .sh symlink
|
# Remove only the .sh symlink
|
||||||
rm -fv "${0%/*}/.launch/${gameName}.sh" | \
|
rm -fv "${0%/*}/.launch/${gameName}.sh" | \
|
||||||
dialog --backtitle "Linux Game Manager" \
|
ui_progressbox "Linux Game Manager" "Removing game from list..."
|
||||||
--progressbox "Removing game from list..." -1 -1
|
|
||||||
else
|
else
|
||||||
# Found install path, can remove game files
|
# Found install path, can remove game files
|
||||||
dialog --backtitle "Linux Game Manager" \
|
ui_yesno "Linux Game Manager" "Linux Game Manager" "This will remove the directory \"${gameInstallPath}\" and all of its contents. Do you want to continue?" || exit 0
|
||||||
--yesno "This will remove the directory \"${gameInstallPath}\" and all of its contents. Do you want to continue?" -1 -1 || exit 0
|
|
||||||
# Remove the game directory and symlink
|
# Remove the game directory and symlink
|
||||||
{ rm -rfv "${gameInstallPath}"
|
{ rm -rfv "${gameInstallPath}"
|
||||||
rm -fv "${0%/*}/.launch/${gameName}.sh";
|
rm -fv "${0%/*}/.launch/${gameName}.sh";
|
||||||
} | dialog --backtitle "Linux Game Manager" \
|
} | ui_progressbox "Linux Game Manager" "Removing game..."
|
||||||
--progressbox "Removing game..." -1 -1
|
|
||||||
fi
|
fi
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
@ -469,10 +606,7 @@ game_update() {
|
|||||||
done
|
done
|
||||||
menuList+=("Donate" "Donate")
|
menuList+=("Donate" "Donate")
|
||||||
menuList+=("Become a Patron" "Become a Patron")
|
menuList+=("Become a Patron" "Become a Patron")
|
||||||
local game="$(dialog --backtitle "Audio Game Updater" \
|
local game="$(ui_menu "Audio Game Updater" "Audio Game Updater" "Please select a game to update" "${menuList[@]}")"
|
||||||
--clear \
|
|
||||||
--no-tags \
|
|
||||||
--menu "Please select a game to update" 0 0 0 "${menuList[@]}" --stdout)"
|
|
||||||
if [[ ${#game} -gt 0 ]]; then
|
if [[ ${#game} -gt 0 ]]; then
|
||||||
if [[ "$game" == "Donate" ]]; then
|
if [[ "$game" == "Donate" ]]; then
|
||||||
open_url "https://ko-fi.com/stormux"
|
open_url "https://ko-fi.com/stormux"
|
||||||
@ -482,8 +616,10 @@ game_update() {
|
|||||||
open_url "https://2mb.games/product/2mb-patron/"
|
open_url "https://2mb.games/product/2mb-patron/"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
source "${game}"
|
||||||
|
else
|
||||||
|
exit 0
|
||||||
fi
|
fi
|
||||||
source "${game}"
|
|
||||||
run_update
|
run_update
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
@ -504,17 +640,18 @@ game_launcher() {
|
|||||||
fi
|
fi
|
||||||
)
|
)
|
||||||
if [[ ${#menuList} -eq 0 ]]; then
|
if [[ ${#menuList} -eq 0 ]]; then
|
||||||
dialog --backtitle "Linux Game Manager" \
|
ui_msgbox "Linux Game Manager" "Linux Game Manager" "No games found."
|
||||||
--msgbox "No games found." 5 20
|
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
# Create the menu of all games
|
# Create the menu of all games
|
||||||
selectedGame="$(dialog --backtitle "Linux Game Launcher" \
|
# menuList has alternating full_path, display_name pairs
|
||||||
--clear \
|
declare -a menuArgs
|
||||||
--no-tags \
|
for ((i=0; i<${#menuList[@]}; i+=2)); do
|
||||||
--menu "Please select a game to play" 0 0 0 "${menuList[@]}" --stdout)"
|
menuArgs+=("${menuList[i]}" "${menuList[i+1]}")
|
||||||
|
done
|
||||||
|
selectedGame="$(ui_menu "Linux Game Launcher" "Linux Game Launcher" "Please select a game to play" "${menuArgs[@]}")"
|
||||||
local menuCode=$?
|
local menuCode=$?
|
||||||
if [[ $menuCode -eq 1 ]]; then
|
if [[ $menuCode -ne 0 ]] || [[ -z "$selectedGame" ]]; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
. "${selectedGame}"
|
. "${selectedGame}"
|
||||||
@ -538,11 +675,18 @@ migrate_launcher() {
|
|||||||
done < <(sed '/^$/d' "${configFile}")
|
done < <(sed '/^$/d' "${configFile}")
|
||||||
# Move the old config file and notify user
|
# Move the old config file and notify user
|
||||||
mv "${configFile}" "${configFile}.bak"
|
mv "${configFile}" "${configFile}.bak"
|
||||||
dialog --backtitle "Linux Game manager" --msgbox \
|
ui_msgbox "Linux Game Manager" "Linux Game manager" "Games have been converted to the new launch system.\nThe old game launch information has been moved to ${configFile}.bak\nIf everything works like you expect, feel free to delete ${configFile}"
|
||||||
"Games have been converted to the new launch system.\nThe old game launch information has been moved to ${configFile}.bak\nIf everything works like you expect, feel free to delete ${configFile}" -1 -1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Detect dialog interface type BEFORE potentially setting DISPLAY
|
||||||
|
# This must happen before we modify DISPLAY to preserve console detection
|
||||||
|
if [[ -z "$DISPLAY" ]]; then
|
||||||
|
dialog_type="dialog"
|
||||||
|
else
|
||||||
|
dialog_type="yad"
|
||||||
|
fi
|
||||||
|
|
||||||
# If display isn't set assume we are launching from console and an X environment is running using display :0
|
# If display isn't set assume we are launching from console and an X environment is running using display :0
|
||||||
# Warning, launching games from console is not recommended.
|
# Warning, launching games from console is not recommended.
|
||||||
if [[ -z "$DISPLAY" ]]; then
|
if [[ -z "$DISPLAY" ]]; then
|
||||||
@ -618,8 +762,7 @@ while getopts "${args}" i ; do
|
|||||||
r) game_removal ;;
|
r) game_removal ;;
|
||||||
t)
|
t)
|
||||||
gameCount=$(find .install -type f -iname "*.sh" | wc -l)
|
gameCount=$(find .install -type f -iname "*.sh" | wc -l)
|
||||||
dialog --backtitle "Linux Game Manager" \
|
ui_infobox "Linux Game Manager" "Linux Game Manager" "There are currently ${gameCount} games available."
|
||||||
--infobox "There are currently ${gameCount} games available." -1 -1
|
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
u) game_update ;;
|
u) game_update ;;
|
||||||
|
Reference in New Issue
Block a user