aboutsummaryrefslogtreecommitdiff
path: root/src/Scrollbar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Scrollbar.cpp')
-rw-r--r--src/Scrollbar.cpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/Scrollbar.cpp b/src/Scrollbar.cpp
new file mode 100644
index 0000000..c1a06b2
--- /dev/null
+++ b/src/Scrollbar.cpp
@@ -0,0 +1,84 @@
+#include "../include/Scrollbar.hpp"
+#include <SFML/Graphics/RectangleShape.hpp>
+#include <SFML/Window/Mouse.hpp>
+#include <cmath>
+
+namespace dchat
+{
+ const float MIN_HEIGHT = 30.0f;
+
+ Scrollbar::Scrollbar() :
+ width(0.0f),
+ maxHeight(0.0),
+ scroll(0.0),
+ maxScroll(0.0),
+ scrollRelative(0.0),
+ grabbing(false),
+ followMouse(false)
+ {
+
+ }
+
+ // TODO: Add scroll by clicking on scrollbar background and smoothly move scrollbar to mouse
+ void Scrollbar::draw(sf::RenderWindow &window)
+ {
+ sf::RectangleShape backgroundRect(sf::Vector2f(floor(width), floor(maxHeight)));
+ backgroundRect.setPosition(floor(position.x), floor(position.y));
+ backgroundRect.setFillColor(backgroundColor);
+ window.draw(backgroundRect);
+
+ float minHeight = fmin(MIN_HEIGHT, maxHeight);
+ float scrollHeight = maxHeight * (maxHeight / maxScroll);
+ if(scrollHeight >= maxHeight)
+ return;
+ scrollHeight = floor(std::max(scrollHeight, minHeight));
+
+ scrollRelative = scroll / (maxScroll - maxHeight);
+ float possibleScrollRange = maxHeight - scrollHeight;
+ sf::Vector2f scrollSize(floor(width), scrollHeight);
+ sf::Vector2f scrollPosition(floor(position.x), floor(position.y + scrollRelative * possibleScrollRange));
+ sf::RectangleShape scrollRect(scrollSize);
+
+ bool grabbingThisFrame = false;
+ if(sf::Mouse::isButtonPressed(sf::Mouse::Button::Left))
+ {
+ if(!grabbing)
+ grabbingThisFrame = true;
+ grabbing = true;
+ }
+ else
+ {
+ grabbing = false;
+ followMouse = false;
+ }
+
+ auto mousePos = sf::Mouse::getPosition(window);
+ if(followMouse)
+ {
+ float grabOffsetTopY = scrollSize.y * 0.5f + grabOffset.y;
+ scrollPosition.y = fmax(mousePos.y - grabOffsetTopY, position.y);
+ scrollPosition.y = fmin(scrollPosition.y, position.y + maxHeight - scrollHeight);
+ scrollPosition.y = floor(scrollPosition.y);
+ scrollRelative = (scrollPosition.y - position.y) / possibleScrollRange;
+ }
+
+ scrollRect.setPosition(scrollPosition);
+ scrollRect.setFillColor(scrollColor);
+ window.draw(scrollRect);
+
+ if(!grabbingThisFrame) return;
+
+ sf::Vector2f scrollbarCenter(scrollPosition.x + scrollSize.x * 0.5f, scrollPosition.y + scrollSize.y * 0.5f);
+ sf::Vector2f mouseScrollbarOffset(mousePos.x - scrollbarCenter.x, mousePos.y - scrollbarCenter.y);
+ if(fabs(mouseScrollbarOffset.x) <= scrollSize.x * 0.5f && fabs(mouseScrollbarOffset.y) <= scrollSize.y * 0.5f)
+ {
+ grabOffset = mouseScrollbarOffset;
+ followMouse = true;
+ }
+ }
+
+ float Scrollbar::getScrollingForContent() const
+ {
+ return -(scrollRelative * (maxScroll - maxHeight));
+ }
+}