SpaceAnalyzer: Keep the current path via filenames, not indices

The tree map widget keeps the current path to allow the user to navigate
between directories. This path was being kept as indices into the
children array. The indices might change after the tree is regenerated
and this change is required to keep the user's current place after a
re-analysis
This commit is contained in:
Arda Cinar 2022-12-13 12:03:12 +03:00 committed by Sam Atkins
parent ba33267132
commit c045ae1a96
2 changed files with 15 additions and 12 deletions

View file

@ -6,7 +6,9 @@
*/
#include "TreeMapWidget.h"
#include "Tree.h"
#include <AK/Array.h>
#include <AK/DeprecatedString.h>
#include <AK/NumberFormat.h>
#include <LibGUI/ConnectionToWindowServer.h>
#include <LibGUI/Painter.h>
@ -222,11 +224,11 @@ TreeNode const* TreeMapWidget::path_node(size_t n) const
TreeNode const* iter = &m_tree->root();
size_t path_index = 0;
while (iter && path_index < m_path.size() && path_index < n) {
size_t child_index = m_path[path_index];
if (child_index >= iter->num_children()) {
auto child_name = m_path[path_index];
auto maybe_child = iter->child_with_name(child_name);
if (!maybe_child.has_value())
return nullptr;
}
iter = &iter->child_at(child_index);
iter = &maybe_child.release_value();
path_index++;
}
return iter;
@ -259,16 +261,16 @@ void TreeMapWidget::paint_event(GUI::PaintEvent& event)
}
}
Vector<int> TreeMapWidget::path_to_position(Gfx::IntPoint position)
Vector<DeprecatedString> TreeMapWidget::path_to_position(Gfx::IntPoint position)
{
TreeNode const* node = path_node(m_viewpoint);
if (!node) {
return {};
}
Vector<int> path;
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) {
Vector<DeprecatedString> path;
lay_out_children(*node, frame_inner_rect(), m_viewpoint, [&](TreeNode const& node, int, Gfx::IntRect const& rect, Gfx::IntRect const&, int, HasLabel, IsRemainder is_remainder) {
if (is_remainder == IsRemainder::No && rect.contains(position)) {
path.append(index);
path.append(node.name());
}
});
return path;
@ -296,7 +298,7 @@ void TreeMapWidget::mousedown_event(GUI::MouseEvent& event)
{
TreeNode const* node = path_node(m_viewpoint);
if (node && !node_is_leaf(*node)) {
Vector<int> path = path_to_position(event.position());
auto path = path_to_position(event.position());
if (!path.is_empty()) {
m_path.shrink(m_viewpoint);
m_path.extend(path);
@ -314,7 +316,7 @@ void TreeMapWidget::doubleclick_event(GUI::MouseEvent& event)
return;
TreeNode const* node = path_node(m_viewpoint);
if (node && !node_is_leaf(*node)) {
Vector<int> path = path_to_position(event.position());
auto path = path_to_position(event.position());
m_path.shrink(m_viewpoint);
m_path.extend(path);
m_viewpoint = m_path.size();

View file

@ -7,6 +7,7 @@
#pragma once
#include "Tree.h"
#include <AK/DeprecatedString.h>
#include <LibGUI/Frame.h>
#include <LibGfx/Rect.h>
@ -49,10 +50,10 @@ private:
template<typename Function>
void lay_out_children(TreeNode const&, Gfx::IntRect const&, int depth, Function);
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<DeprecatedString> path_to_position(Gfx::IntPoint);
RefPtr<Tree> m_tree;
Vector<int> m_path;
Vector<DeprecatedString> m_path;
size_t m_viewpoint { 0 };
void const* m_selected_node_cache;
};