Migrate all of menubar to new widgets, clean up dead code

This commit is contained in:
Garrett Cox
2024-05-22 09:04:58 -05:00
parent d56128146c
commit 9d6c44fd25
7 changed files with 422 additions and 648 deletions
+12 -143
View File
@@ -1,11 +1,4 @@
//
// SohGui.cpp
// soh
//
// Created by David Chavez on 24.08.22.
//
#include "SohGui.hpp"
#include "BenGui.hpp"
#include <spdlog/spdlog.h>
#include <ImGui/imgui.h>
@@ -13,6 +6,7 @@
#include <ImGui/imgui_internal.h>
#include <libultraship/libultraship.h>
#include <Fast3D/gfx_pc.h>
#include "UIWidgets.hpp"
#ifdef __APPLE__
#include "graphic/Fast3D/gfx_metal.h"
@@ -22,116 +16,34 @@
#include <port/switch/SwitchImpl.h>
#endif
//#include "UIWidgets.hpp"
#include "include/global.h"
#include "include/z64audio.h"
//#include "soh/SaveManager.h"
//#include "OTRGlobals.h"
//#include "soh/Enhancements/presets.h"
//#include "2s2h/resource/type/Skeleton.h"
#include "libultraship/libultraship.h"
//#ifdef ENABLE_CROWD_CONTROL
//#include "Enhancements/crowd-control/CrowdControl.h"
//#endif
//#include "Enhancements/game-interactor/GameInteractor.h"
//#include "Enhancements/cosmetics/authenticGfxPatches.h"
bool ShouldClearTextureCacheAtEndOfFrame = false;
bool isBetaQuestEnabled = false;
extern "C" {
void enableBetaQuest() { isBetaQuestEnabled = true; }
void disableBetaQuest() { isBetaQuestEnabled = false; }
}
namespace SohGui {
// MARK: - Properties
static const char* chestSizeAndTextureMatchesContentsOptions[4] = { "Disabled", "Both", "Texture Only", "Size Only" };
static const char* bunnyHoodOptions[3] = { "Disabled", "Faster Run & Longer Jump", "Faster Run" };
static const char* allPowers[9] = {
"Vanilla (1x)",
"Double (2x)",
"Quadruple (4x)",
"Octuple (8x)",
"Foolish (16x)",
"Ridiculous (32x)",
"Merciless (64x)",
"Pure Torture (128x)",
"OHKO (256x)" };
static const char* subPowers[8] = { allPowers[0], allPowers[1], allPowers[2], allPowers[3], allPowers[4], allPowers[5], allPowers[6], allPowers[7] };
static const char* subSubPowers[7] = { allPowers[0], allPowers[1], allPowers[2], allPowers[3], allPowers[4], allPowers[5], allPowers[6] };
static const char* zFightingOptions[3] = { "Disabled", "Consistent Vanish", "No Vanish" };
static const char* autosaveLabels[6] = { "Off", "New Location + Major Item", "New Location + Any Item", "New Location", "Major Item", "Any Item" };
static const char* FastFileSelect[5] = { "File N.1", "File N.2", "File N.3", "Zelda Map Select (require OoT Debug Mode)", "File select" };
static const char* bonkDamageValues[8] = {
"No Damage",
"0.25 Heart",
"0.5 Heart",
"1 Heart",
"2 Hearts",
"4 Hearts",
"8 Hearts",
"OHKO"
};
static const inline std::vector<std::pair<const char*, const char*>> audioBackends = {
#ifdef _WIN32
{ "wasapi", "Windows Audio Session API" },
#endif
#if defined(__linux)
{ "pulse", "PulseAudio" },
#endif
{ "sdl", "SDL Audio" }
};
// MARK: - Helpers
std::string GetWindowButtonText(const char* text, bool menuOpen) {
char buttonText[100] = "";
if (menuOpen) {
strcat(buttonText, ICON_FA_CHEVRON_RIGHT " ");
}
strcat(buttonText, text);
if (!menuOpen) { strcat(buttonText, " "); }
return buttonText;
}
namespace BenGui {
// MARK: - Delegates
std::shared_ptr<SohMenuBar> mSohMenuBar;
std::shared_ptr<BenMenuBar> mBenMenuBar;
std::shared_ptr<LUS::GuiWindow> mConsoleWindow;
std::shared_ptr<LUS::GuiWindow> mStatsWindow;
std::shared_ptr<LUS::GuiWindow> mInputEditorWindow;
std::shared_ptr<LUS::GuiWindow> mGfxDebuggerWindow;
//std::shared_ptr<AudioEditor> mAudioEditorWindow;
//std::shared_ptr<GameControlEditor::GameControlEditorWindow> mGameControlEditorWindow;
//std::shared_ptr<CosmeticsEditorWindow> mCosmeticsEditorWindow;
//std::shared_ptr<ActorViewerWindow> mActorViewerWindow;
//std::shared_ptr<ColViewerWindow> mColViewerWindow;
std::shared_ptr<SaveEditorWindow> mSaveEditorWindow;
//std::shared_ptr<DLViewerWindow> mDLViewerWindow;
//std::shared_ptr<GameplayStatsWindow> mGameplayStatsWindow;
//std::shared_ptr<CheckTracker::CheckTrackerSettingsWindow> mCheckTrackerSettingsWindow;
//std::shared_ptr<CheckTracker::CheckTrackerWindow> mCheckTrackerWindow;
//std::shared_ptr<EntranceTrackerWindow> mEntranceTrackerWindow;
//std::shared_ptr<ItemTrackerSettingsWindow> mItemTrackerSettingsWindow;
//std::shared_ptr<ItemTrackerWindow> mItemTrackerWindow;
//std::shared_ptr<RandomizerSettingsWindow> mRandomizerSettingsWindow;
void SetupGuiElements() {
auto gui = LUS::Context::GetInstance()->GetWindow()->GetGui();
mSohMenuBar = std::make_shared<SohMenuBar>("gOpenMenuBar", CVarGetInteger("gOpenMenuBar", 0));
gui->SetMenuBar(std::reinterpret_pointer_cast<LUS::GuiMenuBar>(mSohMenuBar));
auto& style = ImGui::GetStyle();
style.FramePadding = ImVec2(4.0f, 6.0f);
style.ItemSpacing = ImVec2(8.0f, 6.0f);
style.Colors[ImGuiCol_MenuBarBg] = UIWidgets::Colors::DarkGray;
mBenMenuBar = std::make_shared<BenMenuBar>("gOpenMenuBar", CVarGetInteger("gOpenMenuBar", 0));
gui->SetMenuBar(std::reinterpret_pointer_cast<LUS::GuiMenuBar>(mBenMenuBar));
if (gui->GetMenuBar() && !gui->GetMenuBar()->IsVisible()) {
#if defined(__SWITCH__) || defined(__WIIU__)
@@ -163,55 +75,12 @@ namespace SohGui {
mSaveEditorWindow = std::make_shared<SaveEditorWindow>("gSaveEditorEnabled", "Save Editor");
gui->AddGuiWindow(mSaveEditorWindow);
/*
mAudioEditorWindow = std::make_shared<AudioEditor>("gAudioEditor.WindowOpen", "Audio Editor");
gui->AddGuiWindow(mAudioEditorWindow);
mGameControlEditorWindow = std::make_shared<GameControlEditor::GameControlEditorWindow>("gGameControlEditorEnabled", "Game Control Editor");
gui->AddGuiWindow(mGameControlEditorWindow);
mCosmeticsEditorWindow = std::make_shared<CosmeticsEditorWindow>("gCosmeticsEditorEnabled", "Cosmetics Editor");
gui->AddGuiWindow(mCosmeticsEditorWindow);
mActorViewerWindow = std::make_shared<ActorViewerWindow>("gActorViewerEnabled", "Actor Viewer");
gui->AddGuiWindow(mActorViewerWindow);
mColViewerWindow = std::make_shared<ColViewerWindow>("gCollisionViewerEnabled", "Collision Viewer");
gui->AddGuiWindow(mColViewerWindow);
mDLViewerWindow = std::make_shared<DLViewerWindow>("gDLViewerEnabled", "Display List Viewer");
gui->AddGuiWindow(mDLViewerWindow);
mGameplayStatsWindow = std::make_shared<GameplayStatsWindow>("gGameplayStatsEnabled", "Gameplay Stats");
gui->AddGuiWindow(mGameplayStatsWindow);
mCheckTrackerWindow = std::make_shared<CheckTracker::CheckTrackerWindow>("gCheckTrackerEnabled", "Check Tracker");
gui->AddGuiWindow(mCheckTrackerWindow);
mCheckTrackerSettingsWindow = std::make_shared<CheckTracker::CheckTrackerSettingsWindow>("gCheckTrackerSettingsEnabled", "Check Tracker Settings");
gui->AddGuiWindow(mCheckTrackerSettingsWindow);
mEntranceTrackerWindow = std::make_shared<EntranceTrackerWindow>("gEntranceTrackerEnabled","Entrance Tracker");
gui->AddGuiWindow(mEntranceTrackerWindow);
mItemTrackerWindow = std::make_shared<ItemTrackerWindow>("gItemTrackerEnabled", "Item Tracker");
gui->AddGuiWindow(mItemTrackerWindow);
mItemTrackerSettingsWindow = std::make_shared<ItemTrackerSettingsWindow>("gItemTrackerSettingsEnabled", "Item Tracker Settings");
gui->AddGuiWindow(mItemTrackerSettingsWindow);
mRandomizerSettingsWindow = std::make_shared<RandomizerSettingsWindow>("gRandomizerSettingsEnabled", "Randomizer Settings");
gui->AddGuiWindow(mRandomizerSettingsWindow);
*/
}
void Destroy() {
//mRandomizerSettingsWindow = nullptr;
//mItemTrackerWindow = nullptr;
//mItemTrackerSettingsWindow = nullptr;
//mEntranceTrackerWindow = nullptr;
//mCheckTrackerWindow = nullptr;
//mCheckTrackerSettingsWindow = nullptr;
//mGameplayStatsWindow = nullptr;
//mDLViewerWindow = nullptr;
mSaveEditorWindow = nullptr;
//mColViewerWindow = nullptr;
//mActorViewerWindow = nullptr;
//mCosmeticsEditorWindow = nullptr;
//mGameControlEditorWindow = nullptr;
//mAudioEditorWindow = nullptr;
//mInputEditorWindow = nullptr;
mStatsWindow = nullptr;
mConsoleWindow = nullptr;
mSohMenuBar = nullptr;
mBenMenuBar = nullptr;
}
}
+5 -33
View File
@@ -1,43 +1,15 @@
//
// SohGui.hpp
// soh
//
// Created by David Chavez on 24.08.22.
//
#ifndef SohGui_hpp
#define SohGui_hpp
#ifndef BenGui_hpp
#define BenGui_hpp
#include <stdio.h>
#include "SohMenuBar.h"
#include "BenMenuBar.h"
#include "DeveloperTools/SaveEditor.h"
//#include "Enhancements/audio/AudioEditor.h"
//#include "Enhancements/controls/GameControlEditor.h"
//#include "Enhancements/cosmetics/CosmeticsEditor.h"
//#include "Enhancements/debugger/actorViewer.h"
//#include "Enhancements/debugger/colViewer.h"
//#include "Enhancements/debugger/debugSaveEditor.h"
//#include "Enhancements/debugger/dlViewer.h"
//#include "Enhancements/gameplaystatswindow.h"
//#include "Enhancements/randomizer/randomizer_check_tracker.h"
//#include "Enhancements/randomizer/randomizer_entrance_tracker.h"
//#include "Enhancements/randomizer/randomizer_item_tracker.h"
//#include "Enhancements/randomizer/randomizer_settings_window.h"
#ifdef __cplusplus
extern "C" {
#endif
void enableBetaQuest();
void disableBetaQuest();
#ifdef __cplusplus
}
#endif
namespace SohGui {
namespace BenGui {
void SetupHooks();
void SetupGuiElements();
void Draw();
void Destroy();
}
#endif /* SohGui_hpp */
#endif /* BenGui_hpp */
+129 -379
View File
File diff suppressed because it is too large Load Diff
+7 -5
View File
@@ -1,12 +1,12 @@
#pragma once
#ifndef BenMenuBar_h
#define BenMenuBar_h
//#include <libultraship/libultraship.h>
#include "window/gui/GuiMenuBar.h"
#include "window/gui/GuiElement.h"
#include "DeveloperTools/SaveEditor.h"
namespace SohGui {
class SohMenuBar : public LUS::GuiMenuBar {
namespace BenGui {
class BenMenuBar : public LUS::GuiMenuBar {
public:
using LUS::GuiMenuBar::GuiMenuBar;
protected:
@@ -14,4 +14,6 @@ class SohMenuBar : public LUS::GuiMenuBar {
void InitElement() override {};
void UpdateElement() override {};
};
} // namespace SohGui
} // namespace BenGui
#endif // BenMenuBar_h
+3 -3
View File
@@ -50,7 +50,7 @@ CrowdControl* CrowdControl::Instance;
#endif
#include <libultraship/libultraship.h>
#include <SohGui.hpp>
#include <BenGui.hpp>
#include "Enhancements/controls/SohInputEditorWindow.h"
@@ -299,7 +299,7 @@ extern "C" void InitOTR() {
#endif
OTRGlobals::Instance = new OTRGlobals();
SohGui::SetupGuiElements();
BenGui::SetupGuiElements();
clearMtx = (uintptr_t)&gMtxClear;
//OTRMessage_Init();
@@ -340,7 +340,7 @@ extern "C" void DeinitOTR() {
// Destroying gui here because we have shared ptrs to LUS objects which output to SPDLOG which is destroyed before
// these shared ptrs.
//SohGui::Destroy();
//BenGui::Destroy();
OTRGlobals::Instance->context = nullptr;
}
+3 -83
View File
@@ -10,6 +10,8 @@
#define IMGUI_DEFINE_MATH_OPERATORS
#include <ImGui/imgui_internal.h>
#include <libultraship/libultraship.h>
#include <string>
#include <unordered_map>
#include <libultraship/libultra/types.h>
//#include "soh/Enhancements/cosmetics/CosmeticsEditor.h"
@@ -733,6 +735,7 @@ namespace UIWidgets {
bool BeginMenu(const char* label, const ImVec4& color) {
bool dirty = false;
PushStyleMenu(color);
ImGui::SetNextWindowSizeConstraints(ImVec2(200.0f, 0.0f), ImVec2(FLT_MAX, FLT_MAX));
if (ImGui::BeginMenu(label)) {
dirty = true;
}
@@ -906,89 +909,6 @@ namespace UIWidgets {
ImGui::PopStyleColor(9);
}
bool Combobox(const char* label, uint8_t* value, std::span<const char*, std::dynamic_extent> comboArray, const ComboboxOptions& options) {
bool dirty = false;
float startX = ImGui::GetCursorPosX();
std::string invisibleLabelStr = "##" + std::string(label);
const char* invisibleLabel = invisibleLabelStr.c_str();
ImGui::PushID(label);
ImGui::BeginGroup();
ImGui::BeginDisabled(options.disabled);
PushStyleCombobox(options.color);
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Above) {
ImGui::Text(label);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
} else if (options.labelPosition == LabelPosition::Near) {
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x - ImGui::GetStyle().ItemSpacing.x * 2);
} else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
ImGui::SetNextItemWidth(ImGui::CalcTextSize(comboArray[*value]).x + ImGui::GetStyle().FramePadding.x * 4 + ImGui::GetStyle().ItemSpacing.x);
}
} else if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition == LabelPosition::Above) {
ImGui::NewLine();
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
ImGui::Text(label);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
} else if (options.labelPosition == LabelPosition::Near) {
ImGui::SameLine(ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x * 2);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
} else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
float width = ImGui::CalcTextSize(comboArray[*value]).x + ImGui::GetStyle().FramePadding.x * 4;
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
}
}
if (ImGui::BeginCombo(invisibleLabel, comboArray[*value], options.flags)) {
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f));
for (uint8_t i = 0; i < comboArray.size(); i++) {
if (strlen(comboArray[i]) > 1) {
if (ImGui::Selectable(comboArray[i], i == *value)) {
*value = i;
dirty = true;
}
}
}
ImGui::PopStyleVar();
ImGui::EndCombo();
}
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Near) {
ImGui::SameLine();
ImGui::Text(label);
} else if (options.labelPosition == LabelPosition::Far) {
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
ImGui::Text(label);
}
} else if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) {
ImGui::SameLine(startX);
ImGui::Text(label);
}
}
PopStyleCombobox();
ImGui::EndDisabled();
ImGui::EndGroup();
if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && strcmp(options.disabledTooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip));
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && strcmp(options.tooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.tooltip));
}
ImGui::PopID();
return dirty;
}
bool CVarCombobox(const char* label, const char* cvarName, std::span<const char*, std::dynamic_extent> comboArray, const ComboboxOptions& options) {
bool dirty = false;
uint8_t value = (uint8_t)CVarGetInteger(cvarName, options.defaultIndex);
if (Combobox(label, &value, comboArray, options)) {
CVarSetInteger(cvarName, value);
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
dirty = true;
}
return dirty;
}
void PushStyleSlider(const ImVec4& color) {
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(color.x, color.y, color.z, 1.0f));
+263 -2
View File
@@ -15,6 +15,7 @@
#define IMGUI_DEFINE_MATH_OPERATORS
#include <ImGui/imgui.h>
#include <libultraship/libultraship.h>
#include <unordered_map>
namespace UIWidgets {
@@ -181,8 +182,268 @@ namespace UIWidgets {
void PushStyleCombobox(const ImVec4& color = Colors::Indigo);
void PopStyleCombobox();
bool Combobox(const char* label, uint8_t* value, std::span<const char*, std::dynamic_extent> comboArray, const ComboboxOptions& options = {});
bool CVarCombobox(const char* label, const char* cvarName, std::span<const char*, std::dynamic_extent> comboArray, const ComboboxOptions& options = {});
template <typename T>
bool Combobox(const char* label, T* value, const std::unordered_map<T, const char*>& comboMap, const ComboboxOptions& options = {}) {
bool dirty = false;
float startX = ImGui::GetCursorPosX();
std::string invisibleLabelStr = "##" + std::string(label);
const char* invisibleLabel = invisibleLabelStr.c_str();
ImGui::PushID(label);
ImGui::BeginGroup();
ImGui::BeginDisabled(options.disabled);
PushStyleCombobox(options.color);
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Above) {
ImGui::Text(label);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
} else if (options.labelPosition == LabelPosition::Near) {
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x - ImGui::GetStyle().ItemSpacing.x * 2);
} else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
ImGui::SetNextItemWidth(ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 4 + ImGui::GetStyle().ItemSpacing.x);
}
} else if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition == LabelPosition::Above) {
ImGui::NewLine();
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
ImGui::Text(label);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
} else if (options.labelPosition == LabelPosition::Near) {
ImGui::SameLine(ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x * 2);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
} else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
float width = ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 4;
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
}
}
if (ImGui::BeginCombo(invisibleLabel, comboMap.at(*value), options.flags)) {
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f));
for (const auto& pair : comboMap) {
if (strlen(pair.second) > 1) {
if (ImGui::Selectable(pair.second, pair.first == *value)) {
*value = pair.first;
dirty = true;
}
}
}
ImGui::PopStyleVar();
ImGui::EndCombo();
}
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Near) {
ImGui::SameLine();
ImGui::Text(label);
} else if (options.labelPosition == LabelPosition::Far) {
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
ImGui::Text(label);
}
} else if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) {
ImGui::SameLine(startX);
ImGui::Text(label);
}
}
PopStyleCombobox();
ImGui::EndDisabled();
ImGui::EndGroup();
if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && strcmp(options.disabledTooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip));
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && strcmp(options.tooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.tooltip));
}
ImGui::PopID();
return dirty;
}
template <typename T = size_t>
bool Combobox(const char* label, T* value, const std::vector<const char*>& comboVector, const ComboboxOptions& options = {}) {
bool dirty = false;
float startX = ImGui::GetCursorPosX();
size_t currentValueIndex = static_cast<size_t>(*value);
std::string invisibleLabelStr = "##" + std::string(label);
const char* invisibleLabel = invisibleLabelStr.c_str();
ImGui::PushID(label);
ImGui::BeginGroup();
ImGui::BeginDisabled(options.disabled);
PushStyleCombobox(options.color);
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Above) {
ImGui::Text(label);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
} else if (options.labelPosition == LabelPosition::Near) {
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x - ImGui::GetStyle().ItemSpacing.x * 2);
} else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
ImGui::SetNextItemWidth(ImGui::CalcTextSize(comboVector.at(currentValueIndex)).x + ImGui::GetStyle().FramePadding.x * 4 + ImGui::GetStyle().ItemSpacing.x);
}
} else if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition == LabelPosition::Above) {
ImGui::NewLine();
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
ImGui::Text(label);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
} else if (options.labelPosition == LabelPosition::Near) {
ImGui::SameLine(ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x * 2);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
} else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
float width = ImGui::CalcTextSize(comboVector.at(currentValueIndex)).x + ImGui::GetStyle().FramePadding.x * 4;
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
}
}
if (ImGui::BeginCombo(invisibleLabel, comboVector.at(currentValueIndex), options.flags)) {
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f));
for (size_t i = 0; i < comboVector.size(); ++i) {
auto newValue = static_cast<T>(i);
if (strlen(comboVector.at(i)) > 1) {
if (ImGui::Selectable(comboVector.at(i), newValue == *value)) {
*value = newValue;
dirty = true;
}
}
}
ImGui::PopStyleVar();
ImGui::EndCombo();
}
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Near) {
ImGui::SameLine();
ImGui::Text(label);
} else if (options.labelPosition == LabelPosition::Far) {
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
ImGui::Text(label);
}
} else if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) {
ImGui::SameLine(startX);
ImGui::Text(label);
}
}
PopStyleCombobox();
ImGui::EndDisabled();
ImGui::EndGroup();
if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && strcmp(options.disabledTooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip));
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && strcmp(options.tooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.tooltip));
}
ImGui::PopID();
return dirty;
}
template <typename T = size_t, size_t N>
bool Combobox(const char* label, T* value, const char* (&comboArray)[N], const ComboboxOptions& options = {}) {
bool dirty = false;
float startX = ImGui::GetCursorPosX();
size_t currentValueIndex = static_cast<size_t>(*value);
if (currentValueIndex >= N) {
currentValueIndex = 0;
}
std::string invisibleLabelStr = "##" + std::string(label);
const char* invisibleLabel = invisibleLabelStr.c_str();
ImGui::PushID(label);
ImGui::BeginGroup();
ImGui::BeginDisabled(options.disabled);
PushStyleCombobox(options.color);
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Above) {
ImGui::Text(label);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
} else if (options.labelPosition == LabelPosition::Near) {
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x - ImGui::GetStyle().ItemSpacing.x * 2);
} else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
ImGui::SetNextItemWidth(ImGui::CalcTextSize(comboArray[currentValueIndex]).x + ImGui::GetStyle().FramePadding.x * 4 + ImGui::GetStyle().ItemSpacing.x);
}
} else if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition == LabelPosition::Above) {
ImGui::NewLine();
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
ImGui::Text(label);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
} else if (options.labelPosition == LabelPosition::Near) {
ImGui::SameLine(ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x * 2);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
} else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
float width = ImGui::CalcTextSize(comboArray[currentValueIndex]).x + ImGui::GetStyle().FramePadding.x * 4;
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
}
}
if (ImGui::BeginCombo(invisibleLabel, comboArray[currentValueIndex], options.flags)) {
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f));
for (size_t i = 0; i < N; ++i) {
auto newValue = static_cast<T>(i);
if (strlen(comboArray[i]) > 1) {
if (ImGui::Selectable(comboArray[i], newValue == *value)) {
*value = newValue;
dirty = true;
}
}
}
ImGui::PopStyleVar();
ImGui::EndCombo();
}
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Near) {
ImGui::SameLine();
ImGui::Text(label);
} else if (options.labelPosition == LabelPosition::Far) {
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
ImGui::Text(label);
}
} else if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) {
ImGui::SameLine(startX);
ImGui::Text(label);
}
}
PopStyleCombobox();
ImGui::EndDisabled();
ImGui::EndGroup();
if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && strcmp(options.disabledTooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip));
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && strcmp(options.tooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.tooltip));
}
ImGui::PopID();
return dirty;
}
template <typename T = int32_t>
bool CVarCombobox(const char* label, const char* cvarName, const std::unordered_map<T, const char*>& comboMap, const ComboboxOptions& options = {}) {
bool dirty = false;
int32_t value = CVarGetInteger(cvarName, options.defaultIndex);
if (Combobox<T>(label, &value, comboMap, options)) {
CVarSetInteger(cvarName, value);
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
dirty = true;
}
return dirty;
}
template <typename T = int32_t>
bool CVarCombobox(const char* label, const char* cvarName, const std::vector<const char*>& comboVector, const ComboboxOptions& options = {}) {
bool dirty = false;
int32_t value = CVarGetInteger(cvarName, options.defaultIndex);
if (Combobox<T>(label, &value, comboVector, options)) {
CVarSetInteger(cvarName, value);
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
dirty = true;
}
return dirty;
}
template <typename T = int32_t, size_t N>
bool CVarCombobox(const char* label, const char* cvarName, const char* (&comboArray)[N], const ComboboxOptions& options = {}) {
bool dirty = false;
int32_t value = CVarGetInteger(cvarName, options.defaultIndex);
if (Combobox<T>(label, &value, comboArray, options)) {
CVarSetInteger(cvarName, value);
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
dirty = true;
}
return dirty;
}
struct IntSliderOptions {
const ImVec4 color = Colors::Gray;