node_model.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /* node_model.h - node tree model wrapper
  2. * Copyright (C) 2017-2018 caryoscelus
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #ifndef STUDIO_MODELS_NODE_MODEL_H_7049227A_5FEA_5FDF_9D8E_5C61B5F8AAAF
  18. #define STUDIO_MODELS_NODE_MODEL_H_7049227A_5FEA_5FDF_9D8E_5C61B5F8AAAF
  19. #include <QAbstractItemModel>
  20. #include <core/node_info/node_info.h>
  21. #include <core/node/traverse.h>
  22. #include <core/node_tree/index.h>
  23. #include <generic/context_listener.h>
  24. namespace rainynite::studio {
  25. class NodeModel : public QAbstractItemModel, public ContextListener
  26. {
  27. Q_OBJECT
  28. public:
  29. explicit NodeModel(core::AbstractReference root, shared_ptr<core::ActionStack> action_stack, QObject* parent = nullptr);
  30. virtual ~NodeModel();
  31. QVariant data(QModelIndex const& index, int role) const override;
  32. Qt::ItemFlags flags(QModelIndex const& index) const override;
  33. QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
  34. QModelIndex index(int row, int column, QModelIndex const& parent = {}) const override;
  35. QModelIndex parent(QModelIndex const& index) const override;
  36. int rowCount(QModelIndex const& parent = {}) const override;
  37. int columnCount(QModelIndex const& parent = {}) const override;
  38. void time_changed(core::Time time) override;
  39. bool can_rename(QModelIndex const& index) const;
  40. QString get_name(QModelIndex const& index) const;
  41. void set_name(QModelIndex const& index, QString const& name);
  42. bool can_add_custom_property(QModelIndex const& parent) const;
  43. void add_empty_custom_property(QModelIndex const& parent, std::string const& name);
  44. bool is_custom_property(QModelIndex const& index) const;
  45. void remove_custom_property(QModelIndex const& index);
  46. bool can_clear_list(QModelIndex const& list) const;
  47. void clear_list(QModelIndex const& list);
  48. bool can_add_element(QModelIndex const& parent) const;
  49. void add_empty_element(QModelIndex const& parent);
  50. void remove_list_item(QModelIndex const& parent, size_t index);
  51. void convert_node(QModelIndex const& index, core::NodeInfo const* node_info);
  52. bool node_is_connected(QModelIndex const& index) const;
  53. void disconnect_node(QModelIndex const& index);
  54. void connect_nodes(QList<QModelIndex> const& selection, QModelIndex const& source);
  55. void replace_node(QModelIndex const& index, core::AbstractReference node);
  56. void swap_nodes(QModelIndex const& a, QModelIndex const& b);
  57. bool can_remove_node(QModelIndex const& index) const;
  58. /**
  59. * Remove "filter" node (replacing it with its child)
  60. */
  61. void remove_node(QModelIndex const& index);
  62. /**
  63. * Checks if node can be moved up.
  64. *
  65. * NOTE: this function doesn't check type compatibility! It should usually
  66. * be used after parent is checked to be editable list.
  67. */
  68. bool can_move_up(size_t offset, QModelIndex const& parent);
  69. /**
  70. * Checks if node can be moved down, same as can_move_up.
  71. */
  72. bool can_move_down(size_t offset, QModelIndex const& parent);
  73. void move_up(size_t offset, QModelIndex const& parent);
  74. void move_down(size_t offset, QModelIndex const& parent);
  75. /// Return node enabled status
  76. bool node_enabled(QModelIndex const& index) const;
  77. /// Enable/disable node
  78. void node_set_enabled(QModelIndex const& index, bool value);
  79. template <typename T, typename F>
  80. T find_nodes(core::AbstractReference node_to_find, F f) const {
  81. // TODO: perfect forward f
  82. return core::traverse_once<T>(
  83. root,
  84. [&f, &node_to_find](auto const& node) -> optional<T> {
  85. if (node == node_to_find)
  86. return f();
  87. return {};
  88. },
  89. core::TraverseDepth::Deeper
  90. );
  91. }
  92. core::TypeConstraint get_link_type(QModelIndex const& index) const;
  93. shared_ptr<core::AbstractValue> get_node(QModelIndex const& index) const;
  94. template <class T>
  95. shared_ptr<T> get_node_as(QModelIndex const& index) const {
  96. return dynamic_pointer_cast<T>(get_node(index));
  97. }
  98. shared_ptr<core::AbstractListLinked> get_list_node(QModelIndex const& index) const {
  99. return get_node_as<core::AbstractListLinked>(index);
  100. }
  101. size_t get_node_index(QModelIndex const& index) const;
  102. core::NodeTreeIndex get_inner_index(QModelIndex const& parent, size_t i) const;
  103. core::NodeTreeIndex get_inner_index(QModelIndex const& index) const;
  104. QModelIndex from_inner_index(core::NodeTreeIndex index) const;
  105. private:
  106. core::AbstractReference root;
  107. shared_ptr<core::NodeTree> tree;
  108. shared_ptr<core::ActionStack> action_stack;
  109. mutable map<pair<QModelIndex, size_t>, quintptr> indexes;
  110. mutable map<quintptr, QModelIndex> parents;
  111. mutable quintptr index_count = 0;
  112. };
  113. } // namespace rainynite::studio
  114. #endif