diff --git a/shared/audio_player.cpp b/shared/audio_player.cpp index 3088660..1b726db 100644 --- a/shared/audio_player.cpp +++ b/shared/audio_player.cpp @@ -1,301 +1,63 @@ -/* -Demonstrates how to load a sound file and play it back using the low-level API. - -The low-level API uses a callback to deliver audio between the application and miniaudio for playback or recording. When -in playback mode, as in this example, the application sends raw audio data to miniaudio which is then played back through -the default playback device as defined by the operating system. - -This example uses the `ma_decoder` API to load a sound and play it back. The decoder is entirely decoupled from the -device and can be used independently of it. This example only plays back a single sound file, but it's possible to play -back multiple files by simple loading multiple decoders and mixing them (do not create multiple devices to do this). See -the simple_mixing example for how best to do this. -*/ - -#define STB_VORBIS_HEADER_ONLY -#include "stb_vorbis.c" - - -#define MINIAUDIO_IMPLEMENTATION -#include "miniaudio.h" #include #include #include "audio_player.h" -// #define MA_NO_LIBOPUS -// #include "miniaudio_libvorbis.h" -// #include "miniaudio_libopus.h" - +#include #include -#if 0 -static ma_result ma_decoding_backend_init__libvorbis(void* pUserData, ma_read_proc onRead, ma_seek_proc onSeek, ma_tell_proc onTell, void* pReadSeekTellUserData, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend) -{ - ma_result result; - ma_libvorbis* pVorbis; - - (void)pUserData; - - pVorbis = (ma_libvorbis*)ma_malloc(sizeof(*pVorbis), pAllocationCallbacks); - if (pVorbis == NULL) { - return MA_OUT_OF_MEMORY; - } - - result = ma_libvorbis_init(onRead, onSeek, onTell, pReadSeekTellUserData, pConfig, pAllocationCallbacks, pVorbis); - if (result != MA_SUCCESS) { - ma_free(pVorbis, pAllocationCallbacks); - return result; - } - - *ppBackend = pVorbis; - - return MA_SUCCESS; -} - -static ma_result ma_decoding_backend_init_file__libvorbis(void* pUserData, const char* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend) -{ - ma_result result; - ma_libvorbis* pVorbis; - - (void)pUserData; - - pVorbis = (ma_libvorbis*)ma_malloc(sizeof(*pVorbis), pAllocationCallbacks); - if (pVorbis == NULL) { - return MA_OUT_OF_MEMORY; - } - - result = ma_libvorbis_init_file(pFilePath, pConfig, pAllocationCallbacks, pVorbis); - if (result != MA_SUCCESS) { - ma_free(pVorbis, pAllocationCallbacks); - return result; - } - - *ppBackend = pVorbis; - - return MA_SUCCESS; -} - -static void ma_decoding_backend_uninit__libvorbis(void* pUserData, ma_data_source* pBackend, const ma_allocation_callbacks* pAllocationCallbacks) -{ - ma_libvorbis* pVorbis = (ma_libvorbis*)pBackend; - - (void)pUserData; - - ma_libvorbis_uninit(pVorbis, pAllocationCallbacks); - ma_free(pVorbis, pAllocationCallbacks); -} - -static ma_result ma_decoding_backend_get_channel_map__libvorbis(void* pUserData, ma_data_source* pBackend, ma_channel* pChannelMap, size_t channelMapCap) -{ - ma_libvorbis* pVorbis = (ma_libvorbis*)pBackend; - - (void)pUserData; - - return ma_libvorbis_get_data_format(pVorbis, NULL, NULL, NULL, pChannelMap, channelMapCap); -} - -static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_libvorbis = -{ - ma_decoding_backend_init__libvorbis, - ma_decoding_backend_init_file__libvorbis, - NULL, /* onInitFileW() */ - NULL, /* onInitMemory() */ - ma_decoding_backend_uninit__libvorbis -}; - - - -static ma_result ma_decoding_backend_init__libopus(void* pUserData, ma_read_proc onRead, ma_seek_proc onSeek, ma_tell_proc onTell, void* pReadSeekTellUserData, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend) -{ - ma_result result; - ma_libopus* pOpus; - - (void)pUserData; - - pOpus = (ma_libopus*)ma_malloc(sizeof(*pOpus), pAllocationCallbacks); - if (pOpus == NULL) { - return MA_OUT_OF_MEMORY; - } - - result = ma_libopus_init(onRead, onSeek, onTell, pReadSeekTellUserData, pConfig, pAllocationCallbacks, pOpus); - if (result != MA_SUCCESS) { - ma_free(pOpus, pAllocationCallbacks); - return result; - } - - *ppBackend = pOpus; - - return MA_SUCCESS; -} - -static ma_result ma_decoding_backend_init_file__libopus(void* pUserData, const char* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend) -{ - ma_result result; - ma_libopus* pOpus; - - (void)pUserData; - - pOpus = (ma_libopus*)ma_malloc(sizeof(*pOpus), pAllocationCallbacks); - if (pOpus == NULL) { - return MA_OUT_OF_MEMORY; - } - - result = ma_libopus_init_file(pFilePath, pConfig, pAllocationCallbacks, pOpus); - if (result != MA_SUCCESS) { - ma_free(pOpus, pAllocationCallbacks); - return result; - } - - *ppBackend = pOpus; - - return MA_SUCCESS; -} - -static void ma_decoding_backend_uninit__libopus(void* pUserData, ma_data_source* pBackend, const ma_allocation_callbacks* pAllocationCallbacks) -{ - ma_libopus* pOpus = (ma_libopus*)pBackend; - - (void)pUserData; - - ma_libopus_uninit(pOpus, pAllocationCallbacks); - ma_free(pOpus, pAllocationCallbacks); -} - -static ma_result ma_decoding_backend_get_channel_map__libopus(void* pUserData, ma_data_source* pBackend, ma_channel* pChannelMap, size_t channelMapCap) -{ - ma_libopus* pOpus = (ma_libopus*)pBackend; - - (void)pUserData; - - return ma_libopus_get_data_format(pOpus, NULL, NULL, NULL, pChannelMap, channelMapCap); -} - -static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_libopus = -{ - ma_decoding_backend_init__libopus, - ma_decoding_backend_init_file__libopus, - NULL, /* onInitFileW() */ - NULL, /* onInitMemory() */ - ma_decoding_backend_uninit__libopus -}; - - -#endif - -// void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount) -// { -// ma_data_source* pDataSource = (ma_data_source*)pDevice->pUserData; -// if (pDataSource == NULL) { -// return; -// } - -// ma_data_source_read_pcm_frames(pDataSource, pOutput, frameCount, NULL); - -// (void)pInput; -// } +static int audio_open = 0; +static Mix_Music *music = NULL; +static int next_track = 0; +SDL_AudioSpec spec; + static ThreadSafeQueue g_audioQueue; -static ma_decoder decoder; -static ma_device device; -void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount) + +void music_finished() { - ma_decoder* pDecoder = (ma_decoder*)pDevice->pUserData; - if (pDecoder == NULL) { - return; - } - - ma_uint64 framesRead; - ma_result result = ma_decoder_read_pcm_frames(pDecoder, pOutput, frameCount, &framesRead); - - - if (result == MA_AT_END) { - g_audioQueue.push({"end", ""}); - } - // if (framesRead < frameCount) { - // // Reached the end. - // ma_event_signal(&g_stopEvent); - // } - - (void)pInput; + Mix_FreeMusic(music); + music = NULL; + g_audioQueue.push({"end", ""}); } -static int miniaudio_play(const char* filename) -{ - ma_result result; - ma_device_config deviceConfig; - short *output = NULL; - - result = ma_decoder_init_file(filename, NULL, &decoder); - if (result != MA_SUCCESS) - { - printf("Could not load file: %s\n", filename); - - // Try OGG (FIXME: plus tard, utiliser l'extension pour choisir le décodeur) - int channels = 0, sample_rate = 0; - - int sample_count = stb_vorbis_decode_filename("chemin/vers/fichier.ogg", &channels, &sample_rate, &output); - if (sample_count == -1) - { - printf("Erreur de décodage du fichier Vorbis\n"); - return -2; - } - - ma_device_config deviceConfig = ma_device_config_init(ma_device_type_playback); - deviceConfig.playback.format = ma_format_s16; - deviceConfig.playback.channels = channels; - deviceConfig.sampleRate = sample_rate; - deviceConfig.dataCallback = data_callback; - deviceConfig.pUserData = &decoder; - } - else - { - deviceConfig = ma_device_config_init(ma_device_type_playback); - deviceConfig.playback.format = decoder.outputFormat; - deviceConfig.playback.channels = decoder.outputChannels; - deviceConfig.sampleRate = decoder.outputSampleRate; - deviceConfig.dataCallback = data_callback; - deviceConfig.pUserData = &decoder; - } - - if (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) { - printf("Failed to open playback device.\n"); - ma_decoder_uninit(&decoder); - if (output != NULL) - { - free(output); - } - return -3; - } - - if (ma_device_start(&device) != MA_SUCCESS) { - printf("Failed to start playback device.\n"); - ma_device_uninit(&device); - ma_decoder_uninit(&decoder); - if (output != NULL) - { - free(output); - } - return -4; - } - - if (output != NULL) - { - free(output); - } - - return 0; -} - AudioPlayer::AudioPlayer(IAudioEvent &event) : m_event(event) { m_audioThread = std::thread( std::bind(&AudioPlayer::AudioThread, this) ); } +void AudioPlayer::Initialize() +{ + /* Initialize variables */ + spec.freq = MIX_DEFAULT_FREQUENCY; + spec.format = MIX_DEFAULT_FORMAT; + spec.channels = MIX_DEFAULT_CHANNELS; + + if (Mix_Init(MIX_INIT_FLAC | MIX_INIT_MP3 | MIX_INIT_OGG) < 0) { + return ; + } + + if (Mix_OpenAudio(0, &spec) < 0) { + SDL_Log("Couldn't open audio: %s\n", SDL_GetError()); + return; + } else { + Mix_QuerySpec(&spec.freq, &spec.format, &spec.channels); + SDL_Log("Opened audio at %d Hz %d bit%s %s audio buffer\n", spec.freq, + (spec.format&0xFF), + (SDL_AUDIO_ISFLOAT(spec.format) ? " (float)" : ""), + (spec.channels > 2) ? "surround" : (spec.channels > 1) ? "stereo" : "mono"); + } + audio_open = 1; + + Mix_HookMusicFinished(music_finished); + +} + void AudioPlayer::Play(const std::string &filename) { g_audioQueue.push({"play", filename}); @@ -304,6 +66,7 @@ void AudioPlayer::Play(const std::string &filename) AudioPlayer::~AudioPlayer() { // Quit audio thread + g_audioQueue.clear(); g_audioQueue.push({"quit", ""}); if (m_audioThread.joinable()) { @@ -311,11 +74,12 @@ AudioPlayer::~AudioPlayer() } } -void AudioPlayer::CloseAudio() -{ - ma_device_uninit(&device); - ma_decoder_uninit(&decoder); -} + void AudioPlayer::Stop() + { + g_audioQueue.clear(); + g_audioQueue.push({"end", ""}); + } + #define AUDIO_STATE_WAIT_PLAY 1 #define AUDIO_STATE_WAIT_END 2 @@ -328,7 +92,8 @@ void AudioPlayer::AudioThread() auto cmd = g_audioQueue.front(); g_audioQueue.pop(); - if (cmd.order == "quit") { + if (cmd.order == "quit") + { return; } else if (cmd.order == "play") @@ -336,7 +101,12 @@ void AudioPlayer::AudioThread() if (state == AUDIO_STATE_WAIT_PLAY) { state = AUDIO_STATE_WAIT_END; - miniaudio_play(cmd.filename.c_str()); + music = Mix_LoadMUS(cmd.filename.c_str()); + + if (music) + { + Mix_PlayMusic(music, 0); + } } } else if (cmd.order == "end") @@ -344,7 +114,8 @@ void AudioPlayer::AudioThread() if (state == AUDIO_STATE_WAIT_END) { state = AUDIO_STATE_WAIT_PLAY; - CloseAudio(); + Mix_HaltMusic(); + Mix_FreeMusic(music); m_event.EndOfAudio(); } } diff --git a/shared/audio_player.h b/shared/audio_player.h index ceba559..e60874c 100644 --- a/shared/audio_player.h +++ b/shared/audio_player.h @@ -1,7 +1,6 @@ #ifndef AUDIO_PLAYER_H #define AUDIO_PLAYER_H -#include "miniaudio.h" #include #include #include @@ -34,6 +33,8 @@ public: ~AudioPlayer(); void Play(const std::string &filename); + void Stop(); + void Initialize(); private: IAudioEvent &m_event; @@ -41,7 +42,7 @@ private: std::thread m_audioThread; void AudioThread(); - void CloseAudio(); + }; diff --git a/shared/thread_safe_queue.h b/shared/thread_safe_queue.h index 28cd42d..5911bb2 100644 --- a/shared/thread_safe_queue.h +++ b/shared/thread_safe_queue.h @@ -33,6 +33,13 @@ public: queue.pop(); } + void clear() { + std::lock_guard lock(mutex); + while(!queue.empty()) { + queue.pop(); + } + } + bool try_pop(T& popped_item) { std::unique_lock lock(mutex); diff --git a/story-editor/CMakeLists.txt b/story-editor/CMakeLists.txt index a8d1175..8f10968 100644 --- a/story-editor/CMakeLists.txt +++ b/story-editor/CMakeLists.txt @@ -126,6 +126,25 @@ FetchContent_MakeAvailable(sdl3) include_directories(${sdl3_SOURCE_DIR}/include) # add_subdirectory(${sdl3_SOURCE_DIR}) +# ========================================================================================================================= +# SDL3 MIXER +# ========================================================================================================================= +FetchContent_Declare( + sdl3_mixer + GIT_REPOSITORY https://github.com/libsdl-org/SDL_mixer.git + GIT_TAG ace2d37796d2541123cdcbc06dce0b716a0416ad + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + GIT_SUBMODULES "" +) + +set(BUILD_SHARED_LIBS TRUE) +set(SDL_PULSEAUDIO_SHARED TRUE) +set(SDL_PIPEWIRE_SHARED TRUE) +FetchContent_MakeAvailable(sdl3_mixer) +include_directories(${sdl3_mixer_SOURCE_DIR}/include) + + # ========================================================================================================================= # SDL3-Image # ========================================================================================================================= @@ -326,6 +345,7 @@ if(UNIX) dl SDL3::SDL3 SDL3_image::SDL3_image + SDL3_mixer::SDL3_mixer libcurl_static # OpenSSL::SSL OpenSSL::Crypto ) diff --git a/story-editor/src/gui.cpp b/story-editor/src/gui.cpp index bd88513..c8e3131 100644 --- a/story-editor/src/gui.cpp +++ b/story-editor/src/gui.cpp @@ -105,6 +105,18 @@ Gui::Gui() std::cout << "PATH: " << m_executablePath << std::endl; } +static ImFont* normalFont; +// static ImFont* bigFont; + +void Gui::PushBigFont() +{ + // ImGui::PushFont(bigFont); +} + +void Gui::PopBigFont() +{ + // ImGui::PopFont(); +} bool Gui::Initialize() { @@ -112,11 +124,29 @@ bool Gui::Initialize() // if (SDL_Init(SDL_INIT_EVERYTHING) != 0) // Setup SDL3 - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMEPAD) != 0) + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) { printf("Error: SDL_Init(): %s\n", SDL_GetError()); - return -1; + return false; } +/* + if (SDL_InitSubSystem(SDL_INIT_AUDIO) != 0) + { + int i, num_devices; + SDL_AudioDeviceID *devices = SDL_GetAudioOutputDevices(&num_devices); + if (devices) { + for (i = 0; i < num_devices; ++i) { + SDL_AudioDeviceID instance_id = devices[i]; + char *name = SDL_GetAudioDeviceName(instance_id); + SDL_Log("AudioDevice %" SDL_PRIu32 ": %s\n", instance_id, name); + SDL_free(name); + } + SDL_free(devices); + } + + printf("Error: SDL_InitSubSystem(): %s\n", SDL_GetError()); + return false; + }*/ // Enable native IME. SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1"); @@ -133,13 +163,13 @@ bool Gui::Initialize() if (window == nullptr) { printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError()); - return -1; + return false; } renderer = SDL_CreateRenderer(window, nullptr, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED); if (renderer == nullptr) { SDL_Log("Error: SDL_CreateRenderer(): %s\n", SDL_GetError()); - return -1; + return false; } SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); SDL_ShowWindow(window); @@ -155,7 +185,9 @@ bool Gui::Initialize() io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; - io.Fonts->AddFontFromFileTTF( std::string(m_executablePath + "/fonts/roboto.ttf").c_str(), 20); + // bigFont = io.Fonts->AddFontFromFileTTF( std::string(m_executablePath + "/fonts/roboto.ttf").c_str(), 40); + // io.Fonts->Build(); + normalFont = io.Fonts->AddFontFromFileTTF( std::string(m_executablePath + "/fonts/roboto.ttf").c_str(), 20); { ImFontConfig config; diff --git a/story-editor/src/gui.h b/story-editor/src/gui.h index 0f87c06..09c1313 100644 --- a/story-editor/src/gui.h +++ b/story-editor/src/gui.h @@ -47,8 +47,12 @@ public: static bool LoadRawImage(const std::string &filename, Image &image); static Size GetWindowSize(); + static void PushBigFont(); + static void PopBigFont(); + private: std::string m_executablePath; + }; // namespace ImGui { diff --git a/story-editor/src/main.cpp b/story-editor/src/main.cpp index 1012bae..06037e3 100644 --- a/story-editor/src/main.cpp +++ b/story-editor/src/main.cpp @@ -6,9 +6,10 @@ int main(int, char**) { MainWindow w; - w.Initialize(); - - w.Loop(); + if (w.Initialize()) + { + w.Loop(); + } return 0; } diff --git a/story-editor/src/main_window.cpp b/story-editor/src/main_window.cpp index b8346c9..ab47bdc 100644 --- a/story-editor/src/main_window.cpp +++ b/story-editor/src/main_window.cpp @@ -256,13 +256,15 @@ void MainWindow::DrawStatusBar() ImGui::End(); } -void MainWindow::DrawMainMenuBar() +float MainWindow::DrawMainMenuBar() { bool showAboutPopup = false; bool showParameters = false; bool showNewProject = false; bool showOpenProject = false; + float height = 60; + if (ImGui::BeginMainMenuBar()) { if (ImGui::BeginMenu("File")) @@ -333,6 +335,8 @@ void MainWindow::DrawMainMenuBar() ImGui::EndMenu(); } + + height = ImGui::GetFrameHeight(); ImGui::EndMainMenuBar(); } @@ -380,21 +384,31 @@ void MainWindow::DrawMainMenuBar() } ImGui::EndPopup(); } + + return height; } -void MainWindow::Initialize() +bool MainWindow::Initialize() { + bool success = false; LoadParams(); // GUI Init - m_gui.Initialize(); - // gui.ApplyTheme(); + if (m_gui.Initialize()) + { + m_player.Initialize(); // Initialize audio after GUI (uses SDL) + // gui.ApplyTheme(); - m_editorWindow.Initialize(); - m_emulatorWindow.Initialize(); - m_nodeEditorWindow.Initialize(); - m_PropertiesWindow.Initialize(); - m_libraryWindow.Initialize(); + m_editorWindow.Initialize(); + m_emulatorWindow.Initialize(); + m_nodeEditorWindow.Initialize(); + m_PropertiesWindow.Initialize(); + m_libraryWindow.Initialize(); + + success = true; + } + + return success; } @@ -591,20 +605,20 @@ void MainWindow::ProjectPropertiesPopup() } - auto GetImageFormat = [](int idx) -> StoryProject::ImageFormat + auto GetImageFormat = [](int idx) -> Resource::ImageFormat { - StoryProject::ImageFormat img{StoryProject::IMG_SAME_FORMAT}; - if (idx < StoryProject::IMG_FORMAT_COUNT) { - img = static_cast(idx); + Resource::ImageFormat img{Resource::IMG_SAME_FORMAT}; + if (idx < Resource::IMG_FORMAT_COUNT) { + img = static_cast(idx); } return img; }; - auto GetSoundFormat = [](int idx) -> StoryProject::SoundFormat { + auto GetSoundFormat = [](int idx) -> Resource::SoundFormat { - StoryProject::SoundFormat img{StoryProject::SND_FORMAT_WAV}; - if (idx < StoryProject::IMG_FORMAT_COUNT) { - img = static_cast(idx); + Resource::SoundFormat img{Resource::SND_FORMAT_WAV}; + if (idx < Resource::IMG_FORMAT_COUNT) { + img = static_cast(idx); } return img; @@ -652,6 +666,11 @@ void MainWindow::OpenProject(const std::string &uuid) CloseProject(); m_story = m_libraryManager.GetStory(uuid); + // DEBUG CODE !!!!!!!!!!!!! Permet si décommenter de forcer l'import, permet de tester plus facilement l'algo en ouvrant le projet + // PackArchive arch(*this); + // std::string basePath = m_libraryManager.LibraryPath() + "/" + uuid; + // arch.ConvertJsonStudioToOst(basePath, uuid, m_libraryManager.LibraryPath()); + if (!m_story) { Log("Cannot find story: " + uuid); @@ -712,11 +731,11 @@ void MainWindow::RefreshProjectInformation() void MainWindow::CloseProject() { - if (m_story) - { - m_story->Clear(); - m_story.reset(); - } + // if (m_story) + // { + // m_story->Clear(); + // m_story.reset(); + // } m_resources.Clear(); @@ -736,7 +755,43 @@ void MainWindow::CloseProject() } +void MainWindow::DrawToolBar(float topPadding) +{ + ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDecoration | + ImGuiWindowFlags_NoMove | + ImGuiWindowFlags_NoScrollbar | + ImGuiWindowFlags_NoScrollWithMouse | + ImGuiWindowFlags_NoDocking; + // Définit la taille et la position de la barre d'outils + ImVec2 size = ImVec2(60, ImGui::GetIO().DisplaySize.y - topPadding); // Largeur de 60 pixels et hauteur égale à celle de l'écran + ImGui::SetNextWindowSize(size); + ImGui::SetNextWindowPos(ImVec2(0, topPadding)); // Positionné à gauche et en haut + + // Création de la fenêtre pour la barre d'outils + ImGui::Begin("ToolBar", nullptr, window_flags); + + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.0f, 0.0f, 1.0f)); // rouge + float old_size = ImGui::GetFont()->Scale; + ImGui::GetFont()->Scale *= 2.5; + + ImGui::PushFont(ImGui::GetFont()); + + // Ajouter des boutons à la barre d'outils + if (ImGui::Button(ICON_MDI_SPEAKER_STOP "##stop_sound", ImVec2(-1, 50))) { // Le bouton prend toute la largeur de la fenêtre et a une hauteur de 50 pixels + m_player.Stop(); + } + + ImGui::GetFont()->Scale = old_size; + ImGui::PopFont(); + ImGui::PopStyleColor(); + + + // Fermeture de la fenêtre ImGui + ImGui::End(); +} + +#include "imgui_internal.h" void MainWindow::Loop() { // Main loop @@ -749,14 +804,21 @@ void MainWindow::Loop() m_gui.StartFrame(); - ImGui::DockSpaceOverViewport(ImGui::GetMainViewport()); - DrawMainMenuBar(); + auto vp = ImGui::GetMainViewport(); + + auto pos = vp->WorkPos; + auto size = vp->WorkSize; + pos.x += 60; + size.x -= 60; + vp->WorkPos = pos; + vp->WorkSize = size; + ImGui::DockSpaceOverViewport(vp); + float height = DrawMainMenuBar(); + // DrawStatusBar(); - ProcessStory(); - // ------------ Draw all windows m_libraryWindow.Draw(); @@ -771,6 +833,12 @@ void MainWindow::Loop() m_PropertiesWindow.SetSelectedNode(m_nodeEditorWindow.GetSelectedNode()); m_PropertiesWindow.Draw(); + + + // static ImGuiAxis toolbar2_axis = ImGuiAxis_Y; + // DockingToolbar("Toolbar2", &toolbar2_axis); + + DrawToolBar(height); } ProjectPropertiesPopup(); @@ -863,7 +931,7 @@ void MainWindow::Build(bool compileonly) if (!compileonly) { // 3. Convert all media to desired type format - m_resources.ConvertResources(m_story->AssetsPath(), ""); // pas de répertoire de destination + m_resources.ConvertResources(m_story->AssetsPath(), "", m_story->GetImageFormat(), m_story->GetSoundFormat()); // pas de répertoire de destination } Chip32::Assembler::Error err; diff --git a/story-editor/src/main_window.h b/story-editor/src/main_window.h index 4868965..afecdcc 100644 --- a/story-editor/src/main_window.h +++ b/story-editor/src/main_window.h @@ -69,7 +69,7 @@ public: MainWindow(); ~MainWindow(); - void Initialize(); + bool Initialize(); void Loop(); private: @@ -155,8 +155,9 @@ private: void SaveParams(); void LoadParams(); - void DrawMainMenuBar(); + float DrawMainMenuBar(); bool ShowQuitConfirm(); + void DrawToolBar(float topPadding); void SaveProject(); void CloseProject(); diff --git a/story-editor/src/node_editor/node_editor_window.cpp b/story-editor/src/node_editor/node_editor_window.cpp index b82f462..dabfefe 100644 --- a/story-editor/src/node_editor/node_editor_window.cpp +++ b/story-editor/src/node_editor/node_editor_window.cpp @@ -37,7 +37,9 @@ NodeEditorWindow::~NodeEditorWindow() void NodeEditorWindow::Initialize() { ed::Config config; - config.SettingsFile = "Widgets.json"; + config.SettingsFile = nullptr; + config.SaveSettings = nullptr; + config.LoadSettings = nullptr; m_context = ed::CreateEditor(&config); ed::SetCurrentEditor(m_context);