Files
pico-launcher/arm9/source/gui/views/RecyclerView.h
2025-11-25 17:41:31 +01:00

113 lines
3.0 KiB
C++

#pragma once
#include <memory>
#include "View.h"
#include "RecyclerAdapter.h"
#include "gui/FocusManager.h"
#include "animation/Animator.h"
#include "RecyclerViewBase.h"
class RecyclerView : public RecyclerViewBase
{
public:
enum class Mode
{
/// @brief A single row that grows horizontally.
HorizontalList,
/// @brief A multi-row grid that grows horizontally.
HorizontalGrid,
/// @brief A single column that grows vertically.
VerticalList,
/// @brief A multi-column grid that grows vertically.
VerticalGrid
};
RecyclerView(int x, int y, int width, int height, Mode mode);
~RecyclerView();
void SetAdapter(const RecyclerAdapter* adapter, int initialSelectedIndex = 0) override;
void InitVram(const VramContext& vramContext) override;
void Update() override;
void Draw(GraphicsContext& graphicsContext) override;
void VBlank() override;
Rectangle GetBounds() const override
{
return Rectangle(_position, _width, _height);
}
View* MoveFocus(View* currentFocus, FocusMoveDirection direction, View* source) override;
bool HandleInput(const InputProvider& inputProvider, FocusManager& focusManager) override;
void Focus(FocusManager& focusManager) override
{
if (_selectedItem)
focusManager.Focus(_selectedItem->view);
else
focusManager.Focus(this);
}
int GetSelectedItem() const override
{
return _selectedItem ? _selectedItem->itemIdx : -1;
}
constexpr Mode GetMode() const { return _mode; }
void SetPadding(int x, int y)
{
_xPadding = x;
_yPadding = y;
}
void SetItemSpacing(int x, int y)
{
_xSpacing = x;
_ySpacing = y;
}
private:
struct ViewPoolEntry
{
View* view;
int itemIdx;
};
int _width;
int _height;
Mode _mode;
int _rows;
int _columns;
std::unique_ptr<ViewPoolEntry[]> _viewPool;
u32 _viewPoolFreeCount;
u32 _viewPoolTotalCount;
int _xOffset;
int _yOffset;
int _xPadding;
int _yPadding;
int _xSpacing;
int _ySpacing;
int _itemWidth;
int _itemHeight;
u32 _itemCount;
ViewPoolEntry* _selectedItem;
int _curRangeStart;
int _curRangeLength;
Animator<int> _scrollOffsetAnimator;
void UpdatePosition(ViewPoolEntry& viewPoolEntry);
ViewPoolEntry* GetViewPoolEntryByItemIndex(int itemIdx);
void BindRange(int start, int end);
ViewPoolEntry* BindViewPoolEntry(int itemIdx);
void ReleaseRange(int start, int end);
void ReleaseViewPoolEntry(int itemIdx);
void SetSelectedItem(int itemIdx);
int GetMaxScrollOffset();
void SetScrollOffset(int offset, bool animate);
void EnsureVisible(int itemIdx, bool animate);
Point GetItemPosition(int itemIdx);
View* MoveFocusHorizontal(View* currentFocus, FocusMoveDirection direction, View* source);
View* MoveFocusVertical(View* currentFocus, FocusMoveDirection direction, View* source);
};