feat: horizontal scroll

This commit is contained in:
MihailRis 2026-08-07 22:26:58 +03:00
parent 2448869bf9
commit 863cc923a0
4 changed files with 26 additions and 19 deletions

View file

@ -11,7 +11,7 @@
using namespace gui; using namespace gui;
Container::Container(GUI& gui, glm::vec2 size) : UINode(gui, size) { Container::Container(GUI& gui, glm::vec2 size) : UINode(gui, size) {
actualLength = size.y; actualLengthY = size.y;
setColor(glm::vec4()); setColor(glm::vec4());
} }
@ -26,7 +26,7 @@ std::shared_ptr<UINode> Container::getAt(const glm::vec2& pos) {
if (!isInside(pos)) { if (!isInside(pos)) {
return nullptr; return nullptr;
} }
int diff = (actualLength-size.y); int diff = (actualLengthY-size.y);
if (scrollable && diff > 0 && pos.x > calcPos().x + getSize().x - scrollBarWidth) { if (scrollable && diff > 0 && pos.x > calcPos().x + getSize().x - scrollBarWidth) {
return UINode::getAt(pos); return UINode::getAt(pos);
} }
@ -65,11 +65,11 @@ void Container::mouseMove(int x, int y) {
auto pos = calcPos(); auto pos = calcPos();
x -= pos.x; x -= pos.x;
y -= pos.y; y -= pos.y;
int diff = (actualLength-size.y); int diff = (actualLengthY-size.y);
if (diff > 0) { if (diff > 0) {
scroll -= (y - prevScrollY) / static_cast<float>(size.y) * actualLength; scrollY -= (y - prevScrollY) / static_cast<float>(size.y) * actualLengthY;
scroll = -glm::min( scrollY = -glm::min(
glm::max(static_cast<float>(-scroll), 0.0f), actualLength - size.y glm::max(static_cast<float>(-scrollY), 0.0f), actualLengthY - size.y
); );
} }
prevScrollY = y; prevScrollY = y;
@ -110,7 +110,10 @@ void Container::act(float delta) {
} }
void Container::scrolled(int value) { void Container::scrolled(int value) {
int diff = (actualLength-getSize().y); auto size = getSize();
int diff = (actualLengthY > size.y ? actualLengthY - size.y : actualLengthX - size.x);
int& scroll = (actualLengthY > size.y ? scrollY : scrollX);
if (scroll < 0 && diff <= 0) { if (scroll < 0 && diff <= 0) {
scroll = 0; scroll = 0;
} }
@ -146,14 +149,14 @@ void Container::draw(const DrawContext& pctx, const Assets& assets) {
node->draw(pctx, assets); node->draw(pctx, assets);
} }
int diff = (actualLength-size.y); int diff = (actualLengthY-size.y);
if (scrollable && diff > 0) { if (scrollable && diff > 0) {
int h = glm::max(size.y / actualLength * size.y, scrollBarWidth / 2.0f); int h = glm::max(size.y / actualLengthY * size.y, scrollBarWidth / 2.0f);
batch->untexture(); batch->untexture();
batch->setColor(glm::vec4(1, 1, 1, 0.3f)); batch->setColor(glm::vec4(1, 1, 1, 0.3f));
batch->rect( batch->rect(
pos.x + size.x - scrollBarWidth, pos.x + size.x - scrollBarWidth,
pos.y - scroll / static_cast<float>(diff) * (size.y - h), pos.y - scrollY / static_cast<float>(diff) * (size.y - h),
scrollBarWidth, h scrollBarWidth, h
); );
} }
@ -248,7 +251,7 @@ void Container::refresh() {
} }
void Container::setScroll(int scroll) { void Container::setScroll(int scroll) {
this->scroll = scroll; this->scrollY = scroll;
} }
const std::vector<std::shared_ptr<UINode>>& Container::getNodes() const { const std::vector<std::shared_ptr<UINode>>& Container::getNodes() const {

View file

@ -13,10 +13,12 @@ namespace gui {
protected: protected:
std::vector<std::shared_ptr<UINode>> nodes; std::vector<std::shared_ptr<UINode>> nodes;
std::vector<IntervalEvent> intervalEvents; std::vector<IntervalEvent> intervalEvents;
int scroll = 0; int scrollY = 0;
int scrollX = 0;
int scrollStep = 40; int scrollStep = 40;
int scrollBarWidth = 10; int scrollBarWidth = 10;
int actualLength = 0; int actualLengthY = 0;
int actualLengthX = 0;
bool scrollable = true; bool scrollable = true;
bool isScrolling() const { bool isScrolling() const {
@ -40,7 +42,7 @@ namespace gui {
virtual void setScrollable(bool flag); virtual void setScrollable(bool flag);
void listenInterval(float interval, OnTimeOut callback, int repeat=-1); void listenInterval(float interval, OnTimeOut callback, int repeat=-1);
virtual glm::vec2 getContentOffset() const override { virtual glm::vec2 getContentOffset() const override {
return glm::vec2(0.0f, scroll); return glm::vec2(scrollX, scrollY);
}; };
virtual void setSize(const glm::vec2& size) override; virtual void setSize(const glm::vec2& size) override;
virtual int getScrollStep() const; virtual int getScrollStep() const;

View file

@ -41,10 +41,10 @@ glm::vec2 Panel::getContentSize() const {
void Panel::cropToContent() { void Panel::cropToContent() {
if (maxLength > 0.0f) { if (maxLength > 0.0f) {
setSize(glm::vec2( setSize(glm::vec2(
getSize().x, glm::max(minLength, glm::min(maxLength, actualLength)) glm::max(minLength, glm::min(maxLength, actualLengthX)), glm::max(minLength, glm::min(maxLength, actualLengthY))
)); ));
} else { } else {
setSize(glm::vec2(getSize().x, glm::max(minLength, actualLength))); setSize(glm::vec2(glm::max(minLength, actualLengthX), glm::max(minLength, actualLengthY)));
} }
} }
@ -93,7 +93,8 @@ void Panel::refresh() {
y += nodeSize.y + margin.w + interval; y += nodeSize.y + margin.w + interval;
maxw = fmax(maxw, ex + nodeSize.x + margin.z + padding.z); maxw = fmax(maxw, ex + nodeSize.x + margin.z + padding.z);
} }
actualLength = y + padding.w; actualLengthX = size.x;
actualLengthY = y + padding.w;
} else { } else {
float maxh = size.y; float maxh = size.y;
for (auto& node : nodes) { for (auto& node : nodes) {
@ -115,6 +116,7 @@ void Panel::refresh() {
x += nodesize.x + margin.z + interval; x += nodesize.x + margin.z + interval;
maxh = fmax(maxh, ey + nodesize.y + margin.w + padding.w); maxh = fmax(maxh, ey + nodesize.y + margin.w + padding.w);
} }
actualLength = size.y; actualLengthY = size.y;
actualLengthX = x + padding.z;
} }
} }

View file

@ -452,7 +452,7 @@ void TextBox::refreshLabel() {
uint height = label->getLinesNumber() * rawTextCache.metrics.lineHeight * uint height = label->getLinesNumber() * rawTextCache.metrics.lineHeight *
label->getLineInterval(); label->getLineInterval();
label->setSize(glm::vec2(label->getSize().x, height)); label->setSize(glm::vec2(label->getSize().x, height));
actualLength = height; actualLengthY = height;
} else { } else {
setScrollable(false); setScrollable(false);
} }