From 7913c19875cd407a1559da66a26906184dcd712b Mon Sep 17 00:00:00 2001
From: dec05eba <dec05eba@protonmail.com>
Date: Thu, 31 May 2018 20:00:19 +0200
Subject: Add scrollbar (currently only used in message board)

---
 src/MessageBoard.cpp   | 12 +++++++-
 src/Scrollbar.cpp      | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/UsersSidePanel.cpp |  4 +--
 3 files changed, 97 insertions(+), 3 deletions(-)
 create mode 100644 src/Scrollbar.cpp

(limited to 'src')

diff --git a/src/MessageBoard.cpp b/src/MessageBoard.cpp
index 74afab8..6ed4378 100644
--- a/src/MessageBoard.cpp
+++ b/src/MessageBoard.cpp
@@ -51,7 +51,8 @@ namespace dchat
         visibleMessageStartIndex(-1),
         visibleMessageEndIndex(-1)
     {
-        
+        scrollbar.backgroundColor = sf::Color(51, 54, 59);
+        scrollbar.scrollColor = sf::Color(45, 47, 52);
     }
     
     MessageBoard::~MessageBoard()
@@ -434,6 +435,15 @@ namespace dchat
                 scroll = 0.0;
         }
         
+        scrollbar.scroll = abs(scroll);
+        scrollbar.maxScroll = totalHeight;
+        scrollbar.width = 15.0f * Settings::getScaling();
+        scrollbar.maxHeight = (float)backgroundSize.y;
+        scrollbar.position.x = windowSize.x - UsersSidePanel::getWidth() - scrollbar.width;
+        scrollbar.position.y = backgroundPos.y;
+        scrollbar.draw(window);
+        scroll = scrollbar.getScrollingForContent();
+        
         //staticContentTexture.display();
         dirty = false;
         
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));
+    }
+}
diff --git a/src/UsersSidePanel.cpp b/src/UsersSidePanel.cpp
index bea11e5..687b976 100644
--- a/src/UsersSidePanel.cpp
+++ b/src/UsersSidePanel.cpp
@@ -73,9 +73,9 @@ namespace dchat
         float posY = ChannelTopPanel::getHeight();
         auto windowSize = window.getSize();
         sf::RectangleShape rect(sf::Vector2f(getWidth(), windowSize.y - ChannelTopPanel::getHeight()));
-        rect.setFillColor(ColorScheme::getPanelColor());
+        rect.setFillColor(ColorScheme::getBackgroundColor());
         rect.setPosition(windowSize.x - getWidth(), posY);
-        //window.draw(rect);
+        window.draw(rect); // TODO: Remove this?
         
         Channel *currentChannel = Channel::getCurrent();
         if(!currentChannel) return;
-- 
cgit v1.2.3-70-g09d2