|
| 1 | +@tool |
| 2 | +## Common BlockExtension for scene group options. |
| 3 | +extends BlockExtension |
| 4 | + |
| 5 | +const OptionData = preload("res://addons/block_code/code_generation/option_data.gd") |
| 6 | +const Util = preload("res://addons/block_code/ui/util.gd") |
| 7 | + |
| 8 | + |
| 9 | +# Global groups are just project settings in the global_group group. |
| 10 | +# ProjectSettings doesn't offer an API to get the project groups or to get all |
| 11 | +# settings. Fortunately, settings are simply implemented as properties on the |
| 12 | +# ProjectSettings object. |
| 13 | +static func _add_global_groups(groups: Dictionary): |
| 14 | + for prop in ProjectSettings.get_property_list(): |
| 15 | + var name: String = prop["name"] |
| 16 | + var parts := name.split("/", false, 1) |
| 17 | + if parts[0] == "global_group": |
| 18 | + groups[parts[1]] = null |
| 19 | + |
| 20 | + |
| 21 | +# Add all the groups in a node and its children, ignoring internal _ prefixed |
| 22 | +# groups. |
| 23 | +static func _add_node_groups(groups: Dictionary, node: Node): |
| 24 | + for group in node.get_groups(): |
| 25 | + if not group.begins_with("_"): |
| 26 | + groups[String(group)] = null |
| 27 | + |
| 28 | + for child in node.get_children(): |
| 29 | + _add_node_groups(groups, child) |
| 30 | + |
| 31 | + |
| 32 | +func _get_edited_scene_groups() -> Array[String]: |
| 33 | + var groups: Dictionary |
| 34 | + _add_global_groups(groups) |
| 35 | + |
| 36 | + var root := context_node.get_tree().edited_scene_root |
| 37 | + _add_node_groups(groups, root) |
| 38 | + |
| 39 | + var sorted_groups: Array[String] |
| 40 | + sorted_groups.assign(groups.keys()) |
| 41 | + sorted_groups.sort() |
| 42 | + return sorted_groups |
| 43 | + |
| 44 | + |
| 45 | +func _init(): |
| 46 | + # FIXME: Only global group changes are monitored. Scene local groups should |
| 47 | + # also be monitored, but godot does not have any reasonable API to do that. |
| 48 | + ProjectSettings.settings_changed.connect(_on_project_settings_changed) |
| 49 | + |
| 50 | + |
| 51 | +func _context_node_changed(): |
| 52 | + # If the context node changed, the scene local groups need to be updated. |
| 53 | + changed.emit() |
| 54 | + |
| 55 | + |
| 56 | +func get_defaults() -> Dictionary: |
| 57 | + if not context_node: |
| 58 | + return {} |
| 59 | + |
| 60 | + # The default groups are only needed in the editor. |
| 61 | + if not Util.node_is_part_of_edited_scene(context_node): |
| 62 | + return {} |
| 63 | + |
| 64 | + var groups: Array[String] = _get_edited_scene_groups() |
| 65 | + return {"group": OptionData.new(groups)} |
| 66 | + |
| 67 | + |
| 68 | +func _on_project_settings_changed(): |
| 69 | + # FIXME: The global groups should be cached and compared so that the |
| 70 | + # defaults are only changed when the global groups actually change. |
| 71 | + changed.emit() |
0 commit comments