Move ImGui setup to common, and enable fullscreen UI in Qt

This commit is contained in:
Connor McLaughlin
2021-02-22 02:38:16 +10:00
parent d0f6ff03a5
commit 8318cdb3c1
16 changed files with 319 additions and 216 deletions

View File

@ -25,6 +25,8 @@
#include "game_list.h"
#include "icon.h"
#include "imgui.h"
#include "imgui_fullscreen.h"
#include "imgui_styles.h"
#include "ini_settings_interface.h"
#include "save_state_selector_ui.h"
#include "scmversion/scmversion.h"
@ -84,6 +86,9 @@ bool CommonHostInterface::Initialize()
RegisterHotkeys();
UpdateControllerInterface();
CreateImGuiContext();
return true;
}
@ -91,6 +96,8 @@ void CommonHostInterface::Shutdown()
{
HostInterface::Shutdown();
ImGui::DestroyContext();
#ifdef WITH_DISCORD_PRESENCE
ShutdownDiscordPresence();
#endif
@ -139,7 +146,7 @@ void CommonHostInterface::InitializeUserDirectory()
bool CommonHostInterface::BootSystem(const SystemBootParameters& parameters)
{
// If the fullscreen UI is enabled, make sure it's finished loading the game list so we don't race it.
if (m_fullscreen_ui_enabled)
if (m_display && m_fullscreen_ui_enabled)
FullscreenUI::EnsureGameListLoaded();
if (!HostInterface::BootSystem(parameters))
@ -268,7 +275,7 @@ bool CommonHostInterface::ParseCommandLineParameters(int argc, char* argv[],
else if (CHECK_ARG("-batch"))
{
Log_InfoPrintf("Enabling batch mode.");
m_command_line_flags.batch_mode = true;
m_flags.batch_mode = true;
continue;
}
else if (CHECK_ARG("-fastboot"))
@ -286,7 +293,7 @@ bool CommonHostInterface::ParseCommandLineParameters(int argc, char* argv[],
else if (CHECK_ARG("-nocontroller"))
{
Log_InfoPrintf("Disabling controller support.");
m_command_line_flags.disable_controller_interface = true;
m_flags.disable_controller_interface = true;
continue;
}
else if (CHECK_ARG("-resume"))
@ -307,7 +314,7 @@ bool CommonHostInterface::ParseCommandLineParameters(int argc, char* argv[],
else if (CHECK_ARG("-fullscreen"))
{
Log_InfoPrintf("Going fullscreen after booting.");
m_command_line_flags.start_fullscreen = true;
m_flags.start_fullscreen = true;
force_fullscreen = true;
continue;
}
@ -444,6 +451,16 @@ bool CommonHostInterface::SetFullscreen(bool enabled)
return false;
}
void CommonHostInterface::CreateImGuiContext()
{
ImGui::CreateContext();
ImGui::GetIO().IniFilename = nullptr;
#ifndef __ANDROID__
// Android has no keyboard, nor are we using ImGui for any actual user-interactable windows.
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_NavEnableGamepad;
#endif
}
bool CommonHostInterface::CreateHostDisplayResources()
{
m_logo_texture = m_display->CreateTexture(APP_ICON_WIDTH, APP_ICON_HEIGHT, 1, 1, 1, HostDisplayPixelFormat::RGBA8,
@ -451,14 +468,83 @@ bool CommonHostInterface::CreateHostDisplayResources()
if (!m_logo_texture)
Log_WarningPrintf("Failed to create logo texture");
const float framebuffer_scale = m_display->GetWindowScale();
ImGui::GetIO().DisplayFramebufferScale = ImVec2(framebuffer_scale, framebuffer_scale);
ImGui::GetStyle() = ImGuiStyle();
ImGui::StyleColorsDarker();
ImGui::GetStyle().ScaleAllSizes(framebuffer_scale);
if (!m_display->CreateImGuiContext())
{
Log_ErrorPrintf("Failed to create ImGui device context");
return false;
}
if (m_fullscreen_ui_enabled)
{
if (!FullscreenUI::Initialize(this))
{
Log_ErrorPrintf("Failed to initialize fullscreen UI, disabling.");
m_fullscreen_ui_enabled = false;
}
}
if (!m_fullscreen_ui_enabled)
ImGuiFullscreen::ResetFonts();
if (!m_display->UpdateImGuiFontTexture())
{
Log_ErrorPrintf("Failed to create ImGui font text");
if (m_fullscreen_ui_enabled)
FullscreenUI::Shutdown();
m_display->DestroyImGuiContext();
return false;
}
return true;
}
void CommonHostInterface::ReleaseHostDisplayResources()
{
if (m_fullscreen_ui_enabled)
FullscreenUI::Shutdown();
if (m_display)
m_display->DestroyImGuiContext();
m_logo_texture.reset();
}
void CommonHostInterface::OnHostDisplayResized(u32 new_width, u32 new_height, float new_scale)
{
if (new_scale != ImGui::GetIO().DisplayFramebufferScale.x)
{
ImGui::GetIO().DisplayFramebufferScale = ImVec2(new_scale, new_scale);
ImGui::GetStyle() = ImGuiStyle();
ImGui::StyleColorsDarker();
ImGui::GetStyle().ScaleAllSizes(new_scale);
ImGuiFullscreen::ResetFonts();
if (!m_display->UpdateImGuiFontTexture())
Panic("Failed to recreate font texture after resize");
}
if (m_fullscreen_ui_enabled)
{
if (ImGuiFullscreen::UpdateLayoutScale())
{
if (ImGuiFullscreen::UpdateFonts())
{
if (!m_display->UpdateImGuiFontTexture())
Panic("Failed to update font texture");
}
}
}
if (!System::IsShutdown())
g_gpu->UpdateResolutionScale();
}
std::unique_ptr<AudioStream> CommonHostInterface::CreateAudioStream(AudioBackend backend)
{
switch (backend)
@ -492,7 +578,7 @@ void CommonHostInterface::UpdateControllerInterface()
ControllerInterface::ParseBackendName(backend_str.c_str());
const ControllerInterface::Backend current_backend =
(m_controller_interface ? m_controller_interface->GetBackend() : ControllerInterface::Backend::None);
if (new_backend == current_backend || m_command_line_flags.disable_controller_interface)
if (new_backend == current_backend || m_flags.disable_controller_interface)
return;
if (m_controller_interface)
@ -781,6 +867,9 @@ void CommonHostInterface::OnSystemCreated()
{
HostInterface::OnSystemCreated();
if (m_fullscreen_ui_enabled)
FullscreenUI::SystemCreated();
if (g_settings.display_post_processing && !m_display->SetPostProcessingChain(g_settings.display_post_process_chain))
AddOSDMessage(TranslateStdString("OSDMessage", "Failed to load post processing shader chain."), 20.0f);
}
@ -789,6 +878,9 @@ void CommonHostInterface::OnSystemPaused(bool paused)
{
ReportFormattedMessage("System %s.", paused ? "paused" : "resumed");
if (m_fullscreen_ui_enabled)
FullscreenUI::SystemPaused(paused);
if (paused)
{
if (IsFullscreen() && !m_fullscreen_ui_enabled)
@ -808,6 +900,9 @@ void CommonHostInterface::OnSystemDestroyed()
HostInterface::OnSystemDestroyed();
if (m_fullscreen_ui_enabled)
FullscreenUI::SystemDestroyed();
StopControllerRumble();
}
@ -837,6 +932,9 @@ void CommonHostInterface::OnControllerTypeChanged(u32 slot)
void CommonHostInterface::DrawImGuiWindows()
{
if (m_save_state_selector_ui->IsOpen())
m_save_state_selector_ui->Draw();
if (m_fullscreen_ui_enabled)
{
FullscreenUI::Render();
@ -850,9 +948,6 @@ void CommonHostInterface::DrawImGuiWindows()
}
DrawOSDMessages();
if (m_save_state_selector_ui->IsOpen())
m_save_state_selector_ui->Draw();
}
void CommonHostInterface::DrawFPSWindow()
@ -2383,6 +2478,36 @@ void CommonHostInterface::LoadSettings(SettingsInterface& si)
#ifdef WITH_DISCORD_PRESENCE
SetDiscordPresenceEnabled(si.GetBoolValue("Main", "EnableDiscordPresence", false));
#endif
const bool fullscreen_ui_enabled =
si.GetBoolValue("Main", "EnableFullscreenUI", false) || m_flags.force_fullscreen_ui;
if (fullscreen_ui_enabled != m_fullscreen_ui_enabled)
{
m_fullscreen_ui_enabled = fullscreen_ui_enabled;
if (m_display)
{
if (!fullscreen_ui_enabled)
{
FullscreenUI::Shutdown();
ImGuiFullscreen::ResetFonts();
if (!m_display->UpdateImGuiFontTexture())
Panic("Failed to recreate font texture after fullscreen UI disable");
}
else
{
if (FullscreenUI::Initialize(this))
{
if (!m_display->UpdateImGuiFontTexture())
Panic("Failed to recreate font textre after fullscreen UI enable");
}
else
{
Log_ErrorPrintf("Failed to initialize fullscreen UI. Disabling.");
m_fullscreen_ui_enabled = false;
}
}
}
}
}
void CommonHostInterface::SaveSettings(SettingsInterface& si)

View File

@ -122,6 +122,7 @@ public:
virtual bool SetFullscreen(bool enabled);
virtual bool Initialize() override;
virtual void Shutdown() override;
virtual bool BootSystem(const SystemBootParameters& parameters) override;
@ -141,7 +142,7 @@ public:
ALWAYS_INLINE ControllerInterface* GetControllerInterface() const { return m_controller_interface.get(); }
/// Returns true if running in batch mode, i.e. exit after emulation.
ALWAYS_INLINE bool InBatchMode() const { return m_command_line_flags.batch_mode; }
ALWAYS_INLINE bool InBatchMode() const { return m_flags.batch_mode; }
/// Returns true if the fullscreen UI is enabled.
ALWAYS_INLINE bool IsFullscreenUIEnabled() const { return m_fullscreen_ui_enabled; }
@ -390,6 +391,7 @@ protected:
bool CreateHostDisplayResources();
void ReleaseHostDisplayResources();
void OnHostDisplayResized(u32 new_width, u32 new_height, float new_scale);
virtual void DrawImGuiWindows();
@ -430,7 +432,10 @@ protected:
// starting fullscreen (outside of boot options)
BitField<u8, bool, 2, 1> start_fullscreen;
} m_command_line_flags = {};
// force fullscreen UI enabled (nogui)
BitField<u8, bool, 3, 1> force_fullscreen_ui;
} m_flags = {};
private:
void LoadSettings();
@ -444,6 +449,7 @@ private:
bool UpdateControllerInputMapFromGameSettings();
void UpdateHotkeyInputMap(SettingsInterface& si);
void ClearAllControllerBindings();
void CreateImGuiContext();
#ifdef WITH_DISCORD_PRESENCE
void SetDiscordPresenceEnabled(bool enabled);

View File

@ -35,6 +35,8 @@ Log_SetChannel(FullscreenUI);
static constexpr float LAYOUT_MAIN_MENU_BAR_SIZE = 20.0f; // Should be DPI scaled, not layout scaled!
using ImGuiFullscreen::g_large_font;
using ImGuiFullscreen::g_layout_padding_left;
using ImGuiFullscreen::g_layout_padding_top;
using ImGuiFullscreen::g_medium_font;
using ImGuiFullscreen::LAYOUT_LARGE_FONT_SIZE;
using ImGuiFullscreen::LAYOUT_MEDIUM_FONT_SIZE;
@ -171,7 +173,6 @@ static bool s_save_state_selector_loading = true;
//////////////////////////////////////////////////////////////////////////
static void DrawGameListWindow();
static void SwitchToGameList();
static void QueueGameListRefresh();
static void SortGameList();
static HostDisplayTexture* GetTextureForGameListEntryType(GameListEntryType type);
static HostDisplayTexture* GetGameListCover(const GameListEntry* entry);
@ -194,12 +195,16 @@ bool Initialize(CommonHostInterface* host_interface)
s_settings_copy.Load(*s_host_interface->GetSettingsInterface());
SetDebugMenuEnabled(s_host_interface->GetSettingsInterface()->GetBoolValue("Main", "ShowDebugMenu", false));
QueueGameListRefresh();
ImGuiFullscreen::UpdateLayoutScale();
ImGuiFullscreen::UpdateFonts();
ImGuiFullscreen::SetResolveTextureFunction(ResolveTextureHandle);
if (System::IsValid())
SystemCreated();
if (System::IsPaused())
SystemPaused(true);
return true;
}

View File

@ -54,6 +54,7 @@ bool InvalidateCachedTexture(const std::string& path);
bool DrawErrorWindow(const char* message);
bool DrawConfirmWindow(const char* message, bool* result);
void QueueGameListRefresh();
void EnsureGameListLoaded();
Settings& GetSettingsCopy();

View File

@ -47,10 +47,18 @@ void SetFontFilename(const char* filename)
std::string().swap(s_font_filename);
}
void SetIconFontFilename(const char* icon_font_filename)
void SetFontFilename(std::string filename)
{
if (icon_font_filename)
s_icon_font_filename = icon_font_filename;
if (!filename.empty())
s_font_filename = std::move(filename);
else
std::string().swap(s_font_filename);
}
void SetIconFontFilename(std::string icon_font_filename)
{
if (!icon_font_filename.empty())
s_icon_font_filename = std::move(icon_font_filename);
else
std::string().swap(s_icon_font_filename);
}
@ -111,8 +119,8 @@ bool UpdateFonts()
const float medium_font_size = std::ceil(LayoutScale(LAYOUT_MEDIUM_FONT_SIZE));
const float large_font_size = std::ceil(LayoutScale(LAYOUT_LARGE_FONT_SIZE));
if (g_standard_font && g_standard_font->FontSize == standard_font_size && medium_font_size &&
g_medium_font->FontSize == medium_font_size && large_font_size && g_large_font->FontSize == large_font_size)
if (g_standard_font && g_standard_font->FontSize == standard_font_size && g_medium_font &&
g_medium_font->FontSize == medium_font_size && g_large_font && g_large_font->FontSize == large_font_size)
{
return false;
}
@ -147,6 +155,30 @@ bool UpdateFonts()
return true;
}
void ResetFonts()
{
const float standard_font_size = std::ceil(DPIScale(s_font_size));
ImGuiIO& io = ImGui::GetIO();
io.Fonts->Clear();
if (s_font_filename.empty())
{
g_standard_font = ImGui::AddRobotoRegularFont(standard_font_size);
}
else
{
g_standard_font =
io.Fonts->AddFontFromFileTTF(s_font_filename.c_str(), standard_font_size, nullptr, s_font_glyph_range);
}
g_medium_font = nullptr;
g_large_font = nullptr;
if (!io.Fonts->Build())
Panic("Failed to rebuild font atlas");
}
bool UpdateLayoutScale()
{
static constexpr float LAYOUT_RATIO = LAYOUT_SCREEN_WIDTH / LAYOUT_SCREEN_HEIGHT;

View File

@ -141,6 +141,9 @@ void SetResolveTextureFunction(ResolveTextureHandleCallback callback);
/// Rebuilds fonts to a new scale if needed. Returns true if fonts have changed and the texture needs updating.
bool UpdateFonts();
/// Removes the fullscreen fonts, leaving only the standard font.
void ResetFonts();
bool UpdateLayoutScale();
void BeginLayout();