FileManager: Make the tree view follow the directory view navigations.

This commit is contained in:
Andreas Kling 2019-03-30 03:27:25 +01:00
parent f10e0d0546
commit 2c6a597d77
Notes: sideshowbarker 2024-07-19 14:53:45 +09:00
10 changed files with 72 additions and 3 deletions

View file

@ -40,6 +40,7 @@ bool FileSystemPath::canonicalize(bool resolve_symbolic_links)
builder.append('/');
builder.append(cpart);
}
m_parts = move(canonical_parts);
m_string = builder.to_string();
return true;
}

View file

@ -14,9 +14,12 @@ public:
String basename() const { return m_basename; }
const Vector<String>& parts() const { return m_parts; }
private:
bool canonicalize(bool resolve_symbolic_links = false);
Vector<String> m_parts;
String m_string;
String m_basename;
bool m_is_valid { false };

View file

@ -166,9 +166,12 @@ int main(int argc, char** argv)
main_toolbar->add_action(view_as_icons_action.copy_ref());
main_toolbar->add_action(view_as_table_action.copy_ref());
directory_view->on_path_change = [window, location_textbox] (const String& new_path) {
directory_view->on_path_change = [window, location_textbox, &file_system_model, tree_view] (const String& new_path) {
window->set_title(String::format("FileManager: %s", new_path.characters()));
location_textbox->set_text(new_path);
file_system_model->set_selected_index(file_system_model->index(new_path));
tree_view->scroll_into_view(file_system_model->selected_index(), Orientation::Vertical);
tree_view->update();
};
directory_view->on_status_message = [statusbar] (String message) {

View file

@ -35,3 +35,7 @@ void GAbstractView::did_update_model()
{
model_notification(GModelNotification(GModelNotification::ModelUpdated));
}
void GAbstractView::did_update_selection()
{
}

View file

@ -14,10 +14,9 @@ public:
GModel* model() { return m_model.ptr(); }
const GModel* model() const { return m_model.ptr(); }
void scroll_into_view(const GModelIndex&, Orientation);
virtual bool accepts_focus() const override { return true; }
virtual void did_update_model();
virtual void did_update_selection();
Function<void(const GModelNotification&)> on_model_notification;

View file

@ -92,6 +92,30 @@ struct GFileSystemModel::Node {
}
};
GModelIndex GFileSystemModel::index(const String& path) const
{
FileSystemPath canonical_path(path);
const Node* node = m_root;
if (canonical_path.string() == "/")
return m_root->index(*this);
for (int i = 0; i < canonical_path.parts().size(); ++i) {
auto& part = canonical_path.parts()[i];
bool found = false;
for (auto& child : node->children) {
if (child->name == part) {
node = child;
found = true;
if (i == canonical_path.parts().size() - 1)
return node->index(*this);
break;
}
}
if (!found)
return { };
}
return { };
}
String GFileSystemModel::path(const GModelIndex& index) const
{
if (!index.is_valid())

View file

@ -15,6 +15,7 @@ public:
String root_path() const { return m_root_path; }
String path(const GModelIndex&) const;
GModelIndex index(const String& path) const;
virtual int row_count(const GModelIndex& = GModelIndex()) const override;
virtual int column_count(const GModelIndex& = GModelIndex()) const override;

View file

@ -41,6 +41,9 @@ void GModel::set_selected_index(const GModelIndex& index)
m_selected_index = index;
if (on_selection_changed)
on_selection_changed(index);
for_each_view([] (auto& view) {
view.did_update_selection();
});
if (m_activates_on_selection && is_valid(index))
activate(index);
}

View file

@ -270,3 +270,32 @@ void GTreeView::paint_event(GPaintEvent& event)
return IterationDecision::Continue;
});
}
void GTreeView::scroll_into_view(const GModelIndex& a_index, Orientation orientation)
{
if (!a_index.is_valid())
return;
Rect found_rect;
traverse_in_paint_order([&] (const GModelIndex& index, const Rect& rect, int) {
if (index == a_index) {
found_rect = rect;
return IterationDecision::Abort;
}
return IterationDecision::Continue;
});
GScrollableWidget::scroll_into_view(found_rect, orientation);
}
void GTreeView::did_update_selection()
{
ASSERT(model());
auto& model = *this->model();
auto index = model.selected_index();
if (!index.is_valid())
return;
auto parent = index.parent();
while (parent.is_valid()) {
ensure_metadata_for_index(parent).open = true;
parent = parent.parent();
}
}

View file

@ -7,6 +7,7 @@ public:
explicit GTreeView(GWidget*);
virtual ~GTreeView() override;
virtual void scroll_into_view(const GModelIndex&, Orientation);
virtual const char* class_name() const override { return "GTreeView"; }
GModelIndex index_at_content_position(const Point&) const;
@ -14,6 +15,7 @@ public:
protected:
virtual void paint_event(GPaintEvent&) override;
virtual void mousedown_event(GMouseEvent&) override;
virtual void did_update_selection() override;
private:
int item_height() const { return 16; }