#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)); } }