1
0
mirror of synced 2025-02-02 12:27:25 +01:00
ImHex/plugins/fonts/source/font_settings.cpp
2025-01-18 23:34:43 +01:00

207 lines
6.5 KiB
C++

#include <font_settings.hpp>
#include <hex/api/content_registry.hpp>
#include <wolv/utils/string.hpp>
#include <hex/helpers/utils.hpp>
#include <imgui.h>
namespace hex::fonts {
constexpr static auto PixelPerfectName = "Pixel-Perfect Default Font (Proggy Clean)";
constexpr static auto SmoothName = "Smooth Default Font (JetbrainsMono)";
constexpr static auto CustomName = "Custom Font";
bool FontFilePicker::draw(const std::string &name) {
bool changed = false;
const bool pixelPerfectFont = isPixelPerfectFontSelected();
bool customFont = updateSelectedFontName();
if (ImGui::BeginCombo(name.c_str(), m_selectedFontName.c_str())) {
if (ImGui::Selectable(PixelPerfectName, m_path.empty() && pixelPerfectFont)) {
m_path.clear();
m_pixelPerfectFont = true;
changed = true;
}
if (ImGui::Selectable(SmoothName, m_path.empty() && !pixelPerfectFont)) {
m_path.clear();
m_pixelPerfectFont = false;
changed = true;
}
if (ImGui::Selectable(CustomName, customFont)) {
changed = fs::openFileBrowser(fs::DialogMode::Open, { { "TTF Font", "ttf" }, { "OTF Font", "otf" } }, [this](const std::fs::path &path) {
m_path = path;
m_pixelPerfectFont = false;
});
}
for (const auto &[path, fontName] : hex::getFonts()) {
if (ImGui::Selectable(limitStringLength(fontName, 50).c_str(), m_path == path)) {
m_path = path;
m_pixelPerfectFont = false;
changed = true;
}
ImGui::SetItemTooltip("%s", fontName.c_str());
}
ImGui::EndCombo();
}
return changed;
}
bool FontFilePicker::isPixelPerfectFontSelected() const {
return m_pixelPerfectFont;
}
const std::string& FontFilePicker::getSelectedFontName() const {
return m_selectedFontName;
}
void FontFilePicker::load(const nlohmann::json& data) {
FilePicker::load(data["path"]);
m_pixelPerfectFont = data["pixel_perfect_font"];
updateSelectedFontName();
}
nlohmann::json FontFilePicker::store() {
nlohmann::json data = nlohmann::json::object();
data["path"] = FilePicker::store();
data["pixel_perfect_font"] = m_pixelPerfectFont;
return data;
}
bool FontFilePicker::updateSelectedFontName() {
const auto &fonts = hex::getFonts();
bool customFont = false;
const bool pixelPerfectFont = isPixelPerfectFontSelected();
if (m_path.empty() && pixelPerfectFont) {
m_selectedFontName = PixelPerfectName;
} else if (m_path.empty() && !pixelPerfectFont) {
m_selectedFontName = SmoothName;
} else if (fonts.contains(m_path)) {
m_selectedFontName = fonts.at(m_path);
} else {
m_selectedFontName = wolv::util::toUTF8String(m_path.filename());
customFont = true;
}
return customFont;
}
static float pixelsToPoints(float pixels) {
return pixels * (72_scaled / 96.0F);
}
static float pointsToPixels(float points) {
return points / (72_scaled / 96.0F);
}
bool SliderPoints::draw(const std::string &name) {
float value = pixelsToPoints(m_value);
float min = pixelsToPoints(m_min);
float max = pixelsToPoints(m_max);
auto changed = ImGui::SliderFloat(name.c_str(), &value, min, max, "%.0f pt");
m_value = pointsToPixels(value);
return changed;
}
bool FontSelector::draw(const std::string &name) {
ImGui::PushID(name.c_str());
ON_SCOPE_EXIT { ImGui::PopID(); };
if (ImGui::Button(m_fontFilePicker.getSelectedFontName().c_str(), ImVec2(300_scaled, 0))) {
ImGui::OpenPopup("Fonts");
}
ImGui::SameLine();
ImGui::TextUnformatted(name.c_str());
ImGui::SetNextWindowPos(ImGui::GetCursorScreenPos());
return drawPopup();
}
nlohmann::json FontSelector::store() {
nlohmann::json json = nlohmann::json::object();
json["font_file"] = m_fontFilePicker.store();
json["font_size"] = m_fontSize.store();
json["bold"] = m_bold.store();
json["italic"] = m_italic.store();
json["antialiased"] = m_antiAliased.store();
return json;
}
void FontSelector::load(const nlohmann::json& data) {
m_fontFilePicker.load(data["font_file"]);
m_fontSize.load(data["font_size"]);
m_bold.load(data["bold"]);
m_italic.load(data["italic"]);
m_antiAliased.load(data["antialiased"]);
}
bool FontSelector::drawPopup() {
bool changed = false;
if (ImGui::BeginPopup("Fonts")) {
m_fontFilePicker.draw("hex.fonts.setting.font.custom_font"_lang);
ImGui::BeginDisabled(m_fontFilePicker.isPixelPerfectFontSelected());
{
m_fontSize.draw("hex.fonts.setting.font.font_size"_lang);
m_bold.draw("hex.fonts.setting.font.font_bold"_lang);
m_italic.draw("hex.fonts.setting.font.font_italic"_lang);
m_antiAliased.draw("hex.fonts.setting.font.font_antialias"_lang);
}
ImGui::EndDisabled();
ImGui::NewLine();
if (ImGui::Button("hex.ui.common.apply"_lang))
changed = true;
ImGui::EndPopup();
}
return changed;
}
[[nodiscard]] const std::fs::path& FontSelector::getFontPath() const {
return m_fontFilePicker.getPath();
}
[[nodiscard]] bool FontSelector::isPixelPerfectFont() const {
return m_fontFilePicker.isPixelPerfectFontSelected();
}
[[nodiscard]] float FontSelector::getFontSize() const {
return m_fontSize.getValue();
}
[[nodiscard]] bool FontSelector::isBold() const {
return m_bold.isChecked();
}
[[nodiscard]] bool FontSelector::isItalic() const {
return m_italic.isChecked();
}
[[nodiscard]] bool FontSelector::isAntiAliased() const {
return m_antiAliased.isChecked();
}
ContentRegistry::Settings::Widgets::Widget::Interface& addFontSettingsWidget(UnlocalizedString name) {
return ContentRegistry::Settings::add<FontSelector>("hex.fonts.setting.font", "hex.fonts.setting.font.custom_font", std::move(name));
}
}