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 git pull
- name: Install Dependencies - 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 # setup vs env
- uses: ilammy/msvc-dev-cmd@v1 - uses: ilammy/msvc-dev-cmd@v1
@ -212,7 +212,7 @@ jobs:
git pull git pull
- name: Install Dependencies - 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 # setup vs env
- uses: ilammy/msvc-dev-cmd@v1 - uses: ilammy/msvc-dev-cmd@v1

View File

@ -129,7 +129,7 @@ jobs:
git pull git pull
- name: Install Dependencies - 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 # setup vs env
- uses: ilammy/msvc-dev-cmd@v1 - uses: ilammy/msvc-dev-cmd@v1

View File

@ -96,14 +96,11 @@
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter> </intent-filter>
<!-- Drop file event --> <!-- Drop file event -->
<!--
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" /> <data android:mimeType="*/*" />
</intent-filter> </intent-filter>
-->
</activity> </activity>
</application> </application>
</manifest> </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(EXPERIMENTAL_API ON CACHE BOOL "" FORCE)
set(UNITTEST OFF CACHE BOOL "" FORCE) set(UNITTEST OFF CACHE BOOL "" FORCE)
set(BOOTSTRAP_DAEMON OFF CACHE BOOL "" FORCE) set(BOOTSTRAP_DAEMON OFF CACHE BOOL "" FORCE)
#set(BUILD_TOXAV ON CACHE BOOL "")
add_subdirectory(./c-toxcore) add_subdirectory(./c-toxcore)
# the ideal case #message("II BUILD_TOXAV: ${BUILD_TOXAV}")
#add_library(toxcore ALIAS toxcore_static)
# the sad case # the sad case
add_library(toxcore INTERFACE) add_library(toxcore INTERFACE)
if (TARGET toxcore_static) if (TARGET toxcore_static)
target_link_libraries(toxcore INTERFACE toxcore_static) target_link_libraries(toxcore INTERFACE toxcore_static)
# the ideal case
#add_library(toxcore ALIAS toxcore_static)
else() else()
target_link_libraries(toxcore INTERFACE toxcore_shared) target_link_libraries(toxcore INTERFACE toxcore_shared)
# the ideal case
#add_library(toxcore ALIAS toxcore_shared)
endif() endif()
# HACK: "install" api headers into binary dir # HACK: "install" api headers into binary dir
@ -64,3 +70,8 @@ elseif(sodium_FOUND)
else() else()
message(SEND_ERROR "missing libsodium") message(SEND_ERROR "missing libsodium")
endif() 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": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1718111384, "lastModified": 1720691131,
"narHash": "sha256-7tSst0S5FOmcgvNtfy6cjZX5w8CabCVAfAeCkhY4OVg=", "narHash": "sha256-CWT+KN8aTPyMIx8P303gsVxUnkinIz0a/Cmasz1jyIM=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "a508a44af0c1b1b57785c34d8b54783536273eeb", "rev": "a046c1202e11b62cbede5385ba64908feb7bfac4",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

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

View File

@ -67,6 +67,16 @@ target_sources(tomato PUBLIC
./chat_gui/theme.hpp ./chat_gui/theme.hpp
./chat_gui/theme.cpp ./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.hpp
./chat_gui/contact_list.cpp ./chat_gui/contact_list.cpp
./chat_gui/file_selector.hpp ./chat_gui/file_selector.hpp
@ -76,6 +86,10 @@ target_sources(tomato PUBLIC
./chat_gui/settings_window.hpp ./chat_gui/settings_window.hpp
./chat_gui/settings_window.cpp ./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.hpp
./tox_ui_utils.cpp ./tox_ui_utils.cpp

View File

@ -1,139 +1,16 @@
#include "./contact_list.hpp" #include "./contact_list.hpp"
#include <solanaceae/contact/components.hpp> #include <solanaceae/contact/components.hpp>
#include <solanaceae/util/utils.hpp>
#include <imgui/imgui.h> #include <imgui/imgui.h>
//#include <imgui/imgui_internal.h> //#include <imgui/imgui_internal.h>
#include <array> #include "./icons/direct.hpp"
#include "./icons/cloud.hpp"
static void drawIconDirectLines( #include "./icons/mail.hpp"
const ImVec2 p0, #include "./icons/person.hpp"
const ImVec2 p1_o, #include "./icons/group.hpp"
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);
}
void renderAvatar( void renderAvatar(
const Theme& th, const Theme& th,
@ -220,6 +97,11 @@ bool renderContactBig(
const auto* cstate = c.try_get<Contact::Components::ConnectionState>(); const auto* cstate = c.try_get<Contact::Components::ConnectionState>();
if (ImGui::BeginItemTooltip()) { 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) { if (cstate != nullptr) {
ImGui::Text("Connection state: %s", ImGui::Text("Connection state: %s",
(cstate->state == Contact::Components::ConnectionState::disconnected) (cstate->state == Contact::Components::ConnectionState::disconnected)
@ -264,6 +146,9 @@ bool renderContactBig(
ImGui::SameLine(0.f, same_line_spacing); ImGui::SameLine(0.f, same_line_spacing);
ImGui::BeginGroup(); ImGui::BeginGroup();
{ {
const bool is_group = c.all_of<Contact::Components::TagGroup>();
const bool is_private = c.all_of<Contact::Components::TagPrivate>();
{ // line 1 { // line 1
if (line_height == 1 && cstate != nullptr) { if (line_height == 1 && cstate != nullptr) {
// icon pos // icon pos
@ -271,6 +156,8 @@ bool renderContactBig(
p0.y += ImGui::GetStyle().FramePadding.y; p0.y += ImGui::GetStyle().FramePadding.y;
ImVec2 p1_o = {img_y, img_y}; // img_y is 1 line_height in this case ImVec2 p1_o = {img_y, img_y}; // img_y is 1 line_height in this case
ImGui::Dummy(p1_o);
if (ImGui::IsItemVisible()) {
const ImU32 col_back = ImGui::GetColorU32(th.getColor<ThemeCol_Contact::icon_backdrop>()); const ImU32 col_back = ImGui::GetColorU32(th.getColor<ThemeCol_Contact::icon_backdrop>());
if (cstate->state == Contact::Components::ConnectionState::direct) { // direct icon if (cstate->state == Contact::Components::ConnectionState::direct) { // direct icon
drawIconDirect( drawIconDirect(
@ -287,7 +174,34 @@ bool renderContactBig(
col_back 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); 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); ImGui::SameLine(0.f, same_line_spacing);
} }
@ -327,6 +241,8 @@ bool renderContactBig(
const float box_hight = TEXT_BASE_HEIGHT - ImGui::GetStyle().FramePadding.y*2; const float box_hight = TEXT_BASE_HEIGHT - ImGui::GetStyle().FramePadding.y*2;
ImVec2 p1_o = {box_hight, box_hight}; ImVec2 p1_o = {box_hight, box_hight};
ImGui::Dummy(p1_o);
if (ImGui::IsItemVisible()) {
const ImU32 col_back = ImGui::GetColorU32(th.getColor<ThemeCol_Contact::icon_backdrop>()); const ImU32 col_back = ImGui::GetColorU32(th.getColor<ThemeCol_Contact::icon_backdrop>());
if (cstate->state == Contact::Components::ConnectionState::direct) { // direct icon if (cstate->state == Contact::Components::ConnectionState::direct) { // direct icon
drawIconDirect( drawIconDirect(
@ -343,7 +259,7 @@ bool renderContactBig(
col_back col_back
); );
} }
ImGui::Dummy(p1_o); }
ImGui::SameLine(0.f, same_line_spacing); ImGui::SameLine(0.f, same_line_spacing);
} }

View File

@ -6,6 +6,7 @@
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <algorithm>
void FileSelector::reset(void) { void FileSelector::reset(void) {
_is_valid = [](auto){ return true; }; _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); 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) { static std::string file_path_url_escape(const std::string&& value) {
std::ostringstream escaped; std::ostringstream escaped;
@ -817,6 +839,7 @@ void ChatGui4::sendFilePath(const char* file_path) {
void ChatGui4::renderMessageBodyText(Message3Registry& reg, const Message3 e) { void ChatGui4::renderMessageBodyText(Message3Registry& reg, const Message3 e) {
const auto& msgtext = reg.get<Message::Components::MessageText>(e).text; const auto& msgtext = reg.get<Message::Components::MessageText>(e).text;
#if 0
// TODO: set word wrap // TODO: set word wrap
ImVec2 text_size = ImGui::CalcTextSize(msgtext.c_str(), msgtext.c_str()+msgtext.size()); ImVec2 text_size = ImGui::CalcTextSize(msgtext.c_str(), msgtext.c_str()+msgtext.size());
text_size.x = -FLT_MIN; // fill width (suppresses label) 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::EndPopup();
} }
ImGui::PopStyleColor(); ImGui::PopStyleColor();
ImGui::PopStyleVar(); 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) { 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++) { for (size_t i = 0; i < file_list.size(); i++) {
ImGui::PushID(i); ImGui::PushID(i);
const char* byte_suffix = "???";
int64_t byte_divider = sizeToHumanReadable(file_list[i].file_size, byte_suffix);
// TODO: selectable text widget ? // 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)) { if (reg.all_of<Message::Components::Transfer::FileInfoLocal>(e)) {
const auto& local_info = reg.get<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 // only positive values are valid
ImageResult crop(int32_t c_x, int32_t c_y, int32_t c_w, int32_t c_h) const; 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; 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 // more RAII
std::unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)> window { 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 &SDL_DestroyWindow
}; };

View File

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

View File

@ -29,6 +29,7 @@
#include "./chat_gui4.hpp" #include "./chat_gui4.hpp"
#include "./chat_gui/settings_window.hpp" #include "./chat_gui/settings_window.hpp"
#include "./object_store_ui.hpp"
#include "./tox_ui_utils.hpp" #include "./tox_ui_utils.hpp"
#include "./tox_dht_cap_histo.hpp" #include "./tox_dht_cap_histo.hpp"
#include "./tox_friend_faux_offline_messaging.hpp" #include "./tox_friend_faux_offline_messaging.hpp"
@ -77,6 +78,7 @@ struct MainScreen final : public Screen {
ChatGui4 cg; ChatGui4 cg;
SettingsWindow sw; SettingsWindow sw;
ObjectStoreUI osui;
ToxUIUtils tuiu; ToxUIUtils tuiu;
ToxDHTCapHisto tdch; 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)); float display_scale = SDL_GetWindowDisplayScale(SDL_GetRenderWindow(renderer));
if (display_scale < 0.001f) { if (display_scale < 0.001f) {
// error? // error?
@ -134,6 +140,9 @@ StartScreen::StartScreen(const std::vector<std::string_view>& args, SDL_Renderer
} }
Screen* StartScreen::render(float, bool&) { 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? // TODO: imgui tox profile selector?
@ -246,7 +255,7 @@ Screen* StartScreen::render(float, bool&) {
// load but file missing // load but file missing
ImGui::BeginDisabled(); ImGui::BeginDisabled();
ImGui::Button("load", {60, 25}); ImGui::Button("load", {TEXT_LOAD_WIDTH*1.5f, TEXT_BASE_HEIGHT*1.5f});
ImGui::EndDisabled(); ImGui::EndDisabled();
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_AllowWhenDisabled)) { if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_AllowWhenDisabled)) {
@ -256,14 +265,14 @@ Screen* StartScreen::render(float, bool&) {
// new but file exists // new but file exists
ImGui::BeginDisabled(); ImGui::BeginDisabled();
ImGui::Button("load", {60, 25}); ImGui::Button("load", {TEXT_LOAD_WIDTH*1.5f, TEXT_BASE_HEIGHT*1.5f});
ImGui::EndDisabled(); ImGui::EndDisabled();
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_AllowWhenDisabled)) { if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_AllowWhenDisabled)) {
ImGui::SetTooltip("file already exists"); ImGui::SetTooltip("file already exists");
} }
} else { } 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); 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(); return new_screen.release();

View File

@ -29,6 +29,9 @@ void ToxUIUtils::render(void) {
if (ImGui::MenuItem("add Friend by ID")) { if (ImGui::MenuItem("add Friend by ID")) {
_show_add_friend_window = true; _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)")) { if (ImGui::MenuItem("join Group by ID (ngc)")) {
_show_add_group_window = true; _show_add_group_window = true;
} }