GUI: implement custom title format

New option "Window Title Format" in Misc.
Backward compatible with FPS disabler.
Make rpcs3:::get_branch() return string_view.
This commit is contained in:
Nekotekina 2020-02-12 23:52:11 +03:00
parent 606693a9f7
commit 0d7aa5e310
8 changed files with 142 additions and 54 deletions

View File

@ -44,6 +44,8 @@
#include "display_sleep_control.h"
#include "rpcs3_version.h"
#if defined(_WIN32) || defined(HAVE_VULKAN)
#include "Emu/RSX/VK/VulkanAPI.h"
#endif
@ -1865,6 +1867,126 @@ void Emulator::Stop(bool restart)
}
}
std::string Emulator::FormatTitle(double fps) const
{
// Get version by substringing VersionNumber-buildnumber-commithash to get just the part before the dash
std::string version = rpcs3::get_version().to_string();
const auto last_minus = version.find_last_of('-');
// Add branch and commit hash to version on frame unless it's master.
if (rpcs3::get_branch() != "master"sv && rpcs3::get_branch() != "HEAD"sv)
{
version = version.substr(0, ~last_minus ? last_minus + 9 : last_minus);
version += '-';
version += rpcs3::get_branch();
}
else
{
version = version.substr(0, last_minus);
}
auto [title_format, life1] = g_cfg.misc.title_format.get();
// Parse title format string
std::string title_string;
// Backward compatibility hack
std::size_t fmt_start = 0;
if (g_cfg.misc.show_fps_in_title.get() == false)
{
if (title_format.starts_with("FPS: %F | "))
{
// Remove "FPS" from the title if detected
fmt_start = 10;
}
}
for (std::size_t i = fmt_start; i < title_format.size();)
{
const char c1 = title_format[i];
if (c1 == '\0')
{
break;
}
switch (c1)
{
case '%':
{
const char c2 = title_format[i + 1];
if (c2 == '\0')
{
title_string += '%';
i++;
continue;
}
switch (c2)
{
case '%':
{
title_string += '%';
break;
}
case 'T':
{
title_string += this->GetTitle();
break;
}
case 't':
{
title_string += this->GetTitleID();
break;
}
case 'R':
{
fmt::append(title_string, "%s", g_cfg.video.renderer.get());
break;
}
case 'V':
{
title_string += version;
break;
}
case 'F':
{
if (g_cfg.misc.show_fps_in_title)
{
fmt::append(title_string, "%.2f", fps);
}
else
{
title_string += "Disabled";
}
break;
}
default:
{
title_string += '%';
title_string += c2;
break;
}
}
i += 2;
break;
}
default:
{
title_string += c1;
i += 1;
break;
}
}
}
return title_string;
}
std::string cfg_root::node_vfs::get(const cfg::string& _cfg, const char* _def) const
{
auto [spath, sshared] = _cfg.get();

View File

@ -377,6 +377,8 @@ public:
bool HasGui() const { return m_has_gui; }
void SetHasGui(bool has_gui) { m_has_gui = has_gui; }
std::string FormatTitle(double fps) const;
};
extern Emulator Emu;
@ -626,6 +628,7 @@ struct cfg_root : cfg::node
cfg::_bool use_native_interface{ this, "Use native user interface", true };
cfg::string gdb_server{this, "GDB Server", "127.0.0.1:2345"};
cfg::_bool silence_all_logs{this, "Silence All Logs", false, false};
cfg::string title_format{this, "Window Title Format", "FPS: %F | %R | %V | %T [%t]", true};
} misc{this};

View File

@ -5,7 +5,7 @@
namespace rpcs3
{
std::string get_branch()
std::string_view get_branch()
{
return RPCS3_GIT_BRANCH;
}

View File

@ -5,7 +5,7 @@
namespace rpcs3
{
std::string get_branch();
std::string_view get_branch();
std::pair<std::string, std::string> get_commit_and_hash();
const utils::version& get_version();
}

View File

@ -7,7 +7,7 @@
#include <QWindow>
gl_gs_frame::gl_gs_frame(const QRect& geometry, const QIcon& appIcon, const std::shared_ptr<gui_settings>& gui_settings)
: gs_frame("OpenGL", geometry, appIcon, gui_settings)
: gs_frame(geometry, appIcon, gui_settings)
{
setSurfaceType(QSurface::OpenGLSurface);

View File

@ -13,8 +13,6 @@
#include <QMessageBox>
#include <string>
#include "rpcs3_version.h"
#include "png.h"
#ifdef _WIN32
@ -35,32 +33,12 @@ LOG_CHANNEL(screenshot);
constexpr auto qstr = QString::fromStdString;
gs_frame::gs_frame(const QString& title, const QRect& geometry, const QIcon& appIcon, const std::shared_ptr<gui_settings>& gui_settings)
: QWindow(), m_windowTitle(title), m_gui_settings(gui_settings)
gs_frame::gs_frame(const QRect& geometry, const QIcon& appIcon, const std::shared_ptr<gui_settings>& gui_settings)
: QWindow(), m_gui_settings(gui_settings)
{
m_disable_mouse = gui_settings->GetValue(gui::gs_disableMouse).toBool();
// Get version by substringing VersionNumber-buildnumber-commithash to get just the part before the dash
std::string version = rpcs3::get_version().to_string();
version = version.substr(0 , version.find_last_of('-'));
// Add branch and commit hash to version on frame unless it's master.
if ((rpcs3::get_branch().compare("master") != 0) && (rpcs3::get_branch().compare("HEAD") != 0))
{
version = version + "-" + rpcs3::get_version().to_string().substr((rpcs3::get_version().to_string().find_last_of('-') + 1), 8) + "-" + rpcs3::get_branch();
}
m_windowTitle += qstr(" | " + version);
if (!Emu.GetTitle().empty())
{
m_windowTitle += qstr(" | " + Emu.GetTitle());
}
if (!Emu.GetTitleID().empty())
{
m_windowTitle += qstr(" [" + Emu.GetTitleID() + ']');
}
m_window_title = qstr(Emu.FormatTitle(0));
if (!appIcon.isNull())
{
@ -76,7 +54,7 @@ gs_frame::gs_frame(const QString& title, const QRect& geometry, const QIcon& app
setMinimumWidth(160);
setMinimumHeight(90);
setGeometry(geometry);
setTitle(m_windowTitle);
setTitle(m_window_title);
setVisibility(Hidden);
create();
@ -291,31 +269,22 @@ void gs_frame::flip(draw_context_t, bool /*skip_frame*/)
{
static Timer fps_t;
if (!m_show_fps_in_title && !g_cfg.misc.show_fps_in_title)
{
return;
}
++m_frames;
if (fps_t.GetElapsedTimeInSec() >= 0.5)
{
QString fps_title;
QString new_title = qstr(Emu.FormatTitle(m_frames / fps_t.GetElapsedTimeInSec()));
if ((m_show_fps_in_title = g_cfg.misc.show_fps_in_title.get()))
if (new_title != m_window_title)
{
fps_title = qstr(fmt::format("FPS: %.2f", m_frames / fps_t.GetElapsedTimeInSec()));
m_window_title = new_title;
if (!m_windowTitle.isEmpty())
Emu.CallAfter([this, title = std::move(new_title)]()
{
fps_title += " | ";
}
setTitle(title);
});
}
fps_title += m_windowTitle;
Emu.CallAfter([this, title = std::move(fps_title)]() { setTitle(title); });
m_frames = 0;
fps_t.Start();
}

View File

@ -36,13 +36,11 @@ private:
std::shared_ptr<gui_settings> m_gui_settings;
u64 m_frames = 0;
// display status of last title update, needed for dynamic changes of the fps setting
bool m_show_fps_in_title = false;
QString m_windowTitle;
QString m_window_title;
bool m_disable_mouse;
public:
gs_frame(const QString& title, const QRect& geometry, const QIcon& appIcon, const std::shared_ptr<gui_settings>& gui_settings);
gs_frame(const QRect& geometry, const QIcon& appIcon, const std::shared_ptr<gui_settings>& gui_settings);
~gs_frame();
draw_context_t make_context() override;

View File

@ -233,19 +233,15 @@ std::unique_ptr<gs_frame> gui_application::get_gs_frame()
switch (video_renderer type = g_cfg.video.renderer)
{
case video_renderer::null:
{
frame = new gs_frame("Null", frame_geometry, app_icon, m_gui_settings);
break;
}
case video_renderer::opengl:
{
frame = new gl_gs_frame(frame_geometry, app_icon, m_gui_settings);
break;
}
case video_renderer::null:
case video_renderer::vulkan:
{
frame = new gs_frame("Vulkan", frame_geometry, app_icon, m_gui_settings);
frame = new gs_frame(frame_geometry, app_icon, m_gui_settings);
break;
}
default: fmt::throw_exception("Invalid video renderer: %s" HERE, type);