207 lines
6.5 KiB
C++
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));
|
||
|
}
|
||
|
|
||
|
}
|