Răsfoiți Sursa

Implemented gesture for town/hero lists and town/hero selection

Ivan Savenko 2 ani în urmă
părinte
comite
57df1c3e0d

+ 1 - 1
client/CServerHandler.cpp

@@ -485,7 +485,7 @@ void CServerHandler::setPlayer(PlayerColor color) const
 	sendLobbyPack(lsp);
 }
 
-void CServerHandler::setPlayerOption(ui8 what, ui8 dir, PlayerColor player) const
+void CServerHandler::setPlayerOption(ui8 what, si8 dir, PlayerColor player) const
 {
 	LobbyChangePlayerOption lcpo;
 	lcpo.what = what;

+ 2 - 2
client/CServerHandler.h

@@ -62,7 +62,7 @@ public:
 	virtual void setCampaignBonus(int bonusId) const = 0;
 	virtual void setMapInfo(std::shared_ptr<CMapInfo> to, std::shared_ptr<CMapGenOptions> mapGenOpts = {}) const = 0;
 	virtual void setPlayer(PlayerColor color) const = 0;
-	virtual void setPlayerOption(ui8 what, ui8 dir, PlayerColor player) const = 0;
+	virtual void setPlayerOption(ui8 what, si8 dir, PlayerColor player) const = 0;
 	virtual void setDifficulty(int to) const = 0;
 	virtual void setTurnLength(int npos) const = 0;
 	virtual void sendMessage(const std::string & txt) const = 0;
@@ -140,7 +140,7 @@ public:
 	void setCampaignBonus(int bonusId) const override;
 	void setMapInfo(std::shared_ptr<CMapInfo> to, std::shared_ptr<CMapGenOptions> mapGenOpts = {}) const override;
 	void setPlayer(PlayerColor color) const override;
-	void setPlayerOption(ui8 what, ui8 dir, PlayerColor player) const override;
+	void setPlayerOption(ui8 what, si8 dir, PlayerColor player) const override;
 	void setDifficulty(int to) const override;
 	void setTurnLength(int npos) const override;
 	void sendMessage(const std::string & txt) const override;

+ 38 - 11
client/adventureMap/CList.cpp

@@ -31,7 +31,7 @@
 #include "../../lib/mapObjects/CGTownInstance.h"
 
 CList::CListItem::CListItem(CList * Parent)
-	: CIntObject(LCLICK | RCLICK | HOVER | WHEEL),
+	: CIntObject(LCLICK | RCLICK | HOVER),
 	parent(Parent),
 	selection()
 {
@@ -40,15 +40,6 @@ CList::CListItem::CListItem(CList * Parent)
 
 CList::CListItem::~CListItem() = default;
 
-void CList::CListItem::wheelScrolled(int distance)
-{
-	if (distance < 0)
-		parent->listBox->moveToNext();
-	if (distance > 0)
-		parent->listBox->moveToPrev();
-	parent->update();
-}
-
 void CList::CListItem::clickRight(tribool down, bool previousState)
 {
 	if (down == true)
@@ -91,8 +82,9 @@ void CList::CListItem::onSelect(bool on)
 }
 
 CList::CList(int Size, Rect widgetDimensions)
-	: CIntObject(0, widgetDimensions.topLeft()),
+	: CIntObject(WHEEL | GESTURE_PANNING, widgetDimensions.topLeft()),
 	size(Size),
+	panningDistanceAccumulated(0),
 	selected(nullptr)
 {
 	pos.w = widgetDimensions.w;
@@ -196,6 +188,41 @@ void CList::selectPrev()
 		selectIndex(index-1);
 }
 
+void CList::panning(bool on)
+{
+	panningDistanceAccumulated = 0;
+}
+
+void CList::gesturePanning(const Point & distanceDelta)
+{
+	int panningDistanceSingle = 32;
+
+	panningDistanceAccumulated += distanceDelta.y;
+
+	while (-panningDistanceAccumulated > panningDistanceSingle )
+	{
+		listBox->moveToPrev();
+		panningDistanceAccumulated += panningDistanceSingle;
+	}
+
+	while (panningDistanceAccumulated > panningDistanceSingle )
+	{
+		listBox->moveToNext();
+		panningDistanceAccumulated -= panningDistanceSingle;
+	}
+
+	update();
+}
+
+void CList::wheelScrolled(int distance)
+{
+	if (distance < 0)
+		listBox->moveToNext();
+	if (distance > 0)
+		listBox->moveToPrev();
+	update();
+}
+
 CHeroList::CEmptyHeroItem::CEmptyHeroItem()
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);

+ 5 - 1
client/adventureMap/CList.h

@@ -35,7 +35,6 @@ protected:
 		CListItem(CList * parent);
 		~CListItem();
 
-		void wheelScrolled(int distance) override;
 		void clickRight(tribool down, bool previousState) override;
 		void clickLeft(tribool down, bool previousState) override;
 		void hover(bool on) override;
@@ -56,6 +55,8 @@ protected:
 
 private:
 	const size_t size;
+	/// How far have player moved finger/mouse via gesture so far.
+	int panningDistanceAccumulated;
 
 	//for selection\deselection
 	std::shared_ptr<CListItem> selected;
@@ -93,6 +94,9 @@ public:
 	void selectPrev();
 
 	void showAll(Canvas & to) override;
+	void panning(bool on) override;
+	void gesturePanning(const Point & distanceDelta) override;
+	void wheelScrolled(int distance) override;
 };
 
 /// List of heroes which is shown at the right of the adventure map screen

+ 4 - 1
client/gui/EventDispatcher.cpp

@@ -227,6 +227,7 @@ void EventDispatcher::dispatchGesturePanningStarted(const Point & initialPositio
 	{
 		if (it->receiveEvent(initialPosition, AEventsReceiver::GESTURE_PANNING))
 		{
+			assert(it->panningState == false);
 			it->panning(true);
 			it->panningState = true;
 		}
@@ -247,7 +248,9 @@ void EventDispatcher::dispatchGesturePanningEnded()
 
 void EventDispatcher::dispatchGesturePanning(const Point & distance)
 {
-	for(auto it : panningInterested)
+	auto copied = panningInterested;
+
+	for(auto it : copied)
 	{
 		if (it->isPanning())
 			it->gesturePanning(distance);

+ 1 - 0
client/gui/EventsReceiver.cpp

@@ -17,6 +17,7 @@
 AEventsReceiver::AEventsReceiver()
 	: activeState(0)
 	, hoveredState(false)
+	, panningState(false)
 {
 }
 

+ 37 - 1
client/lobby/OptionsTab.cpp

@@ -412,7 +412,9 @@ void OptionsTab::CPlayerOptionTooltipBox::genBonusWindow()
 }
 
 OptionsTab::SelectedBox::SelectedBox(Point position, PlayerSettings & settings, SelType type)
-	: CIntObject(RCLICK | WHEEL, position), CPlayerSettingsHelper(settings, type)
+	: CIntObject(RCLICK | WHEEL | GESTURE_PANNING, position)
+	, CPlayerSettingsHelper(settings, type)
+	, panningDistanceAccumulated(0)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
 
@@ -444,6 +446,8 @@ void OptionsTab::SelectedBox::clickRight(tribool down, bool previousState)
 
 void OptionsTab::SelectedBox::wheelScrolled(int distance)
 {
+	distance = std::clamp(distance, -1, 1);
+
 	switch(CPlayerSettingsHelper::type)
 	{
 		case TOWN:
@@ -458,6 +462,38 @@ void OptionsTab::SelectedBox::wheelScrolled(int distance)
 	}
 }
 
+void OptionsTab::SelectedBox::panning(bool on)
+{
+	panningDistanceAccumulated = 0;
+}
+
+void OptionsTab::SelectedBox::gesturePanning(const Point & distanceDelta)
+{
+	// FIXME: currently options tab is completely recreacted from scratch whenever we receive any information from server
+	// because of that, panning event gets interrupted (due to destruction of element)
+	// so, currently, gesture will always move selection only by 1, and then wait for recreation from server info
+
+	int panningDistanceSingle = 48;
+
+	panningDistanceAccumulated += distanceDelta.x;
+
+	if (-panningDistanceAccumulated > panningDistanceSingle )
+	{
+		int scrollAmount = (-panningDistanceAccumulated) / panningDistanceSingle;
+		wheelScrolled(-scrollAmount);
+		panningDistanceAccumulated += scrollAmount * panningDistanceSingle;
+		removeUsedEvents(GESTURE_PANNING);
+	}
+
+	if (panningDistanceAccumulated > panningDistanceSingle )
+	{
+		int scrollAmount = panningDistanceAccumulated / panningDistanceSingle;
+		wheelScrolled(scrollAmount);
+		panningDistanceAccumulated += -scrollAmount * panningDistanceSingle;
+		removeUsedEvents(GESTURE_PANNING);
+	}
+}
+
 OptionsTab::PlayerOptionsEntry::PlayerOptionsEntry(const PlayerSettings & S, const OptionsTab & parent)
 	: pi(std::make_unique<PlayerInfo>(SEL->getPlayerInfo(S.color.getNum())))
 	, s(std::make_unique<PlayerSettings>(S))

+ 3 - 0
client/lobby/OptionsTab.h

@@ -97,10 +97,13 @@ public:
 	{
 		std::shared_ptr<CAnimImage> image;
 		std::shared_ptr<CLabel> subtitle;
+		int panningDistanceAccumulated;
 
 		SelectedBox(Point position, PlayerSettings & settings, SelType type);
 		void clickRight(tribool down, bool previousState) override;
 		void wheelScrolled(int distance) override;
+		void gesturePanning(const Point & distanceDelta) override;
+		void panning(bool on) override;
 
 		void update();
 	};

+ 1 - 1
client/lobby/SelectionTab.cpp

@@ -132,7 +132,7 @@ static ESortBy getSortBySelectionScreen(ESelectionScreen Type)
 }
 
 SelectionTab::SelectionTab(ESelectionScreen Type)
-	: CIntObject(LCLICK | WHEEL | KEYBOARD | DOUBLECLICK), callOnSelect(nullptr), tabType(Type), selectionPos(0), sortModeAscending(true), inputNameRect{32, 539, 350, 20}
+	: CIntObject(LCLICK | KEYBOARD | DOUBLECLICK), callOnSelect(nullptr), tabType(Type), selectionPos(0), sortModeAscending(true), inputNameRect{32, 539, 350, 20}
 {
 	OBJ_CONSTRUCTION;