feat: Added font picker to the settings (#1570)
This commit is contained in:
parent
8bf7aa9ceb
commit
ec69849749
@ -141,7 +141,7 @@ namespace hex {
|
||||
|
||||
[[nodiscard]] bool isChecked() const { return m_value; }
|
||||
|
||||
private:
|
||||
protected:
|
||||
bool m_value;
|
||||
};
|
||||
|
||||
@ -155,7 +155,7 @@ namespace hex {
|
||||
|
||||
[[nodiscard]] i32 getValue() const { return m_value; }
|
||||
|
||||
private:
|
||||
protected:
|
||||
int m_value;
|
||||
i32 m_min, m_max;
|
||||
};
|
||||
@ -170,7 +170,7 @@ namespace hex {
|
||||
|
||||
[[nodiscard]] float getValue() const { return m_value; }
|
||||
|
||||
private:
|
||||
protected:
|
||||
float m_value;
|
||||
float m_min, m_max;
|
||||
};
|
||||
@ -186,7 +186,7 @@ namespace hex {
|
||||
|
||||
[[nodiscard]] ImColor getColor() const;
|
||||
|
||||
private:
|
||||
protected:
|
||||
std::array<float, 4> m_value{};
|
||||
};
|
||||
|
||||
@ -202,7 +202,7 @@ namespace hex {
|
||||
[[nodiscard]]
|
||||
const nlohmann::json& getValue() const;
|
||||
|
||||
private:
|
||||
protected:
|
||||
std::vector<std::string> m_items;
|
||||
std::vector<nlohmann::json> m_settingsValues;
|
||||
nlohmann::json m_defaultItem;
|
||||
@ -222,7 +222,7 @@ namespace hex {
|
||||
[[nodiscard]]
|
||||
const std::string& getValue() const { return m_value; }
|
||||
|
||||
private:
|
||||
protected:
|
||||
std::string m_value;
|
||||
};
|
||||
|
||||
@ -233,12 +233,12 @@ namespace hex {
|
||||
void load(const nlohmann::json &data) override;
|
||||
nlohmann::json store() override;
|
||||
|
||||
[[nodiscard]] std::fs::path getPath() const {
|
||||
return m_value;
|
||||
[[nodiscard]] const std::fs::path& getPath() const {
|
||||
return m_path;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_value;
|
||||
protected:
|
||||
std::fs::path m_path;
|
||||
};
|
||||
|
||||
class Label : public Widget {
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <concepts>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
@ -76,6 +77,9 @@ namespace hex {
|
||||
int executeCommand(const std::string &command);
|
||||
void openWebpage(std::string url);
|
||||
|
||||
extern "C" void registerFont(const char *fontName, const char *fontPath);
|
||||
const std::map<std::fs::path, std::string>& getFonts();
|
||||
|
||||
[[nodiscard]] std::string encodeByteString(const std::vector<u8> &bytes);
|
||||
[[nodiscard]] std::vector<u8> decodeByteString(const std::string &string);
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
void setupMacosWindowStyle(GLFWwindow *window, bool borderlessWindowMode);
|
||||
|
||||
void enumerateFontsMacos();
|
||||
}
|
||||
|
||||
#endif
|
@ -413,16 +413,18 @@ namespace hex {
|
||||
|
||||
bool FilePicker::draw(const std::string &name) {
|
||||
bool changed = false;
|
||||
if (ImGui::InputText("##font_path", m_value)) {
|
||||
|
||||
auto pathString = wolv::util::toUTF8String(m_path);
|
||||
if (ImGui::InputText("##font_path", pathString)) {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGuiExt::IconButton("...", ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
|
||||
return fs::openFileBrowser(fs::DialogMode::Open, { { "TTF Font", "ttf" }, { "OTF Font", "otf" } },
|
||||
changed = fs::openFileBrowser(fs::DialogMode::Open, { { "TTF Font", "ttf" }, { "OTF Font", "otf" } },
|
||||
[&](const std::fs::path &path) {
|
||||
m_value = wolv::util::toUTF8String(path);
|
||||
pathString = wolv::util::toUTF8String(path);
|
||||
});
|
||||
}
|
||||
|
||||
@ -430,19 +432,23 @@ namespace hex {
|
||||
|
||||
ImGuiExt::TextFormatted("{}", name);
|
||||
|
||||
if (changed) {
|
||||
m_path = pathString;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
void FilePicker::load(const nlohmann::json &data) {
|
||||
if (data.is_string()) {
|
||||
m_value = data.get<std::string>();
|
||||
m_path = data.get<std::fs::path>();
|
||||
} else {
|
||||
log::warn("Invalid data type loaded from settings for file picker!");
|
||||
}
|
||||
}
|
||||
|
||||
nlohmann::json FilePicker::store() {
|
||||
return m_value;
|
||||
return m_path;
|
||||
}
|
||||
|
||||
bool Label::draw(const std::string& name) {
|
||||
|
@ -677,14 +677,23 @@ namespace hex {
|
||||
return value;
|
||||
}
|
||||
|
||||
static std::optional<std::fs::path> fileToOpen;
|
||||
static std::optional<std::fs::path> s_fileToOpen;
|
||||
extern "C" void openFile(const char *path) {
|
||||
log::info("Opening file: {0}", path);
|
||||
fileToOpen = path;
|
||||
s_fileToOpen = path;
|
||||
}
|
||||
|
||||
std::optional<std::fs::path> getInitialFilePath() {
|
||||
return fileToOpen;
|
||||
return s_fileToOpen;
|
||||
}
|
||||
|
||||
static std::map<std::fs::path, std::string> s_fonts;
|
||||
extern "C" void registerFont(const char *fontName, const char *fontPath) {
|
||||
s_fonts[fontPath] = fontName;
|
||||
}
|
||||
|
||||
const std::map<std::fs::path, std::string>& getFonts() {
|
||||
return s_fonts;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -3,8 +3,9 @@
|
||||
#include <CoreFoundation/CFBundle.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <AppKit/NSScreen.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <CoreText/CoreText.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@ -23,6 +24,7 @@
|
||||
}
|
||||
|
||||
void openFile(const char *path);
|
||||
void registerFont(const char *fontName, const char *fontPath);
|
||||
|
||||
void openWebpageMacos(const char *url) {
|
||||
CFURLRef urlRef = CFURLCreateWithBytes(NULL, (uint8_t*)(url), strlen(url), kCFStringEncodingASCII, NULL);
|
||||
@ -64,6 +66,28 @@
|
||||
return (cocoaWindow.styleMask & NSWindowStyleMaskFullScreen) == NSWindowStyleMaskFullScreen;
|
||||
}
|
||||
|
||||
void enumerateFontsMacos(void) {
|
||||
CFArrayRef fontDescriptors = CTFontManagerCopyAvailableFontFamilyNames();
|
||||
CFIndex count = CFArrayGetCount(fontDescriptors);
|
||||
|
||||
for (CFIndex i = 0; i < count; i++) {
|
||||
CFStringRef fontName = (CFStringRef)CFArrayGetValueAtIndex(fontDescriptors, i);
|
||||
|
||||
// Get font path
|
||||
CFDictionaryRef attributes = (__bridge CFDictionaryRef)@{ (__bridge NSString *)kCTFontNameAttribute : (__bridge NSString *)fontName };
|
||||
CTFontDescriptorRef descriptor = CTFontDescriptorCreateWithAttributes(attributes);
|
||||
CFURLRef fontURL = CTFontDescriptorCopyAttribute(descriptor, kCTFontURLAttribute);
|
||||
CFStringRef fontPath = CFURLCopyFileSystemPath(fontURL, kCFURLPOSIXPathStyle);
|
||||
|
||||
registerFont([(__bridge NSString *)fontName UTF8String], [(__bridge NSString *)fontPath UTF8String]);
|
||||
|
||||
CFRelease(descriptor);
|
||||
CFRelease(fontURL);
|
||||
}
|
||||
|
||||
CFRelease(fontDescriptors);
|
||||
}
|
||||
|
||||
@interface HexDocument : NSDocument
|
||||
|
||||
@end
|
||||
|
@ -47,6 +47,31 @@ namespace hex {
|
||||
} // Hopefully one of these commands is installed
|
||||
}
|
||||
|
||||
void enumerateFonts() {
|
||||
const std::array FontDirectories = {
|
||||
"/usr/share/fonts",
|
||||
"/usr/local/share/fonts",
|
||||
"~/.fonts",
|
||||
"~/.local/share/fonts"
|
||||
};
|
||||
|
||||
for (const auto &directory : FontDirectories) {
|
||||
if (!std::fs::exists(directory))
|
||||
continue;
|
||||
|
||||
for (const auto &entry : std::fs::recursive_directory_iterator(directory)) {
|
||||
if (!entry.exists())
|
||||
continue;
|
||||
if (!entry.is_regular_file())
|
||||
continue;
|
||||
if (entry.path().extension() != ".ttf" && entry.path().extension() != ".otf")
|
||||
continue;
|
||||
|
||||
registerFont(entry.path().stem().c_str(), entry.path().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Window::initNative() {
|
||||
log::impl::enableColorPrinting();
|
||||
|
||||
@ -65,6 +90,8 @@ namespace hex {
|
||||
if (!isatty(STDOUT_FILENO)) {
|
||||
log::impl::redirectToFile();
|
||||
}
|
||||
|
||||
enumerateFonts();
|
||||
}
|
||||
|
||||
void Window::setupNativeWindow() {
|
||||
|
@ -38,6 +38,8 @@ namespace hex {
|
||||
if (!isatty(STDOUT_FILENO)) {
|
||||
log::impl::redirectToFile();
|
||||
}
|
||||
|
||||
enumerateFontsMacos();
|
||||
}
|
||||
|
||||
void Window::setupNativeWindow() {
|
||||
|
@ -268,6 +268,46 @@ namespace hex {
|
||||
dup2(unboundFd, stdFileDescriptor);
|
||||
}
|
||||
|
||||
void enumerateFonts() {
|
||||
constexpr static auto FontRegistryPath = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
|
||||
|
||||
static const std::array RegistryLocations = {
|
||||
HKEY_LOCAL_MACHINE,
|
||||
HKEY_CURRENT_USER
|
||||
};
|
||||
|
||||
for (const auto location : RegistryLocations) {
|
||||
HKEY key;
|
||||
if (RegOpenKeyExW(location, FontRegistryPath, 0, KEY_READ, &key) != ERROR_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DWORD index = 0;
|
||||
std::wstring valueName(0xFFF, L'\0');
|
||||
DWORD valueNameSize = valueName.size() * sizeof(wchar_t);
|
||||
std::wstring valueData(0xFFF, L'\0');
|
||||
DWORD valueDataSize = valueData.size() * sizeof(wchar_t);
|
||||
DWORD valueType;
|
||||
|
||||
while (RegEnumValueW(key, index, valueName.data(), &valueNameSize, nullptr, &valueType, reinterpret_cast<BYTE *>(valueData.data()), &valueDataSize) == ERROR_SUCCESS) {
|
||||
if (valueType == REG_SZ) {
|
||||
auto fontName = hex::utf16ToUtf8(valueName.c_str());
|
||||
auto fontPath = std::fs::path(valueData);
|
||||
if (fontPath.is_relative())
|
||||
fontPath = std::fs::path("C:\\Windows\\Fonts") / fontPath;
|
||||
|
||||
registerFont(fontName.c_str(), wolv::util::toUTF8String(fontPath).c_str());
|
||||
}
|
||||
|
||||
valueNameSize = valueName.size();
|
||||
valueDataSize = valueData.size();
|
||||
index++;
|
||||
}
|
||||
|
||||
RegCloseKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Window::initNative() {
|
||||
if (ImHexApi::System::isDebugBuild()) {
|
||||
@ -301,6 +341,8 @@ namespace hex {
|
||||
if (std::fs::exists(path))
|
||||
AddDllDirectory(path.c_str());
|
||||
}
|
||||
|
||||
enumerateFonts();
|
||||
}
|
||||
|
||||
class DropManager : public IDropTarget {
|
||||
@ -486,7 +528,6 @@ namespace hex {
|
||||
});
|
||||
|
||||
ImGui::GetIO().ConfigDebugIsDebuggerPresent = ::IsDebuggerPresent();
|
||||
|
||||
}
|
||||
|
||||
void Window::beginNativeWindowFrame() {
|
||||
|
@ -603,6 +603,50 @@ namespace hex::plugin::builtin {
|
||||
i32 m_currIndex = 0;
|
||||
};
|
||||
|
||||
class FontFilePicker : public ContentRegistry::Settings::Widgets::FilePicker {
|
||||
public:
|
||||
bool draw(const std::string &name) {
|
||||
bool changed = false;
|
||||
|
||||
const auto &fonts = hex::getFonts();
|
||||
|
||||
bool customFont = false;
|
||||
std::string pathPreview = "";
|
||||
if (m_path.empty()) {
|
||||
pathPreview = "Default Font";
|
||||
} else if (fonts.contains(m_path)) {
|
||||
pathPreview = fonts.at(m_path);
|
||||
} else {
|
||||
pathPreview = wolv::util::toUTF8String(m_path.filename());
|
||||
customFont = true;
|
||||
}
|
||||
|
||||
if (ImGui::BeginCombo(name.c_str(), pathPreview.c_str())) {
|
||||
if (ImGui::Selectable("Default Font", m_path.empty())) {
|
||||
m_path.clear();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (ImGui::Selectable("Custom Font", customFont)) {
|
||||
changed = fs::openFileBrowser(fs::DialogMode::Open, { { "TTF Font", "ttf" }, { "OTF Font", "otf" } }, [this](const std::fs::path &path) {
|
||||
m_path = path;
|
||||
});
|
||||
}
|
||||
|
||||
for (const auto &[path, fontName] : fonts) {
|
||||
if (ImGui::Selectable(fontName.c_str(), m_path == path)) {
|
||||
m_path = path;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
bool getDefaultBorderlessWindowMode() {
|
||||
bool result = false;
|
||||
@ -739,7 +783,7 @@ namespace hex::plugin::builtin {
|
||||
return customFontsEnabled.isChecked();
|
||||
};
|
||||
|
||||
auto customFontPathSetting = ContentRegistry::Settings::add<Widgets::FilePicker>("hex.builtin.setting.font", "hex.builtin.setting.font.custom_font", "hex.builtin.setting.font.font_path")
|
||||
auto customFontPathSetting = ContentRegistry::Settings::add<FontFilePicker>("hex.builtin.setting.font", "hex.builtin.setting.font.custom_font", "hex.builtin.setting.font.font_path")
|
||||
.requiresRestart()
|
||||
.setEnabledCallback(customFontsEnabled);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user