2021-04-20 10:37:56 -04:00
|
|
|
#include "imgui_backend.hpp"
|
2020-08-11 12:07:21 -04:00
|
|
|
|
|
|
|
#include <imgui.h>
|
|
|
|
#include <imgui_stdlib.h>
|
|
|
|
|
|
|
|
#include "engine.hpp"
|
|
|
|
#include "platform.hpp"
|
|
|
|
#include "assertions.hpp"
|
2021-10-07 17:46:28 -04:00
|
|
|
#include "input.hpp"
|
2021-10-12 11:47:13 -04:00
|
|
|
#include "app.hpp"
|
2020-08-11 12:07:21 -04:00
|
|
|
|
2021-04-20 10:37:56 -04:00
|
|
|
using prism::imgui_backend;
|
|
|
|
|
2020-08-11 12:07:21 -04:00
|
|
|
const std::map<ImGuiKey, InputButton> imToPl = {
|
|
|
|
{ImGuiKey_Tab, InputButton::Tab},
|
|
|
|
{ImGuiKey_LeftArrow, InputButton::LeftArrow},
|
|
|
|
{ImGuiKey_RightArrow, InputButton::RightArrow},
|
|
|
|
{ImGuiKey_UpArrow, InputButton::Escape},
|
|
|
|
{ImGuiKey_DownArrow, InputButton::Escape},
|
|
|
|
{ImGuiKey_PageUp, InputButton::Escape},
|
|
|
|
{ImGuiKey_PageDown, InputButton::Escape},
|
|
|
|
{ImGuiKey_Home, InputButton::Escape},
|
|
|
|
{ImGuiKey_End, InputButton::Escape},
|
|
|
|
{ImGuiKey_Insert, InputButton::Escape},
|
|
|
|
{ImGuiKey_Delete, InputButton::Escape},
|
|
|
|
{ImGuiKey_Backspace, InputButton::Backspace},
|
|
|
|
{ImGuiKey_Space, InputButton::Space},
|
|
|
|
{ImGuiKey_Enter, InputButton::Enter},
|
|
|
|
{ImGuiKey_Escape, InputButton::Escape},
|
|
|
|
{ImGuiKey_A, InputButton::A},
|
|
|
|
{ImGuiKey_C, InputButton::C},
|
|
|
|
{ImGuiKey_V, InputButton::V},
|
|
|
|
{ImGuiKey_X, InputButton::X},
|
|
|
|
{ImGuiKey_Y, InputButton::Y},
|
|
|
|
{ImGuiKey_Z, InputButton::Z}
|
|
|
|
};
|
|
|
|
|
2021-04-20 10:37:56 -04:00
|
|
|
imgui_backend::imgui_backend() {
|
2020-08-11 12:07:21 -04:00
|
|
|
ImGui::CreateContext();
|
|
|
|
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
|
io.IniFilename = "";
|
|
|
|
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
|
|
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
|
|
|
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports;
|
|
|
|
io.BackendPlatformName = "Prism";
|
2021-10-12 11:47:13 -04:00
|
|
|
|
2020-08-11 12:07:21 -04:00
|
|
|
for (auto& [im, pl] : imToPl)
|
|
|
|
io.KeyMap[im] = platform::get_keycode(pl);
|
2020-09-22 12:27:41 -04:00
|
|
|
|
|
|
|
const auto theme = platform::get_theme();
|
|
|
|
switch(theme) {
|
|
|
|
case PlatformTheme::Light:
|
|
|
|
ImGui::StyleColorsLight();
|
|
|
|
break;
|
|
|
|
case PlatformTheme::Dark:
|
|
|
|
{
|
|
|
|
ImGui::StyleColorsDark();
|
|
|
|
|
|
|
|
auto& style = ImGui::GetStyle();
|
|
|
|
style.FrameRounding = 3;
|
|
|
|
style.FrameBorderSize = 0.0f;
|
|
|
|
style.WindowBorderSize = 0.0f;
|
|
|
|
style.WindowPadding = ImVec2(10, 10);
|
|
|
|
style.FramePadding = ImVec2(4, 4);
|
|
|
|
style.ItemInnerSpacing = ImVec2(5, 0);
|
|
|
|
style.ItemSpacing = ImVec2(10, 5);
|
|
|
|
style.ScrollbarSize = 10;
|
|
|
|
style.GrabMinSize = 6;
|
|
|
|
style.WindowRounding = 3.0f;
|
|
|
|
style.ChildRounding = 3.0f;
|
|
|
|
style.PopupRounding = 3.0f;
|
|
|
|
style.ScrollbarRounding = 12.0f;
|
|
|
|
style.GrabRounding = 3.0f;
|
|
|
|
style.TabRounding = 3.0f;
|
|
|
|
style.WindowTitleAlign = ImVec2(0.0, 0.5);
|
|
|
|
|
|
|
|
ImVec4* colors = ImGui::GetStyle().Colors;
|
|
|
|
colors[ImGuiCol_FrameBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.54f);
|
|
|
|
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.68f, 0.68f, 0.68f, 0.40f);
|
|
|
|
colors[ImGuiCol_FrameBgActive] = ImVec4(0.42f, 0.47f, 0.52f, 0.67f);
|
|
|
|
colors[ImGuiCol_TitleBgActive] = ImVec4(0.23f, 0.43f, 0.73f, 1.00f);
|
|
|
|
colors[ImGuiCol_CheckMark] = ImVec4(0.74f, 0.80f, 0.87f, 1.00f);
|
|
|
|
colors[ImGuiCol_SliderGrab] = ImVec4(0.46f, 0.54f, 0.64f, 1.00f);
|
|
|
|
colors[ImGuiCol_Button] = ImVec4(0.38f, 0.51f, 0.65f, 0.40f);
|
|
|
|
colors[ImGuiCol_ButtonHovered] = ImVec4(0.57f, 0.61f, 0.67f, 1.00f);
|
|
|
|
colors[ImGuiCol_ButtonActive] = ImVec4(0.32f, 0.34f, 0.36f, 1.00f);
|
|
|
|
colors[ImGuiCol_Tab] = ImVec4(0.22f, 0.27f, 0.33f, 0.86f);
|
|
|
|
colors[ImGuiCol_TabActive] = ImVec4(0.33f, 0.51f, 0.75f, 1.00f);
|
|
|
|
colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.30f, 0.33f, 0.38f, 1.00f);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2020-08-11 12:07:21 -04:00
|
|
|
|
|
|
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
|
|
|
|
|
|
ImGuiPlatformMonitor monitor = {};
|
|
|
|
|
2021-10-12 10:52:29 -04:00
|
|
|
const auto monitorArea = platform::get_monitor_resolution();
|
|
|
|
monitor.MainPos = monitorArea.offset;
|
|
|
|
monitor.MainSize = monitorArea.extent;
|
2020-08-11 12:07:21 -04:00
|
|
|
|
2021-10-12 10:52:29 -04:00
|
|
|
const auto workArea = platform::get_monitor_work_area();
|
|
|
|
monitor.WorkPos = workArea.offset;
|
|
|
|
monitor.WorkSize = workArea.extent;
|
2020-08-11 12:07:21 -04:00
|
|
|
|
|
|
|
monitor.DpiScale = platform::get_monitor_dpi();
|
|
|
|
|
|
|
|
platform_io.Monitors.push_back(monitor);
|
2021-10-12 10:22:16 -04:00
|
|
|
|
2020-08-11 12:07:21 -04:00
|
|
|
platform_io.Platform_CreateWindow = [](ImGuiViewport* viewport) {
|
2021-10-13 10:55:20 -04:00
|
|
|
viewport->PlatformHandle = platform::open_window("", {viewport->Pos, viewport->Size}, WindowFlags::Borderless | WindowFlags::Hidden);
|
2020-08-11 12:07:21 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
platform_io.Platform_DestroyWindow = [](ImGuiViewport* viewport) {
|
2021-10-12 10:22:16 -04:00
|
|
|
platform::close_window(viewport->PlatformHandle);
|
2020-08-11 12:07:21 -04:00
|
|
|
};
|
|
|
|
|
2021-10-13 10:55:20 -04:00
|
|
|
platform_io.Platform_ShowWindow = [](ImGuiViewport* viewport) {
|
|
|
|
platform::show_window(viewport->PlatformHandle);
|
|
|
|
};
|
2021-10-12 10:22:16 -04:00
|
|
|
|
2020-08-11 12:07:21 -04:00
|
|
|
platform_io.Platform_SetWindowPos = [](ImGuiViewport* viewport, const ImVec2 pos) {
|
2021-10-12 10:22:16 -04:00
|
|
|
platform::set_window_position(viewport->PlatformHandle, pos);
|
2020-08-11 12:07:21 -04:00
|
|
|
};
|
|
|
|
|
2021-10-12 10:52:29 -04:00
|
|
|
platform_io.Platform_GetWindowPos = [](ImGuiViewport* viewport) -> ImVec2 {
|
|
|
|
return platform::get_window_position(viewport->PlatformHandle);
|
2020-08-11 12:07:21 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
platform_io.Platform_SetWindowSize = [](ImGuiViewport* viewport, const ImVec2 size) {
|
2021-10-12 10:22:16 -04:00
|
|
|
platform::set_window_size(viewport->PlatformHandle, size);
|
2021-10-12 11:25:01 -04:00
|
|
|
::engine->resize(viewport->PlatformHandle, size);
|
2020-08-11 12:07:21 -04:00
|
|
|
};
|
|
|
|
|
2021-10-12 10:52:29 -04:00
|
|
|
platform_io.Platform_GetWindowSize = [](ImGuiViewport* viewport) -> ImVec2 {
|
|
|
|
return platform::get_window_size(viewport->PlatformHandle);
|
2020-08-11 12:07:21 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
platform_io.Platform_SetWindowFocus = [](ImGuiViewport* viewport) {
|
2021-10-12 10:22:16 -04:00
|
|
|
platform::set_window_focused(viewport->PlatformHandle);
|
2020-08-11 12:07:21 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
platform_io.Platform_GetWindowFocus = [](ImGuiViewport* viewport) {
|
2021-10-12 10:22:16 -04:00
|
|
|
return platform::is_window_focused(viewport->PlatformHandle);
|
2020-08-11 12:07:21 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
platform_io.Platform_GetWindowMinimized = [](ImGuiViewport*) {
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
2021-10-12 10:22:16 -04:00
|
|
|
platform_io.Platform_SetWindowTitle = [](ImGuiViewport* viewport, const char* title) {
|
|
|
|
platform::set_window_title(viewport->PlatformHandle, title);
|
2020-08-11 12:07:21 -04:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-10-12 10:22:16 -04:00
|
|
|
void imgui_backend::process_move(platform::window_ptr identifier) {
|
|
|
|
auto viewport = ImGui::FindViewportByPlatformHandle(identifier);
|
|
|
|
if(viewport != nullptr)
|
|
|
|
viewport->PlatformRequestMove = true;
|
|
|
|
}
|
|
|
|
|
2021-10-12 11:06:59 -04:00
|
|
|
void imgui_backend::process_resize(platform::window_ptr identifier) {
|
|
|
|
auto viewport = ImGui::FindViewportByPlatformHandle(identifier);
|
|
|
|
if(viewport != nullptr)
|
|
|
|
viewport->PlatformRequestResize = true;
|
|
|
|
}
|
|
|
|
|
2021-04-20 10:37:56 -04:00
|
|
|
void imgui_backend::begin_frame(const float delta_time) {
|
2020-08-11 12:07:21 -04:00
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
2021-10-07 17:46:28 -04:00
|
|
|
|
|
|
|
const bool imgui_wants_text = io.WantTextInput;
|
|
|
|
const bool input_is_text = ::engine->get_input()->is_text_input();
|
|
|
|
|
|
|
|
if(imgui_wants_text != input_is_text) {
|
|
|
|
if(imgui_wants_text) {
|
|
|
|
::engine->get_input()->begin_text_input();
|
|
|
|
} else {
|
|
|
|
::engine->get_input()->end_text_input();
|
|
|
|
}
|
|
|
|
}
|
2021-10-12 10:22:16 -04:00
|
|
|
|
2021-10-12 10:52:29 -04:00
|
|
|
const auto size = platform::get_window_size(::engine->get_main_window());
|
|
|
|
const auto drawableSize = platform::get_window_drawable_size(::engine->get_main_window());
|
2020-08-11 12:07:21 -04:00
|
|
|
|
2021-10-12 10:52:29 -04:00
|
|
|
io.DisplaySize = size;
|
|
|
|
io.DisplayFramebufferScale = ImVec2(static_cast<float>(drawableSize.width) / static_cast<float>(size.width),
|
|
|
|
static_cast<float>(drawableSize.height) / static_cast<float>(size.height));
|
2020-08-11 12:07:21 -04:00
|
|
|
io.DeltaTime = delta_time;
|
|
|
|
io.KeyCtrl = platform::get_key_down(InputButton::Ctrl);
|
|
|
|
io.KeyShift = platform::get_key_down(InputButton::Shift);
|
|
|
|
io.KeyAlt = platform::get_key_down(InputButton::Alt);
|
|
|
|
io.KeySuper = platform::get_key_down(InputButton::Super);
|
|
|
|
io.MouseHoveredViewport = 0;
|
|
|
|
|
|
|
|
const auto [sx, sy] = platform::get_wheel_delta();
|
|
|
|
io.MouseWheel = sy;
|
|
|
|
io.MouseWheelH = sx;
|
|
|
|
|
|
|
|
if(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
|
|
|
|
const auto [x, y] = platform::get_screen_cursor_position();
|
|
|
|
|
|
|
|
io.MousePos = ImVec2(static_cast<float>(x), static_cast<float>(y));
|
|
|
|
} else {
|
|
|
|
const auto [x, y] = platform::get_cursor_position();
|
|
|
|
|
|
|
|
io.MousePos = ImVec2(static_cast<float>(x), static_cast<float>(y));
|
|
|
|
}
|
|
|
|
|
2021-05-11 17:05:29 -04:00
|
|
|
io.MouseDown[0] = mouse_buttons[0] || platform::get_mouse_button_down(0); // left
|
|
|
|
io.MouseDown[1] = mouse_buttons[1] || platform::get_mouse_button_down(1); // right
|
|
|
|
io.MouseDown[2] = mouse_buttons[2] || platform::get_mouse_button_down(2); // middle
|
|
|
|
mouse_buttons[0] = mouse_buttons[1] = mouse_buttons[2] = false;
|
|
|
|
|
2020-08-11 12:07:21 -04:00
|
|
|
ImGui::NewFrame();
|
2021-10-11 13:39:15 -04:00
|
|
|
|
|
|
|
if(open_dialog_next_frame) {
|
|
|
|
ImGui::OpenPopup("Open File");
|
|
|
|
open_dialog_next_frame = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(save_dialog_next_frame) {
|
|
|
|
ImGui::OpenPopup("Save File");
|
|
|
|
save_dialog_next_frame = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto dialog_function = [](dialog_data& data) {
|
|
|
|
if(ImGui::Selectable("..", false, ImGuiSelectableFlags_DontClosePopups))
|
|
|
|
data.current_path = data.current_path.parent_path();
|
|
|
|
|
2022-02-01 20:53:47 +00:00
|
|
|
if(data.select_directory) {
|
|
|
|
if(ImGui::Selectable(".", false, ImGuiSelectableFlags_DontClosePopups))
|
|
|
|
data.selected_path = data.current_path;
|
|
|
|
}
|
|
|
|
|
2021-10-14 08:51:58 -04:00
|
|
|
for(const auto& dir_ent : std::filesystem::directory_iterator(data.current_path)) {
|
2021-10-11 13:39:15 -04:00
|
|
|
if(ImGui::Selectable(dir_ent.path().c_str(), data.selected_path == dir_ent.path(), ImGuiSelectableFlags_DontClosePopups)) {
|
|
|
|
if(dir_ent.is_directory())
|
|
|
|
data.current_path = dir_ent.path();
|
|
|
|
else
|
|
|
|
data.selected_path = dir_ent.path();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::TextDisabled("Selected: %s", data.selected_path.c_str());
|
|
|
|
|
|
|
|
if(ImGui::Button("OK")) {
|
|
|
|
data.return_function(data.selected_path.string());
|
|
|
|
ImGui::CloseCurrentPopup();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ImGui::Button("Cancel"))
|
|
|
|
ImGui::CloseCurrentPopup();
|
|
|
|
};
|
|
|
|
|
|
|
|
if(ImGui::BeginPopup("Open File")) {
|
|
|
|
dialog_function(open_dialog_data);
|
|
|
|
ImGui::EndPopup();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ImGui::BeginPopup("Save File")) {
|
|
|
|
dialog_function(save_dialog_data);
|
|
|
|
ImGui::EndPopup();
|
|
|
|
}
|
2020-08-11 12:07:21 -04:00
|
|
|
}
|
|
|
|
|
2021-10-12 10:22:16 -04:00
|
|
|
void imgui_backend::render() {
|
|
|
|
ImGui::EndFrame();
|
|
|
|
ImGui::Render();
|
2020-08-11 12:07:21 -04:00
|
|
|
}
|
|
|
|
|
2021-04-20 10:37:56 -04:00
|
|
|
void imgui_backend::process_key_down(unsigned int key_code) {
|
|
|
|
Expects(key_code >= 0);
|
2021-10-07 17:46:28 -04:00
|
|
|
|
2020-08-11 12:07:21 -04:00
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
2021-10-07 17:46:28 -04:00
|
|
|
|
2021-04-20 10:37:56 -04:00
|
|
|
io.KeysDown[key_code] = true;
|
2020-08-11 12:07:21 -04:00
|
|
|
}
|
|
|
|
|
2021-04-20 10:37:56 -04:00
|
|
|
void imgui_backend::process_key_up(unsigned int key_code) {
|
|
|
|
Expects(key_code >= 0);
|
2020-08-11 12:07:21 -04:00
|
|
|
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
|
|
2021-04-20 10:37:56 -04:00
|
|
|
io.KeysDown[key_code] = false;
|
2020-08-11 12:07:21 -04:00
|
|
|
}
|
2021-05-11 17:05:29 -04:00
|
|
|
|
|
|
|
void imgui_backend::process_mouse_down(int button) {
|
|
|
|
mouse_buttons[button] = true;
|
2021-10-07 17:46:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void prism::imgui_backend::process_text_input(const std::string_view string) {
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
|
io.AddInputCharactersUTF8(string.data());
|
|
|
|
}
|
2021-10-11 13:39:15 -04:00
|
|
|
|
2022-02-01 20:53:47 +00:00
|
|
|
void prism::imgui_backend::open_dialog(const bool, std::function<void(std::string)> returnFunction, bool openDirectory) {
|
2021-10-11 13:39:15 -04:00
|
|
|
open_dialog_next_frame = true;
|
|
|
|
open_dialog_data.current_path = std::filesystem::current_path();
|
|
|
|
open_dialog_data.return_function = returnFunction;
|
2022-02-01 20:53:47 +00:00
|
|
|
open_dialog_data.select_directory = openDirectory;
|
2021-10-11 13:39:15 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void prism::imgui_backend::save_dialog(std::function<void(std::string)> returnFunction) {
|
|
|
|
save_dialog_next_frame = true;
|
|
|
|
save_dialog_data.current_path = std::filesystem::current_path();
|
|
|
|
save_dialog_data.return_function = returnFunction;
|
2022-02-01 20:53:47 +00:00
|
|
|
}
|