NotificationServer: Manually calculate the text label height

The layout system can't currently answer the question "what height does
this Label want to be, if it has a certain width available?" Instead it
relies on counting newlines, which doesn't work in a lot of cases. This
made the notification windows look and behave in a funky way when their
text wraps onto multiple lines.

This patch uses TextLayout to measure how many lines we need, and then
manually sets the Label and Window heights to match. It's a bit hacky,
hence the FIXME, but it does make things behave the way they are
supposed to.
This commit is contained in:
Sam Atkins 2024-01-16 16:12:56 +00:00 committed by Tim Flynn
parent 84e8bf3421
commit 9703510682
2 changed files with 13 additions and 6 deletions

View file

@ -17,11 +17,13 @@
name: "title"
font_weight: "Bold"
text_alignment: "CenterLeft"
preferred_height: "shrink"
max_height: "shrink"
}
@GUI::Label {
name: "text"
text_alignment: "CenterLeft"
text_alignment: "TopLeft"
}
}
}

View file

@ -17,6 +17,7 @@
#include <LibGfx/Bitmap.h>
#include <LibGfx/Font/FontDatabase.h>
#include <LibGfx/ShareableBitmap.h>
#include <LibGfx/TextLayout.h>
namespace NotificationServer {
@ -100,11 +101,15 @@ RefPtr<NotificationWindow> NotificationWindow::get_window_by_id(i32 id)
void NotificationWindow::resize_to_fit_text()
{
auto line_height = m_text_label->font().pixel_size_rounded_up();
auto total_height = m_text_label->text_calculated_preferred_height();
// FIXME: It would be good if Labels could size themselves based on their available width, but for now, we have to
// do the calculation manually.
Gfx::TextLayout text_layout { m_text_label->font(), Utf8View { m_text_label->text() }, m_text_label->rect().to_type<float>() };
auto line_count = text_layout.lines(Gfx::TextElision::None, m_text_label->text_wrapping()).size();
m_text_label->set_fixed_height(total_height);
set_height(40 - line_height + total_height);
auto line_height = m_text_label->font().preferred_line_height();
auto text_height = line_height * line_count;
m_text_label->set_height(text_height);
set_height(m_title_label->height() + GUI::Layout::default_spacing + text_height + main_widget()->layout()->margins().vertical_total());
}
void NotificationWindow::enter_event(Core::Event&)
@ -118,7 +123,7 @@ void NotificationWindow::enter_event(Core::Event&)
void NotificationWindow::leave_event(Core::Event&)
{
m_hovering = false;
m_text_label->set_preferred_height(GUI::SpecialDimension::Grow);
m_text_label->set_height(40 - (m_title_label->height() + GUI::Layout::default_spacing + main_widget()->layout()->margins().vertical_total()));
set_height(40);
update_notification_window_locations(GUI::Desktop::the().rect());
}