1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Use Scrollable class for all appropriate locations

This commit is contained in:
Ivan Savenko 2023-05-30 18:53:51 +03:00
parent 052d0d314a
commit 0e36a3ab5a
7 changed files with 47 additions and 94 deletions

View File

@ -82,9 +82,8 @@ void CList::CListItem::onSelect(bool on)
} }
CList::CList(int Size, Rect widgetDimensions) CList::CList(int Size, Rect widgetDimensions)
: CIntObject(WHEEL | GESTURE_PANNING, widgetDimensions.topLeft()), : Scrollable(0, widgetDimensions.topLeft(), Orientation::VERTICAL),
size(Size), size(Size),
panningDistanceAccumulated(0),
selected(nullptr) selected(nullptr)
{ {
pos.w = widgetDimensions.w; pos.w = widgetDimensions.w;
@ -108,8 +107,7 @@ void CList::setScrollUpButton(std::shared_ptr<CButton> button)
addChild(button.get()); addChild(button.get());
scrollUp = button; scrollUp = button;
scrollUp->addCallback(std::bind(&CListBox::moveToPrev, listBox)); scrollUp->addCallback(std::bind(&CList::scrollPrev, this));
scrollUp->addCallback(std::bind(&CList::update, this));
update(); update();
} }
@ -118,8 +116,29 @@ void CList::setScrollDownButton(std::shared_ptr<CButton> button)
addChild(button.get()); addChild(button.get());
scrollDown = button; scrollDown = button;
scrollDown->addCallback(std::bind(&CList::update, this)); scrollDown->addCallback(std::bind(&CList::scrollNext, this));
scrollDown->addCallback(std::bind(&CListBox::moveToNext, listBox)); update();
}
void CList::scrollBy(int distance)
{
if (distance < 0 && listBox->getPos() < -distance)
listBox->moveToPos(0);
else
listBox->moveToPos(static_cast<int>(listBox->getPos()) + distance);
update();
}
void CList::scrollPrev()
{
listBox->moveToPrev();
update();
}
void CList::scrollNext()
{
listBox->moveToNext();
update(); update();
} }
@ -188,41 +207,6 @@ void CList::selectPrev()
selectIndex(index-1); 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() CHeroList::CEmptyHeroItem::CEmptyHeroItem()
{ {
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);

View File

@ -9,7 +9,7 @@
*/ */
#pragma once #pragma once
#include "../gui/CIntObject.h" #include "../widgets/Scrollable.h"
#include "../../lib/FunctionList.h" #include "../../lib/FunctionList.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
@ -24,7 +24,7 @@ class CButton;
class CAnimImage; class CAnimImage;
/// Base UI Element for hero\town lists /// Base UI Element for hero\town lists
class CList : public CIntObject class CList : public Scrollable
{ {
protected: protected:
class CListItem : public CIntObject, public std::enable_shared_from_this<CListItem> class CListItem : public CIntObject, public std::enable_shared_from_this<CListItem>
@ -55,8 +55,6 @@ protected:
private: private:
const size_t size; const size_t size;
/// How far have player moved finger/mouse via gesture so far.
int panningDistanceAccumulated;
//for selection\deselection //for selection\deselection
std::shared_ptr<CListItem> selected; std::shared_ptr<CListItem> selected;
@ -66,6 +64,10 @@ private:
std::shared_ptr<CButton> scrollUp; std::shared_ptr<CButton> scrollUp;
std::shared_ptr<CButton> scrollDown; std::shared_ptr<CButton> scrollDown;
void scrollBy(int distance) override;
void scrollPrev() override;
void scrollNext() override;
protected: protected:
std::shared_ptr<CListBox> listBox; std::shared_ptr<CListBox> listBox;
@ -94,9 +96,6 @@ public:
void selectPrev(); void selectPrev();
void showAll(Canvas & to) override; 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 /// List of heroes which is shown at the right of the adventure map screen

View File

@ -198,10 +198,8 @@ void EventDispatcher::dispatchMouseScrolled(const Point & distance, const Point
if(!vstd::contains(wheelInterested,i)) if(!vstd::contains(wheelInterested,i))
continue; continue;
// ignore distance value and only provide its sign - we expect one scroll "event" to move sliders and such by 1 point,
// and not by system-specific "number of lines to scroll", which is what 'distance' represents
if (i->receiveEvent(position, AEventsReceiver::WHEEL)) if (i->receiveEvent(position, AEventsReceiver::WHEEL))
i->wheelScrolled( std::clamp(distance.y, -1, 1)); i->wheelScrolled(distance.y);
} }
} }
@ -227,7 +225,6 @@ void EventDispatcher::dispatchGesturePanningStarted(const Point & initialPositio
{ {
if (it->receiveEvent(initialPosition, AEventsReceiver::GESTURE_PANNING)) if (it->receiveEvent(initialPosition, AEventsReceiver::GESTURE_PANNING))
{ {
assert(it->panningState == false);
it->panning(true); it->panning(true);
it->panningState = true; it->panningState = true;
} }

View File

@ -413,9 +413,8 @@ void OptionsTab::CPlayerOptionTooltipBox::genBonusWindow()
} }
OptionsTab::SelectedBox::SelectedBox(Point position, PlayerSettings & settings, SelType type) OptionsTab::SelectedBox::SelectedBox(Point position, PlayerSettings & settings, SelType type)
: CIntObject(RCLICK | WHEEL | GESTURE_PANNING, position) : Scrollable(RCLICK, position, Orientation::HORIZONTAL)
, CPlayerSettingsHelper(settings, type) , CPlayerSettingsHelper(settings, type)
, panningDistanceAccumulated(0)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
@ -423,6 +422,8 @@ OptionsTab::SelectedBox::SelectedBox(Point position, PlayerSettings & settings,
subtitle = std::make_shared<CLabel>(23, 39, FONT_TINY, ETextAlignment::CENTER, Colors::WHITE, getName()); subtitle = std::make_shared<CLabel>(23, 39, FONT_TINY, ETextAlignment::CENTER, Colors::WHITE, getName());
pos = image->pos; pos = image->pos;
setPanningStep(pos.w);
} }
void OptionsTab::SelectedBox::update() void OptionsTab::SelectedBox::update()
@ -445,8 +446,11 @@ void OptionsTab::SelectedBox::clickRight(tribool down, bool previousState)
} }
} }
void OptionsTab::SelectedBox::wheelScrolled(int distance) void OptionsTab::SelectedBox::scrollBy(int distance)
{ {
// 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
distance = std::clamp(distance, -1, 1); distance = std::clamp(distance, -1, 1);
switch(CPlayerSettingsHelper::type) switch(CPlayerSettingsHelper::type)
@ -461,38 +465,8 @@ void OptionsTab::SelectedBox::wheelScrolled(int distance)
CSH->setPlayerOption(LobbyChangePlayerOption::BONUS, distance, settings.color); CSH->setPlayerOption(LobbyChangePlayerOption::BONUS, distance, settings.color);
break; break;
} }
}
void OptionsTab::SelectedBox::panning(bool on) setScrollingEnabled(false);
{
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) OptionsTab::PlayerOptionsEntry::PlayerOptionsEntry(const PlayerSettings & S, const OptionsTab & parent)

View File

@ -16,6 +16,8 @@ struct PlayerSettings;
struct PlayerInfo; struct PlayerInfo;
VCMI_LIB_NAMESPACE_END VCMI_LIB_NAMESPACE_END
#include "../widgets/Scrollable.h"
class CSlider; class CSlider;
class CLabel; class CLabel;
class CMultiLineLabel; class CMultiLineLabel;
@ -93,17 +95,14 @@ public:
}; };
/// Image with current town/hero/bonus /// Image with current town/hero/bonus
struct SelectedBox : public CIntObject, public CPlayerSettingsHelper struct SelectedBox : public Scrollable, public CPlayerSettingsHelper
{ {
std::shared_ptr<CAnimImage> image; std::shared_ptr<CAnimImage> image;
std::shared_ptr<CLabel> subtitle; std::shared_ptr<CLabel> subtitle;
int panningDistanceAccumulated;
SelectedBox(Point position, PlayerSettings & settings, SelType type); SelectedBox(Point position, PlayerSettings & settings, SelType type);
void clickRight(tribool down, bool previousState) override; void clickRight(tribool down, bool previousState) override;
void wheelScrolled(int distance) override; void scrollBy(int distance) override;
void gesturePanning(const Point & distanceDelta) override;
void panning(bool on) override;
void update(); void update();
}; };

View File

@ -28,9 +28,9 @@ void Scrollable::panning(bool on)
void Scrollable::wheelScrolled(int distance) void Scrollable::wheelScrolled(int distance)
{ {
if (orientation == Orientation::HORIZONTAL) if (orientation == Orientation::HORIZONTAL)
scrollBy(distance * 3); scrollBy(distance * scrollStep);
else else
scrollBy(-distance * 3); scrollBy(-distance * scrollStep);
} }
void Scrollable::gesturePanning(const Point & distanceDelta) void Scrollable::gesturePanning(const Point & distanceDelta)

View File

@ -21,7 +21,7 @@ enum class Orientation
/// Simple class that provides scrolling functionality via either mouse wheel or touchscreen gesture /// Simple class that provides scrolling functionality via either mouse wheel or touchscreen gesture
class Scrollable : public CIntObject class Scrollable : public CIntObject
{ {
/// how many elements will be scrolled via one click, default = 1 /// how many elements will be scrolled via one wheel action, default = 1
int scrollStep; int scrollStep;
/// How far player must move finger/mouse to move slider by 1 via gesture /// How far player must move finger/mouse to move slider by 1 via gesture
int panningDistanceSingle; int panningDistanceSingle;