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; }
|
[[nodiscard]] bool isChecked() const { return m_value; }
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
bool m_value;
|
bool m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ namespace hex {
|
|||||||
|
|
||||||
[[nodiscard]] i32 getValue() const { return m_value; }
|
[[nodiscard]] i32 getValue() const { return m_value; }
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
int m_value;
|
int m_value;
|
||||||
i32 m_min, m_max;
|
i32 m_min, m_max;
|
||||||
};
|
};
|
||||||
@ -170,7 +170,7 @@ namespace hex {
|
|||||||
|
|
||||||
[[nodiscard]] float getValue() const { return m_value; }
|
[[nodiscard]] float getValue() const { return m_value; }
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
float m_value;
|
float m_value;
|
||||||
float m_min, m_max;
|
float m_min, m_max;
|
||||||
};
|
};
|
||||||
@ -186,7 +186,7 @@ namespace hex {
|
|||||||
|
|
||||||
[[nodiscard]] ImColor getColor() const;
|
[[nodiscard]] ImColor getColor() const;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
std::array<float, 4> m_value{};
|
std::array<float, 4> m_value{};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ namespace hex {
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
const nlohmann::json& getValue() const;
|
const nlohmann::json& getValue() const;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
std::vector<std::string> m_items;
|
std::vector<std::string> m_items;
|
||||||
std::vector<nlohmann::json> m_settingsValues;
|
std::vector<nlohmann::json> m_settingsValues;
|
||||||
nlohmann::json m_defaultItem;
|
nlohmann::json m_defaultItem;
|
||||||
@ -222,7 +222,7 @@ namespace hex {
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
const std::string& getValue() const { return m_value; }
|
const std::string& getValue() const { return m_value; }
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
std::string m_value;
|
std::string m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -233,12 +233,12 @@ namespace hex {
|
|||||||
void load(const nlohmann::json &data) override;
|
void load(const nlohmann::json &data) override;
|
||||||
nlohmann::json store() override;
|
nlohmann::json store() override;
|
||||||
|
|
||||||
[[nodiscard]] std::fs::path getPath() const {
|
[[nodiscard]] const std::fs::path& getPath() const {
|
||||||
return m_value;
|
return m_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
std::string m_value;
|
std::fs::path m_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Label : public Widget {
|
class Label : public Widget {
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <concepts>
|
#include <concepts>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -76,6 +77,9 @@ namespace hex {
|
|||||||
int executeCommand(const std::string &command);
|
int executeCommand(const std::string &command);
|
||||||
void openWebpage(std::string url);
|
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::string encodeByteString(const std::vector<u8> &bytes);
|
||||||
[[nodiscard]] std::vector<u8> decodeByteString(const std::string &string);
|
[[nodiscard]] std::vector<u8> decodeByteString(const std::string &string);
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
void setupMacosWindowStyle(GLFWwindow *window, bool borderlessWindowMode);
|
void setupMacosWindowStyle(GLFWwindow *window, bool borderlessWindowMode);
|
||||||
|
|
||||||
|
void enumerateFontsMacos();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -413,16 +413,18 @@ namespace hex {
|
|||||||
|
|
||||||
bool FilePicker::draw(const std::string &name) {
|
bool FilePicker::draw(const std::string &name) {
|
||||||
bool changed = false;
|
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;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
if (ImGuiExt::IconButton("...", ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
|
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) {
|
[&](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);
|
ImGuiExt::TextFormatted("{}", name);
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
m_path = pathString;
|
||||||
|
}
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilePicker::load(const nlohmann::json &data) {
|
void FilePicker::load(const nlohmann::json &data) {
|
||||||
if (data.is_string()) {
|
if (data.is_string()) {
|
||||||
m_value = data.get<std::string>();
|
m_path = data.get<std::fs::path>();
|
||||||
} else {
|
} else {
|
||||||
log::warn("Invalid data type loaded from settings for file picker!");
|
log::warn("Invalid data type loaded from settings for file picker!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nlohmann::json FilePicker::store() {
|
nlohmann::json FilePicker::store() {
|
||||||
return m_value;
|
return m_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Label::draw(const std::string& name) {
|
bool Label::draw(const std::string& name) {
|
||||||
|
@ -677,14 +677,23 @@ namespace hex {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::optional<std::fs::path> fileToOpen;
|
static std::optional<std::fs::path> s_fileToOpen;
|
||||||
extern "C" void openFile(const char *path) {
|
extern "C" void openFile(const char *path) {
|
||||||
log::info("Opening file: {0}", path);
|
log::info("Opening file: {0}", path);
|
||||||
fileToOpen = path;
|
s_fileToOpen = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::fs::path> getInitialFilePath() {
|
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 {
|
namespace {
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
#include <CoreFoundation/CFBundle.h>
|
#include <CoreFoundation/CFBundle.h>
|
||||||
#include <ApplicationServices/ApplicationServices.h>
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
#include <Foundation/NSUserDefaults.h>
|
#include <Foundation/NSUserDefaults.h>
|
||||||
#include <Foundation/Foundation.h>
|
|
||||||
#include <AppKit/NSScreen.h>
|
#include <AppKit/NSScreen.h>
|
||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
#include <CoreText/CoreText.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -23,6 +24,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
void openFile(const char *path);
|
void openFile(const char *path);
|
||||||
|
void registerFont(const char *fontName, const char *fontPath);
|
||||||
|
|
||||||
void openWebpageMacos(const char *url) {
|
void openWebpageMacos(const char *url) {
|
||||||
CFURLRef urlRef = CFURLCreateWithBytes(NULL, (uint8_t*)(url), strlen(url), kCFStringEncodingASCII, NULL);
|
CFURLRef urlRef = CFURLCreateWithBytes(NULL, (uint8_t*)(url), strlen(url), kCFStringEncodingASCII, NULL);
|
||||||
@ -64,6 +66,28 @@
|
|||||||
return (cocoaWindow.styleMask & NSWindowStyleMaskFullScreen) == NSWindowStyleMaskFullScreen;
|
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
|
@interface HexDocument : NSDocument
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -47,6 +47,31 @@ namespace hex {
|
|||||||
} // Hopefully one of these commands is installed
|
} // 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() {
|
void Window::initNative() {
|
||||||
log::impl::enableColorPrinting();
|
log::impl::enableColorPrinting();
|
||||||
|
|
||||||
@ -65,6 +90,8 @@ namespace hex {
|
|||||||
if (!isatty(STDOUT_FILENO)) {
|
if (!isatty(STDOUT_FILENO)) {
|
||||||
log::impl::redirectToFile();
|
log::impl::redirectToFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enumerateFonts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::setupNativeWindow() {
|
void Window::setupNativeWindow() {
|
||||||
|
@ -38,6 +38,8 @@ namespace hex {
|
|||||||
if (!isatty(STDOUT_FILENO)) {
|
if (!isatty(STDOUT_FILENO)) {
|
||||||
log::impl::redirectToFile();
|
log::impl::redirectToFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enumerateFontsMacos();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::setupNativeWindow() {
|
void Window::setupNativeWindow() {
|
||||||
|
@ -268,6 +268,46 @@ namespace hex {
|
|||||||
dup2(unboundFd, stdFileDescriptor);
|
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() {
|
void Window::initNative() {
|
||||||
if (ImHexApi::System::isDebugBuild()) {
|
if (ImHexApi::System::isDebugBuild()) {
|
||||||
@ -301,6 +341,8 @@ namespace hex {
|
|||||||
if (std::fs::exists(path))
|
if (std::fs::exists(path))
|
||||||
AddDllDirectory(path.c_str());
|
AddDllDirectory(path.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enumerateFonts();
|
||||||
}
|
}
|
||||||
|
|
||||||
class DropManager : public IDropTarget {
|
class DropManager : public IDropTarget {
|
||||||
@ -486,7 +528,6 @@ namespace hex {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ImGui::GetIO().ConfigDebugIsDebuggerPresent = ::IsDebuggerPresent();
|
ImGui::GetIO().ConfigDebugIsDebuggerPresent = ::IsDebuggerPresent();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::beginNativeWindowFrame() {
|
void Window::beginNativeWindowFrame() {
|
||||||
|
@ -603,6 +603,50 @@ namespace hex::plugin::builtin {
|
|||||||
i32 m_currIndex = 0;
|
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 getDefaultBorderlessWindowMode() {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
@ -739,7 +783,7 @@ namespace hex::plugin::builtin {
|
|||||||
return customFontsEnabled.isChecked();
|
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()
|
.requiresRestart()
|
||||||
.setEnabledCallback(customFontsEnabled);
|
.setEnabledCallback(customFontsEnabled);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user