diff options
author | dec05eba <dec05eba@protonmail.com> | 2018-05-31 20:00:19 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2018-05-31 20:22:39 +0200 |
commit | 7913c19875cd407a1559da66a26906184dcd712b (patch) | |
tree | bff43faa87ce66a745b499f3f281add609f68ed6 /src/Scrollbar.cpp | |
parent | ee691432cc618474f12bac7976189cb4f91e2f63 (diff) |
Add scrollbar (currently only used in message board)
Diffstat (limited to 'src/Scrollbar.cpp')
-rw-r--r-- | src/Scrollbar.cpp | 84 |
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)); + } +} |