editor.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /* editor.cpp - abstract canvas editor
  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. #include <QDebug>
  18. #include <core/node_info/node_info.h>
  19. #include <core/node_tree/exceptions.h>
  20. #include <core/node_tree/node_tree.h>
  21. #include <generic/node_editor.h>
  22. #include "abstract_editor.h"
  23. #include "registry.h"
  24. namespace rainynite::studio {
  25. shared_ptr<AbstractCanvasEditor> add_canvas_named_editor(AbstractCanvas& canvas, string const& name) {
  26. try {
  27. shared_ptr<AbstractCanvasEditor> editor = class_init::name_info<AbstractAbstractCanvasEditorFactory>(name)();
  28. if (auto context_listener = dynamic_cast<ContextListener*>(editor.get()))
  29. context_listener->set_context(canvas.get_context());
  30. canvas.add_editor(editor);
  31. return editor;
  32. } catch (class_init::RuntimeTypeError const&) {
  33. return nullptr;
  34. }
  35. }
  36. vector<shared_ptr<AbstractCanvasEditor>> add_canvas_node_editor(AbstractCanvas& canvas, core::NodeTreeIndex index) {
  37. auto node = canvas.get_context()->get_node(index);
  38. if (node == nullptr)
  39. return {};
  40. vector<shared_ptr<AbstractCanvasEditor>> added_editors;
  41. shared_ptr<AbstractCanvasEditor> editor;
  42. try {
  43. editor = make_canvas_editor_for(canvas, node->get_type());
  44. } catch (class_init::RuntimeTypeError const&) {
  45. }
  46. if (editor != nullptr) {
  47. canvas.add_editor(editor);
  48. if (auto context_listener = dynamic_cast<ContextListener*>(editor.get()))
  49. context_listener->set_context(canvas.get_context());
  50. if (auto node_editor = dynamic_cast<NodeEditor*>(editor.get()))
  51. node_editor->set_node(index);
  52. added_editors.push_back(editor);
  53. }
  54. editor.reset();
  55. try {
  56. editor = make_canvas_node_editor_for(canvas, typeid(*node));
  57. } catch (class_init::TypeLookupError const&) {
  58. }
  59. if (editor != nullptr) {
  60. // TODO: avoid code duplication
  61. canvas.add_editor(editor);
  62. if (auto context_listener = dynamic_cast<ContextListener*>(editor.get()))
  63. context_listener->set_context(canvas.get_context());
  64. if (auto node_editor = dynamic_cast<NodeEditor*>(editor.get()))
  65. node_editor->set_node(index);
  66. added_editors.push_back(editor);
  67. }
  68. bool show_children = false;
  69. try {
  70. show_children = class_init::name_info<NodeEditorShowChildren>(core::node_name(*node))();
  71. } catch (class_init::TypeLookupError const&) {
  72. }
  73. if (show_children) {
  74. // NOTE: this may lead to infinite recursion if node tree is looped
  75. if (auto tree = canvas.get_context()->tree()) {
  76. for (size_t i = 0; i < tree->children_count(index); ++i) {
  77. core::NodeTreeIndex child_idx;
  78. try {
  79. child_idx = tree->index(index, i);
  80. } catch (core::NodeTreeError const&) {
  81. // TODO: better report
  82. qWarning() << "adding child failed";
  83. break;
  84. }
  85. auto children_editors = add_canvas_node_editor(canvas, child_idx);
  86. added_editors.insert(
  87. added_editors.end(),
  88. children_editors.begin(),
  89. children_editors.end()
  90. );
  91. }
  92. }
  93. }
  94. return added_editors;
  95. }
  96. } // namespace rainynite::studio