Compare commits

...

15 Commits

20 changed files with 210 additions and 39 deletions

View File

@ -28,7 +28,7 @@ jobs:
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato
- name: Determine tag name
id: tag
@ -67,6 +67,12 @@ jobs:
with:
submodules: recursive
- name: update vcpkg
shell: bash
run: |
cd C:/vcpkg
git pull
- name: Install Dependencies
run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static pkgconf:x64-windows
@ -82,7 +88,7 @@ jobs:
run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DSDL3IMAGE_VENDORED=ON -DSDL3IMAGE_DEPS_SHARED=ON -DSDL3IMAGE_JXL=OFF -DSDL3IMAGE_AVIF=OFF -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -t tomato
- name: Determine tag name
id: tag
@ -121,6 +127,12 @@ jobs:
with:
submodules: recursive
- name: update vcpkg
shell: bash
run: |
cd C:/vcpkg
git pull
- name: Install Dependencies
run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static pkgconf:x64-windows
@ -136,7 +148,7 @@ jobs:
run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DTOMATO_ASAN=ON -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DSDL3IMAGE_VENDORED=ON -DSDL3IMAGE_DEPS_SHARED=ON -DSDL3IMAGE_JXL=OFF -DSDL3IMAGE_AVIF=OFF -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato
- name: Determine tag name
id: tag

View File

@ -27,7 +27,7 @@ jobs:
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato
macos:
timeout-minutes: 10
@ -46,7 +46,7 @@ jobs:
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato
windows:
timeout-minutes: 15
@ -58,6 +58,12 @@ jobs:
with:
submodules: recursive
- name: update vcpkg
shell: bash
run: |
cd C:/vcpkg
git pull
- name: Install Dependencies
run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static pkgconf:x64-windows
@ -73,5 +79,5 @@ jobs:
run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DSDL3IMAGE_VENDORED=ON -DSDL3IMAGE_DEPS_SHARED=ON -DSDL3IMAGE_JXL=OFF -DSDL3IMAGE_AVIF=OFF -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato

View File

@ -38,6 +38,10 @@ if (TOMATO_ASAN)
endif()
endif()
# uggly, but it needs to be defined for all of tomato.
# but this also means that we can not compile tomato in the same cmake as plugins
add_compile_definitions(ENTT_API_EXPORT)
# external libs
add_subdirectory(./external) # before increasing warn levels, sad :(

View File

@ -10,7 +10,10 @@ if (NOT TARGET SDL3::SDL3)
FetchContent_Declare(SDL3
GIT_REPOSITORY https://github.com/libsdl-org/SDL
#GIT_TAG 0429f5d6a36fc35b551bcc2acd4a40c2db6dab82 # tip when looking
GIT_TAG 14f584a94bfd49cf1524db75bf3c419fdf9436cd # tip 26-04-2024
#GIT_TAG 14f584a94bfd49cf1524db75bf3c419fdf9436cd # tip 26-04-2024
GIT_TAG 06d6f2cb2518622593570985589700910cf4399f # 13-05-2024 - before
# made changes that break imgui release 1.90.6
#GIT_TAG 1103294d33f47ab4c697bb22a9cf27c79c658630 # tip 15-05-2024
FIND_PACKAGE_ARGS # for the future
)
FetchContent_MakeAvailable(SDL3)

View File

@ -15,7 +15,8 @@ if (NOT TARGET SDL3_image::SDL3_image)
FetchContent_Declare(SDL3_image
GIT_REPOSITORY https://github.com/libsdl-org/SDL_image
# waiting on the imgui pr to get merged so i can update sdl <.<
GIT_TAG a45d6e5b84ccc0f3faae6ba7d561709ed600eee7 # tip last check
#GIT_TAG a45d6e5b84ccc0f3faae6ba7d561709ed600eee7 # tip last check
GIT_TAG a34ccf16f961e6d5a480045eb650fc3dddb4bfaa # tip 14-05-2024
FIND_PACKAGE_ARGS # for the future
)
FetchContent_MakeAvailable(SDL3_image)

16
flake.lock generated
View File

@ -63,34 +63,34 @@
"sdl3": {
"flake": false,
"locked": {
"lastModified": 1714100414,
"narHash": "sha256-eaiVG5WJoLnFvdpYBR+DF+YuMu5C3lA1SKuzN8+hfDM=",
"lastModified": 1715616572,
"narHash": "sha256-SCl7RbRThjci0xXUz9vmwDfqp0kenxEuuvoNlx6yiyU=",
"owner": "libsdl-org",
"repo": "SDL",
"rev": "14f584a94bfd49cf1524db75bf3c419fdf9436cd",
"rev": "06d6f2cb2518622593570985589700910cf4399f",
"type": "github"
},
"original": {
"owner": "libsdl-org",
"repo": "SDL",
"rev": "14f584a94bfd49cf1524db75bf3c419fdf9436cd",
"rev": "06d6f2cb2518622593570985589700910cf4399f",
"type": "github"
}
},
"sdl3_image": {
"flake": false,
"locked": {
"lastModified": 1712700609,
"narHash": "sha256-PVPH1uJ6g65SzHUboeQE6ZkC+72doMz9t9SG2LBo+7I=",
"lastModified": 1715708273,
"narHash": "sha256-scNPhzGk+d8VqkOKsSxmH/OVLgkWrOkEeWn/b2f3XaU=",
"owner": "libsdl-org",
"repo": "SDL_image",
"rev": "a45d6e5b84ccc0f3faae6ba7d561709ed600eee7",
"rev": "a34ccf16f961e6d5a480045eb650fc3dddb4bfaa",
"type": "github"
},
"original": {
"owner": "libsdl-org",
"repo": "SDL_image",
"rev": "a45d6e5b84ccc0f3faae6ba7d561709ed600eee7",
"rev": "a34ccf16f961e6d5a480045eb650fc3dddb4bfaa",
"type": "github"
}
},

View File

@ -11,11 +11,11 @@
flake = false;
};
sdl3 = {
url = "github:libsdl-org/SDL/14f584a94bfd49cf1524db75bf3c419fdf9436cd"; # keep in sync this cmake
url = "github:libsdl-org/SDL/06d6f2cb2518622593570985589700910cf4399f"; # keep in sync this cmake
flake = false;
};
sdl3_image = {
url = "github:libsdl-org/SDL_image/a45d6e5b84ccc0f3faae6ba7d561709ed600eee7";
url = "github:libsdl-org/SDL_image/a34ccf16f961e6d5a480045eb650fc3dddb4bfaa";
flake = false;
};
};

View File

@ -105,3 +105,8 @@ target_link_libraries(tomato PUBLIC
SDL3_image::SDL3_image
)
# probably not enough
#target_compile_definitions(tomato PUBLIC ENTT_API_EXPORT)
set_target_properties(tomato PROPERTIES POSITION_INDEPENDENT_CODE ON)

View File

@ -89,6 +89,52 @@ static void drawIconCloud(
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(
const Theme& th,
ContactTextureCache& contact_tc,
@ -245,7 +291,26 @@ bool renderContactBig(
ImGui::SameLine(0.f, same_line_spacing);
}
ImGui::Text("%s%s", unread?"* ":"", (c.all_of<Contact::Components::Name>() ? c.get<Contact::Components::Name>().name.c_str() : "<unk>"));
//ImGui::Text("%s%s", unread?"* ":"", (c.all_of<Contact::Components::Name>() ? c.get<Contact::Components::Name>().name.c_str() : "<unk>"));
ImGui::TextUnformatted(c.all_of<Contact::Components::Name>() ? c.get<Contact::Components::Name>().name.c_str() : "<unk>");
if (unread) {
ImGui::SameLine();
const float icon_size { TEXT_BASE_HEIGHT - ImGui::GetStyle().FramePadding.y*2 };
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - icon_size);
// icon pos
auto p0 = ImGui::GetCursorScreenPos();
//p0.y += ImGui::GetStyle().FramePadding.y;
ImVec2 p1_o = {icon_size, icon_size};
drawIconMail(
p0,
p1_o,
ImGui::GetColorU32(th.getColor<ThemeCol_Contact::unread>()),
ImGui::GetColorU32(th.getColor<ThemeCol_Contact::icon_backdrop>())
);
ImGui::Dummy(p1_o);
}
}
// line 2

View File

@ -14,6 +14,9 @@ enum class ThemeCol_Contact {
avatar_online_cloud,
avatar_offline,
unread,
unread_muted,
icon_backdrop,
};
@ -27,7 +30,7 @@ void renderAvatar(
// returns true if clicked, if selectable, will highlight on hover and respect selected
// TODO: refine
// +------+
// | | *Name (Alias?)
// | | *Name (Alias?) [v]
// |Avatar| Satus Message <-- richpresence interface?
// | | user status (online/away/busy)-direct/relayed / offline <-- last text?
// +------+

View File

@ -41,14 +41,17 @@ bool Theme::store(void) {
Theme getDefaultThemeDark(void) {
Theme t;
t.setColor<ThemeCol_Contact::request_incoming >({0.98f, 0.41f, 0.26f, 0.52f});
t.setColor<ThemeCol_Contact::request_outgoing >({0.98f, 0.26f, 0.41f, 0.52f});
t.setColor<ThemeCol_Contact::request_incoming >({0.98f, 0.41f, 0.26f, 0.52f});
t.setColor<ThemeCol_Contact::request_outgoing >({0.98f, 0.26f, 0.41f, 0.52f});
t.setColor<ThemeCol_Contact::avatar_online_direct >({0.3f, 1.0f, 0.0f, 1.0f});
t.setColor<ThemeCol_Contact::avatar_online_cloud >({0.0f, 1.0f, 0.8f, 1.0f});
t.setColor<ThemeCol_Contact::avatar_offline >({0.4f, 0.4f, 0.4f, 1.0f});
t.setColor<ThemeCol_Contact::avatar_offline >({0.4f, 0.4f, 0.4f, 1.0f});
t.setColor<ThemeCol_Contact::icon_backdrop >({0.0f, 0.0f, 0.0f, 0.4f});
t.setColor<ThemeCol_Contact::unread >(ImGui::GetStyleColorVec4(ImGuiCol_PlotHistogramHovered));
t.setColor<ThemeCol_Contact::unread_muted >({0.6f, 0.6f, 0.6f, 0.9f});
t.setColor<ThemeCol_Contact::icon_backdrop >({0.0f, 0.0f, 0.0f, 0.4f});
return t;
}

View File

@ -89,6 +89,30 @@ static std::string file_path_url_escape(const std::string&& value) {
return escaped.str();
}
static std::string file_path_to_file_url(const std::filesystem::path& path) {
const auto can_path = std::filesystem::canonical(path);
std::string url {"file://"};
// special windows detection <.<
// we detect a drive letter here
if (can_path.has_root_name() && can_path.root_name().generic_u8string().back() == ':') {
const std::string root_name = can_path.root_name().generic_u8string();
// drive letters have a colon, which needs skipping the url escaping
url += "/";
url += root_name;
//url += "/";
// bugged, does not work (but it should, open msvc stl issue?)
//url += file_path_url_escape(can_path.lexically_proximate(can_path.root_name()).generic_u8string());
// remove drive letter
url += file_path_url_escape(can_path.generic_u8string().substr(root_name.size()));
} else {
url += file_path_url_escape(can_path.generic_u8string());
}
return url;
}
const void* clipboard_callback(void* userdata, const char* mime_type, size_t* size) {
if (mime_type == nullptr) {
// cleared or new data is set
@ -130,10 +154,14 @@ void ChatGui4::setClipboardData(std::vector<std::string> mime_types, std::shared
std::vector<const char*> tmp_mimetype_list;
std::lock_guard lg{_set_clipboard_data_mutex};
for (const auto& mime_type : mime_types) {
tmp_mimetype_list.push_back(mime_type.data());
_set_clipboard_data[mime_type] = data;
{
std::lock_guard lg{_set_clipboard_data_mutex};
for (const auto& mime_type : mime_types) {
tmp_mimetype_list.push_back(mime_type.data());
_set_clipboard_data[mime_type] = data;
}
// release lock, since on some platforms the callback is called immediatly
}
SDL_SetClipboardData(clipboard_callback, nullptr, this, tmp_mimetype_list.data(), tmp_mimetype_list.size());
@ -974,12 +1002,12 @@ void ChatGui4::renderMessageBodyFile(Message3Registry& reg, const Message3 e) {
const auto& local_info = reg.get<Message::Components::Transfer::FileInfoLocal>(e);
if (local_info.file_list.size() > i && ImGui::BeginPopupContextItem("##file_c")) {
if (ImGui::MenuItem("open")) {
const std::string url{"file://" + file_path_url_escape(std::filesystem::canonical(local_info.file_list.at(i)).generic_u8string())};
const std::string url {file_path_to_file_url(local_info.file_list.at(i))};
std::cout << "opening file '" << url << "'\n";
SDL_OpenURL(url.c_str());
}
if (ImGui::MenuItem("copy file")) {
const std::string url{"file://" + file_path_url_escape(std::filesystem::canonical(local_info.file_list.at(i)).generic_u8string())};
const std::string url {file_path_to_file_url(local_info.file_list.at(i))};
//ImGui::SetClipboardText(url.c_str());
setClipboardData({"text/uri-list", "text/x-moz-url"}, std::make_shared<std::vector<uint8_t>>(url.begin(), url.end()));
}

View File

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

View File

@ -73,15 +73,56 @@ MainScreen::MainScreen(SDL_Renderer* renderer_, Theme& theme_, std::string save_
// TODO: pm?
// graphics
g_provideInstance("ImGuiContext", ImGui::GetVersion(), "host", ImGui::GetCurrentContext());
g_provideInstance<ImGuiContext>("ImGuiContext", ImGui::GetVersion(), "host", ImGui::GetCurrentContext());
{
ImGuiMemAllocFunc alloc_func = nullptr;
ImGuiMemFreeFunc free_func = nullptr;
void* user_data = nullptr;
ImGui::GetAllocatorFunctions(&alloc_func, &free_func, &user_data);
// function pointers are funky
g_provideInstance("ImGuiMemAllocFunc", ImGui::GetVersion(), "host", reinterpret_cast<void*>(alloc_func));
g_provideInstance("ImGuiMemFreeFunc", ImGui::GetVersion(), "host", reinterpret_cast<void*>(free_func));
if (user_data != nullptr) { // dont register nullptrs (can be valid, we rely on the other 2 pointers to indicate)
g_provideInstance("ImGuiMemUserData", ImGui::GetVersion(), "host", user_data);
}
}
g_provideInstance<TextureUploaderI>("TextureUploaderI", "host", &sdlrtu);
}
for (const auto& ppath : plugins) {
if (!pm.add(ppath)) {
std::cerr << "MS error: loading plugin '" << ppath << "' failed!\n";
// thow?
assert(false && "failed to load plugin");
//assert(false && "failed to load plugin");
SDL_MessageBoxData mb;
mb.flags = SDL_MESSAGEBOX_ERROR;
mb.window = nullptr;
mb.title = "Tomato failed to load a plugin!";
std::string message {"Failed to load plugin '"};
message += ppath;
message += "' !";
mb.message = message.c_str();
mb.numbuttons = 2;
SDL_MessageBoxButtonData mb_buttons[2] {};
mb_buttons[0].buttonID = 1;
mb_buttons[0].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
mb_buttons[0].text = "Abort";
mb_buttons[1].buttonID = 2;
mb_buttons[1].flags = SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT;
mb_buttons[1].text = "Continue Anyway";
mb.buttons = mb_buttons;
mb.colorScheme = nullptr;
int button_id = 0;
SDL_ShowMessageBox(&mb, &button_id);
if (button_id == 1) {
exit(1);
}
}
}