mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-02-16 20:15:38 +00:00
Added on-demand texture loading for wheel carousels.
Also added proper support for horizontal and vertical offsetting and fixed a clipping issue.
This commit is contained in:
parent
1c14da35e1
commit
04473d0ff3
|
@ -354,11 +354,57 @@ void CarouselComponent<T>::updateEntry(Entry& entry, const std::shared_ptr<Theme
|
||||||
template <typename T> void CarouselComponent<T>::onDemandTextureLoad()
|
template <typename T> void CarouselComponent<T>::onDemandTextureLoad()
|
||||||
{
|
{
|
||||||
if constexpr (std::is_same_v<T, FileData*>) {
|
if constexpr (std::is_same_v<T, FileData*>) {
|
||||||
int numEntries {static_cast<int>(mEntries.size())};
|
const int numEntries {static_cast<int>(mEntries.size())};
|
||||||
int center {getCursor()};
|
const int center {getCursor()};
|
||||||
int itemInclusion {static_cast<int>(std::ceil((mMaxItemCount + 1) / 2.0f))};
|
const bool isWheel {mType == CarouselType::VERTICAL_WHEEL ||
|
||||||
|
mType == CarouselType::HORIZONTAL_WHEEL};
|
||||||
|
int centerOffset {0};
|
||||||
|
int itemInclusion {0};
|
||||||
|
int itemInclusionBefore {0};
|
||||||
|
int itemInclusionAfter {0};
|
||||||
|
|
||||||
for (int i = center - itemInclusion + 1; i < center + itemInclusion; ++i) {
|
if (isWheel) {
|
||||||
|
itemInclusion = 1;
|
||||||
|
itemInclusionBefore = mItemsBeforeCenter - 1;
|
||||||
|
itemInclusionAfter = mItemsAfterCenter;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
itemInclusion = static_cast<int>(std::ceil((mMaxItemCount + 1) / 2.0f));
|
||||||
|
itemInclusionBefore = -1;
|
||||||
|
// If the carousel is offset we need to load additional textures to fully populate
|
||||||
|
// the visible entries.
|
||||||
|
if (mType == CarouselType::HORIZONTAL && mHorizontalOffset != 0.0f) {
|
||||||
|
const float itemSpacing {
|
||||||
|
((mSize.x - (mItemSize.x * mMaxItemCount)) / mMaxItemCount) + mItemSize.x};
|
||||||
|
|
||||||
|
centerOffset = static_cast<int>(std::ceil(mSize.x * std::fabs(mHorizontalOffset) /
|
||||||
|
std::min(mItemSize.x, itemSpacing)));
|
||||||
|
if (mHorizontalOffset < 0.0f)
|
||||||
|
itemInclusionAfter += centerOffset;
|
||||||
|
else
|
||||||
|
itemInclusionBefore += centerOffset;
|
||||||
|
|
||||||
|
if (mHorizontalOffset > 0.0f)
|
||||||
|
centerOffset = -centerOffset;
|
||||||
|
}
|
||||||
|
else if (mType == CarouselType::VERTICAL && mVerticalOffset != 0.0f) {
|
||||||
|
const float itemSpacing {
|
||||||
|
((mSize.y - (mItemSize.y * mMaxItemCount)) / mMaxItemCount) + mItemSize.y};
|
||||||
|
|
||||||
|
centerOffset = static_cast<int>(std::ceil(mSize.y * std::fabs(mVerticalOffset) /
|
||||||
|
std::min(mItemSize.y, itemSpacing)));
|
||||||
|
if (mVerticalOffset < 0.0f)
|
||||||
|
itemInclusionAfter += centerOffset;
|
||||||
|
else
|
||||||
|
itemInclusionBefore += centerOffset;
|
||||||
|
|
||||||
|
if (mVerticalOffset > 0.0f)
|
||||||
|
centerOffset = -centerOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = center - itemInclusion - itemInclusionBefore;
|
||||||
|
i < center + itemInclusion + itemInclusionAfter; ++i) {
|
||||||
int cursor {i};
|
int cursor {i};
|
||||||
|
|
||||||
while (cursor < 0)
|
while (cursor < 0)
|
||||||
|
@ -527,6 +573,7 @@ template <typename T> void CarouselComponent<T>::render(const glm::mat4& parentT
|
||||||
if (carouselTrans[3].x + mSize.x <= 0.0f || carouselTrans[3].y + mSize.y <= 0.0f)
|
if (carouselTrans[3].x + mSize.x <= 0.0f || carouselTrans[3].y + mSize.y <= 0.0f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const float sizeX {carouselTrans[3].x < 0.0f ? mSize.x + carouselTrans[3].x : mSize.x};
|
||||||
const float sizeY {carouselTrans[3].y < 0.0f ? mSize.y + carouselTrans[3].y : mSize.y};
|
const float sizeY {carouselTrans[3].y < 0.0f ? mSize.y + carouselTrans[3].y : mSize.y};
|
||||||
|
|
||||||
glm::ivec2 clipPos {static_cast<int>(glm::clamp(std::round(carouselTrans[3].x), 0.0f,
|
glm::ivec2 clipPos {static_cast<int>(glm::clamp(std::round(carouselTrans[3].x), 0.0f,
|
||||||
|
@ -534,7 +581,7 @@ template <typename T> void CarouselComponent<T>::render(const glm::mat4& parentT
|
||||||
static_cast<int>(glm::clamp(std::round(carouselTrans[3].y), 0.0f,
|
static_cast<int>(glm::clamp(std::round(carouselTrans[3].y), 0.0f,
|
||||||
mRenderer->getScreenHeight()))};
|
mRenderer->getScreenHeight()))};
|
||||||
glm::ivec2 clipDim {
|
glm::ivec2 clipDim {
|
||||||
static_cast<int>(std::min(std::round(mSize.x), mRenderer->getScreenWidth())),
|
static_cast<int>(std::min(std::round(sizeX), mRenderer->getScreenWidth())),
|
||||||
static_cast<int>(std::min(std::round(sizeY), mRenderer->getScreenHeight()))};
|
static_cast<int>(std::min(std::round(sizeY), mRenderer->getScreenHeight()))};
|
||||||
|
|
||||||
mRenderer->pushClipRect(clipPos, clipDim);
|
mRenderer->pushClipRect(clipPos, clipDim);
|
||||||
|
@ -646,6 +693,7 @@ template <typename T> void CarouselComponent<T>::render(const glm::mat4& parentT
|
||||||
}
|
}
|
||||||
|
|
||||||
int center {0};
|
int center {0};
|
||||||
|
int centerOffset {0};
|
||||||
// Needed to make sure that overlapping items are renderered correctly.
|
// Needed to make sure that overlapping items are renderered correctly.
|
||||||
if (mPositiveDirection)
|
if (mPositiveDirection)
|
||||||
center = static_cast<int>(std::floor(camOffset));
|
center = static_cast<int>(std::floor(camOffset));
|
||||||
|
@ -659,6 +707,30 @@ template <typename T> void CarouselComponent<T>::render(const glm::mat4& parentT
|
||||||
if (mLegacyMode || mType == CarouselType::HORIZONTAL || mType == CarouselType::VERTICAL) {
|
if (mLegacyMode || mType == CarouselType::HORIZONTAL || mType == CarouselType::VERTICAL) {
|
||||||
itemInclusion = static_cast<int>(std::ceil(mMaxItemCount / 2.0f)) + 1;
|
itemInclusion = static_cast<int>(std::ceil(mMaxItemCount / 2.0f)) + 1;
|
||||||
itemInclusionAfter = 2;
|
itemInclusionAfter = 2;
|
||||||
|
// If the carousel is offset we need to calculate the center offset so the items are
|
||||||
|
// rendered in the correct order (as seen when overlapping).
|
||||||
|
if (mType == CarouselType::HORIZONTAL && mHorizontalOffset != 0.0f) {
|
||||||
|
centerOffset = static_cast<int>(std::ceil(mSize.x * std::fabs(mHorizontalOffset) /
|
||||||
|
std::min(mItemSize.x, itemSpacing.x)));
|
||||||
|
if (mHorizontalOffset < 0.0f)
|
||||||
|
itemInclusionAfter += centerOffset;
|
||||||
|
else
|
||||||
|
itemInclusionBefore += centerOffset;
|
||||||
|
|
||||||
|
if (mHorizontalOffset > 0.0f)
|
||||||
|
centerOffset = -centerOffset;
|
||||||
|
}
|
||||||
|
else if (mType == CarouselType::VERTICAL && mVerticalOffset != 0.0f) {
|
||||||
|
centerOffset = static_cast<int>(std::ceil(mSize.y * std::fabs(mVerticalOffset) /
|
||||||
|
std::min(mItemSize.y, itemSpacing.y)));
|
||||||
|
if (mVerticalOffset < 0.0f)
|
||||||
|
itemInclusionAfter += centerOffset;
|
||||||
|
else
|
||||||
|
itemInclusionBefore += centerOffset;
|
||||||
|
|
||||||
|
if (mVerticalOffset > 0.0f)
|
||||||
|
centerOffset = -centerOffset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// For the wheel types.
|
// For the wheel types.
|
||||||
|
@ -667,7 +739,7 @@ template <typename T> void CarouselComponent<T>::render(const glm::mat4& parentT
|
||||||
itemInclusionAfter = mItemsAfterCenter;
|
itemInclusionAfter = mItemsAfterCenter;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool singleEntry {numEntries == 1};
|
const bool singleEntry {numEntries == 1};
|
||||||
|
|
||||||
struct renderStruct {
|
struct renderStruct {
|
||||||
int index;
|
int index;
|
||||||
|
@ -728,8 +800,7 @@ template <typename T> void CarouselComponent<T>::render(const glm::mat4& parentT
|
||||||
renderItems.emplace_back(renderItem);
|
renderItems.emplace_back(renderItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
int belowCenter {static_cast<int>(std::ceil(renderItems.size() / 2)) - 1};
|
int belowCenter {static_cast<int>(std::round((renderItems.size() - centerOffset - 1) / 2))};
|
||||||
|
|
||||||
if (renderItems.size() == 1) {
|
if (renderItems.size() == 1) {
|
||||||
renderItemsSorted.emplace_back(renderItems.front());
|
renderItemsSorted.emplace_back(renderItems.front());
|
||||||
}
|
}
|
||||||
|
@ -760,15 +831,16 @@ template <typename T> void CarouselComponent<T>::render(const glm::mat4& parentT
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (isWheel) {
|
if (isWheel) {
|
||||||
if (mItemAxisHorizontal) {
|
|
||||||
glm::mat4 positionCalc {renderItem.trans};
|
glm::mat4 positionCalc {renderItem.trans};
|
||||||
const float xOff {(GuiComponent::mOrigin.x - mItemRotationOrigin.x) * mItemSize.x};
|
const float xOffTrans {(GuiComponent::mOrigin.x - mItemRotationOrigin.x) * mItemSize.x};
|
||||||
const float yOff {(GuiComponent::mOrigin.y - mItemRotationOrigin.y) * mItemSize.y};
|
const float yOffTrans {mItemAxisHorizontal ?
|
||||||
|
0.0f :
|
||||||
|
(GuiComponent::mOrigin.y - mItemRotationOrigin.y) *
|
||||||
|
mItemSize.y};
|
||||||
|
|
||||||
// Transform to offset point.
|
// Transform to offset point.
|
||||||
if (xOff != 0.0f || yOff != 0.0f)
|
positionCalc = glm::translate(positionCalc,
|
||||||
positionCalc =
|
glm::vec3 {xOffTrans * -1.0f, yOffTrans * -1.0f, 0.0f});
|
||||||
glm::translate(positionCalc, glm::vec3 {xOff * -1.0f, 0.0f * -1.0f, 0.0f});
|
|
||||||
|
|
||||||
// Apply rotation transform.
|
// Apply rotation transform.
|
||||||
positionCalc =
|
positionCalc =
|
||||||
|
@ -776,15 +848,16 @@ template <typename T> void CarouselComponent<T>::render(const glm::mat4& parentT
|
||||||
glm::vec3 {0.0f, 0.0f, 1.0f});
|
glm::vec3 {0.0f, 0.0f, 1.0f});
|
||||||
|
|
||||||
// Transform back to original point.
|
// Transform back to original point.
|
||||||
if (xOff != 0.0f || yOff != 0.0f)
|
positionCalc = glm::translate(positionCalc, glm::vec3 {xOffTrans, yOffTrans, 0.0f});
|
||||||
positionCalc = glm::translate(positionCalc, glm::vec3 {xOff, 0.0f, 0.0f});
|
|
||||||
|
if (mItemAxisHorizontal) {
|
||||||
// Only keep position and discard the rotation data.
|
// Only keep position and discard the rotation data.
|
||||||
renderItem.trans[3].x = positionCalc[3].x;
|
renderItem.trans[3].x = positionCalc[3].x;
|
||||||
renderItem.trans[3].y = positionCalc[3].y;
|
renderItem.trans[3].y = positionCalc[3].y;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
comp->setRotationDegrees(mItemRotation * renderItem.distance);
|
renderItem.trans = positionCalc;
|
||||||
comp->setRotationOrigin(mItemRotationOrigin);
|
renderItem.trans = positionCalc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue