mirror of
https://github.com/obsqrbtz/clrsync.git
synced 2026-04-08 20:19:04 +03:00
feat: font selector
This commit is contained in:
@@ -226,3 +226,101 @@ void font_loader::pop_font()
|
||||
{
|
||||
ImGui::PopFont();
|
||||
}
|
||||
|
||||
std::vector<std::string> font_loader::get_system_fonts()
|
||||
{
|
||||
std::vector<std::string> fonts;
|
||||
|
||||
#if defined(_WIN32)
|
||||
auto enumerate_registry_fonts = [&fonts](HKEY root_key, const char* subkey)
|
||||
{
|
||||
HKEY hKey;
|
||||
if (RegOpenKeyExA(root_key, subkey, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
|
||||
return;
|
||||
|
||||
char value_name[512];
|
||||
DWORD value_name_size;
|
||||
DWORD index = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
value_name_size = sizeof(value_name);
|
||||
LONG result = RegEnumValueA(hKey, index++, value_name, &value_name_size, nullptr, nullptr, nullptr, nullptr);
|
||||
|
||||
if (result != ERROR_SUCCESS)
|
||||
break;
|
||||
|
||||
std::string font_name = value_name;
|
||||
size_t pos = font_name.find(" (");
|
||||
if (pos != std::string::npos)
|
||||
font_name = font_name.substr(0, pos);
|
||||
|
||||
if (std::find(fonts.begin(), fonts.end(), font_name) == fonts.end())
|
||||
fonts.push_back(font_name);
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
};
|
||||
|
||||
enumerate_registry_fonts(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts");
|
||||
enumerate_registry_fonts(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts");
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
CTFontCollectionRef collection = CTFontCollectionCreateFromAvailableFonts(nullptr);
|
||||
if (collection)
|
||||
{
|
||||
CFArrayRef fontDescriptors = CTFontCollectionCreateMatchingFontDescriptors(collection);
|
||||
CFRelease(collection);
|
||||
|
||||
if (fontDescriptors)
|
||||
{
|
||||
CFIndex count = CFArrayGetCount(fontDescriptors);
|
||||
for (CFIndex i = 0; i < count; i++)
|
||||
{
|
||||
CTFontDescriptorRef descriptor = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fontDescriptors, i);
|
||||
CFStringRef fontName = (CFStringRef)CTFontDescriptorCopyAttribute(descriptor, kCTFontDisplayNameAttribute);
|
||||
|
||||
if (fontName)
|
||||
{
|
||||
char buffer[256];
|
||||
if (CFStringGetCString(fontName, buffer, sizeof(buffer), kCFStringEncodingUTF8))
|
||||
{
|
||||
std::string font_name = buffer;
|
||||
if (std::find(fonts.begin(), fonts.end(), font_name) == fonts.end())
|
||||
fonts.push_back(font_name);
|
||||
}
|
||||
CFRelease(fontName);
|
||||
}
|
||||
}
|
||||
CFRelease(fontDescriptors);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
FcInit();
|
||||
FcPattern* pattern = FcPatternCreate();
|
||||
FcObjectSet* os = FcObjectSetBuild(FC_FAMILY, nullptr);
|
||||
FcFontSet* fs = FcFontList(nullptr, pattern, os);
|
||||
|
||||
if (fs)
|
||||
{
|
||||
for (int i = 0; i < fs->nfont; i++)
|
||||
{
|
||||
FcChar8* family = nullptr;
|
||||
if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, &family) == FcResultMatch)
|
||||
{
|
||||
std::string font_name = reinterpret_cast<const char*>(family);
|
||||
if (std::find(fonts.begin(), fonts.end(), font_name) == fonts.end())
|
||||
fonts.push_back(font_name);
|
||||
}
|
||||
}
|
||||
FcFontSetDestroy(fs);
|
||||
}
|
||||
|
||||
FcObjectSetDestroy(os);
|
||||
FcPatternDestroy(pattern);
|
||||
#endif
|
||||
|
||||
std::sort(fonts.begin(), fonts.end());
|
||||
return fonts;
|
||||
}
|
||||
|
||||
@@ -10,11 +10,12 @@ class font_loader
|
||||
public:
|
||||
font_loader() = default;
|
||||
|
||||
// Loads system font by name and returns an ImFont* or nullptr.
|
||||
ImFont* load_font(const char* font_name, float size_px);
|
||||
void push_default_font();
|
||||
void pop_font();
|
||||
|
||||
std::vector<std::string> get_system_fonts();
|
||||
|
||||
private:
|
||||
std::string find_font_path(const char* font_name);
|
||||
|
||||
|
||||
@@ -6,11 +6,15 @@
|
||||
#include <cstring>
|
||||
|
||||
settings_window::settings_window()
|
||||
: m_font_size(14)
|
||||
: m_font_size(14), m_selected_font_idx(0)
|
||||
{
|
||||
m_default_theme[0] = '\0';
|
||||
m_palettes_path[0] = '\0';
|
||||
m_font[0] = '\0';
|
||||
|
||||
font_loader loader;
|
||||
m_available_fonts = loader.get_system_fonts();
|
||||
|
||||
load_settings();
|
||||
}
|
||||
|
||||
@@ -51,10 +55,25 @@ void settings_window::render()
|
||||
ImGui::Text("Font:");
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(300.0f);
|
||||
ImGui::InputText("##font", m_font, sizeof(m_font));
|
||||
if (ImGui::BeginCombo("##font", m_font))
|
||||
{
|
||||
for (int i = 0; i < static_cast<int>(m_available_fonts.size()); i++)
|
||||
{
|
||||
bool is_selected = (i == m_selected_font_idx);
|
||||
if (ImGui::Selectable(m_available_fonts[i].c_str(), is_selected))
|
||||
{
|
||||
m_selected_font_idx = i;
|
||||
strncpy(m_font, m_available_fonts[i].c_str(), sizeof(m_font) - 1);
|
||||
m_font[sizeof(m_font) - 1] = '\0';
|
||||
}
|
||||
if (is_selected)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetTooltip("Font");
|
||||
ImGui::SetTooltip("Select font for the application");
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
@@ -134,6 +153,16 @@ void settings_window::load_settings()
|
||||
strncpy(m_font, font.c_str(), sizeof(m_font) - 1);
|
||||
m_font[sizeof(m_font) - 1] = '\0';
|
||||
|
||||
m_selected_font_idx = 0;
|
||||
for (int i = 0; i < static_cast<int>(m_available_fonts.size()); i++)
|
||||
{
|
||||
if (m_available_fonts[i] == font)
|
||||
{
|
||||
m_selected_font_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_font_size = cfg.font_size();
|
||||
|
||||
m_error_message = "";
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define CLRSYNC_GUI_SETTINGS_WINDOW_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class settings_window
|
||||
{
|
||||
@@ -24,6 +25,9 @@ private:
|
||||
char m_font[128];
|
||||
int m_font_size;
|
||||
|
||||
std::vector<std::string> m_available_fonts;
|
||||
int m_selected_font_idx;
|
||||
|
||||
std::string m_error_message;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user