1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 01:17:35 +00:00

SpaceAnalyzer: Remove an unnecessary level of inheritance

The TreeMapNode and TreeMap structs inside TreeMapWidget.h both had
single implementers, TreeNode and Tree inside main.cpp. The indirection
was removed and the new structures were moved to their own file
This commit is contained in:
Arda Cinar 2022-12-11 22:45:11 +03:00 committed by Sam Atkins
parent f476b827de
commit 8ba37872e9
6 changed files with 84 additions and 74 deletions

View file

@ -7,6 +7,7 @@ compile_gml(SpaceAnalyzer.gml SpaceAnalyzerGML.h space_analyzer_gml)
set(SOURCES set(SOURCES
TreeMapWidget.cpp TreeMapWidget.cpp
Tree.cpp
main.cpp main.cpp
) )

View file

@ -0,0 +1,16 @@
/*
* Copyright (c) 2022, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "Tree.h"
#include <AK/QuickSort.h>
void TreeNode::sort_children_by_area() const
{
if (m_children) {
Vector<TreeNode>* children = const_cast<Vector<TreeNode>*>(m_children.ptr());
quick_sort(*children, [](auto& a, auto& b) { return b.m_area < a.m_area; });
}
}

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2022, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/DeprecatedString.h>
#include <AK/Forward.h>
#include <AK/OwnPtr.h>
#include <AK/RefCounted.h>
#include <AK/Vector.h>
struct TreeNode final {
TreeNode(DeprecatedString name)
: m_name(move(name)) {};
DeprecatedString name() const { return m_name; }
i64 area() const { return m_area; }
size_t num_children() const
{
if (m_children) {
return m_children->size();
}
return 0;
}
TreeNode const& child_at(size_t i) const { return m_children->at(i); }
void sort_children_by_area() const;
DeprecatedString m_name;
i64 m_area { 0 };
OwnPtr<Vector<TreeNode>> m_children;
};
struct Tree : public RefCounted<Tree> {
Tree(DeprecatedString root_name)
: m_root(move(root_name)) {};
~Tree() {};
TreeNode m_root;
TreeNode const& root() const
{
return m_root;
};
};

View file

@ -36,7 +36,7 @@ static float get_normalized_aspect_ratio(float a, float b)
} }
} }
static bool node_is_leaf(TreeMapNode const& node) static bool node_is_leaf(TreeNode const& node)
{ {
return node.num_children() == 0; return node.num_children() == 0;
} }
@ -46,7 +46,7 @@ bool TreeMapWidget::rect_can_contain_label(Gfx::IntRect const& rect) const
return rect.height() >= font().presentation_size() && rect.width() > 20; return rect.height() >= font().presentation_size() && rect.width() > 20;
} }
void TreeMapWidget::paint_cell_frame(GUI::Painter& painter, TreeMapNode const& node, Gfx::IntRect const& cell_rect, Gfx::IntRect const& inner_rect, int depth, HasLabel has_label) const void TreeMapWidget::paint_cell_frame(GUI::Painter& painter, TreeNode const& node, Gfx::IntRect const& cell_rect, Gfx::IntRect const& inner_rect, int depth, HasLabel has_label) const
{ {
if (cell_rect.width() <= 2 || cell_rect.height() <= 2) { if (cell_rect.width() <= 2 || cell_rect.height() <= 2) {
painter.fill_rect(cell_rect, Color::Black); painter.fill_rect(cell_rect, Color::Black);
@ -102,7 +102,7 @@ void TreeMapWidget::paint_cell_frame(GUI::Painter& painter, TreeMapNode const& n
} }
template<typename Function> template<typename Function>
void TreeMapWidget::lay_out_children(TreeMapNode const& node, Gfx::IntRect const& rect, int depth, Function callback) void TreeMapWidget::lay_out_children(TreeNode const& node, Gfx::IntRect const& rect, int depth, Function callback)
{ {
if (node.num_children() == 0) { if (node.num_children() == 0) {
return; return;
@ -215,11 +215,11 @@ void TreeMapWidget::lay_out_children(TreeMapNode const& node, Gfx::IntRect const
} }
} }
TreeMapNode const* TreeMapWidget::path_node(size_t n) const TreeNode const* TreeMapWidget::path_node(size_t n) const
{ {
if (!m_tree.ptr()) if (!m_tree.ptr())
return nullptr; return nullptr;
TreeMapNode const* iter = &m_tree->root(); TreeNode const* iter = &m_tree->root();
size_t path_index = 0; size_t path_index = 0;
while (iter && path_index < m_path.size() && path_index < n) { while (iter && path_index < m_path.size() && path_index < n) {
size_t child_index = m_path[path_index]; size_t child_index = m_path[path_index];
@ -239,13 +239,13 @@ void TreeMapWidget::paint_event(GUI::PaintEvent& event)
m_selected_node_cache = path_node(m_path.size()); m_selected_node_cache = path_node(m_path.size());
TreeMapNode const* node = path_node(m_viewpoint); TreeNode const* node = path_node(m_viewpoint);
if (!node) { if (!node) {
painter.fill_rect(frame_inner_rect(), Color::MidGray); painter.fill_rect(frame_inner_rect(), Color::MidGray);
} else if (node_is_leaf(*node)) { } else if (node_is_leaf(*node)) {
paint_cell_frame(painter, *node, frame_inner_rect(), Gfx::IntRect(), m_viewpoint - 1, HasLabel::Yes); paint_cell_frame(painter, *node, frame_inner_rect(), Gfx::IntRect(), m_viewpoint - 1, HasLabel::Yes);
} else { } else {
lay_out_children(*node, frame_inner_rect(), m_viewpoint, [&](TreeMapNode const& node, int, Gfx::IntRect const& rect, Gfx::IntRect const& inner_rect, int depth, HasLabel has_label, IsRemainder remainder) { lay_out_children(*node, frame_inner_rect(), m_viewpoint, [&](TreeNode const& node, int, Gfx::IntRect const& rect, Gfx::IntRect const& inner_rect, int depth, HasLabel has_label, IsRemainder remainder) {
if (remainder == IsRemainder::No) { if (remainder == IsRemainder::No) {
paint_cell_frame(painter, node, rect, inner_rect, depth, has_label); paint_cell_frame(painter, node, rect, inner_rect, depth, has_label);
} else { } else {
@ -261,12 +261,12 @@ void TreeMapWidget::paint_event(GUI::PaintEvent& event)
Vector<int> TreeMapWidget::path_to_position(Gfx::IntPoint position) Vector<int> TreeMapWidget::path_to_position(Gfx::IntPoint position)
{ {
TreeMapNode const* node = path_node(m_viewpoint); TreeNode const* node = path_node(m_viewpoint);
if (!node) { if (!node) {
return {}; return {};
} }
Vector<int> path; Vector<int> path;
lay_out_children(*node, frame_inner_rect(), m_viewpoint, [&](TreeMapNode const&, int index, Gfx::IntRect const& rect, Gfx::IntRect const&, int, HasLabel, IsRemainder is_remainder) { lay_out_children(*node, frame_inner_rect(), m_viewpoint, [&](TreeNode const&, int index, Gfx::IntRect const& rect, Gfx::IntRect const&, int, HasLabel, IsRemainder is_remainder) {
if (is_remainder == IsRemainder::No && rect.contains(position)) { if (is_remainder == IsRemainder::No && rect.contains(position)) {
path.append(index); path.append(index);
} }
@ -283,7 +283,7 @@ void TreeMapWidget::mousemove_event(GUI::MouseEvent& event)
} }
auto* hovered_node = node; auto* hovered_node = node;
lay_out_children(*node, frame_inner_rect(), m_viewpoint, [&](TreeMapNode const&, int index, Gfx::IntRect const& rect, Gfx::IntRect const&, int, HasLabel, IsRemainder is_remainder) { lay_out_children(*node, frame_inner_rect(), m_viewpoint, [&](TreeNode const&, int index, Gfx::IntRect const& rect, Gfx::IntRect const&, int, HasLabel, IsRemainder is_remainder) {
if (is_remainder == IsRemainder::No && rect.contains(event.position())) { if (is_remainder == IsRemainder::No && rect.contains(event.position())) {
hovered_node = &hovered_node->child_at(index); hovered_node = &hovered_node->child_at(index);
} }
@ -294,7 +294,7 @@ void TreeMapWidget::mousemove_event(GUI::MouseEvent& event)
void TreeMapWidget::mousedown_event(GUI::MouseEvent& event) void TreeMapWidget::mousedown_event(GUI::MouseEvent& event)
{ {
TreeMapNode const* node = path_node(m_viewpoint); TreeNode const* node = path_node(m_viewpoint);
if (node && !node_is_leaf(*node)) { if (node && !node_is_leaf(*node)) {
Vector<int> path = path_to_position(event.position()); Vector<int> path = path_to_position(event.position());
if (!path.is_empty()) { if (!path.is_empty()) {
@ -312,7 +312,7 @@ void TreeMapWidget::doubleclick_event(GUI::MouseEvent& event)
{ {
if (event.button() != GUI::MouseButton::Primary) if (event.button() != GUI::MouseButton::Primary)
return; return;
TreeMapNode const* node = path_node(m_viewpoint); TreeNode const* node = path_node(m_viewpoint);
if (node && !node_is_leaf(*node)) { if (node && !node_is_leaf(*node)) {
Vector<int> path = path_to_position(event.position()); Vector<int> path = path_to_position(event.position());
m_path.shrink(m_viewpoint); m_path.shrink(m_viewpoint);
@ -355,7 +355,7 @@ void TreeMapWidget::context_menu_event(GUI::ContextMenuEvent& context_menu_event
on_context_menu_request(context_menu_event); on_context_menu_request(context_menu_event);
} }
void TreeMapWidget::set_tree(RefPtr<TreeMap> tree) void TreeMapWidget::set_tree(RefPtr<Tree> tree)
{ {
m_tree = tree; m_tree = tree;
m_path.clear(); m_path.clear();

View file

@ -6,27 +6,12 @@
#pragma once #pragma once
#include "Tree.h"
#include <LibGUI/Frame.h> #include <LibGUI/Frame.h>
#include <LibGfx/Rect.h> #include <LibGfx/Rect.h>
namespace SpaceAnalyzer { namespace SpaceAnalyzer {
struct TreeMapNode {
virtual DeprecatedString name() const = 0;
virtual i64 area() const = 0;
virtual size_t num_children() const = 0;
virtual TreeMapNode const& child_at(size_t i) const = 0;
virtual void sort_children_by_area() const = 0;
protected:
virtual ~TreeMapNode() = default;
};
struct TreeMap : public RefCounted<TreeMap> {
virtual ~TreeMap() = default;
virtual TreeMapNode const& root() const = 0;
};
class TreeMapWidget final : public GUI::Frame { class TreeMapWidget final : public GUI::Frame {
C_OBJECT(TreeMapWidget) C_OBJECT(TreeMapWidget)
@ -35,10 +20,10 @@ public:
Function<void()> on_path_change; Function<void()> on_path_change;
Function<void(GUI::ContextMenuEvent&)> on_context_menu_request; Function<void(GUI::ContextMenuEvent&)> on_context_menu_request;
size_t path_size() const; size_t path_size() const;
TreeMapNode const* path_node(size_t n) const; TreeNode const* path_node(size_t n) const;
size_t viewpoint() const; size_t viewpoint() const;
void set_viewpoint(size_t); void set_viewpoint(size_t);
void set_tree(RefPtr<TreeMap> tree); void set_tree(RefPtr<Tree> tree);
private: private:
TreeMapWidget() = default; TreeMapWidget() = default;
@ -62,11 +47,11 @@ private:
}; };
template<typename Function> template<typename Function>
void lay_out_children(TreeMapNode const&, Gfx::IntRect const&, int depth, Function); void lay_out_children(TreeNode const&, Gfx::IntRect const&, int depth, Function);
void paint_cell_frame(GUI::Painter&, TreeMapNode const&, Gfx::IntRect const&, Gfx::IntRect const&, int depth, HasLabel has_label) const; void paint_cell_frame(GUI::Painter&, TreeNode const&, Gfx::IntRect const&, Gfx::IntRect const&, int depth, HasLabel has_label) const;
Vector<int> path_to_position(Gfx::IntPoint); Vector<int> path_to_position(Gfx::IntPoint);
RefPtr<TreeMap> m_tree; RefPtr<Tree> m_tree;
Vector<int> m_path; Vector<int> m_path;
size_t m_viewpoint { 0 }; size_t m_viewpoint { 0 };
void const* m_selected_node_cache; void const* m_selected_node_cache;

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include "Tree.h"
#include "TreeMapWidget.h" #include "TreeMapWidget.h"
#include <AK/Error.h> #include <AK/Error.h>
#include <AK/LexicalPath.h> #include <AK/LexicalPath.h>
@ -38,44 +39,6 @@
static constexpr auto APP_NAME = "Space Analyzer"sv; static constexpr auto APP_NAME = "Space Analyzer"sv;
static constexpr size_t FILES_ENCOUNTERED_UPDATE_STEP_SIZE = 25; static constexpr size_t FILES_ENCOUNTERED_UPDATE_STEP_SIZE = 25;
struct TreeNode : public SpaceAnalyzer::TreeMapNode {
TreeNode(DeprecatedString name)
: m_name(move(name)) {};
virtual DeprecatedString name() const override { return m_name; }
virtual i64 area() const override { return m_area; }
virtual size_t num_children() const override
{
if (m_children) {
return m_children->size();
}
return 0;
}
virtual TreeNode const& child_at(size_t i) const override { return m_children->at(i); }
virtual void sort_children_by_area() const override
{
if (m_children) {
Vector<TreeNode>* children = const_cast<Vector<TreeNode>*>(m_children.ptr());
quick_sort(*children, [](auto& a, auto& b) { return b.m_area < a.m_area; });
}
}
DeprecatedString m_name;
i64 m_area { 0 };
OwnPtr<Vector<TreeNode>> m_children;
};
struct Tree : public SpaceAnalyzer::TreeMap {
Tree(DeprecatedString root_name)
: m_root(move(root_name)) {};
virtual ~Tree() {};
TreeNode m_root;
virtual SpaceAnalyzer::TreeMapNode const& root() const override
{
return m_root;
};
};
struct MountInfo { struct MountInfo {
DeprecatedString mount_point; DeprecatedString mount_point;
DeprecatedString source; DeprecatedString source;
@ -301,7 +264,7 @@ static DeprecatedString get_absolute_path_to_selected_node(SpaceAnalyzer::TreeMa
if (k != 0) { if (k != 0) {
path_builder.append('/'); path_builder.append('/');
} }
SpaceAnalyzer::TreeMapNode const* node = treemapwidget.path_node(k); TreeNode const* node = treemapwidget.path_node(k);
path_builder.append(node->name()); path_builder.append(node->name());
} }
return path_builder.build(); return path_builder.build();
@ -416,7 +379,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
continue; continue;
} }
const SpaceAnalyzer::TreeMapNode* node = treemapwidget.path_node(k); const TreeNode* node = treemapwidget.path_node(k);
builder.append('/'); builder.append('/');
builder.append(node->name()); builder.append(node->name());