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)
: CIntObject(WHEEL | GESTURE_PANNING, widgetDimensions.topLeft()),
: Scrollable(0, widgetDimensions.topLeft(), Orientation::VERTICAL),
size(Size),
panningDistanceAccumulated(0),
selected(nullptr)
{
pos.w = widgetDimensions.w;
@ -108,8 +107,7 @@ void CList::setScrollUpButton(std::shared_ptr<CButton> button)
addChild(button.get());
scrollUp = button;
scrollUp->addCallback(std::bind(&CListBox::moveToPrev, listBox));
scrollUp->addCallback(std::bind(&CList::update, this));
scrollUp->addCallback(std::bind(&CList::scrollPrev, this));
update();
}
@ -118,8 +116,29 @@ void CList::setScrollDownButton(std::shared_ptr<CButton> button)
addChild(button.get());
scrollDown = button;
scrollDown->addCallback(std::bind(&CList::update, this));
scrollDown->addCallback(std::bind(&CListBox::moveToNext, listBox));
scrollDown->addCallback(std::bind(&CList::scrollNext, this));
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();
}
@ -188,41 +207,6 @@ 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);

View File

@ -9,7 +9,7 @@
*/
#pragma once
#include "../gui/CIntObject.h"
#include "../widgets/Scrollable.h"
#include "../../lib/FunctionList.h"
VCMI_LIB_NAMESPACE_BEGIN
@ -24,7 +24,7 @@ class CButton;
class CAnimImage;
/// Base UI Element for hero\town lists
class CList : public CIntObject
class CList : public Scrollable
{
protected:
class CListItem : public CIntObject, public std::enable_shared_from_this<CListItem>
@ -55,8 +55,6 @@ 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;
@ -66,6 +64,10 @@ private:
std::shared_ptr<CButton> scrollUp;
std::shared_ptr<CButton> scrollDown;
void scrollBy(int distance) override;
void scrollPrev() override;
void scrollNext() override;
protected:
std::shared_ptr<CListBox> listBox;
@ -94,9 +96,6 @@ 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

View File

@ -198,10 +198,8 @@ void EventDispatcher::dispatchMouseScrolled(const Point & distance, const Point
if(!vstd::contains(wheelInterested,i))
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))
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))
{
assert(it->panningState == false);
it->panning(true);
it->panningState = true;
}

View File

@ -413,9 +413,8 @@ void OptionsTab::CPlayerOptionTooltipBox::genBonusWindow()
}
OptionsTab::SelectedBox::SelectedBox(Point position, PlayerSettings & settings, SelType type)
: CIntObject(RCLICK | WHEEL | GESTURE_PANNING, position)
: Scrollable(RCLICK, position, Orientation::HORIZONTAL)
, CPlayerSettingsHelper(settings, type)
, panningDistanceAccumulated(0)
{
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());
pos = image->pos;
setPanningStep(pos.w);
}
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);
switch(CPlayerSettingsHelper::type)
@ -461,38 +465,8 @@ void OptionsTab::SelectedBox::wheelScrolled(int distance)
CSH->setPlayerOption(LobbyChangePlayerOption::BONUS, distance, settings.color);
break;
}
}
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);
}
setScrollingEnabled(false);
}
OptionsTab::PlayerOptionsEntry::PlayerOptionsEntry(const PlayerSettings & S, const OptionsTab & parent)

View File

@ -16,6 +16,8 @@ struct PlayerSettings;
struct PlayerInfo;
VCMI_LIB_NAMESPACE_END
#include "../widgets/Scrollable.h"
class CSlider;
class CLabel;
class CMultiLineLabel;
@ -93,17 +95,14 @@ public:
};
/// 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<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 scrollBy(int distance) override;
void update();
};

View File

@ -28,9 +28,9 @@ void Scrollable::panning(bool on)
void Scrollable::wheelScrolled(int distance)
{
if (orientation == Orientation::HORIZONTAL)
scrollBy(distance * 3);
scrollBy(distance * scrollStep);
else
scrollBy(-distance * 3);
scrollBy(-distance * scrollStep);
}
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
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;
/// How far player must move finger/mouse to move slider by 1 via gesture
int panningDistanceSingle;