From 1cafda1147c06a647e3d3f1e3f986d7296ccbd08 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Mon, 1 Jul 2013 23:18:52 +0300 Subject: add support for drag and drop in spells window. --- src/dragdrop.h | 55 ++++++++++++++- src/gui/gui.cpp | 16 ++++- src/gui/outfitwindow.cpp | 3 +- src/gui/widgets/dropshortcutcontainer.cpp | 3 +- src/gui/widgets/spellshortcutcontainer.cpp | 110 +++++++++++++++++++---------- src/gui/widgets/spellshortcutcontainer.h | 2 + src/spellmanager.cpp | 34 +++++++++ src/spellmanager.h | 2 + 8 files changed, 180 insertions(+), 45 deletions(-) diff --git a/src/dragdrop.h b/src/dragdrop.h index d67c2623e..845420968 100644 --- a/src/dragdrop.h +++ b/src/dragdrop.h @@ -22,6 +22,7 @@ #define DRAGDROP_H #include "item.h" +#include "textcommand.h" #include "resources/image.h" @@ -51,7 +52,9 @@ class DragDrop mItemImage(item ? item->getImage() : nullptr), mSelItem(0), mSelItemColor(1), - mSource(source) + mSource(source), + mText(), + mTag() { if (mItemImage) mItemImage->incRef(); @@ -77,11 +80,14 @@ class DragDrop DragDropSource getSource() const { return mSource; } - void dragItem(Item *const item, const DragDropSource source) + void dragItem(Item *const item, + const DragDropSource source, + const int tag = 0) { if (mItemImage) mItemImage->decRef(); + mText.clear(); if (item) { mItem = item->getId(); @@ -89,14 +95,50 @@ class DragDrop mItemImage = item->getImage(); if (mItemImage) mItemImage->incRef(); + mSource = source; + mTag = tag; } else { mItem = 0; mItemColor = 1; mItemImage = nullptr; + mSource = DRAGDROP_SOURCE_EMPTY; + mTag = 0; + } + } + + void dragCommand(TextCommand *const command, + const DragDropSource source, + const int tag = 0) + { + if (mItemImage) + mItemImage->decRef(); + mItem = 0; + mItemColor = 1; + + if (command) + { + mText = command->getSymbol(); + mItemImage = command->getImage(); + if (mItemImage) + { + mItemImage->incRef(); + } + else if (mText.empty()) + { + mSource = DRAGDROP_SOURCE_EMPTY; + mTag = 0; + return; + } + } + else + { + mText.clear(); + mItemImage = nullptr; } mSource = source; + mTag = tag; } void clear() @@ -107,6 +149,7 @@ class DragDrop mItemColor = 1; mItemImage = nullptr; mSource = DRAGDROP_SOURCE_EMPTY; + mText.clear(); } bool isEmpty() const @@ -145,6 +188,12 @@ class DragDrop { } + const std::string &getText() + { return mText; } + + int getTag() + { return mTag; } + private: int mItem; uint8_t mItemColor; @@ -152,6 +201,8 @@ class DragDrop int mSelItem; uint8_t mSelItemColor; DragDropSource mSource; + std::string mText; + int mTag; }; extern DragDrop dragDrop; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index d751c6ec0..debbe342f 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -438,9 +438,19 @@ void Gui::draw() const Image *const image = dragDrop.getItemImage(); if (image) { - const int tPosX = mouseX - (image->mBounds.w / 2); - const int tPosY = mouseY - (image->mBounds.h / 2); - g2->drawImage(image, tPosX, tPosY); + const int posX = mouseX - (image->mBounds.w / 2); + const int posY = mouseY - (image->mBounds.h / 2); + g2->drawImage(image, posX, posY); + } + if (mGuiFont) + { + const std::string &str = dragDrop.getText(); + if (!str.empty()) + { + const int posX = mouseX - mGuiFont->getWidth(str) / 2; + const int posY = mouseY + (image ? image->mBounds.h / 2 : 0); + mGuiFont->drawString(g2, str, posX, posY); + } } Image *const mouseCursor = mMouseCursors->get(mCursorType); diff --git a/src/gui/outfitwindow.cpp b/src/gui/outfitwindow.cpp index 132419c91..d14abd701 100644 --- a/src/gui/outfitwindow.cpp +++ b/src/gui/outfitwindow.cpp @@ -471,7 +471,8 @@ void OutfitWindow::mouseReleased(gcn::MouseEvent &event) } mMoved = false; event.consume(); - if (!dragDrop.isEmpty()) + if (!dragDrop.isEmpty() && dragDrop.getSource() + == DRAGDROP_SOURCE_INVENTORY) { mItems[mCurrentOutfit][index] = dragDrop.getItem(); mItemColors[mCurrentOutfit][index] = dragDrop.getItemColor(); diff --git a/src/gui/widgets/dropshortcutcontainer.cpp b/src/gui/widgets/dropshortcutcontainer.cpp index ac2916c1d..8078347f7 100644 --- a/src/gui/widgets/dropshortcutcontainer.cpp +++ b/src/gui/widgets/dropshortcutcontainer.cpp @@ -252,7 +252,8 @@ void DropShortcutContainer::mouseReleased(gcn::MouseEvent &event) dragDrop.clear(); return; } - if (!dragDrop.isEmpty()) + if (!dragDrop.isEmpty() && dragDrop.getSource() + == DRAGDROP_SOURCE_INVENTORY) { dropShortcut->setItems(index, dragDrop.getItem(), dragDrop.getItemColor()); diff --git a/src/gui/widgets/spellshortcutcontainer.cpp b/src/gui/widgets/spellshortcutcontainer.cpp index ef92ba09c..df9f421b8 100644 --- a/src/gui/widgets/spellshortcutcontainer.cpp +++ b/src/gui/widgets/spellshortcutcontainer.cpp @@ -22,6 +22,13 @@ #include "gui/widgets/spellshortcutcontainer.h" +#include "client.h" +#include "dragdrop.h" +#include "itemshortcut.h" +#include "keyboardconfig.h" +#include "localplayer.h" +#include "spellshortcut.h" + #include "gui/inventorywindow.h" #include "gui/okdialog.h" #include "gui/shortcutwindow.h" @@ -29,12 +36,6 @@ #include "gui/viewport.h" #include "gui/textcommandeditor.h" -#include "client.h" -#include "spellshortcut.h" -#include "itemshortcut.h" -#include "keyboardconfig.h" -#include "localplayer.h" - #include "resources/image.h" #include "resources/resourcemanager.h" @@ -117,8 +118,7 @@ void SpellShortcutContainer::draw(gcn::Graphics *graphics) const int itemX = (i % mGridWidth) * mBoxWidth; const int itemY = (i / mGridWidth) * mBoxHeight; - const int itemId = spellShortcut->getItem( - (mNumber * SPELL_SHORTCUT_ITEMS) + i); + const int itemId = getItemByIndex(i); if (selectedId >= 0 && itemId == selectedId) { g->drawRectangle(gcn::Rectangle(itemX + 1, itemY + 1, @@ -154,23 +154,28 @@ void SpellShortcutContainer::mouseDragged(gcn::MouseEvent &event) { if (event.getButton() == gcn::MouseEvent::LEFT) { - if (!mSpellMoved && mSpellClicked) + if (dragDrop.isEmpty() && mSpellClicked) { + mSpellClicked = false; const int index = getIndexFromGrid(event.getX(), event.getY()); if (index == -1) return; - const int itemId = spellShortcut->getItem( - (mNumber * SPELL_SHORTCUT_ITEMS) + index); - + const int itemId = getItemByIndex(index); if (itemId < 0) return; - } - if (mSpellMoved) - { - mCursorPosX = event.getX(); - mCursorPosY = event.getY(); + event.consume(); + TextCommand *const spell = spellManager->getSpell(itemId); + if (spell) + { + dragDrop.dragCommand(spell, DRAGDROP_SOURCE_SPELLS, index); + } + else + { + dragDrop.clear(); + mSpellClicked = false; + } } } } @@ -185,6 +190,9 @@ void SpellShortcutContainer::mousePressed(gcn::MouseEvent &event) const unsigned int eventButton = event.getButton(); if (eventButton == gcn::MouseEvent::LEFT) { + const int itemId = getItemByIndex(index); + if (itemId > 0) + mSpellClicked = true; } else if (eventButton == gcn::MouseEvent::RIGHT) { @@ -194,8 +202,7 @@ void SpellShortcutContainer::mousePressed(gcn::MouseEvent &event) if (!spellShortcut || !spellManager) return; - const int itemId = spellShortcut->getItem( - (mNumber * SPELL_SHORTCUT_ITEMS) + index); + const int itemId = getItemByIndex(index); spellManager->invoke(itemId); } } @@ -208,43 +215,66 @@ void SpellShortcutContainer::mouseReleased(gcn::MouseEvent &event) const int index = getIndexFromGrid(event.getX(), event.getY()); if (index == -1) + { + dragDrop.clear(); return; + } - const int itemId = spellShortcut->getItem( - (mNumber * SPELL_SHORTCUT_ITEMS) + index); + const int itemId = getItemByIndex(index); const unsigned int eventButton = event.getButton(); if (eventButton == gcn::MouseEvent::LEFT) { + mSpellClicked = false; + if (itemId < 0) return; const int selectedId = spellShortcut->getSelectedItem(); + event.consume(); - if (selectedId != itemId) + if (!dragDrop.isEmpty()) { - const TextCommand *const spell = spellManager->getSpell(itemId); - if (spell && !spell->isEmpty()) + if (dragDrop.getSource() == DRAGDROP_SOURCE_SPELLS) { - const int num = itemShortcutWindow->getTabIndex(); - if (num >= 0 && num < static_cast(SHORTCUT_TABS) - && itemShortcut[num]) + const int oldIndex = dragDrop.getTag(); + const int oldItemId = getItemByIndex(oldIndex); + const int idx = mNumber * SPELL_SHORTCUT_ITEMS; + if (spellManager) { - itemShortcut[num]->setItemSelected( - spell->getId() + SPELL_MIN_ID); + spellManager->swap(idx + index, idx + oldIndex); + spellManager->save(); } - spellShortcut->setItemSelected(spell->getId()); } } else { - const int num = itemShortcutWindow->getTabIndex(); - if (num >= 0 && num < static_cast(SHORTCUT_TABS) - && itemShortcut[num]) + if (selectedId != itemId) { - itemShortcut[num]->setItemSelected(-1); + const TextCommand *const + spell = spellManager->getSpell(itemId); + if (spell && !spell->isEmpty()) + { + const int num = itemShortcutWindow->getTabIndex(); + if (num >= 0 && num < static_cast(SHORTCUT_TABS) + && itemShortcut[num]) + { + itemShortcut[num]->setItemSelected( + spell->getId() + SPELL_MIN_ID); + } + spellShortcut->setItemSelected(spell->getId()); + } + } + else + { + const int num = itemShortcutWindow->getTabIndex(); + if (num >= 0 && num < static_cast(SHORTCUT_TABS) + && itemShortcut[num]) + { + itemShortcut[num]->setItemSelected(-1); + } + spellShortcut->setItemSelected(-1); } - spellShortcut->setItemSelected(-1); } } else if (eventButton == gcn::MouseEvent::RIGHT) @@ -269,9 +299,7 @@ void SpellShortcutContainer::mouseMoved(gcn::MouseEvent &event) if (index == -1) return; - const int itemId = spellShortcut->getItem( - (mNumber * SPELL_SHORTCUT_ITEMS) + index); - + const int itemId = getItemByIndex(index); mSpellPopup->setVisible(false); const TextCommand *const spell = spellManager->getSpell(itemId); if (spell && !spell->isEmpty()) @@ -296,3 +324,9 @@ void SpellShortcutContainer::widgetHidden(const gcn::Event &event A_UNUSED) if (mSpellPopup) mSpellPopup->setVisible(false); } + +int SpellShortcutContainer::getItemByIndex(const int index) +{ + return spellShortcut->getItem( + (mNumber * SPELL_SHORTCUT_ITEMS) + index); +} diff --git a/src/gui/widgets/spellshortcutcontainer.h b/src/gui/widgets/spellshortcutcontainer.h index c880a2d0c..509b96c61 100644 --- a/src/gui/widgets/spellshortcutcontainer.h +++ b/src/gui/widgets/spellshortcutcontainer.h @@ -79,6 +79,8 @@ class SpellShortcutContainer final : public ShortcutContainer void setWidget2(const Widget2 *const widget) override; + int getItemByIndex(const int index); + private: TextCommand *mSpellMoved; SpellPopup *mSpellPopup; diff --git a/src/spellmanager.cpp b/src/spellmanager.cpp index bad5cd78b..83fb746a7 100644 --- a/src/spellmanager.cpp +++ b/src/spellmanager.cpp @@ -393,3 +393,37 @@ std::string SpellManager::autoComplete(const std::string &partName) const } return newName; } + +void SpellManager::swap(const int id1, const int id2) +{ + TextCommand *const spell1 = mSpells[id1]; + TextCommand *const spell2 = mSpells[id2]; + // swap in map + mSpells[id1] = spell2; + mSpells[id2] = spell1; + + // swap id + int tmp = spell1->getId(); + spell1->setId(spell2->getId()); + spell2->setId(tmp); + + // swap in vector + const int sz = SPELL_SHORTCUT_ITEMS * SPELL_SHORTCUT_TABS; + for (unsigned f = 0; f < sz; f++) + { + const TextCommand *const spellA = mSpellsVector[f]; + if (spellA == spell1) + { + for (unsigned d = 0; d < sz; d++) + { + const TextCommand *const spellB = mSpellsVector[d]; + if (spellB == spell2) + { + mSpellsVector[f] = spell2; + mSpellsVector[d] = spell1; + return; + } + } + } + } +} diff --git a/src/spellmanager.h b/src/spellmanager.h index 25e127e8a..d2320e8a1 100644 --- a/src/spellmanager.h +++ b/src/spellmanager.h @@ -63,6 +63,8 @@ class SpellManager final std::string autoComplete(const std::string &partName) const A_WARN_UNUSED; + void swap(const int id1, const int id2); + private: void fillSpells(); -- cgit v1.2.3-70-g09d2