diff --git a/src/GUI/MainWindow.cpp b/src/GUI/MainWindow.cpp new file mode 100644 index 0000000..ea6125f --- /dev/null +++ b/src/GUI/MainWindow.cpp @@ -0,0 +1,315 @@ +#include "MainWindow.hpp" +#include "backends/imgui_impl_sdl2.h" +#include "backends/imgui_impl_opengl3.h" + +namespace ougge::GUI { + +f32 MainWindow::getDPI(){ + int w=0, h=0; + SDL_GL_GetDrawableSize(sdl_window, &w, &h); + int sim_w=0, sim_h=0; + SDL_GetWindowSize(sdl_window, &sim_w, &sim_h); + f32 wdpi=(f32)w / sim_w; + f32 hdpi=(f32)h / sim_h; + f32 dpi=SDL_sqrtf(wdpi*wdpi + hdpi*hdpi); + return dpi; +} + +void MainWindow::init(const char* window_title){ + SDL_TRY(SDL_Init(SDL_INIT_VIDEO)); + SDL_version v; + SDL_GetVersion(&v); + std::cout<= prev_update_time_ms + 1000/fps_min){ + // if frame rate < fps_min then requests frame draw + // works only if main_loop_wait_for_input = false + frame_updates_requested=1; + prev_update_time_ms=update_time_ms; + } + else { + // skips frame rendering and waits to limit fps + u32 frame_delay_ms=1000/fps_max; + SDL_Delay(frame_delay_ms); + continue; + } + } + + // deaws requested number of frames + while(frame_updates_requested>0) { + draw_frame(); + frame_updates_requested--; + } + } + + // Cleanup + MainWindow::destroy(); +} + +void MainWindow::close(){ + loop_running=false; +} + +void MainWindow::destroy(){ + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplSDL2_Shutdown(); + ImGui::DestroyContext(); + SDL_GL_DeleteContext(gl_context); + SDL_DestroyWindow(sdl_window); + SDL_Quit(); +} + +void MainWindow::draw_bg_window(){ + const ImGuiDockNodeFlags dockspace_flags = + ImGuiDockNodeFlags_PassthruCentralNode; + const ImGuiWindowFlags window_flags = + ImGuiWindowFlags_MenuBar | + ImGuiWindowFlags_NoDocking | + ImGuiWindowFlags_NoScrollbar | + ImGuiWindowFlags_NoScrollWithMouse | + ImGuiWindowFlags_NoBringToFrontOnFocus | + ImGuiWindowFlags_NoFocusOnAppearing | + ImGuiWindowFlags_NoMove | + ImGuiWindowFlags_NoResize | + ImGuiWindowFlags_NoCollapse | + ImGuiWindowFlags_NoTitleBar | + ImGuiWindowFlags_NoBackground; + // not dockable window that always bound to viewport + ImGuiViewport* viewport = ImGui::GetWindowViewport(); + ImGui::SetNextWindowPos(viewport->Pos, ImGuiCond_Always); + ImGui::SetNextWindowSize(viewport->Size, ImGuiCond_Always); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); + ImGui::Begin("bg_window", nullptr, window_flags); + ImGui::PopStyleVar(3); + + // DockSpace + ImGuiID dockspace_id = ImGui::GetID("bg_dockspace"); + ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags); + + // MenuBar + if(ImGui::BeginMainMenuBar()){ + if(ImGui::BeginMenu("test")){ + if(ImGui::MenuItem("throw exception")){ + ImGui::EndMenu(); + ImGui::EndMainMenuBar(); + ImGui::End(); + throw UsefulException("example exception"); + } + if(ImGui::MenuItem("throw const char*")){ + ImGui::EndMenu(); + ImGui::EndMainMenuBar(); + ImGui::End(); + throw "cptr"; + } + if(ImGui::MenuItem("throw std::string")){ + ImGui::EndMenu(); + ImGui::EndMainMenuBar(); + ImGui::End(); + throw std::string("str"); + } + if(ImGui::MenuItem("throw unknown")){ + ImGui::EndMenu(); + ImGui::EndMainMenuBar(); + ImGui::End(); + throw 111; + } + ImGui::EndMenu(); + } + ImGui::EndMainMenuBar(); + } + + ImGui::End(); +} + +void MainWindow::draw_debug_window(){ + ImGuiIO& io = ImGui::GetIO(); + + ImGui::Begin("Debug Options"); + ImGui::ColorEdit3("clear_color", (float*)&clear_color); + ImGui::Checkbox("main_loop_wait_for_input", &main_loop_wait_for_input); + ImGui::Text("Application average %.3f ms/frame (%.2f FPS)", 1000.0f / io.Framerate, io.Framerate); + ImGui::Checkbox("Demo Window", &show_demo_window); + ImGui::Checkbox("Metrics/Debug Window", &show_metrics_window); + ImGui::End(); + + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + if (show_metrics_window) + ImGui::ShowMetricsWindow(&show_metrics_window); +} + +} \ No newline at end of file diff --git a/src/GUI/MainWindow.hpp b/src/GUI/MainWindow.hpp new file mode 100644 index 0000000..94a1094 --- /dev/null +++ b/src/GUI/MainWindow.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include +#include +#include +#include "../std.hpp" +#include "../format.hpp" +#include "exceptions.hpp" + +/// converts hex color to float vector +#define RGBAHexToF(R8,G8,B8,A8) ImVec4(((u8)35)/255.0f, ((u8)35)/255.0f, ((u8)50)/255.0f, ((u8)255)/255.0f) +/// converts float vector to hex color +#define RGBAFToHex(VEC4) {(u8)(VEC4.x*255), (u8)(VEC4.y*255), (u8)(VEC4.z*255), (u8)(VEC4.w*255)} + +namespace ougge::GUI { + +#define default_font "DroidSans" + +class MainWindow { +public: + ImVec4 clear_color = RGBAHexToF(35,35,50,255); + f32 default_font_size = 14.0f; + u8 fps_min = 30; + u8 fps_max = 60; + +private: + bool loop_running=false; + bool main_loop_wait_for_input=true; + bool show_demo_window = false; + bool show_metrics_window = false; + SDL_Window* sdl_window = nullptr; + SDL_GLContext gl_context = nullptr; + +public: + void init(const char* window_title); + void startAndWait(); + void close(); + f32 getDPI(); + +private: + void destroy(); + void poll_events(u16& frame_updates_requested, bool wait); + void draw_frame(); + void draw_ui(); + void draw_debug_window(); + void draw_bg_window(); +}; + +} diff --git a/src/GUI/exceptions.cpp b/src/GUI/exceptions.cpp new file mode 100644 index 0000000..4fc6156 --- /dev/null +++ b/src/GUI/exceptions.cpp @@ -0,0 +1,12 @@ +#include "exceptions.hpp" +#include + +namespace ougge::GUI { + +SDLException_::SDLException_(const std::string& _file,const std::string& _func, int _line_n) + : UsefulException_(SDL_GetError(), _file, _func, _line_n) +{ + SDL_ClearError(); +} + +} diff --git a/src/GUI/exceptions.hpp b/src/GUI/exceptions.hpp new file mode 100644 index 0000000..4b3b563 --- /dev/null +++ b/src/GUI/exceptions.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "../UsefulException.hpp" + +namespace ougge::GUI { + +#define SDLException() SDLException_(__FILE__, __func__, __LINE__) + +class SDLException_ : public UsefulException_ { +public: + SDLException_(const std::string& _file, const std::string& _func, int line_n); +}; + +#define SDL_TRY(EXPR) if(EXPR) throw SDLException(); + +} diff --git a/src/format.hpp b/src/format.hpp index bf7b4b6..493df97 100644 --- a/src/format.hpp +++ b/src/format.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include "../dependencies/kerep/src/base/std.h" +#include "std.hpp" std::string _format(const std::string& format_str, const size_t args_count, ...); #define format(FORMAT_STR, ARGS...) _format(FORMAT_STR, count_args(ARGS) ,##ARGS) diff --git a/src/main.cpp b/src/main.cpp index 20eeefc..cbb22f3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,34 @@ #define SDL_MAIN_HANDLED -#include +#include "GUI/MainWindow.hpp" #include "std.hpp" #include +using namespace ougge; + int main(int argc, const char** argv){ - std::cout<<"UwU"<