bluenoise-raytracer/raytracer/nvpro_core/nvvkhl/element_gui.hpp
2024-05-25 11:53:25 +02:00

173 lines
4.6 KiB
C++

/*
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
// Various Application utilities
// - Display a menu with File/Quit
// - Display basic information in the window title
#include "imgui.h"
#include "implot.h"
#include "application.hpp"
#include "GLFW/glfw3.h"
// Use:
// include this file at the end of all other includes,
// and add engines
//
// Ex:
// app->addEngine(std::make_shared<AppDefaultMenu>());
//
namespace nvvkhl {
/** @DOC_START
# class nvvkhl::ElementDefaultMenu
> This class is an element of the application that is responsible for the default menu of the application. It is using the `ImGui` library to create a menu with File/Exit and View/V-Sync.
To use this class, you need to add it to the `nvvkhl::Application` using the `addElement` method.
@DOC_END */
class ElementDefaultMenu : public nvvkhl::IAppElement
{
public:
void onAttach(nvvkhl::Application* app) override { m_app = app; }
void onUIMenu() override
{
static bool close_app{false};
bool v_sync = m_app->isVsync();
#ifndef NDEBUG
static bool s_showDemo{false};
static bool s_showDemoPlot{false};
#endif
if(ImGui::BeginMenu("File"))
{
if(ImGui::MenuItem("Exit", "Ctrl+Q"))
{
close_app = true;
}
ImGui::EndMenu();
}
if(ImGui::BeginMenu("View"))
{
ImGui::MenuItem("V-Sync", "Ctrl+Shift+V", &v_sync);
ImGui::EndMenu();
}
#ifndef NDEBUG
if(ImGui::BeginMenu("Debug"))
{
ImGui::MenuItem("Show ImGui Demo", nullptr, &s_showDemo);
ImGui::MenuItem("Show ImPlot Demo", nullptr, &s_showDemoPlot);
ImGui::EndMenu();
}
#endif // !NDEBUG
// Shortcuts
if(ImGui::IsKeyPressed(ImGuiKey_Q) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
{
close_app = true;
}
if(ImGui::IsKeyPressed(ImGuiKey_V) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyDown(ImGuiKey_LeftShift))
{
v_sync = !v_sync;
}
if(close_app)
{
m_app->close();
}
#ifndef NDEBUG
if(s_showDemo)
{
ImGui::ShowDemoWindow(&s_showDemo);
}
if(s_showDemoPlot)
{
ImPlot::ShowDemoWindow(&s_showDemoPlot);
}
#endif // !NDEBUG
if(m_app->isVsync() != v_sync)
{
m_app->setVsync(v_sync);
}
}
private:
nvvkhl::Application* m_app{nullptr};
};
/** @DOC_START
# class nvvkhl::ElementDefaultWindowTitle
> This class is an element of the application that is responsible for the default window title of the application. It is using the `GLFW` library to set the window title with the application name, the size of the window and the frame rate.
To use this class, you need to add it to the `nvvkhl::Application` using the `addElement` method.
@DOC_END */
class ElementDefaultWindowTitle : public nvvkhl::IAppElement
{
public:
ElementDefaultWindowTitle(const std::string& prefix = "", const std::string& suffix = "")
: m_prefix(prefix)
, m_suffix(suffix)
{
}
void onAttach(nvvkhl::Application* app) override { m_app = app; }
void onUIRender() override
{
// Window Title
m_dirtyTimer += ImGui::GetIO().DeltaTime;
if(m_dirtyTimer > 1.0F) // Refresh every seconds
{
const auto& size = m_app->getViewportSize();
std::string title;
if(!m_prefix.empty())
{
title += fmt::format("{} | ", m_prefix.c_str());
}
title += fmt::format("{} | {}x{} | {:.0f} FPS / {:.3f}ms", PROJECT_NAME, size.width, size.height,
ImGui::GetIO().Framerate, 1000.F / ImGui::GetIO().Framerate);
if(!m_suffix.empty())
{
title += fmt::format(" | {}", m_suffix.c_str());
}
glfwSetWindowTitle(m_app->getWindowHandle(), title.c_str());
m_dirtyTimer = 0;
}
}
void setPrefix(const std::string& str) { m_prefix = str; }
void setSuffix(const std::string& str) { m_suffix = str; }
private:
nvvkhl::Application* m_app{nullptr};
float m_dirtyTimer{0.0F};
std::string m_prefix;
std::string m_suffix;
};
} // namespace nvvkhl