diff --git a/include/Cubed/gameplay/chat_message.hpp b/include/Cubed/gameplay/chat_message.hpp new file mode 100644 index 0000000..87f6a2e --- /dev/null +++ b/include/Cubed/gameplay/chat_message.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include +#include +namespace Cubed { +struct ChatMessage { + std::string player; + std::string text; + uint64_t time; +}; +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/scene/world_scene.hpp b/include/Cubed/scene/world_scene.hpp index a48e6be..42370ba 100644 --- a/include/Cubed/scene/world_scene.hpp +++ b/include/Cubed/scene/world_scene.hpp @@ -33,6 +33,8 @@ public: bool pause() const; void set_pause(bool pause); void set_error(std::string_view error); + void set_mouse(bool pause); + void set_chatting(bool chatting); private: bool handle_mouse_move_event(const MouseMoveEvent& e) override; @@ -40,7 +42,7 @@ private: bool handle_window_resize_event(const WindowResizeEvent& e) override; bool handle_mouse_wheel_event(const MouseWheelEvent& e) override; bool handle_key_event(const KeyEvent& e) override; - + bool handle_text_input_event(const TextInputEvent&) override; SceneManager& m_scene_manager; DevPanel m_dev_panel; Camera m_camera; @@ -50,6 +52,7 @@ private: bool m_paused = false; bool m_show_hud = true; bool m_show_dev_pannel = true; + bool m_chatting = false; PauseMenuUIManager m_pasue_menu; WorldUIManager m_hud_ui; ErrorUI m_error_ui; diff --git a/include/Cubed/tools/text_tools.hpp b/include/Cubed/tools/text_tools.hpp index 38b6869..b4d5a21 100644 --- a/include/Cubed/tools/text_tools.hpp +++ b/include/Cubed/tools/text_tools.hpp @@ -1,6 +1,10 @@ #pragma once +#include "Cubed/tools/cubed_assert.hpp" + #include #include +#include +#include namespace Cubed { inline std::string codepoint_to_utf8(uint32_t cp) { std::string out; @@ -38,4 +42,28 @@ inline void utf8_pop_back(std::string& str) { str.erase(i); } +inline std::vector split_utf8(const std::string& str, int size) { + ASSERT(size > 0); + if (!utf8::is_valid(str)) { + return {}; + } + std::vector blocks; + auto cur = str.begin(); + int chat_count = 0; + + for (auto it = str.begin(); it != str.end();) { + if (chat_count >= size) { + blocks.emplace_back(cur, it); + cur = it; + chat_count = 0; + } + utf8::next(it, str.end()); + ++chat_count; + if (it == str.end()) { + blocks.emplace_back(cur, it); + } + } + return blocks; +} + } // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/tools/time_tools.hpp b/include/Cubed/tools/time_tools.hpp new file mode 100644 index 0000000..7d4add8 --- /dev/null +++ b/include/Cubed/tools/time_tools.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include +#include +namespace Cubed { +namespace Tools { +inline uint64_t get_time_ticks() { return SDL_GetTicks(); } +} // namespace Tools + +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/ui/chat_box.hpp b/include/Cubed/ui/chat_box.hpp new file mode 100644 index 0000000..ef46314 --- /dev/null +++ b/include/Cubed/ui/chat_box.hpp @@ -0,0 +1,53 @@ +#pragma once + +#include "Cubed/gameplay/chat_message.hpp" +#include "Cubed/ui/text_field.hpp" +#include "Cubed/ui/widget.hpp" + +#include + +namespace Cubed { +class ChatBox : public Widget { +public: + ChatBox(Widget* parent); + + void add_message(ChatMessage& message); + + ChatBox& set_scale(float scale); + ChatBox& set_text_scale(float scale); + ChatBox& set_width(float width); + ChatBox& set_show_lines(int lines); + ChatBox& set_spacing(float spacing); + float width() const override; + float height() const override; + void set_d_image(TextureManager& m); + void set_typing(bool typing); + void set_app(App* app); + template ChatBox& set_on_finish(F&& f) { + m_text_field->set_on_finish(std::forward(f)); + return *this; + } + +private: + static constexpr int MAX_MESSGAES_SUM = 50; + + struct Line { + std::unique_ptr