Updated SDL and fixed Emscripten build

This commit is contained in:
Yousef Khadadeh 2026-04-12 17:31:32 +03:00
parent 919e41db22
commit bd4d662dd9
36 changed files with 1156 additions and 125 deletions

View file

@ -193,6 +193,7 @@ void ClientData::draw_cursor(SkCanvas* canvas, const DrawData& drawData) const {
canvas->translate(cursorPos.x(), cursorPos.y());
SkPaint p(SkColor4f{cursorColor.x(), cursorColor.y(), cursorColor.z(), 0.2f});
p.setAntiAlias(drawData.skiaAA);
canvas->drawCircle(0.0f, 0.0f, 4.5f, p);
p.setStroke(true);
p.setStrokeWidth(1.0f);
@ -207,9 +208,11 @@ void ClientData::draw_cursor(SkCanvas* canvas, const DrawData& drawData) const {
Vector2f bounds{nextText, - metrics.fAscent + metrics.fDescent};
SkPaint p2(SkColor4f{cursorColor.x(), cursorColor.y(), cursorColor.z(), 0.5f});
p2.setAntiAlias(drawData.skiaAA);
canvas->drawSimpleText(displayName.c_str(), displayName.length(), SkTextEncoding::kUTF8, 6.0f, -metrics.fDescent, f, p2);
SkPaint p3(color_mul_alpha(drawData.main->g.gui.io.theme->backColor1, 0.5f));
p3.setAntiAlias(drawData.skiaAA);
canvas->drawRoundRect(SkRect::MakeXYWH(6.0f, -bounds.y(), bounds.x(), bounds.y()), 3.0f, 3.0f, p3);
canvas->restore();

View file

@ -14,7 +14,7 @@ struct ColorPickerItemsOptions {
template <typename T> void color_picker_items(GUIManager& gui, const char* id, T* val, const ColorPickerItemsOptions& options = {}) {
gui.new_id(id, [&] {
auto fullOnEdit = [&gui, oE = options.onEdit, val]() {
auto fullOnEdit = [&gui, oE = options.onEdit]() {
if(oE) oE();
gui.set_to_layout();
};

View file

@ -93,7 +93,7 @@ template <typename T> void input_scalar(GUIManager& gui, const char* id, T* val,
return minVal;
return std::clamp(toRet, minVal, maxVal);
};
d.toStr = [decimalPrecision = options.decimalPrecision, minVal, maxVal](const T& a) {
d.toStr = [decimalPrecision = options.decimalPrecision](const T& a) {
std::stringstream ss;
if(std::is_floating_point<T>()) {
ss.precision(decimalPrecision);

View file

@ -69,7 +69,7 @@ template <typename T> class ColorPicker : public Element {
ColorPicker(GUIManager& gui);
void layout(const Clay_ElementId& id, T* data, bool selectAlpha, const ColorPickerData& config);
virtual void update() override;
virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA);
virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) override;
void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override;
void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
private:

View file

@ -33,7 +33,7 @@ template <typename T> class NumberSlider : public Element {
}
}
virtual void update() {
virtual void update() override {
smooth_two_way_animation_time(dd.holdAnimation, gui.io.deltaTime, dd.isHeld, HOLD_ANIMATION_TIME);
smooth_two_way_animation_time(dd.hoverAnimation, gui.io.deltaTime, mouseHovering, gui.io.theme->hoverExpandTime);
if(oldDD != dd) {

View file

@ -81,9 +81,7 @@ InputManager::InputManager(MainProgram& initMain):
});
emscripten_browser_clipboard::paste_event([](std::string&& pasteData, void* callbackData){
InputManager* inMan = (InputManager*)callbackData;
inMan->text.isNextPasteRich = true;
std::string pData = pasteData;
inMan->process_text_paste(pData);
inMan->process_text_paste(pasteData, true);
}, this);
#endif
@ -927,25 +925,35 @@ void InputManager::backend_key_down_update(const SDL_KeyboardEvent& e) {
void InputManager::call_paste(CustomEvents::PasteEvent::DataType type, const InputManagerCallPasteInfo& info) {
// Workaround for not being able to copy richtext to system clipboard, this should at least work within the application itself
#ifdef __EMSCRIPTEN__
if(type == PasteDataType::TEXT) {
emscripten_browser_clipboard::paste_async([](std::string&& pasteData, void* callbackData){
InputManager* inMan = (InputManager*)callbackData;
std::string pData = pasteData;
inMan->process_text_paste(pData);
}, this);
}
else {
struct PasteData {
std::optional<Vector2f> pos;
InputManager* t;
};
static PasteData pasteData;
pasteData.pos = info.pastePosition;
pasteData.t = this;
emscripten_browser_clipboard::paste_async_image([](std::string_view pasteData, void* callbackData){
PasteData* p = (PasteData*)callbackData;
p->t->process_image_paste(pasteData, p->pos);
}, &pasteData);
switch(type) {
case CustomEvents::PasteEvent::DataType::TEXT: {
struct PasteData {
bool allowRichText;
InputManager* t;
};
static PasteData pasteData;
pasteData.allowRichText = info.allowRichText;
pasteData.t = this;
emscripten_browser_clipboard::paste_async([](std::string&& pasteData, void* callbackData){
PasteData* p = (PasteData*)callbackData;
p->t->process_text_paste(pasteData, p->allowRichText);
}, &pasteData);
break;
}
case CustomEvents::PasteEvent::DataType::IMAGE: {
struct PasteData {
std::optional<Vector2f> pos;
InputManager* t;
};
static PasteData pasteData;
pasteData.pos = info.pastePosition;
pasteData.t = this;
emscripten_browser_clipboard::paste_async_image([](std::string_view pasteData, void* callbackData){
PasteData* p = (PasteData*)callbackData;
p->t->process_image_paste(pasteData, p->pos);
}, &pasteData);
break;
}
}
#else
switch(type) {

View file

@ -111,17 +111,6 @@ void MainProgram::save_config() {
f.close();
}
conf.save_palettes();
#ifdef __EMSCRIPTEN__
EM_ASM(
FS.syncfs(false, (err) => {
if(err)
console.log("Error syncing IDBFS: ", err);
else
console.log("Synced to IDBFS");
});
);
#endif
}
void MainProgram::load_config() {
@ -174,7 +163,7 @@ void MainProgram::load_config() {
}
#ifdef __EMSCRIPTEN__
else
toolbar.viewWebVersionWelcome = true;
conf.viewWebVersionWelcome = true;
#endif
conf.load_palettes();
g.load_theme(conf.configPath, conf.themeCurrentlyLoaded);

View file

@ -183,8 +183,6 @@ void TextBox::process_mouse_left_button(Cursor& cur, const Vector2f& pos, int cl
if(clickCount || held) {
rebuild();
Cursor oldCursor = cur;
cur.pos = get_text_pos_closest_to_point(pos);
if(lastClicksCursorPos != cur.pos && clickCount) {
lastClicksAtCursorPos = 1;

View file

@ -0,0 +1 @@
#include "FileSelectScreen.hpp"

View file

@ -0,0 +1,7 @@
#pragma once
class FileSelectScreen {
public:
FileSelectScreen();
private:
};

View file

@ -551,7 +551,6 @@ void Toolbar::top_toolbar() {
#ifdef __EMSCRIPTEN__
emscripten_browser_file::upload("*", [](std::string const& fileName, std::string const& mimeType, std::string_view buffer, void* callbackData) {
if(!buffer.empty()) {
auto& main = *static_cast<MainProgram*>(callbackData);
CustomEvents::emit_event<CustomEvents::AddFileToCanvasEvent>({
.type = CustomEvents::AddFileToCanvasEvent::Type::BUFFER,
.name = fileName,
@ -1469,13 +1468,13 @@ void Toolbar::open_world_file(bool isClient, const std::string& netSource, const
emscripten_browser_file::upload("." + World::FILE_EXTENSION, [](std::string const& fileName, std::string const& mimeType, std::string_view buffer, void* callbackData) {
if(!buffer.empty()) {
UploadData* uD = (UploadData*)callbackData;
uD->main->new_tab({
CustomEvents::emit_event<CustomEvents::OpenInfiniPaintFileEvent>({
.isClient = uD->iC,
.filePathSource = std::filesystem::path(fileName),
.netSource = uD->nS,
.serverLocalID = uD->sLID,
.fileDataBuffer = buffer
}, true);
});
}
}, &uploadData);
#else

View file

@ -21,9 +21,6 @@
#include "WorldGrid.hpp"
#include <cereal/archives/portable_binary.hpp>
#include <chrono>
#include <fstream>
#include "FileHelpers.hpp"
#include "FontData.hpp"
#include <include/core/SkFontMetrics.h>
#include <Helpers/Networking/NetLibrary.hpp>
#include <Helpers/Logger.hpp>
@ -245,6 +242,8 @@ void World::update() {
void World::on_tab_out() {
rMan.clear_display_cache();
if(!clientStillConnecting)
drawProg.on_tab_out();
}
void World::input_add_file_to_canvas_callback(const CustomEvents::AddFileToCanvasEvent& addFile) {

View file

@ -151,11 +151,6 @@ struct MainStruct {
std::chrono::steady_clock::duration frameRefreshDuration = std::chrono::steady_clock::duration::zero();
} MainData;
#ifdef __EMSCRIPTEN__
bool emscriptenFilesystemReadReady = false;
bool emscriptenFilesystemLoadConfigDone = false;
#endif
bool load_file_to_string(std::string& toRet, std::string_view fileName) {
// https://nullptr.org/cpp-read-file-into-string/
std::ifstream file(fileName.data(), std::ios::in | std::ios::binary | std::ios::ate);
@ -334,12 +329,6 @@ void resize_window(MainStruct& mS) {
}
#ifdef __EMSCRIPTEN__
extern "C" {
EMSCRIPTEN_KEEPALIVE inline void emscripten_filesystem_loaded() {
emscriptenFilesystemReadReady = true;
}
}
const char* emscripten_before_unload(int eventType, const void *reserved, void *userData) {
MainStruct& mS = *((MainStruct*)userData);
mS.m->save_config();
@ -351,23 +340,7 @@ void init_logs(MainStruct& mS) {
char* homePathSDL = SDL_GetCurrentDirectory();
mS.homePath = std::filesystem::path(homePathSDL);
SDL_free(homePathSDL);
#ifdef __EMSCRIPTEN__
EM_ASM(
FS.mkdir('/infinipaint');
FS.mount(FS.filesystems.IDBFS, {}, '/infinipaint');
FS.syncfs(true, (err) => {
if(err)
console.log("Error syncing IDBFS: ", err);
else {
console.log("Synced to IDBFS. Read Ready");
Module["ccall"]('emscripten_filesystem_loaded', null, [], []);
}
});
);
mS.homePath = std::filesystem::path("/");
mS.configPath = std::filesystem::path("/infinipaint");
#elif CONFIG_NEXT_TO_EXECUTABLE
#ifdef CONFIG_NEXT_TO_EXECUTABLE
std::string CONFIG_FOLDER_NAME = "config";
std::filesystem::create_directory(CONFIG_FOLDER_NAME);
mS.configPath = mS.homePath / CONFIG_FOLDER_NAME;
@ -420,17 +393,19 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
int initWidth = 1000;
int initHeight = 900;
#ifdef __EMSCRIPTEN__
Vector2d sizeD;
EMSCRIPTEN_RESULT result = emscripten_get_element_css_size("#canvas", &sizeD.x(), &sizeD.y());
if(result != EMSCRIPTEN_RESULT_SUCCESS)
std::cout << "Failed to get canvas size" << std::endl;
else {
initWidth = sizeD.x();
initHeight = sizeD.y();
std::cout << "Initial window size: " << initWidth << " " << initHeight << std::endl;
#ifdef __EMSCRIPTEN__
{
Vector2d sizeD;
EMSCRIPTEN_RESULT result = emscripten_get_element_css_size("#canvas", &sizeD.x(), &sizeD.y());
if(result != EMSCRIPTEN_RESULT_SUCCESS)
std::cout << "Failed to get canvas size" << std::endl;
else {
initWidth = sizeD.x();
initHeight = sizeD.y();
std::cout << "Initial window size: " << initWidth << " " << initHeight << std::endl;
}
}
#endif
#endif
initialize_sdl(mS, initWidth, initHeight);
@ -443,25 +418,24 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
mS.m->logFile = &mS.logFile;
mS.m->conf.configPath = mS.configPath;
mS.m->homePath = mS.homePath;
#ifndef __EMSCRIPTEN__
const char* documentsPathSDL = SDL_GetUserFolder(SDL_FOLDER_DOCUMENTS);
if(!documentsPathSDL) {
documentsPathSDL = SDL_GetUserFolder(SDL_FOLDER_DESKTOP);
if(!documentsPathSDL)
mS.m->documentsPath = mS.m->conf.configPath;
#ifndef __EMSCRIPTEN__
const char* documentsPathSDL = SDL_GetUserFolder(SDL_FOLDER_DOCUMENTS);
if(!documentsPathSDL) {
documentsPathSDL = SDL_GetUserFolder(SDL_FOLDER_DESKTOP);
if(!documentsPathSDL)
mS.m->documentsPath = mS.m->conf.configPath;
else
mS.m->documentsPath = std::filesystem::path(documentsPathSDL);
}
else
mS.m->documentsPath = std::filesystem::path(documentsPathSDL);
}
else
mS.m->documentsPath = std::filesystem::path(documentsPathSDL);
#endif
#endif
mS.m->window.sdlWindow = mS.window;
mS.m->update_scale_and_density();
#ifdef __EMSCRIPTEN__
emscripten_set_beforeunload_callback((void*)mSPtr, emscripten_before_unload);
#else
mS.m->load_config();
#endif
#ifdef __EMSCRIPTEN__
emscripten_set_beforeunload_callback((void*)mSPtr, emscripten_before_unload);
#endif
#ifdef USE_BACKEND_VULKAN
#ifdef USE_SKIA_BACKEND_GRAPHITE
std::unique_ptr<const skwindow::DisplayParams> displayParams = skwindow::DisplayParamsBuilder().build();
@ -614,13 +588,6 @@ SDL_AppResult SDL_AppIterate(void *appstate) {
#ifdef NDEBUG
try {
#endif
#ifdef __EMSCRIPTEN__
if(emscriptenFilesystemReadReady && !emscriptenFilesystemLoadConfigDone) {
mS.m->load_config();
emscriptenFilesystemLoadConfigDone = true;
}
#endif
mS.m->update();
if(mS.m->setToQuit)