summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gui/buy.cpp37
-rw-r--r--src/gui/buy.h12
-rw-r--r--src/gui/inventorywindow.h4
-rw-r--r--src/gui/listbox.cpp57
-rw-r--r--src/gui/listbox.h41
-rw-r--r--src/gui/sell.cpp29
-rw-r--r--src/gui/sell.h13
7 files changed, 157 insertions, 36 deletions
diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp
index 20ceca92..ddbfe90a 100644
--- a/src/gui/buy.cpp
+++ b/src/gui/buy.cpp
@@ -91,6 +91,7 @@ BuyDialog::BuyDialog(Network *network):
mSlider->setEventId("slider");
mItemList->addActionListener(this);
+ mItemList->addSelectionListener(this);
mSlider->addActionListener(this);
add(mScrollArea);
@@ -153,7 +154,8 @@ void BuyDialog::action(const std::string& eventId, gcn::Widget* widget)
{
int selectedItem = mItemList->getSelected();
- if (eventId == "item") {
+ if (eventId == "item")
+ {
// Reset amount of items and update labels
mAmountItems = 0;
mSlider->setValue(0);
@@ -176,23 +178,27 @@ void BuyDialog::action(const std::string& eventId, gcn::Widget* widget)
mIncreaseButton->setEnabled(mMaxItems > 0);
mSlider->setEnabled(mMaxItems > 0);
}
- else if (eventId == "quit") {
+ else if (eventId == "quit")
+ {
setVisible(false);
current_npc = 0;
}
// The following actions require a valid selection
- if (selectedItem < 0 || selectedItem >= int(mShopItems->size())) {
+ if (selectedItem < 0 || selectedItem >= int(mShopItems->size()))
+ {
return;
}
bool updateButtonsAndLabels = false;
- if (eventId == "slider") {
+ if (eventId == "slider")
+ {
mAmountItems = (int)(mSlider->getValue() * mMaxItems);
updateButtonsAndLabels = true;
}
- else if (eventId == "+") {
+ else if (eventId == "+")
+ {
if (mAmountItems < mMaxItems) {
mAmountItems++;
} else {
@@ -202,7 +208,8 @@ void BuyDialog::action(const std::string& eventId, gcn::Widget* widget)
mSlider->setValue(double(mAmountItems)/double(mMaxItems));
updateButtonsAndLabels = true;
}
- else if (eventId == "-") {
+ else if (eventId == "-")
+ {
if (mAmountItems > 0) {
mAmountItems--;
} else {
@@ -212,11 +219,12 @@ void BuyDialog::action(const std::string& eventId, gcn::Widget* widget)
mSlider->setValue(double(mAmountItems)/double(mMaxItems));
updateButtonsAndLabels = true;
}
- // TODO Actually we'd have a bug elsewhere if this check for the number
+ // TODO: Actually we'd have a bug elsewhere if this check for the number
// of items to be bought ever fails, Bertram removed the assertions, is
// there a better way to ensure this fails in an _obivous_ way in C++?
else if (eventId == "buy" && (mAmountItems > 0 &&
- mAmountItems <= mMaxItems)) {
+ mAmountItems <= mMaxItems))
+ {
MessageOut outMsg(mNetwork);
outMsg.writeInt16(CMSG_NPC_BUY_REQUEST);
outMsg.writeInt16(8);
@@ -240,7 +248,8 @@ void BuyDialog::action(const std::string& eventId, gcn::Widget* widget)
}
// If anything has changed, we have to update the buttons and labels
- if (updateButtonsAndLabels) {
+ if (updateButtonsAndLabels)
+ {
// Update buttons
mIncreaseButton->setEnabled(mAmountItems < mMaxItems);
mDecreaseButton->setEnabled(mAmountItems > 0);
@@ -256,11 +265,10 @@ void BuyDialog::action(const std::string& eventId, gcn::Widget* widget)
}
}
-void BuyDialog::mouseClick(int x, int y, int button, int count)
+void BuyDialog::selectionChanged(const SelectionEvent &event)
{
- Window::mouseClick(x, y, button, count);
-
int selectedItem = mItemList->getSelected();
+
if (selectedItem > -1)
{
const ItemInfo &info =
@@ -269,4 +277,9 @@ void BuyDialog::mouseClick(int x, int y, int button, int count)
mItemDescLabel->setCaption("Description: " + info.getDescription());
mItemEffectLabel->setCaption("Effect: " + info.getEffect());
}
+ else
+ {
+ mItemDescLabel->setCaption("Description:");
+ mItemEffectLabel->setCaption("Effect:");
+ }
}
diff --git a/src/gui/buy.h b/src/gui/buy.h
index b09b648b..6a8d45e3 100644
--- a/src/gui/buy.h
+++ b/src/gui/buy.h
@@ -27,18 +27,20 @@
#include <guichan/actionlistener.hpp>
#include "window.h"
+#include "selectionlistener.h"
#include "../guichanfwd.h"
class Network;
class ShopItems;
+class ListBox;
/**
* The buy dialog.
*
* \ingroup Interface
*/
-class BuyDialog : public Window, public gcn::ActionListener
+class BuyDialog : public Window, public gcn::ActionListener, SelectionListener
{
public:
/**
@@ -79,9 +81,11 @@ class BuyDialog : public Window, public gcn::ActionListener
int getNumberOfElements();
/**
- * Mouse callback
+ * Updates the labels according to the selected item.
+ *
+ * @see SelectionListener::selectionChanged
*/
- void mouseClick(int x, int y, int buton, int count);
+ void selectionChanged(const SelectionEvent &event);
/**
* Returns the name of item number i in the shop inventory.
@@ -94,7 +98,7 @@ class BuyDialog : public Window, public gcn::ActionListener
gcn::Button *mQuitButton;
gcn::Button *mIncreaseButton;
gcn::Button *mDecreaseButton;
- gcn::ListBox *mItemList;
+ ListBox *mItemList;
gcn::ScrollArea *mScrollArea;
gcn::Label *mItemDescLabel;
gcn::Label *mItemEffectLabel;
diff --git a/src/gui/inventorywindow.h b/src/gui/inventorywindow.h
index a2c7535b..d46e91e7 100644
--- a/src/gui/inventorywindow.h
+++ b/src/gui/inventorywindow.h
@@ -75,9 +75,9 @@ class InventoryWindow : public Window, gcn::ActionListener, SelectionListener
void selectionChanged(const SelectionEvent &event);
private:
- void updateButtons(); /** Updates button states */
+ void updateButtons(); /**< Updates button states. */
- void updateWidgets(); /** Updates widgets size/position */
+ void updateWidgets(); /**< Updates widgets size/position. */
ItemContainer *mItems;
diff --git a/src/gui/listbox.cpp b/src/gui/listbox.cpp
index df03b81b..14626d06 100644
--- a/src/gui/listbox.cpp
+++ b/src/gui/listbox.cpp
@@ -23,12 +23,16 @@
#include "listbox.h"
+#include "selectionlistener.h"
+
#include <guichan/font.hpp>
#include <guichan/graphics.hpp>
#include <guichan/listmodel.hpp>
+#include <guichan/mouseinput.hpp>
ListBox::ListBox(gcn::ListModel *listModel):
- gcn::ListBox(listModel)
+ gcn::ListBox(listModel),
+ mMousePressed(false)
{
}
@@ -45,8 +49,8 @@ void ListBox::draw(gcn::Graphics *graphics)
// Draw rectangle below the selected list element
if (mSelected >= 0) {
- graphics->fillRectangle(
- gcn::Rectangle(0, fontHeight * mSelected, getWidth(), fontHeight));
+ graphics->fillRectangle(gcn::Rectangle(0, fontHeight * mSelected,
+ getWidth(), fontHeight));
}
// Draw the list elements
@@ -55,3 +59,50 @@ void ListBox::draw(gcn::Graphics *graphics)
graphics->drawText(mListModel->getElementAt(i), 1, y);
}
}
+
+void ListBox::setSelected(int selected)
+{
+ gcn::ListBox::setSelected(selected);
+ fireSelectionChangedEvent();
+}
+
+void ListBox::mousePress(int x, int y, int button)
+{
+ gcn::ListBox::mousePress(x, y, button);
+
+ if (button == gcn::MouseInput::LEFT && hasMouse())
+ {
+ mMousePressed = true;
+ }
+}
+
+void ListBox::mouseRelease(int x, int y, int button)
+{
+ gcn::ListBox::mouseRelease(x, y, button);
+
+ mMousePressed = false;
+}
+
+void ListBox::mouseMotion(int x, int y)
+{
+ gcn::ListBox::mouseMotion(x, y);
+
+ // Pretend mouse is pressed continuously while dragged. Causes list
+ // selection to be updated as is default in many GUIs.
+ if (mMousePressed)
+ {
+ mousePress(x, y, gcn::MouseInput::LEFT);
+ }
+}
+
+void ListBox::fireSelectionChangedEvent()
+{
+ SelectionEvent event(this);
+ SelectionListeners::iterator i_end = mListeners.end();
+ SelectionListeners::iterator i;
+
+ for (i = mListeners.begin(); i != i_end; ++i)
+ {
+ (*i)->selectionChanged(event);
+ }
+}
diff --git a/src/gui/listbox.h b/src/gui/listbox.h
index 5999f7a7..c1932f54 100644
--- a/src/gui/listbox.h
+++ b/src/gui/listbox.h
@@ -26,10 +26,12 @@
#include <guichan/widgets/listbox.hpp>
+class SelectionListener;
+
/**
* A list box, meant to be used inside a scroll area. Same as the Guichan list
* box except this one doesn't have a background, instead completely relying
- * on the scroll area.
+ * on the scroll area. It also adds selection listener functionality.
*
* \ingroup GUI
*/
@@ -45,6 +47,43 @@ class ListBox : public gcn::ListBox
* Draws the list box.
*/
void draw(gcn::Graphics *graphics);
+
+ void mousePress(int x, int y, int button);
+ void mouseRelease(int x, int y, int button);
+ void mouseMotion(int x, int y);
+
+ /**
+ * Adds a listener to the list that's notified each time a change to
+ * the selection occurs.
+ */
+ void addSelectionListener(SelectionListener *listener)
+ {
+ mListeners.push_back(listener);
+ }
+
+ /**
+ * Removes a listener from the list that's notified each time a change
+ * to the selection occurs.
+ */
+ void removeSelectionListener(SelectionListener *listener)
+ {
+ mListeners.remove(listener);
+ }
+
+ /**
+ * Sets the index of the selected element.
+ */
+ void setSelected(int selected);
+
+ private:
+ /**
+ * Sends out selection events to the list of selection listeners.
+ */
+ void fireSelectionChangedEvent();
+
+ bool mMousePressed; /**< Keeps track of mouse pressed status. */
+
+ std::list<SelectionListener*> mListeners;
};
#endif
diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp
index 44fa8e41..cc43d36c 100644
--- a/src/gui/sell.cpp
+++ b/src/gui/sell.cpp
@@ -95,6 +95,7 @@ SellDialog::SellDialog(Network *network):
mSlider->setEventId("mSlider");
mItemList->addActionListener(this);
+ mItemList->addSelectionListener(this);
mSlider->addActionListener(this);
add(scrollArea);
@@ -156,7 +157,8 @@ void SellDialog::action(const std::string& eventId, gcn::Widget* widget)
{
int selectedItem = mItemList->getSelected();
- if (eventId == "item") {
+ if (eventId == "item")
+ {
mAmountItems = 0;
mSlider->setValue(0);
mDecreaseButton->setEnabled(false);
@@ -189,19 +191,22 @@ void SellDialog::action(const std::string& eventId, gcn::Widget* widget)
bool updateButtonsAndLabels = false;
- if (eventId == "mSlider") {
+ if (eventId == "mSlider")
+ {
mAmountItems = (int)(mSlider->getValue() * mMaxItems);
updateButtonsAndLabels = true;
}
- else if (eventId == "+") {
+ else if (eventId == "+")
+ {
assert(mAmountItems < mMaxItems);
mAmountItems++;
mSlider->setValue(double(mAmountItems)/double(mMaxItems));
updateButtonsAndLabels = true;
}
- else if (eventId == "-") {
+ else if (eventId == "-")
+ {
assert(mAmountItems > 0);
mAmountItems--;
@@ -209,7 +214,8 @@ void SellDialog::action(const std::string& eventId, gcn::Widget* widget)
updateButtonsAndLabels = true;
}
- else if (eventId == "sell") {
+ else if (eventId == "sell")
+ {
// Attempt sell
assert(mAmountItems > 0 && mAmountItems <= mMaxItems);
@@ -236,7 +242,8 @@ void SellDialog::action(const std::string& eventId, gcn::Widget* widget)
}
// If anything changed, we need to update the buttons and labels
- if (updateButtonsAndLabels) {
+ if (updateButtonsAndLabels)
+ {
// Update labels
mQuantityLabel->setCaption(toString(mAmountItems));
mQuantityLabel->adjustSize();
@@ -252,11 +259,10 @@ void SellDialog::action(const std::string& eventId, gcn::Widget* widget)
}
}
-void SellDialog::mouseClick(int x, int y, int button, int count)
+void SellDialog::selectionChanged(const SelectionEvent &event)
{
- Window::mouseClick(x, y, button, count);
-
int selectedItem = mItemList->getSelected();
+
if (selectedItem > -1)
{
const ItemInfo &info =
@@ -265,4 +271,9 @@ void SellDialog::mouseClick(int x, int y, int button, int count)
mItemDescLabel->setCaption("Description: " + info.getDescription());
mItemEffectLabel->setCaption("Effect: " + info.getEffect());
}
+ else
+ {
+ mItemDescLabel->setCaption("Description");
+ mItemEffectLabel->setCaption("Effect");
+ }
}
diff --git a/src/gui/sell.h b/src/gui/sell.h
index 423fea26..12000bc3 100644
--- a/src/gui/sell.h
+++ b/src/gui/sell.h
@@ -27,20 +27,21 @@
#include <guichan/actionlistener.hpp>
#include "window.h"
+#include "selectionlistener.h"
#include "../guichanfwd.h"
class Item;
class Network;
class ShopItems;
-
+class ListBox;
/**
* The sell dialog.
*
* \ingroup Interface
*/
-class SellDialog : public Window, public gcn::ActionListener
+class SellDialog : public Window, gcn::ActionListener, SelectionListener
{
public:
/**
@@ -71,16 +72,18 @@ class SellDialog : public Window, public gcn::ActionListener
void action(const std::string& eventId, gcn::Widget* widget);
/**
- * Mouse callback
+ * Updates labels according to selected item.
+ *
+ * @see SelectionListener::selectionChanged
*/
- void mouseClick(int x, int y, int buton, int count);
+ void selectionChanged(const SelectionEvent &event);
private:
Network *mNetwork;
gcn::Button *mSellButton;
gcn::Button *mIncreaseButton;
gcn::Button *mDecreaseButton;
- gcn::ListBox *mItemList;
+ ListBox *mItemList;
gcn::Label *mMoneyLabel;
gcn::Label *mItemDescLabel;
gcn::Label *mItemEffectLabel;