Serenity Operating System
at master 92 lines 3.0 kB view raw
1/* 2 * Copyright (c) 2022, Linus Groh <linusg@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/DeprecatedString.h> 10#include <AK/NonnullRefPtr.h> 11#include <AK/Optional.h> 12#include <AK/RefPtr.h> 13#include <AK/StdLibExtras.h> 14#include <AK/WeakPtr.h> 15#include <LibGUI/Model.h> 16 17namespace GUI { 18 19class TreeViewModel final : public Model { 20public: 21 static NonnullRefPtr<TreeViewModel> create() 22 { 23 return adopt_ref(*new TreeViewModel()); 24 } 25 26 virtual ~TreeViewModel() override = default; 27 28 virtual int row_count(ModelIndex const& = {}) const override; 29 virtual int column_count(ModelIndex const& = {}) const override { return 1; } 30 virtual Variant data(ModelIndex const&, ModelRole role) const override; 31 virtual ModelIndex parent_index(ModelIndex const&) const override; 32 virtual ModelIndex index(int row, int column, ModelIndex const& parent = {}) const override; 33 34 class Node 35 : public RefCounted<Node> 36 , public Weakable<Node> { 37 public: 38 Node(DeprecatedString text, Optional<Icon> icon, Node* parent_node = nullptr) 39 : m_text(move(text)) 40 , m_icon(move(icon)) 41 , m_parent_node(parent_node) 42 { 43 } 44 45 virtual ~Node() = default; 46 47 template<typename NodeType = Node, typename... Args> 48 NonnullRefPtr<NodeType> add_node(DeprecatedString text, Optional<Icon> icon, Args&&... args) 49 requires(IsBaseOf<Node, NodeType>) 50 { 51 auto node = adopt_ref(*new NodeType(move(text), move(icon), this, forward<Args>(args)...)); 52 m_child_nodes.append(*static_cast<Node*>(node.ptr())); 53 return node; 54 } 55 56 DeprecatedString const& text() const { return m_text; } 57 Optional<Icon> const& icon() const { return m_icon; } 58 59 Node const* parent_node() const { return m_parent_node; } 60 Node* parent_node() { return m_parent_node; } 61 62 Vector<NonnullRefPtr<Node>> const& child_nodes() const { return m_child_nodes; } 63 Vector<NonnullRefPtr<Node>>& child_nodes() { return m_child_nodes; } 64 65 private: 66 DeprecatedString m_text; 67 Optional<Icon> m_icon; 68 WeakPtr<Node> m_parent_node; 69 Vector<NonnullRefPtr<Node>> m_child_nodes; 70 }; 71 72 Vector<NonnullRefPtr<Node>> const& nodes() const { return m_nodes; } 73 Vector<NonnullRefPtr<Node>>& nodes() { return m_nodes; } 74 75 template<typename NodeType = Node, typename... Args> 76 NonnullRefPtr<NodeType> add_node(DeprecatedString text, Optional<Icon> icon, Args&&... args) 77 requires(IsBaseOf<Node, NodeType>) 78 { 79 auto node = adopt_ref(*new NodeType(move(text), move(icon), nullptr, forward<Args>(args)...)); 80 m_nodes.append(*static_cast<Node*>(node.ptr())); 81 return node; 82 } 83 84 Optional<ModelIndex> index_for_node(Node const&, ModelIndex const& parent = {}) const; 85 86private: 87 TreeViewModel() = default; 88 89 Vector<NonnullRefPtr<Node>> m_nodes; 90}; 91 92}