Use std::format in components/fx

This commit is contained in:
Evil Eye 2025-08-16 13:46:34 +02:00
parent 9610be7c8a
commit cf3d0b7dd3
6 changed files with 70 additions and 80 deletions

View File

@ -3,6 +3,7 @@
#include "MyGUI_LanguageManager.h" #include "MyGUI_LanguageManager.h"
#include <components/lua/util.hpp> #include <components/lua/util.hpp>
#include <components/misc/strings/format.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"

View File

@ -2,11 +2,7 @@
#include <cctype> #include <cctype>
#include <cstdlib> #include <cstdlib>
#include <optional> #include <format>
#include <string>
#include <string_view>
#include <components/misc/strings/format.hpp>
namespace Fx namespace Fx
{ {
@ -126,7 +122,7 @@ namespace Fx
[[noreturn]] void Lexer::error(const std::string& msg) [[noreturn]] void Lexer::error(const std::string& msg)
{ {
throw LexerException(Misc::StringUtils::format("Line %zu Col %zu. %s", mLine + 1, mColumn, msg)); throw LexerException(std::format("Line {} Col {}. {}", mLine + 1, mColumn, msg));
} }
void Lexer::advance() void Lexer::advance()
@ -209,7 +205,7 @@ namespace Fx
advance(); advance();
return { Comma{} }; return { Comma{} };
default: default:
error(Misc::StringUtils::format("unexpected token <%c>", head())); error(std::format("unexpected token <{}>", head()));
} }
} }

View File

@ -300,7 +300,7 @@ float omw_EstimateFogCoverageFromUV(vec2 uv)
header.replace(pos, define.size(), value); header.replace(pos, define.size(), value);
for (const auto& target : mRenderTargets) for (const auto& target : mRenderTargets)
header.append("uniform sampler2D " + std::string(target) + ";"); header.append("uniform sampler2D " + target + ";");
for (auto& uniform : technique.getUniformMap()) for (auto& uniform : technique.getUniformMap())
if (auto glsl = uniform->getGLSL()) if (auto glsl = uniform->getGLSL())

View File

@ -1,6 +1,7 @@
#include "technique.hpp" #include "technique.hpp"
#include <array> #include <array>
#include <format>
#include <string> #include <string>
#include <utility> #include <utility>
@ -91,10 +92,7 @@ namespace Fx
std::string Technique::getBlockWithLineDirective() std::string Technique::getBlockWithLineDirective()
{ {
auto block = mLexer->getLastJumpBlock(); auto block = mLexer->getLastJumpBlock();
std::string content = std::string(block.content); return std::format("\n#line {}\n{}\n", block.line + 1, block.content);
content = "\n#line " + std::to_string(block.line + 1) + "\n" + std::string(block.content) + "\n";
return content;
} }
Technique::UniformMap::iterator Technique::findUniform(const std::string& name) Technique::UniformMap::iterator Technique::findUniform(const std::string& name)
@ -140,9 +138,9 @@ namespace Fx
if (it == mPassMap.end()) if (it == mPassMap.end())
error( error(
Misc::StringUtils::format("pass '%s' was found in the pass list, but there was no matching " std::format("pass '{}' was found in the pass list, but there was no matching 'fragment', "
"'fragment', 'vertex' or 'compute' block", "'vertex' or 'compute' block",
std::string(name))); name));
if (mLastAppliedType != Pass::Type::None && mLastAppliedType != it->second->mType) if (mLastAppliedType != Pass::Type::None && mLastAppliedType != it->second->mType)
{ {
@ -167,7 +165,7 @@ namespace Fx
{ {
auto rtIt = mRenderTargets.find(it->second->mTarget); auto rtIt = mRenderTargets.find(it->second->mTarget);
if (rtIt == mRenderTargets.end()) if (rtIt == mRenderTargets.end())
error(Misc::StringUtils::format("target '%s' not defined", std::string(it->second->mTarget))); error(std::format("target '{}' not defined", it->second->mTarget));
} }
mPasses.emplace_back(it->second); mPasses.emplace_back(it->second);
@ -212,7 +210,7 @@ namespace Fx
void Technique::parseBlockImp<Lexer::Shared>() void Technique::parseBlockImp<Lexer::Shared>()
{ {
if (!mLexer->jump()) if (!mLexer->jump())
error(Misc::StringUtils::format("unterminated 'shared' block, expected closing brackets")); error("unterminated 'shared' block, expected closing brackets");
if (!mShared.empty()) if (!mShared.empty())
error("repeated 'shared' block, only one allowed per technique file"); error("repeated 'shared' block, only one allowed per technique file");
@ -255,7 +253,7 @@ namespace Fx
else if (key == "glsl_profile") else if (key == "glsl_profile")
{ {
expect<Lexer::String>(); expect<Lexer::String>();
mGLSLProfile = std::string(std::get<Lexer::String>(mToken).value); mGLSLProfile = std::get<Lexer::String>(mToken).value;
} }
else if (key == "glsl_extensions") else if (key == "glsl_extensions")
{ {
@ -265,7 +263,7 @@ namespace Fx
else if (key == "dynamic") else if (key == "dynamic")
mDynamic = parseBool(); mDynamic = parseBool();
else else
error(Misc::StringUtils::format("unexpected key '%s'", std::string{ key })); error(std::format("unexpected key '{}'", key));
expect<Lexer::SemiColon>(); expect<Lexer::SemiColon>();
} }
@ -278,7 +276,7 @@ namespace Fx
void Technique::parseBlockImp<Lexer::Render_Target>() void Technique::parseBlockImp<Lexer::Render_Target>()
{ {
if (mRenderTargets.count(mBlockName)) if (mRenderTargets.count(mBlockName))
error(Misc::StringUtils::format("redeclaration of render target '%s'", std::string(mBlockName))); error(std::format("redeclaration of render target '{}'", mBlockName));
Fx::Types::RenderTarget rt; Fx::Types::RenderTarget rt;
rt.mTarget->setTextureSize(mWidth, mHeight); rt.mTarget->setTextureSize(mWidth, mHeight);
@ -324,7 +322,7 @@ namespace Fx
else if (key == "clear_color") else if (key == "clear_color")
rt.mClearColor = parseVec<osg::Vec4f, Lexer::Vec4>(); rt.mClearColor = parseVec<osg::Vec4f, Lexer::Vec4>();
else else
error(Misc::StringUtils::format("unexpected key '%s'", std::string(key))); error(std::format("unexpected key '{}'", key));
expect<Lexer::SemiColon>(); expect<Lexer::SemiColon>();
} }
@ -336,7 +334,7 @@ namespace Fx
void Technique::parseBlockImp<Lexer::Vertex>() void Technique::parseBlockImp<Lexer::Vertex>()
{ {
if (!mLexer->jump()) if (!mLexer->jump())
error(Misc::StringUtils::format("unterminated 'vertex' block, expected closing brackets")); error("unterminated 'vertex' block, expected closing brackets");
auto& pass = mPassMap[mBlockName]; auto& pass = mPassMap[mBlockName];
@ -346,11 +344,11 @@ namespace Fx
pass->mName = mBlockName; pass->mName = mBlockName;
if (pass->mCompute) if (pass->mCompute)
error(Misc::StringUtils::format("'compute' block already defined. Usage is ambiguous.")); error("'compute' block already defined. Usage is ambiguous.");
else if (!pass->mVertex) else if (!pass->mVertex)
pass->mVertex = new osg::Shader(osg::Shader::VERTEX, getBlockWithLineDirective()); pass->mVertex = new osg::Shader(osg::Shader::VERTEX, getBlockWithLineDirective());
else else
error(Misc::StringUtils::format("duplicate vertex shader for block '%s'", std::string(mBlockName))); error(std::format("duplicate vertex shader for block '{}'", mBlockName));
pass->mType = Pass::Type::Pixel; pass->mType = Pass::Type::Pixel;
} }
@ -359,7 +357,7 @@ namespace Fx
void Technique::parseBlockImp<Lexer::Fragment>() void Technique::parseBlockImp<Lexer::Fragment>()
{ {
if (!mLexer->jump()) if (!mLexer->jump())
error(Misc::StringUtils::format("unterminated 'fragment' block, expected closing brackets")); error("unterminated 'fragment' block, expected closing brackets");
auto& pass = mPassMap[mBlockName]; auto& pass = mPassMap[mBlockName];
@ -370,11 +368,11 @@ namespace Fx
pass->mName = mBlockName; pass->mName = mBlockName;
if (pass->mCompute) if (pass->mCompute)
error(Misc::StringUtils::format("'compute' block already defined. Usage is ambiguous.")); error("'compute' block already defined. Usage is ambiguous.");
else if (!pass->mFragment) else if (!pass->mFragment)
pass->mFragment = new osg::Shader(osg::Shader::FRAGMENT, getBlockWithLineDirective()); pass->mFragment = new osg::Shader(osg::Shader::FRAGMENT, getBlockWithLineDirective());
else else
error(Misc::StringUtils::format("duplicate vertex shader for block '%s'", std::string(mBlockName))); error(std::format("duplicate vertex shader for block '{}'", mBlockName));
pass->mType = Pass::Type::Pixel; pass->mType = Pass::Type::Pixel;
} }
@ -383,7 +381,7 @@ namespace Fx
void Technique::parseBlockImp<Lexer::Compute>() void Technique::parseBlockImp<Lexer::Compute>()
{ {
if (!mLexer->jump()) if (!mLexer->jump())
error(Misc::StringUtils::format("unterminated 'compute' block, expected closing brackets")); error("unterminated 'compute' block, expected closing brackets");
auto& pass = mPassMap[mBlockName]; auto& pass = mPassMap[mBlockName];
@ -393,13 +391,13 @@ namespace Fx
pass->mName = mBlockName; pass->mName = mBlockName;
if (pass->mFragment) if (pass->mFragment)
error(Misc::StringUtils::format("'fragment' block already defined. Usage is ambiguous.")); error("'fragment' block already defined. Usage is ambiguous.");
else if (pass->mVertex) else if (pass->mVertex)
error(Misc::StringUtils::format("'vertex' block already defined. Usage is ambiguous.")); error("'vertex' block already defined. Usage is ambiguous.");
else if (!pass->mFragment) else if (!pass->mFragment)
pass->mCompute = new osg::Shader(osg::Shader::COMPUTE, getBlockWithLineDirective()); pass->mCompute = new osg::Shader(osg::Shader::COMPUTE, getBlockWithLineDirective());
else else
error(Misc::StringUtils::format("duplicate vertex shader for block '%s'", std::string(mBlockName))); error(std::format("duplicate vertex shader for block '{}'", mBlockName));
pass->mType = Pass::Type::Compute; pass->mType = Pass::Type::Compute;
} }
@ -408,7 +406,7 @@ namespace Fx
void Technique::parseSampler() void Technique::parseSampler()
{ {
if (findUniform(std::string(mBlockName)) != mDefinedUniforms.end()) if (findUniform(std::string(mBlockName)) != mDefinedUniforms.end())
error(Misc::StringUtils::format("redeclaration of uniform '%s'", std::string(mBlockName))); error(std::format("redeclaration of uniform '{}'", mBlockName));
ProxyTextureData proxy; ProxyTextureData proxy;
osg::ref_ptr<osg::Texture> sampler; osg::ref_ptr<osg::Texture> sampler;
@ -466,13 +464,12 @@ namespace Fx
} }
} }
else else
error(Misc::StringUtils::format("unexpected key '%s'", std::string{ key })); error(std::format("unexpected key '{}'", key));
expect<Lexer::SemiColon>(); expect<Lexer::SemiColon>();
} }
if (!sampler) if (!sampler)
error(Misc::StringUtils::format( error(std::format("{} '{}' requires a filename", T::repr, mBlockName));
"%s '%s' requires a filename", std::string(T::repr), std::string{ mBlockName }));
if (!is1D) if (!is1D)
{ {
@ -497,7 +494,7 @@ namespace Fx
std::shared_ptr<Types::UniformBase> uniform = std::make_shared<Types::UniformBase>(); std::shared_ptr<Types::UniformBase> uniform = std::make_shared<Types::UniformBase>();
uniform->mSamplerType = type; uniform->mSamplerType = type;
uniform->mName = std::string(mBlockName); uniform->mName = mBlockName;
mDefinedUniforms.emplace_back(std::move(uniform)); mDefinedUniforms.emplace_back(std::move(uniform));
} }
@ -534,7 +531,7 @@ namespace Fx
void Technique::parseUniform() void Technique::parseUniform()
{ {
if (findUniform(std::string(mBlockName)) != mDefinedUniforms.end()) if (findUniform(std::string(mBlockName)) != mDefinedUniforms.end())
error(Misc::StringUtils::format("redeclaration of uniform '%s'", std::string(mBlockName))); error(std::format("redeclaration of uniform '{}'", mBlockName));
std::shared_ptr<Types::UniformBase> uniform = std::make_shared<Types::UniformBase>(); std::shared_ptr<Types::UniformBase> uniform = std::make_shared<Types::UniformBase>();
Types::Uniform<SrcT> data = Types::Uniform<SrcT>(); Types::Uniform<SrcT> data = Types::Uniform<SrcT>();
@ -591,7 +588,7 @@ namespace Fx
parseWidgetType<SrcT, T>(data); parseWidgetType<SrcT, T>(data);
} }
else else
error(Misc::StringUtils::format("unexpected key '%s'", std::string{ key })); error(std::format("unexpected key '{}'", key));
expect<Lexer::SemiColon>(); expect<Lexer::SemiColon>();
} }
@ -599,7 +596,7 @@ namespace Fx
if (data.isArray()) if (data.isArray())
uniform->mStatic = false; uniform->mStatic = false;
uniform->mName = std::string(mBlockName); uniform->mName = mBlockName;
uniform->mData = data; uniform->mData = data;
uniform->mTechniqueName = mName; uniform->mTechniqueName = mName;
@ -680,9 +677,9 @@ namespace Fx
if (!std::holds_alternative<T>(mToken)) if (!std::holds_alternative<T>(mToken))
{ {
if (err.empty()) if (err.empty())
error(Misc::StringUtils::format("Expected %s", std::string(T::repr))); error(std::format("Expected {}", T::repr));
else else
error(Misc::StringUtils::format("%s. Expected %s", err, std::string(T::repr))); error(std::format("{}. Expected {}", err, T::repr));
} }
} }
@ -693,10 +690,9 @@ namespace Fx
if (!std::holds_alternative<T>(mToken) && !std::holds_alternative<T2>(mToken)) if (!std::holds_alternative<T>(mToken) && !std::holds_alternative<T2>(mToken))
{ {
if (err.empty()) if (err.empty())
error(Misc::StringUtils::format( error(std::format("{}. Expected {} or {}", err, T::repr, T2::repr));
"%s. Expected %s or %s", err, std::string(T::repr), std::string(T2::repr)));
else else
error(Misc::StringUtils::format("Expected %s or %s", std::string(T::repr), std::string(T2::repr))); error(std::format("Expected {} or {}", T::repr, T2::repr));
} }
} }
@ -856,14 +852,14 @@ namespace Fx
pass->mBlendEq = blendEq; pass->mBlendEq = blendEq;
} }
else else
error(Misc::StringUtils::format("unrecognized key '%s' in block header", std::string(key))); error(std::format("unrecognized key '{}' in block header", key));
mToken = mLexer->next(); mToken = mLexer->next();
if (std::holds_alternative<Lexer::Comma>(mToken)) if (std::holds_alternative<Lexer::Comma>(mToken))
{ {
if (std::holds_alternative<Lexer::Close_Parenthesis>(mLexer->peek())) if (std::holds_alternative<Lexer::Close_Parenthesis>(mLexer->peek()))
error(Misc::StringUtils::format("leading comma in '%s' is not allowed", std::string(mBlockName))); error(std::format("leading comma in '{}' is not allowed", mBlockName));
else else
continue; continue;
} }
@ -888,7 +884,7 @@ namespace Fx
if (Misc::StringUtils::ciEqual(term, identifer)) if (Misc::StringUtils::ciEqual(term, identifer))
return bit; return bit;
} }
error(Misc::StringUtils::format("unrecognized flag '%s'", std::string(term))); error(std::format("unrecognized flag '{}'", term));
}; };
FlagsType flag = 0; FlagsType flag = 0;
@ -908,7 +904,7 @@ namespace Fx
return mode; return mode;
} }
error(Misc::StringUtils::format("unrecognized filter mode '%s'", std::string{ asLiteral() })); error(std::format("unrecognized filter mode '{}'", asLiteral()));
} }
osg::Texture::WrapMode Technique::parseWrapMode() osg::Texture::WrapMode Technique::parseWrapMode()
@ -926,7 +922,7 @@ namespace Fx
"unsupported wrap mode 'clamp'; 'clamp_to_edge' was likely intended, look for an updated shader or " "unsupported wrap mode 'clamp'; 'clamp_to_edge' was likely intended, look for an updated shader or "
"contact author"); "contact author");
error(Misc::StringUtils::format("unrecognized wrap mode '%s'", std::string{ asLiteral() })); error(std::format("unrecognized wrap mode '{}'", asLiteral()));
} }
osg::Texture::InternalFormatMode Technique::parseCompression() osg::Texture::InternalFormatMode Technique::parseCompression()
@ -939,7 +935,7 @@ namespace Fx
return mode; return mode;
} }
error(Misc::StringUtils::format("unrecognized compression '%s'", std::string{ asLiteral() })); error(std::format("unrecognized compression '{}'", asLiteral()));
} }
int Technique::parseInternalFormat() int Technique::parseInternalFormat()
@ -952,7 +948,7 @@ namespace Fx
return mode; return mode;
} }
error(Misc::StringUtils::format("unrecognized internal format '%s'", std::string{ asLiteral() })); error(std::format("unrecognized internal format '{}'", asLiteral()));
} }
int Technique::parseSourceType() int Technique::parseSourceType()
@ -965,7 +961,7 @@ namespace Fx
return mode; return mode;
} }
error(Misc::StringUtils::format("unrecognized source type '%s'", std::string{ asLiteral() })); error(std::format("unrecognized source type '{}'", asLiteral()));
} }
int Technique::parseSourceFormat() int Technique::parseSourceFormat()
@ -978,7 +974,7 @@ namespace Fx
return mode; return mode;
} }
error(Misc::StringUtils::format("unrecognized source format '%s'", std::string{ asLiteral() })); error(std::format("unrecognized source format '{}'", asLiteral()));
} }
osg::BlendEquation::Equation Technique::parseBlendEquation() osg::BlendEquation::Equation Technique::parseBlendEquation()
@ -991,7 +987,7 @@ namespace Fx
return mode; return mode;
} }
error(Misc::StringUtils::format("unrecognized blend equation '%s'", std::string{ asLiteral() })); error(std::format("unrecognized blend equation '{}'", asLiteral()));
} }
osg::BlendFunc::BlendFuncMode Technique::parseBlendFuncMode() osg::BlendFunc::BlendFuncMode Technique::parseBlendFuncMode()
@ -1004,7 +1000,7 @@ namespace Fx
return mode; return mode;
} }
error(Misc::StringUtils::format("unrecognized blend function '%s'", std::string{ asLiteral() })); error(std::format("unrecognized blend function '{}'", asLiteral()));
} }
template <class SrcT, class T> template <class SrcT, class T>
@ -1057,7 +1053,7 @@ namespace Fx
} }
else else
{ {
error(Misc::StringUtils::format("unrecognized widget type '%s'", std::string{ asLiteral() })); error(std::format("unrecognized widget type '{}'", asLiteral()));
} }
} }

View File

@ -1,6 +1,7 @@
#ifndef OPENMW_COMPONENTS_FX_TYPES_HPP #ifndef OPENMW_COMPONENTS_FX_TYPES_HPP
#define OPENMW_COMPONENTS_FX_TYPES_HPP #define OPENMW_COMPONENTS_FX_TYPES_HPP
#include <format>
#include <optional> #include <optional>
#include <variant> #include <variant>
@ -8,7 +9,6 @@
#include <osg/Uniform> #include <osg/Uniform>
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
#include <components/misc/strings/format.hpp>
#include <components/sceneutil/depth.hpp> #include <components/sceneutil/depth.hpp>
#include <components/settings/shadermanager.hpp> #include <components/settings/shadermanager.hpp>
@ -236,11 +236,11 @@ namespace Fx
switch (mSamplerType.value()) switch (mSamplerType.value())
{ {
case Texture_1D: case Texture_1D:
return Misc::StringUtils::format("uniform sampler1D %s;", mName); return std::format("uniform sampler1D {};", mName);
case Texture_2D: case Texture_2D:
return Misc::StringUtils::format("uniform sampler2D %s;", mName); return std::format("uniform sampler2D {};", mName);
case Texture_3D: case Texture_3D:
return Misc::StringUtils::format("uniform sampler3D %s;", mName); return std::format("uniform sampler3D {};", mName);
} }
} }
@ -253,54 +253,52 @@ namespace Fx
const bool useUniform = arg.isArray() const bool useUniform = arg.isArray()
|| (Settings::ShaderManager::get().getMode() == Settings::ShaderManager::Mode::Debug || (Settings::ShaderManager::get().getMode() == Settings::ShaderManager::Mode::Debug
|| mStatic == false); || mStatic == false);
const std::string uname = arg.isArray() const std::string uname
? Misc::StringUtils::format("%s[%zu]", mName, arg.getArray().size()) = arg.isArray() ? std::format("{}[{}]", mName, arg.getArray().size()) : mName;
: mName;
if constexpr (std::is_same_v<T, osg::Vec2f>) if constexpr (std::is_same_v<T, osg::Vec2f>)
{ {
if (useUniform) if (useUniform)
return Misc::StringUtils::format("uniform vec2 %s;", uname); return std::format("uniform vec2 {};", uname);
return Misc::StringUtils::format("const vec2 %s=vec2(%f,%f);", mName, value[0], value[1]); return std::format("const vec2 {}=vec2({},{});", mName, value[0], value[1]);
} }
else if constexpr (std::is_same_v<T, osg::Vec3f>) else if constexpr (std::is_same_v<T, osg::Vec3f>)
{ {
if (useUniform) if (useUniform)
return Misc::StringUtils::format("uniform vec3 %s;", uname); return std::format("uniform vec3 {};", uname);
return Misc::StringUtils::format( return std::format("const vec3 {}=vec3({},{},{});", mName, value[0], value[1], value[2]);
"const vec3 %s=vec3(%f,%f,%f);", mName, value[0], value[1], value[2]);
} }
else if constexpr (std::is_same_v<T, osg::Vec4f>) else if constexpr (std::is_same_v<T, osg::Vec4f>)
{ {
if (useUniform) if (useUniform)
return Misc::StringUtils::format("uniform vec4 %s;", uname); return std::format("uniform vec4 {};", uname);
return Misc::StringUtils::format( return std::format(
"const vec4 %s=vec4(%f,%f,%f,%f);", mName, value[0], value[1], value[2], value[3]); "const vec4 {}=vec4({},{},{},{});", mName, value[0], value[1], value[2], value[3]);
} }
else if constexpr (std::is_same_v<T, float>) else if constexpr (std::is_same_v<T, float>)
{ {
if (useUniform) if (useUniform)
return Misc::StringUtils::format("uniform float %s;", uname); return std::format("uniform float {};", uname);
return Misc::StringUtils::format("const float %s=%f;", mName, value); return std::format("const float {}={};", mName, value);
} }
else if constexpr (std::is_same_v<T, int>) else if constexpr (std::is_same_v<T, int>)
{ {
if (useUniform) if (useUniform)
return Misc::StringUtils::format("uniform int %s;", uname); return std::format("uniform int {};", uname);
return Misc::StringUtils::format("const int %s=%i;", mName, value); return std::format("const int {}={};", mName, value);
} }
else else
{ {
static_assert(std::is_same_v<T, bool>, "Non-exhaustive visitor"); static_assert(std::is_same_v<T, bool>, "Non-exhaustive visitor");
if (useUniform) if (useUniform)
return Misc::StringUtils::format("uniform bool %s;", uname); return std::format("uniform bool {};", uname);
return Misc::StringUtils::format("const bool %s=%s;", mName, value ? "true" : "false"); return std::format("const bool {}={};", mName, value ? "true" : "false");
} }
}, },
mData); mData);

View File

@ -10,6 +10,7 @@
#include <MyGUI_Widget.h> #include <MyGUI_Widget.h>
#include <algorithm> #include <algorithm>
#include <format>
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
@ -18,8 +19,6 @@
#include <osg/Vec3f> #include <osg/Vec3f>
#include <osg/Vec4f> #include <osg/Vec4f>
#include <components/misc/strings/format.hpp>
#include "types.hpp" #include "types.hpp"
namespace Gui namespace Gui
@ -88,7 +87,7 @@ namespace Fx
{ {
mValue = value; mValue = value;
if constexpr (std::is_floating_point_v<T>) if constexpr (std::is_floating_point_v<T>)
mValueLabel->setCaption(Misc::StringUtils::format("%.3f", mValue)); mValueLabel->setCaption(std::format("{:.3f}", mValue));
else else
mValueLabel->setCaption(std::to_string(mValue)); mValueLabel->setCaption(std::to_string(mValue));