summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIra Rice <irarice@gmail.com>2009-02-25 00:50:33 -0700
committerIra Rice <irarice@gmail.com>2009-02-25 00:50:33 -0700
commitd8bc3a6418c5027d7f6c42ce8f8dceca8dee8971 (patch)
treefbb0b461bd151cbf3ad5aeedb80257140253f57c
parenta1e483913672e55704e8fbafeff5ea0ccc0c9b07 (diff)
downloadmana-d8bc3a6418c5027d7f6c42ce8f8dceca8dee8971.tar.gz
mana-d8bc3a6418c5027d7f6c42ce8f8dceca8dee8971.tar.bz2
mana-d8bc3a6418c5027d7f6c42ce8f8dceca8dee8971.tar.xz
mana-d8bc3a6418c5027d7f6c42ce8f8dceca8dee8971.zip
Fixed up NPC list dialogs to be navigatable by keyboard (scrolling
through the list requires the use of the mouse wheel at the moment), fixed wrapping behavior for wrapping around lists to actually wrap around lists properly, and placed a few checks for current_npc where they were assumed before which could cause the client to hang or crash in case the NPC is no longer around. Signed-off-by: Ira Rice <irarice@gmail.com>
-rw-r--r--src/game.cpp2
-rw-r--r--src/gui/listbox.cpp85
-rw-r--r--src/gui/listbox.h19
-rw-r--r--src/gui/npcintegerdialog.cpp11
-rw-r--r--src/gui/npclistdialog.cpp16
-rw-r--r--src/gui/npclistdialog.h5
-rw-r--r--src/gui/npcstringdialog.cpp5
-rw-r--r--src/gui/table.cpp6
-rw-r--r--src/net/npchandler.cpp2
9 files changed, 136 insertions, 15 deletions
diff --git a/src/game.cpp b/src/game.cpp
index e5f7b22b..16790cac 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -490,7 +490,7 @@ void Game::handleInput()
gcn::Window *requestedWindow = NULL;
if (setupWindow->isVisible() &&
- keyboard.getNewKeyIndex() > keyboard.KEY_NO_VALUE)
+ keyboard.getNewKeyIndex() > keyboard.KEY_NO_VALUE)
{
keyboard.setNewKey((int) event.key.keysym.sym);
keyboard.callbackNewKey();
diff --git a/src/gui/listbox.cpp b/src/gui/listbox.cpp
index f16857ce..8ae68e09 100644
--- a/src/gui/listbox.cpp
+++ b/src/gui/listbox.cpp
@@ -22,6 +22,7 @@
#include <guichan/font.hpp>
#include <guichan/graphics.hpp>
+#include <guichan/key.hpp>
#include <guichan/listmodel.hpp>
#include "color.h"
@@ -69,6 +70,90 @@ void ListBox::draw(gcn::Graphics *graphics)
}
}
+void ListBox::setSelected(int selected)
+{
+ if (!mListModel)
+ {
+ mSelected = -1;
+ }
+ else
+ {
+ if (selected < 0 && !mWrappingEnabled)
+ {
+ mSelected = -1;
+ }
+ else if (selected >= mListModel->getNumberOfElements() &&
+ mWrappingEnabled)
+ {
+ mSelected = 0;
+ }
+ else if ((selected >= mListModel->getNumberOfElements() &&
+ !mWrappingEnabled) || (selected < 0 && mWrappingEnabled))
+ {
+ mSelected = mListModel->getNumberOfElements() - 1;
+ }
+ else
+ {
+ mSelected = selected;
+ }
+ }
+}
+
+// -- KeyListener notifications
+void ListBox::keyPressed(gcn::KeyEvent& keyEvent)
+{
+ gcn::Key key = keyEvent.getKey();
+
+ if (key.getValue() == gcn::Key::ENTER || key.getValue() == gcn::Key::SPACE)
+ {
+ distributeActionEvent();
+ keyEvent.consume();
+ }
+ else if (key.getValue() == gcn::Key::UP)
+ {
+ setSelected(mSelected - 1);
+ keyEvent.consume();
+ }
+ else if (key.getValue() == gcn::Key::DOWN)
+ {
+ setSelected(mSelected + 1);
+ keyEvent.consume();
+ }
+ else if (key.getValue() == gcn::Key::HOME)
+ {
+ setSelected(0);
+ keyEvent.consume();
+ }
+ else if (key.getValue() == gcn::Key::END)
+ {
+ setSelected(getListModel()->getNumberOfElements() - 1);
+ keyEvent.consume();
+ }
+}
+
+void ListBox::mouseWheelMovedUp(gcn::MouseEvent& mouseEvent)
+{
+ if (isFocused())
+ {
+ if (getSelected() > 0 || (getSelected() == 0 && mWrappingEnabled))
+ {
+ setSelected(getSelected() - 1);
+ }
+
+ mouseEvent.consume();
+ }
+}
+
+void ListBox::mouseWheelMovedDown(gcn::MouseEvent& mouseEvent)
+{
+ if (isFocused())
+ {
+ setSelected(getSelected() + 1);
+
+ mouseEvent.consume();
+ }
+}
+
void ListBox::mouseDragged(gcn::MouseEvent &event)
{
// Pretend mouse is pressed continuously while dragged. Causes list
diff --git a/src/gui/listbox.h b/src/gui/listbox.h
index e783083f..a6392a94 100644
--- a/src/gui/listbox.h
+++ b/src/gui/listbox.h
@@ -49,6 +49,25 @@ class ListBox : public gcn::ListBox
void mouseDragged(gcn::MouseEvent &event);
+ // Inherited from KeyListener
+
+ virtual void keyPressed(gcn::KeyEvent& keyEvent);
+
+ // Inherited from MouseListener
+
+ virtual void mouseWheelMovedUp(gcn::MouseEvent& mouseEvent);
+
+ virtual void mouseWheelMovedDown(gcn::MouseEvent& mouseEvent);
+
+ /**
+ * Sets the selected item. The selected item is represented by
+ * an index from the list model.
+ *
+ * @param selected the selected item as an index from the list model.
+ * @see getSelected
+ */
+ void setSelected(int selected);
+
private:
static float mAlpha;
};
diff --git a/src/gui/npcintegerdialog.cpp b/src/gui/npcintegerdialog.cpp
index ea3398c9..d0a7c7be 100644
--- a/src/gui/npcintegerdialog.cpp
+++ b/src/gui/npcintegerdialog.cpp
@@ -72,15 +72,15 @@ int NpcIntegerDialog::getValue()
void NpcIntegerDialog::action(const gcn::ActionEvent &event)
{
- int finish = 0;
+ bool finish = false;
if (event.getId() == "ok")
{
- finish = 1;
+ finish = true;
}
else if (event.getId() == "cancel")
{
- finish = 1;
+ finish = true;
mValueField->reset();
}
else if (event.getId() == "decvalue")
@@ -99,7 +99,10 @@ void NpcIntegerDialog::action(const gcn::ActionEvent &event)
if (finish)
{
setVisible(false);
- current_npc->integerInput(mValueField->getValue());
+
+ if (current_npc)
+ current_npc->integerInput(mValueField->getValue());
+
current_npc = NULL;
mValueField->reset();
}
diff --git a/src/gui/npclistdialog.cpp b/src/gui/npclistdialog.cpp
index 81c33049..f3bb949a 100644
--- a/src/gui/npclistdialog.cpp
+++ b/src/gui/npclistdialog.cpp
@@ -45,7 +45,9 @@ NpcListDialog::NpcListDialog():
mItemList = new ListBox(this);
mItemList->setWrappingEnabled(true);
+
scrollArea = new ScrollArea(mItemList);
+
okButton = new Button(_("OK"), "ok", this);
cancelButton = new Button(_("Cancel"), "cancel", this);
@@ -95,10 +97,9 @@ void NpcListDialog::action(const gcn::ActionEvent &event)
{
// Send the selected index back to the server
int selectedIndex = mItemList->getSelected();
+
if (selectedIndex > -1)
- {
choice = selectedIndex + 1;
- }
}
else if (event.getId() == "cancel")
{
@@ -109,7 +110,16 @@ void NpcListDialog::action(const gcn::ActionEvent &event)
{
setVisible(false);
reset();
- current_npc->dialogChoice(choice);
+
+ if (current_npc)
+ current_npc->dialogChoice(choice);
+
current_npc = NULL;
}
}
+
+void NpcListDialog::requestFocus()
+{
+ mItemList->requestFocus();
+ mItemList->setSelected(0);
+}
diff --git a/src/gui/npclistdialog.h b/src/gui/npclistdialog.h
index a30bec28..de3a7a77 100644
--- a/src/gui/npclistdialog.h
+++ b/src/gui/npclistdialog.h
@@ -73,6 +73,11 @@ class NpcListDialog : public Window, public gcn::ActionListener,
*/
void reset();
+ /**
+ * Requests the listbox to take focus for input.
+ */
+ void requestFocus();
+
private:
gcn::ListBox *mItemList;
gcn::ScrollArea *scrollArea;
diff --git a/src/gui/npcstringdialog.cpp b/src/gui/npcstringdialog.cpp
index ef2de73a..140ca40f 100644
--- a/src/gui/npcstringdialog.cpp
+++ b/src/gui/npcstringdialog.cpp
@@ -64,7 +64,10 @@ void NpcStringDialog::action(const gcn::ActionEvent &event)
}
setVisible(false);
- current_npc->stringInput(mValueField->getText());
+
+ if (current_npc)
+ current_npc->stringInput(mValueField->getText());
+
current_npc = NULL;
mValueField->setText("");
}
diff --git a/src/gui/table.cpp b/src/gui/table.cpp
index 8acbc4f4..29a33b7a 100644
--- a/src/gui/table.cpp
+++ b/src/gui/table.cpp
@@ -402,25 +402,21 @@ void GuiTable::keyPressed(gcn::KeyEvent& keyEvent)
else if (key.getValue() == gcn::Key::UP)
{
setSelectedRow(mSelectedRow - 1);
-
keyEvent.consume();
}
else if (key.getValue() == gcn::Key::DOWN)
{
setSelectedRow(mSelectedRow + 1);
-
keyEvent.consume();
}
else if (key.getValue() == gcn::Key::LEFT)
{
setSelectedColumn(mSelectedColumn - 1);
-
keyEvent.consume();
}
else if (key.getValue() == gcn::Key::RIGHT)
{
setSelectedColumn(mSelectedColumn + 1);
-
keyEvent.consume();
}
else if (key.getValue() == gcn::Key::HOME)
@@ -460,7 +456,7 @@ void GuiTable::mouseWheelMovedUp(gcn::MouseEvent& mouseEvent)
{
if (isFocused())
{
- if (getSelectedRow() >= 0 )
+ if (getSelectedRow() > 0 || (getSelectedRow() == 0 && mWrappingEnabled))
{
setSelectedRow(getSelectedRow() - 1);
}
diff --git a/src/net/npchandler.cpp b/src/net/npchandler.cpp
index 94e145b4..26250d9e 100644
--- a/src/net/npchandler.cpp
+++ b/src/net/npchandler.cpp
@@ -60,6 +60,7 @@ void NPCHandler::handleMessage(MessageIn *msg)
current_npc = dynamic_cast<NPC*>(beingManager->findBeing(id));
npcListDialog->parseItems(msg->readString(msg->getLength() - 8));
npcListDialog->setVisible(true);
+ npcListDialog->requestFocus();
break;
case SMSG_NPC_MESSAGE:
@@ -68,7 +69,6 @@ void NPCHandler::handleMessage(MessageIn *msg)
player_node->setAction(LocalPlayer::STAND);
current_npc = dynamic_cast<NPC*>(beingManager->findBeing(id));
npcTextDialog->addText(msg->readString(msg->getLength() - 8));
- npcListDialog->setVisible(false);
npcTextDialog->setVisible(true);
break;