2023-08-16 14:13:14 -04:00
|
|
|
#define SATDUMP_DLL_EXPORT 1
|
|
|
|
|
|
2021-02-17 23:21:59 +01:00
|
|
|
#include "style.h"
|
2025-04-27 12:24:09 +02:00
|
|
|
#include "backend.h"
|
|
|
|
|
#include "config.h"
|
2026-02-08 23:13:49 +01:00
|
|
|
#include "core/resources.h"
|
2021-02-17 23:21:59 +01:00
|
|
|
#include "imgui/imgui.h"
|
|
|
|
|
#include "imgui/imgui_internal.h"
|
2023-02-26 01:12:02 +00:00
|
|
|
#include "logger.h"
|
2025-04-27 12:24:09 +02:00
|
|
|
#include "nlohmann/json_utils.h"
|
|
|
|
|
#include <filesystem>
|
2021-02-17 23:21:59 +01:00
|
|
|
|
2023-09-03 21:53:04 -04:00
|
|
|
#ifdef __APPLE__
|
|
|
|
|
#include <CoreGraphics/CGDirectDisplay.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2024-10-15 21:59:48 -04:00
|
|
|
SATDUMP_DLL float ui_scale = 1; // UI Scaling factor, set to 1 (no scaling) by default
|
|
|
|
|
SATDUMP_DLL int demod_constellation_size = 200; // Demodulator constellation size
|
|
|
|
|
|
2021-06-12 21:14:32 +02:00
|
|
|
namespace style
|
|
|
|
|
{
|
2024-01-21 14:57:41 -05:00
|
|
|
SATDUMP_DLL Theme theme;
|
2023-08-16 14:13:14 -04:00
|
|
|
SATDUMP_DLL ImFont *baseFont;
|
|
|
|
|
SATDUMP_DLL ImFont *bigFont;
|
2025-02-07 22:57:27 +01:00
|
|
|
// SATDUMP_DLL ImFont *hugeFont;
|
2021-06-12 21:14:32 +02:00
|
|
|
|
2024-01-22 23:39:05 -05:00
|
|
|
void hexToImVec4(std::string color_hex, ImVec4 *this_color)
|
2021-06-12 21:14:32 +02:00
|
|
|
{
|
2025-04-27 12:24:09 +02:00
|
|
|
color_hex.erase(std::remove_if(color_hex.begin(), color_hex.end(), [&](const char c) { return !std::isxdigit(c); }), color_hex.end());
|
2024-01-22 23:39:05 -05:00
|
|
|
if (color_hex.size() != 8)
|
2024-01-22 23:56:54 -05:00
|
|
|
{
|
|
|
|
|
logger->debug("Invalid color code %s", color_hex.c_str());
|
2024-01-22 23:39:05 -05:00
|
|
|
return;
|
2024-01-22 23:56:54 -05:00
|
|
|
}
|
2024-01-22 23:39:05 -05:00
|
|
|
|
|
|
|
|
this_color->x = (float)std::stoi(color_hex.substr(0, 2), 0, 16) / 255.0f;
|
|
|
|
|
this_color->y = (float)std::stoi(color_hex.substr(2, 2), 0, 16) / 255.0f;
|
|
|
|
|
this_color->z = (float)std::stoi(color_hex.substr(4, 2), 0, 16) / 255.0f;
|
|
|
|
|
this_color->w = (float)std::stoi(color_hex.substr(6, 2), 0, 16) / 255.0f;
|
2021-06-12 21:14:32 +02:00
|
|
|
}
|
|
|
|
|
|
2024-01-22 23:39:05 -05:00
|
|
|
void setStyle()
|
2021-06-12 21:14:32 +02:00
|
|
|
{
|
2024-01-22 23:39:05 -05:00
|
|
|
// Set standard theme info
|
2025-06-08 16:57:37 +02:00
|
|
|
ui_scale = backend::device_scale * satdump::satdump_cfg.main_cfg["user_interface"]["manual_dpi_scaling"]["value"].get<float>();
|
2026-02-08 23:13:49 +01:00
|
|
|
if (ui_scale <= 0)
|
|
|
|
|
ui_scale = 1; // Avoid having ImGui crash...
|
2024-01-22 23:39:05 -05:00
|
|
|
ImGuiStyle &style = ImGui::GetStyle();
|
|
|
|
|
style = ImGuiStyle();
|
|
|
|
|
theme = Theme();
|
|
|
|
|
|
|
|
|
|
// Load Theme File
|
|
|
|
|
nlohmann::json data;
|
|
|
|
|
try
|
|
|
|
|
{
|
2025-06-08 16:57:37 +02:00
|
|
|
std::string selected_theme = satdump::satdump_cfg.main_cfg["user_interface"]["theme"]["value"];
|
2024-01-23 15:02:53 -05:00
|
|
|
std::string theme_path;
|
2025-02-07 22:57:27 +01:00
|
|
|
if (resources::resourceExists("themes/" + selected_theme + ".json"))
|
2024-01-23 15:02:53 -05:00
|
|
|
theme_path = "themes/" + selected_theme + ".json";
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
logger->warn("Failed to load theme \"%s\". Will fall back to Dark", selected_theme.c_str());
|
2025-06-08 16:57:37 +02:00
|
|
|
satdump::satdump_cfg.main_cfg["user_interface"]["theme"]["value"] = selected_theme = "Dark";
|
|
|
|
|
satdump::satdump_cfg.saveUser();
|
2024-01-23 15:02:53 -05:00
|
|
|
}
|
|
|
|
|
|
2024-01-22 23:39:05 -05:00
|
|
|
std::ifstream file(resources::getResourcePath("themes/" + selected_theme + ".json"));
|
|
|
|
|
file >> data;
|
|
|
|
|
file.close();
|
|
|
|
|
}
|
2025-02-07 22:57:27 +01:00
|
|
|
catch (std::exception &)
|
2024-01-22 23:39:05 -05:00
|
|
|
{
|
2024-01-23 15:02:53 -05:00
|
|
|
logger->error("Failed to load any theme! Your SatDump installation may be missing critical files.");
|
2024-01-22 23:39:05 -05:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set base theme
|
|
|
|
|
bool light_mode = getValueOrDefault(data["light"], false);
|
|
|
|
|
if (light_mode)
|
|
|
|
|
ImGui::StyleColorsLight();
|
|
|
|
|
else
|
|
|
|
|
ImGui::StyleColorsDark();
|
|
|
|
|
|
2024-01-23 15:02:53 -05:00
|
|
|
// Set font
|
|
|
|
|
if (data.contains("font") && data["font"].is_string())
|
|
|
|
|
{
|
|
|
|
|
std::string font = data["font"];
|
|
|
|
|
if (resources::resourceExists("fonts/" + font + ".ttf"))
|
|
|
|
|
theme.font = font;
|
|
|
|
|
else
|
|
|
|
|
logger->debug("Specified font \"%s\" not found. Falling back to default", font.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set font size
|
|
|
|
|
if (data.contains("font_size") && data["font_size"].is_number() && data["font_size"].get<float>() > 0)
|
|
|
|
|
theme.font_size = data["font_size"];
|
|
|
|
|
|
2024-01-22 23:39:05 -05:00
|
|
|
// ImGui sizes
|
|
|
|
|
if (data.contains("ImGuiStyle") && data["ImGuiStyle"].is_object())
|
|
|
|
|
{
|
2025-04-27 12:24:09 +02:00
|
|
|
const std::map<std::string, float ImGuiStyle::*> style_map = {{"Alpha", &ImGuiStyle::Alpha},
|
|
|
|
|
{"DisabledAlpha", &ImGuiStyle::DisabledAlpha},
|
|
|
|
|
{"WindowRounding", &ImGuiStyle::WindowRounding},
|
|
|
|
|
{"WindowBorderSize", &ImGuiStyle::WindowBorderSize},
|
|
|
|
|
{"ChildRounding", &ImGuiStyle::ChildRounding},
|
|
|
|
|
{"ChildBorderSize", &ImGuiStyle::ChildBorderSize},
|
|
|
|
|
{"PopupRounding", &ImGuiStyle::PopupRounding},
|
|
|
|
|
{"PopupBorderSize", &ImGuiStyle::PopupBorderSize},
|
|
|
|
|
{"FrameRounding", &ImGuiStyle::FrameRounding},
|
|
|
|
|
{"FrameBorderSize", &ImGuiStyle::FrameBorderSize},
|
|
|
|
|
{"IndentSpacing", &ImGuiStyle::IndentSpacing},
|
|
|
|
|
{"LogSliderDeadzone", &ImGuiStyle::LogSliderDeadzone},
|
|
|
|
|
{"ColumnsMinSpacing", &ImGuiStyle::ColumnsMinSpacing},
|
|
|
|
|
{"ScrollbarSize", &ImGuiStyle::ScrollbarSize},
|
|
|
|
|
{"ScrollbarRounding", &ImGuiStyle::ScrollbarRounding},
|
|
|
|
|
{"GrabMinSize", &ImGuiStyle::GrabMinSize},
|
|
|
|
|
{"GrabRounding", &ImGuiStyle::GrabRounding},
|
|
|
|
|
{"TabRounding", &ImGuiStyle::TabRounding},
|
|
|
|
|
{"TabBorderSize", &ImGuiStyle::TabBorderSize},
|
|
|
|
|
{"TabBarBorderSize", &ImGuiStyle::TabBarBorderSize},
|
|
|
|
|
{"SeparatorTextBorderSize", &ImGuiStyle::SeparatorTextBorderSize}};
|
2024-01-22 23:39:05 -05:00
|
|
|
|
2025-02-07 22:57:27 +01:00
|
|
|
for (auto &style_item : data["ImGuiStyle"].items())
|
2024-01-22 23:39:05 -05:00
|
|
|
{
|
|
|
|
|
if (!style_item.value().is_number_float())
|
|
|
|
|
{
|
|
|
|
|
logger->debug("Invalid theme value for %s", style_item.key().c_str());
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::map<std::string, float ImGuiStyle::*>::const_iterator style_pos = style_map.find(style_item.key());
|
|
|
|
|
if (style_pos != style_map.end())
|
|
|
|
|
style.*(style_pos->second) = style_item.value();
|
|
|
|
|
else
|
|
|
|
|
logger->debug("Invalid theme attribute: %s", style_item.key().c_str());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
style.ScaleAllSizes(ui_scale);
|
|
|
|
|
|
|
|
|
|
// Built-in ImGui colors
|
|
|
|
|
if (data.contains("ImGuiColors") && data["ImGuiColors"].is_object())
|
|
|
|
|
{
|
|
|
|
|
const std::map<std::string, ImGuiCol> color_map = {
|
|
|
|
|
{"Text", ImGuiCol_Text},
|
|
|
|
|
{"TextDisabled", ImGuiCol_TextDisabled},
|
|
|
|
|
{"WindowBg", ImGuiCol_WindowBg},
|
|
|
|
|
{"ChildBg", ImGuiCol_ChildBg},
|
|
|
|
|
{"PopupBg", ImGuiCol_PopupBg},
|
|
|
|
|
{"Border", ImGuiCol_Border},
|
|
|
|
|
{"BorderShadow", ImGuiCol_BorderShadow},
|
|
|
|
|
{"FrameBg", ImGuiCol_FrameBg},
|
|
|
|
|
{"FrameBgHovered", ImGuiCol_FrameBgHovered},
|
|
|
|
|
{"FrameBgActive", ImGuiCol_FrameBgActive},
|
|
|
|
|
{"TitleBg", ImGuiCol_TitleBg},
|
|
|
|
|
{"TitleBgActive", ImGuiCol_TitleBgActive},
|
|
|
|
|
{"TitleBgCollapsed", ImGuiCol_TitleBgCollapsed},
|
|
|
|
|
{"MenuBarBg", ImGuiCol_MenuBarBg},
|
|
|
|
|
{"ScrollbarBg", ImGuiCol_ScrollbarBg},
|
|
|
|
|
{"ScrollbarGrab", ImGuiCol_ScrollbarGrab},
|
|
|
|
|
{"ScrollbarGrabHovered", ImGuiCol_ScrollbarGrabHovered},
|
|
|
|
|
{"ScrollbarGrabActive", ImGuiCol_ScrollbarGrabActive},
|
|
|
|
|
{"CheckMark", ImGuiCol_CheckMark},
|
|
|
|
|
{"SliderGrab", ImGuiCol_SliderGrab},
|
|
|
|
|
{"SliderGrabActive", ImGuiCol_SliderGrabActive},
|
|
|
|
|
{"Button", ImGuiCol_Button},
|
|
|
|
|
{"ButtonHovered", ImGuiCol_ButtonHovered},
|
|
|
|
|
{"ButtonActive", ImGuiCol_ButtonActive},
|
|
|
|
|
{"Header", ImGuiCol_Header},
|
|
|
|
|
{"HeaderHovered", ImGuiCol_HeaderHovered},
|
|
|
|
|
{"HeaderActive", ImGuiCol_HeaderActive},
|
|
|
|
|
{"Separator", ImGuiCol_Separator},
|
|
|
|
|
{"SeparatorHovered", ImGuiCol_SeparatorHovered},
|
|
|
|
|
{"SeparatorActive", ImGuiCol_SeparatorActive},
|
|
|
|
|
{"ResizeGrip", ImGuiCol_ResizeGrip},
|
|
|
|
|
{"ResizeGripHovered", ImGuiCol_ResizeGripHovered},
|
|
|
|
|
{"ResizeGripActive", ImGuiCol_ResizeGripActive},
|
|
|
|
|
{"Tab", ImGuiCol_Tab},
|
|
|
|
|
{"TabHovered", ImGuiCol_TabHovered},
|
|
|
|
|
{"TabActive", ImGuiCol_TabActive},
|
|
|
|
|
{"TabUnfocused", ImGuiCol_TabUnfocused},
|
|
|
|
|
{"TabUnfocusedActive", ImGuiCol_TabUnfocusedActive},
|
|
|
|
|
{"PlotLines", ImGuiCol_PlotLines},
|
|
|
|
|
{"PlotLinesHovered", ImGuiCol_PlotLinesHovered},
|
|
|
|
|
{"PlotHistogram", ImGuiCol_PlotHistogram},
|
|
|
|
|
{"PlotHistogramHovered", ImGuiCol_PlotHistogramHovered},
|
|
|
|
|
{"TextSelectedBg", ImGuiCol_TextSelectedBg},
|
|
|
|
|
{"DragDropTarget", ImGuiCol_DragDropTarget},
|
|
|
|
|
{"NavHighlight", ImGuiCol_NavHighlight},
|
|
|
|
|
{"NavWindowingHighlight", ImGuiCol_NavWindowingHighlight},
|
|
|
|
|
{"NavWindowingDimBg", ImGuiCol_NavWindowingDimBg},
|
2024-01-23 10:01:40 -05:00
|
|
|
{"ModalWindowDimBg", ImGuiCol_ModalWindowDimBg},
|
|
|
|
|
{"TableHeaderBg", ImGuiCol_TableHeaderBg},
|
|
|
|
|
{"TableBorderStrong", ImGuiCol_TableBorderStrong},
|
|
|
|
|
{"TableBorderLight", ImGuiCol_TableBorderLight},
|
|
|
|
|
{"TableRowBg", ImGuiCol_TableRowBg},
|
|
|
|
|
{"TableRowBgAlt", ImGuiCol_TableRowBgAlt},
|
2024-01-22 23:39:05 -05:00
|
|
|
};
|
|
|
|
|
|
2025-02-07 22:57:27 +01:00
|
|
|
for (auto &color : data["ImGuiColors"].items())
|
2024-01-22 23:39:05 -05:00
|
|
|
{
|
|
|
|
|
if (!color.value().is_string())
|
|
|
|
|
{
|
|
|
|
|
logger->debug("Invalid theme color for %s", color.key().c_str());
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::map<std::string, ImGuiCol>::const_iterator color_pos = color_map.find(color.key());
|
|
|
|
|
if (color_pos != color_map.end())
|
|
|
|
|
hexToImVec4(color.value(), &style.Colors[color_pos->second]);
|
|
|
|
|
else
|
|
|
|
|
logger->debug("Invalid theme color: %s", color.key().c_str());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Custom SatDump Colors
|
|
|
|
|
if (data.contains("SatDumpColors") && data["SatDumpColors"].is_object())
|
|
|
|
|
{
|
2025-04-27 12:24:09 +02:00
|
|
|
const std::map<std::string, ImColor Theme::*> custom_color_map = {{"red", &Theme::red},
|
|
|
|
|
{"green", &Theme::green},
|
|
|
|
|
{"blue", &Theme::blue},
|
|
|
|
|
{"yellow", &Theme::yellow},
|
|
|
|
|
{"orange", &Theme::orange},
|
|
|
|
|
{"cyan", &Theme::cyan},
|
|
|
|
|
{"fuchsia", &Theme::fuchsia},
|
|
|
|
|
{"magenta", &Theme::magenta},
|
|
|
|
|
{"lavender", &Theme::lavender},
|
|
|
|
|
{"light_green", &Theme::light_green},
|
|
|
|
|
{"light_cyan", &Theme::light_cyan},
|
|
|
|
|
{"constellation", &Theme::constellation},
|
|
|
|
|
{"plot_bg", &Theme::plot_bg},
|
|
|
|
|
{"fft_graduations", &Theme::fft_graduations},
|
|
|
|
|
{"widget_bg", &Theme::widget_bg},
|
|
|
|
|
{"frame_bg", &Theme::frame_bg},
|
|
|
|
|
{"overlay_bg", &Theme::overlay_bg},
|
|
|
|
|
{"notification_bg", &Theme::notification_bg},
|
|
|
|
|
{"freq_highlight", &Theme::freq_highlight},
|
|
|
|
|
{"treeview_icon", &Theme::treeview_icon}};
|
2024-01-22 23:39:05 -05:00
|
|
|
|
2025-02-07 22:57:27 +01:00
|
|
|
for (auto &color : data["SatDumpColors"].items())
|
2024-01-22 23:39:05 -05:00
|
|
|
{
|
|
|
|
|
if (!color.value().is_string())
|
|
|
|
|
{
|
|
|
|
|
logger->debug("Invalid theme color for %s", color.key().c_str());
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::map<std::string, ImColor Theme::*>::const_iterator color_pos = custom_color_map.find(color.key());
|
|
|
|
|
if (color_pos != custom_color_map.end())
|
|
|
|
|
hexToImVec4(color.value(), &(theme.*(color_pos->second)).Value);
|
|
|
|
|
else
|
|
|
|
|
logger->debug("Invalid theme color: %s", color.key().c_str());
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-02-17 23:21:59 +01:00
|
|
|
}
|
|
|
|
|
|
2021-06-12 21:14:32 +02:00
|
|
|
void beginDisabled()
|
|
|
|
|
{
|
2024-01-19 15:54:21 -05:00
|
|
|
ImVec4 *colors = ImGui::GetStyle().Colors;
|
|
|
|
|
ImVec4 frame_bg = colors[ImGuiCol_FrameBg];
|
|
|
|
|
ImVec4 button = colors[ImGuiCol_Button];
|
2024-01-23 10:01:40 -05:00
|
|
|
frame_bg.w *= 0.33f;
|
|
|
|
|
button.w *= 0.33f;
|
2024-01-19 15:54:21 -05:00
|
|
|
|
2021-02-17 23:21:59 +01:00
|
|
|
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
2024-01-19 15:54:21 -05:00
|
|
|
ImGui::PushStyleColor(ImGuiCol_Button, button);
|
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_FrameBg, frame_bg);
|
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_Text, colors[ImGuiCol_TextDisabled]);
|
2021-02-17 23:21:59 +01:00
|
|
|
}
|
|
|
|
|
|
2021-06-12 21:14:32 +02:00
|
|
|
void endDisabled()
|
|
|
|
|
{
|
2021-02-17 23:21:59 +01:00
|
|
|
ImGui::PopItemFlag();
|
|
|
|
|
ImGui::PopStyleColor(3);
|
|
|
|
|
}
|
2022-09-07 18:44:52 +02:00
|
|
|
|
2023-08-23 15:45:10 -04:00
|
|
|
void setFonts(float dpi_scaling)
|
2022-09-08 21:51:50 +02:00
|
|
|
{
|
2023-09-03 21:53:04 -04:00
|
|
|
ImGuiIO &io = ImGui::GetIO();
|
|
|
|
|
io.Fonts->Clear();
|
2025-02-07 22:57:27 +01:00
|
|
|
const ImWchar def[] = {0x20, 0x2300, 0}; // default range
|
2025-04-27 12:24:09 +02:00
|
|
|
const ImWchar list[9][3] = {
|
|
|
|
|
{0xf000, 0xf0ff, 0}, //
|
|
|
|
|
{0xf400, 0xf4ff, 0}, //
|
|
|
|
|
{0xf800, 0xf8ff, 0}, //
|
|
|
|
|
{0xfc00, 0xfcff, 0}, //
|
|
|
|
|
{0xea00, 0xeaff, 0}, //
|
|
|
|
|
{0xf200, 0xf2ff, 0}, //
|
|
|
|
|
{0x2000, 0x20ff, 0}, //
|
|
|
|
|
{0xf500, 0xfd46, 0}, //
|
|
|
|
|
{0xea60, 0xebeb, 0}, //
|
2025-02-07 22:57:27 +01:00
|
|
|
};
|
2022-09-13 23:40:18 +02:00
|
|
|
static ImFontConfig config;
|
2023-09-03 21:53:04 -04:00
|
|
|
float macos_fbs = macos_framebuffer_scale();
|
|
|
|
|
float font_scaling = dpi_scaling * macos_fbs;
|
|
|
|
|
|
2024-01-23 15:02:53 -05:00
|
|
|
baseFont = io.Fonts->AddFontFromFileTTF(resources::getResourcePath("fonts/" + theme.font + ".ttf").c_str(), theme.font_size * font_scaling, &config, def);
|
2022-09-17 17:20:24 +02:00
|
|
|
config.MergeMode = true;
|
|
|
|
|
|
2025-04-27 12:24:09 +02:00
|
|
|
for (int i = 0; i < 9; i++)
|
2024-01-23 15:02:53 -05:00
|
|
|
baseFont = io.Fonts->AddFontFromFileTTF(resources::getResourcePath("fonts/font.ttf").c_str(), theme.font_size * font_scaling, &config, list[i]);
|
2023-08-16 21:35:34 -04:00
|
|
|
config.MergeMode = false;
|
2023-12-17 23:17:40 -05:00
|
|
|
|
2025-02-07 22:57:27 +01:00
|
|
|
bigFont = io.Fonts->AddFontFromFileTTF(resources::getResourcePath("fonts/" + theme.font + ".ttf").c_str(), 45.0f * font_scaling); //, &config, ranges);
|
|
|
|
|
// hugeFont = io.Fonts->AddFontFromFileTTF(resources::getResourcePath("fonts/" + theme.font + ".ttf").c_str(), 128.0f * font_scaling); //, &config, ranges);
|
2023-09-03 21:53:04 -04:00
|
|
|
io.Fonts->Build();
|
|
|
|
|
io.FontGlobalScale = 1 / macos_fbs;
|
2024-01-21 17:30:00 -05:00
|
|
|
|
|
|
|
|
backend::rebuildFonts();
|
2023-09-03 21:53:04 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float macos_framebuffer_scale()
|
|
|
|
|
{
|
|
|
|
|
#ifdef __APPLE__
|
|
|
|
|
CGDirectDisplayID display_id = CGMainDisplayID();
|
|
|
|
|
CGDisplayModeRef display_mode = CGDisplayCopyDisplayMode(display_id);
|
|
|
|
|
float return_value = (float)CGDisplayModeGetPixelWidth(display_mode) / (float)CGDisplayPixelsWide(display_id);
|
|
|
|
|
CGDisplayModeRelease(display_mode);
|
|
|
|
|
return return_value;
|
|
|
|
|
#else
|
|
|
|
|
return 1.0f;
|
|
|
|
|
#endif
|
2022-09-07 18:44:52 +02:00
|
|
|
}
|
2025-04-27 12:24:09 +02:00
|
|
|
} // namespace style
|