summaryrefslogtreecommitdiff
path: root/src/gui/itemcontainer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/itemcontainer.cpp')
-rw-r--r--src/gui/itemcontainer.cpp338
1 files changed, 247 insertions, 91 deletions
diff --git a/src/gui/itemcontainer.cpp b/src/gui/itemcontainer.cpp
index 444be2a2..2f65d157 100644
--- a/src/gui/itemcontainer.cpp
+++ b/src/gui/itemcontainer.cpp
@@ -30,7 +30,7 @@
#include "../graphics.h"
#include "../inventory.h"
#include "../item.h"
-#include "../log.h"
+#include "../localplayer.h"
#include "../resources/image.h"
#include "../resources/iteminfo.h"
@@ -38,18 +38,30 @@
#include "../utils/tostring.h"
-ItemContainer::ItemContainer(Inventory *inventory):
+static const int BOX_WIDTH = 36;
+static const int BOX_HEIGHT = 44;
+
+ItemContainer::ItemContainer(Inventory *inventory,
+ int gridColumns = 1, int gridRows = 1):
mInventory(inventory),
- mSelectedItem(NULL)
+ mGridColumns(gridColumns),
+ mGridRows(gridRows),
+ mSelectedItem(NULL),
+ mHighlightedItem(NULL),
+ mDragged(false),
+ mSwapItems(false)
{
+ setFocusable(true);
+
ResourceManager *resman = ResourceManager::getInstance();
mSelImg = resman->getImage("graphics/gui/selection.png");
- if (!mSelImg) logger->error("Unable to load selection.png");
-
- mMaxItems = mInventory->getLastUsedSlot() + 1;
+ addKeyListener(this);
addMouseListener(this);
+
+ setSize((BOX_WIDTH - 1) * mGridColumns + 1,
+ (BOX_HEIGHT - 1) * mGridRows + 1);
}
ItemContainer::~ItemContainer()
@@ -58,140 +70,284 @@ ItemContainer::~ItemContainer()
}
void
-ItemContainer::logic()
+ItemContainer::draw(gcn::Graphics *graphics)
{
- gcn::Widget::logic();
-
- int i = mInventory->getLastUsedSlot() + 1;
+ Graphics *g = static_cast<Graphics*>(graphics);
- if (i != mMaxItems)
+ for (int i = 0; i < mGridColumns; i++)
{
- mMaxItems = i;
- setWidth(getWidth());
+ for (int j = 0; j < mGridRows; j++)
+ {
+ // Items positions made to overlap on another.
+ int itemX = i * (BOX_WIDTH - 1);
+ int itemY = j * (BOX_HEIGHT - 1);
+
+ // Set color to black.
+ g->setColor(gcn::Color(0, 0, 0));
+ // Draw box border.
+ g->drawRectangle(
+ gcn::Rectangle(itemX, itemY, BOX_WIDTH, BOX_HEIGHT));
+
+ Item *item = mInventory->getItem((j * mGridColumns) + i);
+
+ if (!item)
+ return;
+ Image *image = item->getInfo().getImage();
+ if (image)
+ {
+ if (item == mSelectedItem)
+ {
+ if (mDragged) {
+ // Reposition the coords to that of the cursor.
+ itemX = mDragPosX - (BOX_WIDTH / 2);
+ itemY = mDragPosY - (BOX_HEIGHT / 2);
+ }
+ else {
+ // Draw selected image.
+ g->drawImage(mSelImg, itemX, itemY);
+ }
+ }
+ g->drawImage(image, itemX, itemY);
+ }
+ if (item->getQuantity() > 1) {
+ // Draw item caption
+ g->drawText(
+ toString(item->getQuantity()),
+ itemX + BOX_WIDTH / 2,
+ itemY + BOX_HEIGHT - 14,
+ gcn::Graphics::CENTER);
+ }
+
+ }
+ }
+
+ if (isFocused() && mHighlightedItem) {
+ // Items positions made to overlap on another.
+ const int i = mHighlightedItem->getInvIndex();
+ const int itemX = (i % mGridColumns) * (BOX_WIDTH - 1);
+ const int itemY = (i / mGridColumns) * (BOX_HEIGHT - 1);
+ // Set color to orange.
+ g->setColor(gcn::Color(255, 128, 0));
+ // Draw box border.
+ g->drawRectangle(gcn::Rectangle(itemX, itemY, BOX_WIDTH, BOX_HEIGHT));
}
}
void
-ItemContainer::draw(gcn::Graphics *graphics)
+ItemContainer::selectNone()
{
- int gridWidth = 36; //(item icon width + 4)
- int gridHeight = 42; //(item icon height + 10)
- int columns = getWidth() / gridWidth;
+ setSelectedItem(NULL);
+}
- // Have at least 1 column
- if (columns < 1)
- {
- columns = 1;
+void
+ItemContainer::setSelectedItem(Item *item)
+{
+ if (mSelectedItem != item) {
+ mSelectedItem = item;
+ fireSelectionChangedEvent();
}
+}
- // Reset selected item when quantity not above 0 (should probably be made
- // sure somewhere else)
- if (mSelectedItem && mSelectedItem->getQuantity() <= 0)
+void
+ItemContainer::fireSelectionChangedEvent()
+{
+ SelectionEvent event(this);
+ SelectionListeners::iterator i_end = mListeners.end();
+ SelectionListeners::iterator i;
+
+ for (i = mListeners.begin(); i != i_end; ++i) {
+ (*i)->selectionChanged(event);
+ }
+}
+
+void
+ItemContainer::keyPressed(gcn::KeyEvent &event)
+{
+ switch (event.getKey().getValue())
{
- selectNone();
+ case gcn::Key::LEFT:
+ moveHighlight(ItemContainer::MOVE_SELECTED_LEFT);
+ break;
+ case gcn::Key::RIGHT:
+ moveHighlight(ItemContainer::MOVE_SELECTED_RIGHT);
+ break;
+ case gcn::Key::UP:
+ moveHighlight(ItemContainer::MOVE_SELECTED_UP);
+ break;
+ case gcn::Key::DOWN:
+ moveHighlight(ItemContainer::MOVE_SELECTED_DOWN);
+ break;
+ case gcn::Key::SPACE:
+ keyAction();
+ break;
+ case gcn::Key::LEFT_ALT:
+ case gcn::Key::RIGHT_ALT:
+ mSwapItems = true;
}
+}
- for (int i = 0; i < INVENTORY_SIZE; i++)
+void
+ItemContainer::keyReleased(gcn::KeyEvent &event)
+{
+ switch (event.getKey().getValue())
{
- Item *item = mInventory->getItem(i);
+ case gcn::Key::LEFT_ALT:
+ case gcn::Key::RIGHT_ALT:
+ mSwapItems = false;
+ }
+}
- if (item->getQuantity() <= 0) {
- continue;
+void
+ItemContainer::mousePressed(gcn::MouseEvent &event)
+{
+
+ const int button = event.getButton();
+ if (button == gcn::MouseEvent::LEFT || button == gcn::MouseEvent::RIGHT)
+ {
+ const int index = getSlotIndex(event.getX(), event.getY());
+ if (index == Inventory::NO_SLOT_INDEX) {
+ return;
}
- int itemX = (i % columns) * gridWidth;
- int itemY = (i / columns) * gridHeight;
+ Item *item = mInventory->getItem(index);
- // Draw selection image below selected item
- if (mSelectedItem == item)
- {
- static_cast<Graphics*>(graphics)->drawImage(mSelImg, itemX, itemY);
+ if (mSelectedItem && mSelectedItem == item) {
+ setSelectedItem(NULL);
}
-
- // Draw item icon
- if (Image *image = item->getInfo().getImage())
- {
- static_cast<Graphics*>(graphics)->drawImage(image, itemX, itemY);
+ else if (item->getId()) {
+ setSelectedItem(item);
+ }
+ else {
+ setSelectedItem(NULL);
}
-
- // Draw item caption
- graphics->drawText(
- toString(item->getQuantity()),
- itemX + gridWidth / 2,
- itemY + gridHeight - 11,
- gcn::Graphics::CENTER);
}
}
void
-ItemContainer::setWidth(int width)
+ItemContainer::mouseDragged(gcn::MouseEvent &event)
{
- gcn::Widget::setWidth(width);
-
- int gridWidth = 36; //item icon width + 4
- int gridHeight = 46; //item icon height + 14
- int columns = getWidth() / gridWidth;
-
- if (columns < 1)
+ if (mSelectedItem)
{
- columns = 1;
+ if (!mDragged) {
+ mDragged = true;
+ }
+ mDragPosX = event.getX();
+ mDragPosY = event.getY();
}
-
- setHeight((mMaxItems + columns - 1) / columns * gridHeight);
-}
-
-Item*
-ItemContainer::getItem()
-{
- return mSelectedItem;
}
void
-ItemContainer::selectNone()
+ItemContainer::mouseReleased(gcn::MouseEvent &event)
{
- setSelectedItem(NULL);
+ if (mDragged)
+ {
+ mDragged = false;
+
+ const int index = getSlotIndex(event.getX(), event.getY());
+ if (index == Inventory::NO_SLOT_INDEX) {
+ return;
+ }
+
+ if (mSelectedItem) {
+ player_node->moveInvItem(mSelectedItem, index);
+ setSelectedItem(NULL);
+ }
+ }
}
-void
-ItemContainer::setSelectedItem(Item *item)
+int
+ItemContainer::getSlotIndex(const int posX, const int posY) const
{
- if (mSelectedItem != item)
+ if(gcn::Rectangle(0, 0, (getWidth() - 1), (getHeight() - 1))
+ .isPointInRect(posX, posY))
{
- mSelectedItem = item;
- fireSelectionChangedEvent();
+ // Takes into account, boxes are overlapping each other.
+ return (posY / (BOX_HEIGHT - 1)) * mGridColumns +
+ (posX / (BOX_WIDTH - 1));
}
+ return Inventory::NO_SLOT_INDEX;
}
void
-ItemContainer::fireSelectionChangedEvent()
+ItemContainer::keyAction()
{
- SelectionEvent event(this);
- SelectionListeners::iterator i_end = mListeners.end();
- SelectionListeners::iterator i;
+ // If there is no highlight then return.
+ if (!mHighlightedItem)
+ return;
- for (i = mListeners.begin(); i != i_end; ++i)
+ // If the highlight is on the selected item, then deselect it.
+ if (mHighlightedItem == mSelectedItem)
{
- (*i)->selectionChanged(event);
+ setSelectedItem(NULL);
+ }
+ // Check and swap items if necessary.
+ else if (mSwapItems &&
+ mSelectedItem &&
+ mHighlightedItem->getId())
+ {
+ player_node->moveInvItem(
+ mSelectedItem, mHighlightedItem->getInvIndex());
+ setSelectedItem(mHighlightedItem);
+ }
+ // If the highlight is on an item the select it.
+ else if (mHighlightedItem->getId())
+ {
+ setSelectedItem(mHighlightedItem);
+ }
+ // If the highlight is on a blank space then move it.
+ else if (mSelectedItem)
+ {
+ player_node->moveInvItem(
+ mSelectedItem, mHighlightedItem->getInvIndex());
+ setSelectedItem(NULL);
}
}
void
-ItemContainer::mousePressed(gcn::MouseEvent &event)
+ItemContainer::moveHighlight(int direction)
{
- int button = event.getButton();
-
- if (button == gcn::MouseEvent::LEFT || button == gcn::MouseEvent::RIGHT)
+ if (!mHighlightedItem)
{
- int gridWidth = 36; //(item icon width + 4)
- int gridHeight = 42; //(item icon height + 10)
- int columns = getWidth() / gridWidth;
- int mx = event.getX();
- int my = event.getY();
- int index = mx / gridWidth + ((my / gridHeight) * columns);
-
- if (index > INVENTORY_SIZE)
- index = INVENTORY_SIZE - 1;
+ if (mSelectedItem) {
+ mHighlightedItem = mSelectedItem;
+ }
+ else {
+ mHighlightedItem = mInventory->getItem(0);
+ }
+ return;
+ }
- setSelectedItem(mInventory->getItem(index));
+ switch (direction)
+ {
+ case MOVE_SELECTED_LEFT:
+ if (mHighlightedItem->getInvIndex() % mGridColumns == 0)
+ {
+ mHighlightedItem += mGridColumns;
+ }
+ mHighlightedItem--;
+ break;
+ case MOVE_SELECTED_RIGHT:
+ if ((mHighlightedItem->getInvIndex() % mGridColumns) ==
+ (mGridColumns - 1))
+ {
+ mHighlightedItem -= mGridColumns;
+ }
+ mHighlightedItem++;
+ break;
+ case MOVE_SELECTED_UP:
+ if (mHighlightedItem->getInvIndex() / mGridColumns == 0)
+ {
+ mHighlightedItem += (mGridColumns * mGridRows);
+ }
+ mHighlightedItem -= mGridColumns;
+ break;
+ case MOVE_SELECTED_DOWN:
+ if ((mHighlightedItem->getInvIndex() / mGridColumns) ==
+ (mGridRows - 1))
+ {
+ mHighlightedItem -= (mGridColumns * mGridRows);
+ }
+ mHighlightedItem += mGridColumns;
+ break;
}
}