diff --git a/src/gui/gui2_scrollbar.cpp b/src/gui/gui2_scrollbar.cpp index 77447861b2..a28468d422 100644 --- a/src/gui/gui2_scrollbar.cpp +++ b/src/gui/gui2_scrollbar.cpp @@ -24,24 +24,21 @@ void GuiScrollbar::onDraw(sp::RenderTarget& renderer) renderer.drawStretched(rect, back.texture, back.color); - int range = (max_value - min_value); - float arrow_size = rect.size.x / 2.0f; - float move_height = (rect.size.y - arrow_size * 2); - float bar_size = move_height * value_size / range; - if (bar_size > move_height) - bar_size = move_height; - renderer.drawStretched(sp::Rect(rect.position.x, rect.position.y + arrow_size + move_height * getValue() / range, rect.size.x, bar_size), front.texture, front.color); + // Update the bar's range, size, and draggable bar size. + range = max_value - min_value - value_size; + arrow_size = rect.size.x / 2.0f; + move_height = rect.size.y - arrow_size * 2; + // Clamp the size of the draggable bar to no less than 20px. + bar_size = std::clamp(move_height * value_size / (range + value_size), 20.0F, move_height); + // Set the bottom of the draggable bar no lower than the top of the bottom arrow. + const float bar_y = std::min((rect.position.y + arrow_size + (move_height - bar_size) * getValue() / range), rect.position.y + rect.size.y - arrow_size - bar_size); + + renderer.drawStretched(sp::Rect(rect.position.x, bar_y, rect.size.x, bar_size), front.texture, front.color); } bool GuiScrollbar::onMouseDown(sp::io::Pointer::Button button, glm::vec2 position, sp::io::Pointer::ID id) { - int range = (max_value - min_value); - float arrow_size = rect.size.x / 2.0f; - float move_height = (rect.size.y - arrow_size * 2); - float bar_size = move_height * value_size / range; - if (bar_size > move_height) - bar_size = move_height; - float bar_y = rect.position.y + arrow_size + move_height * getValue() / range; + float bar_y = rect.position.y + arrow_size + (move_height - bar_size) * getValue() / range; if (position.y >= bar_y && position.y <= bar_y + bar_size) { drag_scrollbar = true; @@ -56,19 +53,12 @@ void GuiScrollbar::onMouseDrag(glm::vec2 position, sp::io::Pointer::ID id) { if (drag_scrollbar) { - float arrow_size = rect.size.x / 2.0f; - int range = (max_value - min_value); - float move_height = (rect.size.y - arrow_size * 2); - float bar_size = move_height * value_size / range; - if (bar_size > move_height) - bar_size = move_height; - float target_y_offset = position.y - drag_select_offset - (rect.position.y + arrow_size); target_y_offset = std::max(target_y_offset, 0.0f); target_y_offset = std::min(target_y_offset, move_height - bar_size); if (bar_size < move_height) - setValue(int(target_y_offset / move_height * range + 0.5f)); + setValue(int(target_y_offset / (move_height - bar_size) * range + 0.5f)); } } @@ -76,19 +66,12 @@ void GuiScrollbar::onMouseUp(glm::vec2 position, sp::io::Pointer::ID id) { if (!drag_scrollbar) { - float arrow_size = rect.size.x / 2.0f; - int range = (max_value - min_value); - float move_height = (rect.size.y - arrow_size * 2); - float bar_size = move_height * value_size / range; - if (bar_size > move_height) - bar_size = move_height; - float target_y_offset = position.y - bar_size / 2.0f - (rect.position.y + arrow_size); target_y_offset = std::max(target_y_offset, 0.0f); target_y_offset = std::min(target_y_offset, move_height - bar_size); if (bar_size < move_height) - setValue(int(target_y_offset / move_height * range + 0.5f)); + setValue(int(target_y_offset / (move_height - bar_size) * range + 0.5f)); } } @@ -126,6 +109,7 @@ int GuiScrollbar::getValue() const value = max_value - value_size; if (value < min_value) value = min_value; + return value; } diff --git a/src/gui/gui2_scrollbar.h b/src/gui/gui2_scrollbar.h index 523033fe8f..87527fcd1c 100644 --- a/src/gui/gui2_scrollbar.h +++ b/src/gui/gui2_scrollbar.h @@ -20,6 +20,11 @@ class GuiScrollbar : public GuiElement bool drag_scrollbar; float drag_select_offset; + int range; + float arrow_size; + float move_height; + float bar_size; + const GuiThemeStyle* back_style; const GuiThemeStyle* front_style; public: