Add "Fullscreen UI"
After Width: | Height: | Size: 120 KiB |
After Width: | Height: | Size: 117 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 202 KiB |
After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 6.0 KiB |
After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 5.8 KiB |
@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
#include "common/types.h"
|
||||
|
||||
class CommonHostInterface;
|
||||
class SettingsInterface;
|
||||
struct Settings;
|
||||
|
||||
namespace FrontendCommon {
|
||||
enum class ControllerNavigationButton : u32;
|
||||
}
|
||||
|
||||
namespace FullscreenUI {
|
||||
enum class MainWindowType
|
||||
{
|
||||
None,
|
||||
Landing,
|
||||
GameList,
|
||||
Settings,
|
||||
QuickMenu,
|
||||
MoreQuickMenu
|
||||
};
|
||||
|
||||
enum class SettingsPage
|
||||
{
|
||||
InterfaceSettings,
|
||||
GameListSettings,
|
||||
ConsoleSettings,
|
||||
EmulationSettings,
|
||||
BIOSSettings,
|
||||
ControllerSettings,
|
||||
HotkeySettings,
|
||||
MemoryCardSettings,
|
||||
DisplaySettings,
|
||||
EnhancementSettings,
|
||||
AudioSettings,
|
||||
AdvancedSettings,
|
||||
Count
|
||||
};
|
||||
|
||||
bool Initialize(CommonHostInterface* host_interface, SettingsInterface* settings_interface);
|
||||
bool HasActiveWindow();
|
||||
void SystemCreated();
|
||||
void SystemDestroyed();
|
||||
void SystemPaused(bool paused);
|
||||
void OpenQuickMenu();
|
||||
void CloseQuickMenu();
|
||||
void Shutdown();
|
||||
void Render();
|
||||
|
||||
void EnsureGameListLoaded();
|
||||
|
||||
Settings& GetSettingsCopy();
|
||||
void SaveAndApplySettings();
|
||||
void SetDebugMenuEnabled(bool enabled, bool save_to_ini = false);
|
||||
|
||||
/// Only ImGuiNavInput_Activate, ImGuiNavInput_Cancel, and DPad should be forwarded.
|
||||
/// Returns true if the UI consumed the event, and it should not execute the normal handler.
|
||||
bool SetControllerNavInput(FrontendCommon::ControllerNavigationButton button, bool value);
|
||||
|
||||
/// Forwards the controller navigation to ImGui for fullscreen navigation. Call before NewFrame().
|
||||
void SetImGuiNavInputs();
|
||||
|
||||
} // namespace FullscreenUI
|
@ -0,0 +1,117 @@
|
||||
#include "fullscreen_ui_progress_callback.h"
|
||||
#include "common/log.h"
|
||||
#include "core/host_interface.h"
|
||||
#include "imgui_fullscreen.h"
|
||||
Log_SetChannel(ProgressCallback);
|
||||
|
||||
namespace FullscreenUI {
|
||||
|
||||
ProgressCallback::ProgressCallback(String name) : BaseProgressCallback(), m_name(std::move(name))
|
||||
{
|
||||
ImGuiFullscreen::OpenBackgroundProgressDialog(m_name, "", 0, 100, 0);
|
||||
}
|
||||
|
||||
ProgressCallback::~ProgressCallback()
|
||||
{
|
||||
ImGuiFullscreen::CloseBackgroundProgressDialog(m_name);
|
||||
}
|
||||
|
||||
void ProgressCallback::PushState()
|
||||
{
|
||||
BaseProgressCallback::PushState();
|
||||
}
|
||||
|
||||
void ProgressCallback::PopState()
|
||||
{
|
||||
BaseProgressCallback::PopState();
|
||||
Redraw(true);
|
||||
}
|
||||
|
||||
void ProgressCallback::SetCancellable(bool cancellable)
|
||||
{
|
||||
BaseProgressCallback::SetCancellable(cancellable);
|
||||
Redraw(true);
|
||||
}
|
||||
|
||||
void ProgressCallback::SetTitle(const char* title)
|
||||
{
|
||||
// todo?
|
||||
}
|
||||
|
||||
void ProgressCallback::SetStatusText(const char* text)
|
||||
{
|
||||
BaseProgressCallback::SetStatusText(text);
|
||||
Redraw(true);
|
||||
}
|
||||
|
||||
void ProgressCallback::SetProgressRange(u32 range)
|
||||
{
|
||||
u32 last_range = m_progress_range;
|
||||
|
||||
BaseProgressCallback::SetProgressRange(range);
|
||||
|
||||
if (m_progress_range != last_range)
|
||||
Redraw(false);
|
||||
}
|
||||
|
||||
void ProgressCallback::SetProgressValue(u32 value)
|
||||
{
|
||||
u32 lastValue = m_progress_value;
|
||||
|
||||
BaseProgressCallback::SetProgressValue(value);
|
||||
|
||||
if (m_progress_value != lastValue)
|
||||
Redraw(false);
|
||||
}
|
||||
|
||||
void ProgressCallback::Redraw(bool force)
|
||||
{
|
||||
const int percent =
|
||||
static_cast<int>((static_cast<float>(m_progress_value) / static_cast<float>(m_progress_range)) * 100.0f);
|
||||
if (percent == m_last_progress_percent && !force)
|
||||
return;
|
||||
|
||||
m_last_progress_percent = percent;
|
||||
ImGuiFullscreen::UpdateBackgroundProgressDialog(
|
||||
m_name, m_status_text.GetCharArray(), 0, 100, percent);
|
||||
}
|
||||
|
||||
void ProgressCallback::DisplayError(const char* message)
|
||||
{
|
||||
Log_ErrorPrint(message);
|
||||
}
|
||||
|
||||
void ProgressCallback::DisplayWarning(const char* message)
|
||||
{
|
||||
Log_WarningPrint(message);
|
||||
}
|
||||
|
||||
void ProgressCallback::DisplayInformation(const char* message)
|
||||
{
|
||||
Log_InfoPrint(message);
|
||||
}
|
||||
|
||||
void ProgressCallback::DisplayDebugMessage(const char* message)
|
||||
{
|
||||
Log_DevPrint(message);
|
||||
}
|
||||
|
||||
void ProgressCallback::ModalError(const char* message)
|
||||
{
|
||||
Log_ErrorPrint(message);
|
||||
g_host_interface->ReportError(message);
|
||||
}
|
||||
|
||||
bool ProgressCallback::ModalConfirmation(const char* message)
|
||||
{
|
||||
Log_InfoPrint(message);
|
||||
return g_host_interface->ConfirmMessage(message);
|
||||
}
|
||||
|
||||
void ProgressCallback::ModalInformation(const char* message)
|
||||
{
|
||||
Log_InfoPrint(message);
|
||||
g_host_interface->ReportMessage(message);
|
||||
}
|
||||
|
||||
} // namespace FullscreenUI
|
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include "common/progress_callback.h"
|
||||
#include "common/string.h"
|
||||
|
||||
namespace FullscreenUI {
|
||||
|
||||
class ProgressCallback final : public BaseProgressCallback
|
||||
{
|
||||
public:
|
||||
ProgressCallback(String name);
|
||||
~ProgressCallback() override;
|
||||
|
||||
void PushState() override;
|
||||
void PopState() override;
|
||||
|
||||
void SetCancellable(bool cancellable) override;
|
||||
void SetTitle(const char* title) override;
|
||||
void SetStatusText(const char* text) override;
|
||||
void SetProgressRange(u32 range) override;
|
||||
void SetProgressValue(u32 value) override;
|
||||
|
||||
void DisplayError(const char* message) override;
|
||||
void DisplayWarning(const char* message) override;
|
||||
void DisplayInformation(const char* message) override;
|
||||
void DisplayDebugMessage(const char* message) override;
|
||||
|
||||
void ModalError(const char* message) override;
|
||||
bool ModalConfirmation(const char* message) override;
|
||||
void ModalInformation(const char* message) override;
|
||||
|
||||
private:
|
||||
void Redraw(bool force);
|
||||
|
||||
String m_name;
|
||||
int m_last_progress_percent = -1;
|
||||
};
|
||||
|
||||
} // namespace FullscreenUI
|
@ -0,0 +1,226 @@
|
||||
#pragma once
|
||||
#include "common/types.h"
|
||||
#include "imgui.h"
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
namespace ImGuiFullscreen {
|
||||
#define HEX_TO_IMVEC4(hex, alpha) \
|
||||
ImVec4(static_cast<float>((hex >> 16) & 0xFFu) / 255.0f, static_cast<float>((hex >> 8) & 0xFFu) / 255.0f, \
|
||||
static_cast<float>(hex & 0xFFu) / 255.0f, static_cast<float>(alpha) / 255.0f)
|
||||
|
||||
static constexpr float LAYOUT_SCREEN_WIDTH = 1280.0f;
|
||||
static constexpr float LAYOUT_SCREEN_HEIGHT = 720.0f;
|
||||
static constexpr float LAYOUT_LARGE_FONT_SIZE = 26.0f;
|
||||
static constexpr float LAYOUT_MEDIUM_FONT_SIZE = 16.0f;
|
||||
static constexpr float LAYOUT_SMALL_FONT_SIZE = 10.0f;
|
||||
static constexpr float LAYOUT_MENU_BUTTON_HEIGHT = 50.0f;
|
||||
static constexpr float LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY = 26.0f;
|
||||
static constexpr float LAYOUT_MENU_BUTTON_X_PADDING = 15.0f;
|
||||
static constexpr float LAYOUT_MENU_BUTTON_Y_PADDING = 10.0f;
|
||||
|
||||
extern ImFont* g_standard_font;
|
||||
extern ImFont* g_medium_font;
|
||||
extern ImFont* g_large_font;
|
||||
|
||||
extern float g_layout_scale;
|
||||
extern float g_layout_padding_left;
|
||||
extern float g_layout_padding_top;
|
||||
|
||||
static ALWAYS_INLINE float DPIScale(float v)
|
||||
{
|
||||
return ImGui::GetIO().DisplayFramebufferScale.x * v;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE float DPIScale(int v)
|
||||
{
|
||||
return ImGui::GetIO().DisplayFramebufferScale.x * static_cast<float>(v);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE ImVec2 DPIScale(const ImVec2& v)
|
||||
{
|
||||
const ImVec2& fbs = ImGui::GetIO().DisplayFramebufferScale;
|
||||
return ImVec2(v.x * fbs.x, v.y * fbs.y);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE float WindowWidthScale(float v)
|
||||
{
|
||||
return ImGui::GetWindowWidth() * v;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE float WindowHeightScale(float v)
|
||||
{
|
||||
return ImGui::GetWindowHeight() * v;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE float LayoutScale(float v)
|
||||
{
|
||||
return g_layout_scale * v;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE ImVec2 LayoutScale(const ImVec2& v)
|
||||
{
|
||||
return ImVec2(v.x * g_layout_scale, v.y * g_layout_scale);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE ImVec2 LayoutScale(float x, float y)
|
||||
{
|
||||
return ImVec2(x * g_layout_scale, y * g_layout_scale);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE ImVec4 UIPrimaryColor()
|
||||
{
|
||||
return HEX_TO_IMVEC4(0x212121, 0xff);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE ImVec4 UIPrimaryLightColor()
|
||||
{
|
||||
return HEX_TO_IMVEC4(0x484848, 0xff);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE ImVec4 UIPrimaryDarkColor()
|
||||
{
|
||||
return HEX_TO_IMVEC4(0x484848, 0xff);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE ImVec4 UIPrimaryTextColor()
|
||||
{
|
||||
return HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE ImVec4 UIPrimaryDisabledTextColor()
|
||||
{
|
||||
return HEX_TO_IMVEC4(0xaaaaaa, 0xff);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE ImVec4 UITextHighlightColor()
|
||||
{
|
||||
return HEX_TO_IMVEC4(0x90caf9, 0xff);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE ImVec4 UIPrimaryLineColor()
|
||||
{
|
||||
return HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE ImVec4 UISecondaryColor()
|
||||
{
|
||||
return HEX_TO_IMVEC4(0x1565c0, 0xff);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE ImVec4 UISecondaryLightColor()
|
||||
{
|
||||
return HEX_TO_IMVEC4(0x5e92f3, 0xff);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE ImVec4 UISecondaryDarkColor()
|
||||
{
|
||||
return HEX_TO_IMVEC4(0x003c8f, 0xff);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE ImVec4 UISecondaryTextColor()
|
||||
{
|
||||
return HEX_TO_IMVEC4(0xffffff, 0xff);
|
||||
}
|
||||
|
||||
void SetFontFilename(std::string filename);
|
||||
void SetIconFontFilename(std::string icon_font_filename);
|
||||
void SetIconFontData(std::vector<u8> data);
|
||||
void SetFontSize(float size_pixels);
|
||||
void SetFontGlyphRanges(const ImWchar* glyph_ranges);
|
||||
|
||||
/// Changes the menu bar size. Don't forget to call UpdateLayoutScale() and UpdateFonts().
|
||||
void SetMenuBarSize(float size);
|
||||
|
||||
/// Rebuilds fonts to a new scale if needed. Returns true if fonts have changed and the texture needs updating.
|
||||
bool UpdateFonts();
|
||||
|
||||
bool UpdateLayoutScale();
|
||||
|
||||
void BeginLayout();
|
||||
void EndLayout();
|
||||
|
||||
void DrawWindowTitle(const char* title);
|
||||
|
||||
bool BeginFullscreenColumns(const char* title = nullptr);
|
||||
void EndFullscreenColumns();
|
||||
|
||||
bool BeginFullscreenColumnWindow(float start, float end, const char* name,
|
||||
const ImVec4& background = HEX_TO_IMVEC4(0x212121, 0xFF));
|
||||
void EndFullscreenColumnWindow();
|
||||
|
||||
bool BeginFullscreenWindow(float left, float top, float width, float height, const char* name,
|
||||
const ImVec4& background = HEX_TO_IMVEC4(0x212121, 0xFF), float rounding = 0.0f,
|
||||
float padding = 0.0f, ImGuiWindowFlags flags = 0);
|
||||
void EndFullscreenWindow();
|
||||
|
||||
void BeginMenuButtons(u32 num_items = 0, float y_align = 0.0f, float x_padding = LAYOUT_MENU_BUTTON_X_PADDING,
|
||||
float y_padding = LAYOUT_MENU_BUTTON_Y_PADDING, float item_height = LAYOUT_MENU_BUTTON_HEIGHT);
|
||||
void EndMenuButtons();
|
||||
bool MenuButtonFrame(const char* str_id, bool enabled, float height, bool* visible, bool* hovered, ImVec2* min,
|
||||
ImVec2* max, ImGuiButtonFlags flags = 0);
|
||||
void MenuHeading(const char* title, bool draw_line = true);
|
||||
bool ActiveButton(const char* title, bool is_active, bool enabled = true,
|
||||
float height = LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, ImFont* font = g_large_font);
|
||||
bool MenuButton(const char* title, const char* summary, bool enabled = true, float height = LAYOUT_MENU_BUTTON_HEIGHT,
|
||||
ImFont* font = g_large_font, ImFont* summary_font = g_medium_font);
|
||||
bool MenuButtonWithValue(const char* title, const char* summary, const char* value, bool enabled = true,
|
||||
float height = LAYOUT_MENU_BUTTON_HEIGHT, ImFont* font = g_large_font,
|
||||
ImFont* summary_font = g_medium_font);
|
||||
bool MenuImageButton(const char* title, const char* summary, ImTextureID user_texture_id, const ImVec2& image_size,
|
||||
bool enabled = true, float height = LAYOUT_MENU_BUTTON_HEIGHT,
|
||||
const ImVec2& uv0 = ImVec2(0.0f, 0.0f), const ImVec2& uv1 = ImVec2(1.0f, 1.0f),
|
||||
ImFont* font = g_large_font, ImFont* summary_font = g_medium_font);
|
||||
bool ToggleButton(const char* title, const char* summary, bool* v, bool enabled = true,
|
||||
float height = LAYOUT_MENU_BUTTON_HEIGHT, ImFont* font = g_large_font,
|
||||
ImFont* summary_font = g_medium_font);
|
||||
bool RangeButton(const char* title, const char* summary, s32* value, s32 min, s32 max, s32 increment,
|
||||
const char* format = "%d", bool enabled = true, float height = LAYOUT_MENU_BUTTON_HEIGHT,
|
||||
ImFont* font = g_large_font, ImFont* summary_font = g_medium_font);
|
||||
bool RangeButton(const char* title, const char* summary, float* value, float min, float max, float increment,
|
||||
const char* format = "%f", bool enabled = true, float height = LAYOUT_MENU_BUTTON_HEIGHT,
|
||||
ImFont* font = g_large_font, ImFont* summary_font = g_medium_font);
|
||||
bool EnumChoiceButtonImpl(const char* title, const char* summary, s32* value_pointer,
|
||||
const char* (*to_display_name_function)(s32 value, void* opaque), void* opaque, u32 count,
|
||||
bool enabled, float height, ImFont* font, ImFont* summary_font);
|
||||
|
||||
template<typename DataType, typename CountType>
|
||||
static ALWAYS_INLINE bool EnumChoiceButton(const char* title, const char* summary, DataType* value_pointer,
|
||||
const char* (*to_display_name_function)(DataType value), CountType count,
|
||||
bool enabled = true, float height = LAYOUT_MENU_BUTTON_HEIGHT,
|
||||
ImFont* font = g_large_font, ImFont* summary_font = g_medium_font)
|
||||
{
|
||||
s32 value = static_cast<s32>(*value_pointer);
|
||||
auto to_display_name_wrapper = [](s32 value, void* opaque) -> const char* {
|
||||
return (*static_cast<decltype(to_display_name_function)*>(opaque))(static_cast<DataType>(value));
|
||||
};
|
||||
|
||||
if (EnumChoiceButtonImpl(title, summary, &value, to_display_name_wrapper, &to_display_name_function,
|
||||
static_cast<u32>(count), enabled, height, font, summary_font))
|
||||
{
|
||||
*value_pointer = static_cast<DataType>(value);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
using FileSelectorCallback = std::function<void(const std::string& path)>;
|
||||
using FileSelectorFilters = std::vector<std::string>;
|
||||
void OpenFileSelector(const char* title, bool select_directory, FileSelectorCallback callback,
|
||||
FileSelectorFilters filters = FileSelectorFilters(),
|
||||
std::string initial_directory = std::string());
|
||||
void CloseFileSelector();
|
||||
|
||||
using ChoiceDialogCallback = std::function<void(s32 index, const std::string& title, bool checked)>;
|
||||
using ChoiceDialogOptions = std::vector<std::pair<std::string, bool>>;
|
||||
void OpenChoiceDialog(const char* title, bool checkable, ChoiceDialogOptions options, ChoiceDialogCallback callback);
|
||||
void CloseChoiceDialog();
|
||||
|
||||
void OpenBackgroundProgressDialog(const char* str_id, std::string message, s32 min, s32 max, s32 value);
|
||||
void UpdateBackgroundProgressDialog(const char* str_id, std::string message, s32 min, s32 max, s32 value);
|
||||
void CloseBackgroundProgressDialog(const char* str_id);
|
||||
|
||||
} // namespace ImGuiFullscreen
|