feat: Implement rendering of scroll bar thumb
This commit is contained in:
parent
8d8329a3f9
commit
277c9719bb
4 changed files with 99 additions and 22 deletions
|
@ -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>());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue