Skip to content

Commit

Permalink
[MouseItemWidget] Now supports drag-click.
Browse files Browse the repository at this point in the history
  • Loading branch information
Unarelith committed Mar 1, 2020
1 parent 908bb10 commit 0c71255
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 53 deletions.
3 changes: 2 additions & 1 deletion client/source/gui/AbstractInventoryWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ class AbstractInventoryWidget : public Widget {

const std::vector<std::string> &shiftDestination() const { return m_shiftDestination; }
void setShiftDestination(const std::string &shiftDestination);
void setShiftDestination(const std::vector<std::string> &shiftDestination) { m_shiftDestination = shiftDestination; }

private:
protected:
std::vector<std::string> m_shiftDestination;
};

Expand Down
16 changes: 8 additions & 8 deletions client/source/gui/CraftingWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,14 @@ void CraftingWidget::init(unsigned int offset, unsigned int size) {

m_craftingInventoryWidget.setParent(this);
m_craftingResultInventoryWidget.setParent(this);

m_craftingInventoryWidget.setShiftDestination(m_shiftDestination);
m_craftingResultInventoryWidget.setShiftDestination(m_shiftDestination);
}

void CraftingWidget::onMouseEvent(const SDL_Event &event, MouseItemWidget &mouseItemWidget) {
m_craftingInventoryWidget.onMouseEvent(event, mouseItemWidget);
m_craftingResultInventoryWidget.onMouseEvent(event, mouseItemWidget, true);
void CraftingWidget::onEvent(const SDL_Event &event) {
m_craftingInventoryWidget.onEvent(event);
m_craftingResultInventoryWidget.onEvent(event);

m_currentInventoryWidget = m_craftingResultInventoryWidget.currentItemWidget()
? &m_craftingResultInventoryWidget : &m_craftingInventoryWidget;
Expand Down Expand Up @@ -81,11 +84,8 @@ void CraftingWidget::update() {
}

bool CraftingWidget::sendItemStackToDest(const ItemWidget *itemStack, AbstractInventoryWidget *dest) {
if (m_currentInventoryWidget && dest->receiveItemStack(itemStack)) {
m_currentInventoryWidget->inventory()->clearStack(itemStack->x(), itemStack->y());
m_currentInventoryWidget->update();
m_currentInventoryWidget->sendUpdatePacket();
return true;
if (m_currentInventoryWidget) {
return m_currentInventoryWidget->sendItemStackToDest(itemStack, dest);
}

return false;
Expand Down
7 changes: 4 additions & 3 deletions client/source/gui/CraftingWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,15 @@ class CraftingWidget : public AbstractInventoryWidget {

void init(unsigned int offset = 0, unsigned int size = 3);

void onMouseEvent(const SDL_Event &event, MouseItemWidget &mouseItemWidget);
void onEvent(const SDL_Event &event) override;

void update() override;

bool sendItemStackToDest(const ItemWidget *itemStack, AbstractInventoryWidget *dest) override;
bool receiveItemStack(const ItemWidget *itemStack) override;

const ItemWidget *currentItemWidget() const { return m_craftingResultInventoryWidget.currentItemWidget() ? m_craftingResultInventoryWidget.currentItemWidget() : m_craftingInventoryWidget.currentItemWidget(); }
ItemWidget *currentItemWidget() const { return m_craftingResultInventoryWidget.currentItemWidget() ? m_craftingResultInventoryWidget.currentItemWidget() : m_craftingInventoryWidget.currentItemWidget(); }
InventoryWidget *currentInventoryWidget() const { return m_currentInventoryWidget; }

InventoryWidget &craftingInventoryWidget() { return m_craftingInventoryWidget; }
InventoryWidget &craftingResultInventoryWidget() { return m_craftingResultInventoryWidget; }
Expand All @@ -60,7 +61,7 @@ class CraftingWidget : public AbstractInventoryWidget {
InventoryWidget m_craftingInventoryWidget{m_client};

Inventory m_craftingResultInventory{1, 1};
InventoryWidget m_craftingResultInventoryWidget{m_client};
InventoryWidget m_craftingResultInventoryWidget{m_client, true};

const Recipe *m_recipe = nullptr;
};
Expand Down
39 changes: 17 additions & 22 deletions client/source/gui/InventoryWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void InventoryWidget::init(Inventory &inventory, u16 offset, u16 size) {
m_inventoryHeight = inventory.height();
}

void InventoryWidget::onMouseEvent(const SDL_Event &event, MouseItemWidget &mouseItemWidget, bool isReadOnly) {
void InventoryWidget::onEvent(const SDL_Event &event) {
if (event.type == SDL_MOUSEMOTION) {
m_currentItemWidget = nullptr;
for (std::size_t i = 0 ; i < m_itemWidgets.size() ; ++i) {
Expand All @@ -61,34 +61,24 @@ void InventoryWidget::onMouseEvent(const SDL_Event &event, MouseItemWidget &mous
}
}
}
else if (event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT && m_currentItemWidget) {
if (m_inventory && !m_inventory->isUnlimited())
mouseItemWidget.swapItems(*m_currentItemWidget, isReadOnly);
else if (m_inventory && mouseItemWidget.getStack().amount() == 0 && m_currentItemWidget->stack().amount() != 0)
mouseItemWidget.setStack(m_currentItemWidget->stack().item().stringID(), 64);

sendUpdatePacket();
}
else if (event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_RIGHT && m_currentItemWidget) {
if (!isReadOnly) {
if (m_inventory && !m_inventory->isUnlimited())
mouseItemWidget.putItem(*m_currentItemWidget);
else if (m_inventory && mouseItemWidget.getStack().amount() == 0 && m_currentItemWidget->stack().amount() != 0)
mouseItemWidget.setStack(m_currentItemWidget->stack().item().stringID(), 1);

sendUpdatePacket();
}
}
}

void InventoryWidget::update() {
for (auto &it : m_itemWidgets)
bool hasChanged = false;

for (auto &it : m_itemWidgets) {
it.update();

hasChanged = hasChanged || it.hasChanged();
it.setChanged(false);
}

if (hasChanged)
sendUpdatePacket();
}

bool InventoryWidget::sendItemStackToDest(const ItemWidget *itemStack, AbstractInventoryWidget *dest) {
if (dest->receiveItemStack(itemStack)) {
m_inventory->clearStack(itemStack->x(), itemStack->y());
update();
sendUpdatePacket();
return true;
Expand All @@ -98,10 +88,15 @@ bool InventoryWidget::sendItemStackToDest(const ItemWidget *itemStack, AbstractI
}

bool InventoryWidget::receiveItemStack(const ItemWidget *itemStack) {
bool stackAdded = m_inventory->addStack(itemStack->stack().item().stringID(), itemStack->stack().amount(), m_offset, m_size);
ItemStack stack = itemStack->stack();
m_inventory->clearStack(itemStack->x(), itemStack->y());

bool stackAdded = m_inventory->addStack(stack.item().stringID(), stack.amount(), m_offset, m_size);

if (stackAdded)
sendUpdatePacket();
else
m_inventory->setStack(itemStack->x(), itemStack->y(), stack.item().stringID(), stack.amount());

return stackAdded;
}
Expand Down
14 changes: 9 additions & 5 deletions client/source/gui/InventoryWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ class ClientCommandHandler;

class InventoryWidget : public AbstractInventoryWidget {
public:
InventoryWidget(ClientCommandHandler &client, Widget *parent = nullptr)
: AbstractInventoryWidget(parent), m_client(client) {}
InventoryWidget(ClientCommandHandler &client, bool isReadOnly = false, Widget *parent = nullptr)
: AbstractInventoryWidget(parent), m_client(client), m_isReadOnly(isReadOnly) {}

void init(Inventory &inventory, u16 offset = 0, u16 size = 0);

void onMouseEvent(const SDL_Event &event, MouseItemWidget &mouseItemWidget, bool isReadOnly = false);
void onEvent(const SDL_Event &event) override;

void update() override;

Expand All @@ -50,9 +50,11 @@ class InventoryWidget : public AbstractInventoryWidget {

void sendUpdatePacket();

Inventory *inventory() { return m_inventory; }
Inventory *inventory() const { return m_inventory; }

const ItemWidget *currentItemWidget() const { return m_currentItemWidget; }
bool isReadOnly() const { return m_isReadOnly; }

ItemWidget *currentItemWidget() const { return m_currentItemWidget; }

private:
void draw(gk::RenderTarget &target, gk::RenderStates states) const override;
Expand All @@ -67,6 +69,8 @@ class InventoryWidget : public AbstractInventoryWidget {
u16 m_offset = 0;
u16 m_size = 0;

bool m_isReadOnly = false;

std::vector<ItemWidget> m_itemWidgets;
ItemWidget *m_currentItemWidget = nullptr;

Expand Down
5 changes: 5 additions & 0 deletions client/source/gui/ItemWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ class ItemWidget : public Widget {
unsigned int x() const { return m_x; }
unsigned int y() const { return m_y; }

bool hasChanged() const { return m_hasChanged; }
void setChanged(bool hasChanged) { m_hasChanged = hasChanged; }

protected:
void draw(gk::RenderTarget &target, gk::RenderStates states) const override;

Expand All @@ -64,6 +67,8 @@ class ItemWidget : public Widget {
InventoryCube m_cube{10};

bool m_isImage = false;

bool m_hasChanged = false;
};

#endif // ITEMWIDGET_HPP_
96 changes: 93 additions & 3 deletions client/source/gui/MouseItemWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
*
* =====================================================================================
*/
#include "InventoryWidget.hpp"
#include "MouseItemWidget.hpp"

MouseItemWidget::MouseItemWidget(Widget *parent) : ItemWidget(m_inventory, 0, 0, parent) {
Expand All @@ -39,15 +40,103 @@ MouseItemWidget::MouseItemWidget(Widget *parent) : ItemWidget(m_inventory, 0, 0,
void MouseItemWidget::onEvent(const SDL_Event &event) {
if (event.type == SDL_MOUSEMOTION) {
updatePosition(event.motion.x, event.motion.y);
}

if (m_isDragging) {
for (auto &it : m_draggedSlots) {
u16 splitAmount;
if (m_isLeftClickDrag)
splitAmount = m_draggedStack.amount() / m_draggedSlots.size();
else
splitAmount = 1;

it.first->setStack(m_draggedStack.item().stringID(), it.second.amount() + splitAmount);
it.first->update();
}

if (m_isLeftClickDrag)
setStack(m_draggedStack.item().stringID(), m_draggedStack.amount() % m_draggedSlots.size());
else
setStack(m_draggedStack.item().stringID(), m_draggedStack.amount() - m_draggedSlots.size());
}
}
else if (event.type == SDL_MOUSEBUTTONDOWN) {
updatePosition(event.button.x, event.button.y);

if (getStack().amount() == 0) {
if (event.button.button == SDL_BUTTON_LEFT) {
leftClickBehaviour();
}
else if (event.button.button == SDL_BUTTON_RIGHT) {
rightClickBehaviour();
}

m_isDragging = false;
}
else {
m_isDragging = true;
m_isLeftClickDrag = event.button.button == SDL_BUTTON_LEFT;
m_draggedStack = getStack();

if (m_currentItemWidget && (m_currentItemWidget->stack().amount() == 0 || m_currentItemWidget->stack().item().stringID() == m_draggedStack.item().stringID()))
m_draggedSlots[m_currentItemWidget] = m_currentItemWidget->stack();
}
}
else if (event.type == SDL_MOUSEBUTTONUP) {
updatePosition(event.button.x, event.button.y);

if (m_isDragging && m_draggedSlots.size() == 1) {
if (event.button.button == SDL_BUTTON_LEFT) {
leftClickBehaviour();
}
else if (event.button.button == SDL_BUTTON_RIGHT) {
rightClickBehaviour();
}
}

m_isDragging = false;

for (auto &it : m_draggedSlots)
it.first->setChanged(true);

m_draggedSlots.clear();
}
}

void MouseItemWidget::updateCurrentItem(const ItemWidget *currentItemWidget) {
void MouseItemWidget::leftClickBehaviour() {
if (m_currentInventoryWidget && m_currentInventoryWidget->currentItemWidget() && m_currentInventoryWidget->inventory()) {
ItemWidget *currentItemWidget = m_currentInventoryWidget->currentItemWidget();
if (!m_currentInventoryWidget->inventory()->isUnlimited())
swapItems(*currentItemWidget, m_currentInventoryWidget->isReadOnly());
else if (getStack().amount() == 0 && currentItemWidget->stack().amount() != 0)
setStack(currentItemWidget->stack().item().stringID(), 64);

m_currentInventoryWidget->sendUpdatePacket();
}
}

void MouseItemWidget::rightClickBehaviour() {
if (m_currentInventoryWidget && m_currentInventoryWidget->currentItemWidget() && m_currentInventoryWidget->inventory()) {
if (!m_currentInventoryWidget->isReadOnly()) {
ItemWidget *currentItemWidget = m_currentInventoryWidget->currentItemWidget();
if (!m_currentInventoryWidget->inventory()->isUnlimited())
putItem(*currentItemWidget);
else if (getStack().amount() == 0 && currentItemWidget->stack().amount() != 0)
setStack(currentItemWidget->stack().item().stringID(), 1);

m_currentInventoryWidget->sendUpdatePacket();
}
}
}

void MouseItemWidget::updateCurrentItem(ItemWidget *currentItemWidget) {
if (currentItemWidget) {
if (m_isDragging && (currentItemWidget->stack().amount() == 0 || currentItemWidget->stack().item().stringID() == m_draggedStack.item().stringID())) {
auto it = m_draggedSlots.find(currentItemWidget);
if (it == m_draggedSlots.end()) {
m_draggedSlots.emplace(std::make_pair(currentItemWidget, currentItemWidget->stack()));
}
}

m_currentItemWidget = (currentItemWidget->stack().item().id()) ? currentItemWidget : nullptr;
m_tooltipText.setText(currentItemWidget->stack().item().label() + " [" + std::to_string(currentItemWidget->stack().item().id()) + "]");

Expand Down Expand Up @@ -101,7 +190,8 @@ void MouseItemWidget::putItem(ItemWidget &widget) {
}

void MouseItemWidget::draw(gk::RenderTarget &target, gk::RenderStates states) const {
ItemWidget::draw(target, states);
if (getStack().amount() > 0)
ItemWidget::draw(target, states);

states.transform *= getTransform();

Expand Down
17 changes: 15 additions & 2 deletions client/source/gui/MouseItemWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,25 @@
#include "ItemWidget.hpp"
#include "Text.hpp"

class InventoryWidget;

class MouseItemWidget : public ItemWidget {
public:
MouseItemWidget(Widget *parent);

void onEvent(const SDL_Event &event) override;

void leftClickBehaviour();
void rightClickBehaviour();

const ItemWidget *currentItemWidget() const { return m_currentItemWidget; }
void updateCurrentItem(const ItemWidget *currentItemWidget);
void updateCurrentItem(ItemWidget *currentItemWidget);

void swapItems(ItemWidget &widget, bool isReadOnly = false);
void putItem(ItemWidget &widget);

void setCurrentInventoryWidget(InventoryWidget *inventoryWidget) { m_currentInventoryWidget = inventoryWidget; }

const ItemStack &getStack() const { return m_inventory.getStack(0, 0); }

private:
Expand All @@ -53,11 +60,17 @@ class MouseItemWidget : public ItemWidget {

Inventory m_inventory{1, 1};

const ItemWidget *m_currentItemWidget = nullptr;
ItemWidget *m_currentItemWidget = nullptr;
InventoryWidget *m_currentInventoryWidget = nullptr;

gk::Sprite m_tooltipBackground{"texture-toasts", 160, 32};
Text m_tooltipText;
Text m_tooltipInfoText;

bool m_isDragging = false;
bool m_isLeftClickDrag = false;
std::unordered_map<ItemWidget *, ItemStack> m_draggedSlots;
ItemStack m_draggedStack;
};

#endif // MOUSEITEMWIDGET_HPP_
Loading

0 comments on commit 0c71255

Please sign in to comment.