aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/Channel.hpp2
-rw-r--r--include/Gif.hpp2
-rw-r--r--include/ResourceCache.hpp3
-rw-r--r--include/Text.hpp2
-rw-r--r--include/User.hpp1
-rw-r--r--shaders/circleMask.glsl10
-rw-r--r--src/Channel.cpp24
-rw-r--r--src/ChannelSidePanel.cpp7
-rw-r--r--src/ChannelTopPanel.cpp14
-rw-r--r--src/ColorScheme.cpp6
-rw-r--r--src/Gif.cpp4
-rw-r--r--src/MessageBoard.cpp108
-rw-r--r--src/ResourceCache.cpp20
-rw-r--r--src/Text.cpp37
-rw-r--r--src/UsersSidePanel.cpp13
15 files changed, 182 insertions, 71 deletions
diff --git a/include/Channel.hpp b/include/Channel.hpp
index 17128fd..1acfcd1 100644
--- a/include/Channel.hpp
+++ b/include/Channel.hpp
@@ -40,7 +40,7 @@ namespace dchat
OnlineUser* getUserByPublicKey(const odhtdb::Signature::PublicKey &publicKey);
const odhtdb::DatabaseNode& getNodeInfo() const;
- // If timestamp is 0, then timestamp is not used
+ // If timestamp is 0, then current time is used
void addLocalMessage(const std::string &msg, User *owner, u64 timestampSeconds = 0);
void addMessage(const std::string &msg);
void addUserLocally(User *user);
diff --git a/include/Gif.hpp b/include/Gif.hpp
index 84299e9..8f5d4e7 100644
--- a/include/Gif.hpp
+++ b/include/Gif.hpp
@@ -32,7 +32,7 @@ namespace dchat
void setPosition(const sf::Vector2f &position);
void setScale(const sf::Vector2f &scale);
- void draw(sf::RenderTarget &target);
+ void draw(sf::RenderTarget &target, const sf::RenderStates &renderStates = sf::RenderStates::Default);
static bool isDataGif(const StringView &data);
private:
diff --git a/include/ResourceCache.hpp b/include/ResourceCache.hpp
index de35500..75ebd88 100644
--- a/include/ResourceCache.hpp
+++ b/include/ResourceCache.hpp
@@ -2,6 +2,7 @@
#include <SFML/Graphics/Font.hpp>
#include <SFML/Graphics/Texture.hpp>
+#include <SFML/Graphics/Shader.hpp>
#include <string>
#include <stdexcept>
@@ -21,5 +22,7 @@ namespace dchat
// Throws FailedToLoadResourceException on failure
static sf::Texture* getTexture(const std::string &filepath);
+
+ static sf::Shader* getShader(const std::string &filepath, sf::Shader::Type shaderType);
};
}
diff --git a/include/Text.hpp b/include/Text.hpp
index 9df973d..0bc3ced 100644
--- a/include/Text.hpp
+++ b/include/Text.hpp
@@ -87,7 +87,7 @@ namespace dchat
bool plainText;
bool editable;
CaretMoveDirection caretMoveDirection;
- float totalHeight;
+ sf::FloatRect boundingBox;
float lineSpacing;
std::vector<TextElement> textElements;
diff --git a/include/User.hpp b/include/User.hpp
index 821be6f..a83b9dc 100644
--- a/include/User.hpp
+++ b/include/User.hpp
@@ -24,6 +24,7 @@ namespace dchat
virtual const std::string& getName() const = 0;
const Type type;
+ std::string avatarUrl;
};
class OnlineUser : public User
diff --git a/shaders/circleMask.glsl b/shaders/circleMask.glsl
new file mode 100644
index 0000000..7595ea9
--- /dev/null
+++ b/shaders/circleMask.glsl
@@ -0,0 +1,10 @@
+uniform sampler2D texture;
+
+void main()
+{
+ vec4 pixel = texture2D(texture, gl_TexCoord[0].xy);
+ vec2 pixelOffset = gl_TexCoord[0].xy - vec2(0.5, 0.5);
+ float dist = sqrt(dot(pixelOffset, pixelOffset));
+ dist = smoothstep(0.47, 0.5, dist);
+ gl_FragColor = gl_Color * pixel * vec4(1.0, 1.0, 1.0, 1.0 - dist);
+}
diff --git a/src/Channel.cpp b/src/Channel.cpp
index 2bd1b0b..185c544 100644
--- a/src/Channel.cpp
+++ b/src/Channel.cpp
@@ -19,21 +19,11 @@ namespace dchat
localUser(_localUser ? _localUser : new OfflineUser("You"))
{
addUserLocally(localUser);
- {
- Message *message = new Message(&systemUser, u8"[emoji](https://discordemoji.com/assets/emoji/PepeDab.gif) deaf [emoji](https://discordemoji.com/assets/emoji/COGGERS.gif)");
- messageBoard.addMessage(message);
- }
-
- {
- Message *message = new Message(&systemUser, u8"[emoji](https://discordemoji.com/assets/emoji/PepeDab.gif)[emoji](https://discordemoji.com/assets/emoji/COGGERS.gif)");
- messageBoard.addMessage(message);
- }
-
- {
- Message *message = new Message(&systemUser, u8"pepedab https://discordemoji.com/assets/emoji/PepeDab.gif coggers https://discordemoji.com/assets/emoji/COGGERS.gif check out this url http://www.grandtournation.com/6808/start-date-of-the-grand-tour-season-3-confirmed-mark-your-calendars/ owo");
- message->text.setEditable(true);
- messageBoard.addMessage(message);
- }
+ localUser->avatarUrl = "https://archive.lainchan.jp/diy/thumb/1445879602710.png";
+
+ addLocalMessage(u8"[emoji](https://discordemoji.com/assets/emoji/PepeDab.gif) deaf [emoji](https://discordemoji.com/assets/emoji/COGGERS.gif)", &systemUser);
+ addLocalMessage(u8"[emoji](https://discordemoji.com/assets/emoji/PepeDab.gif)[emoji](https://discordemoji.com/assets/emoji/COGGERS.gif)", &systemUser);
+ addLocalMessage(u8"pepedab https://discordemoji.com/assets/emoji/PepeDab.gif coggers https://discordemoji.com/assets/emoji/COGGERS.gif check out this url http://www.grandtournation.com/6808/start-date-of-the-grand-tour-season-3-confirmed-mark-your-calendars/ owo", &systemUser);
if(database)
database->seed(databaseNodeInfo);
@@ -91,6 +81,10 @@ namespace dchat
void Channel::addLocalMessage(const std::string &msg, User *owner, u64 timestampSeconds)
{
assert(owner);
+ if(timestampSeconds == 0)
+ {
+ timestampSeconds = time(NULL);
+ }
messageBoard.addMessage(new Message(owner, msg, timestampSeconds));
}
diff --git a/src/ChannelSidePanel.cpp b/src/ChannelSidePanel.cpp
index 89a550a..58cb9bc 100644
--- a/src/ChannelSidePanel.cpp
+++ b/src/ChannelSidePanel.cpp
@@ -33,11 +33,10 @@ namespace dchat
{
float posY = ChannelTopPanel::getHeight();
auto windowSize = window.getSize();
- sf::RectangleShape rect(sf::Vector2f(getWidth(), windowSize.y - ChannelTopPanel::getHeight()));
- rect.setPosition(0.0f, posY);
+ sf::RectangleShape rect(sf::Vector2f(getWidth(), windowSize.y));
+ rect.setPosition(0.0f, 0.0f);
rect.setFillColor(ColorScheme::getPanelColor());
window.draw(rect);
- //posY += 10.0f;
const sf::Font *font = ResourceCache::getFont("fonts/Roboto-Regular.ttf");
const float fontSize = FONT_SIZE * Settings::getScaling();
@@ -49,7 +48,7 @@ namespace dchat
{
if(channel == Channel::getCurrent())
{
- rect.setFillColor(ColorScheme::getPanelColor() + sf::Color(15, 15, 15));
+ rect.setFillColor(ColorScheme::getBackgroundColor() + sf::Color(15, 15, 15));
rect.setSize(sf::Vector2f(getWidth(), channelBoxHeight));
rect.setPosition(sf::Vector2f(0.0f, position.y));
window.draw(rect);
diff --git a/src/ChannelTopPanel.cpp b/src/ChannelTopPanel.cpp
index d597353..1781e74 100644
--- a/src/ChannelTopPanel.cpp
+++ b/src/ChannelTopPanel.cpp
@@ -3,6 +3,8 @@
#include "../include/ResourceCache.hpp"
#include "../include/Channel.hpp"
#include "../include/ColorScheme.hpp"
+#include "../include/ChannelSidePanel.hpp"
+#include "../include/UsersSidePanel.hpp"
#include <SFML/Graphics/RectangleShape.hpp>
#include <cmath>
@@ -17,6 +19,7 @@ namespace dchat
const float BOTTOM_LINE_HEIGHT = 2.0f;
const float PADDING_TOP = 20.0f;
const float PADDING_BOTTOM = PADDING_TOP;
+ const float PADDING_SIDE = 20.0f;
static void drawGradientLine(const sf::Vector2f &position, const sf::Vector2f &size, const LineColor &color, sf::RenderWindow &window)
{
@@ -37,16 +40,17 @@ namespace dchat
void ChannelTopPanel::draw(sf::RenderWindow &window)
{
- const sf::Color lineSideColor = ColorScheme::getBackgroundColor();
+ const sf::Color lineSideColor = ColorScheme::getBackgroundColor() + sf::Color(20, 0, 0);
const sf::Color lineCenterColor = lineSideColor + sf::Color(40, 0, 0);
auto windowSize = window.getSize();
- sf::RectangleShape rect(sf::Vector2f(windowSize.x, getHeight() - BOTTOM_LINE_HEIGHT));
+ sf::RectangleShape rect(sf::Vector2f(floor(windowSize.x - ChannelSidePanel::getWidth() - UsersSidePanel::getWidth()), getHeight() - BOTTOM_LINE_HEIGHT));
+ rect.setPosition(ChannelSidePanel::getWidth(), 0.0f);
rect.setFillColor(ColorScheme::getBackgroundColor());
window.draw(rect);
- sf::Vector2f bottomLinePos(0.0f, getHeight() - BOTTOM_LINE_HEIGHT);
- sf::Vector2f bottomLineSize(windowSize.x, BOTTOM_LINE_HEIGHT);
+ sf::Vector2f bottomLinePos(floor(ChannelSidePanel::getWidth() + PADDING_SIDE * Settings::getScaling()), getHeight() - BOTTOM_LINE_HEIGHT);
+ sf::Vector2f bottomLineSize(floor(windowSize.x - ChannelSidePanel::getWidth() - UsersSidePanel::getWidth() - PADDING_SIDE * Settings::getScaling() * 2.0f), BOTTOM_LINE_HEIGHT);
LineColor lineColor
{
@@ -63,7 +67,7 @@ namespace dchat
float fontSize = FONT_SIZE * Settings::getScaling();
sf::Text text(str, *ResourceCache::getFont("fonts/Roboto-Regular.ttf"), fontSize);
auto textBounds = text.getLocalBounds();
- text.setPosition(floor((float)windowSize.x * 0.5f - textBounds.width * 0.5f), PADDING_TOP);
+ text.setPosition(floor(ChannelSidePanel::getWidth() + PADDING_SIDE * Settings::getScaling()), PADDING_TOP);
text.setFillColor(ColorScheme::getTextRegularColor());
window.draw(text);
}
diff --git a/src/ColorScheme.cpp b/src/ColorScheme.cpp
index e2138c3..09dde51 100644
--- a/src/ColorScheme.cpp
+++ b/src/ColorScheme.cpp
@@ -14,7 +14,7 @@ namespace dchat
colorSchemeType = type;
}
- sf::Color ColorScheme::getBackgroundColor(){ return sf::Color(40, 40, 40); }
- sf::Color ColorScheme::getPanelColor() { return sf::Color(35, 35, 35); }
- sf::Color ColorScheme::getTextRegularColor() { return sf::Color(240, 240, 240); }
+ sf::Color ColorScheme::getBackgroundColor(){ return sf::Color(54,57,62); }
+ sf::Color ColorScheme::getPanelColor() { return sf::Color(47,49,54); }
+ sf::Color ColorScheme::getTextRegularColor() { return sf::Color(255, 255, 255); }
}
diff --git a/src/Gif.cpp b/src/Gif.cpp
index c79153c..69c0be8 100644
--- a/src/Gif.cpp
+++ b/src/Gif.cpp
@@ -149,7 +149,7 @@ namespace dchat
sprite.setScale(scale);
}
- void Gif::draw(sf::RenderTarget &target)
+ void Gif::draw(sf::RenderTarget &target, const sf::RenderStates &renderState)
{
double timeElapsedMilli = (double)frameTimer.getElapsedTime().asMilliseconds();
// If gif is not redrawn for a while, then we reset timer (gif is paused). This happens when gif is not visible and then appears visible
@@ -196,7 +196,7 @@ namespace dchat
texture.generateMipmap();
sprite.setTexture(texture, true);
}
- target.draw(sprite);
+ target.draw(sprite, renderState);
}
bool Gif::isDataGif(const StringView &data)
diff --git a/src/MessageBoard.cpp b/src/MessageBoard.cpp
index d73dc84..8572873 100644
--- a/src/MessageBoard.cpp
+++ b/src/MessageBoard.cpp
@@ -8,6 +8,7 @@
#include "../include/Chatbar.hpp"
#include "../include/ColorScheme.hpp"
#include "../include/Theme.hpp"
+#include <SFML/Graphics/CircleShape.hpp>
#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Graphics/Sprite.hpp>
#include <SFML/Window/Mouse.hpp>
@@ -30,7 +31,9 @@ namespace dchat
const float PADDING_TOP = 0.0f;
const float LINE_SIDE_PADDING = 20.0f;
const float LINE_HEIGHT = 1.0f;
- const float USERNAME_TIMESTAMP_SIDE_PADDING = 10.0f;
+ const float USERNAME_TIMESTAMP_SIDE_PADDING = 15.0f;
+ const float AVATAR_DIAMETER = 70.0f;
+ const float AVATAR_PADDING_SIDE = 30.0f;
const double SCROLL_MAX_SPEED = 20.0;
MessageBoard::MessageBoard(const sf::Vector2u &size) :
@@ -77,7 +80,7 @@ namespace dchat
const float usernameTextHeight = usernameFont->getLineSpacing(usernameTextCharacterSize);
const sf::Font *timestampFont = ResourceCache::getFont("fonts/Roboto-Regular.ttf");
- const int timestampTextCharacterSize = 15 * Settings::getScaling();
+ const int timestampTextCharacterSize = (float)usernameTextCharacterSize * 0.75f;
const float timestampTextHeight = timestampFont->getLineSpacing(timestampTextCharacterSize);
sf::RectangleShape lineRect(sf::Vector2f(backgroundSizeWithoutPadding.x - LINE_SIDE_PADDING * Settings::getScaling() * 2.0f, LINE_HEIGHT));
@@ -90,45 +93,94 @@ namespace dchat
for(usize i = 0; i < numMessages; ++i)
{
Message *message = messages[i];
- position.y += (MESSAGE_PADDING_TOP * Settings::getScaling());
- if(position.y + usernameTextHeight > 0.0f && position.y < backgroundPos.y + backgroundSize.y)
+
+ bool mergeTextWithPrev = false;
+ if(i > 0)
{
- sf::Text usernameText(sf::String::fromUtf8(message->user->getName().begin(), message->user->getName().end()), *usernameFont, usernameTextCharacterSize);
- usernameText.setFillColor(sf::Color(15, 192, 252));
- usernameText.setPosition(sf::Vector2f(floor(position.x), floor(position.y)));
- window.draw(usernameText);
+ Message *prevMessage = messages[i - 1];
+ mergeTextWithPrev = prevMessage->user == message->user && (message->timestampSeconds == 0 || message->timestampSeconds - prevMessage->timestampSeconds);
+ }
+ mergeTextWithPrev = false;
+
+ if(!mergeTextWithPrev)
+ {
+ position.y += (MESSAGE_PADDING_TOP * Settings::getScaling());
+ if(position.y + usernameTextHeight > 0.0f && position.y < backgroundPos.y + backgroundSize.y)
+ {
+ sf::Text usernameText(sf::String::fromUtf8(message->user->getName().begin(), message->user->getName().end()), *usernameFont, usernameTextCharacterSize);
+ usernameText.setFillColor(sf::Color(15, 192, 252));
+ usernameText.setPosition(sf::Vector2f(floor(position.x + (AVATAR_DIAMETER + AVATAR_PADDING_SIDE) * Settings::getScaling()), floor(position.y)));
+ window.draw(usernameText);
+
+ if(message->timestampSeconds)
+ {
+ time_t time = (time_t)message->timestampSeconds;
+ struct tm *localTimePtr = localtime(&time);
+ char date[30];
+ strftime(date, sizeof(date), "%Y-%m-%d at %T", localTimePtr);
+
+ sf::Text timestamp(date, *timestampFont, timestampTextCharacterSize);
+ timestamp.setFillColor(ColorScheme::getTextRegularColor() * sf::Color(255, 255, 255, 50));
+ timestamp.setPosition(sf::Vector2f(floor(position.x + (AVATAR_DIAMETER + AVATAR_PADDING_SIDE) * Settings::getScaling() + usernameText.getLocalBounds().width + USERNAME_TIMESTAMP_SIDE_PADDING * Settings::getScaling()), floor(position.y + 2.0f * Settings::getScaling() + usernameTextHeight * 0.5f - timestampTextHeight * 0.5f)));
+ window.draw(timestamp);
+ }
+ }
- if(message->timestampSeconds)
+ const ContentByUrlResult avatarResult = cache.getContentByUrl(message->user->avatarUrl);
+ if(avatarResult.type == ContentByUrlResult::Type::CACHED)
{
- time_t time = (time_t)message->timestampSeconds;
- struct tm *localTimePtr = localtime(&time);
- char date[30];
- strftime(date, sizeof(date), "%Y-%m-%d at %T", localTimePtr);
+ sf::Shader *circleShader = ResourceCache::getShader("shaders/circleMask.glsl", sf::Shader::Fragment);
+ circleShader->setUniform("texture", sf::Shader::CurrentTexture);
- sf::Text timestamp(date, *timestampFont, timestampTextCharacterSize);
- timestamp.setFillColor(ColorScheme::getTextRegularColor() * sf::Color(255, 255, 255, 30));
- timestamp.setPosition(sf::Vector2f(floor(position.x + usernameText.getLocalBounds().width + USERNAME_TIMESTAMP_SIDE_PADDING * Settings::getScaling()), floor(position.y + 2.0f * Settings::getScaling() + usernameTextHeight * 0.5f - timestampTextHeight * 0.5f)));
- window.draw(timestamp);
+ if(avatarResult.cachedType == ContentByUrlResult::CachedType::TEXTURE)
+ {
+ // TODO: Store this sprite somewhere, might not be efficient to create a new sprite object every frame
+ sf::Sprite sprite(*avatarResult.texture);
+ auto textureSize = avatarResult.texture->getSize();
+ sprite.setPosition(sf::Vector2f(floor(position.x), floor(position.y)));
+ sprite.setScale(sf::Vector2f(AVATAR_DIAMETER * Settings::getScaling() / (float)textureSize.x, AVATAR_DIAMETER * Settings::getScaling() / (float)textureSize.y));
+ window.draw(sprite, circleShader);
+ }
+ else if(avatarResult.cachedType == ContentByUrlResult::CachedType::GIF)
+ {
+ auto gifSize = avatarResult.gif->getSize();
+ avatarResult.gif->setPosition(sf::Vector2f(floor(position.x), floor(position.y)));
+ avatarResult.gif->setScale(sf::Vector2f(AVATAR_DIAMETER * Settings::getScaling() / (float)gifSize.x, AVATAR_DIAMETER * Settings::getScaling() / (float)gifSize.y));
+ avatarResult.gif->draw(window, circleShader);
+ }
+ }
+ else
+ {
+ sf::CircleShape avatarCircle(AVATAR_DIAMETER * 0.5f * Settings::getScaling(), 60 * Settings::getScaling());
+ avatarCircle.setPosition(sf::Vector2f(floor(position.x), floor(position.y)));
+ window.draw(avatarCircle);
}
+
+ position.y += usernameTextHeight + USERNAME_PADDING_BOTTOM * Settings::getScaling();
}
- position.y += usernameTextHeight + USERNAME_PADDING_BOTTOM * Settings::getScaling();
// No need to perform culling here, that is done in @Text draw function
message->text.setCharacterSize(18 * Settings::getScaling());
- message->text.setMaxWidth(backgroundSize.x);
- message->text.setPosition(sf::Vector2f(floor(position.x), floor(position.y)));
+ message->text.setMaxWidth(backgroundSize.x - (AVATAR_DIAMETER + AVATAR_PADDING_SIDE) * Settings::getScaling());
+ message->text.setPosition(sf::Vector2f(floor(position.x + (AVATAR_DIAMETER + AVATAR_PADDING_SIDE) * Settings::getScaling()), floor(position.y)));
message->text.setLineSpacing(LINE_SPACING);
message->text.draw(window, cache);
- position.y += (message->text.getHeight() + MESSAGE_PADDING_BOTTOM * Settings::getScaling());
-
- if(position.y + LINE_HEIGHT > 0.0f && position.y < backgroundPos.y + backgroundSize.y && i + 1 != numMessages)
+ position.y += message->text.getHeight();
+ if(!mergeTextWithPrev)
{
- lineRect.setPosition(sf::Vector2f(position.x + LINE_SIDE_PADDING * Settings::getScaling() - PADDING_SIDE * Settings::getScaling(), floor(position.y)));
- window.draw(lineRect);
- //drawGradientLine(sf::Vector2f(position.x + LINE_SIDE_PADDING, floor(position.y)), sf::Vector2f(backgroundSizeWithoutPadding.x - LINE_SIDE_PADDING * 2.0f, LINE_HEIGHT), LINE_COLOR, window);
- }
+ position.y += (MESSAGE_PADDING_BOTTOM * Settings::getScaling());
- position.y += LINE_HEIGHT;
+ if(position.y + LINE_HEIGHT > 0.0f && position.y < backgroundPos.y + backgroundSize.y && i + 1 != numMessages)
+ {
+ lineRect.setPosition(sf::Vector2f(position.x + LINE_SIDE_PADDING * Settings::getScaling() - PADDING_SIDE * Settings::getScaling(), floor(position.y)));
+ window.draw(lineRect);
+ //drawGradientLine(sf::Vector2f(position.x + LINE_SIDE_PADDING, floor(position.y)), sf::Vector2f(backgroundSizeWithoutPadding.x - LINE_SIDE_PADDING * 2.0f, LINE_HEIGHT), LINE_COLOR, window);
+ }
+
+ position.y += LINE_HEIGHT;
+ }
+ else
+ position.y += LINE_SPACING;
}
totalHeight = (position.y - scroll) - startHeight;
}
diff --git a/src/ResourceCache.cpp b/src/ResourceCache.cpp
index 3f73189..4664bf0 100644
--- a/src/ResourceCache.cpp
+++ b/src/ResourceCache.cpp
@@ -7,6 +7,7 @@ namespace dchat
{
unordered_map<string, sf::Font*> fonts;
unordered_map<string, sf::Texture*> textures;
+ unordered_map<string, sf::Shader*> shaders;
const sf::Font* ResourceCache::getFont(const string &filepath)
{
@@ -47,4 +48,23 @@ namespace dchat
textures[filepath] = texture;
return texture;
}
+
+ sf::Shader* ResourceCache::getShader(const std::string &filepath, sf::Shader::Type shaderType)
+ {
+ auto it = shaders.find(filepath);
+ if(it != shaders.end())
+ return it->second;
+
+ sf::Shader *shader = new sf::Shader();
+ if(!shader->loadFromFile(filepath, shaderType))
+ {
+ delete shader;
+ string errMsg = "Failed to load shader: ";
+ errMsg += filepath;
+ throw FailedToLoadResourceException(errMsg);
+ }
+
+ shaders[filepath] = shader;
+ return shader;
+ }
}
diff --git a/src/Text.cpp b/src/Text.cpp
index be147db..9ea4847 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -2,6 +2,7 @@
#include "../include/Cache.hpp"
#include "../include/Gif.hpp"
#include "../include/WebPagePreview.hpp"
+#include "../include/ColorScheme.hpp"
#include <SFML/Graphics/RectangleShape.hpp>
#include <cmath>
@@ -27,7 +28,6 @@ namespace dchat
plainText(false),
editable(false),
caretMoveDirection(CaretMoveDirection::NONE),
- totalHeight(0.0f),
caretIndex(0)
{
@@ -46,7 +46,6 @@ namespace dchat
plainText(_plainText),
editable(false),
caretMoveDirection(CaretMoveDirection::NONE),
- totalHeight(0.0f),
lineSpacing(0.0f),
caretIndex(0)
{
@@ -126,7 +125,7 @@ namespace dchat
float Text::getHeight() const
{
- return totalHeight;
+ return boundingBox.height;
}
size_t stringSplitUrl(const StringViewUtf32 textElementStr, const sf::String &urlStr, size_t offset, std::vector<TextElement> &newTextElements)
@@ -282,6 +281,8 @@ namespace dchat
float hspace = font->getGlyph(' ', characterSize, false).advance;
float vspace = font->getLineSpacing(characterSize);
+ boundingBox = sf::FloatRect();
+
sf::Vector2f glyphPos;
sf::Uint32 prevCodePoint = 0;
size_t lastSpacingWordWrapIndex = -1;
@@ -335,6 +336,7 @@ namespace dchat
glyphPos.y += vspace + lineSpacing;
}
+ boundingBox.width = std::max(boundingBox.width, glyphPos.x);
continue;
}
@@ -451,7 +453,14 @@ namespace dchat
glyphPos.y += floor(vspace * IMAGE_HEIGHT_SCALE) + lineSpacing;
}
}
- totalHeight = glyphPos.y + vspace + lineSpacing;
+
+ boundingBox.height = glyphPos.y + vspace + lineSpacing;
+ usize numVertices = vertices.getVertexCount();
+ for(usize i = 0; i < numVertices; i += 4)
+ {
+ const sf::Vertex &bottomRight = vertices[i + 2];
+ boundingBox.width = std::max(boundingBox.width, bottomRight.position.x);
+ }
}
void Text::updateCaret()
@@ -616,7 +625,9 @@ namespace dchat
void Text::processEvent(const sf::Event &event)
{
- if(!editable) return;
+ if(!editable || textElements.size() == 0) return;
+
+ bool caretAtEnd = textElements[0].text.size == 0 || caretIndex == textElements[0].text.size;
if(event.type == sf::Event::KeyPressed)
{
@@ -625,7 +636,7 @@ namespace dchat
--caretIndex;
dirtyCaret = true;
}
- else if(event.key.code == sf::Keyboard::Right && !isCaretAtEnd())
+ else if(event.key.code == sf::Keyboard::Right && !caretAtEnd)
{
++caretIndex;
dirtyCaret = true;
@@ -638,7 +649,7 @@ namespace dchat
--caretIndex;
dirtyCaret = true;
}
- else if(event.key.code == sf::Keyboard::Delete && !isCaretAtEnd())
+ else if(event.key.code == sf::Keyboard::Delete && !caretAtEnd)
{
auto strBefore = str.substring(0, caretIndex);
auto strAfter = str.substring(caretIndex + 1);
@@ -666,7 +677,7 @@ namespace dchat
if(event.text.unicode == 8 || event.text.unicode == 127) // backspace, del
return;
- if(isCaretAtEnd())
+ if(caretAtEnd)
str += event.text.unicode;
else
{
@@ -715,7 +726,15 @@ namespace dchat
//sf::FloatRect textRect(pos.x, pos.y, maxWidth, )
//colRect.contains()
//if(pos.x + maxWidth <= 0.0f || pos.x >= maxWidth || pos.y + totalHeight <= 0.0f || pos.y >= target.getSize().y) return;
- if(pos.y + totalHeight <= 0.0f || pos.y >= target.getSize().y) return;
+ if(pos.y + getHeight() <= 0.0f || pos.y >= target.getSize().y) return;
+
+ if(editable)
+ {
+ sf::RectangleShape editBox(sf::Vector2f(std::max(maxWidth, boundingBox.width), boundingBox.height));
+ editBox.setPosition(pos.x, pos.y - floor(vspace));
+ editBox.setFillColor(ColorScheme::getBackgroundColor() + sf::Color(10, 10, 10));
+ target.draw(editBox);
+ }
states.transform.translate(pos);
states.texture = &font->getTexture(characterSize);
diff --git a/src/UsersSidePanel.cpp b/src/UsersSidePanel.cpp
index 9c04062..672dffa 100644
--- a/src/UsersSidePanel.cpp
+++ b/src/UsersSidePanel.cpp
@@ -23,14 +23,23 @@ namespace dchat
sf::RectangleShape rect(sf::Vector2f(getWidth(), windowSize.y - ChannelTopPanel::getHeight()));
rect.setFillColor(ColorScheme::getPanelColor());
rect.setPosition(windowSize.x - getWidth(), posY);
- window.draw(rect);
- posY += 10.0f;
+ //window.draw(rect);
Channel *currentChannel = Channel::getCurrent();
if(!currentChannel) return;
const sf::Font *font = ResourceCache::getFont("fonts/Roboto-Regular.ttf");
sf::Vector2f position(rect.getPosition().x + 10.0f, posY);
+
+ // TODO: Remove this shit
+ sf::String str = "Online - ";
+ str += to_string(currentChannel->getUsers().size());
+ sf::Text text(str, *font, FONT_SIZE * Settings::getScaling() * 1.25f);
+ text.setPosition(position);
+ text.setFillColor(ColorScheme::getTextRegularColor());
+ window.draw(text);
+ position.y += floor(font->getLineSpacing(text.getCharacterSize()));
+
for(User *user : currentChannel->getUsers())
{
// TODO: Remove this shit