Merge pull request #12 from garrettjoecox/ui-widgets-v2

Start migrating to WIP UIWidgets v2
This commit is contained in:
Lywx
2023-10-11 23:19:30 -06:00
committed by GitHub
3 changed files with 514 additions and 93 deletions
+63 -93
View File
@@ -23,6 +23,11 @@ std::shared_ptr<AdvancedResolutionSettings::AdvancedResolutionSettingsWindow> mA
void SetupGuiElements() {
auto gui = LUS::Context::GetInstance()->GetWindow()->GetGui();
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;
mGameMenuBar = std::make_shared<GameMenuBar>("gOpenMenuBar", CVarGetInteger("gOpenMenuBar", 0));
gui->SetMenuBar(mGameMenuBar);
mStatsWindow = gui->GetGuiWindow("Stats");
@@ -73,8 +78,8 @@ static const char* filters[3] = {
};
void DrawSettingsMenu(){
if(ImGui::BeginMenu("Settings")){
if (ImGui::BeginMenu("Audio")) {
if(UIWidgets::BeginMenu("Settings")){
if (UIWidgets::BeginMenu("Audio")) {
UIWidgets::PaddedEnhancementSliderFloat("Master Volume: %d %%", "##Master_Vol", "gGameMasterVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true);
if (UIWidgets::PaddedEnhancementSliderFloat("Main Music Volume: %d %%", "##Main_Music_Vol", "gMainMusicVolume", 0.0f, 1.0f, "", 1.0f, true, true, false, true)) {
audio_set_player_volume(SEQ_PLAYER_LEVEL, CVarGetFloat("gMainMusicVolume", 1.0f));
@@ -116,25 +121,19 @@ void DrawSettingsMenu(){
UIWidgets::Spacer(0);
if (ImGui::BeginMenu("Controller")) {
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2 (12.0f, 6.0f));
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.0f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.22f, 0.38f, 0.56f, 1.0f));
if (GameUI::mInputEditorWindow) {
if (ImGui::Button("Controller Mapping", ImVec2 (-1.0f, 0.0f))) {
GameUI::mInputEditorWindow->ToggleVisibility();
}
}
UIWidgets::PaddedSeparator();
ImGui::PopStyleColor(1);
ImGui::PopStyleVar(3);
if (UIWidgets::BeginMenu("Controller")) {
UIWidgets::WindowButton("Controller Mapping", "gInputEditorWindow", GameUI::mInputEditorWindow);
UIWidgets::Spacer(0);
#ifndef __SWITCH__
UIWidgets::EnhancementCheckbox("Menubar Controller Navigation", "gControlNav");
UIWidgets::Tooltip("Allows controller navigation of the SOH menu bar (Settings, Enhancements,...)\nCAUTION: This will disable game inputs while the menubar is visible.\n\nD-pad to move between items, A to select, and X to grab focus on the menu bar");
UIWidgets::CVarCheckbox("Menubar Controller Navigation", "gControlNav", {
.tooltip = "Allows controller navigation of the SOH menu bar (Settings, Enhancements,...)\nCAUTION: This will disable game inputs while the menubar is visible.\n\nD-pad to move between items, A to select, and X to grab focus on the menu bar"
});
#endif
UIWidgets::PaddedEnhancementCheckbox("Show Inputs", "gInputEnabled", true, false);
UIWidgets::Tooltip("Shows currently pressed inputs on the bottom right of the screen");
UIWidgets::CVarCheckbox("Show Inputs", "gInputEnabled", {
.tooltip = "Shows currently pressed inputs on the bottom right of the screen"
});
UIWidgets::PaddedEnhancementSliderFloat("Input Scale: %.1f", "##Input", "gInputScale", 1.0f, 3.0f, "", 1.0f, false, true, true, false);
UIWidgets::Tooltip("Sets the on screen size of the displayed inputs from the Show Inputs setting");
@@ -144,31 +143,22 @@ void DrawSettingsMenu(){
ImGui::EndMenu();
}
UIWidgets::Spacer(0);
ImGui::SetCursorPosY(0.0f);
if (ImGui::BeginMenu("Graphics")) {
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 6.0f));
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.0f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.22f, 0.38f, 0.56f, 1.0f));
UIWidgets::Spacer(0);
if (GameUI::mAdvancedResolutionSettingsWindow) {
if (ImGui::Button(GameUI::GetWindowButtonText("Advanced Resolution", CVarGetInteger("gAdvancedResolutionEditorEnabled", 0)).c_str(), ImVec2(-1.0f, 0.0f))) {
GameUI::mAdvancedResolutionSettingsWindow->ToggleVisibility();
}
}
ImGui::PopStyleColor(1);
ImGui::PopStyleVar(3);
if (UIWidgets::BeginMenu("Graphics")) {
UIWidgets::WindowButton("Resolution Editor", "gAdvancedResolutionEditorEnabled", GameUI::mAdvancedResolutionSettingsWindow);
UIWidgets::Tooltip("Multiplies your output resolution by the value inputted, as a more intensive but effective form of anti-aliasing");
LUS::Context::GetInstance()->GetWindow()->SetResolutionMultiplier(CVarGetFloat("gInternalResolution", 1));
UIWidgets::Spacer(0);
// Previously was running every frame, and nothing was setting it? Maybe a bad copy/paste?
// LUS::Context::GetInstance()->GetWindow()->SetResolutionMultiplier(CVarGetFloat("gInternalResolution", 1));
// UIWidgets::Tooltip("Multiplies your output resolution by the value inputted, as a more intensive but effective form of anti-aliasing");
#ifndef __WIIU__
UIWidgets::PaddedEnhancementSliderInt("MSAA: %d", "##IMSAA", "gMSAAValue", 1, 8, "", 1, true, true, false);
UIWidgets::Tooltip("Activates multi-sample anti-aliasing when above 1x up to 8x for 8 samples for every pixel");
LUS::Context::GetInstance()->GetWindow()->SetMsaaLevel(CVarGetInteger("gMSAAValue", 1));
if (UIWidgets::CVarSliderInt("MSAA: %d", "gMSAAValue", 1, 8, 1, {
.tooltip = "Activates multi-sample anti-aliasing when above 1x up to 8x for 8 samples for every pixel"
})) {
LUS::Context::GetInstance()->GetWindow()->SetMsaaLevel(CVarGetInteger("gMSAAValue", 1));
}
#endif
UIWidgets::Tooltip("Matches interpolation value to the current game's window refresh rate");
{ // FPS Slider
const int minFps = 30;
@@ -361,8 +351,8 @@ void DrawMenuBarIcon() {
ImVec2 iconSize = ImVec2(16.0f * 2, 16.0f * 2);
float posScale = 2.0f;
#else
ImVec2 iconSize = ImVec2(16.0f, 16.0f);
float posScale = 1.0f;
ImVec2 iconSize = ImVec2(20.0f, 20.0f);
float posScale = 1.5f;
#endif
ImGui::SetCursorPos(ImVec2(5, 2.5f) * posScale);
ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Game_Icon"), iconSize);
@@ -372,8 +362,8 @@ void DrawMenuBarIcon() {
}
void DrawGameMenu() {
if (ImGui::BeginMenu("Ghostship")) {
if (ImGui::MenuItem("Reset",
if (UIWidgets::BeginMenu("Ghostship")) {
if (UIWidgets::MenuItem("Reset",
#ifdef __APPLE__
"Command-R"
#else
@@ -384,11 +374,11 @@ void DrawGameMenu() {
}
#if !defined(__SWITCH__) && !defined(__WIIU__)
if (ImGui::MenuItem("Toggle Fullscreen", "F9")) {
if (UIWidgets::MenuItem("Toggle Fullscreen", "F9")) {
LUS::Context::GetInstance()->GetWindow()->ToggleFullscreen();
}
if (ImGui::MenuItem("Quit")) {
if (UIWidgets::MenuItem("Quit")) {
LUS::Context::GetInstance()->GetWindow()->Close();
}
#endif
@@ -397,17 +387,21 @@ void DrawGameMenu() {
}
void DrawEnhancementsMenu() {
if (ImGui::BeginMenu("Enhancements")) {
if (UIWidgets::BeginMenu("Enhancements")) {
if (ImGui::BeginMenu("Gameplay")) {
UIWidgets::PaddedEnhancementCheckbox("No Level of Detail (LOD)", "gDisableLOD", true, false);
UIWidgets::Tooltip("Disable Level of Detail (LOD) to avoid models using lower poly versions at a distance");
UIWidgets::PaddedEnhancementCheckbox("Select any star from menu", "gSelectAllStars", true, false);
UIWidgets::Tooltip("Let's you select any star from the menu regardless of the courses completion status.");
UIWidgets::PaddedEnhancementCheckbox("Collecting Stars Will Not Exit Level", "gStarNoExit", true, false);
UIWidgets::Tooltip("Stars act like the 100 coin star and will not take you out of the level");
UIWidgets::PaddedEnhancementCheckbox("Avoid playing peach cutscene", "gDisablePeachCutscene", true, false);
UIWidgets::Tooltip("Avoid playing the peach cutscene when starting a new game");
if (UIWidgets::BeginMenu("Gameplay")) {
UIWidgets::CVarCheckbox("No Level of Detail (LOD)", "gDisableLOD", {
.tooltip = "Disable Level of Detail (LOD) to avoid models using lower poly versions at a distance"
});
UIWidgets::CVarCheckbox("Select any star from menu", "gSelectAllStars", {
.tooltip = "Let's you select any star from the menu regardless of the courses completion status."
});
UIWidgets::CVarCheckbox("Collecting Stars Will Not Exit Level", "gStarNoExit", {
.tooltip = "Stars act like the 100 coin star and will not take you out of the level"
});
UIWidgets::CVarCheckbox("Avoid playing peach cutscene", "gDisablePeachCutscene", {
.tooltip = "Avoid playing the peach cutscene when starting a new game"
});
ImGui::EndMenu();
}
@@ -416,47 +410,28 @@ void DrawEnhancementsMenu() {
}
void DrawCheatsMenu() {
if (ImGui::BeginMenu("Cheats")) {
UIWidgets::PaddedEnhancementCheckbox("Infinite Health", "gInfiniteHealth", true, false);
UIWidgets::PaddedEnhancementCheckbox("Infinite Lives", "gInfiniteLives", true, false);
if (UIWidgets::BeginMenu("Cheats")) {
UIWidgets::CVarCheckbox("Infinite Health", "gInfiniteHealth");
UIWidgets::CVarCheckbox("Infinite Lives", "gInfiniteLives");
ImGui::EndMenu();
}
}
void DrawDebugMenu() {
if (ImGui::BeginMenu("Developer")) {
if (UIWidgets::BeginMenu("Developer")) {
UIWidgets::CVarCheckbox("Debug mode", "gEnableDebugMode", {
.tooltip = "Various debug features, including a level selector from the main menu"
});
UIWidgets::PaddedEnhancementCheckbox("Enable level selector", "gEnableDebugMode", true, false);
UIWidgets::Tooltip("Enable the level selector in the main menu");
UIWidgets::Spacer(0);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 6.0f));
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.22f, 0.38f, 0.56f, 1.0f));
if (GameUI::mStatsWindow) {
if (ImGui::Button(
GameUI::GetWindowButtonText("Stats", CVarGetInteger("gStatsEnabled", 0)).c_str(),
ImVec2(-1.0f, 0.0f))) {
GameUI::mStatsWindow->ToggleVisibility();
}
UIWidgets::Tooltip("Shows the stats window, with your FPS and frametimes, and the OS "
"you're playing on");
}
if (GameUI::mConsoleWindow) {
if (ImGui::Button(
GameUI::GetWindowButtonText("Console", CVarGetInteger("gConsoleEnabled", 0))
.c_str(),
ImVec2(-1.0f, 0.0f))) {
GameUI::mConsoleWindow->ToggleVisibility();
}
UIWidgets::Tooltip("Enables the console window, allowing you to input commands, type "
"help for some examples");
}
ImGui::PopStyleVar(3);
ImGui::PopStyleColor(1);
UIWidgets::WindowButton("Stats", "gStatsEnabled", GameUI::mStatsWindow, {
.tooltip = "Shows the stats window, with your FPS and frametimes, and the OS you're playing on"
});
UIWidgets::WindowButton("Console", "gConsoleEnabled", GameUI::mConsoleWindow, {
.tooltip = "Enables the console window, allowing you to input commands, type help for some examples"
});
ImGui::EndMenu();
}
@@ -466,10 +441,6 @@ void GameMenuBar::DrawElement() {
if(ImGui::BeginMenuBar()){
DrawMenuBarIcon();
static ImVec2 sWindowPadding(8.0f, 8.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, sWindowPadding);
DrawGameMenu();
ImGui::SetCursorPosY(0.0f);
@@ -488,7 +459,6 @@ void GameMenuBar::DrawElement() {
DrawDebugMenu();
ImGui::PopStyleVar(1);
ImGui::EndMenuBar();
}
}
+349
View File
@@ -596,4 +596,353 @@ namespace UIWidgets {
}
ImGui::PopID();
}
// V2
void PushStyleMenu(const ImVec4& color) {
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(color.x, color.y, color.z, 0.5f));
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_PopupBg, UIWidgets::Colors::DarkGray);
ImGui::PushStyleColor(ImGuiCol_Border, UIWidgets::Colors::DarkGray);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8.0f, 15.0f));
ImGui::PushStyleVar(ImGuiStyleVar_PopupBorderSize, 3.0f);
}
void PopStyleMenu() {
ImGui::PopStyleVar(2);
ImGui::PopStyleColor(4);
}
bool BeginMenu(const char* label, const ImVec4& color) {
bool dirty = false;
PushStyleMenu(color);
if (ImGui::BeginMenu(label)) {
dirty = true;
}
PopStyleMenu();
return dirty;
}
void PushStyleMenuItem(const ImVec4& color) {
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(20.0f, 15.0f));
}
void PopStyleMenuItem() {
ImGui::PopStyleVar(1);
ImGui::PopStyleColor(1);
}
bool MenuItem(const char* label, const char* shortcut, const ImVec4& color) {
bool dirty = false;
PushStyleMenuItem(color);
if (ImGui::MenuItem(label, shortcut)) {
dirty = true;
}
PopStyleMenuItem();
return dirty;
}
void PushStyleButton(const ImVec4& color) {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(color.x, color.y, color.z, 0.8f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(color.x, color.y, color.z, 0.6f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.0f, 0.0f, 0.0f, 0.3f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10.0f, 8.0f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 5.0f);
}
void PopStyleButton() {
ImGui::PopStyleVar(3);
ImGui::PopStyleColor(4);
}
bool Button(const char* label, const ButtonOptions& options) {
ImGui::BeginDisabled(options.disabled);
PushStyleButton(options.color);
bool dirty = ImGui::Button(label, options.size);
PopStyleButton();
ImGui::EndDisabled();
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));
}
return dirty;
}
bool WindowButton(const char* label, const char* cvarName, std::shared_ptr<LUS::GuiWindow> windowPtr, const ButtonOptions& options) {
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0));
std::string buttonText = label;
bool dirty = false;
if (CVarGetInteger(cvarName, 0)) {
buttonText = ICON_FA_WINDOW_CLOSE " " + buttonText;
} else {
buttonText = ICON_FA_EXTERNAL_LINK_SQUARE " " + buttonText;
}
if (Button(buttonText.c_str(), options)) {
windowPtr->ToggleVisibility();
dirty = true;
}
ImGui::PopStyleVar();
return dirty;
}
void PushStyleCheckbox(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, 0.8f));
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(color.x, color.y, color.z, 0.6f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.0f, 0.0f, 0.0f, 0.3f));
ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(1.0f, 1.0f, 1.0f, 0.7f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10.0f, 6.0f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 5.0f);
}
void PopStyleCheckbox() {
ImGui::PopStyleVar(3);
ImGui::PopStyleColor(5);
}
bool Checkbox(const char* label, bool* value, const CheckboxOptions& options) {
ImGui::PushID(label);
bool dirty = false;
float startX = ImGui::GetCursorPosX();
const char* invisibleLabel = ("##" + std::string(label)).c_str();
ImGui::BeginDisabled(options.disabled);
PushStyleCheckbox(options.color);
if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::GetStyle().FramePadding.x * 2 - ImGui::GetStyle().ItemSpacing.x);
} else if (options.labelPosition == LabelPosition::Above) {
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
ImGui::Text(label);
ImGui::NewLine();
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::GetStyle().FramePadding.x * 2 - ImGui::GetStyle().ItemSpacing.x);
}
} else if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Above) {
ImGui::Text(label);
}
}
dirty = ImGui::Checkbox(invisibleLabel, value);
if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition == LabelPosition::Near) {
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x - ImGui::GetStyle().FramePadding.x * 2 - ImGui::GetStyle().ItemSpacing.x * 2);
ImGui::Text(label);
} else if (options.labelPosition == LabelPosition::Far) {
ImGui::SameLine();
ImGui::SetCursorPosX(startX);
ImGui::Text(label);
}
} else 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);
}
}
PopStyleCheckbox();
ImGui::EndDisabled();
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 CVarCheckbox(const char* label, const char* cvarName, const CheckboxOptions& options) {
bool dirty = false;
bool value = (bool)CVarGetInteger(cvarName, options.defaultValue);
if (Checkbox(label, &value, options)) {
CVarSetInteger(cvarName, value);
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
dirty = true;
}
return dirty;
}
void PushStyleCombobox(const ImVec4& color) {
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(color.x, color.y, color.z, 0.8f));
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(color.x, color.y, color.z, 0.6f));
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(color.x, color.y, color.z, 0.6f));
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(color.x, color.y, color.z, 0.8f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(color.x, color.y, color.z, 0.5f));
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(color.x, color.y, color.z, 0.6f));
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(color.x, color.y, color.z, 0.6f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
ImGui::PushStyleVar(ImGuiStyleVar_PopupRounding, 3.0f);
ImGui::PushStyleVar(ImGuiStyleVar_PopupBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10.0f, 6.0f));
}
void PopStyleCombobox() {
ImGui::PopStyleVar(4);
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();
const char* invisibleLabel = ("##" + std::string(label)).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));
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImVec4(1.0, 1.0, 1.0, 0.4f));
ImGui::PushStyleColor(ImGuiCol_SliderGrabActive, ImVec4(1.0, 1.0, 1.0, 0.5f));
ImGui::PushStyleVar(ImGuiStyleVar_GrabRounding, 3.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10.0f, 8.0f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
}
void PopStyleSlider() {
ImGui::PopStyleVar(4);
ImGui::PopStyleColor(6);
}
bool CVarSliderInt(const char* label, const char* cvarName, int32_t min, int32_t max, const int32_t defaultValue, const SliderOptions& options){
bool dirty = false;
const char* invisibleLabel = ("##" + std::string(label)).c_str();
int32_t value = CVarGetInteger(cvarName, defaultValue);
ImGui::PushID(label);
ImGui::BeginGroup();
ImGui::BeginDisabled(options.disabled);
PushStyleSlider(options.color);
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Above) {
ImGui::Text(label, value);
}
} 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, value);
}
}
if (options.showButtons) {
if (Button("-", { .size = Sizes::Inline, .color = options.color }) && value > min) {
value--;
CVarSetInteger(cvarName, value);
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
dirty = true;
}
ImGui::SameLine(0, 3.0f);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - (ImGui::CalcTextSize("+").x + 20.0f + 3.0f));
} else {
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
}
if (ImGui::SliderScalar(invisibleLabel, ImGuiDataType_S32, &value, &min, &max, options.format, options.flags)) {
CVarSetInteger(cvarName, value);
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
dirty = true;
}
if (options.showButtons) {
ImGui::SameLine(0, 3.0f);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (Button("+", { .size = Sizes::Inline, .color = options.color }) && value < max) {
value++;
CVarSetInteger(cvarName, value);
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
dirty = true;
}
}
PopStyleSlider();
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;
}
}
+102
View File
@@ -5,6 +5,7 @@
#include <span>
#include <stdint.h>
#include <ImGui/imgui.h>
#include <libultraship/libultraship.h>
namespace UIWidgets {
@@ -87,4 +88,105 @@ namespace UIWidgets {
void DrawFlagArray32(const std::string& name, uint32_t& flags);
void DrawFlagArray16(const std::string& name, uint16_t& flags);
void DrawFlagArray8(const std::string& name, uint8_t& flags);
// V2
namespace Colors {
const ImVec4 White = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
const ImVec4 Gray = ImVec4(0.4f, 0.4f, 0.4f, 1.0f);
const ImVec4 DarkGray = ImVec4(0.1f, 0.1f, 0.1f, 1.0f);
const ImVec4 Indigo = ImVec4(0.24f, 0.31f, 0.71f, 1.0f);
const ImVec4 Red = ImVec4(0.5f, 0.0f, 0.0f, 1.0f);
const ImVec4 DarkRed = ImVec4(0.3f, 0.0f, 0.0f, 1.0f);
const ImVec4 LightGreen = ImVec4(0.0f, 0.7f, 0.0f, 1.0f);
const ImVec4 Green = ImVec4(0.0f, 0.5f, 0.0f, 1.0f);
const ImVec4 DarkGreen = ImVec4(0.0f, 0.3f, 0.0f, 1.0f);
const ImVec4 Yellow = ImVec4(1.0f, 0.627f, 0.0f, 1.0f);
};
namespace Sizes {
const ImVec2 Inline = ImVec2(0.0f, 0.0f);
const ImVec2 Fill = ImVec2(-1.0f, 0.0f);
}
enum LabelPosition {
Near,
Far,
Above,
None,
Within,
};
enum ComponentAlignment {
Left,
Right,
};
void PushStyleMenu(const ImVec4& color = Colors::Indigo);
void PopStyleMenu();
bool BeginMenu(const char* label, const ImVec4& color = Colors::Indigo);
void PushStyleMenuItem(const ImVec4& color = Colors::Indigo);
void PopStyleMenuItem();
bool MenuItem(const char* label, const char* shortcut = NULL, const ImVec4& color = Colors::Indigo);
struct ButtonOptions {
const ImVec4 color = Colors::Gray;
const ImVec2 size = Sizes::Fill;
const char* tooltip = "";
bool disabled = false;
const char* disabledTooltip = "";
};
void PushStyleButton(const ImVec4& color = Colors::Gray);
void PopStyleButton();
bool Button(const char* label, const ButtonOptions& options = {});
bool WindowButton(const char* label, const char* cvarName, std::shared_ptr<LUS::GuiWindow> windowPtr, const ButtonOptions& options = {});
struct CheckboxOptions {
const ImVec4 color = Colors::Indigo;
const char* tooltip = "";
bool disabled = false;
const char* disabledTooltip = "";
bool defaultValue = false; // Only applicable to CVarCheckbox
ComponentAlignment alignment = ComponentAlignment::Left;
LabelPosition labelPosition = LabelPosition::Near;
};
void PushStyleCheckbox(const ImVec4& color = Colors::Indigo);
void PopStyleCheckbox();
bool Checkbox(const char* label, bool* v, const CheckboxOptions& options = {});
bool CVarCheckbox(const char* label, const char* cvarName, const CheckboxOptions& options = {});
struct ComboboxOptions {
const ImVec4 color = Colors::Indigo;
const char* tooltip = "";
bool disabled = false;
const char* disabledTooltip = "";
uint32_t defaultIndex = 0; // Only applicable to CVarCombobox
ComponentAlignment alignment = ComponentAlignment::Left;
LabelPosition labelPosition = LabelPosition::Above;
ImGuiComboFlags flags = 0;
};
void PushStyleCombobox(const ImVec4& color = Colors::Indigo);
void PopStyleCombobox();
bool Combobox(const char* label, 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 = {});
struct SliderOptions {
const ImVec4 color = Colors::Green;
const char* tooltip = "";
bool disabled = false;
const char* disabledTooltip = "";
bool showButtons = true;
ImGuiSliderFlags flags = 0;
const char* format = "%d";
ComponentAlignment alignment = ComponentAlignment::Left;
LabelPosition labelPosition = LabelPosition::Above;
};
void PushStyleSlider(const ImVec4& color = Colors::Indigo);
void PopStyleSlider();
bool CVarSliderInt(const char* label, const char* cvarName, int32_t min, int32_t max, const int32_t defaultValue, const SliderOptions& options = {});
bool CVarSliderFloat(const char* label, const char* cvarName, float min, float max, const float defaultValue, const SliderOptions& options = {});
}