Compare commits

..

19 Commits

Author SHA1 Message Date
732e08736f update deps (new OS version)
Some checks failed
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
ContinuousDelivery / linux-ubuntu (push) Failing after 4m45s
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m36s
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m39s
ContinuousIntegration / linux (push) Successful in 3m44s
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m19s
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m8s
2024-07-18 10:37:42 +02:00
d5709c421c add os inspector and minor stuff
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Failing after 4m26s
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m33s
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m29s
ContinuousIntegration / linux (push) Successful in 3m42s
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m8s
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m27s
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
2024-07-16 15:03:37 +02:00
18c37f9934 fix multiline text context menu
Some checks failed
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
ContinuousDelivery / linux-ubuntu (push) Failing after 4m47s
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m27s
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m25s
ContinuousIntegration / linux (push) Successful in 3m56s
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m14s
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m4s
2024-07-16 12:47:31 +02:00
53ae3f8ce5 also enable toxav in flake
Some checks failed
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
ContinuousDelivery / linux-ubuntu (push) Failing after 4m41s
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m51s
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m44s
ContinuousIntegration / linux (push) Successful in 3m46s
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m17s
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m4s
2024-07-16 10:37:19 +02:00
b5e90528f0 ci enable toxav for windows 2024-07-16 10:33:16 +02:00
22071b60e6 update deps 2024-07-16 10:30:38 +02:00
5283df7b98 update flake
Some checks failed
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
ContinuousDelivery / linux-ubuntu (push) Failing after 4m33s
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m29s
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m27s
ContinuousIntegration / linux (push) Successful in 3m59s
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m20s
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m4s
2024-07-16 09:59:22 +02:00
21243ea979 show contact ID in tooltip
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Failing after 13m8s
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m26s
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m41s
ContinuousIntegration / linux (push) Successful in 3m53s
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m18s
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m39s
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
2024-07-01 14:00:00 +02:00
1d212c5fab missing include
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Failing after 4m30s
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m37s
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m40s
ContinuousIntegration / linux (push) Successful in 3m48s
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m26s
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m16s
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
2024-06-28 17:11:30 +02:00
37239f1c25 make file message file size readable
Some checks failed
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
ContinuousDelivery / linux-ubuntu (push) Failing after 4m43s
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m31s
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m36s
ContinuousIntegration / linux (push) Successful in 3m50s
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m29s
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m24s
2024-06-27 17:41:27 +02:00
780e1e06d4 fix start load button sizing
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Failing after 4m20s
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m33s
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m28s
ContinuousIntegration / linux (push) Successful in 3m44s
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m15s
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m10s
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
2024-06-23 10:33:39 +02:00
7c227457cd visibility checks + group and person icon
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Failing after 4m33s
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m37s
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m50s
ContinuousIntegration / linux (push) Successful in 3m56s
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m17s
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m21s
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
2024-06-19 16:10:03 +02:00
5544adf345 split icons to their own files
Some checks failed
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
ContinuousDelivery / linux-ubuntu (push) Failing after 4m31s
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m31s
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m45s
ContinuousIntegration / linux (push) Successful in 4m20s
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m20s
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m6s
2024-06-19 14:25:09 +02:00
6d3ef742b5 finally add copy own id
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Failing after 4m27s
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m39s
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m39s
ContinuousIntegration / linux (push) Successful in 3m34s
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m17s
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m16s
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
2024-06-17 15:19:55 +02:00
cba3282dce reformat android manifest
Some checks failed
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
ContinuousDelivery / linux-ubuntu (push) Failing after 4m24s
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m32s
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m23s
ContinuousIntegration / linux (push) Successful in 3m44s
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m28s
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m42s
2024-06-17 12:09:37 +02:00
5c5e830f0f allow android intent receive 2024-06-17 12:08:35 +02:00
e08dbba940 switch selectable chat message text to wrapping and color quotes
Some checks failed
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
ContinuousDelivery / linux-ubuntu (push) Failing after 4m32s
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m39s
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m36s
ContinuousIntegration / linux (push) Successful in 3m45s
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m13s
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m5s
2024-06-16 21:15:08 +02:00
752f2ebe2c support loading tox save path form file
Some checks failed
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
ContinuousDelivery / linux-ubuntu (push) Failing after 4m29s
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m28s
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m28s
ContinuousIntegration / linux (push) Successful in 3m42s
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Failing after 5m14s
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Failing after 5m4s
2024-06-16 11:56:34 +02:00
a47d607a8d enable dpi/display scaling/display density awareness 2024-06-16 11:19:54 +02:00
33 changed files with 1189 additions and 261 deletions

View File

@ -153,7 +153,7 @@ jobs:
git pull
- name: Install Dependencies
run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static pkgconf:x64-windows
run: vcpkg install pkgconf:x64-windows libsodium:x64-windows-static pthreads:x64-windows-static opus:x64-windows-static libvpx:x64-windows-static
# setup vs env
- uses: ilammy/msvc-dev-cmd@v1
@ -212,7 +212,7 @@ jobs:
git pull
- name: Install Dependencies
run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static pkgconf:x64-windows
run: vcpkg install pkgconf:x64-windows libsodium:x64-windows-static pthreads:x64-windows-static opus:x64-windows-static libvpx:x64-windows-static
# setup vs env
- uses: ilammy/msvc-dev-cmd@v1

View File

@ -129,7 +129,7 @@ jobs:
git pull
- name: Install Dependencies
run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static pkgconf:x64-windows
run: vcpkg install pkgconf:x64-windows libsodium:x64-windows-static pthreads:x64-windows-static opus:x64-windows-static libvpx:x64-windows-static
# setup vs env
- uses: ilammy/msvc-dev-cmd@v1

View File

@ -1,109 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Replace com.test.game with the identifier of your game below, e.g.
com.gamemaker.game
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:versionCode="1"
android:versionName="1.0"
android:installLocation="auto">
<!-- OpenGL ES 2.0 -->
<uses-feature android:glEsVersion="0x00020000" />
<!-- OpenGL ES 2.0 -->
<uses-feature android:glEsVersion="0x00020000" />
<!-- Touchscreen support -->
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<!-- 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" />
<!-- 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" />
<!-- 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" /> -->
<!-- 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" />
-->
<!-- 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 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 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" />
<!-- 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" /> -->
<!-- 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
<!-- 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.
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"
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" >
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>
<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>

View File

@ -1,21 +1,27 @@
cmake_minimum_required(VERSION 3.9...3.16 FATAL_ERROR)
cmake_minimum_required(VERSION 3.13...3.16 FATAL_ERROR)
set(EXPERIMENTAL_API ON CACHE BOOL "" FORCE)
set(UNITTEST OFF CACHE BOOL "" FORCE)
set(BOOTSTRAP_DAEMON OFF CACHE BOOL "" FORCE)
#set(BUILD_TOXAV ON CACHE BOOL "")
add_subdirectory(./c-toxcore)
# the ideal case
#add_library(toxcore ALIAS toxcore_static)
#message("II BUILD_TOXAV: ${BUILD_TOXAV}")
# the sad case
add_library(toxcore INTERFACE)
if (TARGET toxcore_static)
target_link_libraries(toxcore INTERFACE toxcore_static)
# the ideal case
#add_library(toxcore ALIAS toxcore_static)
else()
target_link_libraries(toxcore INTERFACE toxcore_shared)
# the ideal case
#add_library(toxcore ALIAS toxcore_shared)
endif()
# HACK: "install" api headers into binary dir
@ -64,3 +70,8 @@ elseif(sodium_FOUND)
else()
message(SEND_ERROR "missing libsodium")
endif()
#if(BUILD_TOXAV)
# set_target_properties(toxcore PROPERTIES TOX_HAS_TOXAV ON)
#endif()

6
flake.lock generated
View File

@ -20,11 +20,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1718111384,
"narHash": "sha256-7tSst0S5FOmcgvNtfy6cjZX5w8CabCVAfAeCkhY4OVg=",
"lastModified": 1720691131,
"narHash": "sha256-CWT+KN8aTPyMIx8P303gsVxUnkinIz0a/Cmasz1jyIM=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a508a44af0c1b1b57785c34d8b54783536273eeb",
"rev": "a046c1202e11b62cbede5385ba64908feb7bfac4",
"type": "github"
},
"original": {

View File

@ -75,11 +75,16 @@
#(libsodium.override { stdenv = pkgs.pkgsStatic.stdenv; })
#pkgsStatic.libsodium
libsodium
libopus
libvpx
] ++ self.packages.${system}.default.dlopenBuildInputs;
cmakeFlags = [
"-DTOMATO_ASAN=OFF"
"-DCMAKE_BUILD_TYPE=RelWithDebInfo"
#"-DCMAKE_BUILD_TYPE=Debug"
#"-DCMAKE_C_FLAGS:STRING=-Og"
#"-DCMAKE_CXX_FLAGS:STRING=-Og"
"-DFETCHCONTENT_SOURCE_DIR_JSON=${nlohmann-json}" # we care about the version
# TODO: use package instead

View File

@ -67,6 +67,16 @@ target_sources(tomato PUBLIC
./chat_gui/theme.hpp
./chat_gui/theme.cpp
./chat_gui/icons/direct.hpp
./chat_gui/icons/direct.cpp
./chat_gui/icons/cloud.hpp
./chat_gui/icons/cloud.cpp
./chat_gui/icons/mail.hpp
./chat_gui/icons/mail.cpp
./chat_gui/icons/person.hpp
./chat_gui/icons/person.cpp
./chat_gui/icons/group.hpp
./chat_gui/icons/group.cpp
./chat_gui/contact_list.hpp
./chat_gui/contact_list.cpp
./chat_gui/file_selector.hpp
@ -76,6 +86,10 @@ target_sources(tomato PUBLIC
./chat_gui/settings_window.hpp
./chat_gui/settings_window.cpp
./imgui_entt_entity_editor.hpp
./object_store_ui.hpp
./object_store_ui.cpp
./tox_ui_utils.hpp
./tox_ui_utils.cpp

View File

@ -1,139 +1,16 @@
#include "./contact_list.hpp"
#include <solanaceae/contact/components.hpp>
#include <solanaceae/util/utils.hpp>
#include <imgui/imgui.h>
//#include <imgui/imgui_internal.h>
#include <array>
static void drawIconDirectLines(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col,
const float thickness
) {
#define PLINE(x0, y0, x1, y1) \
ImGui::GetWindowDrawList()->AddLine( \
{p0.x + p1_o.x*(x0), p0.y + p1_o.y*(y0)}, \
{p0.x + p1_o.x*(x1), p0.y + p1_o.y*(y1)}, \
col, \
thickness \
);
// arrow 1
// (3,1) -> (9,7)
PLINE(0.3f, 0.1f, 0.9f, 0.7f)
// (9,7) -> (9,5)
PLINE(0.9f, 0.7f, 0.9f, 0.5f)
// (9,7) -> (7,7)
PLINE(0.9f, 0.7f, 0.7f, 0.7f)
// arrow 2
// (7,9) -> (1,3)
PLINE(0.7f, 0.9f, 0.1f, 0.3f)
// (1,3) -> (3,3)
PLINE(0.1f, 0.3f, 0.3f, 0.3f)
// (1,3) -> (1,5)
PLINE(0.1f, 0.3f, 0.1f, 0.5f)
#undef PLINE
}
static void drawIconDirect(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col_main,
const ImU32 col_back
) {
// dark background
// the circle looks bad in light mode
//ImGui::GetWindowDrawList()->AddCircleFilled({p0.x + p1_o.x*0.5f, p0.y + p1_o.y*0.5f}, p1_o.x*0.5f, col_back);
drawIconDirectLines(p0, p1_o, col_back, 4.0f);
drawIconDirectLines(p0, p1_o, col_main, 1.5f);
}
static void drawIconCloud(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col_main,
const ImU32 col_back
) {
std::array<ImVec2, 19> points {{
{0.2f, 0.9f},
{0.8f, 0.9f},
{0.9f, 0.8f},
{0.9f, 0.7f},
{0.7f, 0.7f},
{0.9f, 0.5f},
{0.9f, 0.4f},
{0.8f, 0.2f},
{0.6f, 0.2f},
{0.5f, 0.3f},
{0.5f, 0.5f},
{0.4f, 0.4f},
{0.3f, 0.4f},
{0.2f, 0.5f},
{0.2f, 0.6f},
{0.3f, 0.7f},
{0.1f, 0.7f},
{0.1f, 0.8f},
{0.2f, 0.9f},
}};
for (auto& v : points) {
v.y -= 0.1f;
v = {p0.x + p1_o.x*v.x, p0.y + p1_o.y*v.y};
}
// the circle looks bad in light mode
//ImGui::GetWindowDrawList()->AddCircleFilled({p0.x + p1_o.x*0.5f, p0.y + p1_o.y*0.5f}, p1_o.x*0.5f, col_back);
ImGui::GetWindowDrawList()->AddPolyline(points.data(), points.size(), col_back, ImDrawFlags_None, 4.f);
ImGui::GetWindowDrawList()->AddPolyline(points.data(), points.size(), col_main, ImDrawFlags_None, 1.5f);
}
static void drawIconMailLines(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col,
const float thickness
) {
#define PLINE(x0, y0, x1, y1) \
ImGui::GetWindowDrawList()->AddLine( \
{p0.x + p1_o.x*(x0), p0.y + p1_o.y*(y0)}, \
{p0.x + p1_o.x*(x1), p0.y + p1_o.y*(y1)}, \
col, \
thickness \
);
// quad
// (1,2) -> (1,8)
PLINE(0.1f, 0.2f, 0.1f, 0.8f)
// (1,8) -> (9,8)
PLINE(0.1f, 0.8f, 0.9f, 0.8f)
// (9,8) -> (9,2)
PLINE(0.9f, 0.8f, 0.9f, 0.2f)
// (9,2) -> (1,2)
PLINE(0.9f, 0.2f, 0.1f, 0.2f)
// lip
// (1,2) -> (5,5)
PLINE(0.1f, 0.2f, 0.5f, 0.5f)
// (5,5) -> (9,2)
PLINE(0.5f, 0.5f, 0.9f, 0.2f)
#undef PLINE
}
static void drawIconMail(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col_main,
const ImU32 col_back
) {
// dark background
// the circle looks bad in light mode
//ImGui::GetWindowDrawList()->AddCircleFilled({p0.x + p1_o.x*0.5f, p0.y + p1_o.y*0.5f}, p1_o.x*0.5f, col_back);
drawIconMailLines(p0, p1_o, col_back, 4.0f);
drawIconMailLines(p0, p1_o, col_main, 1.5f);
}
#include "./icons/direct.hpp"
#include "./icons/cloud.hpp"
#include "./icons/mail.hpp"
#include "./icons/person.hpp"
#include "./icons/group.hpp"
void renderAvatar(
const Theme& th,
@ -220,6 +97,11 @@ bool renderContactBig(
const auto* cstate = c.try_get<Contact::Components::ConnectionState>();
if (ImGui::BeginItemTooltip()) {
if (c.all_of<Contact::Components::ID>()) {
const auto id_str = bin2hex(c.get<Contact::Components::ID>().data);
ImGui::Text("ID: %s", id_str.c_str());
}
if (cstate != nullptr) {
ImGui::Text("Connection state: %s",
(cstate->state == Contact::Components::ConnectionState::disconnected)
@ -264,6 +146,9 @@ bool renderContactBig(
ImGui::SameLine(0.f, same_line_spacing);
ImGui::BeginGroup();
{
const bool is_group = c.all_of<Contact::Components::TagGroup>();
const bool is_private = c.all_of<Contact::Components::TagPrivate>();
{ // line 1
if (line_height == 1 && cstate != nullptr) {
// icon pos
@ -271,23 +156,52 @@ bool renderContactBig(
p0.y += ImGui::GetStyle().FramePadding.y;
ImVec2 p1_o = {img_y, img_y}; // img_y is 1 line_height in this case
const ImU32 col_back = ImGui::GetColorU32(th.getColor<ThemeCol_Contact::icon_backdrop>());
if (cstate->state == Contact::Components::ConnectionState::direct) { // direct icon
drawIconDirect(
p0,
p1_o,
ImGui::GetColorU32(th.getColor<ThemeCol_Contact::avatar_online_direct>()),
col_back
);
} else if (cstate->state == Contact::Components::ConnectionState::cloud) { // cloud icon
drawIconCloud(
p0,
p1_o,
ImGui::GetColorU32(th.getColor<ThemeCol_Contact::avatar_online_cloud>()),
col_back
);
}
ImGui::Dummy(p1_o);
if (ImGui::IsItemVisible()) {
const ImU32 col_back = ImGui::GetColorU32(th.getColor<ThemeCol_Contact::icon_backdrop>());
if (cstate->state == Contact::Components::ConnectionState::direct) { // direct icon
drawIconDirect(
p0,
p1_o,
ImGui::GetColorU32(th.getColor<ThemeCol_Contact::avatar_online_direct>()),
col_back
);
} else if (cstate->state == Contact::Components::ConnectionState::cloud) { // cloud icon
drawIconCloud(
p0,
p1_o,
ImGui::GetColorU32(th.getColor<ThemeCol_Contact::avatar_online_cloud>()),
col_back
);
}
}
ImGui::SameLine(0.f, same_line_spacing);
}
// we dont render group/private in 1lh mode
if (line_height != 1 && (is_private || is_group)) {
// icon pos
auto p0 = ImGui::GetCursorScreenPos();
p0.y += ImGui::GetStyle().FramePadding.y;
const float box_hight = TEXT_BASE_HEIGHT - ImGui::GetStyle().FramePadding.y*2;
ImVec2 p1_o = {box_hight, box_hight};
ImGui::Dummy(p1_o);
if (ImGui::IsItemVisible()) {
if (is_private) {
drawIconPerson(
p0,
p1_o,
ImGui::GetColorU32(ImGui::GetStyleColorVec4(ImGuiCol_Text))
);
} else if (is_group) {
drawIconGroup(
p0,
p1_o,
ImGui::GetColorU32(ImGui::GetStyleColorVec4(ImGuiCol_Text))
);
}
}
ImGui::SameLine(0.f, same_line_spacing);
}
@ -327,23 +241,25 @@ bool renderContactBig(
const float box_hight = TEXT_BASE_HEIGHT - ImGui::GetStyle().FramePadding.y*2;
ImVec2 p1_o = {box_hight, box_hight};
const ImU32 col_back = ImGui::GetColorU32(th.getColor<ThemeCol_Contact::icon_backdrop>());
if (cstate->state == Contact::Components::ConnectionState::direct) { // direct icon
drawIconDirect(
p0,
p1_o,
ImGui::GetColorU32(th.getColor<ThemeCol_Contact::avatar_online_direct>()),
col_back
);
} else if (cstate->state == Contact::Components::ConnectionState::cloud) { // cloud icon
drawIconCloud(
p0,
p1_o,
ImGui::GetColorU32(th.getColor<ThemeCol_Contact::avatar_online_cloud>()),
col_back
);
}
ImGui::Dummy(p1_o);
if (ImGui::IsItemVisible()) {
const ImU32 col_back = ImGui::GetColorU32(th.getColor<ThemeCol_Contact::icon_backdrop>());
if (cstate->state == Contact::Components::ConnectionState::direct) { // direct icon
drawIconDirect(
p0,
p1_o,
ImGui::GetColorU32(th.getColor<ThemeCol_Contact::avatar_online_direct>()),
col_back
);
} else if (cstate->state == Contact::Components::ConnectionState::cloud) { // cloud icon
drawIconCloud(
p0,
p1_o,
ImGui::GetColorU32(th.getColor<ThemeCol_Contact::avatar_online_cloud>()),
col_back
);
}
}
ImGui::SameLine(0.f, same_line_spacing);
}

View File

@ -6,6 +6,7 @@
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
void FileSelector::reset(void) {
_is_valid = [](auto){ return true; };

View File

@ -0,0 +1,41 @@
#include "./cloud.hpp"
#include <array>
void drawIconCloud(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col_main,
const ImU32 col_back
) {
std::array<ImVec2, 19> points {{
{0.2f, 0.9f},
{0.8f, 0.9f},
{0.9f, 0.8f},
{0.9f, 0.7f},
{0.7f, 0.7f},
{0.9f, 0.5f},
{0.9f, 0.4f},
{0.8f, 0.2f},
{0.6f, 0.2f},
{0.5f, 0.3f},
{0.5f, 0.5f},
{0.4f, 0.4f},
{0.3f, 0.4f},
{0.2f, 0.5f},
{0.2f, 0.6f},
{0.3f, 0.7f},
{0.1f, 0.7f},
{0.1f, 0.8f},
{0.2f, 0.9f},
}};
for (auto& v : points) {
v.y -= 0.1f;
v = {p0.x + p1_o.x*v.x, p0.y + p1_o.y*v.y};
}
// the circle looks bad in light mode
//ImGui::GetWindowDrawList()->AddCircleFilled({p0.x + p1_o.x*0.5f, p0.y + p1_o.y*0.5f}, p1_o.x*0.5f, col_back);
ImGui::GetWindowDrawList()->AddPolyline(points.data(), points.size(), col_back, ImDrawFlags_None, 4.f);
ImGui::GetWindowDrawList()->AddPolyline(points.data(), points.size(), col_main, ImDrawFlags_None, 1.5f);
}

View File

@ -0,0 +1,11 @@
#pragma once
#include <imgui/imgui.h>
void drawIconCloud(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col_main,
const ImU32 col_back
);

View File

@ -0,0 +1,49 @@
#include "./direct.hpp"
#include <array>
static void drawIconDirectLines(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col,
const float thickness
) {
#define PLINE(x0, y0, x1, y1) \
ImGui::GetWindowDrawList()->AddLine( \
{p0.x + p1_o.x*(x0), p0.y + p1_o.y*(y0)}, \
{p0.x + p1_o.x*(x1), p0.y + p1_o.y*(y1)}, \
col, \
thickness \
);
// arrow 1
// (3,1) -> (9,7)
PLINE(0.3f, 0.1f, 0.9f, 0.7f)
// (9,7) -> (9,5)
PLINE(0.9f, 0.7f, 0.9f, 0.5f)
// (9,7) -> (7,7)
PLINE(0.9f, 0.7f, 0.7f, 0.7f)
// arrow 2
// (7,9) -> (1,3)
PLINE(0.7f, 0.9f, 0.1f, 0.3f)
// (1,3) -> (3,3)
PLINE(0.1f, 0.3f, 0.3f, 0.3f)
// (1,3) -> (1,5)
PLINE(0.1f, 0.3f, 0.1f, 0.5f)
#undef PLINE
}
void drawIconDirect(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col_main,
const ImU32 col_back
) {
// dark background
// the circle looks bad in light mode
//ImGui::GetWindowDrawList()->AddCircleFilled({p0.x + p1_o.x*0.5f, p0.y + p1_o.y*0.5f}, p1_o.x*0.5f, col_back);
drawIconDirectLines(p0, p1_o, col_back, 4.0f);
drawIconDirectLines(p0, p1_o, col_main, 1.5f);
}

View File

@ -0,0 +1,10 @@
#pragma once
#include <imgui/imgui.h>
void drawIconDirect(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col_main,
const ImU32 col_back
);

View File

@ -0,0 +1,139 @@
#include "./group.hpp"
#include <array>
static void drawIconGroupLines(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col,
const float thickness
) {
#define PLINE(x0, y0, x1, y1) \
ImGui::GetWindowDrawList()->AddLine( \
{p0.x + p1_o.x*(x0), p0.y + p1_o.y*(y0)}, \
{p0.x + p1_o.x*(x1), p0.y + p1_o.y*(y1)}, \
col, \
thickness \
);
// person front
// x y
PLINE(
0.1f, 0.9f,
0.6f, 0.9f
)
PLINE(
0.6f, 0.9f,
0.6f, 0.7f
)
PLINE(
0.6f, 0.7f,
0.5f, 0.6f
)
PLINE(
0.5f, 0.6f,
0.4f, 0.6f
)
PLINE(
0.4f, 0.6f,
0.5f, 0.5f
)
PLINE(
0.5f, 0.5f,
0.5f, 0.4f
)
PLINE(
0.5f, 0.4f,
0.4f, 0.3f
)
PLINE(
0.4f, 0.3f,
0.3f, 0.3f
)
PLINE(
0.3f, 0.3f,
0.2f, 0.4f
)
PLINE(
0.2f, 0.4f,
0.2f, 0.5f
)
PLINE(
0.2f, 0.5f,
0.3f, 0.6f
)
PLINE(
0.3f, 0.6f,
0.2f, 0.6f
)
PLINE(
0.2f, 0.6f,
0.1f, 0.7f
)
PLINE(
0.1f, 0.7f,
0.1f, 0.9f
)
// person back
// x y
PLINE(
0.7f, 0.7f,
0.9f, 0.7f
)
PLINE(
0.9f, 0.7f,
0.9f, 0.5f
)
PLINE(
0.9f, 0.5f,
0.8f, 0.4f
)
PLINE(
0.8f, 0.4f,
0.7f, 0.4f
)
PLINE(
0.7f, 0.4f,
0.8f, 0.3f
)
PLINE(
0.8f, 0.3f,
0.8f, 0.2f
)
PLINE(
0.8f, 0.2f,
0.7f, 0.1f
)
PLINE(
0.7f, 0.1f,
0.6f, 0.1f
)
PLINE(
0.6f, 0.1f,
0.5f, 0.2f
)
PLINE(
0.5f, 0.2f,
0.5f, 0.3f
)
PLINE(
0.5f, 0.3f,
0.6f, 0.4f
)
#undef PLINE
}
void drawIconGroup(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col_main
) {
// dark background
// the circle looks bad in light mode
//ImGui::GetWindowDrawList()->AddCircleFilled({p0.x + p1_o.x*0.5f, p0.y + p1_o.y*0.5f}, p1_o.x*0.5f, col_back);
//drawIconGroupLines(p0, p1_o, col_back, 3.5f);
drawIconGroupLines(p0, p1_o, col_main, 1.0f);
}

View File

@ -0,0 +1,10 @@
#pragma once
#include <imgui/imgui.h>
void drawIconGroup(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col_main
);

View File

@ -0,0 +1,50 @@
#include "./mail.hpp"
#include <array>
static void drawIconMailLines(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col,
const float thickness
) {
#define PLINE(x0, y0, x1, y1) \
ImGui::GetWindowDrawList()->AddLine( \
{p0.x + p1_o.x*(x0), p0.y + p1_o.y*(y0)}, \
{p0.x + p1_o.x*(x1), p0.y + p1_o.y*(y1)}, \
col, \
thickness \
);
// quad
// (1,2) -> (1,8)
PLINE(0.1f, 0.2f, 0.1f, 0.8f)
// (1,8) -> (9,8)
PLINE(0.1f, 0.8f, 0.9f, 0.8f)
// (9,8) -> (9,2)
PLINE(0.9f, 0.8f, 0.9f, 0.2f)
// (9,2) -> (1,2)
PLINE(0.9f, 0.2f, 0.1f, 0.2f)
// lip
// (1,2) -> (5,5)
PLINE(0.1f, 0.2f, 0.5f, 0.5f)
// (5,5) -> (9,2)
PLINE(0.5f, 0.5f, 0.9f, 0.2f)
#undef PLINE
}
void drawIconMail(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col_main,
const ImU32 col_back
) {
// dark background
// the circle looks bad in light mode
//ImGui::GetWindowDrawList()->AddCircleFilled({p0.x + p1_o.x*0.5f, p0.y + p1_o.y*0.5f}, p1_o.x*0.5f, col_back);
drawIconMailLines(p0, p1_o, col_back, 4.0f);
drawIconMailLines(p0, p1_o, col_main, 1.5f);
}

View File

@ -0,0 +1,11 @@
#pragma once
#include <imgui/imgui.h>
void drawIconMail(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col_main,
const ImU32 col_back
);

View File

@ -0,0 +1,101 @@
#include "./person.hpp"
#include <array>
static void drawIconPersonLines(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col,
const float thickness
) {
#define PLINE(x0, y0, x1, y1) \
ImGui::GetWindowDrawList()->AddLine( \
{p0.x + p1_o.x*(x0), p0.y + p1_o.y*(y0)}, \
{p0.x + p1_o.x*(x1), p0.y + p1_o.y*(y1)}, \
col, \
thickness \
);
//// quad
//// (1,2) -> (1,8)
//PLINE(0.1f, 0.2f, 0.1f, 0.8f)
//// (1,8) -> (9,8)
//PLINE(0.1f, 0.8f, 0.9f, 0.8f)
//// (9,8) -> (9,2)
//PLINE(0.9f, 0.8f, 0.9f, 0.2f)
//// (9,2) -> (1,2)
//PLINE(0.9f, 0.2f, 0.1f, 0.2f)
// x y
PLINE(
0.2f, 0.8f,
0.8f, 0.8f
)
PLINE(
0.8f, 0.8f,
0.8f, 0.6f
)
PLINE(
0.8f, 0.6f,
0.7f, 0.5f
)
PLINE(
0.7f, 0.5f,
0.6f, 0.5f
)
PLINE(
0.6f, 0.5f,
0.7f, 0.4f
)
PLINE(
0.7f, 0.4f,
0.7f, 0.2f
)
PLINE(
0.7f, 0.2f,
0.6f, 0.1f
)
PLINE(
0.6f, 0.1f,
0.4f, 0.1f
)
PLINE(
0.4f, 0.1f,
0.3f, 0.2f
)
PLINE(
0.3f, 0.2f,
0.3f, 0.4f
)
PLINE(
0.3f, 0.4f,
0.4f, 0.5f
)
PLINE(
0.4f, 0.5f,
0.3f, 0.5f
)
PLINE(
0.3f, 0.5f,
0.2f, 0.6f
)
PLINE(
0.2f, 0.6f,
0.2f, 0.8f
)
#undef PLINE
}
void drawIconPerson(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col_main
) {
// dark background
// the circle looks bad in light mode
//ImGui::GetWindowDrawList()->AddCircleFilled({p0.x + p1_o.x*0.5f, p0.y + p1_o.y*0.5f}, p1_o.x*0.5f, col_back);
//drawIconPersonLines(p0, p1_o, col_back, 3.5f);
drawIconPersonLines(p0, p1_o, col_main, 1.0f);
}

View File

@ -0,0 +1,10 @@
#pragma once
#include <imgui/imgui.h>
void drawIconPerson(
const ImVec2 p0,
const ImVec2 p1_o,
const ImU32 col_main
);

View File

@ -63,6 +63,28 @@ static constexpr float lerp(float a, float b, float t) {
return a + t * (b - a);
}
// returns divider and places static suffix string into suffix_out
static int64_t sizeToHumanReadable(int64_t file_size, const char*& suffix_out) {
static const char* suffix_arr[] {
"bytes",
"KiB",
"MiB",
"GiB",
"TiB",
"PiB",
// TODO: fix upper bound behaviour
};
int64_t divider = 1024;
for (size_t ij = 0; ij < std::size(suffix_arr); ij++, divider *= 1024) {
if (file_size < divider) {
suffix_out = suffix_arr[ij];
break;
}
}
return (divider > 1024) ? (divider / 1024) : 1;
}
static std::string file_path_url_escape(const std::string&& value) {
std::ostringstream escaped;
@ -817,6 +839,7 @@ void ChatGui4::sendFilePath(const char* file_path) {
void ChatGui4::renderMessageBodyText(Message3Registry& reg, const Message3 e) {
const auto& msgtext = reg.get<Message::Components::MessageText>(e).text;
#if 0
// TODO: set word wrap
ImVec2 text_size = ImGui::CalcTextSize(msgtext.c_str(), msgtext.c_str()+msgtext.size());
text_size.x = -FLT_MIN; // fill width (suppresses label)
@ -849,11 +872,72 @@ void ChatGui4::renderMessageBodyText(Message3Registry& reg, const Message3 e) {
}
}
}
if (ImGui::MenuItem("copy")) {
ImGui::SetClipboardText(msgtext.c_str());
}
ImGui::EndPopup();
}
ImGui::PopStyleColor();
ImGui::PopStyleVar();
#else
ImGui::PushTextWrapPos(0.0f);
std::string_view msgtext_sv{msgtext};
size_t pos_prev {0};
size_t pos_next {msgtext_sv.find_first_of('\n')};
ImGui::BeginGroup();
do {
const auto current_line = msgtext_sv.substr(pos_prev, pos_next - pos_prev);
if (current_line.front() == '>') {
// TODO: theming
ImGui::PushStyleColor(ImGuiCol_Text, {0.3f, 0.9f, 0.1f, 1.f});
ImGui::TextUnformatted(current_line.data(), current_line.data()+current_line.size());
ImGui::PopStyleColor();
} else {
ImGui::TextUnformatted(current_line.data(), current_line.data()+current_line.size());
}
if (pos_next != msgtext_sv.npos) {
pos_next += 1; // skip past
if (pos_next < msgtext_sv.size()) {
pos_prev = pos_next; // old end is new start
pos_next = msgtext_sv.find_first_of('\n', pos_next);
} else {
pos_prev = msgtext_sv.npos;
pos_next = msgtext_sv.npos;
}
} else {
pos_prev = msgtext_sv.npos;
}
} while (pos_prev != msgtext_sv.npos);
ImGui::EndGroup();
ImGui::PopTextWrapPos();
if (ImGui::BeginPopupContextItem("##text")) {
if (ImGui::MenuItem("quote")) {
//text_buffer.insert(0, (_cr.all_of<Contact::Components::Name>(c) ? _cr.get<Contact::Components::Name>(c).name : "<unk>") + ": ");
if (!_text_input_buffer.empty()) {
_text_input_buffer += "\n";
}
_text_input_buffer += "> ";
for (const char c : msgtext) {
_text_input_buffer += c;
if (c == '\n') {
_text_input_buffer += "> ";
}
}
}
if (ImGui::MenuItem("copy")) {
ImGui::SetClipboardText(msgtext.c_str());
}
ImGui::EndPopup();
}
#endif
}
void ChatGui4::renderMessageBodyFile(Message3Registry& reg, const Message3 e) {
@ -995,8 +1079,16 @@ void ChatGui4::renderMessageBodyFile(Message3Registry& reg, const Message3 e) {
for (size_t i = 0; i < file_list.size(); i++) {
ImGui::PushID(i);
const char* byte_suffix = "???";
int64_t byte_divider = sizeToHumanReadable(file_list[i].file_size, byte_suffix);
// TODO: selectable text widget ?
ImGui::Bullet(); ImGui::Text("%s (%lu)", file_list[i].file_name.c_str(), file_list[i].file_size);
ImGui::Bullet(); ImGui::Text("%s (%.2lf %s)", file_list[i].file_name.c_str(), double(file_list[i].file_size)/byte_divider, byte_suffix);
if (ImGui::BeginItemTooltip()) {
ImGui::Text("TODO: file path?");
ImGui::Text("%lu bytes", file_list[i].file_size);
ImGui::EndTooltip();
}
if (reg.all_of<Message::Components::Transfer::FileInfoLocal>(e)) {
const auto& local_info = reg.get<Message::Components::Transfer::FileInfoLocal>(e);

View File

@ -27,6 +27,8 @@ struct ImageLoaderI {
// only positive values are valid
ImageResult crop(int32_t c_x, int32_t c_y, int32_t c_w, int32_t c_h) const;
// TODO: scale
};
virtual ImageResult loadFromMemoryRGBA(const uint8_t* data, uint64_t data_size) = 0;
};

View File

@ -0,0 +1,319 @@
// for the license, see the end of the file
#pragma once
#include "entt/entity/fwd.hpp"
#include <map>
#include <set>
#include <functional>
#include <string>
#include <entt/entt.hpp>
#include <imgui.h>
#ifndef MM_IEEE_ASSERT
#define MM_IEEE_ASSERT(x) assert(x)
#endif
#define MM_IEEE_IMGUI_PAYLOAD_TYPE_ENTITY "MM_IEEE_ENTITY"
#ifndef MM_IEEE_ENTITY_WIDGET
#define MM_IEEE_ENTITY_WIDGET ::MM::EntityWidget
#endif
namespace MM {
template <class EntityType>
inline void EntityWidget(EntityType& e, entt::basic_registry<EntityType>& reg, bool dropTarget = false)
{
ImGui::PushID(static_cast<int>(entt::to_integral(e)));
if (reg.valid(e)) {
ImGui::Text("ID: %d", entt::to_integral(e));
} else {
ImGui::Text("Invalid Entity");
}
if (reg.valid(e)) {
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID)) {
ImGui::SetDragDropPayload(MM_IEEE_IMGUI_PAYLOAD_TYPE_ENTITY, &e, sizeof(e));
ImGui::Text("ID: %d", entt::to_integral(e));
ImGui::EndDragDropSource();
}
}
if (dropTarget && ImGui::BeginDragDropTarget()) {
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(MM_IEEE_IMGUI_PAYLOAD_TYPE_ENTITY)) {
e = *(EntityType*)payload->Data;
}
ImGui::EndDragDropTarget();
}
ImGui::PopID();
}
template <class Component, class EntityType>
void ComponentEditorWidget([[maybe_unused]] entt::basic_registry<EntityType>& registry, [[maybe_unused]] EntityType entity) {}
template <class Component, class EntityType>
void ComponentAddAction(entt::basic_registry<EntityType>& registry, EntityType entity)
{
registry.template emplace<Component>(entity);
}
template <class Component, class EntityType>
void ComponentRemoveAction(entt::basic_registry<EntityType>& registry, EntityType entity)
{
registry.template remove<Component>(entity);
}
template <class EntityType>
class EntityEditor {
public:
using Registry = entt::basic_registry<EntityType>;
using ComponentTypeID = entt::id_type;
struct ComponentInfo {
using Callback = std::function<void(Registry&, EntityType)>;
std::string name;
Callback widget, create, destroy;
};
bool show_window = true;
private:
std::map<ComponentTypeID, ComponentInfo> component_infos;
bool entityHasComponent(Registry& registry, EntityType& entity, ComponentTypeID type_id)
{
const auto* storage_ptr = registry.storage(type_id);
return storage_ptr != nullptr && storage_ptr->contains(entity);
}
public:
template <class Component>
ComponentInfo& registerComponent(const ComponentInfo& component_info)
{
auto index = entt::type_hash<Component>::value();
auto insert_info = component_infos.insert_or_assign(index, component_info);
MM_IEEE_ASSERT(insert_info.second);
return std::get<ComponentInfo>(*insert_info.first);
}
template <class Component>
ComponentInfo& registerComponent(const std::string& name, typename ComponentInfo::Callback widget)
{
return registerComponent<Component>(ComponentInfo{
name,
widget,
ComponentAddAction<Component, EntityType>,
ComponentRemoveAction<Component, EntityType>,
});
}
template <class Component>
ComponentInfo& registerComponent(const std::string& name)
{
return registerComponent<Component>(name, ComponentEditorWidget<Component, EntityType>);
}
void renderEditor(Registry& registry, EntityType& e)
{
ImGui::TextUnformatted("Editing:");
ImGui::SameLine();
MM_IEEE_ENTITY_WIDGET(e, registry, true);
if (ImGui::Button("New")) {
e = registry.create();
}
if (registry.valid(e)) {
ImGui::SameLine();
if (ImGui::Button("Clone")) {
auto old_e = e;
e = registry.create();
// create a copy of an entity component by component
for (auto &&curr: registry.storage()) {
if (auto &storage = curr.second; storage.contains(old_e)) {
// TODO: do something with the return value. returns false on failure.
storage.push(e, storage.value(old_e));
}
}
}
ImGui::SameLine();
ImGui::Dummy({10, 0}); // space destroy a bit, to not accidentally click it
ImGui::SameLine();
// red button
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.65f, 0.15f, 0.15f, 1.f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.8f, 0.3f, 0.3f, 1.f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(1.f, 0.2f, 0.2f, 1.f));
if (ImGui::Button("Destroy")) {
registry.destroy(e);
e = entt::null;
}
ImGui::PopStyleColor(3);
}
ImGui::Separator();
if (registry.valid(e)) {
ImGui::PushID(static_cast<int>(entt::to_integral(e)));
std::map<ComponentTypeID, ComponentInfo> has_not;
for (auto& [component_type_id, ci] : component_infos) {
if (entityHasComponent(registry, e, component_type_id)) {
ImGui::PushID(component_type_id);
if (ImGui::Button("-")) {
ci.destroy(registry, e);
ImGui::PopID();
continue; // early out to prevent access to deleted data
} else {
ImGui::SameLine();
}
if (ImGui::CollapsingHeader(ci.name.c_str())) {
ImGui::Indent(30.f);
ImGui::PushID("Widget");
ci.widget(registry, e);
ImGui::PopID();
ImGui::Unindent(30.f);
}
ImGui::PopID();
} else {
has_not[component_type_id] = ci;
}
}
if (!has_not.empty()) {
if (ImGui::Button("+ Add Component")) {
ImGui::OpenPopup("Add Component");
}
if (ImGui::BeginPopup("Add Component")) {
ImGui::TextUnformatted("Available:");
ImGui::Separator();
for (auto& [component_type_id, ci] : has_not) {
ImGui::PushID(component_type_id);
if (ImGui::Selectable(ci.name.c_str())) {
ci.create(registry, e);
}
ImGui::PopID();
}
ImGui::EndPopup();
}
}
ImGui::PopID();
}
}
void renderEntityList(Registry& registry, std::set<ComponentTypeID>& comp_list)
{
ImGui::Text("Components Filter:");
ImGui::SameLine();
if (ImGui::SmallButton("clear")) {
comp_list.clear();
}
ImGui::Indent();
for (const auto& [component_type_id, ci] : component_infos) {
bool is_in_list = comp_list.count(component_type_id);
bool active = is_in_list;
ImGui::Checkbox(ci.name.c_str(), &active);
if (is_in_list && !active) { // remove
comp_list.erase(component_type_id);
} else if (!is_in_list && active) { // add
comp_list.emplace(component_type_id);
}
}
ImGui::Unindent();
ImGui::Separator();
if (comp_list.empty()) {
ImGui::Text("Orphans:");
for (EntityType e : registry.template storage<EntityType>()) {
if (registry.orphan(e)) {
MM_IEEE_ENTITY_WIDGET(e, registry, false);
}
}
} else {
entt::basic_runtime_view<entt::basic_sparse_set<EntityType>> view{};
for (const auto type : comp_list) {
auto* storage_ptr = registry.storage(type);
if (storage_ptr != nullptr) {
view.iterate(*storage_ptr);
}
}
// TODO: add support for exclude
ImGui::Text("%lu Entities Matching:", view.size_hint());
if (ImGui::BeginChild("entity list")) {
for (auto e : view) {
MM_IEEE_ENTITY_WIDGET(e, registry, false);
}
}
ImGui::EndChild();
}
}
// displays both, editor and list
// uses static internally, use only as a quick way to get going!
void renderSimpleCombo(Registry& registry, EntityType& e)
{
if (show_window) {
ImGui::SetNextWindowSize(ImVec2(550, 400), ImGuiCond_FirstUseEver);
if (ImGui::Begin("Entity Editor", &show_window)) {
if (ImGui::BeginChild("list", {200, 0}, true)) {
static std::set<ComponentTypeID> comp_list;
renderEntityList(registry, comp_list);
}
ImGui::EndChild();
ImGui::SameLine();
if (ImGui::BeginChild("editor")) {
renderEditor(registry, e);
}
ImGui::EndChild();
}
ImGui::End();
}
}
};
} // MM
// MIT License
// Copyright (c) 2019-2022 Erik Scholz
// Copyright (c) 2020 Gnik Droy
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

View File

@ -51,7 +51,7 @@ int main(int argc, char** argv) {
// more RAII
std::unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)> window {
SDL_CreateWindow("tomato", 1280, 720, SDL_WINDOW_RESIZABLE),
SDL_CreateWindow("tomato", 1280, 720, SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY),
&SDL_DestroyWindow
};

View File

@ -35,6 +35,7 @@ MainScreen::MainScreen(SimpleConfigModel&& conf_, SDL_Renderer* renderer_, Theme
msg_tc(mil, sdlrtu),
cg(conf, rmm, cr, sdlrtu, contact_tc, msg_tc, theme),
sw(conf),
osui(os),
tuiu(tc, conf),
tdch(tpi)
{
@ -248,6 +249,7 @@ Screen* MainScreen::render(float time_delta, bool&) {
const float cg_interval = cg.render(time_delta); // render
sw.render(); // render
osui.render();
tuiu.render(); // render
tdch.render(); // render

View File

@ -29,6 +29,7 @@
#include "./chat_gui4.hpp"
#include "./chat_gui/settings_window.hpp"
#include "./object_store_ui.hpp"
#include "./tox_ui_utils.hpp"
#include "./tox_dht_cap_histo.hpp"
#include "./tox_friend_faux_offline_messaging.hpp"
@ -77,6 +78,7 @@ struct MainScreen final : public Screen {
ChatGui4 cg;
SettingsWindow sw;
ObjectStoreUI osui;
ToxUIUtils tuiu;
ToxDHTCapHisto tdch;

104
src/object_store_ui.cpp Normal file
View File

@ -0,0 +1,104 @@
#include "./object_store_ui.hpp"
#include <solanaceae/util/utils.hpp>
#include <solanaceae/object_store/meta_components.hpp>
#include <imgui/imgui.h>
#include <solanaceae/message3/components.hpp>
namespace MM {
template<> void ComponentEditorWidget<ObjectStore::Components::ID>(entt::basic_registry<Object>& registry, Object entity) {
auto& c = registry.get<ObjectStore::Components::ID>(entity);
const auto str = bin2hex(c.v);
ImGui::TextUnformatted(str.c_str());
}
template<> void ComponentEditorWidget<Message::Components::Transfer::FileInfo>(entt::basic_registry<Object>& registry, Object entity) {
auto& c = registry.get<Message::Components::Transfer::FileInfo>(entity);
ImGui::Text("Total size: %lu", c.total_size);
if (ImGui::BeginTable("file list", 2, ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_SizingFixedFit)) {
ImGui::TableSetupColumn("name", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("size", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableHeadersRow();
for (const auto& entry : c.file_list) {
ImGui::TableNextColumn();
ImGui::TextUnformatted(entry.file_name.c_str());
ImGui::TableNextColumn();
ImGui::Text("%lu", entry.file_size);
}
ImGui::EndTable();
}
}
template<> void ComponentEditorWidget<Message::Components::Transfer::FileInfoLocal>(entt::basic_registry<Object>& registry, Object entity) {
auto& c = registry.get<Message::Components::Transfer::FileInfoLocal>(entity);
if (ImGui::BeginTable("file list", 1, ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_SizingFixedFit)) {
ImGui::TableSetupColumn("name", ImGuiTableColumnFlags_WidthStretch);
//ImGui::TableSetupColumn("size", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableHeadersRow();
for (const auto& entry : c.file_list) {
ImGui::TableNextColumn();
ImGui::TextUnformatted(entry.c_str());
}
ImGui::EndTable();
}
}
template<> void ComponentEditorWidget<Message::Components::Transfer::BytesReceived>(entt::basic_registry<Object>& registry, Object entity) {
auto& c = registry.get<Message::Components::Transfer::BytesReceived>(entity);
ImGui::Text("total bytes received: %lu", c.total);
}
template<> void ComponentEditorWidget<Message::Components::Transfer::BytesSent>(entt::basic_registry<Object>& registry, Object entity) {
auto& c = registry.get<Message::Components::Transfer::BytesSent>(entity);
ImGui::Text("total bytes sent: %lu", c.total);
}
} // MM
ObjectStoreUI::ObjectStoreUI(
ObjectStore2& os
) : _os(os) {
_ee.show_window = false;
_ee.registerComponent<ObjectStore::Components::ID>("ID");
_ee.registerComponent<ObjectStore::Components::DataCompressionType>("DataCompressionType");
_ee.registerComponent<Message::Components::Transfer::FileInfo>("Transfer::FileInfo");
_ee.registerComponent<Message::Components::Transfer::FileInfoLocal>("Transfer::FileInfoLocal");
_ee.registerComponent<Message::Components::Transfer::BytesReceived>("Transfer::BytesReceived");
_ee.registerComponent<Message::Components::Transfer::BytesSent>("Transfer::BytesSent");
}
void ObjectStoreUI::render(void) {
{ // main window menubar injection
// assumes the window "tomato" was rendered already by cg
if (ImGui::Begin("tomato")) {
if (ImGui::BeginMenuBar()) {
ImGui::Separator();
if (ImGui::BeginMenu("ObjectStore")) {
if (ImGui::MenuItem("Inspector")) {
_ee.show_window = true;
}
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
}
ImGui::End();
}
static Object selected_ent {entt::null};
_ee.renderSimpleCombo(_os.registry(), selected_ent);
}

19
src/object_store_ui.hpp Normal file
View File

@ -0,0 +1,19 @@
#pragma once
#include <solanaceae/object_store/object_store.hpp>
#include "./imgui_entt_entity_editor.hpp"
class ObjectStoreUI {
ObjectStore2& _os;
MM::EntityEditor<Object> _ee;
public:
ObjectStoreUI(
ObjectStore2& os
);
void render(void);
};

View File

@ -50,6 +50,12 @@ StartScreen::StartScreen(const std::vector<std::string_view>& args, SDL_Renderer
}
}
{ // seed tox save path
if (_conf.has_string("tox", "save_file_path")) {
_tox_profile_path = _conf.get_string("tox", "save_file_path").value();
}
}
float display_scale = SDL_GetWindowDisplayScale(SDL_GetRenderWindow(renderer));
if (display_scale < 0.001f) {
// error?
@ -134,6 +140,9 @@ StartScreen::StartScreen(const std::vector<std::string_view>& args, SDL_Renderer
}
Screen* StartScreen::render(float, bool&) {
const float TEXT_LOAD_WIDTH = ImGui::CalcTextSize("load").x;
const float TEXT_BASE_HEIGHT = ImGui::GetTextLineHeightWithSpacing();
// TODO: imgui tox profile selector?
@ -246,7 +255,7 @@ Screen* StartScreen::render(float, bool&) {
// load but file missing
ImGui::BeginDisabled();
ImGui::Button("load", {60, 25});
ImGui::Button("load", {TEXT_LOAD_WIDTH*1.5f, TEXT_BASE_HEIGHT*1.5f});
ImGui::EndDisabled();
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_AllowWhenDisabled)) {
@ -256,14 +265,14 @@ Screen* StartScreen::render(float, bool&) {
// new but file exists
ImGui::BeginDisabled();
ImGui::Button("load", {60, 25});
ImGui::Button("load", {TEXT_LOAD_WIDTH*1.5f, TEXT_BASE_HEIGHT*1.5f});
ImGui::EndDisabled();
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_AllowWhenDisabled)) {
ImGui::SetTooltip("file already exists");
}
} else {
if (ImGui::Button("load", {60, 25})) {
if (ImGui::Button("load", {TEXT_LOAD_WIDTH*1.5f, TEXT_BASE_HEIGHT*1.5f})) {
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();

View File

@ -29,6 +29,9 @@ void ToxUIUtils::render(void) {
if (ImGui::MenuItem("add Friend by ID")) {
_show_add_friend_window = true;
}
if (ImGui::MenuItem("copy own ToxID")) {
ImGui::SetClipboardText(_tc.toxSelfGetAddressStr().c_str());
}
if (ImGui::MenuItem("join Group by ID (ngc)")) {
_show_add_group_window = true;
}