Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 50 additions & 1 deletion Source/DiabloUI/settingsmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <SDL3/SDL_rect.h>
#include <SDL3/SDL_timer.h>
#else
#include <SDL.h>

Check warning on line 15 in Source/DiabloUI/settingsmenu.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/DiabloUI/settingsmenu.cpp:15:1 [misc-include-cleaner]

included header SDL.h is not used directly
#endif

#include <function_ref.hpp>
Expand Down Expand Up @@ -82,7 +82,7 @@
};

ControllerButtonCombo padEntryCombo {};
Uint32 padEntryStartTime = 0;

Check warning on line 85 in Source/DiabloUI/settingsmenu.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/DiabloUI/settingsmenu.cpp:85:1 [misc-include-cleaner]

no header providing "Uint32" is directly included
std::string padEntryTimerText;

bool IsValidEntry(OptionEntryBase *pOptionEntry)
Expand All @@ -107,6 +107,41 @@
return GetLineWidth("{}: {}", formatArgs.data(), formatArgs.size(), 0, GameFontTables::GameFont24, 1) >= (rectList.size.width - 90);
}

void AddSettingsSpacer()
{
vecDialogItems.push_back(std::make_unique<UiListItem>(
std::string_view {}, static_cast<int>(SpecialMenuEntry::None), UiFlags::ElementDisabled));
}

void AddSettingsSectionHeader(std::string_view text, bool addSpacer)
{
if (addSpacer)
AddSettingsSpacer();
vecDialogItems.push_back(std::make_unique<UiListItem>(
text, static_cast<int>(SpecialMenuEntry::None), UiFlags::ColorWhitegold | UiFlags::ElementDisabled));
}

void MaybeAddGameplaySectionHeader(OptionEntryBase *pEntry)
{
if (selectedCategory != &GetOptions().Gameplay)
return;

const GameplayOptions &gameplay = GetOptions().Gameplay;

// Sections are intentionally lightweight: just labels/separators, no submenus and no changes to options model.
if (pEntry == &gameplay.friendlyFire) {
AddSettingsSectionHeader(_("Game Rules"), false);
} else if (pEntry == &gameplay.runInTown) {
AddSettingsSectionHeader(_("Controls"), true);
} else if (pEntry == &gameplay.experienceBar) {
AddSettingsSectionHeader(_("Interface"), true);
} else if (pEntry == &gameplay.autoRefillBelt) {
AddSettingsSectionHeader(_("Items & Auto Pickup"), true);
} else if (pEntry == &gameplay.disableCripplingShrines) {
AddSettingsSectionHeader(_("Safety & Focus"), true);
}
}

void CleanUpSettingsUI()
{
UiInitList_clear();
Expand Down Expand Up @@ -139,7 +174,7 @@
void StartPadEntryTimer()
{
padEntryCombo = ControllerButton_NONE;
padEntryStartTime = SDL_GetTicks();

Check warning on line 177 in Source/DiabloUI/settingsmenu.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/DiabloUI/settingsmenu.cpp:177:22 [misc-include-cleaner]

no header providing "SDL_GetTicks" is directly included
if (padEntryStartTime == 0)
padEntryStartTime++;
// Removes access to these dialog items while entering bindings
Expand Down Expand Up @@ -167,7 +202,7 @@
StopPadEntryTimer();
return;
}
padEntryTimerText = StrCat(_("Press gamepad buttons to change."), " ", 10 - elapsed / 1000);

Check warning on line 205 in Source/DiabloUI/settingsmenu.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/DiabloUI/settingsmenu.cpp:205:78 [readability-math-missing-parentheses]

'/' has higher precedence than '-'; add parentheses to explicitly specify the order of operations
vecDialogItems[IndexPadTimerText]->m_text = padEntryTimerText;
}

Expand Down Expand Up @@ -243,7 +278,7 @@
return true;
}

void ItemSelected(size_t value)

Check warning on line 281 in Source/DiabloUI/settingsmenu.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/DiabloUI/settingsmenu.cpp:281:6 [readability-function-cognitive-complexity]

function 'ItemSelected' has cognitive complexity of 32 (threshold 25)
{
auto &vecItem = vecDialogItems[value];
const int vecItemValue = vecItem->m_value;
Expand All @@ -257,7 +292,7 @@
break;
case SpecialMenuEntry::UnbindKey: {
auto *pOptionKey = static_cast<KeymapperOptions::Action *>(selectedOption);
pOptionKey->SetValue(SDLK_UNKNOWN);

Check warning on line 295 in Source/DiabloUI/settingsmenu.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/DiabloUI/settingsmenu.cpp:295:25 [misc-include-cleaner]

no header providing "SDLK_UNKNOWN" is directly included
vecDialogItems[IndexKeyOrPadInput]->m_text = selectedOption->GetValueDescription();
break;
}
Expand Down Expand Up @@ -359,7 +394,7 @@

} // namespace

void UiSettingsMenu()

Check warning on line 397 in Source/DiabloUI/settingsmenu.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/DiabloUI/settingsmenu.cpp:397:6 [readability-function-cognitive-complexity]

function 'UiSettingsMenu' has cognitive complexity of 144 (threshold 25)

Check warning on line 397 in Source/DiabloUI/settingsmenu.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/DiabloUI/settingsmenu.cpp:397:6 [misc-use-internal-linkage]

function 'UiSettingsMenu' can be made static or moved into an anonymous namespace to enforce internal linkage
{
backToMain = false;
shownMenu = ShownMenuType::Categories;
Expand Down Expand Up @@ -401,7 +436,7 @@
vecDialog.push_back(std::make_unique<UiArtText>(titleText.data(), MakeSdlRect(uiRectangle.position.x, uiRectangle.position.y + 161, uiRectangle.size.width, 35), UiFlags::FontSize30 | UiFlags::ColorUiSilver | UiFlags::AlignCenter, 8));

size_t itemToSelect = 0;
std::optional<tl::function_ref<bool(SDL_Event &)>> eventHandler;

Check warning on line 439 in Source/DiabloUI/settingsmenu.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/DiabloUI/settingsmenu.cpp:439:39 [misc-include-cleaner]

no header providing "SDL_Event" is directly included

switch (shownMenu) {
case ShownMenuType::Categories: {
Expand All @@ -419,11 +454,21 @@
}
} break;
case ShownMenuType::Settings: {
bool foundSelectedOption = false;
std::optional<size_t> firstSelectableItemIndex;
for (OptionEntryBase *pEntry : selectedCategory->GetEntries()) {
if (!IsValidEntry(pEntry))
continue;
if (selectedOption == pEntry)

MaybeAddGameplaySectionHeader(pEntry);

if (!firstSelectableItemIndex.has_value())
firstSelectableItemIndex = vecDialogItems.size();
if (selectedOption == pEntry) {
itemToSelect = vecDialogItems.size();
foundSelectedOption = true;
}

auto formatArgs = CreateDrawStringFormatArgForEntry(pEntry);
const int optionId = static_cast<int>(vecOptions.size());
if (NeedsTwoLinesToDisplayOption(formatArgs)) {
Expand All @@ -434,6 +479,10 @@
}
vecOptions.push_back(pEntry);
}
// If previously selected option doesn't exist (e.g., became invisible),
// set focus on first real option, not on header.
if (!foundSelectedOption && firstSelectableItemIndex.has_value())
itemToSelect = *firstSelectableItemIndex;
} break;
case ShownMenuType::ListOption: {
auto *pOptionList = static_cast<OptionEntryListBase *>(selectedOption);
Expand All @@ -452,7 +501,7 @@
if (SelectedItem != IndexKeyOrPadInput)
return false;
uint32_t key = SDLK_UNKNOWN;
switch (event.type) {

Check warning on line 504 in Source/DiabloUI/settingsmenu.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/DiabloUI/settingsmenu.cpp:504:5 [bugprone-switch-missing-default-case]

switching on non-enum value without default case may not cover all cases
case SDL_EVENT_KEY_DOWN: {
SDL_Keycode keycode = SDLC_EventKey(event);
remap_keyboard_key(&keycode);
Expand Down
Loading