From 6014250f3ade79f49667c1e10e107288f6fb480a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 28 Sep 2010 16:28:44 +0000 Subject: [PATCH] - fixed: Option menus with no selectable items crashed. SVN r2861 (trunk) --- src/menu/menu.h | 1 + src/menu/optionmenu.cpp | 59 +++++++++++++++++++++++++++++++++-------- 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/menu/menu.h b/src/menu/menu.h index 692542198..f13300bc0 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -580,6 +580,7 @@ public: FOptionMenuItem *GetItem(FName name); DOptionMenu(DMenu *parent = NULL, FOptionMenuDescriptor *desc = NULL); virtual void Init(DMenu *parent = NULL, FOptionMenuDescriptor *desc = NULL); + int FirstSelectable(); bool Responder (event_t *ev); bool MenuEvent (int mkey, bool fromcontroller); bool MouseEvent(int type, int x, int y); diff --git a/src/menu/optionmenu.cpp b/src/menu/optionmenu.cpp index 9d3213716..5c45d0efb 100644 --- a/src/menu/optionmenu.cpp +++ b/src/menu/optionmenu.cpp @@ -96,18 +96,30 @@ void DOptionMenu::Init(DMenu *parent, FOptionMenuDescriptor *desc) mParentMenu = parent; GC::WriteBarrier(this, parent); mDesc = desc; + if (mDesc != NULL) mDesc->mSelectedItem = FirstSelectable(); + +} + +//============================================================================= +// +// +// +//============================================================================= + +int DOptionMenu::FirstSelectable() +{ if (mDesc != NULL && mDesc->mSelectedItem < 0) { // Go down to the first selectable item int i = -1; - mDesc->mSelectedItem = -1; do { i++; } - while (!mDesc->mItems[i]->Selectable() && i < (int)mDesc->mItems.Size()); - if (i>=0) mDesc->mSelectedItem = i; + while (i < (int)mDesc->mItems.Size() && !mDesc->mItems[i]->Selectable()); + if (i>=0 && i < (int)mDesc->mItems.Size()) return i; } + return -1; } //============================================================================= @@ -176,6 +188,11 @@ bool DOptionMenu::MenuEvent (int mkey, bool fromcontroller) switch (mkey) { case MKEY_Up: + if (mDesc->mSelectedItem == -1) + { + mDesc->mSelectedItem = FirstSelectable(); + break; + } do { --mDesc->mSelectedItem; @@ -214,6 +231,11 @@ bool DOptionMenu::MenuEvent (int mkey, bool fromcontroller) break; case MKEY_Down: + if (mDesc->mSelectedItem == -1) + { + mDesc->mSelectedItem = FirstSelectable(); + break; + } do { ++mDesc->mSelectedItem; @@ -225,8 +247,17 @@ bool DOptionMenu::MenuEvent (int mkey, bool fromcontroller) } if (mDesc->mSelectedItem >= (int)mDesc->mItems.Size()) { - mDesc->mSelectedItem = 0; - mDesc->mScrollPos = 0; + if (startedAt == -1) + { + mDesc->mSelectedItem = -1; + mDesc->mScrollPos = -1; + break; + } + else + { + mDesc->mSelectedItem = 0; + mDesc->mScrollPos = 0; + } } } while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt); @@ -240,10 +271,13 @@ bool DOptionMenu::MenuEvent (int mkey, bool fromcontroller) { mDesc->mScrollPos = 0; } - mDesc->mSelectedItem = mDesc->mScrollTop + mDesc->mScrollPos + 1; - while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable()) + if (mDesc->mSelectedItem != -1) { - ++mDesc->mSelectedItem; + mDesc->mSelectedItem = mDesc->mScrollTop + mDesc->mScrollPos + 1; + while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable()) + { + ++mDesc->mSelectedItem; + } } } break; @@ -257,10 +291,13 @@ bool DOptionMenu::MenuEvent (int mkey, bool fromcontroller) { mDesc->mScrollPos = mDesc->mItems.Size() - mDesc->mScrollTop - pagesize; } - mDesc->mSelectedItem = mDesc->mScrollTop + mDesc->mScrollPos; - while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable()) + if (mDesc->mSelectedItem != -1) { - ++mDesc->mSelectedItem; + mDesc->mSelectedItem = mDesc->mScrollTop + mDesc->mScrollPos; + while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable()) + { + ++mDesc->mSelectedItem; + } } } break;