feat: Implement rendering of scroll bar thumb

This commit is contained in:
Vsevolod Kremianskii 2021-02-27 11:26:30 +07:00
parent 8d8329a3f9
commit 277c9719bb
4 changed files with 99 additions and 22 deletions

View file

@ -214,9 +214,12 @@ void ListBox::render(const glm::ivec2 &offset, const vector<string> &text) {
}
if (_scrollBar) {
ScrollBar::ScrollState state;
state.count = static_cast<int>(_items.size());
state.numVisible = this->_slotCount;
state.offset = _itemOffset;
auto &scrollBar = static_cast<ScrollBar &>(*_scrollBar);
scrollBar.setCanScrollUp(_itemOffset > 0);
scrollBar.setCanScrollDown(_items.size() - _itemOffset > _slotCount);
scrollBar.setScrollState(move(state));
scrollBar.render(offset, vector<string>());
}
}

View file

@ -42,21 +42,87 @@ void ScrollBar::load(const GffStruct &gffs) {
shared_ptr<GffStruct> dir(gffs.getStruct("DIR"));
if (dir) {
string image(dir->getString("IMAGE"));
_dir.image = Textures::instance().get(image, TextureUsage::Diffuse);
_dir.image = Textures::instance().get(image, TextureUsage::GUI);
}
shared_ptr<GffStruct> thumb(gffs.getStruct("THUMB"));
if (thumb) {
string image(thumb->getString("IMAGE"));
_thumb.image = Textures::instance().get(image, TextureUsage::GUI);
}
}
void ScrollBar::render(const glm::ivec2 &offset, const vector<string> &text) {
drawThumb(offset);
drawArrows(offset);
}
void ScrollBar::drawThumb(const glm::ivec2 &offset) {
if (!_thumb.image || _state.numVisible >= _state.count) return;
setActiveTextureUnit(TextureUnits::diffuse);
_thumb.image->bind();
ShaderUniforms uniforms;
uniforms.general.projection = RenderWindow::instance().getOrthoProjection();
// Top edge
uniforms.general.model = glm::translate(glm::mat4(1.0f), glm::vec3(_extent.left + offset.x, _extent.top + _extent.width + offset.y, 0.0f));
uniforms.general.model = glm::scale(uniforms.general.model, glm::vec3(_extent.width, 1.0f, 1.0f));
Shaders::instance().activate(ShaderProgram::SimpleGUI, uniforms);
Meshes::instance().getQuad()->render();
// Left edge
uniforms.general.model = glm::translate(glm::mat4(1.0f), glm::vec3(_extent.left + offset.x, _extent.top + _extent.width + offset.y, 0.0f));
uniforms.general.model = glm::scale(uniforms.general.model, glm::vec3(1.0f, _extent.height - 2.0f * _extent.width, 1.0f));
Shaders::instance().activate(ShaderProgram::SimpleGUI, uniforms);
Meshes::instance().getQuad()->render();
// Right edge
uniforms.general.model = glm::translate(glm::mat4(1.0f), glm::vec3(_extent.left + _extent.width - 1.0f + offset.x, _extent.top + _extent.width + offset.y, 0.0f));
uniforms.general.model = glm::scale(uniforms.general.model, glm::vec3(1.0f, _extent.height - 2.0f * _extent.width, 1.0f));
Shaders::instance().activate(ShaderProgram::SimpleGUI, uniforms);
Meshes::instance().getQuad()->render();
// Bottom edge
uniforms.general.model = glm::translate(glm::mat4(1.0f), glm::vec3(_extent.left + offset.x, _extent.top + _extent.height - _extent.width - 1.0f + offset.y, 0.0f));
uniforms.general.model = glm::scale(uniforms.general.model, glm::vec3(_extent.width, 1.0f, 1.0f));
Shaders::instance().activate(ShaderProgram::SimpleGUI, uniforms);
Meshes::instance().getQuad()->render();
// Thumb
float frameHeight = _extent.height - 2.0f * _extent.width - 4.0f;
float thumbHeight = frameHeight * _state.numVisible / static_cast<float>(_state.count);
float y = glm::mix(0.0f, frameHeight - thumbHeight, _state.offset / static_cast<float>(_state.count - _state.numVisible));
uniforms.general.model = glm::translate(glm::mat4(1.0f), glm::vec3(_extent.left + 2.0f + offset.x, _extent.top + _extent.width + 2.0f + offset.y + y, 0.0f));
uniforms.general.model = glm::scale(uniforms.general.model, glm::vec3(_extent.width - 4.0f, thumbHeight, 1.0f));
Shaders::instance().activate(ShaderProgram::SimpleGUI, uniforms);
Meshes::instance().getQuad()->render();
// END Thumb
}
void ScrollBar::drawArrows(const glm::ivec2 &offset) {
if (!_dir.image) return;
bool canScrollUp = _state.offset > 0;
bool canScrollDown = _state.count - _state.offset > _state.numVisible;
if (!canScrollUp && !canScrollDown) return;
setActiveTextureUnit(TextureUnits::diffuse);
_dir.image->bind();
if (_canScrollUp) drawUpArrow(offset);
if (_canScrollDown) drawDownArrow(offset);
if (canScrollUp) {
drawUpArrow(offset);
}
if (canScrollDown) {
drawDownArrow(offset);
}
}
void ScrollBar::drawUpArrow(const glm::vec2 &offset) {
void ScrollBar::drawUpArrow(const glm::ivec2 &offset) {
glm::mat4 transform(1.0f);
transform = glm::translate(transform, glm::vec3(_extent.left + offset.x, _extent.top + offset.y, 0.0f));
transform = glm::scale(transform, glm::vec3(_extent.width, _extent.width, 1.0f));
@ -69,7 +135,7 @@ void ScrollBar::drawUpArrow(const glm::vec2 &offset) {
Meshes::instance().getQuad()->render();
}
void ScrollBar::drawDownArrow(const glm::vec2 &offset) {
void ScrollBar::drawDownArrow(const glm::ivec2 &offset) {
glm::mat4 transform(1.0f);
transform = glm::translate(transform, glm::vec3(_extent.left + offset.x, _extent.top + _extent.height + offset.y, 0.0f));
transform = glm::scale(transform, glm::vec3(_extent.width, _extent.width, 1.0f));
@ -83,12 +149,8 @@ void ScrollBar::drawDownArrow(const glm::vec2 &offset) {
Meshes::instance().getQuad()->render();
}
void ScrollBar::setCanScrollUp(bool scroll) {
_canScrollUp = scroll;
}
void ScrollBar::setCanScrollDown(bool scroll) {
_canScrollDown = scroll;
void ScrollBar::setScrollState(ScrollState state) {
_state = move(state);
}
} // namespace gui

View file

@ -25,25 +25,37 @@ namespace gui {
class ScrollBar : public Control {
public:
struct ScrollState {
int count { 0 }; /**< total number of list items */
int numVisible { 0 }; /**< number of visible list items */
int offset { 0 }; /**< offset into the list of items */
};
ScrollBar(GUI *gui);
void load(const resource::GffStruct &gffs) override;
void render(const glm::ivec2 &offset, const std::vector<std::string> &text) override;
void setCanScrollUp(bool scroll);
void setCanScrollDown(bool scroll);
void setScrollState(ScrollState state);
private:
struct Direction {
std::shared_ptr<render::Texture> image;
};
Direction _dir;
bool _canScrollUp { false };
bool _canScrollDown { false };
struct Thumb {
std::shared_ptr<render::Texture> image;
};
void drawUpArrow(const glm::vec2 &offset);
void drawDownArrow(const glm::vec2 &offset);
Direction _dir;
Thumb _thumb;
ScrollState _state;
void drawThumb(const glm::ivec2 &offset);
void drawArrows(const glm::ivec2 &offset);
void drawUpArrow(const glm::ivec2 &offset);
void drawDownArrow(const glm::ivec2 &offset);
};
} // namespace gui

View file

@ -26,7 +26,7 @@ namespace reone {
namespace render {
// Quads
// Quad
static const vector<float> g_quadVertices {
0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
@ -67,7 +67,7 @@ static const vector<uint16_t> g_quadIndices = { 0, 1, 2, 2, 3, 0 };
static const Mesh::VertexOffsets g_quadOffsets = { 0, -1, 3 * sizeof(float), -1, -1, -1, -1, -1, 5 * sizeof(float) };
// END Quads
// END Quad
// Cube