mirror of
https://github.com/obsqrbtz/clrsync.git
synced 2026-04-09 04:29:04 +03:00
feat: font selector
This commit is contained in:
@@ -226,3 +226,101 @@ void font_loader::pop_font()
|
|||||||
{
|
{
|
||||||
ImGui::PopFont();
|
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,10 +10,11 @@ class font_loader
|
|||||||
public:
|
public:
|
||||||
font_loader() = default;
|
font_loader() = default;
|
||||||
|
|
||||||
// Loads system font by name and returns an ImFont* or nullptr.
|
|
||||||
ImFont* load_font(const char* font_name, float size_px);
|
ImFont* load_font(const char* font_name, float size_px);
|
||||||
void push_default_font();
|
void push_default_font();
|
||||||
void pop_font();
|
void pop_font();
|
||||||
|
|
||||||
|
std::vector<std::string> get_system_fonts();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string find_font_path(const char* font_name);
|
std::string find_font_path(const char* font_name);
|
||||||
|
|||||||
@@ -6,11 +6,15 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
settings_window::settings_window()
|
settings_window::settings_window()
|
||||||
: m_font_size(14)
|
: m_font_size(14), m_selected_font_idx(0)
|
||||||
{
|
{
|
||||||
m_default_theme[0] = '\0';
|
m_default_theme[0] = '\0';
|
||||||
m_palettes_path[0] = '\0';
|
m_palettes_path[0] = '\0';
|
||||||
m_font[0] = '\0';
|
m_font[0] = '\0';
|
||||||
|
|
||||||
|
font_loader loader;
|
||||||
|
m_available_fonts = loader.get_system_fonts();
|
||||||
|
|
||||||
load_settings();
|
load_settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,10 +55,25 @@ void settings_window::render()
|
|||||||
ImGui::Text("Font:");
|
ImGui::Text("Font:");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::SetNextItemWidth(300.0f);
|
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())
|
if (ImGui::IsItemHovered())
|
||||||
{
|
{
|
||||||
ImGui::SetTooltip("Font");
|
ImGui::SetTooltip("Select font for the application");
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
@@ -134,6 +153,16 @@ void settings_window::load_settings()
|
|||||||
strncpy(m_font, font.c_str(), sizeof(m_font) - 1);
|
strncpy(m_font, font.c_str(), sizeof(m_font) - 1);
|
||||||
m_font[sizeof(m_font) - 1] = '\0';
|
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_font_size = cfg.font_size();
|
||||||
|
|
||||||
m_error_message = "";
|
m_error_message = "";
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define CLRSYNC_GUI_SETTINGS_WINDOW_HPP
|
#define CLRSYNC_GUI_SETTINGS_WINDOW_HPP
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class settings_window
|
class settings_window
|
||||||
{
|
{
|
||||||
@@ -24,6 +25,9 @@ private:
|
|||||||
char m_font[128];
|
char m_font[128];
|
||||||
int m_font_size;
|
int m_font_size;
|
||||||
|
|
||||||
|
std::vector<std::string> m_available_fonts;
|
||||||
|
int m_selected_font_idx;
|
||||||
|
|
||||||
std::string m_error_message;
|
std::string m_error_message;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user