From de059e317e43fa1b94d77fd981be68b86bf6de6e Mon Sep 17 00:00:00 2001 From: dec05eba Date: Fri, 20 Apr 2018 04:25:14 +0200 Subject: Add chatbar. No mouse editing but keyboard editing is supported --- include/Chatbar.hpp | 30 +++++++++++++++++ include/types.hpp | 22 ++++++++++++ src/Chatbar.cpp | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/MessagePart.cpp | 4 +-- src/main.cpp | 41 ++++++++++++++++++++++- 5 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 include/Chatbar.hpp create mode 100644 include/types.hpp create mode 100644 src/Chatbar.cpp diff --git a/include/Chatbar.hpp b/include/Chatbar.hpp new file mode 100644 index 0000000..143ebba --- /dev/null +++ b/include/Chatbar.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include + +namespace dchat +{ + class Chatbar + { + public: + Chatbar(); + + void addChar(sf::Uint32 codePoint); + const sf::String& getString() const; + void removePreviousChar(); + void removeNextChar(); + void clear(); + + void moveCaretLeft(); + void moveCaretRight(); + + void draw(sf::RenderWindow &window); + private: + sf::Text text; + sf::RectangleShape background; + int caretIndex; + sf::Vector2f caretOffset; + }; +} diff --git a/include/types.hpp b/include/types.hpp new file mode 100644 index 0000000..762dab1 --- /dev/null +++ b/include/types.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include + +namespace dchat +{ + typedef int8_t i8; + typedef int16_t i16; + typedef int32_t i32; + typedef int64_t i64; + + typedef uint8_t u8; + typedef uint16_t u16; + typedef uint32_t u32; + typedef uint64_t u64; + + typedef float f32; + typedef double f64; + + typedef intptr_t ssize; + typedef uintptr_t usize; +} diff --git a/src/Chatbar.cpp b/src/Chatbar.cpp new file mode 100644 index 0000000..14edba7 --- /dev/null +++ b/src/Chatbar.cpp @@ -0,0 +1,96 @@ +#include "../include/Chatbar.hpp" +#include "../include/ResourceCache.hpp" +#include "../include/Settings.hpp" +#include + +using namespace std; + +namespace dchat +{ + const float FONT_SIZE = 24; + const float BOX_PADDING_X = 15.0f; + const float BOX_PADDING_Y = 5.0f; + + Chatbar::Chatbar() : + text("", ResourceCache::getFont("fonts/Roboto-Regular.ttf"), FONT_SIZE * Settings::getScaling()), + caretIndex(0) + { + text.setFillColor(sf::Color(240, 240, 240)); + background.setFillColor(sf::Color(60, 60, 60)); + } + + void Chatbar::addChar(sf::Uint32 codePoint) + { + auto str = text.getString(); + str.insert(caretIndex, codePoint); + text.setString(str); + ++caretIndex; + caretOffset = text.findCharacterPos(caretIndex) - text.getPosition(); + } + + const sf::String& Chatbar::getString() const + { + return text.getString(); + } + + void Chatbar::removePreviousChar() + { + if(caretIndex > 0) + { + auto str = text.getString(); + str.erase(caretIndex - 1); + text.setString(str); + --caretIndex; + caretOffset = text.findCharacterPos(caretIndex) - text.getPosition(); + } + } + + void Chatbar::removeNextChar() + { + if(caretIndex < text.getString().getSize()) + { + auto str = text.getString(); + str.erase(caretIndex); + text.setString(str); + } + } + + void Chatbar::clear() + { + text.setString(""); + caretIndex = 0; + caretOffset.x = 0.0f; + caretOffset.y = 0.0f; + } + + void Chatbar::moveCaretLeft() + { + caretIndex = max(0, caretIndex - 1); + // TODO: Use glyph size to optimize this, no need to iterate all glyphs + caretOffset = text.findCharacterPos(caretIndex) - text.getPosition(); + } + + void Chatbar::moveCaretRight() + { + caretIndex = min((int)text.getString().getSize(), caretIndex + 1); + caretOffset = text.findCharacterPos(caretIndex) - text.getPosition(); + } + + void Chatbar::draw(sf::RenderWindow &window) + { + auto windowSize = window.getSize(); + + sf::Vector2f backgroundSize(floor(windowSize.x * 0.7f), floor(text.getCharacterSize() * 1.7f + BOX_PADDING_Y * 2.0f)); + sf::Vector2f backgroundPos(floor(windowSize.x * 0.5f - backgroundSize.x * 0.5f), floor(windowSize.y - backgroundSize.y - 20.0f)); + background.setSize(backgroundSize); + background.setPosition(backgroundPos); + text.setPosition(floor(backgroundPos.x + BOX_PADDING_X), floor(backgroundPos.y + backgroundSize.y * 0.5f - text.getCharacterSize() * 0.5f)); + + window.draw(background); + window.draw(text); + + sf::RectangleShape caretShape(sf::Vector2f(2.0f, backgroundSize.y - BOX_PADDING_Y * 2.0f)); + caretShape.setPosition(floor(text.getPosition().x + caretOffset.x), backgroundPos.y + BOX_PADDING_Y); + window.draw(caretShape); + } +} diff --git a/src/MessagePart.cpp b/src/MessagePart.cpp index 47c96bd..ea8e4a5 100644 --- a/src/MessagePart.cpp +++ b/src/MessagePart.cpp @@ -15,9 +15,9 @@ namespace dchat MessagePartText::MessagePartText(const string &_text) : MessagePart(Type::TEXT), - text(_text, ResourceCache::getFont("fonts/Roboto-Regular.ttf"), MessagePartText::getFontSizeScaled()) + text("", ResourceCache::getFont("fonts/Roboto-Regular.ttf"), MessagePartText::getFontSizeScaled()) { - + text.setString(sf::String::fromUtf8(_text.begin(), _text.end())); } float MessagePartText::getFontSizeScaled() diff --git a/src/main.cpp b/src/main.cpp index 85f1075..481f73a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,11 @@ -#include #include "../include/MessageBoard.hpp" #include "../include/User.hpp" +#include "../include/Chatbar.hpp" +#include +#include +#include +using namespace std; using namespace dchat; int main() @@ -31,6 +35,8 @@ int main() message->addText(u8"hello, world!"); messageBoard.addMessage(message); } + + Chatbar chatbar; while (window.isOpen()) { @@ -44,11 +50,44 @@ int main() sf::View view(sf::FloatRect(0.0f, 0.0f, event.size.width, event.size.height)); window.setView(view); } + else if(event.type == sf::Event::TextEntered) + { + if(event.text.unicode == 8) // backspace + chatbar.removePreviousChar(); + else if(event.text.unicode == 13) // enter + { + Message *message = new Message(localOfflineUser); + auto chatbarMsgUtf8 = chatbar.getString().toUtf8(); + string msg; + msg.resize(chatbarMsgUtf8.size()); + memcpy(&msg[0], chatbarMsgUtf8.data(), chatbarMsgUtf8.size()); + + message->addText(msg); + messageBoard.addMessage(message); + chatbar.clear(); + } + else if(event.text.unicode == 127) // delete + { + chatbar.removeNextChar(); + } + else + { + chatbar.addChar(event.text.unicode); + } + } + else if(event.type == sf::Event::KeyPressed) + { + if(event.key.code == sf::Keyboard::Left) + chatbar.moveCaretLeft(); + else if(event.key.code == sf::Keyboard::Right) + chatbar.moveCaretRight(); + } messageBoard.processEvent(event); } window.clear(); messageBoard.draw(window); + chatbar.draw(window); window.display(); } -- cgit v1.2.3