LibGUI: Improve GBoxLayout so it can better support GToolBar.

Added spacing and margin concepts to GLayout. Support layout a sequence
of nothing but fixed-size objects in the desired orientation. :^)
This commit is contained in:
Andreas Kling 2019-02-20 09:04:28 +01:00
parent b704d3d295
commit dc753b58a5
Notes: sideshowbarker 2024-07-19 15:40:04 +09:00
5 changed files with 84 additions and 20 deletions

View File

@ -66,25 +66,22 @@ void GBoxLayout::run(GWidget& widget)
dbgprintf("GBoxLayout: automatic_size=%s\n", automatic_size.to_string().characters());
#endif
int current_x = 0;
int current_y = 0;
for (auto& entry : m_entries) {
// FIXME: We should also respect the bottom and right margins.
int current_x = margins().left();
int current_y = margins().top();
for (auto& entry : m_entries) {
Rect rect(current_x, current_y, 0, 0);
if (entry.layout) {
// FIXME: Implement recursive layout.
ASSERT_NOT_REACHED();
}
ASSERT(entry.widget);
if (entry.widget->size_policy(orientation()) == SizePolicy::Fixed) {
rect.set_size(automatic_size);
if (orientation() == Orientation::Vertical) {
rect.set_height(entry.widget->preferred_size().height());
} else {
rect.set_width(entry.widget->preferred_size().height());
}
} else {
rect.set_size(automatic_size);
}
rect.set_size(automatic_size);
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().height());
#ifdef GBOXLAYOUT_DEBUG
dbgprintf("GBoxLayout: apply, %s{%p} <- %s\n", entry.widget->class_name(), entry.widget.ptr(), rect.to_string().characters());
@ -92,8 +89,8 @@ void GBoxLayout::run(GWidget& widget)
entry.widget->set_relative_rect(rect);
if (orientation() == Orientation::Horizontal)
current_x += rect.width();
current_x += rect.width() + spacing();
else
current_y += rect.height();
current_y += rect.height() + spacing();
}
}

View File

@ -39,3 +39,21 @@ void GLayout::add_widget(GWidget& widget)
if (m_owner)
m_owner->notify_layout_changed(Badge<GLayout>());
}
void GLayout::set_spacing(int spacing)
{
if (m_spacing == spacing)
return;
m_spacing = spacing;
if (m_owner)
m_owner->notify_layout_changed(Badge<GLayout>());
}
void GLayout::set_margins(const GMargins& margins)
{
if (m_margins == margins)
return;
m_margins = margins;
if (m_owner)
m_owner->notify_layout_changed(Badge<GLayout>());
}

View File

@ -4,6 +4,7 @@
#include <AK/OwnPtr.h>
#include <AK/Vector.h>
#include <AK/WeakPtr.h>
#include <LibGUI/GMargins.h>
class GWidget;
@ -20,6 +21,12 @@ public:
void notify_adopted(Badge<GWidget>, GWidget&);
void notify_disowned(Badge<GWidget>, GWidget&);
GMargins margins() const { return m_margins; }
void set_margins(const GMargins&);
int spacing() const { return m_spacing; }
void set_spacing(int);
protected:
struct Entry {
WeakPtr<GWidget> widget;
@ -27,5 +34,8 @@ protected:
};
WeakPtr<GWidget> m_owner;
Vector<Entry> m_entries;
GMargins m_margins;
int m_spacing { 0 };
};

40
LibGUI/GMargins.h Normal file
View File

@ -0,0 +1,40 @@
#pragma once
class GMargins {
public:
GMargins() { }
GMargins(int left, int top, int right, int bottom)
: m_left(left)
, m_top(top)
, m_right(right)
, m_bottom(bottom)
{
}
~GMargins() { }
bool is_null() const { return !m_left && !m_top && !m_right && !m_bottom; }
int left() const { return m_left; }
int top() const { return m_top; }
int right() const { return m_right; }
int bottom() const { return m_bottom; }
void set_left(int value) { m_left = value; }
void set_top(int value) { m_top = value; }
void set_right(int value) { m_right = value; }
void set_bottom(int value) { m_bottom = value; }
bool operator==(const GMargins& other) const
{
return m_left == other.m_left
&& m_top == other.m_top
&& m_right == other.m_right
&& m_bottom == other.m_bottom;
}
private:
int m_left { 0 };
int m_top { 0 };
int m_right { 0 };
int m_bottom { 0 };
};

View File

@ -8,8 +8,10 @@ GToolBar::GToolBar(GWidget* parent)
: GWidget(parent)
{
set_size_policy(SizePolicy::Fill, SizePolicy::Fixed);
set_preferred_size({ 0, 24 });
set_preferred_size({ 0, 25 });
set_layout(make<GBoxLayout>(Orientation::Horizontal));
layout()->set_spacing(1);
layout()->set_margins({1, 1, 1, 1});
}
GToolBar::~GToolBar()
@ -33,11 +35,8 @@ void GToolBar::add_action(RetainPtr<GAction>&& action)
raw_action_ptr->activate();
};
#if 0
// FIXME: Gotta fix GBoxLayout for this to work.
button->set_size_policy(SizePolicy::Fixed, SizePolicy::Fixed);
button->set_preferred_size({ 16, 16 });
#endif
button->set_preferred_size({ 22, 22 });
m_items.append(move(item));
}