ClockWidget: Left-align clock and center based on ideal width

I personally find it very distracting when the clock continuously
shifts around as seconds tick. Because we're not using a monospace
font for the clock, this is to be expected since each number has a
different typographic width.

However, a tradeoff can be made to make this slightly less distracting.
Instead of _perfectly_ centering the time string for every given
possible time, we can center it once based on a constant measurement
and render the rest of the string as left-aligned.

The advantage is that the clock no longer shifts around anymore while
seconds tick. The disadvantage is that the time may sometimes be not
perfectly centered by a pixel or two for certain numbers. Personally,
I find the tradeoff well worth it, and I don't think I would even
notice the imperfect centering unless I was specifically looking for
it and watching it for a long time.
This commit is contained in:
James Magahern 2021-10-10 23:05:46 -07:00 committed by Andreas Kling
parent d79ab32850
commit 4041848caa
Notes: sideshowbarker 2024-07-18 02:49:22 +09:00

View File

@ -171,7 +171,17 @@ void ClockWidget::paint_event(GUI::PaintEvent& event)
auto time_text = Core::DateTime::now().to_string("%T");
GUI::Painter painter(*this);
painter.add_clip_rect(frame_inner_rect());
painter.draw_text(frame_inner_rect().translated(0, 1), time_text, Gfx::FontDatabase::default_font(), Gfx::TextAlignment::Center, palette().window_text());
// Render string center-left aligned, but attempt to center the string based on a constant
// "ideal" time string (i.e., the same one used to size this widget in the initializer).
// This prevents the rest of the string from shifting around while seconds tick.
const Gfx::Font& font = Gfx::FontDatabase::default_font();
const int frame_width = frame_thickness();
const int ideal_width = m_time_width;
const int widget_width = max_width();
const int translation_x = (widget_width - ideal_width) / 2 - frame_width;
painter.draw_text(frame_inner_rect().translated(translation_x, frame_width), time_text, font, Gfx::TextAlignment::CenterLeft, palette().window_text());
}
void ClockWidget::mousedown_event(GUI::MouseEvent& event)