From 7913c19875cd407a1559da66a26906184dcd712b Mon Sep 17 00:00:00 2001 From: dec05eba Date: Thu, 31 May 2018 20:00:19 +0200 Subject: Add scrollbar (currently only used in message board) --- src/Scrollbar.cpp | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/Scrollbar.cpp (limited to 'src/Scrollbar.cpp') 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 +#include +#include + +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)); + } +} -- cgit v1.2.3