Browse Source

sort town feature

Laserlicht 2 years ago
parent
commit
3b853bff08

BIN
Mods/vcmi/Data/radialMenu/altDown.png


BIN
Mods/vcmi/Data/radialMenu/altUp.png


BIN
Mods/vcmi/Data/radialMenu/itemEmptyAlt.png


BIN
Mods/vcmi/Data/radialMenu/itemInactiveAlt.png


+ 3 - 0
Mods/vcmi/config/vcmi/english.json

@@ -42,6 +42,9 @@
 	"vcmi.radialWheel.moveUnit" : "Move creatures to another army",
 	"vcmi.radialWheel.splitUnit" : "Split creature to another slot",
 
+	"vcmi.radialWheel.townUp" : "Move town up",
+	"vcmi.radialWheel.townDown" : "Move town down",
+
 	"vcmi.mainMenu.serverConnecting" : "Connecting...",
 	"vcmi.mainMenu.serverAddressEnter" : "Enter address:",
 	"vcmi.mainMenu.serverConnectionFailed" : "Failed to connect",

+ 6 - 0
client/PlayerLocalState.cpp

@@ -269,3 +269,9 @@ void PlayerLocalState::removeOwnedTown(const CGTownInstance * town)
 	if (currentSelection == nullptr && !ownedTowns.empty())
 		setSelection(ownedTowns.front());
 }
+
+void PlayerLocalState::swapOwnedTowns(int pos1, int pos2)
+{
+	assert(ownedTowns[pos1] && ownedTowns[pos2]);
+	std::swap(ownedTowns[pos1], ownedTowns[pos2]);
+}

+ 1 - 0
client/PlayerLocalState.h

@@ -66,6 +66,7 @@ public:
 	const CGTownInstance * getOwnedTown(size_t index);
 	void addOwnedTown(const CGTownInstance * hero);
 	void removeOwnedTown(const CGTownInstance * hero);
+	void swapOwnedTowns(int pos1, int pos2);
 
 	const std::vector<const CGHeroInstance *> & getWanderingHeroes();
 	const CGHeroInstance * getWanderingHero(size_t index);

+ 31 - 1
client/adventureMap/CList.cpp

@@ -16,11 +16,13 @@
 #include "../widgets/Images.h"
 #include "../widgets/Buttons.h"
 #include "../widgets/ObjectLists.h"
+#include "../widgets/RadialMenu.h"
 #include "../windows/InfoWindows.h"
 #include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 #include "../PlayerLocalState.h"
 #include "../gui/CGuiHandler.h"
+#include "../gui/WindowHandler.h"
 #include "../render/Canvas.h"
 #include "../render/Colors.h"
 
@@ -293,7 +295,7 @@ void CHeroList::updateWidget()
 
 	for (size_t i = 0; i < heroes.size(); ++i)
 	{
-		auto item =  std::dynamic_pointer_cast<CHeroItem>(listBox->getItem(i));
+		auto item = std::dynamic_pointer_cast<CHeroItem>(listBox->getItem(i));
 
 		if (!item)
 			continue;
@@ -324,12 +326,15 @@ std::shared_ptr<CIntObject> CTownList::createItem(size_t index)
 
 CTownList::CTownItem::CTownItem(CTownList *parent, const CGTownInstance *Town):
 	CListItem(parent),
+	parentList(parent),
 	town(Town)
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
 	picture = std::make_shared<CAnimImage>(AnimationPath::builtin("ITPA"), 0);
 	pos = picture->pos;
 	update();
+
+	addUsedEvents(GESTURE);
 }
 
 std::shared_ptr<CIntObject> CTownList::CTownItem::genSelection()
@@ -361,6 +366,31 @@ void CTownList::CTownItem::showTooltip()
 	CRClickPopup::createAndPush(town, GH.getCursorPosition());
 }
 
+void CTownList::CTownItem::gesture(bool on, const Point & initialPosition, const Point & finalPosition)
+{
+	if(!on)
+		return;
+
+	if(!town)
+		return;
+
+	const std::vector<const CGTownInstance *> towns = LOCPLINT->localState->getOwnedTowns();
+
+	if(towns.size() < 2)
+		return;
+
+	int listPos = std::distance(towns.begin(), std::find(towns.begin(), towns.end(), town));
+	int townUpperPos = (listPos < 1) ? -1 : listPos - 1;
+	int townLowerPos = (listPos > towns.size() - 2) ? -1 : listPos + 1;
+
+	std::vector<RadialMenuConfig> menuElements = {
+		{ RadialMenuConfig::ITEM_ALT_NW, townUpperPos > -1, "altUp", "vcmi.radialWheel.townUp", [this, listPos, townUpperPos](){LOCPLINT->localState->swapOwnedTowns(listPos, townUpperPos); parentList->updateWidget(); } },
+		{ RadialMenuConfig::ITEM_ALT_SW, townLowerPos > -1, "altDown", "vcmi.radialWheel.townDown", [this, listPos, townLowerPos](){ LOCPLINT->localState->swapOwnedTowns(listPos, townLowerPos); parentList->updateWidget(); } },
+	};
+
+	GH.windows().createAndPushWindow<RadialMenu>(pos.center(), menuElements, true);
+}
+
 std::string CTownList::CTownItem::getHoverText()
 {
 	return town->getObjectName();

+ 2 - 0
client/adventureMap/CList.h

@@ -150,6 +150,7 @@ class CTownList	: public CList
 	class CTownItem : public CListItem
 	{
 		std::shared_ptr<CAnimImage> picture;
+		CTownList *parentList;
 	public:
 		const CGTownInstance * const town;
 
@@ -160,6 +161,7 @@ class CTownList	: public CList
 		void select(bool on) override;
 		void open() override;
 		void showTooltip() override;
+		void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override;
 		std::string getHoverText() override;
 	};
 

+ 8 - 7
client/widgets/RadialMenu.cpp

@@ -21,14 +21,14 @@
 
 #include "../../lib/CGeneralTextHandler.h"
 
-RadialMenuItem::RadialMenuItem(const std::string & imageName, const std::string & hoverText, const std::function<void()> & callback)
+RadialMenuItem::RadialMenuItem(const std::string & imageName, const std::string & hoverText, const std::function<void()> & callback, bool altLayout)
 	: callback(callback)
 	, hoverText(hoverText)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
 
-	inactiveImage = std::make_shared<CPicture>(ImagePath::builtin("radialMenu/itemInactive"), Point(0, 0));
-	selectedImage = std::make_shared<CPicture>(ImagePath::builtin("radialMenu/itemEmpty"), Point(0, 0));
+	inactiveImage = std::make_shared<CPicture>(ImagePath::builtin(altLayout ? "radialMenu/itemInactiveAlt" : "radialMenu/itemInactive"), Point(0, 0));
+	selectedImage = std::make_shared<CPicture>(ImagePath::builtin(altLayout ? "radialMenu/itemEmptyAlt" : "radialMenu/itemEmpty"), Point(0, 0));
 
 	iconImage = std::make_shared<CPicture>(ImagePath::builtin("radialMenu/" + imageName), Point(0, 0));
 
@@ -42,13 +42,13 @@ void RadialMenuItem::setSelected(bool selected)
 	inactiveImage->setEnabled(!selected);
 }
 
-RadialMenu::RadialMenu(const Point & positionToCenter, const std::vector<RadialMenuConfig> & menuConfig):
-	centerPosition(positionToCenter)
+RadialMenu::RadialMenu(const Point & positionToCenter, const std::vector<RadialMenuConfig> & menuConfig, bool altLayout):
+	centerPosition(positionToCenter), altLayout(altLayout)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
 	pos += positionToCenter;
 
-	Point itemSize = Point(70, 80);
+	Point itemSize = altLayout ? Point(80, 70) : Point(70, 80);
 	moveBy(-itemSize / 2);
 	pos.w = itemSize.x;
 	pos.h = itemSize.y;
@@ -60,6 +60,7 @@ RadialMenu::RadialMenu(const Point & positionToCenter, const std::vector<RadialM
 
 	for(const auto & item : items)
 		pos = pos.include(item->pos);
+	pos = pos.include(statusBar->pos);
 
 	fitToScreen(10);
 
@@ -71,7 +72,7 @@ void RadialMenu::addItem(const Point & offset, bool enabled, const std::string &
 	if (!enabled)
 		return;
 
-	auto item = std::make_shared<RadialMenuItem>(path, CGI->generaltexth->translate(hoverText), callback);
+	auto item = std::make_shared<RadialMenuItem>(path, CGI->generaltexth->translate(hoverText), callback, altLayout);
 
 	item->moveBy(offset);
 

+ 11 - 2
client/widgets/RadialMenu.h

@@ -26,6 +26,13 @@ struct RadialMenuConfig
 	static constexpr Point ITEM_SW = Point(-40, +70);
 	static constexpr Point ITEM_SE = Point(+40, +70);
 
+	static constexpr Point ITEM_ALT_NN = Point(0,   -80);
+	static constexpr Point ITEM_ALT_SS = Point(0,   +80);
+	static constexpr Point ITEM_ALT_NW = Point(-70, -40);
+	static constexpr Point ITEM_ALT_SW = Point(-70, +40);
+	static constexpr Point ITEM_ALT_NE = Point(+70, -40);
+	static constexpr Point ITEM_ALT_SE = Point(+70, +40);
+
 	Point itemPosition;
 	bool enabled;
 	std::string imageName;
@@ -44,7 +51,7 @@ class RadialMenuItem : public CIntObject
 	std::string hoverText;
 
 public:
-	RadialMenuItem(const std::string & imageName, const std::string & hoverText, const std::function<void()> & callback);
+	RadialMenuItem(const std::string & imageName, const std::string & hoverText, const std::function<void()> & callback, bool altLayout);
 
 	void setSelected(bool selected);
 };
@@ -60,8 +67,10 @@ class RadialMenu : public CIntObject
 	void addItem(const Point & offset, bool enabled, const std::string & path, const std::string & hoverText, const std::function<void()> & callback);
 
 	std::shared_ptr<RadialMenuItem> findNearestItem(const Point & cursorPosition) const;
+
+	bool altLayout;
 public:
-	RadialMenu(const Point & positionToCenter, const std::vector<RadialMenuConfig> & menuConfig);
+	RadialMenu(const Point & positionToCenter, const std::vector<RadialMenuConfig> & menuConfig, bool altLayout = false);
 
 	void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override;
 	void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override;