forked from SerenityOS/serenity
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
LibGUI: Start adding an automatic widget layout system.
My needs are really quite simple, so I'm just going to add what I need as I go along. The first thing I needed was a simple box layout with widgets being able to say whether they prefer fixed or fill for both their vertical and horizontal sizes. I also made a simple GStatusBar so FileManager can show how many bytes worth of files are in the current directory.
- Loading branch information
1 parent
2cf1dd5
commit 2def3d8
Showing
22 changed files
with
411 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
#include <LibGUI/GBoxLayout.h> | ||
#include <LibGUI/GWidget.h> | ||
|
||
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) | ||
{ | ||
if (m_entries.is_empty()) | ||
return; | ||
|
||
Size available_size = widget.size(); | ||
int number_of_entries_with_fixed_size = 0; | ||
|
||
for (auto& entry : m_entries) { | ||
if (entry.widget && entry.widget->size_policy(orientation()) == SizePolicy::Fixed) { | ||
available_size -= entry.widget->preferred_size(); | ||
++number_of_entries_with_fixed_size; | ||
} | ||
} | ||
|
||
int number_of_entries_with_automatic_size = m_entries.size() - number_of_entries_with_fixed_size; | ||
|
||
dbgprintf("GBoxLayout: available_size=%d, fixed=%d, fill=%d\n", available_size.height(), number_of_entries_with_fixed_size, number_of_entries_with_automatic_size); | ||
|
||
Size 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); | ||
} | ||
|
||
dbgprintf("GBoxLayout: automatic_size=%s\n", automatic_size.to_string().characters()); | ||
|
||
int current_x = 0; | ||
int current_y = 0; | ||
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); | ||
} | ||
|
||
dbgprintf("GBoxLayout: apply, %s{%p} <- %s\n", entry.widget->class_name(), entry.widget.ptr(), rect.to_string().characters()); | ||
entry.widget->set_relative_rect(rect); | ||
|
||
if (orientation() == Orientation::Horizontal) | ||
current_x += rect.width(); | ||
else | ||
current_y += rect.height(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#pragma once | ||
|
||
#include <LibGUI/GLayout.h> | ||
#include <LibGUI/GWidget.h> | ||
|
||
class GBoxLayout final : public GLayout { | ||
public: | ||
explicit GBoxLayout(Orientation); | ||
virtual ~GBoxLayout() override; | ||
|
||
Orientation orientation() const { return m_orientation; } | ||
|
||
virtual void run(GWidget&) override; | ||
|
||
private: | ||
Orientation m_orientation; | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#include <LibGUI/GLayout.h> | ||
#include <LibGUI/GWidget.h> | ||
|
||
GLayout::GLayout() | ||
{ | ||
} | ||
|
||
GLayout::~GLayout() | ||
{ | ||
} | ||
|
||
void GLayout::notify_adopted(Badge<GWidget>, GWidget& widget) | ||
{ | ||
if (m_owner.ptr() == &widget) | ||
return; | ||
m_owner = widget.make_weak_ptr(); | ||
} | ||
|
||
void GLayout::notify_disowned(Badge<GWidget>, GWidget& widget) | ||
{ | ||
ASSERT(m_owner.ptr() == &widget); | ||
m_owner.clear(); | ||
} | ||
|
||
void GLayout::add_layout(OwnPtr<GLayout>&& layout) | ||
{ | ||
Entry entry; | ||
entry.layout = move(layout); | ||
m_entries.append(move(entry)); | ||
if (m_owner) | ||
m_owner->notify_layout_changed(Badge<GLayout>()); | ||
} | ||
|
||
void GLayout::add_widget(GWidget& widget) | ||
{ | ||
Entry entry; | ||
entry.widget = widget.make_weak_ptr(); | ||
m_entries.append(move(entry)); | ||
if (m_owner) | ||
m_owner->notify_layout_changed(Badge<GLayout>()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#pragma once | ||
|
||
#include <AK/Badge.h> | ||
#include <AK/OwnPtr.h> | ||
#include <AK/Vector.h> | ||
#include <AK/WeakPtr.h> | ||
|
||
class GWidget; | ||
|
||
class GLayout { | ||
public: | ||
GLayout(); | ||
virtual ~GLayout(); | ||
|
||
void add_widget(GWidget&); | ||
void add_layout(OwnPtr<GLayout>&&); | ||
|
||
virtual void run(GWidget&) = 0; | ||
|
||
void notify_adopted(Badge<GWidget>, GWidget&); | ||
void notify_disowned(Badge<GWidget>, GWidget&); | ||
|
||
protected: | ||
struct Entry { | ||
WeakPtr<GWidget> widget; | ||
OwnPtr<GLayout> layout; | ||
}; | ||
WeakPtr<GWidget> m_owner; | ||
Vector<Entry> m_entries; | ||
}; | ||
|
Oops, something went wrong.