node-manager.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. NodeManager::NodeManager(View* view) : PanelList(view, Size{~0, ~0}) {
  2. setCollapsible().setVisible(false);
  3. listView.onChange([&] { onChange(); });
  4. }
  5. auto NodeManager::show() -> void {
  6. root = emulator.root;
  7. listView.selectNone().doChange();
  8. refresh();
  9. setVisible(true);
  10. }
  11. auto NodeManager::hide() -> void {
  12. setVisible(false);
  13. root = {};
  14. }
  15. //recreate the tree after nodes have been added or removed
  16. auto NodeManager::refresh() -> void {
  17. //save the currently selected node to try and reselect it after rebuilding the tree
  18. higan::Node::Object selected;
  19. if(auto item = listView.selected()) {
  20. selected = item.attribute<higan::Node::Object>("node");
  21. }
  22. listView.reset();
  23. if(root) for(auto& node : *root) refresh(node, 0);
  24. //try and restore the previously selected node
  25. for(auto& item : listView.items()) {
  26. if(item.attribute<higan::Node::Object>("node") == selected) {
  27. item.setSelected().setFocused();
  28. }
  29. }
  30. }
  31. auto NodeManager::refresh(higan::Node::Object node, uint depth) -> void {
  32. if(node->is<higan::Node::Memory>()) return;
  33. if(node->is<higan::Node::Graphics>()) return;
  34. if(node->is<higan::Node::Tracer>()) return;
  35. if(node->is<higan::Node::Input>()) return;
  36. if(node->is<higan::Node::Sprite>()) return;
  37. ListViewItem item{&listView};
  38. item.setAttribute<higan::Node::Object>("node", node);
  39. item.setAttribute<uint>("depth", depth);
  40. item.setText(name(node, depth));
  41. for(auto& node : *node) refresh(node, depth + 1);
  42. }
  43. //refresh the tree after settings have changed
  44. auto NodeManager::refreshSettings() -> void {
  45. for(auto& item : listView.items()) {
  46. auto node = item.attribute<higan::Node::Object>("node");
  47. if(auto setting = node->cast<higan::Node::Setting>()) {
  48. uint depth = item.attribute<uint>("depth");
  49. item.setText(name(node, depth));
  50. }
  51. }
  52. }
  53. //generate a name for the panel list for a given node
  54. //insert spacing based on depth to simulate a TreeView in a ListView widget
  55. auto NodeManager::name(higan::Node::Object node, uint depth) -> string {
  56. string name;
  57. for(uint n : range(depth)) name.append(" ");
  58. name.append(node->attribute("name") ? node->attribute("name") : node->name());
  59. if(auto setting = node->cast<higan::Node::Setting>()) {
  60. name.append(": ", setting->readValue());
  61. if(!setting->dynamic() && setting->readLatch() != setting->readValue()) {
  62. name.append(" (", setting->readLatch(), ")");
  63. }
  64. }
  65. return name;
  66. }
  67. auto NodeManager::onChange() -> void {
  68. if(auto node = listView.selected().attribute<higan::Node::Object>("node")) {
  69. if(auto port = node->cast<higan::Node::Port>()) {
  70. portConnector.refresh(port);
  71. return program.setPanelItem(portConnector);
  72. }
  73. if(auto setting = node->cast<higan::Node::Setting>()) {
  74. settingEditor.refresh(setting);
  75. return program.setPanelItem(settingEditor);
  76. }
  77. if(auto inputs = node->find<higan::Node::Input>()) {
  78. if(inputs.first()->parent() == node) {
  79. inputMapper.refresh(node);
  80. return program.setPanelItem(inputMapper);
  81. }
  82. }
  83. if(auto peripheral = node->cast<higan::Node::Peripheral>()) {
  84. peripheralOverview.refresh(peripheral);
  85. return program.setPanelItem(peripheralOverview);
  86. }
  87. }
  88. program.setPanelItem(home);
  89. }