ci: build apk android with github actions (#1715)

New Features:
- Added scrollable areas to general options, action bar settings, and game panel controls for improved navigation on compact displays.
- Integrated Android APK build automation into the CI pipeline.

Chores:
- Enhanced build system to support flexible Android architecture configuration during automated builds.
This commit is contained in:
kokekanon 2026-05-12 19:47:00 -04:00 committed by GitHub
parent e8ef4cc044
commit 6a478408ee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 1029 additions and 686 deletions

View file

@ -8,6 +8,7 @@ on:
- "src/**"
- "tests/**"
- "cmake/**"
- "android/**"
- "browser/**"
- "data/**"
- "mods/**"
@ -20,6 +21,12 @@ on:
- "Dockerfile"
- "Dockerfile.browser"
- "Dockerfile.browser.sh"
- "build_luajit_android.sh"
- "setup_android_deps.sh"
- "init.lua"
- "otclientrc.lua"
- "cacert.pem"
- "config.ini"
- ".dockerignore"
- ".yamllint.yaml"
- ".reviewdog.yml"
@ -32,6 +39,7 @@ on:
- "src/**"
- "tests/**"
- "cmake/**"
- "android/**"
- "browser/**"
- "data/**"
- "mods/**"
@ -44,6 +52,12 @@ on:
- "Dockerfile"
- "Dockerfile.browser"
- "Dockerfile.browser.sh"
- "build_luajit_android.sh"
- "setup_android_deps.sh"
- "init.lua"
- "otclientrc.lua"
- "cacert.pem"
- "config.ini"
- ".dockerignore"
- ".yamllint.yaml"
- ".reviewdog.yml"
@ -61,6 +75,7 @@ jobs:
contents: read
outputs:
compile: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'merge_group') && 'true' || steps.filter.outputs.compile }}
android: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'merge_group') && 'true' || steps.filter.outputs.android }}
docker: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'merge_group') && 'true' || steps.filter.outputs.docker }}
browser: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'merge_group') && 'true' || steps.filter.outputs.browser }}
steps:
@ -90,6 +105,16 @@ jobs:
- ".github/workflows/reusable-build-windows.yml"
- ".github/workflows/reusable-checks.yml"
- ".github/workflows/reusable-tests-lua.yml"
android:
- "src/**"
- "android/**"
- "cmake/**"
- "CMakeLists.txt"
- "vcpkg.json"
- "build_luajit_android.sh"
- "setup_android_deps.sh"
- ".github/workflows/ci.yml"
- ".github/workflows/reusable-build-android-apk.yml"
docker:
- "Dockerfile"
- ".dockerignore"
@ -151,6 +176,16 @@ jobs:
uses: ./.github/workflows/reusable-build-windows.yml
secrets: inherit
build-android-apk:
name: Build - Android APK
needs: [changes, checks, tests-lua]
if: needs.changes.outputs.android == 'true' && needs.checks.result == 'success' && needs.tests-lua.result == 'success' && (github.event_name != 'pull_request' || github.event.pull_request.draft == false)
permissions:
contents: read
pull-requests: read
uses: ./.github/workflows/reusable-build-android-apk.yml
secrets: inherit
build-docker:
name: Build - Docker
needs: [changes, checks, tests-lua]

View file

@ -0,0 +1,231 @@
name: Reusable Android APK Build
on:
workflow_call:
permissions:
contents: read
pull-requests: read
env:
JAVA_VERSION: "17"
NDK_VERSION: "29.0.13599879"
CMAKE_VERSION: "3.22.1"
COMPILE_SDK: "36"
BUILD_TOOLS_VERSION: "36.0.0"
CI_ANDROID_ABIS: "arm64-v8a"
CI_VCPKG_TRIPLET: "arm64-android"
LUAJIT_COMMIT: "d0e88930ddde28ff662503f9f20facf34f7265aa"
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
VCPKG_FEATURE_FLAGS: versions,binarycaching
concurrency:
group: otclient-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
name: Android release APK
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up JDK ${{ env.JAVA_VERSION }}
uses: actions/setup-java@v4
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: temurin
cache: gradle
cache-dependency-path: |
android/**/*.gradle
android/**/*.gradle.kts
android/gradle/wrapper/gradle-wrapper.properties
- name: Set up Android SDK
uses: android-actions/setup-android@v3
- name: Install host build packages
run: |
set -euo pipefail
sudo apt-get update
sudo apt-get install -y \
build-essential \
curl \
g++-multilib \
gcc-multilib \
git \
make \
ninja-build \
pkg-config \
python3 \
unzip \
zip
- name: Install Android SDK packages
run: |
set -euo pipefail
sdk_root="${ANDROID_SDK_ROOT:-${ANDROID_HOME:-}}"
if [[ -z "${sdk_root}" ]]; then
echo "::error title=Missing Android SDK::ANDROID_SDK_ROOT or ANDROID_HOME must be set."
exit 1
fi
sdkmanager --install \
"platform-tools" \
"platforms;android-${COMPILE_SDK}" \
"build-tools;${BUILD_TOOLS_VERSION}" \
"cmake;${CMAKE_VERSION}" \
"ndk;${NDK_VERSION}"
ndk_dir="${sdk_root}/ndk/${NDK_VERSION}"
if [[ ! -d "${ndk_dir}" ]]; then
ndk_dir="$(find "${sdk_root}/ndk" -maxdepth 1 -type d -name "${NDK_VERSION}*" | sort | head -n 1)"
fi
if [[ -z "${ndk_dir}" || ! -d "${ndk_dir}" ]]; then
echo "::error title=Missing Android NDK::NDK ${NDK_VERSION} was not installed."
exit 1
fi
echo "ANDROID_HOME=${sdk_root}" >> "${GITHUB_ENV}"
echo "ANDROID_SDK_ROOT=${sdk_root}" >> "${GITHUB_ENV}"
echo "ANDROID_NDK_HOME=${ndk_dir}" >> "${GITHUB_ENV}"
echo "ANDROID_NDK_ROOT=${ndk_dir}" >> "${GITHUB_ENV}"
- name: Read vcpkg baseline
id: vcpkg
run: |
set -euo pipefail
baseline="$(python3 -c 'import json; print(json.load(open("vcpkg.json"))["builtin-baseline"])')"
if [[ ! "${baseline}" =~ ^[0-9a-f]{40}$ ]]; then
echo "::error title=Invalid vcpkg baseline::vcpkg.json must contain a full 40-character builtin-baseline SHA."
exit 1
fi
echo "baseline=${baseline}" >> "${GITHUB_OUTPUT}"
- name: Cache vcpkg checkout
uses: actions/cache@v4
with:
path: ${{ env.VCPKG_ROOT }}
key: vcpkg-${{ runner.os }}-${{ steps.vcpkg.outputs.baseline }}
- name: Bootstrap vcpkg
run: |
set -euo pipefail
if [[ ! -d "${VCPKG_ROOT}/.git" ]]; then
git clone https://github.com/microsoft/vcpkg.git "${VCPKG_ROOT}"
fi
git -C "${VCPKG_ROOT}" fetch --depth 1 origin "${{ steps.vcpkg.outputs.baseline }}"
git -C "${VCPKG_ROOT}" checkout "${{ steps.vcpkg.outputs.baseline }}"
"${VCPKG_ROOT}/bootstrap-vcpkg.sh" -disableMetrics
- name: Export vcpkg GitHub Actions cache variables
uses: actions/github-script@v9
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite');
- name: Cache LuaJIT Android libraries
id: luajit-cache
uses: actions/cache@v4
with:
path: |
luajit-src
android/app/libs
key: luajit-android-${{ runner.os }}-${{ env.CI_ANDROID_ABIS }}-ndk-${{ env.NDK_VERSION }}-${{ env.LUAJIT_COMMIT }}-${{ hashFiles('build_luajit_android.sh') }}
- name: Fetch LuaJIT source
if: steps.luajit-cache.outputs.cache-hit != 'true'
run: |
set -euo pipefail
git clone https://github.com/LuaJIT/LuaJIT.git luajit-src
git -C luajit-src checkout "${LUAJIT_COMMIT}"
- name: Build LuaJIT for Android
if: steps.luajit-cache.outputs.cache-hit != 'true'
env:
OTCLIENT_ANDROID_ABIS: ${{ env.CI_ANDROID_ABIS }}
run: |
set -euo pipefail
chmod +x build_luajit_android.sh
./build_luajit_android.sh
- name: Pack game assets into data.zip
run: |
set -euo pipefail
mkdir -p android/app/src/main/assets
python3 - <<'PY'
from pathlib import Path
import zipfile
output = Path("android/app/src/main/assets/data.zip")
roots = [Path("data"), Path("mods"), Path("modules")]
files = [Path("init.lua"), Path("otclientrc.lua"), Path("cacert.pem"), Path("config.ini")]
with zipfile.ZipFile(output, "w", zipfile.ZIP_DEFLATED) as archive:
for root in roots:
if not root.exists():
raise SystemExit(f"Missing asset directory: {root}")
for path in sorted(root.rglob("*")):
if path.is_file():
archive.write(path, path.as_posix())
for path in files:
if path.exists():
archive.write(path, path.as_posix())
print(f"Wrote {output} ({output.stat().st_size} bytes)")
PY
- name: Create fallback release keystore
run: |
set -euo pipefail
mkdir -p "${HOME}/.android"
if [[ ! -f "${HOME}/.android/debug.keystore" ]]; then
keytool -genkeypair \
-keystore "${HOME}/.android/debug.keystore" \
-storepass android \
-keypass android \
-alias androiddebugkey \
-keyalg RSA \
-keysize 2048 \
-validity 10000 \
-dname "CN=Android Debug,O=Android,C=US"
fi
- name: Make Gradle wrapper executable
run: chmod +x android/gradlew
- name: Build APK
working-directory: android
env:
OTCLIENT_ANDROID_ABIS: ${{ env.CI_ANDROID_ABIS }}
VCPKG_ROOT: ${{ env.VCPKG_ROOT }}
run: ./gradlew :app:assembleRelease --no-daemon --stacktrace --info
- name: List APK outputs
run: find android/app/build/outputs/apk/release -maxdepth 1 -type f -name "*.apk" -print
- name: Upload APK artifact
uses: actions/upload-artifact@v7
with:
name: otclient-android-release-${{ github.sha }}
path: android/app/build/outputs/apk/release/*.apk
if-no-files-found: error
retention-days: 14
- name: Write download summary
run: |
{
echo "## Android APK"
echo ""
echo "The APK was uploaded as the workflow artifact:"
echo ""
echo "- otclient-android-release-${GITHUB_SHA}"
} >> "${GITHUB_STEP_SUMMARY}"

View file

@ -3,6 +3,14 @@ plugins {
id("org.jetbrains.kotlin.android")
}
val ciAbiFilters = providers.gradleProperty("otclient.android.abis")
.orElse(providers.environmentVariable("OTCLIENT_ANDROID_ABIS"))
.orNull
?.split(",")
?.map { it.trim() }
?.filter { it.isNotEmpty() }
?: listOf("arm64-v8a", "armeabi-v7a", "x86_64", "x86")
android {
namespace = "com.github.otclient"
compileSdk = 36
@ -16,7 +24,7 @@ android {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
ndk {
abiFilters += listOf("arm64-v8a", "armeabi-v7a", "x86_64", "x86")
abiFilters += ciAbiFilters
}
externalNativeBuild {

View file

@ -1,17 +1,17 @@
#!/bin/bash
set -euo pipefail
# Build LuaJIT 2.1 for all Android ABIs using NDK cross-compilation
# Based on official LuaJIT docs (luajit.org/install.html) and vcpkg build flags
# Build LuaJIT 2.1 for Android ABIs using NDK cross-compilation.
#
# Requirements:
# - ANDROID_NDK_HOME set (NDK 25+)
# - gcc-multilib installed (for 32-bit targets: sudo apt install gcc-multilib)
# - gcc-multilib installed when building 32-bit ABIs
# - LuaJIT source at ./luajit-src/ (commit d0e88930 recommended for vcpkg compat)
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
NDK="${ANDROID_NDK_HOME:-/home/dev/android-sdk/ndk/29.0.13599879}"
NDKBIN="$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin"
LUAJIT_SRC="$SCRIPT_DIR/luajit-src"
INSTALL_BASE="$SCRIPT_DIR/android/app/libs"
REQUESTED_ABIS="${OTCLIENT_ANDROID_ABIS:-arm64-v8a,armeabi-v7a,x86_64,x86}"
if [ ! -d "$LUAJIT_SRC/src" ]; then
echo "ERROR: LuaJIT source not found at $LUAJIT_SRC"
@ -19,10 +19,21 @@ if [ ! -d "$LUAJIT_SRC/src" ]; then
exit 1
fi
# Verify gcc -m32 works (needed for 32-bit targets)
if ! gcc -m32 -x c -c /dev/null -o /dev/null 2>/dev/null; then
echo "Installing gcc-multilib for 32-bit cross-compilation..."
sudo apt-get install -y gcc-multilib g++-multilib
IFS=',' read -r -a ABI_LIST <<< "$REQUESTED_ABIS"
needs_32bit=false
for ABI in "${ABI_LIST[@]}"; do
ABI_TRIMMED="$(echo "$ABI" | xargs)"
if [ "$ABI_TRIMMED" = "armeabi-v7a" ] || [ "$ABI_TRIMMED" = "x86" ]; then
needs_32bit=true
break
fi
done
if [ "$needs_32bit" = true ]; then
if ! gcc -m32 -x c -c /dev/null -o /dev/null 2>/dev/null; then
echo "Installing gcc-multilib for 32-bit cross-compilation..."
sudo apt-get install -y gcc-multilib g++-multilib
fi
fi
build_luajit() {
@ -32,14 +43,7 @@ build_luajit() {
cd "$LUAJIT_SRC"
make clean 2>/dev/null || true
# Official LuaJIT cross-compilation approach:
# - HOST_CC="gcc -m32" for 32-bit targets (correct struct offsets in buildvm)
# - CROSS= for NDK toolchain prefix
# - STATIC_CC/DYNAMIC_CC for clang compiler
# - TARGET_CFLAGS with -DLUAJIT_UNWIND_EXTERNAL (required for Android NDK C++ interop)
# - Never use TARGET_SYS=Android (causes crashes, LuaJIT Issue #440)
# - Use 'amalg' target for optimized single-file compilation
make -j$(nproc) amalg \
make -j"$(nproc)" amalg \
HOST_CC="$HOST_CC" \
CROSS="${NDKBIN}/${CROSS_PREFIX}" \
STATIC_CC="${NDKBIN}/${CC_PREFIX}clang" \
@ -50,26 +54,34 @@ build_luajit() {
TARGET_CFLAGS="-fPIC -DLUAJIT_UNWIND_EXTERNAL -fno-stack-protector" \
BUILDMODE=static
# Install lib
local LIB_DIR="$INSTALL_BASE/lib/$ABI"
mkdir -p "$LIB_DIR"
cp src/libluajit.a "$LIB_DIR/libluajit-5.1.a"
echo " -> $LIB_DIR/libluajit-5.1.a ($(du -h "$LIB_DIR/libluajit-5.1.a" | cut -f1))"
}
# arm64-v8a: 64-bit ARM (most modern Android devices)
build_luajit "arm64-v8a" "aarch64-linux-android-" "aarch64-linux-android21-" "gcc"
for ABI in "${ABI_LIST[@]}"; do
ABI_TRIMMED="$(echo "$ABI" | xargs)"
case "$ABI_TRIMMED" in
arm64-v8a)
build_luajit "arm64-v8a" "aarch64-linux-android-" "aarch64-linux-android21-" "gcc"
;;
armeabi-v7a)
build_luajit "armeabi-v7a" "arm-linux-androideabi-" "armv7a-linux-androideabi21-" "gcc -m32"
;;
x86_64)
build_luajit "x86_64" "x86_64-linux-android-" "x86_64-linux-android21-" "gcc"
;;
x86)
build_luajit "x86" "i686-linux-android-" "i686-linux-android21-" "gcc -m32"
;;
*)
echo "ERROR: Unsupported ABI '$ABI_TRIMMED'"
exit 1
;;
esac
done
# armeabi-v7a: 32-bit ARM (older devices) — requires HOST_CC="gcc -m32"
build_luajit "armeabi-v7a" "arm-linux-androideabi-" "armv7a-linux-androideabi21-" "gcc -m32"
# x86_64: 64-bit x86 (emulators, Chromebooks)
build_luajit "x86_64" "x86_64-linux-android-" "x86_64-linux-android21-" "gcc"
# x86: 32-bit x86 (older emulators) — requires HOST_CC="gcc -m32"
build_luajit "x86" "i686-linux-android-" "i686-linux-android21-" "gcc -m32"
# Install headers (shared across all ABIs)
echo ""
echo "=== Installing headers ==="
mkdir -p "$INSTALL_BASE/include/luajit"
@ -77,7 +89,6 @@ cp "$LUAJIT_SRC/src/lua.h" "$LUAJIT_SRC/src/lualib.h" "$LUAJIT_SRC/src/lauxlib.h
"$LUAJIT_SRC/src/luaconf.h" "$LUAJIT_SRC/src/luajit.h" \
"$INSTALL_BASE/include/luajit/"
# Create lua.hpp C++ wrapper
cat > "$INSTALL_BASE/include/luajit/lua.hpp" << 'LUAHPP'
// C++ wrapper for LuaJIT header files.
@ -90,5 +101,8 @@ extern "C" {
LUAHPP
echo ""
echo "=== All ABIs built successfully ==="
ls -lh "$INSTALL_BASE/lib/"*/libluajit-5.1.a
echo "=== Requested ABIs built successfully ==="
for ABI in "${ABI_LIST[@]}"; do
ABI_TRIMMED="$(echo "$ABI" | xargs)"
ls -lh "$INSTALL_BASE/lib/$ABI_TRIMMED/libluajit-5.1.a"
done

View file

@ -1,218 +1,237 @@
UIWidget
anchors.fill: parent
visible: false
SmallReversedQtPanel
UIScrollArea
id: generalScrollArea
anchors.left: parent.left
anchors.right: parent.right
anchors.right: generalScrollBar.left
anchors.top: parent.top
height: 22
anchors.bottom: parent.bottom
vertical-scrollbar: generalScrollBar
OptionCheckBoxMarked
id: showPing
!text: tr('Show connection ping')
!tooltip: tr('Display connection speed to the server (milliseconds)')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
height: 32
margin-top: 7
$mobile:
height: 0
margin-top: 0
visible: false
Label
id: mouseControlLabel
SmallReversedQtPanel
anchors.left: parent.left
margin-left: 18
color: #c0c0c0ff
anchors.verticalCenter: parent.verticalCenter
text-align: left
!text: tr('Mouse Control:')
QtComboBox
id: mouseControlMode
width: 120
margin-left: 10
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
mouse-scroll: false
!tooltip: tr('Regular Controls: Right-click opens menu, use Ctrl+Click for direct item use\nClassic Controls: Right-click for direct use\nLeft Smart-Click: Left-click for direct item use, look at non-walkable objects, or walk to walkable objects. Right-click opens menu')
anchors.right: parent.right
anchors.top: parent.top
height: 22
OptionCheckBoxMarked
id: showPing
!text: tr('Show connection ping')
!tooltip: tr('Display connection speed to the server (milliseconds)')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
height: 32
margin-top: 7
$mobile:
height: 0
margin-top: 0
visible: false
QtComboBox
id: lootControlMode
width: 120
margin-left: 10
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
mouse-scroll: false
!tooltip: tr('Choose how to loot items when using Classic Controls\nLoot: Right - Use right-click to quickloot AND open containers/corpses\nLoot: SHIFT+Right - Use SHIFT+right-click for quick looting (right-click maintains normal use/open behavior)\nLoot: Left - Use left-click for quick looting only (right-click maintains normal use/open behavior)')
visible: false
SmallReversedQtPanel
anchors.left: parent.left
Label
id: mouseControlLabel
anchors.left: parent.left
margin-left: 18
color: #c0c0c0ff
anchors.verticalCenter: parent.verticalCenter
text-align: left
!text: tr('Mouse Control:')
QtComboBox
id: mouseControlMode
width: 120
margin-left: 10
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
mouse-scroll: false
!tooltip: tr('Regular Controls: Right-click opens menu, use Ctrl+Click for direct item use\nClassic Controls: Right-click for direct use\nLeft Smart-Click: Left-click for direct item use, look at non-walkable objects, or walk to walkable objects. Right-click opens menu')
$mobile:
visible: false
QtComboBox
id: lootControlMode
width: 120
margin-left: 10
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
mouse-scroll: false
!tooltip: tr('Choose how to loot items when using Classic Controls\nLoot: Right - Use right-click to quickloot AND open containers/corpses\nLoot: SHIFT+Right - Use SHIFT+right-click for quick looting (right-click maintains normal use/open behavior)\nLoot: Left - Use left-click for quick looting only (right-click maintains normal use/open behavior)')
visible: false
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBox
id: autoChaseOverride
!text: tr('Allow auto chase override')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBox
id: talkOnRightClick
!text: tr('Right-click talk to NPC')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBoxMarked
id: returnDisablesChat
!text: tr('Enter to disable chat')
!tooltip: tr('Enables disabling chat and enabling WASD when pressed Enter.')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBox
id: moveStack
!text: tr('Move stacks directly')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBoxMarked
id: smartWalk
!text: tr('Enable smart walking')
!tooltip: tr('Will detect when to use diagonal step based on the\nkeys you are pressing')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBox
id: openMaximized
!text: tr('Open containers maximized')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBox
id: displayText
!text: tr('Display text messages')
SmallReversedQtPanel
id: hotkeyDelay_label
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionScaleScroll
id: hotkeyDelay
!text: tr('Hotkey delay: 30ms')
anchors.fill: parent
&minimumScrollValue: 30
&maximumScrollValue: 250
&scrollSize: 21
@onSetup: |
local value = modules.client_options.getOption('hotkeyDelay')
self:setText(tr('Hotkey delay: %dms', value))
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionScaleScroll
id: walkTurnDelay
!text: tr('Walk delay after turn: 50ms')
anchors.fill: parent
&minimumScrollValue: 10
&maximumScrollValue: 500
&scrollSize: 21
@onSetup: |
local value = modules.client_options.getOption('walkTurnDelay')
self:setText(tr('Walk delay after turn: %dms', value))
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionScaleScroll
id: walkTeleportDelay
!text: tr('Walk delay after teleport: 200ms')
anchors.fill: parent
&minimumScrollValue: 50
&maximumScrollValue: 500
&scrollSize: 21
@onSetup: |
local value = modules.client_options.getOption('walkTeleportDelay')
self:setText(tr('Walk delay after turn: %dms', value))
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionScaleScroll
id: walkStairsDelay
!text: tr('Walk delay after floor change: 200ms')
anchors.fill: parent
&minimumScrollValue: 50
&maximumScrollValue: 500
&scrollSize: 21
@onSetup: |
local value = modules.client_options.getOption('walkStairsDelay')
self:setText(tr('Walk delay after turn: %dms', value))
QtButton
id: hotkeysButton
!text: tr('Hotkeys Manager')
@onClick: modules.game_hotkeys.show()
anchors.top: prev.bottom
anchors.left: parent.left
margin-top: 12
size: 120 20
VerticalScrollBar
id: generalScrollBar
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBox
id: autoChaseOverride
!text: tr('Allow auto chase override')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBox
id: talkOnRightClick
!text: tr('Right-click talk to NPC')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBoxMarked
id: returnDisablesChat
!text: tr('Enter to disable chat')
!tooltip: tr('Enables disabling chat and enabling WASD when pressed Enter.')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBox
id: moveStack
!text: tr('Move stacks directly')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBoxMarked
id: smartWalk
!text: tr('Enable smart walking')
!tooltip: tr('Will detect when to use diagonal step based on the\nkeys you are pressing')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBox
id: openMaximized
!text: tr('Open containers maximized')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBox
id: displayText
!text: tr('Display text messages')
SmallReversedQtPanel
id: hotkeyDelay_label
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionScaleScroll
id: hotkeyDelay
!text: tr('Hotkey delay: 30ms')
anchors.fill: parent
&minimumScrollValue: 30
&maximumScrollValue: 250
&scrollSize: 21
@onSetup: |
local value = modules.client_options.getOption('hotkeyDelay')
self:setText(tr('Hotkey delay: %dms', value))
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionScaleScroll
id: walkTurnDelay
!text: tr('Walk delay after turn: 50ms')
anchors.fill: parent
&minimumScrollValue: 10
&maximumScrollValue: 500
&scrollSize: 21
@onSetup: |
local value = modules.client_options.getOption('walkTurnDelay')
self:setText(tr('Walk delay after turn: %dms', value))
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionScaleScroll
id: walkTeleportDelay
!text: tr('Walk delay after teleport: 200ms')
anchors.fill: parent
&minimumScrollValue: 50
&maximumScrollValue: 500
&scrollSize: 21
@onSetup: |
local value = modules.client_options.getOption('walkTeleportDelay')
self:setText(tr('Walk delay after turn: %dms', value))
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionScaleScroll
id: walkStairsDelay
!text: tr('Walk delay after floor change: 200ms')
anchors.fill: parent
&minimumScrollValue: 50
&maximumScrollValue: 500
&scrollSize: 21
@onSetup: |
local value = modules.client_options.getOption('walkStairsDelay')
self:setText(tr('Walk delay after turn: %dms', value))
QtButton
id: hotkeysButton
!text: tr('Hotkeys Manager')
@onClick: modules.game_hotkeys.show()
anchors.top: prev.bottom
anchors.left: parent.left
margin-top: 12
size: 120 20
step: 14
pixels-scroll: true
$!mobile:
visible: false

View file

@ -2,340 +2,356 @@ UIWidget
anchors.fill: parent
visible: false
SmallReversedQtPanel
UIScrollArea
id: actionBarsScrollArea
anchors.left: parent.left
anchors.right: parent.right
anchors.right: actionBarsScrollBar.left
anchors.top: parent.top
height: 67
anchors.bottom: parent.bottom
vertical-scrollbar: actionBarsScrollBar
Label
!text: tr('Show Bottom Action Bars:')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
margin-top: 5
color: #c0c0c0ff
height: 67
OptionCheckBox
id: allActionBar13
!text: tr('All')
anchors.left: prev.right
anchors.top: parent.top
margin-top: 5
margin-left: 12
Label
!text: tr('Show Bottom Action Bars:')
anchors.left: parent.left
anchors.top: parent.top
margin-top: 5
color: #c0c0c0ff
OptionCheckBox
id: actionBarShowBottom1
!text: tr('Bar 1')
anchors.left: prev.left
anchors.top: parent.top
text-offset: 14 0
margin-top: 5
margin-left: 53
OptionCheckBox
id: allActionBar13
!text: tr('All')
anchors.left: prev.right
anchors.top: parent.top
margin-top: 5
margin-left: 12
OptionCheckBox
id: actionBarShowBottom2
!text: tr('Bar 2')
anchors.left: prev.left
anchors.top: parent.top
margin-top: 5
margin-left: 53
text-offset: 14 0
OptionCheckBox
id: actionBarShowBottom3
!text: tr('Bar 3')
anchors.left: prev.left
anchors.top: parent.top
margin-top: 5
margin-left: 53
text-offset: 14 0
Label
id: leftActionLabel
!text: tr('Show Left Action Bars:')
OptionCheckBox
id: actionBarShowBottom1
!text: tr('Bar 1')
anchors.left: prev.left
anchors.top: parent.top
text-offset: 14 0
margin-top: 5
margin-left: 53
OptionCheckBox
id: actionBarShowBottom2
!text: tr('Bar 2')
anchors.left: prev.left
anchors.top: parent.top
margin-top: 5
margin-left: 53
text-offset: 14 0
OptionCheckBox
id: actionBarShowBottom3
!text: tr('Bar 3')
anchors.left: prev.left
anchors.top: parent.top
margin-top: 5
margin-left: 53
text-offset: 14 0
Label
id: leftActionLabel
!text: tr('Show Left Action Bars:')
anchors.left: parent.left
anchors.top: prev.bottom
margin-top: 5
color: #c0c0c0ff
OptionCheckBox
id: allActionBar46
!text: tr('All')
anchors.left: prev.right
anchors.top: prev.top
margin-left: 30
OptionCheckBox
id: actionBarShowLeft1
!text: tr('Bar 1')
text-offset: 14 0
anchors.left: prev.left
anchors.top: prev.top
margin-left: 53
OptionCheckBox
id: actionBarShowLeft2
!text: tr('Bar 2')
anchors.left: prev.left
anchors.top: prev.top
margin-left: 53
text-offset: 14 0
OptionCheckBox
id: actionBarShowLeft3
!text: tr('Bar 3')
anchors.left: prev.left
anchors.top: prev.top
margin-left: 53
text-offset: 14 0
Label
id: rightActionLabel
!text: tr('Show Right Action Bars:')
anchors.left: parent.left
anchors.top: leftActionLabel.bottom
margin-top: 5
color: #c0c0c0ff
OptionCheckBox
id: allActionBar79
!text: tr('All')
anchors.left: prev.right
anchors.top: prev.top
margin-left: 23
OptionCheckBox
id: actionBarShowRight1
!text: tr('Bar 1')
text-offset: 14 0
anchors.left: prev.left
anchors.top: prev.top
margin-left: 53
OptionCheckBox
id: actionBarShowRight2
!text: tr('Bar 2')
text-offset: 14 0
anchors.left: prev.left
anchors.top: prev.top
margin-left: 54
OptionCheckBox
id: actionBarShowRight3
!text: tr('Bar 3')
text-offset: 14 0
anchors.left: prev.left
anchors.top: prev.top
margin-left: 53
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 5
color: #c0c0c0ff
margin-top: 7
height: 22
OptionCheckBox
id: allActionBar46
!text: tr('All')
anchors.left: prev.right
anchors.top: prev.top
margin-left: 30
OptionCheckBoxMarked
id: showAssignedHKButton
!text: tr('Show Assigned Hotkey for Action Button')
!tooltip: tr('Display the hotkey assigned to each action button')
OptionCheckBox
id: actionBarShowLeft1
!text: tr('Bar 1')
text-offset: 14 0
anchors.left: prev.left
anchors.top: prev.top
margin-left: 53
OptionCheckBox
id: actionBarShowLeft2
!text: tr('Bar 2')
anchors.left: prev.left
anchors.top: prev.top
margin-left: 53
text-offset: 14 0
OptionCheckBox
id: actionBarShowLeft3
!text: tr('Bar 3')
anchors.left: prev.left
anchors.top: prev.top
margin-left: 53
text-offset: 14 0
Label
id: rightActionLabel
!text: tr('Show Right Action Bars:')
SmallReversedQtPanel
anchors.left: parent.left
anchors.top: leftActionLabel.bottom
margin-top: 5
color: #c0c0c0ff
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBox
id: allActionBar79
!text: tr('All')
anchors.left: prev.right
anchors.top: prev.top
margin-left: 23
OptionCheckBoxMarked
id: showHKObjectsBars
!text: tr('Show Amount of Assigned Objects')
!tooltip: tr('Display the quantity of items assigned to action buttons')
OptionCheckBox
id: actionBarShowRight1
!text: tr('Bar 1')
text-offset: 14 0
anchors.left: prev.left
anchors.top: prev.top
margin-left: 53
OptionCheckBox
id: actionBarShowRight2
!text: tr('Bar 2')
text-offset: 14 0
anchors.left: prev.left
anchors.top: prev.top
margin-left: 54
OptionCheckBox
id: actionBarShowRight3
!text: tr('Bar 3')
text-offset: 14 0
anchors.left: prev.left
anchors.top: prev.top
margin-left: 53
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBoxMarked
id: showAssignedHKButton
!text: tr('Show Assigned Hotkey for Action Button')
!tooltip: tr('Display the hotkey assigned to each action button')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBoxMarked
id: showHKObjectsBars
!text: tr('Show Amount of Assigned Objects')
!tooltip: tr('Display the quantity of items assigned to action buttons')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBoxMarked
id: showSpellParameters
!text: tr('Show Spell Parameters')
!tooltip: tr('Display spell parameters on action buttons')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBoxMarked
id: graphicalCooldown
!text: tr('Show Graphical Cooldown')
!tooltip: tr('Display visual cooldown animation on action buttons')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBoxMarked
id: cooldownSecond
!text: tr('Show Cooldown in Seconds')
!tooltip: tr('Display remaining cooldown time in seconds')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBoxMarked
id: actionTooltip
!text: tr('Show Action Button Tooltip')
!tooltip: tr('Display tooltips when hovering over action buttons')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 75
Label
!text: tr('Clear Bottom Action Bars:')
SmallReversedQtPanel
anchors.left: parent.left
anchors.top: parent.top
margin-left: 10
margin-top: 5
color: #c0c0c0ff
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
UIWidget
id: toolTipWidgetClearBottom
image-source: /images/icons/show_gui_help_grey
size: 12 12
anchors.right: parent.right
anchors.top: parent.top
margin-right: 3
margin-top: 5
!tooltip: tr('Clear all assignments from bottom action bars')
OptionCheckBoxMarked
id: showSpellParameters
!text: tr('Show Spell Parameters')
!tooltip: tr('Display spell parameters on action buttons')
QtButton
id: clearBottomBar1
!text: tr('Bar 1')
width: 60
height: 18
anchors.right: parent.right
anchors.top: parent.top
margin-right: 130
margin-top: 3
@onClick: modules.game_actionbar.resetAction(1)
QtButton
id: clearBottomBar2
!text: tr('Bar 2')
width: 60
height: 18
anchors.right: parent.right
anchors.top: parent.top
margin-right: 65
margin-top: 3
@onClick: modules.game_actionbar.resetAction(2)
QtButton
id: clearBottomBar3
!text: tr('Bar 3')
width: 60
height: 18
anchors.right: parent.right
anchors.top: parent.top
margin-right: 0
margin-top: 3
@onClick: modules.game_actionbar.resetAction(3)
Label
!text: tr('Clear Left Action Bars:')
SmallReversedQtPanel
anchors.left: parent.left
anchors.top: clearBottomBar1.bottom
margin-left: 10
margin-top: 5
color: #c0c0c0ff
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
QtButton
id: clearLeftBar1
!text: tr('Bar 1')
width: 60
height: 18
anchors.right: parent.right
anchors.top: clearBottomBar1.bottom
margin-right: 130
margin-top: 3
@onClick: modules.game_actionbar.resetAction(4)
QtButton
id: clearLeftBar2
!text: tr('Bar 2')
width: 60
height: 18
anchors.right: parent.right
anchors.top: clearBottomBar2.bottom
margin-right: 65
margin-top: 3
@onClick: modules.game_actionbar.resetAction(5)
QtButton
id: clearLeftBar3
!text: tr('Bar 3')
width: 60
height: 18
anchors.right: parent.right
anchors.top: clearBottomBar3.bottom
margin-right: 0
margin-top: 3
@onClick: modules.game_actionbar.resetAction(6)
Label
!text: tr('Clear Right Action Bars:')
OptionCheckBoxMarked
id: graphicalCooldown
!text: tr('Show Graphical Cooldown')
!tooltip: tr('Display visual cooldown animation on action buttons')
SmallReversedQtPanel
anchors.left: parent.left
anchors.top: clearLeftBar1.bottom
margin-left: 10
margin-top: 5
color: #c0c0c0ff
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 7
height: 22
QtButton
id: clearRightBar1
!text: tr('Bar 1')
width: 60
height: 18
OptionCheckBoxMarked
id: cooldownSecond
!text: tr('Show Cooldown in Seconds')
!tooltip: tr('Display remaining cooldown time in seconds')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: clearLeftBar1.bottom
margin-right: 130
margin-top: 3
@onClick: modules.game_actionbar.resetAction(7)
QtButton
id: clearRightBar2
!text: tr('Bar 2')
width: 60
height: 18
anchors.top: prev.bottom
margin-top: 7
height: 22
OptionCheckBoxMarked
id: actionTooltip
!text: tr('Show Action Button Tooltip')
!tooltip: tr('Display tooltips when hovering over action buttons')
SmallReversedQtPanel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: clearLeftBar2.bottom
margin-right: 65
margin-top: 3
@onClick: modules.game_actionbar.resetAction(8)
anchors.top: prev.bottom
margin-top: 7
height: 75
Label
!text: tr('Clear Bottom Action Bars:')
anchors.left: parent.left
anchors.top: parent.top
margin-left: 10
margin-top: 5
color: #c0c0c0ff
UIWidget
id: toolTipWidgetClearBottom
image-source: /images/icons/show_gui_help_grey
size: 12 12
anchors.right: parent.right
anchors.top: parent.top
margin-right: 3
margin-top: 5
!tooltip: tr('Clear all assignments from bottom action bars')
QtButton
id: clearBottomBar1
!text: tr('Bar 1')
width: 60
height: 18
anchors.right: parent.right
anchors.top: parent.top
margin-right: 130
margin-top: 3
@onClick: modules.game_actionbar.resetAction(1)
QtButton
id: clearBottomBar2
!text: tr('Bar 2')
width: 60
height: 18
anchors.right: parent.right
anchors.top: parent.top
margin-right: 65
margin-top: 3
@onClick: modules.game_actionbar.resetAction(2)
QtButton
id: clearBottomBar3
!text: tr('Bar 3')
width: 60
height: 18
anchors.right: parent.right
anchors.top: parent.top
margin-right: 0
margin-top: 3
@onClick: modules.game_actionbar.resetAction(3)
Label
!text: tr('Clear Left Action Bars:')
anchors.left: parent.left
anchors.top: clearBottomBar1.bottom
margin-left: 10
margin-top: 5
color: #c0c0c0ff
QtButton
id: clearLeftBar1
!text: tr('Bar 1')
width: 60
height: 18
anchors.right: parent.right
anchors.top: clearBottomBar1.bottom
margin-right: 130
margin-top: 3
@onClick: modules.game_actionbar.resetAction(4)
QtButton
id: clearLeftBar2
!text: tr('Bar 2')
width: 60
height: 18
anchors.right: parent.right
anchors.top: clearBottomBar2.bottom
margin-right: 65
margin-top: 3
@onClick: modules.game_actionbar.resetAction(5)
QtButton
id: clearLeftBar3
!text: tr('Bar 3')
width: 60
height: 18
anchors.right: parent.right
anchors.top: clearBottomBar3.bottom
margin-right: 0
margin-top: 3
@onClick: modules.game_actionbar.resetAction(6)
Label
!text: tr('Clear Right Action Bars:')
anchors.left: parent.left
anchors.top: clearLeftBar1.bottom
margin-left: 10
margin-top: 5
color: #c0c0c0ff
QtButton
id: clearRightBar1
!text: tr('Bar 1')
width: 60
height: 18
anchors.right: parent.right
anchors.top: clearLeftBar1.bottom
margin-right: 130
margin-top: 3
@onClick: modules.game_actionbar.resetAction(7)
QtButton
id: clearRightBar2
!text: tr('Bar 2')
width: 60
height: 18
anchors.right: parent.right
anchors.top: clearLeftBar2.bottom
margin-right: 65
margin-top: 3
@onClick: modules.game_actionbar.resetAction(8)
QtButton
id: clearRightBar3
!text: tr('Bar 3')
width: 60
height: 18
anchors.right: parent.right
anchors.top: clearLeftBar3.bottom
margin-right: 0
margin-top: 3
@onClick: modules.game_actionbar.resetAction(7)
QtButton
id: clearRightBar3
!text: tr('Bar 3')
!text: tr('reset')
width: 60
height: 18
anchors.right: parent.right
anchors.top: clearLeftBar3.bottom
margin-right: 0
margin-top: 3
@onClick: modules.game_actionbar.resetAction(7)
anchors.top: prev.bottom
margin-top: 12
@onClick: modules.game_actionbar.resetActionBars()
QtButton
id: clearRightBar3
!text: tr('reset')
width: 60
height: 18
anchors.right: parent.right
VerticalScrollBar
id: actionBarsScrollBar
anchors.top: parent.top
anchors.bottom: parent.bottom
margin-top: 3
@onClick: modules.game_actionbar.resetActionBars()
anchors.right: parent.right
step: 14
pixels-scroll: true
$!mobile:
visible: false

View file

@ -1,148 +1,168 @@
UIWidget
anchors.fill: parent
visible: false
QtButton
id: reset
text: "Reset"
anchors.right: parent.right
anchors.bottom: parent.bottom
@onClick: reset()
Panel
id: panelDisplayedButtons
UIScrollArea
id: optionControlButtonsScrollArea
anchors.left: parent.left
anchors.right: parent.right
anchors.right: optionControlButtonsScrollBar.left
anchors.top: parent.top
size: 502 248
border-width-top: 1
border-color-top: black
border-width-left: 1
border-color-left: black
border-width-bottom: 1
border-color-bottom: #747474
border-width-right: 1
border-color-right: #747474
Label
id: displayedButtonsLabel
!text: tr('Displayed Buttons')
anchors.top: parent.top
anchors.left: parent.left
margin-top: 5
margin-left: 10
color: #C0C0C0
TextList
id: displayedButtonsList
anchors.top: displayedButtonsLabel.bottom
anchors.left: parent.left
anchors.right: parent.right
height: 200
margin-top: 5
margin-left: 10
margin-right: 35
vertical-scrollbar: displayedButtonsScrollBar
background-color: #404040
VerticalQtScrollBar
id: displayedButtonsScrollBar
anchors.top: displayedButtonsList.top
anchors.bottom: displayedButtonsList.bottom
anchors.right: displayedButtonsList.right
step: 14
pixels-scroll: true
UIButton
id: moveToDisplayedAvailableButtonsList
anchors.top: displayedButtonsList.top
anchors.right: parent.right
margin-right: 10
image-source: /images/ui/buttons/button-clear-18x18-up
image-clip: 0 0 20 20
width: 20
@onClick: moveToAvailable()
$pressed:
image-source: /images/ui/buttons/button-clear-18x18-down
UIButton
id: reordenUp
anchors.top: prev.bottom
anchors.right: parent.right
margin-right: 10
margin-top: 5
image-source: /images/ui/buttons/automap-button-moveup-up
image-clip: 0 0 20 20
width: 20
@onClick: moveButtonUp()
$pressed:
image-source: /images/ui/buttons/automap-button-moveup-down
UIButton
id: reordenDown
anchors.top: prev.bottom
anchors.right: parent.right
margin-right: 10
margin-top: 5
image-source: /images/ui/buttons/automap-button-movedown-up
image-clip: 0 0 20 20
width: 20
@onClick: moveButtonDown()
$pressed:
image-source: /images/ui/buttons/automap-button-movedown-down
Panel
id: panelAvailableButtons
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
size: 508 100
margin-top: 10
border-width-top: 1
border-color-top: black
border-width-left: 1
border-color-left: black
border-width-bottom: 1
border-color-bottom: #747474
border-width-right: 1
border-color-right: #747474
Label
id: displayedButtonsLabel
!text: tr('Available Buttons')
anchors.top: parent.top
anchors.left: parent.left
margin-top: 5
margin-left: 10
color: #C0C0C0
TextList
id: displayedAvailableButtonsList
anchors.top: displayedButtonsLabel.bottom
anchors.left: parent.left
anchors.right: parent.right
height: 74
margin-top: 5
margin-left: 10
margin-right: 35
vertical-scrollbar: displayedButtonsScrollBar
background-color: #404040
VerticalQtScrollBar
id: displayedButtonsScrollBar
anchors.top: prev.top
anchors.bottom: prev.bottom
anchors.right: prev.right
step: 14
pixels-scroll: true
UIButton
id: moveToDisplayedButtonsList
anchors.top: prev.top
anchors.right: parent.right
margin-right: 10
image-source: /images/options/button_control
width: 20
@onClick: moveToDisplayed()
image-clip: 0 0 20 20
image-border: 3
$pressed:
image-clip: 20 0 20 20
anchors.bottom: parent.bottom
vertical-scrollbar: optionControlButtonsScrollBar
$on:
image-clip: 20 0 20 20
Panel
id: panelDisplayedButtons
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
size: 502 248
border-width-top: 1
border-color-top: black
border-width-left: 1
border-color-left: black
border-width-bottom: 1
border-color-bottom: #747474
border-width-right: 1
border-color-right: #747474
Label
id: displayedButtonsLabel
!text: tr('Displayed Buttons')
anchors.top: parent.top
anchors.left: parent.left
margin-top: 5
margin-left: 10
color: #C0C0C0
TextList
id: displayedButtonsList
anchors.top: displayedButtonsLabel.bottom
anchors.left: parent.left
anchors.right: parent.right
height: 200
margin-top: 5
margin-left: 10
margin-right: 35
vertical-scrollbar: displayedButtonsScrollBar
background-color: #404040
VerticalQtScrollBar
id: displayedButtonsScrollBar
anchors.top: displayedButtonsList.top
anchors.bottom: displayedButtonsList.bottom
anchors.right: displayedButtonsList.right
step: 14
pixels-scroll: true
UIButton
id: moveToDisplayedAvailableButtonsList
anchors.top: displayedButtonsList.top
anchors.right: parent.right
margin-right: 10
image-source: /images/ui/buttons/button-clear-18x18-up
image-clip: 0 0 20 20
width: 20
@onClick: moveToAvailable()
$pressed:
image-source: /images/ui/buttons/button-clear-18x18-down
UIButton
id: reordenUp
anchors.top: prev.bottom
anchors.right: parent.right
margin-right: 10
margin-top: 5
image-source: /images/ui/buttons/automap-button-moveup-up
image-clip: 0 0 20 20
width: 20
@onClick: moveButtonUp()
$pressed:
image-source: /images/ui/buttons/automap-button-moveup-down
UIButton
id: reordenDown
anchors.top: prev.bottom
anchors.right: parent.right
margin-right: 10
margin-top: 5
image-source: /images/ui/buttons/automap-button-movedown-up
image-clip: 0 0 20 20
width: 20
@onClick: moveButtonDown()
$pressed:
image-source: /images/ui/buttons/automap-button-movedown-down
Panel
id: panelAvailableButtons
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
size: 508 100
margin-top: 10
border-width-top: 1
border-color-top: black
border-width-left: 1
border-color-left: black
border-width-bottom: 1
border-color-bottom: #747474
border-width-right: 1
border-color-right: #747474
Label
id: displayedButtonsLabel
!text: tr('Available Buttons')
anchors.top: parent.top
anchors.left: parent.left
margin-top: 5
margin-left: 10
color: #C0C0C0
TextList
id: displayedAvailableButtonsList
anchors.top: displayedButtonsLabel.bottom
anchors.left: parent.left
anchors.right: parent.right
height: 74
margin-top: 5
margin-left: 10
margin-right: 35
vertical-scrollbar: displayedButtonsScrollBar
background-color: #404040
VerticalQtScrollBar
id: displayedButtonsScrollBar
anchors.top: prev.top
anchors.bottom: prev.bottom
anchors.right: prev.right
step: 14
pixels-scroll: true
UIButton
id: moveToDisplayedButtonsList
anchors.top: prev.top
anchors.right: parent.right
margin-right: 10
image-source: /images/options/button_control
width: 20
@onClick: moveToDisplayed()
image-clip: 0 0 20 20
image-border: 3
$pressed:
image-clip: 20 0 20 20
$on:
image-clip: 20 0 20 20
QtButton
id: reset
text: "Reset"
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 10
@onClick: reset()
VerticalScrollBar
id: optionControlButtonsScrollBar
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
step: 14
pixels-scroll: true
$!mobile:
visible: false