Skip to content

Commit

Permalink
Save/LoadLastRunWindowBounds: also save DpiWindowSizeFactor / restore…
Browse files Browse the repository at this point in the history
… size with DPI handling
  • Loading branch information
pthom committed Jul 5, 2024
1 parent 004a648 commit 6027062
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 3 deletions.
38 changes: 38 additions & 0 deletions src/hello_imgui/internal/backend_impls/abstract_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,39 @@ void AbstractRunner::PrepareWindowGeometry()
params.appWindowParams.windowGeometry.size = windowBounds.size;
}


// If needed, change the size to match the current DPI versus the DPI when the size was saved
// (we want the window to "look" as big as it was when saved, even if the DPI has changed,
// or if we are on a different monitor / computer / OS)
void AbstractRunner::AdjustWindowBoundsAfterCreation_IfDpiChangedBetweenRuns()
{
bool reloadLastSize = params.appWindowParams.restorePreviousGeometry &&
HelloImGuiIniSettings::LoadLastRunWindowBounds(IniSettingsLocation(params)).has_value();
if (!reloadLastSize)
return;

std::optional<float> lastRunDpiWindowSizeFactorOpt = HelloImGuiIniSettings::LoadLastRunDpiWindowSizeFactor(IniSettingsLocation(params));
if (!lastRunDpiWindowSizeFactorOpt.has_value())
return;

float lastRunDpiWindowSizeFactor = lastRunDpiWindowSizeFactorOpt.value();
float currentDpiWindowSizeFactor = params.dpiAwareParams.dpiWindowSizeFactor;
float ratio = currentDpiWindowSizeFactor / lastRunDpiWindowSizeFactor;
bool isSane = ratio > 0.25f && ratio < 4.f;
if (isSane && ratio != 1.f)
{
auto bounds = mBackendWindowHelper->GetWindowBounds(mWindow);
bounds.size = {(int)((float)bounds.size[0] * ratio),
(int)((float)bounds.size[1] * ratio)};
bounds.position = {
(int)((float)bounds.position[0] * ratio),
(int)((float)bounds.position[1] * ratio)
};
mBackendWindowHelper->SetWindowBounds(mWindow, bounds);
}
}


bool AbstractRunner::WantAutoSize()
{
#ifdef __EMSCRIPTEN__
Expand Down Expand Up @@ -717,6 +750,7 @@ void AbstractRunner::Setup()
//printf("Window resized by code\n");
}
};

Impl_CreateWindow(fnRenderCallbackDuringResize);

#ifdef HELLOIMGUI_HAS_OPENGL
Expand All @@ -729,7 +763,11 @@ void AbstractRunner::Setup()

Impl_SetWindowIcon();

// The order is important: first read the DPI aware params
SetupDpiAwareParams();
// Then adjust window size if needed
AdjustWindowBoundsAfterCreation_IfDpiChangedBetweenRuns();


// This should be done before Impl_LinkPlatformAndRenderBackends()
// because, in the case of glfw ImGui_ImplGlfw_InstallCallbacks
Expand Down
1 change: 1 addition & 0 deletions src/hello_imgui/internal/backend_impls/abstract_runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class AbstractRunner
void SetupDpiAwareParams();
bool CheckDpiAwareParamsChanges();
void PrepareWindowGeometry();
void AdjustWindowBoundsAfterCreation_IfDpiChangedBetweenRuns();
void HandleDpiOnSecondFrame();
void MakeWindowSizeRelativeTo96Ppi_IfRequired();
bool ShallSizeWindowRelativeTo96Ppi();
Expand Down
55 changes: 52 additions & 3 deletions src/hello_imgui/internal/hello_imgui_ini_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,13 @@ namespace HelloImGui

void SaveLastRunWindowBounds(const std::string& iniPartsFilename, const ScreenBounds& windowBounds)
{
auto& dpiAwareParams = HelloImGui::GetRunnerParams()->dpiAwareParams;
IniParts iniParts = IniParts::LoadFromFile(iniPartsFilename);

ini::IniFile iniFile;
iniFile["AppWindow"]["WindowPosition"] = IntPairToString(windowBounds.position);
iniFile["AppWindow"]["WindowSize"] = IntPairToString(windowBounds.size);
iniFile["AppWindow"]["DpiWindowSizeFactor"] = dpiAwareParams.dpiWindowSizeFactor;
std::string iniContent = iniFile.encode();

iniParts.SetIniPart("AppWindow", iniContent);
Expand All @@ -191,7 +193,6 @@ namespace HelloImGui
if (!iniParts.HasIniPart("AppWindow"))
return std::nullopt;


auto iniPartContent = iniParts.GetIniPart("AppWindow");
ini::IniFile iniFile;
try
Expand All @@ -206,16 +207,26 @@ namespace HelloImGui
ScreenBounds screenBounds;
bool failed = false;

if (iniFile.find("AppWindow") == iniFile.end())
return std::nullopt;
auto & appWindowSection = iniFile["AppWindow"];

// Read Window Position
{
auto strValue = iniFile["AppWindow"]["WindowPosition"].as<std::string>();
if (appWindowSection.find("WindowPosition") == appWindowSection.end())
return std::nullopt;
auto strValue = appWindowSection["WindowPosition"].as<std::string>();
auto intPair = StringToIntPair(strValue);
if (intPair[0] >= 0)
screenBounds.position = intPair;
else
failed = true;
}
// Read Window Size
{
auto strValue = iniFile["AppWindow"]["WindowSize"].as<std::string>();
if (appWindowSection.find("WindowSize") == appWindowSection.end())
return std::nullopt;
auto strValue = appWindowSection["WindowSize"].as<std::string>();
auto intPair = StringToIntPair(strValue);
if (intPair[0] >= 0)
screenBounds.size = intPair;
Expand All @@ -230,6 +241,44 @@ namespace HelloImGui

}

std::optional<float> LoadLastRunDpiWindowSizeFactor(const std::string& iniPartsFilename)
{
IniParts iniParts = IniParts::LoadFromFile(iniPartsFilename);

if (!iniParts.HasIniPart("AppWindow"))
return std::nullopt;

auto iniPartContent = iniParts.GetIniPart("AppWindow");
ini::IniFile iniFile;
try
{
iniFile.decode(iniPartContent);
}
catch (const std::exception &)
{
return std::nullopt;
}

ScreenBounds screenBounds;
bool failed = false;

if (iniFile.find("AppWindow") == iniFile.end())
return std::nullopt;
auto &appWindowSection = iniFile["AppWindow"];

if (appWindowSection.find("DpiWindowSizeFactor") != appWindowSection.end())
{
float dpiWindowSizeFactor_WhenSaved =
iniFile["AppWindow"]["DpiWindowSizeFactor"].as<float>();
bool isDpiSane = (dpiWindowSizeFactor_WhenSaved >= 0.1f) &&
(dpiWindowSizeFactor_WhenSaved <= 10.f);
if (isDpiSane)
return dpiWindowSizeFactor_WhenSaved;
}
return std::nullopt;
}


void LoadImGuiSettings(const std::string& iniPartsFilename, const std::string& layoutName)
{
std::string iniPartName = "ImGui_" + details::SanitizeIniNameOrCategory(layoutName);
Expand Down
1 change: 1 addition & 0 deletions src/hello_imgui/internal/hello_imgui_ini_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ namespace HelloImGui
//
void SaveLastRunWindowBounds(const std::string& iniPartsFilename, const ScreenBounds& windowBounds);
std::optional<ScreenBounds> LoadLastRunWindowBounds(const std::string& iniPartsFilename);
std::optional<float> LoadLastRunDpiWindowSizeFactor(const std::string& iniPartsFilename);
void SaveHelloImGuiMiscSettings(const std::string& iniPartsFilename, const RunnerParams& runnerParams);
void LoadHelloImGuiMiscSettings(const std::string& iniPartsFilename, RunnerParams* inOutRunnerParams);

Expand Down

0 comments on commit 6027062

Please sign in to comment.