fix(ui): correct chat box layout with dynamic height and bottom anchor

This commit is contained in:
2026-07-18 18:27:49 +08:00
parent 7f2597ebe0
commit f4103e254e
3 changed files with 17 additions and 15 deletions

View File

@@ -15,6 +15,8 @@ public:
ChatBox& set_scale(float scale); ChatBox& set_scale(float scale);
ChatBox& set_text_scale(float scale); ChatBox& set_text_scale(float scale);
// Only the width of TextField can be set; the height is calculated
// dynamically
ChatBox& set_width(float width); ChatBox& set_width(float width);
ChatBox& set_show_lines(int lines); ChatBox& set_show_lines(int lines);
ChatBox& set_spacing(float spacing); ChatBox& set_spacing(float spacing);

View File

@@ -5,6 +5,7 @@ namespace Cubed {
ChatBox::ChatBox(Widget* parent) : Widget(parent) { ChatBox::ChatBox(Widget* parent) : Widget(parent) {
m_text_field = std::make_unique<TextField>(this); m_text_field = std::make_unique<TextField>(this);
m_text_field->set_anchor(Anchor::BOTTOM_LEFT);
} }
void ChatBox::add_message(ChatMessage& message) { void ChatBox::add_message(ChatMessage& message) {
@@ -15,7 +16,7 @@ void ChatBox::add_message(ChatMessage& message) {
std::string str = std::format("<{}>{}", message.player, message.text); std::string str = std::format("<{}>{}", message.player, message.text);
auto split_str = split_utf8(str, 20); auto split_str = split_utf8(str, 20);
for (auto it = split_str.rbegin(); it != split_str.rend(); ++it) { for (auto it = split_str.begin(); it != split_str.end(); ++it) {
auto lable = std::make_unique<Label>(this); auto lable = std::make_unique<Label>(this);
lable->set_text(*it) lable->set_text(*it)
.set_scale(m_text_scale) .set_scale(m_text_scale)
@@ -52,7 +53,10 @@ ChatBox& ChatBox::set_spacing(float spacing) {
return *this; return *this;
} }
float ChatBox::width() const { return m_width * m_scale; } float ChatBox::width() const { return m_width * m_scale; }
float ChatBox::height() const { return m_height * m_scale; } float ChatBox::height() const {
// Height is dynamically calculated, no scaling needed
return m_height;
}
void ChatBox::set_d_image(TextureManager& m) { void ChatBox::set_d_image(TextureManager& m) {
m_text_field->set_default_image(m); m_text_field->set_default_image(m);
} }
@@ -61,9 +65,9 @@ void ChatBox::set_typing(bool typing) { m_text_field->set_typing(typing); }
void ChatBox::set_app(App* app) { m_text_field->set_app(app); } void ChatBox::set_app(App* app) { m_text_field->set_app(app); }
void ChatBox::layout() { void ChatBox::layout() {
set_offset({0, m_text_field->height()}); int y = m_text_field->height() + m_spacing;
int y = 0;
int line = 0; int line = 0;
// Shift upward sequentially starting from the latest
for (auto it = m_messages.rbegin(); it != m_messages.rend(); ++it) { for (auto it = m_messages.rbegin(); it != m_messages.rend(); ++it) {
if (!it->label) { if (!it->label) {
continue; continue;
@@ -73,8 +77,9 @@ void ChatBox::layout() {
continue; continue;
} }
++line; ++line;
it->label->set_anchor(Anchor::TOP_LEFT); it->label->set_anchor(Anchor::BOTTOM_LEFT);
it->label->set_offset({0, y}); // -y means upward offset
it->label->set_offset({0, -y});
it->render = true; it->render = true;
y += it->label->height() + m_spacing; y += it->label->height() + m_spacing;
} }

View File

@@ -30,20 +30,15 @@ void WorldUIManager::init() {
m_widgets.try_emplace("crosshair", &crosshair); m_widgets.try_emplace("crosshair", &crosshair);
auto& chat_box = m_root_widget->add_child<ChatBox>(); auto& chat_box = m_root_widget->add_child<ChatBox>();
chat_box.set_scale(10); chat_box.set_spacing(15);
chat_box.set_anchor(Anchor::BOTTOM_LEFT); chat_box.set_anchor(Anchor::BOTTOM_LEFT);
chat_box.set_offset({0, -10}); chat_box.set_offset({0, -10});
chat_box.set_width(200); chat_box.set_width(200);
chat_box.set_scale(3.0f); chat_box.set_scale(2.0f);
chat_box.set_text_scale(0.5f); chat_box.set_text_scale(0.6f);
ChatMessage m{"zhenyan121", "原神能不能牛逼原神牛逼", 2020};
ChatMessage m1{"zhenyan121", "原神能不能wdadaw牛逼原神牛逼12q432raecawfa",
2021};
chat_box.add_message(m);
chat_box.add_message(m1);
chat_box.set_d_image(m_scene.scene_manager().app().texture_manager()); chat_box.set_d_image(m_scene.scene_manager().app().texture_manager());
chat_box.set_app(&m_scene.scene_manager().app()); chat_box.set_app(&m_scene.scene_manager().app());
chat_box.set_on_finish([]() { Logger::info("Chat Input"); }); chat_box.set_on_finish([]() {});
m_chat_box = &chat_box; m_chat_box = &chat_box;
} }
void WorldUIManager::render(Renderer& renderer) { void WorldUIManager::render(Renderer& renderer) {