Run clang-format (the repo's .clang-format: LLVM base, 120 cols, tabs, Allman functions) over every source file so the tree is formatter-clean. Whitespace only -- no behavior change; full x64 + x86 suites pass. Also set SortIncludes: false in .clang-format. Windows include order is load-bearing (windows.h must precede tlhelp32.h / mmreg.h / xinput.h / dinput.h; winsock2.h must precede windows.h), and the default alphabetical sort reorders tlhelp32.h ahead of windows.h -- a build break. Leaving order alone keeps the manual, correct grouping.
105 lines
3.1 KiB
C++
105 lines
3.1 KiB
C++
#include "imgui_layer.hpp"
|
|
|
|
#include <string>
|
|
|
|
#include <imgui.h>
|
|
#include <imgui_impl_dx11.h>
|
|
#include <imgui_impl_win32.h>
|
|
|
|
#include "coop/dpi.hpp"
|
|
#include "coop/tool_paths.hpp"
|
|
#include "ui/app_chrome.hpp"
|
|
#include "util/utf8.hpp"
|
|
|
|
namespace coop {
|
|
|
|
ImGuiLayer::~ImGuiLayer()
|
|
{
|
|
if (initialized_) {
|
|
ImGui_ImplDX11_Shutdown();
|
|
ImGui_ImplWin32_Shutdown();
|
|
ImGui::DestroyContext();
|
|
initialized_ = false;
|
|
}
|
|
}
|
|
|
|
bool ImGuiLayer::init(HWND hwnd, ID3D11Device* device, ID3D11DeviceContext* context)
|
|
{
|
|
IMGUI_CHECKVERSION();
|
|
ImGui::CreateContext();
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
// Persist the panel layout next to the executable so window positions/sizes survive
|
|
// restarts. CWD is unreliable when Steam launches us under the donor appid, so anchor
|
|
// to the exe directory. If a layout already exists, tell the chrome not to force the
|
|
// computed default on startup (which would clobber the restored positions).
|
|
const std::wstring ini_w = exe_directory() + L"coop_layout.ini";
|
|
const bool had_layout = GetFileAttributesW(ini_w.c_str()) != INVALID_FILE_ATTRIBUTES;
|
|
// ImGui treats IniFilename as UTF-8 (it converts to wide for _wfopen), so narrow to UTF-8, not
|
|
// the system ANSI code page.
|
|
ini_path_ = narrow(ini_w);
|
|
io.IniFilename = ini_path_.c_str();
|
|
set_layout_persisted(had_layout);
|
|
|
|
if (!ImGui_ImplWin32_Init(hwnd)) {
|
|
return false;
|
|
}
|
|
if (!ImGui_ImplDX11_Init(device, context)) {
|
|
return false;
|
|
}
|
|
initialized_ = true;
|
|
|
|
// Scale the overlay (font + style) to the monitor the window opened on. The process is
|
|
// per-monitor-DPI-aware (set in wWinMain), so GetDpiForWindow returns that monitor's real DPI.
|
|
apply_dpi(GetDpiForWindow(hwnd));
|
|
return true;
|
|
}
|
|
|
|
void ImGuiLayer::apply_dpi(unsigned dpi)
|
|
{
|
|
const float scale = dpi_scale_from(dpi);
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
|
// Rebuild the font atlas at the DPI-scaled pixel size so ImGui's built-in default font is
|
|
// rasterized crisp at the target size, rather than bitmap-stretched the way io.FontGlobalScale
|
|
// would leave it. scaled_font_px() scales the one named base-size constant.
|
|
io.Fonts->Clear();
|
|
ImFontConfig cfg;
|
|
cfg.SizePixels = scaled_font_px(dpi);
|
|
io.Fonts->AddFontDefault(&cfg);
|
|
|
|
// Reset to the base dark theme, then scale spacing/padding/border sizes to match. Resetting
|
|
// first keeps repeated DPI changes from compounding (ScaleAllSizes multiplies the style in place).
|
|
ImGui::StyleColorsDark();
|
|
ImGui::GetStyle().ScaleAllSizes(scale);
|
|
|
|
// Drop the DX11 backend's cached font texture so it rebuilds from the new atlas next frame. Before
|
|
// the first frame nothing is built yet, so this is a harmless no-op during init().
|
|
if (initialized_) {
|
|
ImGui_ImplDX11_InvalidateDeviceObjects();
|
|
}
|
|
dpi_scale_ = scale;
|
|
}
|
|
|
|
void ImGuiLayer::set_dpi(unsigned dpi)
|
|
{
|
|
if (!initialized_ || dpi_scale_from(dpi) == dpi_scale_) {
|
|
return; // not up yet, or the scale didn't actually change -- skip a needless atlas rebuild
|
|
}
|
|
apply_dpi(dpi);
|
|
}
|
|
|
|
void ImGuiLayer::begin_frame()
|
|
{
|
|
ImGui_ImplDX11_NewFrame();
|
|
ImGui_ImplWin32_NewFrame();
|
|
ImGui::NewFrame();
|
|
}
|
|
|
|
void ImGuiLayer::end_frame()
|
|
{
|
|
ImGui::Render();
|
|
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
|
}
|
|
|
|
} // namespace coop
|