diff options
Diffstat (limited to 'src/gui/itemcontainer.cpp')
-rw-r--r-- | src/gui/itemcontainer.cpp | 338 |
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; } } |