1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

Merge pull request #4384 from Laserlicht/shortcut

add shortcut for list item ordering
This commit is contained in:
Ivan Savenko 2024-08-14 17:04:45 +03:00 committed by GitHub
commit 89dca5061d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 147 additions and 10 deletions

View File

@ -18,10 +18,12 @@
#include "../widgets/ObjectLists.h"
#include "../widgets/RadialMenu.h"
#include "../windows/InfoWindows.h"
#include "../windows/CCastleInterface.h"
#include "../CGameInfo.h"
#include "../CPlayerInterface.h"
#include "../PlayerLocalState.h"
#include "../gui/CGuiHandler.h"
#include "../gui/Shortcut.h"
#include "../gui/WindowHandler.h"
#include "../render/Canvas.h"
#include "../render/Colors.h"
@ -32,6 +34,8 @@
#include "../../lib/mapObjects/CGHeroInstance.h"
#include "../../lib/mapObjects/CGTownInstance.h"
#include "../../CCallback.h"
CList::CListItem::CListItem(CList * Parent)
: CIntObject(LCLICK | SHOW_POPUP | HOVER),
parent(Parent),
@ -229,7 +233,7 @@ CHeroList::CHeroItem::CHeroItem(CHeroList *parent, const CGHeroInstance * Hero)
update();
addUsedEvents(GESTURE);
addUsedEvents(GESTURE | KEYBOARD);
}
void CHeroList::CHeroItem::update()
@ -300,6 +304,55 @@ void CHeroList::CHeroItem::gesture(bool on, const Point & initialPosition, const
GH.windows().createAndPushWindow<RadialMenu>(pos.center(), menuElements, true);
}
void CHeroList::CHeroItem::keyPressed(EShortcut key)
{
if(!hero)
return;
if(parent->selected != this->shared_from_this())
return;
auto & heroes = LOCPLINT->localState->getWanderingHeroes();
if(key == EShortcut::LIST_HERO_DISMISS)
{
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[22], [=](){ LOCPLINT->cb->dismissHero(hero); }, nullptr);
return;
}
if(heroes.size() < 2)
return;
size_t heroPos = vstd::find_pos(heroes, hero);
const CGHeroInstance * heroUpper = (heroPos < 1) ? nullptr : heroes.at(heroPos - 1);
const CGHeroInstance * heroLower = (heroPos > heroes.size() - 2) ? nullptr : heroes.at(heroPos + 1);
switch(key)
{
case EShortcut::LIST_HERO_UP:
if(heroUpper)
LOCPLINT->localState->swapWanderingHero(heroPos, heroPos - 1);
break;
case EShortcut::LIST_HERO_DOWN:
if(heroLower)
LOCPLINT->localState->swapWanderingHero(heroPos, heroPos + 1);
break;
case EShortcut::LIST_HERO_TOP:
if(heroUpper)
for (size_t i = heroPos; i > 0; i--)
LOCPLINT->localState->swapWanderingHero(i, i - 1);
break;
case EShortcut::LIST_HERO_BOTTOM:
if(heroLower)
for (int i = heroPos; i < heroes.size() - 1; i++)
LOCPLINT->localState->swapWanderingHero(i, i + 1);
break;
}
}
std::shared_ptr<CIntObject> CHeroList::createItem(size_t index)
{
if (LOCPLINT->localState->getWanderingHeroes().size() > index)
@ -369,7 +422,7 @@ CTownList::CTownItem::CTownItem(CTownList *parent, const CGTownInstance *Town):
pos = picture->pos;
update();
addUsedEvents(GESTURE);
addUsedEvents(GESTURE | KEYBOARD);
}
std::shared_ptr<CIntObject> CTownList::CTownItem::genSelection()
@ -418,24 +471,77 @@ void CTownList::CTownItem::gesture(bool on, const Point & initialPosition, const
int townUpperPos = (townIndex < 1) ? -1 : townIndex - 1;
int townLowerPos = (townIndex > towns.size() - 2) ? -1 : townIndex + 1;
auto updateList = [](){
for (auto ki : GH.windows().findWindows<CCastleInterface>())
ki->townChange(); //update list
};
std::vector<RadialMenuConfig> menuElements = {
{ RadialMenuConfig::ITEM_ALT_NN, townUpperPos > -1, "altUpTop", "vcmi.radialWheel.moveTop", [townIndex]()
{ RadialMenuConfig::ITEM_ALT_NN, townUpperPos > -1, "altUpTop", "vcmi.radialWheel.moveTop", [updateList, townIndex]()
{
for (int i = townIndex; i > 0; i--)
LOCPLINT->localState->swapOwnedTowns(i, i - 1);
updateList();
} },
{ RadialMenuConfig::ITEM_ALT_NW, townUpperPos > -1, "altUp", "vcmi.radialWheel.moveUp", [townIndex, townUpperPos](){LOCPLINT->localState->swapOwnedTowns(townIndex, townUpperPos); } },
{ RadialMenuConfig::ITEM_ALT_SW, townLowerPos > -1, "altDown", "vcmi.radialWheel.moveDown", [townIndex, townLowerPos](){ LOCPLINT->localState->swapOwnedTowns(townIndex, townLowerPos); } },
{ RadialMenuConfig::ITEM_ALT_SS, townLowerPos > -1, "altDownBottom", "vcmi.radialWheel.moveBottom", [townIndex, towns]()
{ RadialMenuConfig::ITEM_ALT_NW, townUpperPos > -1, "altUp", "vcmi.radialWheel.moveUp", [updateList, townIndex, townUpperPos](){LOCPLINT->localState->swapOwnedTowns(townIndex, townUpperPos); updateList(); } },
{ RadialMenuConfig::ITEM_ALT_SW, townLowerPos > -1, "altDown", "vcmi.radialWheel.moveDown", [updateList, townIndex, townLowerPos](){ LOCPLINT->localState->swapOwnedTowns(townIndex, townLowerPos); updateList(); } },
{ RadialMenuConfig::ITEM_ALT_SS, townLowerPos > -1, "altDownBottom", "vcmi.radialWheel.moveBottom", [updateList, townIndex, towns]()
{
for (int i = townIndex; i < towns.size() - 1; i++)
LOCPLINT->localState->swapOwnedTowns(i, i + 1);
updateList();
} },
};
GH.windows().createAndPushWindow<RadialMenu>(pos.center(), menuElements, true);
}
void CTownList::CTownItem::keyPressed(EShortcut key)
{
if(parent->selected != this->shared_from_this())
return;
const std::vector<const CGTownInstance *> towns = LOCPLINT->localState->getOwnedTowns();
size_t townIndex = vstd::find_pos(towns, town);
if(townIndex + 1 > towns.size() || !towns.at(townIndex))
return;
if(towns.size() < 2)
return;
int townUpperPos = (townIndex < 1) ? -1 : townIndex - 1;
int townLowerPos = (townIndex > towns.size() - 2) ? -1 : townIndex + 1;
switch(key)
{
case EShortcut::LIST_TOWN_UP:
if(townUpperPos > -1)
LOCPLINT->localState->swapOwnedTowns(townIndex, townUpperPos);
break;
case EShortcut::LIST_TOWN_DOWN:
if(townLowerPos > -1)
LOCPLINT->localState->swapOwnedTowns(townIndex, townLowerPos);
break;
case EShortcut::LIST_TOWN_TOP:
if(townUpperPos > -1)
for (int i = townIndex; i > 0; i--)
LOCPLINT->localState->swapOwnedTowns(i, i - 1);
break;
case EShortcut::LIST_TOWN_BOTTOM:
if(townLowerPos > -1)
for (int i = townIndex; i < towns.size() - 1; i++)
LOCPLINT->localState->swapOwnedTowns(i, i + 1);
break;
}
for (auto ki : GH.windows().findWindows<CCastleInterface>())
ki->townChange(); //update list
}
std::string CTownList::CTownItem::getHoverText()
{
return town->getObjectName();

View File

@ -29,9 +29,10 @@ class CList : public Scrollable
protected:
class CListItem : public CIntObject, public std::enable_shared_from_this<CListItem>
{
CList * parent;
std::shared_ptr<CIntObject> selection;
public:
CList * parent;
CListItem(CList * parent);
~CListItem();
@ -55,9 +56,6 @@ protected:
private:
const size_t size;
//for selection\deselection
std::shared_ptr<CListItem> selected;
void select(std::shared_ptr<CListItem> which);
friend class CListItem;
@ -81,6 +79,9 @@ protected:
void update();
public:
//for selection\deselection
std::shared_ptr<CListItem> selected;
/// functions that will be called when selection changes
CFunctionList<void()> onSelect;
@ -128,6 +129,7 @@ class CHeroList : public CList
void open() override;
void showTooltip() override;
void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override;
void keyPressed(EShortcut key) override;
std::string getHoverText() override;
};
@ -162,6 +164,7 @@ class CTownList : public CList
void open() override;
void showTooltip() override;
void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override;
void keyPressed(EShortcut key) override;
std::string getHoverText() override;
};

View File

@ -293,5 +293,15 @@ enum class EShortcut
SPELLBOOK_TAB_ADVENTURE,
SPELLBOOK_TAB_COMBAT,
LIST_HERO_UP,
LIST_HERO_DOWN,
LIST_HERO_TOP,
LIST_HERO_BOTTOM,
LIST_HERO_DISMISS,
LIST_TOWN_UP,
LIST_TOWN_DOWN,
LIST_TOWN_TOP,
LIST_TOWN_BOTTOM,
AFTER_LAST
};

View File

@ -275,6 +275,15 @@ EShortcut ShortcutHandler::findShortcut(const std::string & identifier ) const
{"heroCostumeLoad9", EShortcut::HERO_COSTUME_LOAD_9 },
{"spellbookTabAdventure", EShortcut::SPELLBOOK_TAB_ADVENTURE },
{"spellbookTabCombat", EShortcut::SPELLBOOK_TAB_COMBAT },
{"listHeroUp", EShortcut::LIST_HERO_UP },
{"listHeroDown", EShortcut::LIST_HERO_DOWN },
{"listHeroTop", EShortcut::LIST_HERO_TOP },
{"listHeroBottom", EShortcut::LIST_HERO_BOTTOM },
{"listHeroDismiss", EShortcut::LIST_HERO_DISMISS },
{"listTownUp", EShortcut::LIST_TOWN_UP },
{"listTownDown", EShortcut::LIST_TOWN_DOWN },
{"listTownTop", EShortcut::LIST_TOWN_TOP },
{"listTownBottom", EShortcut::LIST_TOWN_BOTTOM },
{"mainMenuHotseat", EShortcut::MAIN_MENU_HOTSEAT },
{"mainMenuHostGame", EShortcut::MAIN_MENU_HOST_GAME },
{"mainMenuJoinGame", EShortcut::MAIN_MENU_JOIN_GAME },

View File

@ -242,6 +242,15 @@
"townOpenThievesGuild": "G",
"townOpenVisitingHero": "Ctrl+H",
"townSwapArmies": "Space",
"listHeroUp": "Ctrl+PageUp",
"listHeroDown": "Ctrl+PageDown",
"listHeroTop": "Ctrl+Home",
"listHeroBottom": "Ctrl+End",
"listHeroDismiss": "Delete",
"listTownUp": "Ctrl+PageUp",
"listTownDown": "Ctrl+PageDown",
"listTownTop": "Ctrl+Home",
"listTownBottom": "Ctrl+End",
// Controller-specific
"mouseCursorX": [],