make scrollbar interactive

This commit is contained in:
MihailRis 2024-12-05 14:43:24 +03:00
parent bad2b44c96
commit b65ba61f9a
6 changed files with 65 additions and 16 deletions

View File

@ -124,7 +124,7 @@ std::shared_ptr<InventoryView> 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<InventoryView> 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));

View File

@ -23,6 +23,11 @@ std::shared_ptr<UINode> Container::getAt(glm::vec2 pos, std::shared_ptr<UINode>
}
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<UINode> Container::getAt(glm::vec2 pos, std::shared_ptr<UINode>
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<float>(size.y) * actualLength;
scroll = -glm::min(
glm::max(static_cast<float>(-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<float>(diff) * (size.y - h),
w, h
scrollBarWidth, h
);
}
batch->flush();

View File

@ -7,13 +7,19 @@
namespace gui {
class Container : public UINode {
int prevScrollY = -1;
protected:
std::vector<std::shared_ptr<UINode>> nodes;
std::vector<IntervalEvent> 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<std::shared_ptr<UINode>>& getNodes() const;
};
}

View File

@ -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;

View File

@ -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
);

View File

@ -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);