Compare commits
31 Commits
master
...
font_from_
Author | SHA1 | Date | |
---|---|---|---|
5356e59088 | |||
2189c4c3cb | |||
4b99da5e4e | |||
16dc9e4071 | |||
faad603d88 | |||
41c83619b5 | |||
727f33ae82 | |||
ea83589a82 | |||
1111a11577 | |||
9b163e00d9 | |||
183277250f | |||
6b96be7a57 | |||
a2001b34ea | |||
85b5c9200a | |||
8ab503840a | |||
5a2a30ada6 | |||
64959270a9 | |||
9d6404d130 | |||
ef4e0d0857 | |||
56f1bf559c | |||
b0e25627b3 | |||
e7b1eec2cc | |||
7a2d7336fb | |||
fc5023ec1c | |||
95eb0eb26d | |||
d7e658eba6 | |||
04191858de | |||
df449a475c | |||
9a95dba138 | |||
ef79aa8b80 | |||
ba7188cf66 |
88
.github/workflows/cd.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Dependencies
|
||||
run: sudo apt update && sudo apt -y install libsodium-dev
|
||||
run: sudo apt update && sudo apt -y install libsodium-dev cmake
|
||||
|
||||
- name: Configure CMake
|
||||
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
|
||||
@ -50,12 +50,91 @@ jobs:
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
# TODO: simpler name?
|
||||
name: ${{ github.event.repository.name }}-${{ steps.tag.outputs.name }}-${{ runner.os }}-ubuntu20.04-x86_64
|
||||
# TODO: do propper packing
|
||||
path: |
|
||||
${{github.workspace}}/${{ github.event.repository.name }}-${{ steps.tag.outputs.name }}-${{ runner.os }}-ubuntu20.04-x86_64.tar.gz
|
||||
|
||||
android:
|
||||
timeout-minutes: 30
|
||||
# contains sections copied from sdl repo
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
platform:
|
||||
- vcpkg_toolkit: arm64-android
|
||||
ndk_abi: arm64-v8a
|
||||
- vcpkg_toolkit: x64-android
|
||||
ndk_abi: x86_64
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- uses: nttld/setup-ndk@v1
|
||||
id: setup_ndk
|
||||
with:
|
||||
local-cache: false # https://github.com/nttld/setup-ndk/issues/518
|
||||
ndk-version: r26d
|
||||
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
|
||||
- name: update vcpkg
|
||||
run: |
|
||||
git clone https://github.com/microsoft/vcpkg.git
|
||||
|
||||
- name: Install Dependencies (host)
|
||||
run: sudo apt update && sudo apt -y install cmake pkg-config nasm
|
||||
|
||||
- name: Install Dependencies (target)
|
||||
env:
|
||||
ANDROID_NDK_HOME: ${{steps.setup_ndk.outputs.ndk-path}}
|
||||
run: vcpkg install --triplet ${{matrix.platform.vcpkg_toolkit}} --overlay-ports=vcpkg/ports libsodium opus libvpx libpng libjpeg-turbo
|
||||
|
||||
# vcpkg scripts root /usr/local/share/vcpkg/scripts
|
||||
- name: Configure CMake
|
||||
env:
|
||||
ANDROID_NDK_HOME: ${{steps.setup_ndk.outputs.ndk-path}}
|
||||
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=${{matrix.platform.vcpkg_toolkit}} -DANDROID=1 -DANDROID_PLATFORM=23 -DANDROID_ABI=${{matrix.platform.ndk_abi}} -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=${{steps.setup_ndk.outputs.ndk-path}}/build/cmake/android.toolchain.cmake -DSDL3IMAGE_JPG_SHARED=OFF -DSDL3IMAGE_PNG_SHARED=OFF -DTOMATO_MAIN_SO=ON
|
||||
|
||||
- name: Build (tomato)
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato
|
||||
|
||||
- name: Build (SDL3-jar) (workaround)
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t SDL3-jar
|
||||
|
||||
- name: Build (apk)
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato-apk
|
||||
|
||||
- name: Determine tag name
|
||||
id: tag
|
||||
shell: bash
|
||||
# taken from llama.cpp
|
||||
run: |
|
||||
SHORT_HASH="$(git rev-parse --short=7 HEAD)"
|
||||
if [[ "${{ env.BRANCH_NAME }}" == "master" ]]; then
|
||||
echo "name=dev-${SHORT_HASH}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
SAFE_NAME=$(echo "${{ env.BRANCH_NAME }}" | tr '/' '-')
|
||||
echo "name=dev-${SAFE_NAME}-${SHORT_HASH}" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: rename apk
|
||||
id: rename_apk
|
||||
shell: bash
|
||||
run: mv "${{github.workspace}}/build/android/tomato.apk" "${{github.workspace}}/build/android/${{github.event.repository.name}}-${{steps.tag.outputs.name}}-Android-${{matrix.platform.ndk_abi}}.apk"
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{github.event.repository.name}}-${{steps.tag.outputs.name}}-${{runner.os}}-Android-${{matrix.platform.ndk_abi}}
|
||||
path: |
|
||||
${{github.workspace}}/build/android/${{github.event.repository.name}}-${{steps.tag.outputs.name}}-Android-${{matrix.platform.ndk_abi}}.apk
|
||||
|
||||
windows:
|
||||
timeout-minutes: 15
|
||||
@ -110,8 +189,7 @@ jobs:
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
# TODO: simpler name?
|
||||
name: ${{ github.event.repository.name }}-${{ steps.tag.outputs.name }}-${{ runner.os }}-msvc-x86_64
|
||||
name: ${{github.event.repository.name}}-${{steps.tag.outputs.name}}-${{runner.os}}-msvc-x86_64
|
||||
# TODO: do propper packing
|
||||
path: |
|
||||
${{github.workspace}}/${{ github.event.repository.name }}-${{ steps.tag.outputs.name }}-${{ runner.os }}-msvc-x86_64.zip
|
||||
@ -170,7 +248,6 @@ jobs:
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
# TODO: simpler name?
|
||||
name: ${{ github.event.repository.name }}-${{ steps.tag.outputs.name }}-${{ runner.os }}-msvc-asan-x86_64
|
||||
# TODO: do propper packing
|
||||
path: |
|
||||
@ -183,6 +260,7 @@ jobs:
|
||||
|
||||
needs:
|
||||
- linux-ubuntu
|
||||
- android
|
||||
- windows
|
||||
- windows-asan
|
||||
|
||||
|
66
.github/workflows/ci.yml
vendored
@ -21,7 +21,7 @@ jobs:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Dependencies
|
||||
run: sudo apt update && sudo apt -y install libsodium-dev
|
||||
run: sudo apt update && sudo apt -y install libsodium-dev cmake
|
||||
|
||||
- name: Configure CMake
|
||||
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
|
||||
@ -29,6 +29,70 @@ jobs:
|
||||
- name: Build
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato
|
||||
|
||||
android:
|
||||
timeout-minutes: 30
|
||||
# contains sections copied from sdl repo
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
platform:
|
||||
- vcpkg_toolkit: arm64-android
|
||||
ndk_abi: arm64-v8a
|
||||
- vcpkg_toolkit: x64-android
|
||||
ndk_abi: x86_64
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- uses: nttld/setup-ndk@v1
|
||||
id: setup_ndk
|
||||
with:
|
||||
local-cache: false # https://github.com/nttld/setup-ndk/issues/518
|
||||
ndk-version: r26d
|
||||
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
|
||||
- name: update vcpkg
|
||||
run: |
|
||||
git clone https://github.com/microsoft/vcpkg.git
|
||||
|
||||
- name: Install Dependencies (host)
|
||||
run: sudo apt update && sudo apt -y install cmake pkg-config nasm
|
||||
|
||||
- name: Install Dependencies (target)
|
||||
env:
|
||||
ANDROID_NDK_HOME: ${{steps.setup_ndk.outputs.ndk-path}}
|
||||
run: vcpkg install --triplet ${{matrix.platform.vcpkg_toolkit}} --overlay-ports=vcpkg/ports libsodium opus libvpx libpng libjpeg-turbo
|
||||
|
||||
# vcpkg scripts root /usr/local/share/vcpkg/scripts
|
||||
- name: Configure CMake
|
||||
env:
|
||||
ANDROID_NDK_HOME: ${{steps.setup_ndk.outputs.ndk-path}}
|
||||
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=${{matrix.platform.vcpkg_toolkit}} -DANDROID=1 -DANDROID_PLATFORM=23 -DANDROID_ABI=${{matrix.platform.ndk_abi}} -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=${{steps.setup_ndk.outputs.ndk-path}}/build/cmake/android.toolchain.cmake -DSDL3IMAGE_JPG_SHARED=OFF -DSDL3IMAGE_PNG_SHARED=OFF -DTOMATO_MAIN_SO=ON
|
||||
|
||||
- name: Build (tomato)
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato
|
||||
|
||||
- name: Build (SDL3-jar) (workaround)
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t SDL3-jar
|
||||
|
||||
- name: Build (apk)
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato-apk
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ github.event.repository.name }}-${{matrix.platform.vcpkg_toolkit}}
|
||||
# TODO: do propper packing
|
||||
path: |
|
||||
${{github.workspace}}/build/android/tomato.apk
|
||||
|
||||
macos:
|
||||
timeout-minutes: 10
|
||||
|
||||
|
@ -18,6 +18,7 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
||||
|
||||
option(TOMATO_MAIN_SO "Build tomato as a shared object (for eg android apps)" ANDROID)
|
||||
option(TOMATO_ASAN "Build tomato with asan (gcc/clang/msvc)" OFF)
|
||||
|
||||
if (TOMATO_ASAN)
|
||||
@ -43,7 +44,7 @@ endif()
|
||||
add_compile_definitions(ENTT_API_EXPORT)
|
||||
|
||||
# external libs
|
||||
add_subdirectory(./external) # before increasing warn levels, sad :(
|
||||
add_subdirectory(./external EXCLUDE_FROM_ALL) # before increasing warn levels, sad :(
|
||||
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
@ -69,3 +70,10 @@ endif()
|
||||
|
||||
add_subdirectory(./src)
|
||||
|
||||
# TODO: move to src
|
||||
if (ANDROID AND TARGET SDL3::Jar)
|
||||
message("II building for ANDROID!!!")
|
||||
|
||||
add_subdirectory(android)
|
||||
endif()
|
||||
|
||||
|
100
android/CMakeLists.txt
Normal file
@ -0,0 +1,100 @@
|
||||
cmake_minimum_required(VERSION 3.14...3.24 FATAL_ERROR)
|
||||
|
||||
project(tomato_android)
|
||||
|
||||
# here be dragons
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${SDL3_SOURCE_DIR}/cmake/android")
|
||||
|
||||
find_package(SdlAndroid MODULE)
|
||||
find_package(Java)
|
||||
find_package(SdlAndroidPlatform MODULE)
|
||||
# the existence of SDL3::Jar usually implies platform
|
||||
if(SdlAndroid_FOUND)
|
||||
include(SdlAndroidFunctions)
|
||||
sdl_create_android_debug_keystore(tomato-debug-keystore)
|
||||
sdl_android_compile_resources(tomato-resources RESFOLDER app/res)
|
||||
|
||||
|
||||
set(ANDROID_MANIFEST_PACKAGE "org.libsdl.app.tomato")
|
||||
#set(generated_manifest_path "${CMAKE_CURRENT_BINARY_DIR}/android/${TEST}-src/AndroidManifest.xml")
|
||||
string(REPLACE "." "/" JAVA_PACKAGE_DIR "${ANDROID_MANIFEST_PACKAGE}")
|
||||
#set(GENERATED_SRC_FOLDER "${CMAKE_CURRENT_BINARY_DIR}/android/${TEST}-src")
|
||||
#set(GENERATED_RES_FOLDER "${GENERATED_SRC_FOLDER}/res")
|
||||
#set(JAVA_PACKAGE_DIR "${GENERATED_SRC_FOLDER}/${JAVA_PACKAGE_DIR}")
|
||||
set(JAVA_PACKAGE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/app/java/${JAVA_PACKAGE_DIR}")
|
||||
|
||||
sdl_android_link_resources(tomato-apk-linked
|
||||
MANIFEST "app/AndroidManifest.xml"
|
||||
PACKAGE ${ANDROID_MANIFEST_PACKAGE}
|
||||
RES_TARGETS tomato-resources
|
||||
TARGET_SDK_VERSION 31
|
||||
)
|
||||
|
||||
set(CMAKE_JAVA_COMPILE_FLAGS "-encoding;utf-8")
|
||||
set(classes_path "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/tomato-java.dir/classes")
|
||||
# Some CMake versions have a slow `cmake -E make_directory` implementation
|
||||
if(NOT IS_DIRECTORY "${classes_path}")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory "${classes_path}")
|
||||
endif()
|
||||
set(OUT_JAR "${CMAKE_CURRENT_BINARY_DIR}/tomato.jar")
|
||||
# TODO: convert to cmake's add_jar
|
||||
add_custom_command(
|
||||
OUTPUT "${OUT_JAR}"
|
||||
COMMAND ${CMAKE_COMMAND} -E rm -rf "${classes_path}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${classes_path}"
|
||||
COMMAND ${Java_JAVAC_EXECUTABLE}
|
||||
-source 1.8 -target 1.8
|
||||
-bootclasspath "$<TARGET_PROPERTY:SDL3::Jar,JAR_FILE>"
|
||||
"${JAVA_PACKAGE_DIR}/TomatoActivity.java"
|
||||
$<TARGET_PROPERTY:tomato-apk-linked,JAVA_R>
|
||||
-cp "$<TARGET_PROPERTY:SDL3::Jar,JAR_FILE>:${SDL_ANDROID_PLATFORM_ANDROID_JAR}"
|
||||
-d "${classes_path}"
|
||||
COMMAND ${Java_JAR_EXECUTABLE} cf "${OUT_JAR}" -C "${classes_path}" .
|
||||
DEPENDS $<TARGET_PROPERTY:tomato-apk-linked,OUTPUTS> "$<TARGET_PROPERTY:SDL3::Jar,JAR_FILE>"
|
||||
)
|
||||
add_custom_target(tomato-jar DEPENDS "${OUT_JAR}")
|
||||
add_dependencies(tomato-jar SDL3::Jar) # HACK: somehow their jar is not registered as an output
|
||||
set_property(TARGET tomato-jar PROPERTY OUTPUT "${OUT_JAR}")
|
||||
|
||||
set(dexworkdir "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/tomato-dex.dir")
|
||||
# Some CMake versions have a slow `cmake -E make_directory` implementation
|
||||
if(NOT IS_DIRECTORY "${dexworkdir}")
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory "${dexworkdir}")
|
||||
endif()
|
||||
set(classes_dex_base_name "classes.dex")
|
||||
set(classes_dex "${dexworkdir}/${classes_dex_base_name}")
|
||||
add_custom_command(
|
||||
OUTPUT "${classes_dex}"
|
||||
COMMAND SdlAndroid::d8
|
||||
$<TARGET_PROPERTY:tomato-jar,OUTPUT>
|
||||
$<TARGET_PROPERTY:SDL3::Jar,JAR_FILE>
|
||||
--lib "${SDL_ANDROID_PLATFORM_ANDROID_JAR}"
|
||||
--output "${dexworkdir}"
|
||||
DEPENDS $<TARGET_PROPERTY:tomato-jar,OUTPUT> $<TARGET_PROPERTY:SDL3::Jar,JAR_FILE>
|
||||
)
|
||||
add_custom_target(tomato-dex DEPENDS "${classes_dex}")
|
||||
set_property(TARGET tomato-dex PROPERTY OUTPUT "${classes_dex}")
|
||||
set_property(TARGET tomato-dex PROPERTY OUTPUT_BASE_NAME "${classes_dex_base_name}")
|
||||
|
||||
# file(GLOB RESOURCE_FILES *.bmp *.wav *.hex moose.dat utf8.txt)
|
||||
|
||||
sdl_add_to_apk_unaligned(tomato-unaligned-apk
|
||||
APK_IN tomato-apk-linked
|
||||
OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/intermediates"
|
||||
#ASSETS ${RESOURCE_FILES}
|
||||
#NATIVE_LIBS SDL3::SDL3-shared tomato
|
||||
NATIVE_LIBS tomato
|
||||
DEX tomato-dex
|
||||
)
|
||||
|
||||
sdl_apk_align(tomato-aligned-apk tomato-unaligned-apk
|
||||
OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/intermediates"
|
||||
)
|
||||
sdl_apk_sign(tomato-apk tomato-aligned-apk
|
||||
KEYSTORE tomato-debug-keystore
|
||||
)
|
||||
else()
|
||||
message("EE SdlAndroid module not found")
|
||||
endif()
|
||||
|
109
android/app/AndroidManifest.xml
Normal file
@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Replace com.test.game with the identifier of your game below, e.g.
|
||||
com.gamemaker.game
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.libsdl.app.tomato"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0"
|
||||
android:installLocation="auto">
|
||||
|
||||
<!-- OpenGL ES 2.0 -->
|
||||
<uses-feature android:glEsVersion="0x00020000" />
|
||||
|
||||
<!-- Touchscreen support -->
|
||||
<uses-feature
|
||||
android:name="android.hardware.touchscreen"
|
||||
android:required="false" />
|
||||
|
||||
<!-- Game controller support -->
|
||||
<uses-feature
|
||||
android:name="android.hardware.bluetooth"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.gamepad"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.usb.host"
|
||||
android:required="false" />
|
||||
|
||||
<!-- External mouse input events -->
|
||||
<uses-feature
|
||||
android:name="android.hardware.type.pc"
|
||||
android:required="false" />
|
||||
|
||||
<!-- Audio recording support -->
|
||||
<!-- if you want to capture audio, uncomment this. -->
|
||||
<!-- <uses-feature
|
||||
android:name="android.hardware.microphone"
|
||||
android:required="false" /> -->
|
||||
|
||||
<!-- Camera support -->
|
||||
<!-- if you want to record video, uncomment this. -->
|
||||
<!--
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-feature android:name="android.hardware.camera" />
|
||||
-->
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<!-- Allow downloading to the external storage on Android 5.1 and older -->
|
||||
<!-- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="22" /> -->
|
||||
|
||||
<!-- Allow access to Bluetooth devices -->
|
||||
<!-- Currently this is just for Steam Controller support and requires setting SDL_HINT_JOYSTICK_HIDAPI_STEAM -->
|
||||
<!-- <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> -->
|
||||
<!-- <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> -->
|
||||
|
||||
<!-- Allow access to the vibrator -->
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
|
||||
<!-- if you want to capture audio, uncomment this. -->
|
||||
<!-- <uses-permission android:name="android.permission.RECORD_AUDIO" /> -->
|
||||
|
||||
<!-- Create a Java class extending SDLActivity and place it in a
|
||||
directory under app/src/main/java matching the package, e.g. app/src/main/java/com/gamemaker/game/MyGame.java
|
||||
|
||||
then replace "SDLActivity" with the name of your class (e.g. "MyGame")
|
||||
in the XML below.
|
||||
|
||||
An example Java class can be found in README-android.md
|
||||
-->
|
||||
<application android:label="@string/app_name"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:appCategory="social"
|
||||
android:allowBackup="true"
|
||||
android:theme="@style/AppTheme"
|
||||
android:hardwareAccelerated="true" >
|
||||
|
||||
<!-- setting sdl hints. uses the string value -->
|
||||
<meta-data android:name="SDL_ENV.SDL_ANDROID_BLOCK_ON_PAUSE" android:value="0"/>
|
||||
|
||||
<activity android:name="TomatoActivity"
|
||||
android:label="@string/app_name"
|
||||
android:alwaysRetainTaskState="true"
|
||||
android:launchMode="singleInstance"
|
||||
android:configChanges="layoutDirection|locale|orientation|uiMode|screenLayout|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
|
||||
android:preferMinimalPostProcessing="true"
|
||||
android:exported="true"
|
||||
>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<!-- Let Android know that we can handle some USB devices and should receive this event -->
|
||||
<intent-filter>
|
||||
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
|
||||
</intent-filter>
|
||||
<!-- Drop file event -->
|
||||
<!--
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="*/*" />
|
||||
</intent-filter>
|
||||
-->
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
18
android/app/java/org/libsdl/app/tomato/TomatoActivity.java
Normal file
@ -0,0 +1,18 @@
|
||||
package org.libsdl.app.tomato;
|
||||
|
||||
import org.libsdl.app.SDLActivity;
|
||||
|
||||
public class TomatoActivity extends SDLActivity {
|
||||
protected String[] getLibraries() {
|
||||
return new String[] {
|
||||
// "SDL3", // we link statically
|
||||
// "SDL3_image",
|
||||
// "SDL3_mixer",
|
||||
// "SDL3_net",
|
||||
// "SDL3_ttf",
|
||||
// "main"
|
||||
"tomato"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
BIN
android/app/play_store_512.png
Normal file
After Width: | Height: | Size: 94 KiB |
6
android/app/res/mipmap-anydpi-v26/ic_launcher.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
<monochrome android:drawable="@mipmap/ic_launcher_monochrome"/>
|
||||
</adaptive-icon>
|
BIN
android/app/res/mipmap-hdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
android/app/res/mipmap-hdpi/ic_launcher_background.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
android/app/res/mipmap-hdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
android/app/res/mipmap-hdpi/ic_launcher_monochrome.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
android/app/res/mipmap-mdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
android/app/res/mipmap-mdpi/ic_launcher_background.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
android/app/res/mipmap-mdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
android/app/res/mipmap-mdpi/ic_launcher_monochrome.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
android/app/res/mipmap-xhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 9.7 KiB |
BIN
android/app/res/mipmap-xhdpi/ic_launcher_background.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
android/app/res/mipmap-xhdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
BIN
android/app/res/mipmap-xhdpi/ic_launcher_monochrome.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
android/app/res/mipmap-xxhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
android/app/res/mipmap-xxhdpi/ic_launcher_background.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
android/app/res/mipmap-xxhdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
android/app/res/mipmap-xxhdpi/ic_launcher_monochrome.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
android/app/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
android/app/res/mipmap-xxxhdpi/ic_launcher_background.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
android/app/res/mipmap-xxxhdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
android/app/res/mipmap-xxxhdpi/ic_launcher_monochrome.png
Normal file
After Width: | Height: | Size: 15 KiB |
6
android/app/res/values/colors.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#3F51B5</color>
|
||||
<color name="colorPrimaryDark">#303F9F</color>
|
||||
<color name="colorAccent">#FF4081</color>
|
||||
</resources>
|
3
android/app/res/values/strings.xml
Normal file
@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">Tomato</string>
|
||||
</resources>
|
10
android/app/res/values/styles.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<!-- <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar"> -->
|
||||
<!--<style name="AppTheme" parent="android:Theme.AppCompat">-->
|
||||
<style name="AppTheme" parent="android:Theme">
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
|
||||
</resources>
|
2
external/CMakeLists.txt
vendored
@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.14...3.24 FATAL_ERROR)
|
||||
|
||||
add_subdirectory(./entt)
|
||||
|
||||
add_subdirectory(./json)
|
||||
|
||||
add_subdirectory(./solanaceae_util)
|
||||
add_subdirectory(./solanaceae_contact)
|
||||
add_subdirectory(./solanaceae_message3)
|
||||
|
1
external/imgui/CMakeLists.txt
vendored
@ -18,6 +18,7 @@ add_library(imgui
|
||||
imgui/misc/cpp/imgui_stdlib.cpp
|
||||
)
|
||||
|
||||
target_compile_definitions(imgui PUBLIC IMGUI_USE_WCHAR32)
|
||||
target_compile_features(imgui PUBLIC cxx_std_11)
|
||||
|
||||
target_include_directories(imgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
2
external/imgui/imgui/.github/FUNDING.yml
vendored
@ -1 +1 @@
|
||||
custom: ['https://github.com/ocornut/imgui/wiki/Sponsors']
|
||||
custom: ['https://github.com/ocornut/imgui/wiki/Funding']
|
||||
|
@ -413,15 +413,15 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
||||
bd->WantUpdateGamepadsList = true;
|
||||
|
||||
// Load mouse cursors
|
||||
bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
|
||||
bd->MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE);
|
||||
bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
|
||||
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
|
||||
bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT);
|
||||
bd->MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_TEXT);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_MOVE);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NS_RESIZE);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_EW_RESIZE);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NESW_RESIZE);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NWSE_RESIZE);
|
||||
bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_POINTER);
|
||||
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NOT_ALLOWED);
|
||||
|
||||
// Set platform dependent data in viewport
|
||||
// Our mouse update function expect PlatformHandle to be filled for the main viewport
|
||||
|
44
external/imgui/imgui/docs/CHANGELOG.txt
vendored
@ -35,6 +35,50 @@ HOW TO UPDATE?
|
||||
and API updates have been a little more frequent lately. They are documented below and in imgui.cpp and should not affect all users.
|
||||
- Please report any issue!
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.90.8 (Released 2024-06-06)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.90.8
|
||||
|
||||
Breaking changes:
|
||||
|
||||
- Reordered various ImGuiInputTextFlags values. This should NOT be breaking unless
|
||||
you are using generated headers that have values not matching the main library.
|
||||
- Removed ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft
|
||||
from imgui.h, was mostly unused and misleading.
|
||||
|
||||
Other changes:
|
||||
|
||||
- Inputs: fixed IsMouseClicked(..., repeat=true); broken in 1.90.7 on 2024/05/22.
|
||||
(due to an internal api parameter swap, repeat wouldn't be honored and
|
||||
ownership would be accidentally checked even though this api is meant to not
|
||||
check ownership). (#7657) [@korenkonder]
|
||||
- Windows: fixed altering FramePadding mid-frame not correctly affecting logic
|
||||
responsible for honoring io.ConfigWindowsMoveFromTitleBarOnly. (#7576, #899)
|
||||
- Scrollbar: made scrolling logic more standard: clicking above or below the
|
||||
grab scrolls by one page, holding mouse button repeats scrolling. (#7328, #150)
|
||||
- Scrollbar: fixed miscalculation of vertical scrollbar visibility when required
|
||||
solely by the presence of an horizontal scrollbar. (#1574)
|
||||
- InputScalar, InputInt, InputFloat: added ImGuiInputTextFlags_ParseEmptyRefVal
|
||||
to parse an empty field as zero-value. (#7305) [@supermerill, @ocornut]
|
||||
- InputScalar, InputInt, InputFloat: added ImGuiInputTextFlags_DisplayEmptyRefVal
|
||||
to display a zero-value as empty. (#7305) [@supermerill, @ocornut]
|
||||
- Popups: fixed an issue preventing to close a popup opened over a modal by clicking
|
||||
over void (it required clicking over the visible part of the modal). (#7654)
|
||||
- Tables: fixed an issue where ideal size reported to parent container wouldn't
|
||||
correctly take account of inner scrollbar, affecting potential auto-resize of
|
||||
parent container. (#7651)
|
||||
- Tables: fixed a bug where after disabling the ScrollY flag for a table,
|
||||
previous scrollbar width would be accounted for. (#5920)
|
||||
- Combo: simplified Combo() API uses a list clipper (due to its api it wasn't
|
||||
previously trivial before we added clipper.IncludeItemByIndex() function).
|
||||
- Disabled: nested tooltips or other non-child window within a BeginDisabled()
|
||||
block disable the disabled state. (#211, #7640)
|
||||
- Misc: made ImGuiDir and ImGuiSortDirection stronger-typed enums.
|
||||
- Backends: SDL3: Update for SDL_SYSTEM_CURSOR_xxx api renames. (#7653)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.90.7 (Released 2024-05-27)
|
||||
-----------------------------------------------------------------------
|
||||
|
2
external/imgui/imgui/docs/README.md
vendored
@ -162,7 +162,7 @@ See: [Upcoming Changes](https://github.com/ocornut/imgui/wiki/Upcoming-Changes).
|
||||
|
||||
See: [Dear ImGui Test Engine + Test Suite](https://github.com/ocornut/imgui_test_engine) for Automation & Testing.
|
||||
|
||||
For the purposes of getting search engines to crawl the wiki, here's a link to the [Crawable Wiki](https://github-wiki-see.page/m/ocornut/imgui/wiki) (not for humans, [here's why](https://github-wiki-see.page/)).
|
||||
For the purposes of getting search engines to crawl the wiki, here's a link to the [Crawlable Wiki](https://github-wiki-see.page/m/ocornut/imgui/wiki) (not for humans, [here's why](https://github-wiki-see.page/)).
|
||||
|
||||
Getting started? For first-time users having issues compiling/linking/running or issues loading fonts, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions). For ANY other questions, bug reports, requests, feedback, please post on [GitHub Issues](https://github.com/ocornut/imgui/issues). Please read and fill the New Issue template carefully.
|
||||
|
||||
|
16
external/imgui/imgui/docs/TODO.txt
vendored
@ -39,7 +39,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- scrolling: forward mouse wheel scrolling to parent window when at the edge of scrolling limits? (useful for listbox,tables?)
|
||||
- scrolling/style: shadows on scrollable areas to denote that there is more contents (see e.g. DaVinci Resolve ui)
|
||||
|
||||
- drawdata: make it easy to deep-copy (or swap?) a full ImDrawData so user can easily save that data if they use threaded rendering. (e.g. #2646)
|
||||
- drawdata: make it easy to deep-copy (or swap?) a full ImDrawData so user can easily save that data if they use threaded rendering. (#1860 see ImDrawDataSnapshot)
|
||||
! drawlist: add CalcTextSize() func to facilitate consistent code from user pov (currently need to use ImGui or ImFont alternatives!)
|
||||
- drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). (WIP branch)
|
||||
- drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally
|
||||
@ -117,7 +117,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
!- color: the color conversion helpers/types are a mess and needs sorting out.
|
||||
- color: (api breaking) ImGui::ColorConvertXXX functions should be loose ImColorConvertXX to match imgui_internals.h
|
||||
|
||||
- plot: full featured plot/graph api w/ scrolling, zooming etc. --> ImPlot
|
||||
- plot: full featured plot/graph api w/ scrolling, zooming etc. --> promote using ImPlot
|
||||
- (plot: deleted all other todo lines on 2023-06-28)
|
||||
|
||||
- clipper: ability to disable the clipping through a simple flag/bool.
|
||||
@ -150,7 +150,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- drag float: power != 0.0f with current value being outside the range keeps the value stuck.
|
||||
- drag float: added leeway on edge (e.g. a few invisible steps past the clamp limits)
|
||||
|
||||
- combo: use clipper.
|
||||
- combo: a way/helper to customize the combo preview (#1658) -> experimental BeginComboPreview()
|
||||
- combo/listbox: keyboard control. need InputText-like non-active focus + key handling. considering keyboard for custom listbox (pr #203)
|
||||
- listbox: multiple selection (WIP range-select branch)
|
||||
@ -173,15 +172,14 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- tooltip: drag and drop with tooltip near monitor edges lose/changes its last direction instead of locking one. The drag and drop tooltip should always follow without changing direction.
|
||||
- tooltip: allow to set the width of a tooltip to allow TextWrapped() etc. while keeping the height automatic.
|
||||
- tooltip: drag tooltip hovering over source widget with IsItemHovered/SetTooltip flickers (WIP branch)
|
||||
- tooltip: tooltip priorities to override a stock tooltip (e.g. shortcut tooltip)
|
||||
|
||||
- status-bar: add a per-window status bar helper similar to what menu-bar does. generalize concept of layer0 rect in window (can make _MenuBar window flag obsolete too).
|
||||
- shortcuts: store multiple keychords in ImGuiKeyChord
|
||||
- shortcuts: Hovered route (lower than Focused, higher than Global)
|
||||
- shortcuts: local-style shortcut api, e.g. parse "&Save"
|
||||
- shortcuts,menus: global-style shortcut api e.g. "Save (CTRL+S)" -> explicit flag for recursing into closed menu
|
||||
- shortcuts: programmatically access shortcuts "Focus("&Save"))
|
||||
- menus: menu-bar: main menu-bar could affect clamping of windows position (~ akin to modifying DisplayMin)
|
||||
- menus: hovering from menu to menu on a menu-bar has 1 frame without any menu, which is a little annoying. ideally either 0 either longer.
|
||||
- menus: hovering from menu to menu on a menu-bar has 1 frame without any menu, which is a little annoying. ideally zero.
|
||||
- menus: would be nice if the Selectable() supported horizontal alignment (must be given the equivalent of WorkRect.Max.x matching the position of the shortcut column)
|
||||
|
||||
- tree node: add treenode/treepush int variants? not there because (void*) cast from int warns on some platforms/settings?
|
||||
@ -277,7 +275,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- font/opt: Considering storing standalone AdvanceX table as 16-bit fixed point integer?
|
||||
- font/opt: Glyph currently 40 bytes (2+9*4). Consider storing UV as 16-bits integer? (->32 bytes). X0/Y0/X1/Y1 as 16 fixed-point integers? Or X0/Y0 as float and X1/Y1 as fixed8_8?
|
||||
|
||||
- nav: visual feedback on button press.
|
||||
- nav: some features such as PageUp/Down/Home/End should probably work without ImGuiConfigFlags_NavEnableKeyboard? (where do we draw the line? how about CTRL+Tab)
|
||||
! nav: never clear NavId on some setup (e.g. gamepad centric)
|
||||
- nav: there's currently no way to completely clear focus with the keyboard. depending on patterns used by the application to dispatch inputs, it may be desirable.
|
||||
@ -317,8 +314,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- misc: make the ImGuiCond values linear (non-power-of-two). internal storage for ImGuiWindow can use integers to combine into flags (Why?)
|
||||
- misc: PushItemFlag(): add a flag to disable keyboard capture when used with mouse? (#1682)
|
||||
- misc: use more size_t in public api?
|
||||
- misc: possible compile-time support for string view/range instead of char* would e.g. facilitate usage with Rust (#683, #3038, WIP string_view branch)
|
||||
- misc: possible compile-time support for wchar_t instead of char*?
|
||||
- misc: support for string view/range instead of char* would e.g. facilitate usage with Rust (#683, #3038, WIP string_view branch)
|
||||
|
||||
- demo: demonstrate using PushStyleVar() in more details.
|
||||
- demo: add vertical separator demo
|
||||
@ -338,7 +334,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- backends: bgfx: https://gist.github.com/RichardGale/6e2b74bc42b3005e08397236e4be0fd0
|
||||
- backends: emscriptem: with refactored examples, we could provide a direct imgui_impl_emscripten platform layer (see eg. https://github.com/floooh/sokol-samples/blob/master/html5/imgui-emsc.cc#L42)
|
||||
|
||||
- bindings: ways to use clang ast dump to generate bindings or helpers for bindings? (e.g. clang++ -Xclang -ast-dump=json imgui.h) (WIP project "dear-bindings" still private)
|
||||
- bindings: ways to use clang ast dump to generate bindings or helpers for bindings? (e.g. clang++ -Xclang -ast-dump=json imgui.h) (--> use https://github.com/dearimgui/dear_bindings)
|
||||
|
||||
- optimization: replace vsnprintf with stb_printf? using IMGUI_USE_STB_SPRINTF. (#1038 + needed for string_view)
|
||||
- optimization: add clipping for multi-component widgets (SliderFloatX, ColorEditX, etc.). one problem is that nav branch can't easily clip parent group when there is a move request.
|
||||
|
@ -37,9 +37,9 @@ LIBS =
|
||||
|
||||
ifeq ($(UNAME_S), Linux) #LINUX
|
||||
ECHO_MESSAGE = "Linux"
|
||||
LIBS += $(LINUX_GL_LIBS) -ldl `sdl3-config --libs`
|
||||
LIBS += $(LINUX_GL_LIBS) -ldl `pkg-config sdl3 --libs`
|
||||
|
||||
CXXFLAGS += `sdl3-config --cflags`
|
||||
CXXFLAGS += `pkg-config sdl3 --cflags`
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
endif
|
||||
|
||||
@ -48,7 +48,7 @@ ifeq ($(UNAME_S), Darwin) #APPLE
|
||||
LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo `sdl3-config --libs`
|
||||
LIBS += -L/usr/local/lib -L/opt/local/lib
|
||||
|
||||
CXXFLAGS += `sdl3-config --cflags`
|
||||
CXXFLAGS += `pkg-config sdl3 --cflags`
|
||||
CXXFLAGS += -I/usr/local/include -I/opt/local/include
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
endif
|
||||
|
@ -26,9 +26,9 @@ LIBS =
|
||||
|
||||
ifeq ($(UNAME_S), Linux) #LINUX
|
||||
ECHO_MESSAGE = "Linux"
|
||||
LIBS += -ldl `sdl3-config --libs`
|
||||
LIBS += -ldl `pkg-config sdl3 --libs`
|
||||
|
||||
CXXFLAGS += `sdl3-config --cflags`
|
||||
CXXFLAGS += `pkg-config sdl3 --cflags`
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
endif
|
||||
|
||||
@ -37,7 +37,7 @@ ifeq ($(UNAME_S), Darwin) #APPLE
|
||||
LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo `sdl3-config --libs`
|
||||
LIBS += -L/usr/local/lib -L/opt/local/lib
|
||||
|
||||
CXXFLAGS += `sdl3-config --cflags`
|
||||
CXXFLAGS += `pkg-config sdl3 --cflags`
|
||||
CXXFLAGS += -I/usr/local/include -I/opt/local/include
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
endif
|
||||
|
@ -160,7 +160,7 @@ int main(int, char**)
|
||||
// Rendering
|
||||
ImGui::Render();
|
||||
//SDL_RenderSetScale(renderer, io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
|
||||
SDL_SetRenderDrawColor(renderer, (Uint8)(clear_color.x * 255), (Uint8)(clear_color.y * 255), (Uint8)(clear_color.z * 255), (Uint8)(clear_color.w * 255));
|
||||
SDL_SetRenderDrawColorFloat(renderer, clear_color.x, clear_color.y, clear_color.z, clear_color.w);
|
||||
SDL_RenderClear(renderer);
|
||||
ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(), renderer);
|
||||
SDL_RenderPresent(renderer);
|
||||
|
216
external/imgui/imgui/imgui.cpp
vendored
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.7
|
||||
// dear imgui, v1.90.8
|
||||
// (main code and documentation)
|
||||
|
||||
// Help:
|
||||
@ -430,6 +430,8 @@ CODE
|
||||
When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
|
||||
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
|
||||
|
||||
- 2024/06/06 (1.90.8) - reordered ImGuiInputTextFlags values. This should not be breaking unless you are using generated headers that have values not matching the main library.
|
||||
- 2024/06/06 (1.90.8) - removed 'ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft', was mostly unused and misleading.
|
||||
- 2024/05/27 (1.90.7) - commented out obsolete symbols marked obsolete in 1.88 (May 2022):
|
||||
- old: CaptureKeyboardFromApp(bool)
|
||||
- new: SetNextFrameWantCaptureKeyboard(bool)
|
||||
@ -4237,7 +4239,7 @@ bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id)
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (!bb.Overlaps(window->ClipRect))
|
||||
if (id == 0 || (id != g.ActiveId && id != g.ActiveIdPreviousFrame && id != g.NavId && id != g.NavActivateId))
|
||||
if (!g.LogEnabled)
|
||||
if (!g.ItemUnclipByLog)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@ -5777,7 +5779,7 @@ static inline ImVec2 CalcWindowMinSize(ImGuiWindow* window)
|
||||
|
||||
// Reduce artifacts with very small windows
|
||||
ImGuiWindow* window_for_height = window;
|
||||
size_min.y = ImMax(size_min.y, window_for_height->TitleBarHeight() + window_for_height->MenuBarHeight() + ImMax(0.0f, g.Style.WindowRounding - 1.0f));
|
||||
size_min.y = ImMax(size_min.y, window_for_height->TitleBarHeight + window_for_height->MenuBarHeight + ImMax(0.0f, g.Style.WindowRounding - 1.0f));
|
||||
return size_min;
|
||||
}
|
||||
|
||||
@ -5988,7 +5990,7 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si
|
||||
ImRect clamp_rect = visibility_rect;
|
||||
const bool window_move_from_title_bar = g.IO.ConfigWindowsMoveFromTitleBarOnly && !(window->Flags & ImGuiWindowFlags_NoTitleBar);
|
||||
if (window_move_from_title_bar)
|
||||
clamp_rect.Min.y -= window->TitleBarHeight();
|
||||
clamp_rect.Min.y -= window->TitleBarHeight;
|
||||
|
||||
ImVec2 pos_target(FLT_MAX, FLT_MAX);
|
||||
ImVec2 size_target(FLT_MAX, FLT_MAX);
|
||||
@ -6187,7 +6189,7 @@ static inline void ClampWindowPos(ImGuiWindow* window, const ImRect& visibility_
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImVec2 size_for_clamping = window->Size;
|
||||
if (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(window->Flags & ImGuiWindowFlags_NoTitleBar))
|
||||
size_for_clamping.y = window->TitleBarHeight();
|
||||
size_for_clamping.y = window->TitleBarHeight;
|
||||
window->Pos = ImClamp(window->Pos, visibility_rect.Min - size_for_clamping, visibility_rect.Max);
|
||||
}
|
||||
|
||||
@ -6223,7 +6225,7 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
|
||||
}
|
||||
if (g.Style.FrameBorderSize > 0 && !(window->Flags & ImGuiWindowFlags_NoTitleBar))
|
||||
{
|
||||
float y = window->Pos.y + window->TitleBarHeight() - 1;
|
||||
float y = window->Pos.y + window->TitleBarHeight - 1;
|
||||
window->DrawList->AddLine(ImVec2(window->Pos.x + border_size, y), ImVec2(window->Pos.x + window->Size.x - border_size, y), border_col, g.Style.FrameBorderSize);
|
||||
}
|
||||
}
|
||||
@ -6268,7 +6270,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
|
||||
}
|
||||
if (override_alpha)
|
||||
bg_col = (bg_col & ~IM_COL32_A_MASK) | (IM_F32_TO_INT8_SAT(alpha) << IM_COL32_A_SHIFT);
|
||||
window->DrawList->AddRectFilled(window->Pos + ImVec2(0, window->TitleBarHeight()), window->Pos + window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? 0 : ImDrawFlags_RoundCornersBottom);
|
||||
window->DrawList->AddRectFilled(window->Pos + ImVec2(0, window->TitleBarHeight), window->Pos + window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? 0 : ImDrawFlags_RoundCornersBottom);
|
||||
}
|
||||
|
||||
// Title bar
|
||||
@ -6562,6 +6564,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window_stack_data.Window = window;
|
||||
window_stack_data.ParentLastItemDataBackup = g.LastItemData;
|
||||
window_stack_data.StackSizesOnBegin.SetToContextState(&g);
|
||||
window_stack_data.DisabledOverrideReenable = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0;
|
||||
g.CurrentWindowStack.push_back(window_stack_data);
|
||||
if (flags & ImGuiWindowFlags_ChildMenu)
|
||||
g.BeginMenuDepth++;
|
||||
@ -6648,6 +6651,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
// [EXPERIMENTAL] Skip Refresh mode
|
||||
UpdateWindowSkipRefresh(window);
|
||||
|
||||
// Nested root windows (typically tooltips) override disabled state
|
||||
if (window_stack_data.DisabledOverrideReenable && window->RootWindow == window)
|
||||
BeginDisabledOverrideReenable();
|
||||
|
||||
// We intentionally set g.CurrentWindow to NULL to prevent usage until when the viewport is set, then will call SetCurrentWindow()
|
||||
g.CurrentWindow = NULL;
|
||||
|
||||
@ -6730,6 +6737,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
// Lock menu offset so size calculation can use it as menu-bar windows need a minimum size.
|
||||
window->DC.MenuBarOffset.x = ImMax(ImMax(window->WindowPadding.x, style.ItemSpacing.x), g.NextWindowData.MenuBarOffsetMinVal.x);
|
||||
window->DC.MenuBarOffset.y = g.NextWindowData.MenuBarOffsetMinVal.y;
|
||||
window->TitleBarHeight = (flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : g.FontSize + g.Style.FramePadding.y * 2.0f;
|
||||
window->MenuBarHeight = (flags & ImGuiWindowFlags_MenuBar) ? window->DC.MenuBarOffset.y + g.FontSize + g.Style.FramePadding.y * 2.0f : 0.0f;
|
||||
|
||||
// Depending on condition we use previous or current window size to compare against contents size to decide if a scrollbar should be visible.
|
||||
// Those flags will be altered further down in the function depending on more conditions.
|
||||
@ -6770,7 +6779,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
const ImVec2 scrollbar_sizes_from_last_frame = window->ScrollbarSizes;
|
||||
window->DecoOuterSizeX1 = 0.0f;
|
||||
window->DecoOuterSizeX2 = 0.0f;
|
||||
window->DecoOuterSizeY1 = window->TitleBarHeight() + window->MenuBarHeight();
|
||||
window->DecoOuterSizeY1 = window->TitleBarHeight + window->MenuBarHeight;
|
||||
window->DecoOuterSizeY2 = 0.0f;
|
||||
window->ScrollbarSizes = ImVec2(0.0f, 0.0f);
|
||||
|
||||
@ -6919,7 +6928,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((needed_size_from_last_frame.y > size_y_for_scrollbars) && !(flags & ImGuiWindowFlags_NoScrollbar));
|
||||
window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((needed_size_from_last_frame.x > size_x_for_scrollbars - (window->ScrollbarY ? style.ScrollbarSize : 0.0f)) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar));
|
||||
if (window->ScrollbarX && !window->ScrollbarY)
|
||||
window->ScrollbarY = (needed_size_from_last_frame.y > size_y_for_scrollbars) && !(flags & ImGuiWindowFlags_NoScrollbar);
|
||||
window->ScrollbarY = (needed_size_from_last_frame.y > size_y_for_scrollbars - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar);
|
||||
window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f);
|
||||
|
||||
// Amend the partially filled window->DecorationXXX values.
|
||||
@ -7245,7 +7254,7 @@ void ImGui::End()
|
||||
IM_ASSERT_USER_ERROR(g.CurrentWindowStack.Size > 1, "Calling End() too many times!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(g.CurrentWindowStack.Size > 0);
|
||||
ImGuiWindowStackData& window_stack_data = g.CurrentWindowStack.back();
|
||||
|
||||
// Error checking: verify that user doesn't directly call End() on a child window.
|
||||
if (window->Flags & ImGuiWindowFlags_ChildWindow)
|
||||
@ -7257,6 +7266,8 @@ void ImGui::End()
|
||||
if (!window->SkipRefresh)
|
||||
PopClipRect(); // Inner window clip rectangle
|
||||
PopFocusScope();
|
||||
if (window_stack_data.DisabledOverrideReenable && window->RootWindow == window)
|
||||
EndDisabledOverrideReenable();
|
||||
|
||||
if (window->SkipRefresh)
|
||||
{
|
||||
@ -7272,12 +7283,12 @@ void ImGui::End()
|
||||
ErrorCheckUsingSetCursorPosToExtendParentBoundaries();
|
||||
|
||||
// Pop from window stack
|
||||
g.LastItemData = g.CurrentWindowStack.back().ParentLastItemDataBackup;
|
||||
g.LastItemData = window_stack_data.ParentLastItemDataBackup;
|
||||
if (window->Flags & ImGuiWindowFlags_ChildMenu)
|
||||
g.BeginMenuDepth--;
|
||||
if (window->Flags & ImGuiWindowFlags_Popup)
|
||||
g.BeginPopupStack.pop_back();
|
||||
g.CurrentWindowStack.back().StackSizesOnBegin.CompareWithContextState(&g);
|
||||
window_stack_data.StackSizesOnBegin.CompareWithContextState(&g);
|
||||
g.CurrentWindowStack.pop_back();
|
||||
SetCurrentWindow(g.CurrentWindowStack.Size == 0 ? NULL : g.CurrentWindowStack.back().Window);
|
||||
}
|
||||
@ -7369,9 +7380,13 @@ void ImGui::FocusWindow(ImGuiWindow* window, ImGuiFocusRequestFlags flags)
|
||||
if ((flags & ImGuiFocusRequestFlags_UnlessBelowModal) && (g.NavWindow != window)) // Early out in common case.
|
||||
if (ImGuiWindow* blocking_modal = FindBlockingModal(window))
|
||||
{
|
||||
// This block would typically be reached in two situations:
|
||||
// - API call to FocusWindow() with a window under a modal and ImGuiFocusRequestFlags_UnlessBelowModal flag.
|
||||
// - User clicking on void or anything behind a modal while a modal is open (window == NULL)
|
||||
IMGUI_DEBUG_LOG_FOCUS("[focus] FocusWindow(\"%s\", UnlessBelowModal): prevented by \"%s\".\n", window ? window->Name : "<NULL>", blocking_modal->Name);
|
||||
if (window && window == window->RootWindow && (window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0)
|
||||
BringWindowToDisplayBehind(window, blocking_modal); // Still bring to right below modal.
|
||||
BringWindowToDisplayBehind(window, blocking_modal); // Still bring right under modal. (FIXME: Could move in focus list too?)
|
||||
ClosePopupsOverWindow(GetTopMostPopupModal(), false); // Note how we need to use GetTopMostPopupModal() aad NOT blocking_modal, to handle nested modals
|
||||
return;
|
||||
}
|
||||
|
||||
@ -7521,7 +7536,7 @@ void ImGui::BeginDisabled(bool disabled)
|
||||
}
|
||||
if (was_disabled || disabled)
|
||||
g.CurrentItemFlags |= ImGuiItemFlags_Disabled;
|
||||
g.ItemFlagsStack.push_back(g.CurrentItemFlags);
|
||||
g.ItemFlagsStack.push_back(g.CurrentItemFlags); // FIXME-OPT: can we simply skip this and use DisabledStackSize?
|
||||
g.DisabledStackSize++;
|
||||
}
|
||||
|
||||
@ -7538,6 +7553,29 @@ void ImGui::EndDisabled()
|
||||
g.Style.Alpha = g.DisabledAlphaBackup; //PopStyleVar();
|
||||
}
|
||||
|
||||
// Could have been called BeginDisabledDisable() but it didn't want to be award nominated for most awkward function name.
|
||||
// Ideally we would use a shared e.g. BeginDisabled()->BeginDisabledEx() but earlier needs to be optimal.
|
||||
// The whole code for this is awkward, will reevaluate if we find a way to implement SetNextItemDisabled().
|
||||
void ImGui::BeginDisabledOverrideReenable()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(g.CurrentItemFlags & ImGuiItemFlags_Disabled);
|
||||
g.Style.Alpha = g.DisabledAlphaBackup;
|
||||
g.CurrentItemFlags &= ~ImGuiItemFlags_Disabled;
|
||||
g.ItemFlagsStack.push_back(g.CurrentItemFlags);
|
||||
g.DisabledStackSize++;
|
||||
}
|
||||
|
||||
void ImGui::EndDisabledOverrideReenable()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.DisabledStackSize--;
|
||||
IM_ASSERT(g.DisabledStackSize > 0);
|
||||
g.ItemFlagsStack.pop_back();
|
||||
g.CurrentItemFlags = g.ItemFlagsStack.back();
|
||||
g.Style.Alpha = g.DisabledAlphaBackup * g.Style.DisabledAlpha;
|
||||
}
|
||||
|
||||
void ImGui::PushTabStop(bool tab_stop)
|
||||
{
|
||||
PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop);
|
||||
@ -8868,7 +8906,7 @@ bool ImGui::IsMouseDown(ImGuiMouseButton button, ImGuiID owner_id)
|
||||
|
||||
bool ImGui::IsMouseClicked(ImGuiMouseButton button, bool repeat)
|
||||
{
|
||||
return IsMouseClicked(button, ImGuiKeyOwner_Any, repeat ? ImGuiInputFlags_Repeat : ImGuiInputFlags_None);
|
||||
return IsMouseClicked(button, repeat ? ImGuiInputFlags_Repeat : ImGuiInputFlags_None, ImGuiKeyOwner_Any);
|
||||
}
|
||||
|
||||
bool ImGui::IsMouseClicked(ImGuiMouseButton button, ImGuiInputFlags flags, ImGuiID owner_id)
|
||||
@ -9693,7 +9731,7 @@ void ImGui::SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags)
|
||||
// This is the only public API until we expose owner_id versions of the API as replacements.
|
||||
bool ImGui::IsKeyChordPressed(ImGuiKeyChord key_chord)
|
||||
{
|
||||
return IsKeyChordPressed(key_chord, 0, ImGuiInputFlags_None);
|
||||
return IsKeyChordPressed(key_chord, ImGuiInputFlags_None, ImGuiKeyOwner_Any);
|
||||
}
|
||||
|
||||
// This is equivalent to comparing KeyMods + doing a IsKeyPressed()
|
||||
@ -9993,7 +10031,13 @@ void ImGui::ErrorCheckEndWindowRecover(ImGuiErrorLogCallback log_callback, vo
|
||||
while (g.DisabledStackSize > stack_sizes->SizeOfDisabledStack) //-V1044
|
||||
{
|
||||
if (log_callback) log_callback(user_data, "Recovered from missing EndDisabled() in '%s'", window->Name);
|
||||
EndDisabled();
|
||||
if (g.CurrentItemFlags & ImGuiItemFlags_Disabled)
|
||||
EndDisabled();
|
||||
else
|
||||
{
|
||||
EndDisabledOverrideReenable();
|
||||
g.CurrentWindowStack.back().DisabledOverrideReenable = false;
|
||||
}
|
||||
}
|
||||
while (g.ColorStack.Size > stack_sizes->SizeOfColorStack)
|
||||
{
|
||||
@ -10082,6 +10126,7 @@ void ImGui::KeepAliveID(ImGuiID id)
|
||||
// Note that the size can be different than the one provided to ItemSize(). Typically, widgets that spread over available surface
|
||||
// declare their minimum size requirement to ItemSize() and provide a larger region to ItemAdd() which is used drawing/interaction.
|
||||
// THIS IS IN THE PERFORMANCE CRITICAL PATH (UNTIL THE CLIPPING TEST AND EARLY-RETURN)
|
||||
IM_MSVC_RUNTIME_CHECKS_OFF
|
||||
bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGuiItemFlags extra_flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@ -10134,15 +10179,12 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
|
||||
#endif
|
||||
|
||||
// Clipping test
|
||||
// (this is a modified copy of IsClippedEx() so we can reuse the is_rect_visible value)
|
||||
//const bool is_clipped = IsClippedEx(bb, id);
|
||||
//if (is_clipped)
|
||||
// return false;
|
||||
// (this is an inline copy of IsClippedEx() so we can reuse the is_rect_visible value, otherwise we'd do 'if (IsClippedEx(bb, id)) return false')
|
||||
// g.NavActivateId is not necessarily == g.NavId, in the case of remote activation (e.g. shortcuts)
|
||||
const bool is_rect_visible = bb.Overlaps(window->ClipRect);
|
||||
if (!is_rect_visible)
|
||||
if (id == 0 || (id != g.ActiveId && id != g.ActiveIdPreviousFrame && id != g.NavId && id != g.NavActivateId))
|
||||
if (!g.LogEnabled)
|
||||
if (!g.ItemUnclipByLog)
|
||||
return false;
|
||||
|
||||
// [DEBUG]
|
||||
@ -10169,7 +10211,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredRect;
|
||||
return true;
|
||||
}
|
||||
|
||||
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] LAYOUT
|
||||
@ -10206,6 +10248,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
|
||||
// Register minimum needed size so it can extend the bounding box used for auto-fit calculation.
|
||||
// See comments in ItemAdd() about how/why the size provided to ItemSize() vs ItemAdd() may often different.
|
||||
// THIS IS IN THE PERFORMANCE CRITICAL PATH.
|
||||
IM_MSVC_RUNTIME_CHECKS_OFF
|
||||
void ImGui::ItemSize(const ImVec2& size, float text_baseline_y)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@ -10241,6 +10284,7 @@ void ImGui::ItemSize(const ImVec2& size, float text_baseline_y)
|
||||
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
|
||||
SameLine();
|
||||
}
|
||||
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
|
||||
// Gets back to previous line and continue with horizontal layout
|
||||
// offset_from_start_x == 0 : follow right after previous item
|
||||
@ -13094,6 +13138,8 @@ bool ImGui::IsDragDropActive()
|
||||
void ImGui::ClearDragDrop()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.DragDropActive)
|
||||
IMGUI_DEBUG_LOG_ACTIVEID("[dragdrop] ClearDragDrop()\n");
|
||||
g.DragDropActive = false;
|
||||
g.DragDropPayload.Clear();
|
||||
g.DragDropAcceptFlags = ImGuiDragDropFlags_None;
|
||||
@ -13132,7 +13178,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags)
|
||||
bool source_drag_active = false;
|
||||
ImGuiID source_id = 0;
|
||||
ImGuiID source_parent_id = 0;
|
||||
if (!(flags & ImGuiDragDropFlags_SourceExtern))
|
||||
if ((flags & ImGuiDragDropFlags_SourceExtern) == 0)
|
||||
{
|
||||
source_id = g.LastItemData.ID;
|
||||
if (source_id != 0)
|
||||
@ -13194,43 +13240,44 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags)
|
||||
}
|
||||
|
||||
IM_ASSERT(g.DragDropWithinTarget == false); // Can't nest BeginDragDropSource() and BeginDragDropTarget()
|
||||
if (source_drag_active)
|
||||
if (!source_drag_active)
|
||||
return false;
|
||||
|
||||
// Activate drag and drop
|
||||
if (!g.DragDropActive)
|
||||
{
|
||||
if (!g.DragDropActive)
|
||||
{
|
||||
IM_ASSERT(source_id != 0);
|
||||
ClearDragDrop();
|
||||
ImGuiPayload& payload = g.DragDropPayload;
|
||||
payload.SourceId = source_id;
|
||||
payload.SourceParentId = source_parent_id;
|
||||
g.DragDropActive = true;
|
||||
g.DragDropSourceFlags = flags;
|
||||
g.DragDropMouseButton = mouse_button;
|
||||
if (payload.SourceId == g.ActiveId)
|
||||
g.ActiveIdNoClearOnFocusLoss = true;
|
||||
}
|
||||
g.DragDropSourceFrameCount = g.FrameCount;
|
||||
g.DragDropWithinSource = true;
|
||||
|
||||
if (!(flags & ImGuiDragDropFlags_SourceNoPreviewTooltip))
|
||||
{
|
||||
// Target can request the Source to not display its tooltip (we use a dedicated flag to make this request explicit)
|
||||
// We unfortunately can't just modify the source flags and skip the call to BeginTooltip, as caller may be emitting contents.
|
||||
bool ret;
|
||||
if (g.DragDropAcceptIdPrev && (g.DragDropAcceptFlags & ImGuiDragDropFlags_AcceptNoPreviewTooltip))
|
||||
ret = BeginTooltipHidden();
|
||||
else
|
||||
ret = BeginTooltip();
|
||||
IM_ASSERT(ret); // FIXME-NEWBEGIN: If this ever becomes false, we need to Begin("##Hidden", NULL, ImGuiWindowFlags_NoSavedSettings) + SetWindowHiddendAndSkipItemsForCurrentFrame().
|
||||
IM_UNUSED(ret);
|
||||
}
|
||||
|
||||
if (!(flags & ImGuiDragDropFlags_SourceNoDisableHover) && !(flags & ImGuiDragDropFlags_SourceExtern))
|
||||
g.LastItemData.StatusFlags &= ~ImGuiItemStatusFlags_HoveredRect;
|
||||
|
||||
return true;
|
||||
IM_ASSERT(source_id != 0);
|
||||
ClearDragDrop();
|
||||
IMGUI_DEBUG_LOG_ACTIVEID("[dragdrop] BeginDragDropSource() DragDropActive = true, source_id = %08X\n", source_id);
|
||||
ImGuiPayload& payload = g.DragDropPayload;
|
||||
payload.SourceId = source_id;
|
||||
payload.SourceParentId = source_parent_id;
|
||||
g.DragDropActive = true;
|
||||
g.DragDropSourceFlags = flags;
|
||||
g.DragDropMouseButton = mouse_button;
|
||||
if (payload.SourceId == g.ActiveId)
|
||||
g.ActiveIdNoClearOnFocusLoss = true;
|
||||
}
|
||||
return false;
|
||||
g.DragDropSourceFrameCount = g.FrameCount;
|
||||
g.DragDropWithinSource = true;
|
||||
|
||||
if (!(flags & ImGuiDragDropFlags_SourceNoPreviewTooltip))
|
||||
{
|
||||
// Target can request the Source to not display its tooltip (we use a dedicated flag to make this request explicit)
|
||||
// We unfortunately can't just modify the source flags and skip the call to BeginTooltip, as caller may be emitting contents.
|
||||
bool ret;
|
||||
if (g.DragDropAcceptIdPrev && (g.DragDropAcceptFlags & ImGuiDragDropFlags_AcceptNoPreviewTooltip))
|
||||
ret = BeginTooltipHidden();
|
||||
else
|
||||
ret = BeginTooltip();
|
||||
IM_ASSERT(ret); // FIXME-NEWBEGIN: If this ever becomes false, we need to Begin("##Hidden", NULL, ImGuiWindowFlags_NoSavedSettings) + SetWindowHiddendAndSkipItemsForCurrentFrame().
|
||||
IM_UNUSED(ret);
|
||||
}
|
||||
|
||||
if (!(flags & ImGuiDragDropFlags_SourceNoDisableHover) && !(flags & ImGuiDragDropFlags_SourceExtern))
|
||||
g.LastItemData.StatusFlags &= ~ImGuiItemStatusFlags_HoveredRect;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui::EndDragDropSource()
|
||||
@ -13541,7 +13588,7 @@ void ImGui::LogBegin(ImGuiLogType type, int auto_open_depth)
|
||||
IM_ASSERT(g.LogEnabled == false);
|
||||
IM_ASSERT(g.LogFile == NULL);
|
||||
IM_ASSERT(g.LogBuffer.empty());
|
||||
g.LogEnabled = true;
|
||||
g.LogEnabled = g.ItemUnclipByLog = true;
|
||||
g.LogType = type;
|
||||
g.LogNextPrefix = g.LogNextSuffix = NULL;
|
||||
g.LogDepthRef = window->DC.TreeDepth;
|
||||
@ -13640,7 +13687,7 @@ void ImGui::LogFinish()
|
||||
break;
|
||||
}
|
||||
|
||||
g.LogEnabled = false;
|
||||
g.LogEnabled = g.ItemUnclipByLog = false;
|
||||
g.LogType = ImGuiLogType_None;
|
||||
g.LogFile = NULL;
|
||||
g.LogBuffer.clear();
|
||||
@ -15566,8 +15613,11 @@ void ImGui::DebugLogV(const char* fmt, va_list args)
|
||||
if (g.DebugLogFlags & ImGuiDebugLogFlags_OutputToTTY)
|
||||
IMGUI_DEBUG_PRINTF("%s", g.DebugLogBuf.begin() + old_size);
|
||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||
// IMGUI_TEST_ENGINE_LOG() adds a trailing \n automatically
|
||||
const int new_size = g.DebugLogBuf.size();
|
||||
const bool trailing_carriage_return = (g.DebugLogBuf[new_size - 1] == '\n');
|
||||
if (g.DebugLogFlags & ImGuiDebugLogFlags_OutputToTestEngine)
|
||||
IMGUI_TEST_ENGINE_LOG("%s", g.DebugLogBuf.begin() + old_size);
|
||||
IMGUI_TEST_ENGINE_LOG("%.*s", new_size - old_size - (trailing_carriage_return ? 1 : 0), g.DebugLogBuf.begin() + old_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -15635,25 +15685,7 @@ void ImGui::ShowDebugLogWindow(bool* p_open)
|
||||
clipper.Begin(g.DebugLogIndex.size());
|
||||
while (clipper.Step())
|
||||
for (int line_no = clipper.DisplayStart; line_no < clipper.DisplayEnd; line_no++)
|
||||
{
|
||||
const char* line_begin = g.DebugLogIndex.get_line_begin(g.DebugLogBuf.c_str(), line_no);
|
||||
const char* line_end = g.DebugLogIndex.get_line_end(g.DebugLogBuf.c_str(), line_no);
|
||||
TextUnformatted(line_begin, line_end); // Display line
|
||||
ImRect text_rect = g.LastItemData.Rect;
|
||||
if (IsItemHovered())
|
||||
for (const char* p = line_begin; p <= line_end - 10; p++) // Search for 0x???????? identifiers
|
||||
{
|
||||
ImGuiID id = 0;
|
||||
if (p[0] != '0' || (p[1] != 'x' && p[1] != 'X') || sscanf(p + 2, "%X", &id) != 1)
|
||||
continue;
|
||||
ImVec2 p0 = CalcTextSize(line_begin, p);
|
||||
ImVec2 p1 = CalcTextSize(p, p + 10);
|
||||
g.LastItemData.Rect = ImRect(text_rect.Min + ImVec2(p0.x, 0.0f), text_rect.Min + ImVec2(p0.x + p1.x, p1.y));
|
||||
if (IsMouseHoveringRect(g.LastItemData.Rect.Min, g.LastItemData.Rect.Max, true))
|
||||
DebugLocateItemOnHover(id);
|
||||
p += 10;
|
||||
}
|
||||
}
|
||||
DebugTextUnformattedWithLocateItem(g.DebugLogIndex.get_line_begin(g.DebugLogBuf.c_str(), line_no), g.DebugLogIndex.get_line_end(g.DebugLogBuf.c_str(), line_no));
|
||||
g.DebugLogFlags = backup_log_flags;
|
||||
if (GetScrollY() >= GetScrollMaxY())
|
||||
SetScrollHereY(1.0f);
|
||||
@ -15662,6 +15694,28 @@ void ImGui::ShowDebugLogWindow(bool* p_open)
|
||||
End();
|
||||
}
|
||||
|
||||
// Display line, search for 0xXXXXXXXX identifiers and call DebugLocateItemOnHover() when hovered.
|
||||
void ImGui::DebugTextUnformattedWithLocateItem(const char* line_begin, const char* line_end)
|
||||
{
|
||||
TextUnformatted(line_begin, line_end);
|
||||
if (!IsItemHovered())
|
||||
return;
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImRect text_rect = g.LastItemData.Rect;
|
||||
for (const char* p = line_begin; p <= line_end - 10; p++)
|
||||
{
|
||||
ImGuiID id = 0;
|
||||
if (p[0] != '0' || (p[1] != 'x' && p[1] != 'X') || sscanf(p + 2, "%X", &id) != 1)
|
||||
continue;
|
||||
ImVec2 p0 = CalcTextSize(line_begin, p);
|
||||
ImVec2 p1 = CalcTextSize(p, p + 10);
|
||||
g.LastItemData.Rect = ImRect(text_rect.Min + ImVec2(p0.x, 0.0f), text_rect.Min + ImVec2(p0.x + p1.x, p1.y));
|
||||
if (IsMouseHoveringRect(g.LastItemData.Rect.Min, g.LastItemData.Rect.Max, true))
|
||||
DebugLocateItemOnHover(id);
|
||||
p += 10;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] OTHER DEBUG TOOLS (ITEM PICKER, ID STACK TOOL)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
99
external/imgui/imgui/imgui.h
vendored
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.7
|
||||
// dear imgui, v1.90.8
|
||||
// (headers)
|
||||
|
||||
// Help:
|
||||
@ -27,8 +27,8 @@
|
||||
|
||||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||
#define IMGUI_VERSION "1.90.7"
|
||||
#define IMGUI_VERSION_NUM 19070
|
||||
#define IMGUI_VERSION "1.90.8"
|
||||
#define IMGUI_VERSION_NUM 19080
|
||||
#define IMGUI_HAS_TABLE
|
||||
|
||||
/*
|
||||
@ -143,6 +143,17 @@ Index of this file:
|
||||
// [SECTION] Forward declarations and basic types
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Scalar data types
|
||||
typedef unsigned int ImGuiID;// A unique ID used by widgets (typically the result of hashing a stack of string)
|
||||
typedef signed char ImS8; // 8-bit signed integer
|
||||
typedef unsigned char ImU8; // 8-bit unsigned integer
|
||||
typedef signed short ImS16; // 16-bit signed integer
|
||||
typedef unsigned short ImU16; // 16-bit unsigned integer
|
||||
typedef signed int ImS32; // 32-bit signed integer == int
|
||||
typedef unsigned int ImU32; // 32-bit unsigned integer (often used to store packed colors)
|
||||
typedef signed long long ImS64; // 64-bit signed integer
|
||||
typedef unsigned long long ImU64; // 64-bit unsigned integer
|
||||
|
||||
// Forward declarations
|
||||
struct ImDrawChannel; // Temporary storage to output draw commands out of order, used by ImDrawListSplitter and ImDrawList::ChannelsSplit()
|
||||
struct ImDrawCmd; // A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call, unless it is a callback)
|
||||
@ -181,15 +192,15 @@ struct ImGuiViewport; // A Platform Window (always only one in 'ma
|
||||
// - In Visual Studio: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
|
||||
// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
|
||||
// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments.
|
||||
enum ImGuiDir : int; // -> enum ImGuiDir // Enum: A cardinal direction (Left, Right, Up, Down)
|
||||
enum ImGuiKey : int; // -> enum ImGuiKey // Enum: A key identifier (ImGuiKey_XXX or ImGuiMod_XXX value)
|
||||
enum ImGuiMouseSource : int; // -> enum ImGuiMouseSource // Enum; A mouse input source identifier (Mouse, TouchScreen, Pen)
|
||||
enum ImGuiSortDirection : ImU8; // -> enum ImGuiSortDirection // Enum: A sorting direction (ascending or descending)
|
||||
typedef int ImGuiCol; // -> enum ImGuiCol_ // Enum: A color identifier for styling
|
||||
typedef int ImGuiCond; // -> enum ImGuiCond_ // Enum: A condition for many Set*() functions
|
||||
typedef int ImGuiDataType; // -> enum ImGuiDataType_ // Enum: A primary data type
|
||||
typedef int ImGuiDir; // -> enum ImGuiDir_ // Enum: A cardinal direction
|
||||
typedef int ImGuiMouseButton; // -> enum ImGuiMouseButton_ // Enum: A mouse button identifier (0=left, 1=right, 2=middle)
|
||||
typedef int ImGuiMouseCursor; // -> enum ImGuiMouseCursor_ // Enum: A mouse cursor shape
|
||||
typedef int ImGuiSortDirection; // -> enum ImGuiSortDirection_ // Enum: A sorting direction (ascending or descending)
|
||||
typedef int ImGuiStyleVar; // -> enum ImGuiStyleVar_ // Enum: A variable identifier for styling
|
||||
typedef int ImGuiTableBgTarget; // -> enum ImGuiTableBgTarget_ // Enum: A color target for TableSetBgColor()
|
||||
|
||||
@ -239,17 +250,6 @@ typedef void* ImTextureID; // Default: store a pointer or an integer fi
|
||||
typedef unsigned short ImDrawIdx; // Default: 16-bit (for maximum compatibility with renderer backends)
|
||||
#endif
|
||||
|
||||
// Scalar data types
|
||||
typedef unsigned int ImGuiID;// A unique ID used by widgets (typically the result of hashing a stack of string)
|
||||
typedef signed char ImS8; // 8-bit signed integer
|
||||
typedef unsigned char ImU8; // 8-bit unsigned integer
|
||||
typedef signed short ImS16; // 16-bit signed integer
|
||||
typedef unsigned short ImU16; // 16-bit unsigned integer
|
||||
typedef signed int ImS32; // 32-bit signed integer == int
|
||||
typedef unsigned int ImU32; // 32-bit unsigned integer (often used to store packed colors)
|
||||
typedef signed long long ImS64; // 64-bit signed integer
|
||||
typedef unsigned long long ImU64; // 64-bit unsigned integer
|
||||
|
||||
// Character types
|
||||
// (we generally use UTF-8 encoded string in the API. This is storage specifically for a decoded character used for keyboard input and display)
|
||||
typedef unsigned int ImWchar32; // A single decoded U32 character/code point. We encode them as multi bytes UTF-8 when used in strings.
|
||||
@ -1082,28 +1082,37 @@ enum ImGuiChildFlags_
|
||||
// (Those are per-item flags. There are shared flags in ImGuiIO: io.ConfigInputTextCursorBlink and io.ConfigInputTextEnterKeepActive)
|
||||
enum ImGuiInputTextFlags_
|
||||
{
|
||||
// Basic filters (also see ImGuiInputTextFlags_CallbackCharFilter)
|
||||
ImGuiInputTextFlags_None = 0,
|
||||
ImGuiInputTextFlags_CharsDecimal = 1 << 0, // Allow 0123456789.+-*/
|
||||
ImGuiInputTextFlags_CharsHexadecimal = 1 << 1, // Allow 0123456789ABCDEFabcdef
|
||||
ImGuiInputTextFlags_CharsUppercase = 1 << 2, // Turn a..z into A..Z
|
||||
ImGuiInputTextFlags_CharsNoBlank = 1 << 3, // Filter out spaces, tabs
|
||||
ImGuiInputTextFlags_AutoSelectAll = 1 << 4, // Select entire text when first taking mouse focus
|
||||
ImGuiInputTextFlags_EnterReturnsTrue = 1 << 5, // Return 'true' when Enter is pressed (as opposed to every time the value was modified). Consider looking at the IsItemDeactivatedAfterEdit() function.
|
||||
ImGuiInputTextFlags_CallbackCompletion = 1 << 6, // Callback on pressing TAB (for completion handling)
|
||||
ImGuiInputTextFlags_CallbackHistory = 1 << 7, // Callback on pressing Up/Down arrows (for history handling)
|
||||
ImGuiInputTextFlags_CallbackAlways = 1 << 8, // Callback on each iteration. User code may query cursor position, modify text buffer.
|
||||
ImGuiInputTextFlags_CallbackCharFilter = 1 << 9, // Callback on character inputs to replace or discard them. Modify 'EventChar' to replace or discard, or return 1 in callback to discard.
|
||||
ImGuiInputTextFlags_AllowTabInput = 1 << 10, // Pressing TAB input a '\t' character into the text field
|
||||
ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 11, // In multi-line mode, unfocus with Enter, add new line with Ctrl+Enter (default is opposite: unfocus with Ctrl+Enter, add line with Enter).
|
||||
ImGuiInputTextFlags_NoHorizontalScroll = 1 << 12, // Disable following the cursor horizontally
|
||||
ImGuiInputTextFlags_AlwaysOverwrite = 1 << 13, // Overwrite mode
|
||||
ImGuiInputTextFlags_ReadOnly = 1 << 14, // Read-only mode
|
||||
ImGuiInputTextFlags_Password = 1 << 15, // Password mode, display all characters as '*'
|
||||
ImGuiInputTextFlags_CharsScientific = 1 << 2, // Allow 0123456789.+-*/eE (Scientific notation input)
|
||||
ImGuiInputTextFlags_CharsUppercase = 1 << 3, // Turn a..z into A..Z
|
||||
ImGuiInputTextFlags_CharsNoBlank = 1 << 4, // Filter out spaces, tabs
|
||||
|
||||
// Inputs
|
||||
ImGuiInputTextFlags_AllowTabInput = 1 << 5, // Pressing TAB input a '\t' character into the text field
|
||||
ImGuiInputTextFlags_EnterReturnsTrue = 1 << 6, // Return 'true' when Enter is pressed (as opposed to every time the value was modified). Consider looking at the IsItemDeactivatedAfterEdit() function.
|
||||
ImGuiInputTextFlags_EscapeClearsAll = 1 << 7, // Escape key clears content if not empty, and deactivate otherwise (contrast to default behavior of Escape to revert)
|
||||
ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 8, // In multi-line mode, validate with Enter, add new line with Ctrl+Enter (default is opposite: validate with Ctrl+Enter, add line with Enter).
|
||||
|
||||
// Other options
|
||||
ImGuiInputTextFlags_ReadOnly = 1 << 9, // Read-only mode
|
||||
ImGuiInputTextFlags_Password = 1 << 10, // Password mode, display all characters as '*', disable copy
|
||||
ImGuiInputTextFlags_AlwaysOverwrite = 1 << 11, // Overwrite mode
|
||||
ImGuiInputTextFlags_AutoSelectAll = 1 << 12, // Select entire text when first taking mouse focus
|
||||
ImGuiInputTextFlags_ParseEmptyRefVal = 1 << 13, // InputFloat(), InputInt(), InputScalar() etc. only: parse empty string as zero value.
|
||||
ImGuiInputTextFlags_DisplayEmptyRefVal = 1 << 14, // InputFloat(), InputInt(), InputScalar() etc. only: when value is zero, do not display it. Generally used with ImGuiInputTextFlags_ParseEmptyRefVal.
|
||||
ImGuiInputTextFlags_NoHorizontalScroll = 1 << 15, // Disable following the cursor horizontally
|
||||
ImGuiInputTextFlags_NoUndoRedo = 1 << 16, // Disable undo/redo. Note that input text owns the text data while active, if you want to provide your own undo/redo stack you need e.g. to call ClearActiveID().
|
||||
ImGuiInputTextFlags_CharsScientific = 1 << 17, // Allow 0123456789.+-*/eE (Scientific notation input)
|
||||
ImGuiInputTextFlags_CallbackResize = 1 << 18, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this)
|
||||
ImGuiInputTextFlags_CallbackEdit = 1 << 19, // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active)
|
||||
ImGuiInputTextFlags_EscapeClearsAll = 1 << 20, // Escape key clears content if not empty, and deactivate otherwise (contrast to default behavior of Escape to revert)
|
||||
|
||||
// Callback features
|
||||
ImGuiInputTextFlags_CallbackCompletion = 1 << 17, // Callback on pressing TAB (for completion handling)
|
||||
ImGuiInputTextFlags_CallbackHistory = 1 << 18, // Callback on pressing Up/Down arrows (for history handling)
|
||||
ImGuiInputTextFlags_CallbackAlways = 1 << 19, // Callback on each iteration. User code may query cursor position, modify text buffer.
|
||||
ImGuiInputTextFlags_CallbackCharFilter = 1 << 20, // Callback on character inputs to replace or discard them. Modify 'EventChar' to replace or discard, or return 1 in callback to discard.
|
||||
ImGuiInputTextFlags_CallbackResize = 1 << 21, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this)
|
||||
ImGuiInputTextFlags_CallbackEdit = 1 << 22, // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active)
|
||||
|
||||
// Obsolete names
|
||||
//ImGuiInputTextFlags_AlwaysInsertMode = ImGuiInputTextFlags_AlwaysOverwrite // [renamed in 1.82] name was not matching behavior
|
||||
@ -1123,7 +1132,7 @@ enum ImGuiTreeNodeFlags_
|
||||
ImGuiTreeNodeFlags_OpenOnArrow = 1 << 7, // Only open when clicking on the arrow part. If ImGuiTreeNodeFlags_OpenOnDoubleClick is also set, single-click arrow or double-click all box to open.
|
||||
ImGuiTreeNodeFlags_Leaf = 1 << 8, // No collapsing, no arrow (use as a convenience for leaf nodes).
|
||||
ImGuiTreeNodeFlags_Bullet = 1 << 9, // Display a bullet instead of arrow. IMPORTANT: node can still be marked open/close if you don't set the _Leaf flag!
|
||||
ImGuiTreeNodeFlags_FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignTextToFramePadding().
|
||||
ImGuiTreeNodeFlags_FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignTextToFramePadding() before the node.
|
||||
ImGuiTreeNodeFlags_SpanAvailWidth = 1 << 11, // Extend hit box to the right-most edge, even if not framed. This is not the default in order to allow adding other items on the same line without using AllowOverlap mode.
|
||||
ImGuiTreeNodeFlags_SpanFullWidth = 1 << 12, // Extend hit box to the left-most and right-most edges (cover the indent area).
|
||||
ImGuiTreeNodeFlags_SpanTextWidth = 1 << 13, // Narrow hit box + narrow hovering highlight, will only cover the label text.
|
||||
@ -1314,7 +1323,7 @@ enum ImGuiDataType_
|
||||
};
|
||||
|
||||
// A cardinal direction
|
||||
enum ImGuiDir_
|
||||
enum ImGuiDir : int
|
||||
{
|
||||
ImGuiDir_None = -1,
|
||||
ImGuiDir_Left = 0,
|
||||
@ -1325,7 +1334,7 @@ enum ImGuiDir_
|
||||
};
|
||||
|
||||
// A sorting direction
|
||||
enum ImGuiSortDirection_
|
||||
enum ImGuiSortDirection : ImU8
|
||||
{
|
||||
ImGuiSortDirection_None = 0,
|
||||
ImGuiSortDirection_Ascending = 1, // Ascending = 0->9, A->Z etc.
|
||||
@ -1648,10 +1657,8 @@ enum ImGuiButtonFlags_
|
||||
ImGuiButtonFlags_MouseButtonLeft = 1 << 0, // React on left mouse button (default)
|
||||
ImGuiButtonFlags_MouseButtonRight = 1 << 1, // React on right mouse button
|
||||
ImGuiButtonFlags_MouseButtonMiddle = 1 << 2, // React on center mouse button
|
||||
|
||||
// [Internal]
|
||||
ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle,
|
||||
ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft,
|
||||
ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle, // [Internal]
|
||||
//ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft,
|
||||
};
|
||||
|
||||
// Flags for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton()
|
||||
@ -1924,7 +1931,7 @@ struct ImGuiTableColumnSortSpecs
|
||||
ImGuiID ColumnUserID; // User id of the column (if specified by a TableSetupColumn() call)
|
||||
ImS16 ColumnIndex; // Index of the column
|
||||
ImS16 SortOrder; // Index within parent ImGuiTableSortSpecs (always stored in order starting from 0, tables sorted on a single criteria will always have a 0 here)
|
||||
ImGuiSortDirection SortDirection : 8; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending
|
||||
ImGuiSortDirection SortDirection; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending
|
||||
|
||||
ImGuiTableColumnSortSpecs() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
@ -2073,9 +2080,9 @@ struct ImGuiStyle
|
||||
float SeparatorTextBorderSize; // Thickkness of border in SeparatorText()
|
||||
ImVec2 SeparatorTextAlign; // Alignment of text within the separator. Defaults to (0.0f, 0.5f) (left aligned, center).
|
||||
ImVec2 SeparatorTextPadding; // Horizontal offset of text from each edge of the separator + spacing on other axis. Generally small values. .y is recommended to be == FramePadding.y.
|
||||
ImVec2 DisplayWindowPadding; // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows.
|
||||
ImVec2 DisplaySafeAreaPadding; // If you cannot see the edges of your screen (e.g. on a TV) increase the safe area padding. Apply to popups/tooltips as well regular windows. NB: Prefer configuring your TV sets correctly!
|
||||
float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later.
|
||||
ImVec2 DisplayWindowPadding; // Apply to regular windows: amount which we enforce to keep visible when moving near edges of your screen.
|
||||
ImVec2 DisplaySafeAreaPadding; // Apply to every windows, menus, popups, tooltips: amount where we avoid displaying contents. Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured).
|
||||
float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). We apply per-monitor DPI scaling over this scale. May be removed later.
|
||||
bool AntiAliasedLines; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList).
|
||||
bool AntiAliasedLinesUseTex; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering (NOT point/nearest filtering). Latched at the beginning of the frame (copied to ImDrawList).
|
||||
bool AntiAliasedFill; // Enable anti-aliased edges around filled shapes (rounded rectangles, circles, etc.). Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList).
|
||||
@ -3256,7 +3263,7 @@ namespace ImGui
|
||||
static inline void PopAllowKeyboardFocus() { PopTabStop(); }
|
||||
// OBSOLETED in 1.89 (from August 2022)
|
||||
IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1)); // Use new ImageButton() signature (explicit item id, regular FramePadding)
|
||||
// OBSOLETED in 1.87 (from February 2022)
|
||||
// OBSOLETED in 1.87 (from February 2022 but more formally obsoleted April 2024)
|
||||
IMGUI_API ImGuiKey GetKeyIndex(ImGuiKey key); // Map ImGuiKey_* values into legacy native key index. == io.KeyMap[key]. When using a 1.87+ backend using io.AddKeyEvent(), calling GetKeyIndex() with ANY ImGuiKey_XXXX values will return the same value!
|
||||
//static inline ImGuiKey GetKeyIndex(ImGuiKey key) { IM_ASSERT(key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END); return key; }
|
||||
|
||||
|
40
external/imgui/imgui/imgui_demo.cpp
vendored
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.7
|
||||
// dear imgui, v1.90.8
|
||||
// (demo code)
|
||||
|
||||
// Help:
|
||||
@ -2273,20 +2273,24 @@ static void ShowDemoWindowWidgets()
|
||||
|
||||
IMGUI_DEMO_MARKER("Widgets/Data Types/Inputs");
|
||||
static bool inputs_step = true;
|
||||
static ImGuiInputTextFlags flags = ImGuiInputTextFlags_None;
|
||||
ImGui::SeparatorText("Inputs");
|
||||
ImGui::Checkbox("Show step buttons", &inputs_step);
|
||||
ImGui::InputScalar("input s8", ImGuiDataType_S8, &s8_v, inputs_step ? &s8_one : NULL, NULL, "%d");
|
||||
ImGui::InputScalar("input u8", ImGuiDataType_U8, &u8_v, inputs_step ? &u8_one : NULL, NULL, "%u");
|
||||
ImGui::InputScalar("input s16", ImGuiDataType_S16, &s16_v, inputs_step ? &s16_one : NULL, NULL, "%d");
|
||||
ImGui::InputScalar("input u16", ImGuiDataType_U16, &u16_v, inputs_step ? &u16_one : NULL, NULL, "%u");
|
||||
ImGui::InputScalar("input s32", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%d");
|
||||
ImGui::InputScalar("input s32 hex", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%04X");
|
||||
ImGui::InputScalar("input u32", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%u");
|
||||
ImGui::InputScalar("input u32 hex", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%08X");
|
||||
ImGui::InputScalar("input s64", ImGuiDataType_S64, &s64_v, inputs_step ? &s64_one : NULL);
|
||||
ImGui::InputScalar("input u64", ImGuiDataType_U64, &u64_v, inputs_step ? &u64_one : NULL);
|
||||
ImGui::InputScalar("input float", ImGuiDataType_Float, &f32_v, inputs_step ? &f32_one : NULL);
|
||||
ImGui::InputScalar("input double", ImGuiDataType_Double, &f64_v, inputs_step ? &f64_one : NULL);
|
||||
ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly);
|
||||
ImGui::CheckboxFlags("ImGuiInputTextFlags_ParseEmptyRefVal", &flags, ImGuiInputTextFlags_ParseEmptyRefVal);
|
||||
ImGui::CheckboxFlags("ImGuiInputTextFlags_DisplayEmptyRefVal", &flags, ImGuiInputTextFlags_DisplayEmptyRefVal);
|
||||
ImGui::InputScalar("input s8", ImGuiDataType_S8, &s8_v, inputs_step ? &s8_one : NULL, NULL, "%d", flags);
|
||||
ImGui::InputScalar("input u8", ImGuiDataType_U8, &u8_v, inputs_step ? &u8_one : NULL, NULL, "%u", flags);
|
||||
ImGui::InputScalar("input s16", ImGuiDataType_S16, &s16_v, inputs_step ? &s16_one : NULL, NULL, "%d", flags);
|
||||
ImGui::InputScalar("input u16", ImGuiDataType_U16, &u16_v, inputs_step ? &u16_one : NULL, NULL, "%u", flags);
|
||||
ImGui::InputScalar("input s32", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%d", flags);
|
||||
ImGui::InputScalar("input s32 hex", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%04X", flags);
|
||||
ImGui::InputScalar("input u32", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%u", flags);
|
||||
ImGui::InputScalar("input u32 hex", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%08X", flags);
|
||||
ImGui::InputScalar("input s64", ImGuiDataType_S64, &s64_v, inputs_step ? &s64_one : NULL, NULL, NULL, flags);
|
||||
ImGui::InputScalar("input u64", ImGuiDataType_U64, &u64_v, inputs_step ? &u64_one : NULL, NULL, NULL, flags);
|
||||
ImGui::InputScalar("input float", ImGuiDataType_Float, &f32_v, inputs_step ? &f32_one : NULL, NULL, NULL, flags);
|
||||
ImGui::InputScalar("input double", ImGuiDataType_Double, &f64_v, inputs_step ? &f64_one : NULL, NULL, NULL, flags);
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
@ -3875,7 +3879,7 @@ static void ShowDemoWindowPopups()
|
||||
static int item = 1;
|
||||
static float color[4] = { 0.4f, 0.7f, 0.0f, 0.5f };
|
||||
ImGui::Combo("Combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0");
|
||||
ImGui::ColorEdit4("color", color);
|
||||
ImGui::ColorEdit4("Color", color);
|
||||
|
||||
if (ImGui::Button("Add another modal.."))
|
||||
ImGui::OpenPopup("Stacked 2");
|
||||
@ -3887,6 +3891,7 @@ static void ShowDemoWindowPopups()
|
||||
if (ImGui::BeginPopupModal("Stacked 2", &unused_open))
|
||||
{
|
||||
ImGui::Text("Hello from Stacked The Second!");
|
||||
ImGui::ColorEdit4("Color", color); // Allow opening another nested popup
|
||||
if (ImGui::Button("Close"))
|
||||
ImGui::CloseCurrentPopup();
|
||||
ImGui::EndPopup();
|
||||
@ -6295,7 +6300,7 @@ static void ShowDemoWindowInputs()
|
||||
ImGui::RadioButton("ImGuiInputFlags_RouteAlways", &route_type, ImGuiInputFlags_RouteAlways);
|
||||
ImGuiInputFlags flags = route_type | route_options; // Merged flags
|
||||
if (route_type != ImGuiInputFlags_RouteGlobal)
|
||||
route_options &= ~(ImGuiInputFlags_RouteOverFocused | ImGuiInputFlags_RouteOverActive | ImGuiInputFlags_RouteUnlessBgFocused);
|
||||
flags &= ~(ImGuiInputFlags_RouteOverFocused | ImGuiInputFlags_RouteOverActive | ImGuiInputFlags_RouteUnlessBgFocused);
|
||||
|
||||
ImGui::SeparatorText("Using SetNextItemShortcut()");
|
||||
ImGui::Text("Ctrl+S");
|
||||
@ -6768,7 +6773,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f");
|
||||
int window_menu_button_position = style.WindowMenuButtonPosition + 1;
|
||||
if (ImGui::Combo("WindowMenuButtonPosition", (int*)&window_menu_button_position, "None\0Left\0Right\0"))
|
||||
style.WindowMenuButtonPosition = window_menu_button_position - 1;
|
||||
style.WindowMenuButtonPosition = (ImGuiDir)(window_menu_button_position - 1);
|
||||
ImGui::Combo("ColorButtonPosition", (int*)&style.ColorButtonPosition, "Left\0Right\0");
|
||||
ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f");
|
||||
ImGui::SameLine(); HelpMarker("Alignment applies when a button is larger than its text content.");
|
||||
@ -6793,7 +6798,8 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
}
|
||||
|
||||
ImGui::SeparatorText("Misc");
|
||||
ImGui::SliderFloat2("DisplaySafeAreaPadding", (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f, "%.0f"); ImGui::SameLine(); HelpMarker("Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured).");
|
||||
ImGui::SliderFloat2("DisplayWindowPadding", (float*)&style.DisplayWindowPadding, 0.0f, 30.0f, "%.0f"); ImGui::SameLine(); HelpMarker("Apply to regular windows: amount which we enforce to keep visible when moving near edges of your screen.");
|
||||
ImGui::SliderFloat2("DisplaySafeAreaPadding", (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f, "%.0f"); ImGui::SameLine(); HelpMarker("Apply to every windows, menus, popups, tooltips: amount where we avoid displaying contents. Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured).");
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
2
external/imgui/imgui/imgui_draw.cpp
vendored
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.7
|
||||
// dear imgui, v1.90.8
|
||||
// (drawing and font code)
|
||||
|
||||
/*
|
||||
|
116
external/imgui/imgui/imgui_internal.h
vendored
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.7
|
||||
// dear imgui, v1.90.8
|
||||
// (internal structures/api)
|
||||
|
||||
// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility.
|
||||
@ -14,8 +14,8 @@ Index of this file:
|
||||
// [SECTION] Macros
|
||||
// [SECTION] Generic helpers
|
||||
// [SECTION] ImDrawList support
|
||||
// [SECTION] Widgets support: flags, enums, data structures
|
||||
// [SECTION] Data types support
|
||||
// [SECTION] Widgets support: flags, enums, data structures
|
||||
// [SECTION] Popup support
|
||||
// [SECTION] Inputs support
|
||||
// [SECTION] Clipper support
|
||||
@ -472,7 +472,7 @@ template<typename T> static inline T ImSubClampOverflow(T a, T b, T mn, T mx)
|
||||
// - Misc maths helpers
|
||||
static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y); }
|
||||
static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y); }
|
||||
static inline ImVec2 ImClamp(const ImVec2& v, const ImVec2& mn, ImVec2 mx) { return ImVec2((v.x < mn.x) ? mn.x : (v.x > mx.x) ? mx.x : v.x, (v.y < mn.y) ? mn.y : (v.y > mx.y) ? mx.y : v.y); }
|
||||
static inline ImVec2 ImClamp(const ImVec2& v, const ImVec2&mn, const ImVec2&mx) { return ImVec2((v.x < mn.x) ? mn.x : (v.x > mx.x) ? mx.x : v.x, (v.y < mn.y) ? mn.y : (v.y > mx.y) ? mx.y : v.y); }
|
||||
static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t) { return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t); }
|
||||
static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); }
|
||||
static inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); }
|
||||
@ -798,6 +798,40 @@ struct ImDrawDataBuilder
|
||||
ImDrawDataBuilder() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Data types support
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct ImGuiDataVarInfo
|
||||
{
|
||||
ImGuiDataType Type;
|
||||
ImU32 Count; // 1+
|
||||
ImU32 Offset; // Offset in parent structure
|
||||
void* GetVarPtr(void* parent) const { return (void*)((unsigned char*)parent + Offset); }
|
||||
};
|
||||
|
||||
struct ImGuiDataTypeStorage
|
||||
{
|
||||
ImU8 Data[8]; // Opaque storage to fit any data up to ImGuiDataType_COUNT
|
||||
};
|
||||
|
||||
// Type information associated to one ImGuiDataType. Retrieve with DataTypeGetInfo().
|
||||
struct ImGuiDataTypeInfo
|
||||
{
|
||||
size_t Size; // Size in bytes
|
||||
const char* Name; // Short descriptive name for the type, for debugging
|
||||
const char* PrintFmt; // Default printf format for the type
|
||||
const char* ScanFmt; // Default scanf format for the type
|
||||
};
|
||||
|
||||
// Extend ImGuiDataType_
|
||||
enum ImGuiDataTypePrivate_
|
||||
{
|
||||
ImGuiDataType_String = ImGuiDataType_COUNT + 1,
|
||||
ImGuiDataType_Pointer,
|
||||
ImGuiDataType_ID,
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Widgets support: flags, enums, data structures
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1177,6 +1211,7 @@ enum ImGuiNextItemDataFlags_
|
||||
ImGuiNextItemDataFlags_HasWidth = 1 << 0,
|
||||
ImGuiNextItemDataFlags_HasOpen = 1 << 1,
|
||||
ImGuiNextItemDataFlags_HasShortcut = 1 << 2,
|
||||
ImGuiNextItemDataFlags_HasRefVal = 1 << 3,
|
||||
};
|
||||
|
||||
struct ImGuiNextItemData
|
||||
@ -1189,7 +1224,8 @@ struct ImGuiNextItemData
|
||||
ImGuiKeyChord Shortcut; // Set by SetNextItemShortcut()
|
||||
ImGuiInputFlags ShortcutFlags; // Set by SetNextItemShortcut()
|
||||
bool OpenVal; // Set by SetNextItemOpen()
|
||||
ImGuiCond OpenCond : 8;
|
||||
ImU8 OpenCond; // Set by SetNextItemOpen()
|
||||
ImGuiDataTypeStorage RefVal; // Not exposed yet, for ImGuiInputTextFlags_ParseEmptyAsRefVal
|
||||
|
||||
ImGuiNextItemData() { memset(this, 0, sizeof(*this)); SelectionUserData = -1; }
|
||||
inline void ClearFlags() { Flags = ImGuiNextItemDataFlags_None; ItemFlags = ImGuiItemFlags_None; } // Also cleared manually by ItemAdd()!
|
||||
@ -1243,7 +1279,8 @@ struct ImGuiWindowStackData
|
||||
{
|
||||
ImGuiWindow* Window;
|
||||
ImGuiLastItemData ParentLastItemDataBackup;
|
||||
ImGuiStackSizes StackSizesOnBegin; // Store size of various stacks for asserting
|
||||
ImGuiStackSizes StackSizesOnBegin; // Store size of various stacks for asserting
|
||||
bool DisabledOverrideReenable; // Non-child window override disabled flag
|
||||
};
|
||||
|
||||
struct ImGuiShrinkWidthItem
|
||||
@ -1262,40 +1299,6 @@ struct ImGuiPtrOrIndex
|
||||
ImGuiPtrOrIndex(int index) { Ptr = NULL; Index = index; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Data types support
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct ImGuiDataVarInfo
|
||||
{
|
||||
ImGuiDataType Type;
|
||||
ImU32 Count; // 1+
|
||||
ImU32 Offset; // Offset in parent structure
|
||||
void* GetVarPtr(void* parent) const { return (void*)((unsigned char*)parent + Offset); }
|
||||
};
|
||||
|
||||
struct ImGuiDataTypeTempStorage
|
||||
{
|
||||
ImU8 Data[8]; // Can fit any data up to ImGuiDataType_COUNT
|
||||
};
|
||||
|
||||
// Type information associated to one ImGuiDataType. Retrieve with DataTypeGetInfo().
|
||||
struct ImGuiDataTypeInfo
|
||||
{
|
||||
size_t Size; // Size in bytes
|
||||
const char* Name; // Short descriptive name for the type, for debugging
|
||||
const char* PrintFmt; // Default printf format for the type
|
||||
const char* ScanFmt; // Default scanf format for the type
|
||||
};
|
||||
|
||||
// Extend ImGuiDataType_
|
||||
enum ImGuiDataTypePrivate_
|
||||
{
|
||||
ImGuiDataType_String = ImGuiDataType_COUNT + 1,
|
||||
ImGuiDataType_Pointer,
|
||||
ImGuiDataType_ID,
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Popup support
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1582,6 +1585,7 @@ enum ImGuiNavLayer
|
||||
ImGuiNavLayer_COUNT
|
||||
};
|
||||
|
||||
// Storage for navigation query/results
|
||||
struct ImGuiNavItemData
|
||||
{
|
||||
ImGuiWindow* Window; // Init,Move // Best candidate window (result->ItemWindow->RootWindowForNav == request->Window)
|
||||
@ -1598,6 +1602,7 @@ struct ImGuiNavItemData
|
||||
void Clear() { Window = NULL; ID = FocusScopeId = 0; InFlags = 0; SelectionUserData = -1; DistBox = DistCenter = DistAxial = FLT_MAX; }
|
||||
};
|
||||
|
||||
// Storage for PushFocusScope()
|
||||
struct ImGuiFocusScopeData
|
||||
{
|
||||
ImGuiID ID;
|
||||
@ -1963,10 +1968,11 @@ struct ImGuiContext
|
||||
ImGuiID DebugHookIdInfo; // Will call core hooks: DebugHookIdInfo() from GetID functions, used by ID Stack Tool [next HoveredId/ActiveId to not pull in an extra cache-line]
|
||||
ImGuiID HoveredId; // Hovered widget, filled during the frame
|
||||
ImGuiID HoveredIdPreviousFrame;
|
||||
bool HoveredIdAllowOverlap;
|
||||
bool HoveredIdDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0.
|
||||
float HoveredIdTimer; // Measure contiguous hovering time
|
||||
float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active
|
||||
bool HoveredIdAllowOverlap;
|
||||
bool HoveredIdDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0.
|
||||
bool ItemUnclipByLog; // Disable ItemAdd() clipping, essentially a memory-locality friendly copy of LogEnabled
|
||||
ImGuiID ActiveId; // Active widget
|
||||
ImGuiID ActiveIdIsAlive; // Active widget has been seen this frame (we can't use a bool as the ActiveId may change within the frame)
|
||||
float ActiveIdTimer;
|
||||
@ -2033,11 +2039,11 @@ struct ImGuiContext
|
||||
ImGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusedWindow'
|
||||
ImGuiID NavId; // Focused item for navigation
|
||||
ImGuiID NavFocusScopeId; // Focused focus scope (e.g. selection code often wants to "clear other items" when landing on an item of the same scope)
|
||||
ImVector<ImGuiFocusScopeData> NavFocusRoute; // Reversed copy focus scope stack for NavId (should contains NavFocusScopeId). This essentially follow the window->ParentWindowForFocusRoute chain.
|
||||
ImGuiID NavActivateId; // ~~ (g.ActiveId == 0) && (IsKeyPressed(ImGuiKey_Space) || IsKeyDown(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_NavGamepadActivate)) ? NavId : 0, also set when calling ActivateItem()
|
||||
ImGuiID NavActivateDownId; // ~~ IsKeyDown(ImGuiKey_Space) || IsKeyDown(ImGuiKey_Enter) || IsKeyDown(ImGuiKey_NavGamepadActivate) ? NavId : 0
|
||||
ImGuiID NavActivatePressedId; // ~~ IsKeyPressed(ImGuiKey_Space) || IsKeyPressed(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_NavGamepadActivate) ? NavId : 0 (no repeat)
|
||||
ImGuiActivateFlags NavActivateFlags;
|
||||
ImVector<ImGuiFocusScopeData> NavFocusRoute; // Reversed copy focus scope stack for NavId (should contains NavFocusScopeId). This essentially follow the window->ParentWindowForFocusRoute chain.
|
||||
ImGuiID NavHighlightActivatedId;
|
||||
float NavHighlightActivatedTimer;
|
||||
ImGuiID NavJustMovedToId; // Just navigated to this id (result of a successfully MoveRequest).
|
||||
@ -2150,6 +2156,7 @@ struct ImGuiContext
|
||||
ImGuiInputTextDeactivatedState InputTextDeactivatedState;
|
||||
ImFont InputTextPasswordFont;
|
||||
ImGuiID TempInputId; // Temporary text input when CTRL+clicking on a slider, etc.
|
||||
ImGuiDataTypeStorage DataTypeZeroValue; // 0 for all data types
|
||||
int BeginMenuDepth;
|
||||
int BeginComboDepth;
|
||||
ImGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets
|
||||
@ -2162,13 +2169,14 @@ struct ImGuiContext
|
||||
ImGuiComboPreviewData ComboPreviewData;
|
||||
ImRect WindowResizeBorderExpectedRect; // Expected border rect, switch to relative edit if moving
|
||||
bool WindowResizeRelativeMode;
|
||||
short ScrollbarSeekMode; // 0: relative, -1/+1: prev/next page.
|
||||
float ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage?
|
||||
float SliderGrabClickOffset;
|
||||
float SliderCurrentAccum; // Accumulated slider delta when using navigation controls.
|
||||
bool SliderCurrentAccumDirty; // Has the accumulated slider delta changed since last time we tried to apply it?
|
||||
bool DragCurrentAccumDirty;
|
||||
float DragCurrentAccum; // Accumulator for dragging modification. Always high-precision, not rounded by end-user precision settings
|
||||
float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio
|
||||
float ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage?
|
||||
float DisabledAlphaBackup; // Backup for style.Alpha for BeginDisabled()
|
||||
short DisabledStackSize;
|
||||
short LockMarkEdited;
|
||||
@ -2273,6 +2281,7 @@ struct ImGuiContext
|
||||
HoveredIdAllowOverlap = false;
|
||||
HoveredIdDisabled = false;
|
||||
HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f;
|
||||
ItemUnclipByLog = false;
|
||||
ActiveId = 0;
|
||||
ActiveIdIsAlive = 0;
|
||||
ActiveIdTimer = 0.0f;
|
||||
@ -2370,19 +2379,21 @@ struct ImGuiContext
|
||||
MouseStationaryTimer = 0.0f;
|
||||
|
||||
TempInputId = 0;
|
||||
memset(&DataTypeZeroValue, 0, sizeof(DataTypeZeroValue));
|
||||
BeginMenuDepth = BeginComboDepth = 0;
|
||||
ColorEditOptions = ImGuiColorEditFlags_DefaultOptions_;
|
||||
ColorEditCurrentID = ColorEditSavedID = 0;
|
||||
ColorEditSavedHue = ColorEditSavedSat = 0.0f;
|
||||
ColorEditSavedColor = 0;
|
||||
WindowResizeRelativeMode = false;
|
||||
ScrollbarSeekMode = 0;
|
||||
ScrollbarClickDeltaToGrabCenter = 0.0f;
|
||||
SliderGrabClickOffset = 0.0f;
|
||||
SliderCurrentAccum = 0.0f;
|
||||
SliderCurrentAccumDirty = false;
|
||||
DragCurrentAccumDirty = false;
|
||||
DragCurrentAccum = 0.0f;
|
||||
DragSpeedDefaultRatio = 1.0f / 100.0f;
|
||||
ScrollbarClickDeltaToGrabCenter = 0.0f;
|
||||
DisabledAlphaBackup = 0.0f;
|
||||
DisabledStackSize = 0;
|
||||
LockMarkEdited = 0;
|
||||
@ -2507,12 +2518,14 @@ struct IMGUI_API ImGuiWindow
|
||||
ImVec2 WindowPadding; // Window padding at the time of Begin().
|
||||
float WindowRounding; // Window rounding at the time of Begin(). May be clamped lower to avoid rendering artifacts with title bar, menu bar etc.
|
||||
float WindowBorderSize; // Window border size at the time of Begin().
|
||||
float TitleBarHeight, MenuBarHeight;
|
||||
float DecoOuterSizeX1, DecoOuterSizeY1; // Left/Up offsets. Sum of non-scrolling outer decorations (X1 generally == 0.0f. Y1 generally = TitleBarHeight + MenuBarHeight). Locked during Begin().
|
||||
float DecoOuterSizeX2, DecoOuterSizeY2; // Right/Down offsets (X2 generally == ScrollbarSize.x, Y2 == ScrollbarSizes.y).
|
||||
float DecoInnerSizeX1, DecoInnerSizeY1; // Applied AFTER/OVER InnerRect. Specialized for Tables as they use specialized form of clipping and frozen rows/columns are inside InnerRect (and not part of regular decoration sizes).
|
||||
int NameBufLen; // Size of buffer storing Name. May be larger than strlen(Name)!
|
||||
ImGuiID MoveId; // == window->GetID("#MOVE")
|
||||
ImGuiID ChildId; // ID of corresponding item in parent window (for navigation to return from child window to parent window)
|
||||
ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling)
|
||||
ImVec2 Scroll;
|
||||
ImVec2 ScrollMax;
|
||||
ImVec2 ScrollTarget; // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change)
|
||||
@ -2539,7 +2552,6 @@ struct IMGUI_API ImGuiWindow
|
||||
short BeginOrderWithinParent; // Begin() order within immediate parent window, if we are a child window. Otherwise 0.
|
||||
short BeginOrderWithinContext; // Begin() order within entire imgui context. This is mostly used for debugging submission order related issues.
|
||||
short FocusOrder; // Order within WindowsFocusOrder[], altered when windows are focused.
|
||||
ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling)
|
||||
ImS8 AutoFitFramesX, AutoFitFramesY;
|
||||
bool AutoFitOnlyGrows;
|
||||
ImGuiDir AutoPosLastDirection;
|
||||
@ -2608,10 +2620,8 @@ public:
|
||||
// We don't use g.FontSize because the window may be != g.CurrentWindow.
|
||||
ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
|
||||
float CalcFontSize() const { ImGuiContext& g = *Ctx; float scale = g.FontBaseSize * FontWindowScale; if (ParentWindow) scale *= ParentWindow->FontWindowScale; return scale; }
|
||||
float TitleBarHeight() const { ImGuiContext& g = *Ctx; return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + g.Style.FramePadding.y * 2.0f; }
|
||||
ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight())); }
|
||||
float MenuBarHeight() const { ImGuiContext& g = *Ctx; return (Flags & ImGuiWindowFlags_MenuBar) ? DC.MenuBarOffset.y + CalcFontSize() + g.Style.FramePadding.y * 2.0f : 0.0f; }
|
||||
ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight(); return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight()); }
|
||||
ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight)); }
|
||||
ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight; return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -2992,7 +3002,7 @@ namespace ImGui
|
||||
{
|
||||
// Windows
|
||||
// We should always have a CurrentWindow in the stack (there is an implicit "Debug" window)
|
||||
// If this ever crash because g.CurrentWindow is NULL it means that either
|
||||
// If this ever crashes because g.CurrentWindow is NULL, it means that either:
|
||||
// - ImGui::NewFrame() has never been called, which is illegal.
|
||||
// - You are calling ImGui functions after ImGui::EndFrame()/ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal.
|
||||
inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; }
|
||||
@ -3124,6 +3134,8 @@ namespace ImGui
|
||||
IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled);
|
||||
IMGUI_API void PopItemFlag();
|
||||
IMGUI_API const ImGuiDataVarInfo* GetStyleVarInfo(ImGuiStyleVar idx);
|
||||
IMGUI_API void BeginDisabledOverrideReenable();
|
||||
IMGUI_API void EndDisabledOverrideReenable();
|
||||
|
||||
// Logging/Capture
|
||||
IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name.
|
||||
@ -3450,7 +3462,7 @@ namespace ImGui
|
||||
IMGUI_API const ImGuiDataTypeInfo* DataTypeGetInfo(ImGuiDataType data_type);
|
||||
IMGUI_API int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* p_data, const char* format);
|
||||
IMGUI_API void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, const void* arg_1, const void* arg_2);
|
||||
IMGUI_API bool DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format);
|
||||
IMGUI_API bool DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format, void* p_data_when_empty = NULL);
|
||||
IMGUI_API int DataTypeCompare(ImGuiDataType data_type, const void* arg_1, const void* arg_2);
|
||||
IMGUI_API bool DataTypeClamp(ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max);
|
||||
|
||||
@ -3461,6 +3473,7 @@ namespace ImGui
|
||||
IMGUI_API bool TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format, const void* p_clamp_min = NULL, const void* p_clamp_max = NULL);
|
||||
inline bool TempInputIsActive(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.ActiveId == id && g.TempInputId == id); }
|
||||
inline ImGuiInputTextState* GetInputTextState(ImGuiID id) { ImGuiContext& g = *GImGui; return (id != 0 && g.InputTextState.ID == id) ? &g.InputTextState : NULL; } // Get input text state if active
|
||||
IMGUI_API void SetNextItemRefVal(ImGuiDataType data_type, void* p_data);
|
||||
|
||||
// Color
|
||||
IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags);
|
||||
@ -3492,6 +3505,7 @@ namespace ImGui
|
||||
IMGUI_API void DebugDrawCursorPos(ImU32 col = IM_COL32(255, 0, 0, 255));
|
||||
IMGUI_API void DebugDrawLineExtents(ImU32 col = IM_COL32(255, 0, 0, 255));
|
||||
IMGUI_API void DebugDrawItemRect(ImU32 col = IM_COL32(255, 0, 0, 255));
|
||||
IMGUI_API void DebugTextUnformattedWithLocateItem(const char* line_begin, const char* line_end);
|
||||
IMGUI_API void DebugLocateItem(ImGuiID target_id); // Call sparingly: only 1 at the same time!
|
||||
IMGUI_API void DebugLocateItemOnHover(ImGuiID target_id); // Only call on reaction to a mouse Hover: because only 1 at the same time!
|
||||
IMGUI_API void DebugLocateItemResolveWithLastItem();
|
||||
|
21
external/imgui/imgui/imgui_tables.cpp
vendored
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.7
|
||||
// dear imgui, v1.90.8
|
||||
// (tables and columns code)
|
||||
|
||||
/*
|
||||
@ -437,6 +437,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
// For non-scrolling tables, WorkRect == OuterRect == InnerRect.
|
||||
// But at this point we do NOT have a correct value for .Max.y (unless a height has been explicitly passed in). It will only be updated in EndTable().
|
||||
table->WorkRect = table->OuterRect = table->InnerRect = outer_rect;
|
||||
table->HasScrollbarYPrev = table->HasScrollbarYCurr = false;
|
||||
}
|
||||
|
||||
// Push a standardized ID for both child-using and not-child-using tables
|
||||
@ -1490,9 +1491,13 @@ void ImGui::EndTable()
|
||||
}
|
||||
else if (temp_data->UserOuterSize.x <= 0.0f)
|
||||
{
|
||||
const float decoration_size = table->TempData->AngledHeadersExtraWidth + ((table->Flags & ImGuiTableFlags_ScrollX) ? inner_window->ScrollbarSizes.x : 0.0f);
|
||||
outer_window->DC.IdealMaxPos.x = ImMax(outer_window->DC.IdealMaxPos.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth + decoration_size - temp_data->UserOuterSize.x);
|
||||
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, ImMin(table->OuterRect.Max.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth));
|
||||
// Some references for this: #7651 + tests "table_reported_size", "table_reported_size_outer" equivalent Y block
|
||||
// - Checking for ImGuiTableFlags_ScrollX/ScrollY flag makes us a frame ahead when disabling those flags.
|
||||
// - FIXME-TABLE: Would make sense to pre-compute expected scrollbar visibility/sizes to generally save a frame of feedback.
|
||||
const float inner_content_max_x = table->OuterRect.Min.x + table->ColumnsAutoFitWidth; // Slightly misleading name but used for code symmetry with inner_content_max_y
|
||||
const float decoration_size = table->TempData->AngledHeadersExtraWidth + ((table->Flags & ImGuiTableFlags_ScrollY) ? inner_window->ScrollbarSizes.x : 0.0f);
|
||||
outer_window->DC.IdealMaxPos.x = ImMax(outer_window->DC.IdealMaxPos.x, inner_content_max_x + decoration_size - temp_data->UserOuterSize.x);
|
||||
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, ImMin(table->OuterRect.Max.x, inner_content_max_x + decoration_size));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1500,9 +1505,9 @@ void ImGui::EndTable()
|
||||
}
|
||||
if (temp_data->UserOuterSize.y <= 0.0f)
|
||||
{
|
||||
const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollY) ? inner_window->ScrollbarSizes.y : 0.0f;
|
||||
const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollX) ? inner_window->ScrollbarSizes.y : 0.0f;
|
||||
outer_window->DC.IdealMaxPos.y = ImMax(outer_window->DC.IdealMaxPos.y, inner_content_max_y + decoration_size - temp_data->UserOuterSize.y);
|
||||
outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, ImMin(table->OuterRect.Max.y, inner_content_max_y));
|
||||
outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, ImMin(table->OuterRect.Max.y, inner_content_max_y + decoration_size));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2795,7 +2800,7 @@ ImGuiTableSortSpecs* ImGui::TableGetSortSpecs()
|
||||
static inline ImGuiSortDirection TableGetColumnAvailSortDirection(ImGuiTableColumn* column, int n)
|
||||
{
|
||||
IM_ASSERT(n < column->SortDirectionsAvailCount);
|
||||
return (column->SortDirectionsAvailList >> (n << 1)) & 0x03;
|
||||
return (ImGuiSortDirection)((column->SortDirectionsAvailList >> (n << 1)) & 0x03);
|
||||
}
|
||||
|
||||
// Fix sort direction if currently set on a value which is unavailable (e.g. activating NoSortAscending/NoSortDescending)
|
||||
@ -2949,7 +2954,7 @@ void ImGui::TableSortSpecsBuild(ImGuiTable* table)
|
||||
sort_spec->ColumnUserID = column->UserID;
|
||||
sort_spec->ColumnIndex = (ImGuiTableColumnIdx)column_n;
|
||||
sort_spec->SortOrder = (ImGuiTableColumnIdx)column->SortOrder;
|
||||
sort_spec->SortDirection = column->SortDirection;
|
||||
sort_spec->SortDirection = (ImGuiSortDirection)column->SortDirection;
|
||||
}
|
||||
|
||||
table->SortSpecs.Specs = sort_specs;
|
||||
|
132
external/imgui/imgui/imgui_widgets.cpp
vendored
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.7
|
||||
// dear imgui, v1.90.8
|
||||
// (widgets code)
|
||||
|
||||
/*
|
||||
@ -488,7 +488,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
|
||||
// Default only reacts to left mouse button
|
||||
if ((flags & ImGuiButtonFlags_MouseButtonMask_) == 0)
|
||||
flags |= ImGuiButtonFlags_MouseButtonDefault_;
|
||||
flags |= ImGuiButtonFlags_MouseButtonLeft;
|
||||
|
||||
// Default behavior requires click + release inside bounding box
|
||||
if ((flags & ImGuiButtonFlags_PressedOnMask_) == 0)
|
||||
@ -916,10 +916,10 @@ void ImGui::Scrollbar(ImGuiAxis axis)
|
||||
if (!window->ScrollbarX)
|
||||
rounding_corners |= ImDrawFlags_RoundCornersBottomRight;
|
||||
}
|
||||
float size_avail = window->InnerRect.Max[axis] - window->InnerRect.Min[axis];
|
||||
float size_visible = window->InnerRect.Max[axis] - window->InnerRect.Min[axis];
|
||||
float size_contents = window->ContentSize[axis] + window->WindowPadding[axis] * 2.0f;
|
||||
ImS64 scroll = (ImS64)window->Scroll[axis];
|
||||
ScrollbarEx(bb, id, axis, &scroll, (ImS64)size_avail, (ImS64)size_contents, rounding_corners);
|
||||
ScrollbarEx(bb, id, axis, &scroll, (ImS64)size_visible, (ImS64)size_contents, rounding_corners);
|
||||
window->Scroll[axis] = (float)scroll;
|
||||
}
|
||||
|
||||
@ -929,7 +929,7 @@ void ImGui::Scrollbar(ImGuiAxis axis)
|
||||
// - We store values as normalized ratio and in a form that allows the window content to change while we are holding on a scrollbar
|
||||
// - We handle both horizontal and vertical scrollbars, which makes the terminology not ideal.
|
||||
// Still, the code should probably be made simpler..
|
||||
bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS64* p_scroll_v, ImS64 size_avail_v, ImS64 size_contents_v, ImDrawFlags flags)
|
||||
bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS64* p_scroll_v, ImS64 size_visible_v, ImS64 size_contents_v, ImDrawFlags flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
@ -959,9 +959,9 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
|
||||
|
||||
// Calculate the height of our grabbable box. It generally represent the amount visible (vs the total scrollable amount)
|
||||
// But we maintain a minimum size in pixel to allow for the user to still aim inside.
|
||||
IM_ASSERT(ImMax(size_contents_v, size_avail_v) > 0.0f); // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers.
|
||||
const ImS64 win_size_v = ImMax(ImMax(size_contents_v, size_avail_v), (ImS64)1);
|
||||
const float grab_h_pixels = ImClamp(scrollbar_size_v * ((float)size_avail_v / (float)win_size_v), style.GrabMinSize, scrollbar_size_v);
|
||||
IM_ASSERT(ImMax(size_contents_v, size_visible_v) > 0.0f); // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers.
|
||||
const ImS64 win_size_v = ImMax(ImMax(size_contents_v, size_visible_v), (ImS64)1);
|
||||
const float grab_h_pixels = ImClamp(scrollbar_size_v * ((float)size_visible_v / (float)win_size_v), style.GrabMinSize, scrollbar_size_v);
|
||||
const float grab_h_norm = grab_h_pixels / scrollbar_size_v;
|
||||
|
||||
// Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar().
|
||||
@ -970,7 +970,7 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
|
||||
ItemAdd(bb_frame, id, NULL, ImGuiItemFlags_NoNav);
|
||||
ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_NoNavFocus);
|
||||
|
||||
const ImS64 scroll_max = ImMax((ImS64)1, size_contents_v - size_avail_v);
|
||||
const ImS64 scroll_max = ImMax((ImS64)1, size_contents_v - size_visible_v);
|
||||
float scroll_ratio = ImSaturate((float)*p_scroll_v / (float)scroll_max);
|
||||
float grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v; // Grab position in normalized space
|
||||
if (held && allow_interaction && grab_h_norm < 1.0f)
|
||||
@ -981,29 +981,39 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
|
||||
// Click position in scrollbar normalized space (0.0f->1.0f)
|
||||
const float clicked_v_norm = ImSaturate((mouse_pos_v - scrollbar_pos_v) / scrollbar_size_v);
|
||||
|
||||
bool seek_absolute = false;
|
||||
const int held_dir = (clicked_v_norm < grab_v_norm) ? -1 : (clicked_v_norm > grab_v_norm + grab_h_norm) ? +1 : 0;
|
||||
if (g.ActiveIdIsJustActivated)
|
||||
{
|
||||
// On initial click calculate the distance between mouse and the center of the grab
|
||||
seek_absolute = (clicked_v_norm < grab_v_norm || clicked_v_norm > grab_v_norm + grab_h_norm);
|
||||
if (seek_absolute)
|
||||
g.ScrollbarClickDeltaToGrabCenter = 0.0f;
|
||||
else
|
||||
g.ScrollbarClickDeltaToGrabCenter = clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f;
|
||||
g.ScrollbarSeekMode = (short)held_dir;
|
||||
g.ScrollbarClickDeltaToGrabCenter = (g.ScrollbarSeekMode == 0.0f) ? clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f : 0.0f;
|
||||
}
|
||||
|
||||
// Apply scroll (p_scroll_v will generally point on one member of window->Scroll)
|
||||
// It is ok to modify Scroll here because we are being called in Begin() after the calculation of ContentSize and before setting up our starting position
|
||||
const float scroll_v_norm = ImSaturate((clicked_v_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm * 0.5f) / (1.0f - grab_h_norm));
|
||||
*p_scroll_v = (ImS64)(scroll_v_norm * scroll_max);
|
||||
if (g.ScrollbarSeekMode == 0)
|
||||
{
|
||||
// Absolute seeking
|
||||
const float scroll_v_norm = ImSaturate((clicked_v_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm * 0.5f) / (1.0f - grab_h_norm));
|
||||
*p_scroll_v = (ImS64)(scroll_v_norm * scroll_max);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Page by page
|
||||
if (IsMouseClicked(ImGuiMouseButton_Left, ImGuiInputFlags_Repeat) && held_dir == g.ScrollbarSeekMode)
|
||||
{
|
||||
float page_dir = (g.ScrollbarSeekMode > 0.0f) ? +1.0f : -1.0f;
|
||||
*p_scroll_v = ImClamp(*p_scroll_v + (ImS64)(page_dir * size_visible_v), (ImS64)0, scroll_max);
|
||||
}
|
||||
}
|
||||
|
||||
// Update values for rendering
|
||||
scroll_ratio = ImSaturate((float)*p_scroll_v / (float)scroll_max);
|
||||
grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v;
|
||||
|
||||
// Update distance to grab now that we have seek'ed and saturated
|
||||
if (seek_absolute)
|
||||
g.ScrollbarClickDeltaToGrabCenter = clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f;
|
||||
//if (seek_absolute)
|
||||
// g.ScrollbarClickDeltaToGrabCenter = clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f;
|
||||
}
|
||||
|
||||
// Render
|
||||
@ -1942,28 +1952,30 @@ bool ImGui::Combo(const char* label, int* current_item, const char* (*getter)(vo
|
||||
return false;
|
||||
|
||||
// Display items
|
||||
// FIXME-OPT: Use clipper (but we need to disable it on the appearing frame to make sure our call to SetItemDefaultFocus() is processed)
|
||||
bool value_changed = false;
|
||||
for (int i = 0; i < items_count; i++)
|
||||
{
|
||||
const char* item_text = getter(user_data, i);
|
||||
if (item_text == NULL)
|
||||
item_text = "*Unknown item*";
|
||||
|
||||
PushID(i);
|
||||
const bool item_selected = (i == *current_item);
|
||||
if (Selectable(item_text, item_selected) && *current_item != i)
|
||||
ImGuiListClipper clipper;
|
||||
clipper.Begin(items_count);
|
||||
clipper.IncludeItemByIndex(*current_item);
|
||||
while (clipper.Step())
|
||||
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
|
||||
{
|
||||
value_changed = true;
|
||||
*current_item = i;
|
||||
const char* item_text = getter(user_data, i);
|
||||
if (item_text == NULL)
|
||||
item_text = "*Unknown item*";
|
||||
|
||||
PushID(i);
|
||||
const bool item_selected = (i == *current_item);
|
||||
if (Selectable(item_text, item_selected) && *current_item != i)
|
||||
{
|
||||
value_changed = true;
|
||||
*current_item = i;
|
||||
}
|
||||
if (item_selected)
|
||||
SetItemDefaultFocus();
|
||||
PopID();
|
||||
}
|
||||
if (item_selected)
|
||||
SetItemDefaultFocus();
|
||||
PopID();
|
||||
}
|
||||
|
||||
EndCombo();
|
||||
|
||||
if (value_changed)
|
||||
MarkItemEdited(g.LastItemData.ID);
|
||||
|
||||
@ -2129,17 +2141,24 @@ void ImGui::DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, const
|
||||
|
||||
// User can input math operators (e.g. +100) to edit a numerical values.
|
||||
// NB: This is _not_ a full expression evaluator. We should probably add one and replace this dumb mess..
|
||||
bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format)
|
||||
bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format, void* p_data_when_empty)
|
||||
{
|
||||
// Copy the value in an opaque buffer so we can compare at the end of the function if it changed at all.
|
||||
const ImGuiDataTypeInfo* type_info = DataTypeGetInfo(data_type);
|
||||
ImGuiDataTypeStorage data_backup;
|
||||
memcpy(&data_backup, p_data, type_info->Size);
|
||||
|
||||
while (ImCharIsBlankA(*buf))
|
||||
buf++;
|
||||
if (!buf[0])
|
||||
{
|
||||
if (p_data_when_empty != NULL)
|
||||
{
|
||||
memcpy(p_data, p_data_when_empty, type_info->Size);
|
||||
return memcmp(&data_backup, p_data, type_info->Size) != 0;
|
||||
}
|
||||
return false;
|
||||
|
||||
// Copy the value in an opaque buffer so we can compare at the end of the function if it changed at all.
|
||||
const ImGuiDataTypeInfo* type_info = DataTypeGetInfo(data_type);
|
||||
ImGuiDataTypeTempStorage data_backup;
|
||||
memcpy(&data_backup, p_data, type_info->Size);
|
||||
}
|
||||
|
||||
// Sanitize format
|
||||
// - For float/double we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in, so force them into %f and %lf
|
||||
@ -3459,11 +3478,11 @@ bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG
|
||||
{
|
||||
// Backup old value
|
||||
size_t data_type_size = type_info->Size;
|
||||
ImGuiDataTypeTempStorage data_backup;
|
||||
ImGuiDataTypeStorage data_backup;
|
||||
memcpy(&data_backup, p_data, data_type_size);
|
||||
|
||||
// Apply new value (or operations) then clamp
|
||||
DataTypeApplyFromText(data_buf, data_type, p_data, format);
|
||||
DataTypeApplyFromText(data_buf, data_type, p_data, format, NULL);
|
||||
if (p_clamp_min || p_clamp_max)
|
||||
{
|
||||
if (p_clamp_min && p_clamp_max && DataTypeCompare(data_type, p_clamp_min, p_clamp_max) > 0)
|
||||
@ -3479,6 +3498,13 @@ bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
void ImGui::SetNextItemRefVal(ImGuiDataType data_type, void* p_data)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasRefVal;
|
||||
memcpy(&g.NextItemData.RefVal, p_data, DataTypeGetInfo(data_type)->Size);
|
||||
}
|
||||
|
||||
// Note: p_data, p_step, p_step_fast are _pointers_ to a memory address holding the data. For an Input widget, p_step and p_step_fast are optional.
|
||||
// Read code of e.g. InputFloat(), InputInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
|
||||
bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags)
|
||||
@ -3493,8 +3519,13 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
||||
if (format == NULL)
|
||||
format = DataTypeGetInfo(data_type)->PrintFmt;
|
||||
|
||||
void* p_data_default = (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasRefVal) ? &g.NextItemData.RefVal : &g.DataTypeZeroValue;
|
||||
|
||||
char buf[64];
|
||||
DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, p_data, format);
|
||||
if ((flags & ImGuiInputTextFlags_DisplayEmptyRefVal) && DataTypeCompare(data_type, p_data, p_data_default) == 0)
|
||||
buf[0] = 0;
|
||||
else
|
||||
DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, p_data, format);
|
||||
|
||||
flags |= ImGuiInputTextFlags_AutoSelectAll | (ImGuiInputTextFlags)ImGuiInputTextFlags_NoMarkEdited; // We call MarkItemEdited() ourselves by comparing the actual data rather than the string.
|
||||
flags |= (ImGuiInputTextFlags)ImGuiInputTextFlags_LocalizeDecimalPoint;
|
||||
@ -3503,7 +3534,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
||||
if (p_step == NULL)
|
||||
{
|
||||
if (InputText(label, buf, IM_ARRAYSIZE(buf), flags))
|
||||
value_changed = DataTypeApplyFromText(buf, data_type, p_data, format);
|
||||
value_changed = DataTypeApplyFromText(buf, data_type, p_data, format, (flags & ImGuiInputTextFlags_ParseEmptyRefVal) ? p_data_default : NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3513,7 +3544,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
||||
PushID(label);
|
||||
SetNextItemWidth(ImMax(1.0f, CalcItemWidth() - (button_size + style.ItemInnerSpacing.x) * 2));
|
||||
if (InputText("", buf, IM_ARRAYSIZE(buf), flags)) // PushId(label) + "" gives us the expected ID from outside point of view
|
||||
value_changed = DataTypeApplyFromText(buf, data_type, p_data, format);
|
||||
value_changed = DataTypeApplyFromText(buf, data_type, p_data, format, (flags & ImGuiInputTextFlags_ParseEmptyRefVal) ? p_data_default : NULL);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Inputable);
|
||||
|
||||
// Step buttons
|
||||
@ -6485,7 +6516,7 @@ void ImGui::SetNextItemOpen(bool is_open, ImGuiCond cond)
|
||||
return;
|
||||
g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasOpen;
|
||||
g.NextItemData.OpenVal = is_open;
|
||||
g.NextItemData.OpenCond = cond ? cond : ImGuiCond_Always;
|
||||
g.NextItemData.OpenCond = (ImU8)(cond ? cond : ImGuiCond_Always);
|
||||
}
|
||||
|
||||
// CollapsingHeader returns true when opened but do not indent nor push into the ID stack (because of the ImGuiTreeNodeFlags_NoTreePushOnOpen flag).
|
||||
@ -7001,6 +7032,7 @@ bool ImGui::ListBox(const char* label, int* current_item, const char* (*getter)(
|
||||
bool value_changed = false;
|
||||
ImGuiListClipper clipper;
|
||||
clipper.Begin(items_count, GetTextLineHeightWithSpacing()); // We know exactly our line height here so we pass it as a minor optimization, but generally you don't need to.
|
||||
clipper.IncludeItemByIndex(*current_item);
|
||||
while (clipper.Step())
|
||||
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
|
||||
{
|
||||
@ -7519,7 +7551,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
// Menu inside an horizontal menu bar
|
||||
// Selectable extend their highlight by half ItemSpacing in each direction.
|
||||
// For ChildMenu, the popup position will be overwritten by the call to FindBestWindowPosForPopup() in Begin()
|
||||
popup_pos = ImVec2(pos.x - 1.0f - IM_TRUNC(style.ItemSpacing.x * 0.5f), pos.y - style.FramePadding.y + window->MenuBarHeight());
|
||||
popup_pos = ImVec2(pos.x - 1.0f - IM_TRUNC(style.ItemSpacing.x * 0.5f), pos.y - style.FramePadding.y + window->MenuBarHeight);
|
||||
window->DC.CursorPos.x += IM_TRUNC(style.ItemSpacing.x * 0.5f);
|
||||
PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y));
|
||||
float w = label_size.x;
|
||||
@ -8285,7 +8317,7 @@ ImGuiTabItem* ImGui::TabBarFindTabByOrder(ImGuiTabBar* tab_bar, int order)
|
||||
|
||||
ImGuiTabItem* ImGui::TabBarGetCurrentTab(ImGuiTabBar* tab_bar)
|
||||
{
|
||||
if (tab_bar->LastTabItemIdx <= 0 || tab_bar->LastTabItemIdx >= tab_bar->Tabs.Size)
|
||||
if (tab_bar->LastTabItemIdx < 0 || tab_bar->LastTabItemIdx >= tab_bar->Tabs.Size)
|
||||
return NULL;
|
||||
return &tab_bar->Tabs[tab_bar->LastTabItemIdx];
|
||||
}
|
||||
|
13
external/json/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
cmake_minimum_required(VERSION 3.16...3.24 FATAL_ERROR)
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
if (NOT TARGET nlohmann_json::nlohmann_json)
|
||||
FetchContent_Declare(json
|
||||
URL https://github.com/nlohmann/json/releases/download/v3.11.3/json.tar.xz
|
||||
URL_HASH SHA256=d6c65aca6b1ed68e7a182f4757257b107ae403032760ed6ef121c9d55e81757d
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
FetchContent_MakeAvailable(json)
|
||||
endif()
|
||||
|
6
external/sdl/CMakeLists.txt
vendored
@ -6,6 +6,7 @@ if (NOT TARGET SDL3::SDL3)
|
||||
set(SDL_SHARED OFF CACHE INTERNAL "")
|
||||
set(SDL_STATIC ON CACHE INTERNAL "")
|
||||
#TODO: pic ?
|
||||
set(SDL_DISABLE_ANDROID_JAR OFF CACHE INTERNAL "")
|
||||
|
||||
FetchContent_Declare(SDL3
|
||||
GIT_REPOSITORY https://github.com/libsdl-org/SDL
|
||||
@ -15,7 +16,10 @@ if (NOT TARGET SDL3::SDL3)
|
||||
# made changes that break imgui release 1.90.6
|
||||
#GIT_TAG 1103294d33f47ab4c697bb22a9cf27c79c658630 # tip 15-05-2024
|
||||
#GIT_TAG aacafd62336363077470f678b6217214b3b49473 # tip 28-05-2024
|
||||
GIT_TAG 5fa9432b7d1c1722de93e1ab46e7a9569a47071e # tip 27-05-2024 - before changes made breaking sdl_image
|
||||
#GIT_TAG 5fa9432b7d1c1722de93e1ab46e7a9569a47071e # tip 27-05-2024 - before changes made breaking sdl_image
|
||||
#GIT_TAG 9651ca59187c16079846918483c40d6b5c2f454c # tip 09-06-2024
|
||||
GIT_TAG 657c0135b1ff1685afa1bad63b0417d92f4bcb46 # tip 09-06-2024
|
||||
|
||||
FIND_PACKAGE_ARGS # for the future
|
||||
)
|
||||
FetchContent_MakeAvailable(SDL3)
|
||||
|
3
external/sdl_image/CMakeLists.txt
vendored
@ -17,7 +17,8 @@ if (NOT TARGET SDL3_image::SDL3_image)
|
||||
# waiting on the imgui pr to get merged so i can update sdl <.<
|
||||
#GIT_TAG a45d6e5b84ccc0f3faae6ba7d561709ed600eee7 # tip last check
|
||||
#GIT_TAG a34ccf16f961e6d5a480045eb650fc3dddb4bfaa # tip 14-05-2024
|
||||
GIT_TAG 2fc5310a9a2700fc856663200f94edebeb5e554a # tip 28-05-2024
|
||||
#GIT_TAG 2fc5310a9a2700fc856663200f94edebeb5e554a # tip 28-05-2024
|
||||
GIT_TAG 8eff782fa33d795c9ea1ac42dbe7e17cc9874c78 # tip 09-06-2024
|
||||
FIND_PACKAGE_ARGS # for the future
|
||||
)
|
||||
FetchContent_MakeAvailable(SDL3_image)
|
||||
|
2
external/solanaceae_plugin
vendored
24
flake.lock
generated
@ -20,16 +20,16 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1713189761,
|
||||
"narHash": "sha256-MPp1dBhlY066IeBo+EPGEUN+s+aSUA+LWkvnzKh+rts=",
|
||||
"lastModified": 1718111384,
|
||||
"narHash": "sha256-7tSst0S5FOmcgvNtfy6cjZX5w8CabCVAfAeCkhY4OVg=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ff44be4d8ff33f797ff3e3f87153d4f3b6a85ffb",
|
||||
"rev": "a508a44af0c1b1b57785c34d8b54783536273eeb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "release-23.11",
|
||||
"ref": "release-24.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
@ -63,34 +63,34 @@
|
||||
"sdl3": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1716778470,
|
||||
"narHash": "sha256-/esw8XkLIR7/2HLXaCfsOsEy+Idf6XGsnWGC5yXJipk=",
|
||||
"lastModified": 1718035458,
|
||||
"narHash": "sha256-PGt/GfYUuT7u8UjIU4wvIJhBIMG+wq/fYasSW/4Y00k=",
|
||||
"owner": "libsdl-org",
|
||||
"repo": "SDL",
|
||||
"rev": "5fa9432b7d1c1722de93e1ab46e7a9569a47071e",
|
||||
"rev": "657c0135b1ff1685afa1bad63b0417d92f4bcb46",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "libsdl-org",
|
||||
"repo": "SDL",
|
||||
"rev": "5fa9432b7d1c1722de93e1ab46e7a9569a47071e",
|
||||
"rev": "657c0135b1ff1685afa1bad63b0417d92f4bcb46",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"sdl3_image": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1716394356,
|
||||
"narHash": "sha256-dQ4x7ZbQodOs4PQU90evoa870abC/u0uaVLEqU1nB8k=",
|
||||
"lastModified": 1717528558,
|
||||
"narHash": "sha256-VS5GMxcJgmghmck1FoGJmrt94ubtBr9eGQUmYEMoUZQ=",
|
||||
"owner": "libsdl-org",
|
||||
"repo": "SDL_image",
|
||||
"rev": "2fc5310a9a2700fc856663200f94edebeb5e554a",
|
||||
"rev": "8eff782fa33d795c9ea1ac42dbe7e17cc9874c78",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "libsdl-org",
|
||||
"repo": "SDL_image",
|
||||
"rev": "2fc5310a9a2700fc856663200f94edebeb5e554a",
|
||||
"rev": "8eff782fa33d795c9ea1ac42dbe7e17cc9874c78",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
|
@ -4,18 +4,18 @@
|
||||
# append '.?submodules=1' to the nix commands.
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/release-23.11";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/release-24.05";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
nlohmann-json = {
|
||||
url = "github:nlohmann/json/v3.11.3"; # TODO: read version from file
|
||||
flake = false;
|
||||
};
|
||||
sdl3 = {
|
||||
url = "github:libsdl-org/SDL/5fa9432b7d1c1722de93e1ab46e7a9569a47071e"; # keep in sync this cmake
|
||||
url = "github:libsdl-org/SDL/657c0135b1ff1685afa1bad63b0417d92f4bcb46"; # keep in sync this cmake
|
||||
flake = false;
|
||||
};
|
||||
sdl3_image = {
|
||||
url = "github:libsdl-org/SDL_image/2fc5310a9a2700fc856663200f94edebeb5e554a";
|
||||
url = "github:libsdl-org/SDL_image/8eff782fa33d795c9ea1ac42dbe7e17cc9874c78";
|
||||
flake = false;
|
||||
};
|
||||
};
|
||||
@ -25,6 +25,7 @@
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
stdenv = (pkgs.stdenvAdapters.keepDebugInfo pkgs.stdenv);
|
||||
#stdenv = (pkgs.stdenvAdapters.withCFlags [ "-march=x86-64-v3" ] (pkgs.stdenvAdapters.keepDebugInfo pkgs.stdenv));
|
||||
in {
|
||||
#packages.default = pkgs.stdenv.mkDerivation {
|
||||
packages.default = stdenv.mkDerivation {
|
||||
|
@ -1,11 +1,24 @@
|
||||
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
|
||||
cmake_minimum_required(VERSION 3.9...3.24 FATAL_ERROR)
|
||||
|
||||
########################################
|
||||
|
||||
add_executable(tomato
|
||||
if (TOMATO_MAIN_SO)
|
||||
add_library(tomato MODULE)
|
||||
target_compile_definitions(tomato PUBLIC TOMATO_MAIN_SO)
|
||||
else()
|
||||
add_executable(tomato)
|
||||
endif()
|
||||
|
||||
target_sources(tomato PUBLIC
|
||||
./main.cpp
|
||||
./icon.rc
|
||||
|
||||
./sys_check.hpp
|
||||
./sys_check.cpp
|
||||
|
||||
./json_to_config.hpp
|
||||
./json_to_config.cpp
|
||||
|
||||
./screen.hpp
|
||||
./start_screen.hpp
|
||||
./start_screen.cpp
|
||||
|
@ -151,8 +151,7 @@ void SendImagePopup::sendMemory(
|
||||
}
|
||||
|
||||
// copy paste data to memory
|
||||
original_data.clear();
|
||||
original_data.insert(original_data.begin(), data, data+data_size);
|
||||
original_data = {data, data+data_size};
|
||||
|
||||
if (!load()) {
|
||||
std::cerr << "SIP: failed to load image from memory\n";
|
||||
|
@ -41,7 +41,7 @@ ImageLoaderQOI::ImageResult ImageLoaderQOI::loadFromMemoryRGBA(const uint8_t* da
|
||||
|
||||
auto& new_frame = res.frames.emplace_back();
|
||||
new_frame.ms = 0;
|
||||
new_frame.data.insert(new_frame.data.cbegin(), img_data, img_data+(desc.width*desc.height*4));
|
||||
new_frame.data = {img_data, img_data+(desc.width*desc.height*4)};
|
||||
|
||||
free(img_data);
|
||||
return res;
|
||||
|
@ -47,7 +47,7 @@ ImageLoaderSDLBMP::ImageResult ImageLoaderSDLBMP::loadFromMemoryRGBA(const uint8
|
||||
|
||||
auto& new_frame = res.frames.emplace_back();
|
||||
new_frame.ms = 0;
|
||||
new_frame.data.insert(new_frame.data.cbegin(), (const uint8_t*)conv_surf->pixels, ((const uint8_t*)conv_surf->pixels) + (surf->w*surf->h*4));
|
||||
new_frame.data = {(const uint8_t*)conv_surf->pixels, ((const uint8_t*)conv_surf->pixels) + (surf->w*surf->h*4)};
|
||||
|
||||
SDL_UnlockSurface(conv_surf);
|
||||
SDL_DestroySurface(conv_surf);
|
||||
|
@ -99,7 +99,7 @@ ImageLoaderSDLImage::ImageResult ImageLoaderSDLImage::loadFromMemoryRGBA(const u
|
||||
|
||||
auto& new_frame = res.frames.emplace_back();
|
||||
new_frame.ms = anim->delays[i];
|
||||
new_frame.data.insert(new_frame.data.cbegin(), (const uint8_t*)conv_surf->pixels, ((const uint8_t*)conv_surf->pixels) + (anim->w*anim->h*4));
|
||||
new_frame.data = {(const uint8_t*)conv_surf->pixels, ((const uint8_t*)conv_surf->pixels) + (anim->w*anim->h*4)};
|
||||
|
||||
SDL_UnlockSurface(conv_surf);
|
||||
SDL_DestroySurface(conv_surf);
|
||||
|
@ -41,7 +41,7 @@ ImageLoaderSTB::ImageResult ImageLoaderSTB::loadFromMemoryRGBA(const uint8_t* da
|
||||
for (int i = 0; i < z; i++) {
|
||||
auto& new_frame = res.frames.emplace_back();
|
||||
new_frame.ms = delays[i];
|
||||
new_frame.data.insert(new_frame.data.cbegin(), img_data + (i*stride), img_data + ((i+1)*stride));
|
||||
new_frame.data = {img_data + (i*stride), img_data + ((i+1)*stride)};
|
||||
}
|
||||
|
||||
stbi_image_free(delays); // hope this is right
|
||||
@ -62,7 +62,7 @@ ImageLoaderSTB::ImageResult ImageLoaderSTB::loadFromMemoryRGBA(const uint8_t* da
|
||||
|
||||
auto& new_frame = res.frames.emplace_back();
|
||||
new_frame.ms = 0;
|
||||
new_frame.data.insert(new_frame.data.cbegin(), img_data, img_data+(x*y*4));
|
||||
new_frame.data = {img_data, img_data+(x*y*4)};
|
||||
|
||||
stbi_image_free(img_data);
|
||||
return res;
|
||||
|
@ -78,7 +78,7 @@ ImageLoaderWebP::ImageResult ImageLoaderWebP::loadFromMemoryRGBA(const uint8_t*
|
||||
auto& new_frame = res.frames.emplace_back();
|
||||
new_frame.ms = timestamp-prev_timestamp;
|
||||
prev_timestamp = timestamp;
|
||||
new_frame.data.insert(new_frame.data.end(), buf, buf+(res.width*res.height*4));
|
||||
new_frame.data = {buf, buf+(res.width*res.height*4)};
|
||||
}
|
||||
|
||||
assert(anim_info.frame_count == res.frames.size());
|
||||
|
67
src/json_to_config.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
#include "./json_to_config.hpp"
|
||||
|
||||
#include <solanaceae/util/simple_config_model.hpp>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
bool load_json_into_config(const nlohmann::ordered_json& config_json, SimpleConfigModel& conf) {
|
||||
if (!config_json.is_object()) {
|
||||
std::cerr << "TOMATO error: config file is not an json object!!!\n";
|
||||
return false;
|
||||
}
|
||||
for (const auto& [mod, cats] : config_json.items()) {
|
||||
for (const auto& [cat, cat_v] : cats.items()) {
|
||||
if (cat_v.is_object()) {
|
||||
if (cat_v.contains("default")) {
|
||||
const auto& value = cat_v["default"];
|
||||
if (value.is_string()) {
|
||||
conf.set(mod, cat, value.get_ref<const std::string&>());
|
||||
} else if (value.is_boolean()) {
|
||||
conf.set(mod, cat, value.get_ref<const bool&>());
|
||||
} else if (value.is_number_float()) {
|
||||
conf.set(mod, cat, value.get_ref<const double&>());
|
||||
} else if (value.is_number_integer()) {
|
||||
conf.set(mod, cat, value.get_ref<const int64_t&>());
|
||||
} else {
|
||||
std::cerr << "JSON error: wrong value type in " << mod << "::" << cat << " = " << value << "\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (cat_v.contains("entries")) {
|
||||
for (const auto& [ent, ent_v] : cat_v["entries"].items()) {
|
||||
if (ent_v.is_string()) {
|
||||
conf.set(mod, cat, ent, ent_v.get_ref<const std::string&>());
|
||||
} else if (ent_v.is_boolean()) {
|
||||
conf.set(mod, cat, ent, ent_v.get_ref<const bool&>());
|
||||
} else if (ent_v.is_number_float()) {
|
||||
conf.set(mod, cat, ent, ent_v.get_ref<const double&>());
|
||||
} else if (ent_v.is_number_integer()) {
|
||||
conf.set(mod, cat, ent, ent_v.get_ref<const int64_t&>());
|
||||
} else {
|
||||
std::cerr << "JSON error: wrong value type in " << mod << "::" << cat << "::" << ent << " = " << ent_v << "\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cat_v.is_string()) {
|
||||
conf.set(mod, cat, cat_v.get_ref<const std::string&>());
|
||||
} else if (cat_v.is_boolean()) {
|
||||
conf.set(mod, cat, cat_v.get_ref<const bool&>());
|
||||
} else if (cat_v.is_number_float()) {
|
||||
conf.set(mod, cat, cat_v.get_ref<const double&>());
|
||||
} else if (cat_v.is_number_integer()) {
|
||||
conf.set(mod, cat, cat_v.get_ref<const int64_t&>());
|
||||
} else {
|
||||
std::cerr << "JSON error: wrong value type in " << mod << "::" << cat << " = " << cat_v << "\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
9
src/json_to_config.hpp
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
// fwd
|
||||
struct SimpleConfigModel;
|
||||
|
||||
bool load_json_into_config(const nlohmann::ordered_json& config_json, SimpleConfigModel& conf);
|
||||
|
62
src/main.cpp
@ -8,18 +8,37 @@
|
||||
#include "./theme.hpp"
|
||||
#include "./chat_gui/theme.hpp"
|
||||
|
||||
#include "./sys_check.hpp"
|
||||
|
||||
#include "./start_screen.hpp"
|
||||
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// better args
|
||||
std::vector<std::string_view> args;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
args.push_back(argv[i]);
|
||||
}
|
||||
|
||||
runSysCheck();
|
||||
|
||||
#ifdef __ANDROID__
|
||||
// change current working dir to internal storage
|
||||
std::filesystem::current_path(SDL_AndroidGetInternalStoragePath());
|
||||
#endif
|
||||
|
||||
// setup hints
|
||||
#ifndef __ANDROID__
|
||||
if (SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1") != SDL_TRUE) {
|
||||
std::cerr << "Failed to set '" << SDL_HINT_VIDEO_ALLOW_SCREENSAVER << "' to 1\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
auto last_time_render = std::chrono::steady_clock::now();
|
||||
auto last_time_tick = std::chrono::steady_clock::now();
|
||||
@ -51,16 +70,19 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
SDL_SetRenderVSync(renderer.get(), SDL_RENDERER_VSYNC_ADAPTIVE);
|
||||
|
||||
{
|
||||
SDL_RendererInfo ri;
|
||||
if (SDL_GetRendererInfo(renderer.get(), &ri) == 0) {
|
||||
std::cout << "SDL Renderer: " << ri.name << "\n";
|
||||
}
|
||||
}
|
||||
std::cout << "SDL Renderer: " << SDL_GetRendererName(renderer.get()) << "\n";
|
||||
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
|
||||
// TODO: test android behaviour
|
||||
float display_scale = SDL_GetWindowDisplayScale(window.get());
|
||||
if (display_scale < 0.001f) {
|
||||
// error?
|
||||
display_scale = 1.f;
|
||||
}
|
||||
ImGui::GetStyle().ScaleAllSizes(display_scale);
|
||||
|
||||
Theme theme;
|
||||
if (SDL_GetSystemTheme() == SDL_SYSTEM_THEME_LIGHT) {
|
||||
ImGui::StyleColorsLight();
|
||||
@ -71,29 +93,13 @@ int main(int argc, char** argv) {
|
||||
theme = getDefaultThemeDark();
|
||||
}
|
||||
|
||||
{
|
||||
ImGui::GetIO().Fonts->ClearFonts();
|
||||
ImFontConfig fontcfg;
|
||||
|
||||
// upsampling to int looks almost ok
|
||||
const float font_size_scale = 1.3f;
|
||||
const float font_oversample = 4.f;
|
||||
|
||||
// default font is pixel perfect at 13
|
||||
fontcfg.SizePixels = 13.f * font_size_scale;
|
||||
fontcfg.RasterizerDensity = font_oversample/font_size_scale;
|
||||
// normally density would be set to dpi scale of the display
|
||||
|
||||
ImGui::GetIO().Fonts->AddFontDefault(&fontcfg);
|
||||
ImGui::GetIO().Fonts->Build();
|
||||
}
|
||||
|
||||
ImGui_ImplSDL3_InitForSDLRenderer(window.get(), renderer.get());
|
||||
ImGui_ImplSDLRenderer3_Init(renderer.get());
|
||||
|
||||
std::unique_ptr<Screen> screen = std::make_unique<StartScreen>(renderer.get(), theme);
|
||||
|
||||
std::unique_ptr<Screen> screen = std::make_unique<StartScreen>(args, renderer.get(), theme);
|
||||
|
||||
bool is_background = false;
|
||||
bool quit = false;
|
||||
while (!quit) {
|
||||
auto new_time = std::chrono::steady_clock::now();
|
||||
@ -118,6 +124,10 @@ int main(int argc, char** argv) {
|
||||
if (event.type == SDL_EVENT_QUIT) {
|
||||
quit = true;
|
||||
break;
|
||||
} else if (event.type == SDL_EVENT_WILL_ENTER_BACKGROUND) {
|
||||
is_background = true;
|
||||
} else if (event.type == SDL_EVENT_DID_ENTER_FOREGROUND) {
|
||||
is_background = false;
|
||||
}
|
||||
|
||||
if (screen->handleEvent(event)) {
|
||||
@ -130,6 +140,10 @@ int main(int argc, char** argv) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_background) {
|
||||
render = false;
|
||||
}
|
||||
|
||||
// can do both in the same loop
|
||||
if (render) {
|
||||
ImGui_ImplSDLRenderer3_NewFrame();
|
||||
|
@ -12,8 +12,9 @@
|
||||
#include <memory>
|
||||
#include <cmath>
|
||||
|
||||
MainScreen::MainScreen(SDL_Renderer* renderer_, Theme& theme_, std::string save_path, std::string save_password, std::string new_username, std::vector<std::string> plugins) :
|
||||
MainScreen::MainScreen(SimpleConfigModel&& conf_, SDL_Renderer* renderer_, Theme& theme_, std::string save_path, std::string save_password, std::string new_username, std::vector<std::string> plugins) :
|
||||
renderer(renderer_),
|
||||
conf(std::move(conf_)),
|
||||
rmm(cr),
|
||||
msnj{cr, {}, {}},
|
||||
mts(rmm),
|
||||
@ -191,7 +192,10 @@ bool MainScreen::handleEvent(SDL_Event& e) {
|
||||
e.type == SDL_EVENT_MOUSE_WHEEL ||
|
||||
e.type == SDL_EVENT_MOUSE_BUTTON_DOWN ||
|
||||
e.type == SDL_EVENT_MOUSE_BUTTON_UP ||
|
||||
e.type == SDL_EVENT_FINGER_DOWN ||
|
||||
e.type == SDL_EVENT_FINGER_UP ||
|
||||
e.type == SDL_EVENT_TEXT_INPUT ||
|
||||
e.type == SDL_EVENT_TEXT_EDITING ||
|
||||
e.type == SDL_EVENT_KEY_DOWN ||
|
||||
e.type == SDL_EVENT_KEY_UP ||
|
||||
e.type == SDL_EVENT_WINDOW_MOUSE_ENTER ||
|
||||
|
@ -91,7 +91,7 @@ struct MainScreen final : public Screen {
|
||||
uint64_t _window_hidden_ts {0};
|
||||
float _time_since_event {0.f};
|
||||
|
||||
MainScreen(SDL_Renderer* renderer_, Theme& theme_, std::string save_path, std::string save_password, std::string new_username, std::vector<std::string> plugins);
|
||||
MainScreen(SimpleConfigModel&& conf_, SDL_Renderer* renderer_, Theme& theme_, std::string save_path, std::string save_password, std::string new_username, std::vector<std::string> plugins);
|
||||
~MainScreen(void);
|
||||
|
||||
bool handleEvent(SDL_Event& e) override;
|
||||
|
@ -31,6 +31,11 @@ uint64_t SDLRendererTextureUploader::uploadRGBA(const uint8_t* data, uint32_t wi
|
||||
// TODO: error reporting
|
||||
SDL_UpdateTexture(tex, nullptr, surf->pixels, surf->pitch);
|
||||
|
||||
SDL_BlendMode surf_blend_mode = SDL_BLENDMODE_NONE;
|
||||
if (SDL_GetSurfaceBlendMode(surf, &surf_blend_mode) == 0) {
|
||||
SDL_SetTextureBlendMode(tex, surf_blend_mode);
|
||||
}
|
||||
|
||||
if (filter == NEAREST) {
|
||||
SDL_SetTextureScaleMode(tex, SDL_SCALEMODE_NEAREST);
|
||||
} else if (filter == LINEAR) {
|
||||
|
@ -2,14 +2,135 @@
|
||||
|
||||
#include "./main_screen.hpp"
|
||||
|
||||
#include "./json_to_config.hpp"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <imgui/imgui.h>
|
||||
#include <imgui/misc/cpp/imgui_stdlib.h>
|
||||
|
||||
#include <cctype>
|
||||
#include <memory>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
StartScreen::StartScreen(SDL_Renderer* renderer, Theme& theme) : _renderer(renderer), _theme(theme) {
|
||||
StartScreen::StartScreen(const std::vector<std::string_view>& args, SDL_Renderer* renderer, Theme& theme) : _renderer(renderer), _theme(theme) {
|
||||
for (size_t ai = 1; ai < args.size(); ai++) {
|
||||
if (args.at(ai) == "--config" || args.at(ai) == "-c") {
|
||||
if (args.size() == ai+1) {
|
||||
std::cerr << "TOMATO error: argument '" << args.at(ai) << "' missing parameter!\n";
|
||||
break;
|
||||
}
|
||||
ai++;
|
||||
|
||||
const auto& config_path = args.at(ai);
|
||||
auto config_file = std::ifstream(static_cast<std::string>(config_path));
|
||||
if (!config_file.is_open()) {
|
||||
std::cerr << "TOMATO error: failed to open config file '" << config_path << "'\n";
|
||||
break;
|
||||
}
|
||||
|
||||
auto config_json = nlohmann::ordered_json::parse(config_file);
|
||||
if (!load_json_into_config(config_json, _conf)) {
|
||||
std::cerr << "TOMATO error in config json, exiting...\n";
|
||||
break;
|
||||
}
|
||||
} else if (args.at(ai) == "--plugin" || args.at(ai) == "-p") {
|
||||
if (args.size() == ai+1) {
|
||||
std::cerr << "TOMATO error: argument '" << args.at(ai) << "' missing parameter!\n";
|
||||
break;
|
||||
}
|
||||
ai++;
|
||||
|
||||
const auto& plugin_path = args.at(ai);
|
||||
// TODO: check for dups
|
||||
queued_plugin_paths.push_back(static_cast<std::string>(plugin_path));
|
||||
} else {
|
||||
std::cerr << "TOMATO error: unknown cli arg: '" << args.at(ai) << "'\n";
|
||||
}
|
||||
}
|
||||
|
||||
float display_scale = SDL_GetWindowDisplayScale(SDL_GetRenderWindow(renderer));
|
||||
if (display_scale < 0.001f) {
|
||||
// error?
|
||||
display_scale = 1.f;
|
||||
}
|
||||
|
||||
{
|
||||
auto* font_atlas = ImGui::GetIO().Fonts;
|
||||
font_atlas->ClearFonts();
|
||||
// for now we also always merge
|
||||
//bool has_font {false};
|
||||
|
||||
ImFontGlyphRangesBuilder glyphbld;
|
||||
ImVector<ImWchar> glyph_ranges;
|
||||
{ // build ranges
|
||||
glyphbld.AddRanges(font_atlas->GetGlyphRangesDefault());
|
||||
glyphbld.AddRanges(font_atlas->GetGlyphRangesGreek());
|
||||
glyphbld.AddRanges(font_atlas->GetGlyphRangesCyrillic());
|
||||
glyphbld.AddRanges(font_atlas->GetGlyphRangesChineseSimplifiedCommon()); // contains CJK
|
||||
glyphbld.AddText("™"); // somehow missing
|
||||
// popular emojies
|
||||
glyphbld.AddText(u8"😂❤️🤣👍😭🙏😘🥰😍😊🎉😁💕🥺😅🔥☺️🤦♥️🤷🙄😆🤗😉🎂🤔👏🙂😳🥳😎👌💜😔💪✨💖👀😋😏😢👉💗😩💯🌹💞🎈💙😃😡💐😜🙈🤞😄🤤🙌🤪❣️😀💋💀👇💔😌💓🤩🙃😬😱😴🤭😐🌞😒😇🌸😈🎶✌️🎊🥵😞💚☀️🖤💰😚👑🎁💥🙋☹️😑🥴👈💩✅👋🤮😤🤢🌟❗😥🌈💛😝😫😲🖕‼️🔴🌻🤯💃👊🤬🏃😕👁️⚡☕🍀💦⭐🦋🤨🌺😹🤘🌷💝💤🤝🐰😓💘🍻😟😣🧐😠🤠😻🌙😛🤙🙊");
|
||||
|
||||
if (const auto sv_opt = _conf.get_string("ImGuiFonts", "atlas_extra_text"); sv_opt.has_value) {
|
||||
glyphbld.AddText(sv_opt.s.start, sv_opt.s.start+sv_opt.s.extend);
|
||||
}
|
||||
glyphbld.BuildRanges(&glyph_ranges);
|
||||
}
|
||||
|
||||
ImFontConfig fontcfg;
|
||||
//fontcfg.SizePixels = 16.f*display_scale;
|
||||
fontcfg.SizePixels = _conf.get_int("ImGuiFonts", "size").value_or(13) * display_scale;
|
||||
fontcfg.RasterizerDensity = 1.f;
|
||||
fontcfg.OversampleH = 2;
|
||||
fontcfg.OversampleV = 1;
|
||||
fontcfg.MergeMode = false;
|
||||
|
||||
for (const auto [font_path, should_load] : _conf.entries_bool("ImGuiFonts", "fonts")) {
|
||||
if (!should_load) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::cout << "Font: loading '" << font_path << "'\n";
|
||||
const auto* resulting_font = font_atlas->AddFontFromFileTTF(
|
||||
font_path.c_str(),
|
||||
_conf.get_int("ImGuiFonts", "size", font_path).value_or(0) * display_scale,
|
||||
&fontcfg,
|
||||
&(glyph_ranges[0])
|
||||
);
|
||||
|
||||
if (resulting_font != nullptr) {
|
||||
//has_font = true;
|
||||
fontcfg.MergeMode = true;
|
||||
} else {
|
||||
std::cerr << "Font: failed to load '" << "path" << "' !\n";
|
||||
}
|
||||
}
|
||||
|
||||
// always append the default as a fallback (merge in)
|
||||
{
|
||||
#if 0
|
||||
ImFontConfig fontcfg;
|
||||
|
||||
// upsampling to int looks almost ok
|
||||
//const float font_size_scale = 1.3f * display_scale;
|
||||
const float font_size_scale = 1.0f * display_scale;
|
||||
const float font_oversample = 4.f;
|
||||
|
||||
// default font is pixel perfect at 13
|
||||
fontcfg.SizePixels = 13.f * font_size_scale;
|
||||
fontcfg.RasterizerDensity = font_oversample/font_size_scale;
|
||||
// normally density would be set to dpi scale of the display
|
||||
|
||||
fontcfg.MergeMode = has_font;
|
||||
#endif
|
||||
|
||||
font_atlas->AddFontDefault(&fontcfg);
|
||||
}
|
||||
|
||||
font_atlas->Build();
|
||||
}
|
||||
}
|
||||
|
||||
Screen* StartScreen::render(float, bool&) {
|
||||
@ -143,7 +264,8 @@ Screen* StartScreen::render(float, bool&) {
|
||||
}
|
||||
} else {
|
||||
if (ImGui::Button("load", {60, 25})) {
|
||||
auto new_screen = std::make_unique<MainScreen>(_renderer, _theme, _tox_profile_path, _password, _user_name, queued_plugin_paths);
|
||||
|
||||
auto new_screen = std::make_unique<MainScreen>(std::move(_conf), _renderer, _theme, _tox_profile_path, _password, _user_name, queued_plugin_paths);
|
||||
return new_screen.release();
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include "./chat_gui/theme.hpp"
|
||||
#include "./chat_gui/file_selector.hpp"
|
||||
|
||||
#include <solanaceae/util/simple_config_model.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
@ -16,6 +18,7 @@ extern "C" {
|
||||
struct StartScreen final : public Screen {
|
||||
SDL_Renderer* _renderer;
|
||||
Theme& _theme;
|
||||
SimpleConfigModel _conf;
|
||||
FileSelector _fss;
|
||||
|
||||
bool _new_save {false};
|
||||
@ -28,7 +31,7 @@ struct StartScreen final : public Screen {
|
||||
std::vector<std::string> queued_plugin_paths;
|
||||
|
||||
StartScreen(void) = delete;
|
||||
StartScreen(SDL_Renderer* renderer, Theme& theme);
|
||||
StartScreen(const std::vector<std::string_view>& args, SDL_Renderer* renderer, Theme& theme);
|
||||
~StartScreen(void) = default;
|
||||
|
||||
// return nullptr if not next
|
||||
|
49
src/sys_check.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
#include "./sys_check.hpp"
|
||||
|
||||
// use message boxes to notify the user of system failure
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
typedef LONG NTSTATUS, *PNTSTATUS;
|
||||
#define STATUS_SUCCESS (0x00000000)
|
||||
|
||||
void runSysCheck(void) {
|
||||
NTSTATUS(WINAPI *RtlGetVersion)(LPOSVERSIONINFOEXW);
|
||||
OSVERSIONINFOEXW osInfo;
|
||||
|
||||
HMODULE lib = GetModuleHandleW(L"ntdll.dll");
|
||||
if (lib) {
|
||||
*(FARPROC*)&RtlGetVersion = GetProcAddress(lib, "RtlGetVersion");
|
||||
|
||||
if (NULL != RtlGetVersion) {
|
||||
osInfo.dwOSVersionInfoSize = sizeof(osInfo);
|
||||
RtlGetVersion(&osInfo);
|
||||
|
||||
// check
|
||||
if (
|
||||
osInfo.dwBuildNumber >= 26000 // canary versions of 11 24H2 included
|
||||
) {
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Unsupported System", "Your version of windows is too new and endangers the privacy of all involved.", nullptr);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void runSysCheck(void) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
#endif
|
||||
|
4
src/sys_check.hpp
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
// perform system checks and potentially terminate
|
||||
void runSysCheck(void);
|
@ -80,43 +80,7 @@ ToxClient::ToxClient(std::string_view save_path, std::string_view save_password)
|
||||
// no callbacks, use events
|
||||
tox_events_init(_tox);
|
||||
|
||||
// dht bootstrap
|
||||
{
|
||||
struct DHT_node {
|
||||
const char *ip;
|
||||
uint16_t port;
|
||||
const char key_hex[TOX_PUBLIC_KEY_SIZE*2 + 1]; // 1 for null terminator
|
||||
unsigned char key_bin[TOX_PUBLIC_KEY_SIZE];
|
||||
};
|
||||
|
||||
DHT_node nodes[] =
|
||||
{
|
||||
// TODO: more/diff nodes
|
||||
// you can change or add your own bs and tcprelays here, ideally closer to you
|
||||
|
||||
//{"tox.plastiras.org", 33445, "8E8B63299B3D520FB377FE5100E65E3322F7AE5B20A0ACED2981769FC5B43725", {}}, // LU tha14
|
||||
{"104.244.74.69", 443, "8E8B63299B3D520FB377FE5100E65E3322F7AE5B20A0ACED2981769FC5B43725", {}}, // LU tha14
|
||||
{"104.244.74.69", 33445, "8E8B63299B3D520FB377FE5100E65E3322F7AE5B20A0ACED2981769FC5B43725", {}}, // LU tha14
|
||||
|
||||
//{"tox2.plastiras.org", 33445, "B6626D386BE7E3ACA107B46F48A5C4D522D29281750D44A0CBA6A2721E79C951", {}}, // DE tha14
|
||||
|
||||
//{"tox4.plastiras.org", 33445, "836D1DA2BE12FE0E669334E437BE3FB02806F1528C2B2782113E0910C7711409", {}}, // MD tha14
|
||||
{"37.221.66.161", 443, "836D1DA2BE12FE0E669334E437BE3FB02806F1528C2B2782113E0910C7711409", {}}, // MD tha14
|
||||
{"37.221.66.161", 33445, "836D1DA2BE12FE0E669334E437BE3FB02806F1528C2B2782113E0910C7711409", {}}, // MD tha14
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(nodes)/sizeof(DHT_node); i ++) {
|
||||
sodium_hex2bin(
|
||||
nodes[i].key_bin, sizeof(nodes[i].key_bin),
|
||||
nodes[i].key_hex, sizeof(nodes[i].key_hex)-1,
|
||||
NULL, NULL, NULL
|
||||
);
|
||||
tox_bootstrap(_tox, nodes[i].ip, nodes[i].port, nodes[i].key_bin, NULL);
|
||||
// TODO: use extra tcp option to avoid error msgs
|
||||
// ... this is hardcore
|
||||
tox_add_tcp_relay(_tox, nodes[i].ip, nodes[i].port, nodes[i].key_bin, NULL);
|
||||
}
|
||||
}
|
||||
runBootstrap();
|
||||
}
|
||||
|
||||
ToxClient::~ToxClient(void) {
|
||||
@ -146,6 +110,44 @@ bool ToxClient::iterate(float time_delta) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ToxClient::runBootstrap(void) {
|
||||
// TODO: extend and read from json?
|
||||
// TODO: seperate out relays
|
||||
struct DHT_node {
|
||||
const char *ip;
|
||||
uint16_t port;
|
||||
const char key_hex[TOX_PUBLIC_KEY_SIZE*2 + 1]; // 1 for null terminator
|
||||
unsigned char key_bin[TOX_PUBLIC_KEY_SIZE];
|
||||
};
|
||||
|
||||
DHT_node nodes[] {
|
||||
// TODO: more/diff nodes
|
||||
// you can change or add your own bs and tcprelays here, ideally closer to you
|
||||
|
||||
//{"tox.plastiras.org", 33445, "8E8B63299B3D520FB377FE5100E65E3322F7AE5B20A0ACED2981769FC5B43725", {}}, // LU tha14
|
||||
{"104.244.74.69", 443, "8E8B63299B3D520FB377FE5100E65E3322F7AE5B20A0ACED2981769FC5B43725", {}}, // LU tha14
|
||||
{"104.244.74.69", 33445, "8E8B63299B3D520FB377FE5100E65E3322F7AE5B20A0ACED2981769FC5B43725", {}}, // LU tha14
|
||||
|
||||
//{"tox2.plastiras.org", 33445, "B6626D386BE7E3ACA107B46F48A5C4D522D29281750D44A0CBA6A2721E79C951", {}}, // DE tha14
|
||||
|
||||
//{"tox4.plastiras.org", 33445, "836D1DA2BE12FE0E669334E437BE3FB02806F1528C2B2782113E0910C7711409", {}}, // MD tha14
|
||||
{"37.221.66.161", 443, "836D1DA2BE12FE0E669334E437BE3FB02806F1528C2B2782113E0910C7711409", {}}, // MD tha14
|
||||
{"37.221.66.161", 33445, "836D1DA2BE12FE0E669334E437BE3FB02806F1528C2B2782113E0910C7711409", {}}, // MD tha14
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(nodes)/sizeof(DHT_node); i++) {
|
||||
sodium_hex2bin(
|
||||
nodes[i].key_bin, sizeof(nodes[i].key_bin),
|
||||
nodes[i].key_hex, sizeof(nodes[i].key_hex)-1,
|
||||
NULL, NULL, NULL
|
||||
);
|
||||
tox_bootstrap(_tox, nodes[i].ip, nodes[i].port, nodes[i].key_bin, NULL);
|
||||
// TODO: use extra tcp option to avoid error msgs
|
||||
// ... this is hardcore
|
||||
tox_add_tcp_relay(_tox, nodes[i].ip, nodes[i].port, nodes[i].key_bin, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void ToxClient::subscribeRaw(std::function<void(const Tox_Events*)> fn) {
|
||||
_subscriber_raw = fn;
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ class ToxClient : public ToxDefaultImpl, public ToxEventProviderBase {
|
||||
void setToxProfilePath(const std::string& new_path) { _tox_profile_path = new_path; }
|
||||
void setSelfName(std::string_view new_name) { _self_name = new_name; toxSelfSetName(new_name); }
|
||||
|
||||
void runBootstrap(void);
|
||||
|
||||
public: // raw events
|
||||
void subscribeRaw(std::function<void(const Tox_Events*)> fn);
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
#include "./tox_ui_utils.hpp"
|
||||
|
||||
#include "./tox_client.hpp"
|
||||
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include <solanaceae/toxcore/tox_interface.hpp>
|
||||
#include <solanaceae/util/utils.hpp>
|
||||
|
||||
#include <solanaceae/util/config_model.hpp>
|
||||
@ -11,9 +12,9 @@
|
||||
#include <imgui/misc/cpp/imgui_stdlib.h>
|
||||
|
||||
ToxUIUtils::ToxUIUtils(
|
||||
ToxI& t,
|
||||
ToxClient& tc,
|
||||
ConfigModelI& conf
|
||||
) : _t(t), _conf(conf) {
|
||||
) : _tc(tc), _conf(conf) {
|
||||
}
|
||||
|
||||
void ToxUIUtils::render(void) {
|
||||
@ -31,6 +32,13 @@ void ToxUIUtils::render(void) {
|
||||
if (ImGui::MenuItem("join Group by ID (ngc)")) {
|
||||
_show_add_group_window = true;
|
||||
}
|
||||
|
||||
ImGui::SeparatorText("DHT");
|
||||
|
||||
if (ImGui::MenuItem("rerun bootstrap")) {
|
||||
_tc.runBootstrap();
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
@ -51,7 +59,7 @@ void ToxUIUtils::render(void) {
|
||||
static Tox_Err_Friend_Add err = Tox_Err_Friend_Add::TOX_ERR_FRIEND_ADD_OK;
|
||||
if (ImGui::Button("add")) {
|
||||
// TODO: add string_view variant to utils
|
||||
auto [_, err_r] = _t.toxFriendAdd(hex2bin(std::string{tox_id}), message);
|
||||
auto [_, err_r] = _tc.toxFriendAdd(hex2bin(std::string{tox_id}), message);
|
||||
err = err_r;
|
||||
}
|
||||
if (err != Tox_Err_Friend_Add::TOX_ERR_FRIEND_ADD_OK) {
|
||||
@ -78,7 +86,7 @@ void ToxUIUtils::render(void) {
|
||||
|
||||
static Tox_Err_Group_Join err = Tox_Err_Group_Join::TOX_ERR_GROUP_JOIN_OK;
|
||||
if (ImGui::Button("join")) {
|
||||
auto [_, err_r] = _t.toxGroupJoin(
|
||||
auto [_, err_r] = _tc.toxGroupJoin(
|
||||
hex2bin(std::string{chat_id}), // TODO: add string_view variant to utils
|
||||
self_name,
|
||||
password
|
||||
|
@ -1,18 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
struct ToxI;
|
||||
class ToxClient;
|
||||
struct ConfigModelI;
|
||||
|
||||
class ToxUIUtils {
|
||||
bool _show_add_friend_window {false};
|
||||
bool _show_add_group_window {false};
|
||||
|
||||
ToxI& _t;
|
||||
ToxClient& _tc;
|
||||
ConfigModelI& _conf;
|
||||
|
||||
public:
|
||||
ToxUIUtils(
|
||||
ToxI& t,
|
||||
ToxClient& tc,
|
||||
ConfigModelI& conf
|
||||
);
|
||||
|
||||
|