1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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));
}
}
|