Browse Source

Fix menus wrapping in the up direction

pull/898/head
Anders Jenbo 5 years ago
parent
commit
85f44063df
  1. 70
      SourceX/DiabloUI/diabloui.cpp

70
SourceX/DiabloUI/diabloui.cpp

@ -24,9 +24,7 @@
namespace dvl {
std::size_t SelectedItemMin = 1;
std::size_t SelectedItemMax = 1;
std::size_t SelectedItemMax;
std::size_t ListViewportSize = 1;
const std::size_t *ListOffset = NULL;
@ -78,9 +76,8 @@ void UiDestroy()
void UiInitList(int count, void (*fnFocus)(int value), void (*fnSelect)(int value), void (*fnEsc)(), std::vector<UiItemBase *> items, bool itemsWraps, bool (*fnYesNo)())
{
SelectedItem = 0;
SelectedItemMin = 0;
SelectedItemMax = std::max(count - 1, 0);
ListViewportSize = SelectedItemMax - SelectedItemMin + 1;
ListViewportSize = count;
gfnListFocus = fnFocus;
gfnListSelect = fnSelect;
gfnListEsc = fnEsc;
@ -114,7 +111,7 @@ void UiInitScrollBar(UiScrollBar *ui_sb, std::size_t viewport_size, const std::s
{
ListViewportSize = viewport_size;
ListOffset = current_offset;
if (ListViewportSize >= static_cast<std::size_t>(SelectedItemMax - SelectedItemMin + 1)) {
if (ListViewportSize >= static_cast<std::size_t>(SelectedItemMax + 1)) {
ui_sb->add_flag(UIS_HIDDEN);
} else {
ui_sb->remove_flag(UIS_HIDDEN);
@ -124,8 +121,7 @@ void UiInitScrollBar(UiScrollBar *ui_sb, std::size_t viewport_size, const std::s
void UiInitList_clear()
{
SelectedItem = 0;
SelectedItemMin = 1;
SelectedItemMax = 1;
SelectedItemMax = 0;
ListViewportSize = 1;
gfnListFocus = NULL;
gfnListSelect = NULL;
@ -147,22 +143,8 @@ void UiPlaySelectSound()
gfnSoundFunction("sfx\\items\\titlslct.wav");
}
void UiFocus(std::size_t itemIndex, bool wrap = false)
void UiFocus(std::size_t itemIndex)
{
if (!wrap) {
if (itemIndex < SelectedItemMin) {
itemIndex = SelectedItemMin;
return;
} else if (itemIndex > SelectedItemMax) {
itemIndex = SelectedItemMax ? SelectedItemMax : SelectedItemMin;
return;
}
} else if (itemIndex < SelectedItemMin) {
itemIndex = SelectedItemMax ? SelectedItemMax : SelectedItemMin;
} else if (itemIndex > SelectedItemMax) {
itemIndex = SelectedItemMin;
}
if (SelectedItem == itemIndex)
return;
@ -174,14 +156,30 @@ void UiFocus(std::size_t itemIndex, bool wrap = false)
gfnListFocus(itemIndex);
}
void UiFocusUp()
{
if (SelectedItem > 0)
UiFocus(SelectedItem - 1);
else if (UiItemsWraps)
UiFocus(SelectedItemMax);
}
void UiFocusDown()
{
if (SelectedItem < SelectedItemMax)
UiFocus(SelectedItem + 1);
else if (UiItemsWraps)
UiFocus(0);
}
// UiFocusPageUp/Down mimics the slightly weird behaviour of actual Diablo.
void UiFocusPageUp()
{
if (ListOffset == NULL || *ListOffset == 0) {
UiFocus(SelectedItemMin);
UiFocus(0);
} else {
const std::size_t relpos = (SelectedItem - SelectedItemMin) - *ListOffset;
const std::size_t relpos = SelectedItem - *ListOffset;
std::size_t prev_page_start = SelectedItem - relpos;
if (prev_page_start >= ListViewportSize)
prev_page_start -= ListViewportSize;
@ -197,7 +195,7 @@ void UiFocusPageDown()
if (ListOffset == NULL || *ListOffset + ListViewportSize > static_cast<std::size_t>(SelectedItemMax)) {
UiFocus(SelectedItemMax);
} else {
const std::size_t relpos = (SelectedItem - SelectedItemMin) - *ListOffset;
const std::size_t relpos = SelectedItem - *ListOffset;
std::size_t next_page_end = SelectedItem + (ListViewportSize - relpos - 1);
if (next_page_end + ListViewportSize <= static_cast<std::size_t>(SelectedItemMax))
next_page_end += ListViewportSize;
@ -244,10 +242,10 @@ void UiFocusNavigation(SDL_Event *event)
UiFocusNavigationSelect();
return;
case MenuAction_UP:
UiFocus(SelectedItem - 1, UiItemsWraps);
UiFocusUp();
return;
case MenuAction_DOWN:
UiFocus(SelectedItem + 1, UiItemsWraps);
UiFocusDown();
return;
case MenuAction_PAGE_UP:
UiFocusPageUp();
@ -270,9 +268,9 @@ void UiFocusNavigation(SDL_Event *event)
#ifndef USE_SDL1
if (event->type == SDL_MOUSEWHEEL) {
if (event->wheel.y > 0) {
UiFocus(SelectedItem - 1, UiItemsWraps);
UiFocusUp();
} else if (event->wheel.y < 0) {
UiFocus(SelectedItem + 1, UiItemsWraps);
UiFocusDown();
}
return;
}
@ -749,9 +747,8 @@ void Render(const UiScrollBar *ui_sb)
}
// Thumb:
if (SelectedItemMax - SelectedItemMin > 0) {
const SDL_Rect rect = ThumbRect(
ui_sb, SelectedItem - SelectedItemMin, SelectedItemMax - SelectedItemMin + 1);
if (SelectedItemMax > 0) {
const SDL_Rect rect = ThumbRect(ui_sb, SelectedItem, SelectedItemMax + 1);
DrawArt(rect.x, rect.y, ui_sb->m_thumb);
}
}
@ -842,17 +839,16 @@ bool HandleMouseEventScrollBar(const SDL_Event &event, const UiScrollBar *ui_sb)
return false;
if (event.type == SDL_MOUSEBUTTONUP) {
if (scrollBarState.upArrowPressed && IsInsideRect(event, UpArrowRect(ui_sb))) {
UiFocus(SelectedItem - 1);
UiFocusUp();
return true;
} else if (scrollBarState.downArrowPressed && IsInsideRect(event, DownArrowRect(ui_sb))) {
UiFocus(SelectedItem + 1);
UiFocusDown();
return true;
}
} else if (event.type == SDL_MOUSEBUTTONDOWN) {
if (IsInsideRect(event, BarRect(ui_sb))) {
// Scroll up or down based on thumb position.
const SDL_Rect thumb_rect = ThumbRect(
ui_sb, SelectedItem - SelectedItemMin, SelectedItemMax - SelectedItemMin + 1);
const SDL_Rect thumb_rect = ThumbRect(ui_sb, SelectedItem, SelectedItemMax + 1);
if (event.button.y < thumb_rect.y) {
UiFocusPageUp();
} else if (event.button.y > thumb_rect.y + thumb_rect.h) {

Loading…
Cancel
Save