2026-01-12 05:18:12 -05:00
|
|
|
// SPDX-FileCopyrightText: 2002-2026 PCSX2 Dev Team
|
2024-07-30 13:42:36 +02:00
|
|
|
// SPDX-License-Identifier: GPL-3.0+
|
2022-05-15 18:20:21 +10:00
|
|
|
|
|
|
|
|
#pragma once
|
2024-04-13 00:53:58 +10:00
|
|
|
|
2022-05-15 18:20:21 +10:00
|
|
|
#include "common/Pcsx2Defs.h"
|
2024-04-13 00:53:58 +10:00
|
|
|
|
2025-12-27 20:58:33 +07:00
|
|
|
#include "IconsFontAwesome.h"
|
2022-05-15 18:20:21 +10:00
|
|
|
#include "imgui.h"
|
|
|
|
|
#include "imgui_internal.h"
|
2024-04-13 00:53:58 +10:00
|
|
|
|
2022-05-15 18:20:21 +10:00
|
|
|
#include <functional>
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <optional>
|
2024-04-13 00:53:58 +10:00
|
|
|
#include <span>
|
2022-05-15 18:20:21 +10:00
|
|
|
#include <string>
|
2022-10-10 23:35:59 +10:00
|
|
|
#include <string_view>
|
2022-05-15 18:20:21 +10:00
|
|
|
#include <vector>
|
|
|
|
|
|
2023-04-01 15:54:04 +10:00
|
|
|
class GSTexture;
|
2025-03-05 21:55:05 +00:00
|
|
|
enum class InputLayout : u8;
|
2022-05-15 18:20:21 +10:00
|
|
|
|
|
|
|
|
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;
|
2025-11-21 00:54:42 -06:00
|
|
|
static constexpr float LAYOUT_LARGE_FONT_SIZE = 22.0f;
|
|
|
|
|
static constexpr float LAYOUT_MEDIUM_FONT_SIZE = 14.0f;
|
2022-05-15 18:20:21 +10:00
|
|
|
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;
|
2024-05-15 07:18:39 +10:00
|
|
|
static constexpr float LAYOUT_MENU_WINDOW_X_PADDING = 12.0f;
|
2024-04-13 00:53:58 +10:00
|
|
|
static constexpr float LAYOUT_FOOTER_PADDING = 10.0f;
|
|
|
|
|
static constexpr float LAYOUT_FOOTER_HEIGHT = LAYOUT_MEDIUM_FONT_SIZE + LAYOUT_FOOTER_PADDING * 2.0f;
|
|
|
|
|
static constexpr float LAYOUT_HORIZONTAL_MENU_HEIGHT = 320.0f;
|
|
|
|
|
static constexpr float LAYOUT_HORIZONTAL_MENU_PADDING = 30.0f;
|
|
|
|
|
static constexpr float LAYOUT_HORIZONTAL_MENU_ITEM_WIDTH = 250.0f;
|
2026-04-10 07:50:03 -04:00
|
|
|
static constexpr float LAYOUT_WINDOW_ROUNDING = 8.0f;
|
|
|
|
|
static constexpr float LAYOUT_FRAME_ROUNDING = 6.0f;
|
|
|
|
|
static constexpr float LAYOUT_SCROLLBAR_ROUNDING = 5.0f;
|
2022-05-15 18:20:21 +10:00
|
|
|
|
2025-07-05 20:03:45 +01:00
|
|
|
extern std::pair<ImFont*, float> g_standard_font;
|
|
|
|
|
extern std::pair<ImFont*, float> g_medium_font;
|
|
|
|
|
extern std::pair<ImFont*, float> g_large_font;
|
2022-05-15 18:20:21 +10:00
|
|
|
|
|
|
|
|
extern float g_layout_scale;
|
2023-12-31 02:43:06 +10:00
|
|
|
extern float g_rcp_layout_scale;
|
2022-05-15 18:20:21 +10:00
|
|
|
extern float g_layout_padding_left;
|
|
|
|
|
extern float g_layout_padding_top;
|
|
|
|
|
|
|
|
|
|
extern ImVec4 UIBackgroundColor;
|
|
|
|
|
extern ImVec4 UIBackgroundTextColor;
|
|
|
|
|
extern ImVec4 UIBackgroundLineColor;
|
|
|
|
|
extern ImVec4 UIBackgroundHighlightColor;
|
2024-04-13 01:16:01 +10:00
|
|
|
extern ImVec4 UIPopupBackgroundColor;
|
2022-05-15 18:20:21 +10:00
|
|
|
extern ImVec4 UIDisabledColor;
|
|
|
|
|
extern ImVec4 UIPrimaryColor;
|
|
|
|
|
extern ImVec4 UIPrimaryLightColor;
|
|
|
|
|
extern ImVec4 UIPrimaryDarkColor;
|
|
|
|
|
extern ImVec4 UIPrimaryTextColor;
|
|
|
|
|
extern ImVec4 UITextHighlightColor;
|
|
|
|
|
extern ImVec4 UIPrimaryLineColor;
|
|
|
|
|
extern ImVec4 UISecondaryColor;
|
2023-07-16 19:41:18 -05:00
|
|
|
extern ImVec4 UISecondaryStrongColor;
|
|
|
|
|
extern ImVec4 UISecondaryWeakColor;
|
2022-05-15 18:20:21 +10:00
|
|
|
extern ImVec4 UISecondaryTextColor;
|
|
|
|
|
|
2024-05-15 07:03:54 +10:00
|
|
|
static __fi float LayoutScale(float v) { return ImCeil(g_layout_scale * v); }
|
|
|
|
|
static __fi ImVec2 LayoutScale(const ImVec2& v) { return ImVec2(ImCeil(v.x * g_layout_scale), ImCeil(v.y * g_layout_scale)); }
|
|
|
|
|
static __fi ImVec2 LayoutScale(float x, float y) { return ImVec2(ImCeil(x * g_layout_scale), ImCeil(y * g_layout_scale)); }
|
2025-11-21 00:54:42 -06:00
|
|
|
/// Get the height of a line of text including the space to the next line.
|
|
|
|
|
/// Matches the result returned by CalcTextSizeA for one line of text.
|
|
|
|
|
static __fi float GetLineHeight(std::pair<ImFont*, float> font) { return ImCeil(font.second * font.first->LineHeight); }
|
2022-05-15 18:20:21 +10:00
|
|
|
|
2024-05-15 07:03:54 +10:00
|
|
|
static __fi float LayoutUnscale(float v) { return ImCeil(g_rcp_layout_scale * v); }
|
|
|
|
|
static __fi ImVec2 LayoutUnscale(const ImVec2& v) { return ImVec2(ImCeil(v.x * g_rcp_layout_scale), ImCeil(v.y * g_rcp_layout_scale)); }
|
|
|
|
|
static __fi ImVec2 LayoutUnscale(float x, float y) { return ImVec2(ImCeil(x * g_rcp_layout_scale), ImCeil(y * g_rcp_layout_scale)); }
|
2023-12-31 02:43:06 +10:00
|
|
|
|
2022-09-07 17:44:10 +10:00
|
|
|
static __fi ImVec4 ModAlpha(const ImVec4& v, float a) { return ImVec4(v.x, v.y, v.z, a); }
|
2022-09-03 15:06:56 +10:00
|
|
|
static __fi ImVec4 MulAlpha(const ImVec4& v, float a) { return ImVec4(v.x, v.y, v.z, v.w * a); }
|
2022-05-15 18:20:21 +10:00
|
|
|
|
2024-05-15 09:42:40 +10:00
|
|
|
static __fi std::string_view RemoveHash(const std::string_view s)
|
2022-10-10 23:35:59 +10:00
|
|
|
{
|
|
|
|
|
const std::string_view::size_type pos = s.find('#');
|
|
|
|
|
return (pos != std::string_view::npos) ? s.substr(0, pos) : s;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-15 18:20:21 +10:00
|
|
|
/// Centers an image within the specified bounds, scaling up or down as needed.
|
2025-04-24 23:14:08 +01:00
|
|
|
ImRect CenterImage(const ImVec2& fit_size, const ImVec2& image_size, bool fill = false);
|
|
|
|
|
ImRect CenterImage(const ImRect& fit_rect, const ImVec2& image_size, bool fill = false);
|
2022-05-15 18:20:21 +10:00
|
|
|
|
|
|
|
|
/// Initializes, setting up any state.
|
|
|
|
|
bool Initialize(const char* placeholder_image_path);
|
|
|
|
|
|
2025-02-23 22:25:49 +07:00
|
|
|
void SetTheme(std::string_view theme);
|
2025-07-05 20:03:45 +01:00
|
|
|
void SetFont(ImFont* standard_font);
|
2022-05-15 18:20:21 +10:00
|
|
|
bool UpdateLayoutScale();
|
2025-07-05 20:03:45 +01:00
|
|
|
void UpdateFontScale();
|
2022-05-15 18:20:21 +10:00
|
|
|
|
2022-12-03 00:38:08 +10:00
|
|
|
/// Shuts down, optionally clearing all state (including notifications).
|
|
|
|
|
void Shutdown(bool clear_state);
|
2022-05-15 18:20:21 +10:00
|
|
|
|
|
|
|
|
/// Texture cache.
|
2023-04-01 15:54:04 +10:00
|
|
|
const std::shared_ptr<GSTexture>& GetPlaceholderTexture();
|
2024-04-13 00:53:58 +10:00
|
|
|
std::shared_ptr<GSTexture> LoadTexture(std::string_view path);
|
|
|
|
|
GSTexture* GetCachedTexture(std::string_view name);
|
|
|
|
|
GSTexture* GetCachedTextureAsync(std::string_view name);
|
2025-04-24 23:14:08 +01:00
|
|
|
enum class SvgScaling : u8
|
|
|
|
|
{
|
|
|
|
|
Stretch,
|
|
|
|
|
Fit,
|
|
|
|
|
ZoomFill,
|
|
|
|
|
};
|
|
|
|
|
std::shared_ptr<GSTexture> LoadSvgTexture(std::string_view path, ImVec2 size, SvgScaling mode = SvgScaling::Stretch);
|
|
|
|
|
GSTexture* GetCachedSvgTexture(std::string_view name, ImVec2 size, SvgScaling mode = SvgScaling::Stretch);
|
|
|
|
|
GSTexture* GetCachedSvgTextureAsync(std::string_view name, ImVec2 size, SvgScaling mode = SvgScaling::Stretch);
|
2022-05-15 18:20:21 +10:00
|
|
|
bool InvalidateCachedTexture(const std::string& path);
|
|
|
|
|
void UploadAsyncTextures();
|
|
|
|
|
|
|
|
|
|
void BeginLayout();
|
|
|
|
|
void EndLayout();
|
|
|
|
|
|
2022-10-10 23:35:59 +10:00
|
|
|
void PushResetLayout();
|
|
|
|
|
void PopResetLayout();
|
|
|
|
|
|
2024-08-18 22:11:55 +07:00
|
|
|
enum class FocusResetType : u8
|
|
|
|
|
{
|
|
|
|
|
None,
|
|
|
|
|
PopupOpened,
|
|
|
|
|
PopupClosed,
|
|
|
|
|
WindowChanged,
|
|
|
|
|
Other,
|
|
|
|
|
};
|
|
|
|
|
void QueueResetFocus(FocusResetType type);
|
2022-05-15 18:20:21 +10:00
|
|
|
bool ResetFocusHere();
|
2024-04-13 00:53:58 +10:00
|
|
|
bool IsFocusResetQueued();
|
2024-08-18 22:11:55 +07:00
|
|
|
FocusResetType GetQueuedFocusResetType();
|
2024-04-13 00:53:58 +10:00
|
|
|
void ForceKeyNavEnabled();
|
|
|
|
|
|
2022-05-15 18:20:21 +10:00
|
|
|
bool WantsToCloseMenu();
|
|
|
|
|
void ResetCloseMenuIfNeeded();
|
|
|
|
|
|
|
|
|
|
void PushPrimaryColor();
|
|
|
|
|
void PopPrimaryColor();
|
|
|
|
|
|
|
|
|
|
void DrawWindowTitle(const char* title);
|
|
|
|
|
|
2024-04-13 00:53:58 +10:00
|
|
|
bool BeginFullscreenColumns(const char* title = nullptr, float pos_y = 0.0f, bool expand_to_screen_width = false, bool footer = false);
|
2022-05-15 18:20:21 +10:00
|
|
|
void EndFullscreenColumns();
|
|
|
|
|
|
|
|
|
|
bool BeginFullscreenColumnWindow(float start, float end, const char* name, const ImVec4& background = UIBackgroundColor);
|
|
|
|
|
void EndFullscreenColumnWindow();
|
|
|
|
|
|
|
|
|
|
bool BeginFullscreenWindow(float left, float top, float width, float height, const char* name,
|
2024-05-15 07:18:39 +10:00
|
|
|
const ImVec4& background = HEX_TO_IMVEC4(0x212121, 0xFF), float rounding = 0.0f, const ImVec2& padding = ImVec2(),
|
|
|
|
|
ImGuiWindowFlags flags = 0);
|
2022-05-15 18:20:21 +10:00
|
|
|
bool BeginFullscreenWindow(const ImVec2& position, const ImVec2& size, const char* name,
|
2024-05-15 07:18:39 +10:00
|
|
|
const ImVec4& background = HEX_TO_IMVEC4(0x212121, 0xFF), float rounding = 0.0f, const ImVec2& padding = ImVec2(),
|
|
|
|
|
ImGuiWindowFlags flags = 0);
|
2022-05-15 18:20:21 +10:00
|
|
|
void EndFullscreenWindow();
|
|
|
|
|
|
2024-04-13 00:53:58 +10:00
|
|
|
bool IsGamepadInputSource();
|
2025-03-05 21:55:05 +00:00
|
|
|
void ReportGamepadLayout(InputLayout layout);
|
|
|
|
|
InputLayout GetGamepadLayout();
|
2026-04-10 07:42:29 -04:00
|
|
|
struct GamepadGlyphs
|
|
|
|
|
{
|
|
|
|
|
const char* south;
|
|
|
|
|
const char* east;
|
|
|
|
|
const char* west;
|
|
|
|
|
const char* north;
|
|
|
|
|
const char* dpad;
|
|
|
|
|
const char* dpad_lr;
|
|
|
|
|
const char* dpad_ud;
|
|
|
|
|
const char* select;
|
|
|
|
|
const char* start;
|
|
|
|
|
|
|
|
|
|
const char* confirm(bool circleOK) const { return circleOK ? east : south; }
|
|
|
|
|
const char* cancel(bool circleOK) const { return circleOK ? south : east; }
|
|
|
|
|
};
|
|
|
|
|
GamepadGlyphs GetGamepadGlyphs();
|
2024-04-13 00:53:58 +10:00
|
|
|
void CreateFooterTextString(SmallStringBase& dest, std::span<const std::pair<const char*, std::string_view>> items);
|
|
|
|
|
void SetFullscreenFooterText(std::string_view text);
|
|
|
|
|
void SetFullscreenFooterText(std::span<const std::pair<const char*, std::string_view>> items);
|
2025-10-19 09:29:08 -04:00
|
|
|
void AppendToFullscreenFooterText(std::span<const std::pair<const char*, std::string_view>> items);
|
|
|
|
|
void QueueFooterHint(std::span<const std::pair<const char*, std::string_view>> items);
|
2024-04-13 00:53:58 +10:00
|
|
|
void DrawFullscreenFooter();
|
|
|
|
|
|
2023-12-14 22:18:13 +10:00
|
|
|
void PrerenderMenuButtonBorder();
|
2026-04-09 03:41:25 -04:00
|
|
|
void AddTextWithShadow(ImDrawList* dl, std::pair<ImFont*, float> font, const ImVec2& pos, ImU32 col, const char* text,
|
|
|
|
|
const char* text_end = nullptr, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = nullptr,
|
|
|
|
|
ImU32 shadow_col = IM_COL32(0, 0, 0, 64), bool strip_id_suffix = false);
|
|
|
|
|
void RenderTextClippedWithShadow(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end = nullptr,
|
|
|
|
|
const ImVec2* text_size_if_known = nullptr, const ImVec2& align = ImVec2(0.0f, 0.0f), const ImRect* clip_rect = nullptr);
|
2022-05-15 18:20:21 +10:00
|
|
|
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();
|
2023-12-11 01:28:55 +10:00
|
|
|
void GetMenuButtonFrameBounds(float height, ImVec2* pos, ImVec2* size);
|
2022-05-15 18:20:21 +10:00
|
|
|
bool MenuButtonFrame(const char* str_id, bool enabled, float height, bool* visible, bool* hovered, ImVec2* min, ImVec2* max,
|
2026-04-10 09:35:42 -04:00
|
|
|
ImGuiButtonFlags flags = 0, float hover_alpha = 0.7f);
|
2023-12-14 22:18:13 +10:00
|
|
|
void DrawMenuButtonFrame(const ImVec2& p_min, const ImVec2& p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f);
|
|
|
|
|
void ResetMenuButtonFrame();
|
2022-05-15 18:20:21 +10:00
|
|
|
void MenuHeading(const char* title, bool draw_line = true);
|
|
|
|
|
bool MenuHeadingButton(const char* title, const char* value = nullptr, bool enabled = true, bool draw_line = true);
|
|
|
|
|
bool ActiveButton(const char* title, bool is_active, bool enabled = true, float height = LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY,
|
2025-07-05 20:03:45 +01:00
|
|
|
std::pair<ImFont*, float> font = g_large_font);
|
2024-08-18 22:31:28 +07:00
|
|
|
bool ActiveButtonWithRightText(const char* title, const char* right_title, bool is_active, bool enabled = true,
|
2025-07-05 20:03:45 +01:00
|
|
|
float height = LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, std::pair<ImFont*, float> font = g_large_font);
|
2022-05-15 18:20:21 +10:00
|
|
|
bool MenuButton(const char* title, const char* summary, bool enabled = true, float height = LAYOUT_MENU_BUTTON_HEIGHT,
|
2025-07-05 20:03:45 +01:00
|
|
|
std::pair<ImFont*, float> font = g_large_font, std::pair<ImFont*, float> summary_font = g_medium_font);
|
2022-09-03 15:06:56 +10:00
|
|
|
bool MenuButtonWithoutSummary(const char* title, bool enabled = true, float height = LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY,
|
2025-07-05 20:03:45 +01:00
|
|
|
std::pair<ImFont*, float> font = g_large_font, const ImVec2& text_align = ImVec2(0.0f, 0.0f));
|
2022-05-15 18:20:21 +10:00
|
|
|
bool MenuButtonWithValue(const char* title, const char* summary, const char* value, bool enabled = true,
|
2025-07-05 20:03:45 +01:00
|
|
|
float height = LAYOUT_MENU_BUTTON_HEIGHT, std::pair<ImFont*, float> font = g_large_font, std::pair<ImFont*, float> summary_font = g_medium_font);
|
2022-05-15 18:20:21 +10:00
|
|
|
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),
|
2025-07-05 20:03:45 +01:00
|
|
|
std::pair<ImFont*, float> font = g_large_font, std::pair<ImFont*, float> summary_font = g_medium_font);
|
2022-05-15 18:20:21 +10:00
|
|
|
bool FloatingButton(const char* text, float x, float y, float width = -1.0f, float height = LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY,
|
2025-07-05 20:03:45 +01:00
|
|
|
float anchor_x = 0.0f, float anchor_y = 0.0f, bool enabled = true, std::pair<ImFont*, float> font = g_large_font, ImVec2* out_position = nullptr,
|
2022-10-10 23:35:59 +10:00
|
|
|
bool repeat_button = false);
|
2022-05-15 18:20:21 +10:00
|
|
|
bool ToggleButton(const char* title, const char* summary, bool* v, bool enabled = true, float height = LAYOUT_MENU_BUTTON_HEIGHT,
|
2025-07-05 20:03:45 +01:00
|
|
|
std::pair<ImFont*, float> font = g_large_font, std::pair<ImFont*, float> summary_font = g_medium_font);
|
2022-05-15 18:20:21 +10:00
|
|
|
bool ThreeWayToggleButton(const char* title, const char* summary, std::optional<bool>* v, bool enabled = true,
|
2025-07-05 20:03:45 +01:00
|
|
|
float height = LAYOUT_MENU_BUTTON_HEIGHT, std::pair<ImFont*, float> font = g_large_font, std::pair<ImFont*, float> summary_font = g_medium_font);
|
2022-05-15 18:20:21 +10:00
|
|
|
bool EnumChoiceButtonImpl(const char* title, const char* summary, s32* value_pointer,
|
2025-07-05 20:03:45 +01:00
|
|
|
const char* (*to_display_name_function)(s32 value, void* opaque), void* opaque, u32 count, bool enabled, float height, std::pair<ImFont*, float> font,
|
|
|
|
|
std::pair<ImFont*, float> summary_font);
|
2022-05-15 18:20:21 +10:00
|
|
|
|
|
|
|
|
template <typename DataType, typename CountType>
|
|
|
|
|
static __fi bool EnumChoiceButton(const char* title, const char* summary, DataType* value_pointer,
|
|
|
|
|
const char* (*to_display_name_function)(DataType value), CountType count, bool enabled = true,
|
2025-07-05 20:03:45 +01:00
|
|
|
float height = LAYOUT_MENU_BUTTON_HEIGHT, std::pair<ImFont*, float> font = g_large_font, std::pair<ImFont*, float> summary_font = g_medium_font)
|
2022-05-15 18:20:21 +10:00
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BeginNavBar(float x_padding = LAYOUT_MENU_BUTTON_X_PADDING, float y_padding = LAYOUT_MENU_BUTTON_Y_PADDING);
|
|
|
|
|
void EndNavBar();
|
2025-07-05 20:03:45 +01:00
|
|
|
void NavTitle(const char* title, float height = LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, std::pair<ImFont*, float> font = g_large_font);
|
2022-05-15 18:20:21 +10:00
|
|
|
void RightAlignNavButtons(u32 num_items = 0, float item_width = LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY,
|
|
|
|
|
float item_height = LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY);
|
|
|
|
|
bool NavButton(const char* title, bool is_active, bool enabled = true, float width = -1.0f,
|
2025-07-05 20:03:45 +01:00
|
|
|
float height = LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY, std::pair<ImFont*, float> font = g_large_font);
|
2023-09-17 20:19:51 +10:00
|
|
|
bool NavTab(const char* title, bool is_active, bool enabled, float width, float height, const ImVec4& background,
|
2025-07-05 20:03:45 +01:00
|
|
|
std::pair<ImFont*, float> font = g_large_font);
|
2022-05-15 18:20:21 +10:00
|
|
|
|
2024-04-13 00:53:58 +10:00
|
|
|
bool BeginHorizontalMenu(const char* name, const ImVec2& position, const ImVec2& size, u32 num_items);
|
|
|
|
|
void EndHorizontalMenu();
|
2025-06-21 16:07:15 +01:00
|
|
|
bool HorizontalMenuItem(GSTexture* icon, const ImVec2& icon_uv0, const ImVec2& icon_uv1, const char* title, const char* description);
|
2024-04-13 00:53:58 +10:00
|
|
|
bool HorizontalMenuItem(GSTexture* icon, const char* title, const char* description);
|
2025-06-21 16:07:15 +01:00
|
|
|
bool HorizontalMenuSvgItem(const char* svg_path, const char* title, const char* description, SvgScaling mode = SvgScaling::Stretch);
|
2024-04-13 00:53:58 +10:00
|
|
|
|
2022-05-15 18:20:21 +10:00
|
|
|
using FileSelectorCallback = std::function<void(const std::string& path)>;
|
|
|
|
|
using FileSelectorFilters = std::vector<std::string>;
|
|
|
|
|
bool IsFileSelectorOpen();
|
2024-04-13 00:53:58 +10:00
|
|
|
void OpenFileSelector(std::string_view title, bool select_directory, FileSelectorCallback callback,
|
2022-05-15 18:20:21 +10:00
|
|
|
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>>;
|
|
|
|
|
bool IsChoiceDialogOpen();
|
2024-04-13 00:53:58 +10:00
|
|
|
void OpenChoiceDialog(std::string_view title, bool checkable, ChoiceDialogOptions options, ChoiceDialogCallback callback);
|
2022-05-15 18:20:21 +10:00
|
|
|
void CloseChoiceDialog();
|
|
|
|
|
|
|
|
|
|
using InputStringDialogCallback = std::function<void(std::string text)>;
|
|
|
|
|
bool IsInputDialogOpen();
|
2025-07-01 02:27:25 -04:00
|
|
|
enum class InputFilterType : u8
|
|
|
|
|
{
|
|
|
|
|
None,
|
|
|
|
|
Numeric,
|
|
|
|
|
IPAddress
|
|
|
|
|
};
|
|
|
|
|
|
2022-05-15 18:20:21 +10:00
|
|
|
void OpenInputStringDialog(
|
2025-07-01 02:27:25 -04:00
|
|
|
std::string title, std::string message, std::string caption, std::string ok_button_text, InputStringDialogCallback callback,
|
|
|
|
|
std::string default_value = std::string(), InputFilterType filter_type = InputFilterType::None);
|
2022-05-15 18:20:21 +10:00
|
|
|
void CloseInputDialog();
|
|
|
|
|
|
2022-09-07 17:44:10 +10:00
|
|
|
using ConfirmMessageDialogCallback = std::function<void(bool)>;
|
|
|
|
|
using InfoMessageDialogCallback = std::function<void()>;
|
|
|
|
|
using MessageDialogCallback = std::function<void(s32)>;
|
|
|
|
|
bool IsMessageBoxDialogOpen();
|
2025-10-16 20:17:22 +01:00
|
|
|
void OpenConfirmMessageDialog(std::string title, std::string message, ConfirmMessageDialogCallback callback, bool default_yes = true,
|
2025-07-04 13:46:37 +01:00
|
|
|
std::string yes_button_text = ICON_FA_CHECK " Yes", std::string no_button_text = ICON_FA_XMARK " No");
|
2022-09-03 15:06:56 +10:00
|
|
|
void OpenInfoMessageDialog(std::string title, std::string message, InfoMessageDialogCallback callback = {},
|
2025-07-04 13:46:37 +01:00
|
|
|
std::string button_text = ICON_FA_SQUARE_XMARK " Close");
|
2025-10-16 20:17:22 +01:00
|
|
|
void OpenMessageDialog(std::string title, std::string message, MessageDialogCallback callback, s32 default_index, std::string first_button_text,
|
2022-09-07 17:44:10 +10:00
|
|
|
std::string second_button_text, std::string third_button_text);
|
|
|
|
|
void CloseMessageDialog();
|
|
|
|
|
|
2022-05-15 18:20:21 +10:00
|
|
|
float GetNotificationVerticalPosition();
|
|
|
|
|
float GetNotificationVerticalDirection();
|
|
|
|
|
void SetNotificationVerticalPosition(float position, float direction);
|
2025-07-02 14:21:17 -04:00
|
|
|
void SetNotificationPosition(float horizontal_position, float vertical_position, float direction);
|
2022-05-15 18:20:21 +10:00
|
|
|
|
2025-10-15 15:58:54 -04:00
|
|
|
void OpenProgressDialog(const char* str_id, std::string message, s32 min, s32 max, s32 value);
|
|
|
|
|
void UpdateProgressDialog(const char* str_id, std::string message, s32 min, s32 max, s32 value);
|
|
|
|
|
void CloseProgressDialog(const char* str_id);
|
2022-05-15 18:20:21 +10:00
|
|
|
|
2023-09-17 20:19:51 +10:00
|
|
|
void AddNotification(std::string key, float duration, std::string title, std::string text, std::string image_path);
|
2022-05-15 18:20:21 +10:00
|
|
|
void ClearNotifications();
|
|
|
|
|
|
2026-07-30 02:04:58 -04:00
|
|
|
/// True while any toast notification (e.g. an achievement popup) is queued or on screen. Used to
|
|
|
|
|
/// decide whether a frame that would otherwise be skipped must still be presented so the toast
|
|
|
|
|
/// is actually drawn. GS-thread only, like the notification list itself.
|
|
|
|
|
bool HasActiveNotifications();
|
|
|
|
|
|
2022-05-15 18:20:21 +10:00
|
|
|
void ShowToast(std::string title, std::string message, float duration = 10.0f);
|
|
|
|
|
void ClearToast();
|
2024-04-13 00:53:58 +10:00
|
|
|
|
|
|
|
|
// Message callbacks.
|
|
|
|
|
void GetChoiceDialogHelpText(SmallStringBase& dest);
|
|
|
|
|
void GetFileSelectorHelpText(SmallStringBase& dest);
|
|
|
|
|
void GetInputDialogHelpText(SmallStringBase& dest);
|
2022-05-15 18:20:21 +10:00
|
|
|
} // namespace ImGuiFullscreen
|
2024-05-15 07:25:06 +10:00
|
|
|
|
|
|
|
|
// Host UI triggers from Big Picture mode.
|
|
|
|
|
namespace Host
|
|
|
|
|
{
|
|
|
|
|
/// Returns true if native file dialogs should be preferred over Big Picture.
|
|
|
|
|
bool ShouldPreferHostFileSelector();
|
|
|
|
|
|
|
|
|
|
/// Opens a file selector dialog.
|
|
|
|
|
using FileSelectorCallback = std::function<void(const std::string& path)>;
|
|
|
|
|
using FileSelectorFilters = std::vector<std::string>;
|
|
|
|
|
void OpenHostFileSelectorAsync(std::string_view title, bool select_directory, FileSelectorCallback callback,
|
|
|
|
|
FileSelectorFilters filters = FileSelectorFilters(),
|
|
|
|
|
std::string_view initial_directory = std::string_view());
|
|
|
|
|
} // namespace Host
|