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) --- include/MessageBoard.hpp | 4 ++- include/Scrollbar.hpp | 33 +++++++++++++++++++ src/MessageBoard.cpp | 12 ++++++- src/Scrollbar.cpp | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ src/UsersSidePanel.cpp | 4 +-- 5 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 include/Scrollbar.hpp create mode 100644 src/Scrollbar.cpp diff --git a/include/MessageBoard.hpp b/include/MessageBoard.hpp index acdaad4..fdde8c7 100644 --- a/include/MessageBoard.hpp +++ b/include/MessageBoard.hpp @@ -3,6 +3,7 @@ #include "Message.hpp" #include "types.hpp" #include "../include/Cache.hpp" +#include "../include/Scrollbar.hpp" #include #include #include @@ -42,8 +43,8 @@ namespace dchat odhtdb::MapHash messageIdMap; double scroll; double scrollSpeed; - sf::Clock frameTimer; double totalHeight; + sf::Clock frameTimer; bool scrollToBottom; sf::Vector2f backgroundSizeWithoutPadding; sf::Vector2f backgroundSize; @@ -51,5 +52,6 @@ namespace dchat std::mutex messageProcessMutex; usize visibleMessageStartIndex; usize visibleMessageEndIndex; + Scrollbar scrollbar; }; } diff --git a/include/Scrollbar.hpp b/include/Scrollbar.hpp new file mode 100644 index 0000000..7cf625b --- /dev/null +++ b/include/Scrollbar.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include + +namespace dchat +{ + class Scrollbar + { + public: + Scrollbar(); + + void draw(sf::RenderWindow &window); + + float getScrollingForContent() const; + + float width; + double maxHeight; + double scroll; + double maxScroll; + double scrollRelative; + sf::Vector2f position; + + sf::Color backgroundColor; + sf::Color scrollColor; + private: + float height; + bool grabbing; + bool followMouse; + sf::Vector2f grabOffset; + }; +} 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 +#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)); + } +} 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