Browse Source

backpack window slider

SoundSSGood 2 years ago
parent
commit
ca977d7105

+ 33 - 25
client/widgets/CArtifactsOfHeroBackpack.cpp

@@ -16,6 +16,7 @@
 #include "Buttons.h"
 #include "GameSettings.h"
 #include "IHandlerBase.h"
+#include "ObjectLists.h"
 
 #include "../CPlayerInterface.h"
 #include "../../lib/mapObjects/CGHeroInstance.h"
@@ -43,13 +44,20 @@ CArtifactsOfHeroBackpack::CArtifactsOfHeroBackpack(const Point & position)
 		artPlace->rightClickCallback = std::bind(&CArtifactsOfHeroBase::rightClickArtPlace, this, _1);
 		artPlaceIdx++;
 	}
+
 	if(backpackCap < 0 || visibleCapasityMax < backpackCap)
 	{
-		auto scrollHandler = std::bind(&CArtifactsOfHeroBackpack::scrollBackpack, this, _1);
-		leftBackpackRoll = std::make_shared<CButton>(Point(-20, 0), "hsbtns3.def", CButton::tooltip(), [=]() { scrollHandler(-HERO_BACKPACK_WINDOW_SLOT_COLUMNS); }, EShortcut::MOVE_LEFT);
-		rightBackpackRoll = std::make_shared<CButton>(Point(368, 318), "hsbtns5.def", CButton::tooltip(), [=]() { scrollHandler(HERO_BACKPACK_WINDOW_SLOT_COLUMNS); }, EShortcut::MOVE_RIGHT);
-		leftBackpackRoll->block(true);
-		rightBackpackRoll->block(true);
+		auto onCreate = [](size_t index) -> std::shared_ptr<CIntObject>
+		{
+			return std::make_shared<CIntObject>();
+		};
+		CListBoxWithCallback::MovedPosCallback posMoved = [this](size_t pos) -> void
+		{
+			scrollBackpack(static_cast<int>(pos) * HERO_BACKPACK_WINDOW_SLOT_COLUMNS - backpackPos);
+		};
+		backpackListBox = std::make_shared<CListBoxWithCallback>(
+			posMoved, onCreate, Point(0, 0), Point(0, 0), HERO_BACKPACK_WINDOW_SLOT_LINES, 0, 0, 1,
+			Rect(HERO_BACKPACK_WINDOW_SLOT_COLUMNS * 46 + 10, 0, HERO_BACKPACK_WINDOW_SLOT_LINES * 46 - 5, 0));
 	}
 }
 
@@ -66,26 +74,26 @@ void CArtifactsOfHeroBackpack::pickUpArtifact(CHeroArtPlace & artPlace)
 
 void CArtifactsOfHeroBackpack::scrollBackpack(int offset)
 {
-	if(isScrollStraight)
-	{
-		// offset==-1 => to up; offset==1 => to down
-		backpackPos += offset;
-		auto slot = ArtifactPosition(GameConstants::BACKPACK_START + backpackPos);
-		for(auto artPlace : backpack)
-		{
-			setSlotData(artPlace, slot, *curHero);
-			slot = slot + 1;
-		}
-
-		// Blocking scrolling if there is not enough artifacts to scroll
-		if(leftBackpackRoll)
-			leftBackpackRoll->block(backpackPos <= 0);
-		if(rightBackpackRoll)
-			rightBackpackRoll->block(backpackPos + backpack.size() >= curHero->artifactsInBackpack.size());
-		redraw();
-	}
-	else
+	if(backpackListBox)
+		backpackListBox->resize(getActiveSlotLinesNum());
+	backpackPos += offset;
+	auto slot = ArtifactPosition(GameConstants::BACKPACK_START + backpackPos);
+	for(auto artPlace : backpack)
 	{
-		CArtifactsOfHeroBase::scrollBackpack(offset);
+		setSlotData(artPlace, slot, *curHero);
+		slot = slot + 1;
 	}
+	redraw();
+}
+
+void CArtifactsOfHeroBackpack::updateBackpackSlots()
+{
+	if(backpackListBox)
+		backpackListBox->resize(getActiveSlotLinesNum());
+	CArtifactsOfHeroBase::updateBackpackSlots();
+}
+
+size_t CArtifactsOfHeroBackpack::getActiveSlotLinesNum()
+{
+	return (curHero->artifactsInBackpack.size() + HERO_BACKPACK_WINDOW_SLOT_COLUMNS - 1) / HERO_BACKPACK_WINDOW_SLOT_COLUMNS;
 }

+ 6 - 2
client/widgets/CArtifactsOfHeroBackpack.h

@@ -17,16 +17,20 @@ struct ArtifactLocation;
 
 VCMI_LIB_NAMESPACE_END
 
+class CListBoxWithCallback;
+
 class CArtifactsOfHeroBackpack : public CArtifactsOfHeroBase
 {
 public:
 	CArtifactsOfHeroBackpack(const Point & position);
 	void swapArtifacts(const ArtifactLocation & srcLoc, const ArtifactLocation & dstLoc);
 	void pickUpArtifact(CHeroArtPlace & artPlace);
-	void scrollBackpack(int offset);
+	void scrollBackpack(int offset) override;
+	void updateBackpackSlots() override;
+	size_t getActiveSlotLinesNum();
 
-	bool isScrollStraight = false;
 private:
+	std::shared_ptr<CListBoxWithCallback> backpackListBox;
 	const size_t HERO_BACKPACK_WINDOW_SLOT_COLUMNS = 8;
 	const size_t HERO_BACKPACK_WINDOW_SLOT_LINES = 8;
 };

+ 1 - 1
client/widgets/CArtifactsOfHeroBase.cpp

@@ -232,7 +232,7 @@ void CArtifactsOfHeroBase::updateBackpackSlots()
 {
 	if(curHero->artifactsInBackpack.size() <= backpack.size() && backpackPos != 0)
 		backpackPos = 0;
-	scrollBackpackForArtSet(0, *curHero);
+	scrollBackpack(0);
 }
 
 void CArtifactsOfHeroBase::updateSlot(const ArtifactPosition & slot)

+ 35 - 0
client/widgets/ObjectLists.cpp

@@ -245,3 +245,38 @@ const std::list<std::shared_ptr<CIntObject>> & CListBox::getItems()
 {
 	return items;
 }
+
+CListBoxWithCallback::CListBoxWithCallback(CListBoxWithCallback::MovedPosCallback callback, CreateFunc create, Point pos, Point itemOffset, 
+	size_t visibleSize,	size_t totalSize, size_t initialPos, int slider, Rect sliderPos)
+	: CListBox(create, pos, itemOffset, visibleSize, totalSize, initialPos, slider, sliderPos)
+{
+	movedPosCallback = callback;
+}
+
+void CListBoxWithCallback::scrollTo(size_t pos)
+{
+	CListBox::scrollTo(pos);
+	if(movedPosCallback)
+		movedPosCallback(getPos());
+}
+
+void CListBoxWithCallback::moveToPos(size_t pos)
+{
+	CListBox::moveToPos(pos);
+	if(movedPosCallback)
+		movedPosCallback(getPos());
+}
+
+void CListBoxWithCallback::moveToNext()
+{
+	CListBox::moveToNext();
+	if(movedPosCallback)
+		movedPosCallback(getPos());
+}
+
+void CListBoxWithCallback::moveToPrev()
+{
+	CListBox::moveToPrev();
+	if(movedPosCallback)
+		movedPosCallback(getPos());
+}

+ 20 - 4
client/widgets/ObjectLists.h

@@ -99,12 +99,28 @@ public:
 	size_t getIndexOf(std::shared_ptr<CIntObject> item);
 
 	//scroll list to make item which visible
-	void scrollTo(size_t which);
+	virtual void scrollTo(size_t which);
 
 	//scroll list to specified position
-	void moveToPos(size_t which);
-	void moveToNext();
-	void moveToPrev();
+	virtual void moveToPos(size_t which);
+	virtual void moveToNext();
+	virtual void moveToPrev();
 
 	size_t getPos();
 };
+
+class CListBoxWithCallback : public CListBox
+{
+public:
+	using MovedPosCallback = std::function<void(size_t)>;
+
+	CListBoxWithCallback(MovedPosCallback callback, CreateFunc create, Point pos, Point itemOffset, size_t visibleSize,
+		size_t totalSize, size_t initialPos = 0, int slider = 0, Rect sliderPos = Rect());
+	void scrollTo(size_t pos) override;
+	void moveToPos(size_t pos) override;
+	void moveToNext() override;
+	void moveToPrev() override;
+
+private:
+	MovedPosCallback movedPosCallback;
+};

+ 5 - 5
client/windows/CHeroBackpackWindow.cpp

@@ -11,6 +11,9 @@
 #include "CHeroBackpackWindow.h"
 
 #include "../gui/CGuiHandler.h"
+#include "../gui/Shortcut.h"
+
+#include "../widgets/Buttons.h"
 
 CHeroBackpackWindow::CHeroBackpackWindow(const CGHeroInstance * hero)
 	: CWindowObject(PLAYER_COLORED)
@@ -21,10 +24,7 @@ CHeroBackpackWindow::CHeroBackpackWindow(const CGHeroInstance * hero)
 	arts->setHero(hero);
 	addSet(arts);
 
-	arts_straight = std::make_shared<CArtifactsOfHeroBackpack>(Point(-500, -170));
-	arts_straight->setHero(hero);
-	arts_straight->isScrollStraight = true;
-	addSet(arts_straight);
-
 	addCloseCallback(std::bind(&CHeroBackpackWindow::close, this));
+
+	quitButton = std::make_shared<CButton>(Point(242, 200), "hsbtns.def", CButton::tooltip(""), [this]() { close(); }, EShortcut::GLOBAL_RETURN);
 }

+ 1 - 1
client/windows/CHeroBackpackWindow.h

@@ -19,5 +19,5 @@ public:
 	
 private:
 	std::shared_ptr<CArtifactsOfHeroBackpack> arts;
-	std::shared_ptr<CArtifactsOfHeroBackpack> arts_straight;
+	std::shared_ptr<CButton> quitButton;
 };

+ 0 - 2
client/windows/CHeroWindow.cpp

@@ -137,8 +137,6 @@ CHeroWindow::CHeroWindow(const CGHeroInstance * hero)
 	questlogLabel = std::make_shared<CTextBox>(CGI->generaltexth->jktexts[9], Rect(510, 430, 65, 35), 0, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE);
 	questlogButton = std::make_shared<CButton>(Point(314, 429), "hsbtns4.def", CButton::tooltip(heroscrn[0]), [=](){ LOCPLINT->showQuestLog(); }, EShortcut::ADVENTURE_QUEST_LOG);
 
-	backpackButton = std::make_shared<CButton>(Point(380, 429), "hsbtns2.def", CButton::tooltip(""), [=]() { createBackpackWindow(); }, EShortcut::HERO_BACKPACK);
-
 	formations = std::make_shared<CToggleGroup>(0);
 	formations->addToggle(0, std::make_shared<CToggleButton>(Point(481, 483), "hsbtns6.def", std::make_pair(heroscrn[23], heroscrn[29]), 0, EShortcut::HERO_TIGHT_FORMATION));
 	formations->addToggle(1, std::make_shared<CToggleButton>(Point(481, 519), "hsbtns7.def", std::make_pair(heroscrn[24], heroscrn[30]), 0, EShortcut::HERO_LOOSE_FORMATION));