Files

119 lines
4.6 KiB
C++

/*
* PS5 Vulkan Template - the UI module: the samples' settings windows in the title's theme.
*
* The samples draw their settings with Dear ImGui (base/VulkanUIOverlay.cpp).
* These two functions, which the overlay calls on the console, give ImGui the
* title's theme (ps5ui::active_theme): its palette, its corners and borders,
* and its typeface. ImGui has no frosted glass, glows or bevels, so a theme
* reaches it as colours and shapes; the kit's own screens draw the rest.
*
* Copyright (C) 2026 Mihawk
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "kit.hpp"
namespace {
ImVec4 colour(hui::gfx::Color c, float alpha = 1.0f)
{
return ImVec4(c.r, c.g, c.b, c.a * alpha);
}
ImVec4 blend(hui::gfx::Color a, hui::gfx::Color b, float t, float alpha = 1.0f)
{
return colour(hui::gfx::mix(a, b, t), alpha);
}
} // namespace
void ps5StyleOverlay(ImGuiStyle &style)
{
const hui::ui::Theme &t = ps5ui::active_theme();
ImVec4 *c = style.Colors;
c[ImGuiCol_Text] = colour(t.text);
c[ImGuiCol_TextDisabled] = colour(t.text_muted);
c[ImGuiCol_WindowBg] = colour(t.surface, 0.94f);
c[ImGuiCol_ChildBg] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
c[ImGuiCol_PopupBg] = colour(t.surface, 0.98f);
c[ImGuiCol_Border] = colour(t.outline, t.border > 0.0f ? 1.0f : 0.5f);
c[ImGuiCol_BorderShadow] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
c[ImGuiCol_FrameBg] = colour(t.surface_high);
c[ImGuiCol_FrameBgHovered] = blend(t.surface_high, t.accent, 0.15f);
c[ImGuiCol_FrameBgActive] = blend(t.surface_high, t.accent, 0.3f);
// The title bar carries the window's name in the text colour: a raised surface
c[ImGuiCol_TitleBg] = colour(t.surface_high);
c[ImGuiCol_TitleBgActive] = blend(t.surface_high, t.primary, 0.2f);
c[ImGuiCol_TitleBgCollapsed] = colour(t.surface_high, 0.7f);
c[ImGuiCol_MenuBarBg] = colour(t.surface_high);
c[ImGuiCol_ScrollbarBg] = colour(t.surface, 0.5f);
c[ImGuiCol_ScrollbarGrab] = colour(t.outline);
c[ImGuiCol_ScrollbarGrabHovered] = colour(t.text_muted);
c[ImGuiCol_ScrollbarGrabActive] = colour(t.accent);
c[ImGuiCol_CheckMark] = colour(t.accent);
c[ImGuiCol_SliderGrab] = colour(t.accent);
c[ImGuiCol_SliderGrabActive] = colour(t.primary);
c[ImGuiCol_Button] = colour(t.secondary);
c[ImGuiCol_ButtonHovered] = blend(t.secondary, t.primary, 0.35f);
c[ImGuiCol_ButtonActive] = colour(t.primary);
c[ImGuiCol_Header] = colour(t.accent, 0.3f);
c[ImGuiCol_HeaderHovered] = colour(t.accent, 0.45f);
c[ImGuiCol_HeaderActive] = colour(t.accent, 0.6f);
c[ImGuiCol_Separator] = colour(t.outline);
c[ImGuiCol_SeparatorHovered] = colour(t.accent, 0.7f);
c[ImGuiCol_SeparatorActive] = colour(t.accent);
c[ImGuiCol_ResizeGrip] = colour(t.outline, 0.4f);
c[ImGuiCol_ResizeGripHovered] = colour(t.accent, 0.6f);
c[ImGuiCol_ResizeGripActive] = colour(t.accent);
c[ImGuiCol_PlotLines] = colour(t.accent);
c[ImGuiCol_PlotHistogram] = colour(t.accent);
c[ImGuiCol_TextSelectedBg] = colour(t.accent, 0.35f);
c[ImGuiCol_NavHighlight] = colour(t.focus.a > 0.0f ? t.focus : t.accent);
c[ImGuiCol_ModalWindowDimBg] = colour(t.shadow, 0.5f);
// Shapes, in ImGui's units before the overlay's scale (2.5 at 3840x2160,
// so one unit is 1.25 of the kit's 1920x1080 pixels). Square and notched
// corners stay square; a pill radius becomes a full round.
const bool square = t.corner != hui::ui::Corner::round;
const float unit = 1.0f / 1.25f;
const float control = square ? 0.0f : t.radius >= 100.0f ? 12.0f : t.radius * unit;
style.WindowRounding = square ? 0.0f : std::min(t.radius_card * unit, 16.0f);
style.ChildRounding = style.WindowRounding;
style.PopupRounding = style.WindowRounding;
style.FrameRounding = std::min(control, 12.0f);
style.GrabRounding = style.FrameRounding;
style.ScrollbarRounding = square ? 0.0f : 9.0f;
style.WindowBorderSize = t.border > 0.0f ? 1.0f : 0.0f;
style.FrameBorderSize = (t.button_border >= 0.0f ? t.button_border : t.border) > 0.0f ? 1.0f : 0.0f;
style.PopupBorderSize = style.WindowBorderSize;
}
bool ps5OverlayFont(std::string &path, float &size)
{
// The theme's label face, in the TTF the kit was baked from
const std::string fonts = std::string(VK_EXAMPLE_ASSETS_DIR) + "hui/fonts/";
switch (ps5ui::active_theme().label) {
case hui::ui::FontRole::pixel:
path = fonts + "PressStart2P-Regular.ttf";
size = 10.0f;
break;
case hui::ui::FontRole::hand:
path = fonts + "PatrickHand-Regular.ttf";
size = 20.0f;
break;
case hui::ui::FontRole::regular:
path = fonts + "Inter-Regular.ttf";
size = 16.0f;
break;
case hui::ui::FontRole::mono:
path = fonts + "DejaVuSansMono.ttf";
size = 15.0f;
break;
default:
path = fonts + "Inter-SemiBold.ttf";
size = 16.0f;
break;
}
return true;
}