activity_host_tool_window.h 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. #pragma once
  2. #include <algorithm>
  3. #include <imgui.h>
  4. #include "../../../core/ui/scaling/dpi/ui_dpi_scaling.h"
  5. namespace sunrise::server::ui::activity_host::tool_window {
  6. /** A titled window that moves, resizes and scrolls its own content. */
  7. constexpr ImGuiWindowFlags kWindowFlags =
  8. ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings;
  9. /** Applies bounded size constraints and a centered first-use size given as work-area fractions. */
  10. inline void set_next(const ImVec2& workFraction) noexcept {
  11. namespace scaling = core::ui::scaling::dpi;
  12. const ImGuiViewport* viewport = ImGui::GetMainViewport();
  13. if (viewport == nullptr) {
  14. return;
  15. }
  16. const float margin = scaling::pixels(16.0F);
  17. const ImVec2 maximum{(std::max)(viewport->WorkSize.x - (margin * 2.0F), 1.0F),
  18. (std::max)(viewport->WorkSize.y - (margin * 2.0F), 1.0F)};
  19. const ImVec2 requestedMinimum = scaling::pixels({320.0F, 120.0F});
  20. const ImVec2 minimum{(std::min)(requestedMinimum.x, maximum.x),
  21. (std::min)(requestedMinimum.y, maximum.y)};
  22. const ImVec2 size{std::clamp(viewport->WorkSize.x * workFraction.x, minimum.x, maximum.x),
  23. std::clamp(viewport->WorkSize.y * workFraction.y, minimum.y, maximum.y)};
  24. ImGui::SetNextWindowSizeConstraints(minimum, maximum);
  25. ImGui::SetNextWindowSize(size, ImGuiCond_FirstUseEver);
  26. ImGui::SetNextWindowPos(viewport->GetWorkCenter(), ImGuiCond_FirstUseEver, {0.5F, 0.5F});
  27. }
  28. /** Begins a movable, resizable window whose title bar reads as a raised Sunrise panel. */
  29. [[nodiscard]] inline bool begin(const char* id, bool& open, const ImVec2& workFraction) noexcept {
  30. namespace scaling = core::ui::scaling::dpi;
  31. set_next(workFraction);
  32. // Dear ImGui reads these only while Begin draws the frame, so the body keeps the theme.
  33. // The same colour whether focused or not, so focus never lights the bar up.
  34. const ImGuiStyle& style = ImGui::GetStyle();
  35. const ImVec4 titleBackground = style.Colors[ImGuiCol_ChildBg];
  36. ImGui::PushStyleColor(ImGuiCol_TitleBg, titleBackground);
  37. ImGui::PushStyleColor(ImGuiCol_TitleBgActive, titleBackground);
  38. ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,
  39. ImVec2{style.FramePadding.x, scaling::pixels(8.0F)});
  40. ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, style.WindowBorderSize);
  41. const bool visible = ImGui::Begin(id, &open, kWindowFlags);
  42. ImGui::PopStyleVar(2);
  43. ImGui::PopStyleColor(2);
  44. return visible;
  45. }
  46. } // namespace sunrise::server::ui::activity_host::tool_window