From 7a28cd4410ee68628b27206a580c700dd52f87fe Mon Sep 17 00:00:00 2001 From: oznogon Date: Sun, 12 Mar 2023 18:09:29 -0700 Subject: [PATCH 1/3] [GuiScrollbar] Move copy/paste updates to onDraw, persist values --- src/gui/gui2_scrollbar.cpp | 28 ++++------------------------ src/gui/gui2_scrollbar.h | 5 +++++ 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/src/gui/gui2_scrollbar.cpp b/src/gui/gui2_scrollbar.cpp index 77447861b2..2341c99867 100644 --- a/src/gui/gui2_scrollbar.cpp +++ b/src/gui/gui2_scrollbar.cpp @@ -24,10 +24,10 @@ 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; + range = max_value - min_value; + arrow_size = rect.size.x / 2.0f; + move_height = rect.size.y - arrow_size * 2; + 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); @@ -35,12 +35,6 @@ void GuiScrollbar::onDraw(sp::RenderTarget& renderer) 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; if (position.y >= bar_y && position.y <= bar_y + bar_size) { @@ -56,13 +50,6 @@ 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); @@ -76,13 +63,6 @@ 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); 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: From 494fd70b1a81553966d853faf678032a42745178 Mon Sep 17 00:00:00 2001 From: oznogon Date: Mon, 13 Mar 2023 00:57:19 -0700 Subject: [PATCH 2/3] [GuiScrollbar] Prevent draggable bar from dropping to below bottom arrow button --- src/gui/gui2_scrollbar.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/gui/gui2_scrollbar.cpp b/src/gui/gui2_scrollbar.cpp index 2341c99867..79dbd11b35 100644 --- a/src/gui/gui2_scrollbar.cpp +++ b/src/gui/gui2_scrollbar.cpp @@ -24,13 +24,16 @@ void GuiScrollbar::onDraw(sp::RenderTarget& renderer) renderer.drawStretched(rect, back.texture, back.color); + // Update the bar's range, size, and draggable bar size. range = max_value - min_value; arrow_size = rect.size.x / 2.0f; move_height = rect.size.y - arrow_size * 2; - 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); + // Clamp the size of the draggable bar to no less than 20px. + bar_size = std::clamp(move_height * value_size / range, 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 * 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) @@ -106,6 +109,7 @@ int GuiScrollbar::getValue() const value = max_value - value_size; if (value < min_value) value = min_value; + return value; } From b6909c4de5c920a235edf8858f13adcc84efcdb3 Mon Sep 17 00:00:00 2001 From: Chris Sibbitt Date: Thu, 12 Oct 2023 00:21:05 -0400 Subject: [PATCH 3/3] [GuiScrollbar] Enable full range on large lists * Problems with range calculations prevented access to full range in large lists * These adjustments allow drag-scrolling to the end without any slop * Tested on: ** Comms smaller than the window ** Comms larger than the window ** A log smaller than the window ** A log with 10,000 entries --- src/gui/gui2_scrollbar.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gui/gui2_scrollbar.cpp b/src/gui/gui2_scrollbar.cpp index 79dbd11b35..a28468d422 100644 --- a/src/gui/gui2_scrollbar.cpp +++ b/src/gui/gui2_scrollbar.cpp @@ -25,20 +25,20 @@ void GuiScrollbar::onDraw(sp::RenderTarget& renderer) renderer.drawStretched(rect, back.texture, back.color); // Update the bar's range, size, and draggable bar size. - range = max_value - min_value; + 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, 20.0F, move_height); + 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 * getValue() / range, rect.position.y + rect.size.y - arrow_size - bar_size); + 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) { - 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; @@ -58,7 +58,7 @@ void GuiScrollbar::onMouseDrag(glm::vec2 position, sp::io::Pointer::ID id) 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)); } } @@ -71,7 +71,7 @@ void GuiScrollbar::onMouseUp(glm::vec2 position, sp::io::Pointer::ID id) 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)); } }