Serenity Operating System
at master 83 lines 2.7 kB view raw
1/* 2 * Copyright (c) 2022, Linus Groh <linusg@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <LibGUI/TreeViewModel.h> 8 9namespace GUI { 10 11ModelIndex TreeViewModel::index(int row, int column, ModelIndex const& parent) const 12{ 13 if (!parent.is_valid()) { 14 if (static_cast<size_t>(row) >= m_nodes.size()) 15 return {}; 16 return create_index(row, column, &m_nodes[row]); 17 } 18 auto const& parent_node = *static_cast<Node const*>(parent.internal_data()); 19 if (static_cast<size_t>(row) >= parent_node.child_nodes().size()) 20 return {}; 21 auto const* child = &parent_node.child_nodes()[row]; 22 return create_index(row, column, child); 23} 24 25ModelIndex TreeViewModel::parent_index(ModelIndex const& index) const 26{ 27 if (!index.is_valid()) 28 return {}; 29 auto const& child_node = *static_cast<Node const*>(index.internal_data()); 30 auto const* parent_node = child_node.parent_node(); 31 if (parent_node == nullptr) 32 return {}; 33 if (parent_node->parent_node() == nullptr) { 34 for (size_t row = 0; row < m_nodes.size(); row++) 35 if (m_nodes[row] == parent_node) 36 return create_index(static_cast<int>(row), 0, parent_node); 37 VERIFY_NOT_REACHED(); 38 } 39 for (size_t row = 0; row < parent_node->parent_node()->child_nodes().size(); row++) { 40 auto const* child_node_at_row = parent_node->parent_node()->child_nodes()[row].ptr(); 41 if (child_node_at_row == parent_node) 42 return create_index(static_cast<int>(row), 0, parent_node); 43 } 44 VERIFY_NOT_REACHED(); 45} 46 47int TreeViewModel::row_count(ModelIndex const& index) const 48{ 49 if (!index.is_valid()) 50 return static_cast<int>(m_nodes.size()); 51 auto const& node = *static_cast<Node const*>(index.internal_data()); 52 return static_cast<int>(node.child_nodes().size()); 53} 54 55Variant TreeViewModel::data(ModelIndex const& index, ModelRole role) const 56{ 57 auto const& node = *static_cast<Node const*>(index.internal_data()); 58 switch (role) { 59 case ModelRole::Display: 60 return node.text(); 61 case ModelRole::Icon: 62 if (node.icon().has_value()) 63 return *node.icon(); 64 return {}; 65 default: 66 return {}; 67 } 68} 69 70Optional<ModelIndex> TreeViewModel::index_for_node(Node const& node, ModelIndex const& parent) const 71{ 72 for (int row = 0; row < row_count(parent); ++row) { 73 auto row_index = this->index(row, 0); 74 auto const* row_node = static_cast<TreeViewModel::Node const*>(row_index.internal_data()); 75 if (&node == row_node) 76 return row_index; 77 if (auto index = index_for_node(node, row_index); index.has_value()) 78 return index; 79 } 80 return {}; 81} 82 83}