From b65ba61f9a978e72ef015e938de35b2da2b4d374 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 5 Dec 2024 14:43:24 +0300 Subject: [PATCH] make scrollbar interactive --- src/frontend/hud.cpp | 8 ++-- src/graphics/ui/elements/Container.cpp | 43 +++++++++++++++++++--- src/graphics/ui/elements/Container.hpp | 9 +++++ src/graphics/ui/elements/InventoryView.cpp | 10 ++--- src/graphics/ui/elements/InventoryView.hpp | 2 +- src/graphics/ui/elements/TextBox.cpp | 9 ++++- 6 files changed, 65 insertions(+), 16 deletions(-) diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index 30659969..21111e18 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -124,7 +124,7 @@ std::shared_ptr Hud::createContentAccess() { }); InventoryBuilder builder; - builder.addGrid(8, itemsCount-1, glm::vec2(), 8, true, slotLayout); + builder.addGrid(8, itemsCount-1, glm::vec2(), glm::vec4(8, 8, 12, 8), true, slotLayout); auto view = builder.build(); view->bind(accessInventory, content); view->setMargin(glm::vec4()); @@ -137,7 +137,7 @@ std::shared_ptr Hud::createHotbar() { SlotLayout slotLayout(-1, glm::vec2(), false, false, nullptr, nullptr, nullptr); InventoryBuilder builder; - builder.addGrid(10, 10, glm::vec2(), 4, true, slotLayout); + builder.addGrid(10, 10, glm::vec2(), glm::vec4(4), true, slotLayout); auto view = builder.build(); view->setId("hud.hotbar"); view->setOrigin(glm::vec2(view->getSize().x/2, 0)); @@ -346,9 +346,9 @@ void Hud::update(bool visible) { element.getNode()->setVisible(visible); } - glm::vec2 invSize = contentAccessPanel->getSize(); + glm::vec2 caSize = contentAccessPanel->getSize(); contentAccessPanel->setVisible(inventoryView != nullptr && showContentPanel); - contentAccessPanel->setSize(glm::vec2(invSize.x, Window::height)); + contentAccessPanel->setSize(glm::vec2(caSize.x, Window::height)); contentAccess->setMinSize(glm::vec2(1, Window::height)); hotbarView->setVisible(visible && !(secondUI && !inventoryView)); diff --git a/src/graphics/ui/elements/Container.cpp b/src/graphics/ui/elements/Container.cpp index f5a6a533..86914077 100644 --- a/src/graphics/ui/elements/Container.cpp +++ b/src/graphics/ui/elements/Container.cpp @@ -23,6 +23,11 @@ std::shared_ptr Container::getAt(glm::vec2 pos, std::shared_ptr } if (!isInside(pos)) return nullptr; + int diff = (actualLength-size.y); + if (scrollable && diff > 0 && pos.x > calcPos().x + getSize().x - scrollBarWidth) { + return UINode::getAt(pos, self); + } + for (int i = nodes.size()-1; i >= 0; i--) { auto& node = nodes[i]; if (!node->isVisible()) @@ -35,6 +40,35 @@ std::shared_ptr Container::getAt(glm::vec2 pos, std::shared_ptr return UINode::getAt(pos, self); } +void Container::mouseMove(GUI* gui, int x, int y) { + UINode::mouseMove(gui, x, y); + if (!scrollable) { + return; + } + auto pos = calcPos(); + x -= pos.x; + y -= pos.y; + if (prevScrollY == -1) { + if (x >= size.x - scrollBarWidth) { + prevScrollY = y; + } + return; + } + int diff = (actualLength-size.y); + if (diff > 0) { + scroll -= (y - prevScrollY) / static_cast(size.y) * actualLength; + scroll = -glm::min( + glm::max(static_cast(-scroll), 0.0f), actualLength - size.y + ); + } + prevScrollY = y; +} + +void Container::mouseRelease(GUI* gui, int x, int y) { + UINode::mouseRelease(gui, x, y); + prevScrollY = -1; +} + void Container::act(float delta) { for (const auto& node : nodes) { if (node->isVisible()) { @@ -98,14 +132,13 @@ void Container::draw(const DrawContext* pctx, Assets* assets) { int diff = (actualLength-size.y); if (scrollable && diff > 0) { - int w = 10; - int h = glm::max(size.y / actualLength * size.y, w / 2.0f); + int h = glm::max(size.y / actualLength * size.y, scrollBarWidth / 2.0f); batch->untexture(); - batch->setColor(glm::vec4(1, 1, 1, 0.5f)); + batch->setColor(glm::vec4(1, 1, 1, 0.3f)); batch->rect( - pos.x + size.x - w, + pos.x + size.x - scrollBarWidth, pos.y - scroll / static_cast(diff) * (size.y - h), - w, h + scrollBarWidth, h ); } batch->flush(); diff --git a/src/graphics/ui/elements/Container.hpp b/src/graphics/ui/elements/Container.hpp index bfe40ab5..420a7e55 100644 --- a/src/graphics/ui/elements/Container.hpp +++ b/src/graphics/ui/elements/Container.hpp @@ -7,13 +7,19 @@ namespace gui { class Container : public UINode { + int prevScrollY = -1; protected: std::vector> nodes; std::vector intervalEvents; int scroll = 0; int scrollStep = 40; + int scrollBarWidth = 10; int actualLength = 0; bool scrollable = true; + + bool isScrolling() { + return prevScrollY != -1; + } public: Container(glm::vec2 size); virtual ~Container(); @@ -36,6 +42,9 @@ namespace gui { virtual void setScrollStep(int step); virtual void refresh() override; + virtual void mouseMove(GUI*, int x, int y) override; + virtual void mouseRelease(GUI*, int x, int y) override; + const std::vector>& getNodes() const; }; } diff --git a/src/graphics/ui/elements/InventoryView.cpp b/src/graphics/ui/elements/InventoryView.cpp index 2c763ca4..217de57f 100644 --- a/src/graphics/ui/elements/InventoryView.cpp +++ b/src/graphics/ui/elements/InventoryView.cpp @@ -54,7 +54,7 @@ InventoryBuilder::InventoryBuilder() { void InventoryBuilder::addGrid( int cols, int count, glm::vec2 pos, - int padding, + glm::vec4 padding, bool addpanel, const SlotLayout& slotLayout ) { @@ -63,8 +63,8 @@ void InventoryBuilder::addGrid( int rows = ceildiv(count, cols); - uint width = cols * (slotSize + interval) - interval + padding*2; - uint height = rows * (slotSize + interval) - interval + padding*2; + uint width = cols * (slotSize + interval) - interval + padding.x + padding.z; + uint height = rows * (slotSize + interval) - interval + padding.y + padding.w; glm::vec2 vsize = view->getSize(); if (pos.x + width > vsize.x) { @@ -87,8 +87,8 @@ void InventoryBuilder::addGrid( break; } glm::vec2 position ( - col * (slotSize + interval) + padding, - row * (slotSize + interval) + padding + col * (slotSize + interval) + padding.x, + row * (slotSize + interval) + padding.y ); auto builtSlot = slotLayout; builtSlot.index = row * cols + col; diff --git a/src/graphics/ui/elements/InventoryView.hpp b/src/graphics/ui/elements/InventoryView.hpp index e37e6681..920636cb 100644 --- a/src/graphics/ui/elements/InventoryView.hpp +++ b/src/graphics/ui/elements/InventoryView.hpp @@ -136,7 +136,7 @@ namespace gui { void addGrid( int cols, int count, glm::vec2 pos, - int padding, + glm::vec4 padding, bool addpanel, const SlotLayout& slotLayout ); diff --git a/src/graphics/ui/elements/TextBox.cpp b/src/graphics/ui/elements/TextBox.cpp index 3403e813..4bd72fff 100644 --- a/src/graphics/ui/elements/TextBox.cpp +++ b/src/graphics/ui/elements/TextBox.cpp @@ -74,6 +74,9 @@ void TextBox::draw(const DrawContext* pctx, Assets* assets) { batch->rect(lcoord.x + width, lcoord.y+label->getLineYOffset(line), 2, lineHeight); } if (selectionStart != selectionEnd) { + auto selectionCtx = subctx.sub(batch); + selectionCtx.setBlendMode(BlendMode::addition); + uint startLine = label->getLineByTextIndex(selectionStart); uint endLine = label->getLineByTextIndex(selectionEnd); @@ -433,7 +436,11 @@ void TextBox::click(GUI*, int x, int y) { selectionOrigin = index; } -void TextBox::mouseMove(GUI*, int x, int y) { +void TextBox::mouseMove(GUI* gui, int x, int y) { + Container::mouseMove(gui, x, y); + if (isScrolling()) { + return; + } ptrdiff_t index = calcIndexAt(x, y); setCaret(index); extendSelection(index);