mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 10:57:35 +00:00

This patch adds a simple GMessageBox that can run in a nested event loop. Here's how you use it: GMessageBox box("Message text here", "Message window title"); int result = box.exec(); The next step is to make the WindowServer respect the modality flag of these windows and prevent interaction with other windows in the same process until the modal window has been closed.
138 lines
4.7 KiB
C++
138 lines
4.7 KiB
C++
#include <LibGUI/GBoxLayout.h>
|
|
#include <LibGUI/GWidget.h>
|
|
#include <stdio.h>
|
|
|
|
//#define GBOXLAYOUT_DEBUG
|
|
|
|
GBoxLayout::GBoxLayout(Orientation orientation)
|
|
: m_orientation(orientation)
|
|
{
|
|
}
|
|
|
|
GBoxLayout::~GBoxLayout()
|
|
{
|
|
}
|
|
|
|
#if 0
|
|
Size GLayout::compute_preferred_size() const
|
|
{
|
|
|
|
}
|
|
|
|
|
|
static Size compute_preferred_size(GLayout::Entry& entry)
|
|
{
|
|
if (entry.layout)
|
|
return entry.layout->compute_preferred_size();
|
|
else {
|
|
return entry.widget->preferred_size();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void GBoxLayout::run(GWidget& widget)
|
|
{
|
|
bool should_log = false;
|
|
#ifdef GBOXLAYOUT_DEBUG
|
|
should_log = true;
|
|
#endif
|
|
if (should_log)
|
|
printf("GBoxLayout: running layout on %s{%p}, entry count: %d\n", widget.class_name(), &widget, m_entries.size());
|
|
|
|
if (m_entries.is_empty())
|
|
return;
|
|
|
|
Size available_size = widget.size();
|
|
int number_of_entries_with_fixed_size = 0;
|
|
|
|
int number_of_visible_entries = 0;
|
|
|
|
if (should_log)
|
|
printf("GBoxLayout: Starting with available size: %s\n", available_size.to_string().characters());
|
|
|
|
for (auto& entry : m_entries) {
|
|
if (!entry.widget->is_visible())
|
|
continue;
|
|
++number_of_visible_entries;
|
|
if (entry.widget && entry.widget->size_policy(orientation()) == SizePolicy::Fixed) {
|
|
if (should_log) {
|
|
printf("GBoxLayout: Subtracting for fixed %s{%p}, size: %s\n", entry.widget->class_name(), entry.widget.ptr(), entry.widget->preferred_size().to_string().characters());
|
|
printf("GBoxLayout: Available size before: %s\n", available_size.to_string().characters());
|
|
}
|
|
|
|
available_size -= entry.widget->preferred_size();
|
|
if (should_log)
|
|
printf("GBoxLayout: Available size after: %s\n", available_size.to_string().characters());
|
|
++number_of_entries_with_fixed_size;
|
|
}
|
|
}
|
|
|
|
if (should_log)
|
|
printf("GBoxLayout: Number of visible: %d/%d\n", number_of_visible_entries, m_entries.size());
|
|
|
|
int number_of_entries_with_automatic_size = number_of_visible_entries - number_of_entries_with_fixed_size;
|
|
|
|
#ifdef GBOXLAYOUT_DEBUG
|
|
if (should_log)
|
|
printf("GBoxLayout: available_size=%s, fixed=%d, fill=%d\n", available_size.to_string().characters(), number_of_entries_with_fixed_size, number_of_entries_with_automatic_size);
|
|
#endif
|
|
|
|
Size automatic_size;
|
|
|
|
if (number_of_entries_with_automatic_size) {
|
|
if (m_orientation == Orientation::Horizontal) {
|
|
automatic_size.set_width(available_size.width() / number_of_entries_with_automatic_size);
|
|
automatic_size.set_height(widget.height());
|
|
} else {
|
|
automatic_size.set_width(widget.width());
|
|
automatic_size.set_height(available_size.height() / number_of_entries_with_automatic_size);
|
|
}
|
|
}
|
|
|
|
#ifdef GBOXLAYOUT_DEBUG
|
|
if (should_log)
|
|
printf("GBoxLayout: automatic_size=%s\n", automatic_size.to_string().characters());
|
|
#endif
|
|
|
|
int current_x = margins().left();
|
|
int current_y = margins().top();
|
|
|
|
for (auto& entry : m_entries) {
|
|
if (!entry.widget->is_visible())
|
|
continue;
|
|
Rect rect(current_x, current_y, 0, 0);
|
|
if (entry.layout) {
|
|
// FIXME: Implement recursive layout.
|
|
ASSERT_NOT_REACHED();
|
|
}
|
|
ASSERT(entry.widget);
|
|
rect.set_size(automatic_size.width() - margins().left() - margins().right(), automatic_size.height() - margins().top() - margins().bottom());
|
|
|
|
if (entry.widget->size_policy(Orientation::Vertical) == SizePolicy::Fixed)
|
|
rect.set_height(entry.widget->preferred_size().height());
|
|
|
|
if (entry.widget->size_policy(Orientation::Horizontal) == SizePolicy::Fixed)
|
|
rect.set_width(entry.widget->preferred_size().width());
|
|
|
|
if (orientation() == Orientation::Horizontal) {
|
|
if (entry.widget->size_policy(Orientation::Vertical) == SizePolicy::Fill)
|
|
rect.set_height(widget.height() - margins().top() - margins().bottom());
|
|
rect.center_vertically_within(widget.rect());
|
|
} else {
|
|
if (entry.widget->size_policy(Orientation::Horizontal) == SizePolicy::Fill)
|
|
rect.set_width(widget.width() - margins().left() - margins().right());
|
|
rect.center_horizontally_within(widget.rect());
|
|
}
|
|
|
|
#ifdef GBOXLAYOUT_DEBUG
|
|
if (should_log)
|
|
printf("GBoxLayout: apply, %s{%p} <- %s\n", entry.widget->class_name(), entry.widget.ptr(), rect.to_string().characters());
|
|
#endif
|
|
entry.widget->set_relative_rect(rect);
|
|
|
|
if (orientation() == Orientation::Horizontal)
|
|
current_x += rect.width() + spacing();
|
|
else
|
|
current_y += rect.height() + spacing();
|
|
}
|
|
}
|