Skip to content

Commit

Permalink
Handle iOS notch insets
Browse files Browse the repository at this point in the history
  • Loading branch information
pthom committed Dec 17, 2023
1 parent f113f5f commit 558febe
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 35 deletions.
23 changes: 11 additions & 12 deletions src/hello_imgui/app_window_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,15 @@ struct WindowGeometry
};


#if TARGET_OS_IOS
// If there is a notch on the iPhone, you should not display inside these insets
struct IosEdgeInsets
struct EdgeInsets
{
double top; // Typically around 47
double left; // Typically 0
double bottom; // Typically around 34
double right; // Typically 0
double top = 0.; // Typically around 47
double left = 0.; // Typically 0
double bottom = 0.; // Typically around 34
double right = 0.; // Typically 0
};
#endif


/**
@@md#AppWindowParams
Expand All @@ -171,6 +170,10 @@ creation.
creation.
* `hidden`: _bool, default = false_. Should the window be hidden. This is taken into account dynamically (you
can show/hide the window with this). Full screen windows cannot be hidden.@@md
* `edgeInsets`: _EdgeInsets_. iOS only, out values filled by HelloImGui:
if there is a notch on the iPhone, you should not display inside these insets.
HelloImGui handles this automatically, if runnerParams.imGuiWindowParams.defaultImGuiWindowType is not NoDefaultWindow.
(warning, these values are updated only after a few frames, they are typically 0 for the first 4 frames)
**/
struct AppWindowParams
{
Expand All @@ -185,11 +188,7 @@ struct AppWindowParams
bool resizable = true;
bool hidden = false;

#if TARGET_OS_IOS
// Out values filled by HelloImGui: if there is a notch on the iPhone, you should not display inside these insets.
// (warning, these values are updated only after a few frames, they are typically 0 for the first 4 frames)
IosEdgeInsets iosEdgeInsets;
#endif
EdgeInsets edgeInsets;
};

} // namespace HelloImGui
10 changes: 5 additions & 5 deletions src/hello_imgui/hello_imgui_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,10 @@ creation.
creation.
* `hidden`: _bool, default = false_. Should the window be hidden. This is taken into account dynamically (you
can show/hide the window with this). Full screen windows cannot be hidden.@@md
* `edgeInsets`: _EdgeInsets_. iOS only, out values filled by HelloImGui:
if there is a notch on the iPhone, you should not display inside these insets.
HelloImGui handles this automatically, if runnerParams.imGuiWindowParams.defaultImGuiWindowType is not NoDefaultWindow.
(warning, these values are updated only after a few frames, they are typically 0 for the first 4 frames)
**/
struct AppWindowParams
{
Expand All @@ -351,11 +355,7 @@ struct AppWindowParams
bool resizable = true;
bool hidden = false;

#if TARGET_OS_IOS
// Out values filled by HelloImGui: if there is a notch on the iPhone, you should not display inside these insets.
// (warning, these values are updated only after a few frames, they are typically 0 for the first 4 frames)
IosEdgeInsets iosEdgeInsets;
#endif
EdgeInsets edgeInsets;
};

} // namespace HelloImGui
Expand Down
8 changes: 4 additions & 4 deletions src/hello_imgui/internal/backend_impls/abstract_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -506,10 +506,10 @@ void AbstractRunner::CreateFramesAndRender()

#if TARGET_OS_IOS
auto insets = GetIPhoneSafeAreaInsets();
params.appWindowParams.iosEdgeInsets.top = insets.top;
params.appWindowParams.iosEdgeInsets.left = insets.left;
params.appWindowParams.iosEdgeInsets.bottom = insets.bottom;
params.appWindowParams.iosEdgeInsets.right = insets.right;
params.appWindowParams.edgeInsets.top = insets.top;
params.appWindowParams.edgeInsets.left = insets.left;
params.appWindowParams.edgeInsets.bottom = insets.bottom;
params.appWindowParams.edgeInsets.right = insets.right;
#endif

#ifdef HELLOIMGUI_WITH_TEST_ENGINE
Expand Down
34 changes: 24 additions & 10 deletions src/hello_imgui/internal/docking_details.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,16 +237,30 @@ void ShowDockableWindows(std::vector<DockableWindow>& dockableWindows)
}
}

void DoCreateFullScreenImGuiWindow(const ImGuiWindowParams& imGuiWindowParams, bool useDocking)

void DoCreateFullScreenImGuiWindow(const RunnerParams& runnerParams, bool useDocking)
{
const ImGuiWindowParams& imGuiWindowParams = runnerParams.imGuiWindowParams;

ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->Pos);

ImVec2 viewportSize = viewport->Size;
if (imGuiWindowParams.showStatusBar)
viewportSize.y -= ImGui::GetFrameHeight() * 1.35f;
ImVec2 fullScreenSize, fullScreenPos;
{
// One some platform, like iOS, we need to take into account the insets
// so that our app does not go under the notch or the home indicator
const EdgeInsets& edgeInsets = runnerParams.appWindowParams.edgeInsets;
fullScreenPos = viewport->Pos;
fullScreenPos.x += edgeInsets.left;
fullScreenPos.y += edgeInsets.top;
fullScreenSize = viewport->Size;
fullScreenSize.x -= edgeInsets.left + edgeInsets.right;
fullScreenSize.y -= edgeInsets.top + edgeInsets.bottom;
if (imGuiWindowParams.showStatusBar)
fullScreenSize.y -= ImGui::GetFrameHeight() * 1.35f;
}

ImGui::SetNextWindowSize(viewportSize);
ImGui::SetNextWindowPos(fullScreenPos);
ImGui::SetNextWindowSize(fullScreenSize);
ImGui::SetNextWindowViewport(viewport->ID);
if (useDocking)
ImGui::SetNextWindowBgAlpha(0.0f);
Expand All @@ -268,14 +282,14 @@ void DoCreateFullScreenImGuiWindow(const ImGuiWindowParams& imGuiWindowParams, b
}


void ImplProvideFullScreenImGuiWindow(const ImGuiWindowParams& imGuiWindowParams)
void ImplProvideFullScreenImGuiWindow(const RunnerParams& runnerParams)
{
DoCreateFullScreenImGuiWindow(imGuiWindowParams, false);
DoCreateFullScreenImGuiWindow(runnerParams, false);
}

void ImplProvideFullScreenDockSpace(const RunnerParams& runnerParams)
{
DoCreateFullScreenImGuiWindow(runnerParams.imGuiWindowParams, true);
DoCreateFullScreenImGuiWindow(runnerParams, true);
ImGuiID mainDockspaceId = ImGui::GetID("MainDockSpace");
ImGui::DockSpace(mainDockspaceId, ImVec2(0.0f, 0.0f), runnerParams.dockingParams.mainDockSpaceNodeFlags);
gImGuiSplitIDs["MainDockSpace"] = mainDockspaceId;
Expand Down Expand Up @@ -316,7 +330,7 @@ void ApplyDockLayout(DockingParams& dockingParams)
void ProvideWindowOrDock(RunnerParams& runnerParams)
{
if (runnerParams.imGuiWindowParams.defaultImGuiWindowType == DefaultImGuiWindowType::ProvideFullScreenWindow)
ImplProvideFullScreenImGuiWindow(runnerParams.imGuiWindowParams);
ImplProvideFullScreenImGuiWindow(runnerParams);

if (runnerParams.imGuiWindowParams.defaultImGuiWindowType == DefaultImGuiWindowType::ProvideFullScreenDockSpace)
{
Expand Down
14 changes: 12 additions & 2 deletions src/hello_imgui/internal/menu_statusbar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,18 @@ void ShowStatusBar(RunnerParams & params)
{
float statusWindowHeight = ImGui::GetFrameHeight() * 1.4f;
ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(ImVec2(viewport->Pos.x, viewport->Pos.y + viewport->Size.y - statusWindowHeight));
ImGui::SetNextWindowSize(ImVec2(viewport->Size.x, statusWindowHeight));

ImVec2 statusBarSize, statusBarPos;
{
// One some platform, like iOS, we need to take into account the insets
// so that our app does not go under the notch or the home indicator
const EdgeInsets& edgeInsets = params.appWindowParams.edgeInsets;
statusBarSize = ImVec2(viewport->Size.x - edgeInsets.left - edgeInsets.right, statusWindowHeight);
statusBarPos = ImVec2(edgeInsets.left, viewport->Size.y - edgeInsets.bottom - statusBarSize.y);
}

ImGui::SetNextWindowPos(statusBarPos);
ImGui::SetNextWindowSize(statusBarSize);
ImGui::SetNextWindowViewport(viewport->ID);

ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoDocking;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -495,8 +495,7 @@ int main(int, char**)
// Hello ImGui params (they hold the settings as well as the Gui callbacks)
HelloImGui::RunnerParams runnerParams;
runnerParams.appWindowParams.windowTitle = "Docking demo";

runnerParams.imGuiWindowParams.menuAppTitle = "Docking App";
runnerParams.imGuiWindowParams.menuAppTitle = "Docking Demo";
runnerParams.appWindowParams.windowGeometry.size = {1000, 900};
runnerParams.appWindowParams.restorePreviousGeometry = true;

Expand Down

0 comments on commit 558febe

Please sign in to comment.