// TextEditor - A syntax highlighting text editor for ImGui // Copyright (c) 2024-2026 Johan A. Goossens. All rights reserved. // // This work is licensed under the terms of the MIT license. // For a copy, see . // // Include files // #include #include #include #include #include "imgui.h" #include "imgui_impl_sdl3.h" #include "imgui_impl_sdlgpu3.h" #include "editor.h" #include "dejavu.h" // // main // int main(int, char**) { // setup SDL if (!SDL_Init(SDL_INIT_VIDEO)) { printf("Error: SDL_Init(): %s\n", SDL_GetError()); return -1; } // create SDL window graphics context SDL_Window* window = SDL_CreateWindow("TextEditor Example", 1280, 720, SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY); if (window == nullptr) { printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError()); return -1; } // create GPU device SDL_GPUDevice* gpu_device = SDL_CreateGPUDevice(SDL_GPU_SHADERFORMAT_SPIRV | SDL_GPU_SHADERFORMAT_DXIL | SDL_GPU_SHADERFORMAT_METALLIB, true, nullptr); if (gpu_device == nullptr) { printf("Error: SDL_CreateGPUDevice(): %s\n", SDL_GetError()); return -1; } // claim window for GPU device if (!SDL_ClaimWindowForGPUDevice(gpu_device, window)) { printf("Error: SDL_ClaimWindowForGPUDevice(): %s\n", SDL_GetError()); return -1; } // setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); auto& io = ImGui::GetIO(); io.IniFilename = nullptr; ImGui::StyleColorsDark(); // setup platform/renderer backends ImGui_ImplSDL3_InitForSDLGPU(window); ImGui_ImplSDLGPU3_InitInfo init_info = {}; init_info.Device = gpu_device; init_info.ColorTargetFormat = SDL_GetGPUSwapchainTextureFormat(gpu_device, window); init_info.MSAASamples = SDL_GPU_SAMPLECOUNT_1; ImGui_ImplSDLGPU3_Init(&init_info); // setup our font ImFontConfig config; std::memcpy(config.Name, "DejaVu", 7); config.FontDataOwnedByAtlas = false; config.OversampleH = 1; config.OversampleV = 1; io.Fonts->Clear(); io.Fonts->AddFontFromMemoryCompressedTTF((void*) &dejavu, dejavuSize, 15.0f, &config); // main loop Editor editor; SDL_Event event; while (!editor.isDone()) { // poll and handle events (inputs, window resize, etc.) while (SDL_PollEvent(&event)) { ImGui_ImplSDL3_ProcessEvent(&event); if (event.type == SDL_EVENT_QUIT) { editor.tryToQuit(); } else if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window)) { editor.tryToQuit(); } } if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED) { SDL_Delay(10); continue; } // start the Dear ImGui frame ImGui_ImplSDLGPU3_NewFrame(); ImGui_ImplSDL3_NewFrame(); ImGui::NewFrame(); // render editor editor.render(); // render to the screen ImGui::Render(); ImDrawData* draw_data = ImGui::GetDrawData(); const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f); // acquire a GPU command buffer and swapchain texture SDL_GPUCommandBuffer* command_buffer = SDL_AcquireGPUCommandBuffer(gpu_device); SDL_GPUTexture* swapchain_texture; SDL_AcquireGPUSwapchainTexture(command_buffer, window, &swapchain_texture, nullptr, nullptr); if (swapchain_texture != nullptr && !is_minimized) { // setup and start a render pass ImGui_ImplSDLGPU3_PrepareDrawData(draw_data, command_buffer); SDL_GPUColorTargetInfo target_info = {}; target_info.texture = swapchain_texture; target_info.load_op = SDL_GPU_LOADOP_CLEAR; target_info.store_op = SDL_GPU_STOREOP_STORE; target_info.mip_level = 0; target_info.layer_or_depth_plane = 0; target_info.cycle = false; SDL_GPURenderPass* render_pass = SDL_BeginGPURenderPass(command_buffer, &target_info, 1, nullptr); // render ImGui ImGui_ImplSDLGPU3_RenderDrawData(draw_data, command_buffer, render_pass); SDL_EndGPURenderPass(render_pass); } // submit the command buffer SDL_SubmitGPUCommandBuffer(command_buffer); } // cleanup SDL_WaitForGPUIdle(gpu_device); ImGui_ImplSDL3_Shutdown(); ImGui_ImplSDLGPU3_Shutdown(); ImGui::DestroyContext(); SDL_ReleaseWindowFromGPUDevice(gpu_device, window); SDL_DestroyGPUDevice(gpu_device); SDL_DestroyWindow(window); SDL_Quit(); return 0; }