#include #include #include #include #include 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("hex.fonts.setting.font", "hex.fonts.setting.font.custom_font", std::move(name)); } }