graph_controller.py (9510B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\nodegraph\client\ui\controllers\graph_controller.py 2 from __future__ import print_function 3 import signals 4 from nodegraph.common.nodedata import get_node_graph_data, get_node_type, reload_node_graph_data 5 from nodegraph.client.custom_graph import get_yaml_nodes_as_dict, get_built_nodes_as_dict 6 from nodegraph.client.ui.controllers.node_controller import NodeViewController, AuthoredNodeViewController 7 from nodegraph.client.ui.view import BaseNodeGraphView, AuthoredNodeGraphView 8 9 class NodeGraphViewController(object): 10 node_graph_component_class = BaseNodeGraphView 11 _node_view_controller_class = NodeViewController 12 13 def __init__(self, node_graph_id): 14 from nodegraph.client.ui.controllers import get_node_graph_settings 15 self.node_graph_id = node_graph_id 16 self.selected_nodes = set() 17 self._settings = get_node_graph_settings(self.node_graph_id) 18 self._node_controllers = {} 19 self.on_update = signals.Signal('on_update') 20 self.on_selected_nodes = signals.Signal('on_selected_nodes') 21 self.on_focus_node = signals.Signal('on_focus_node') 22 self.on_highlight_node = signals.Signal('on_highlight_node') 23 self._graph_data = get_node_graph_data(self.node_graph_id) 24 25 def initialize(self): 26 pass 27 28 def get_node_controller(self, node_id): 29 if node_id not in self._node_controllers: 30 self._node_controllers[node_id] = self._node_view_controller_class(node_id=node_id, graph_controller=self) 31 return self._node_controllers[node_id] 32 33 def start_node_graph(self, *args, **kwargs): 34 if self.is_server_graph: 35 self.service.qa_start_node_graph(self.node_graph_id) 36 else: 37 node_graph = self.service.start_node_graph(self.node_graph_id) 38 open_node_graph(node_graph.instance_id) 39 40 def add_to_selection(self, node_id): 41 self.add_selection([node_id]) 42 43 def add_selection(self, node_ids): 44 for node_id in node_ids: 45 if node_id in self.selected_nodes: 46 continue 47 self.selected_nodes.add(node_id) 48 49 self.on_selected_nodes(self.selected_nodes) 50 51 def toggle_selection(self, node_id): 52 if node_id in self.selected_nodes: 53 self.selected_nodes.remove(node_id) 54 else: 55 self.selected_nodes.add(node_id) 56 self.on_selected_nodes(self.selected_nodes) 57 58 def remove_selection(self, node_ids): 59 for node_id in node_ids.copy(): 60 self.selected_nodes.remove(node_id) 61 62 self.on_selected_nodes(self.selected_nodes) 63 64 def select_all(self): 65 self.selected_nodes = set(self.nodes_data.keys()) 66 self.on_selected_nodes(self.selected_nodes) 67 68 def clear_selection(self): 69 self.remove_selection(self.selected_nodes) 70 71 def focus_node(self, node_id): 72 self.on_focus_node(node_id) 73 74 def highlight_node(self, node_id): 75 pass 76 77 def unhighlight_node(self, node_id): 78 pass 79 80 def get_node_context_menu(self, node_id): 81 if len(self.selected_nodes) > 1: 82 return [('MULTIPLE NODES SELECTED', None), ('Copy nodes to clipboard', lambda : self.copy_nodes_to_clipboard(self.selected_nodes))] 83 else: 84 return self.get_node_controller(node_id).get_context_menu() 85 86 def open_fsd_page(self): 87 import webbrowser 88 webbrowser.open_new('http://localhost:8000/nodegraphs/{}/'.format(self.node_graph_id)) 89 90 def copy_nodes_to_clipboard(self, node_ids = None): 91 from nodegraph.tools import copy_nodes_to_clipboard 92 copy_nodes_to_clipboard(self.node_graph_id, node_ids) 93 94 def get_node_data(self, node_id): 95 return self.nodes_data[node_id] 96 97 @property 98 def service(self): 99 return sm.GetService('node_graph') 100 101 @property 102 def nodes_data(self): 103 return self._graph_data.nodes 104 105 @property 106 def name(self): 107 return self._graph_data.name 108 109 @property 110 def description(self): 111 return self._graph_data.description 112 113 @property 114 def parent_graph_id(self): 115 return self._graph_data.parentGraph 116 117 @property 118 def tags(self): 119 return self._graph_data.tags 120 121 @property 122 def is_server_graph(self): 123 return 'server' in self.tags 124 125 @property 126 def can_edit(self): 127 return False 128 129 @property 130 def zoom_level(self): 131 return self._settings.zoom_level 132 133 @zoom_level.setter 134 def zoom_level(self, value): 135 self._settings.zoom_level = value 136 137 @property 138 def pan_left(self): 139 return self._settings.pan_left 140 141 @pan_left.setter 142 def pan_left(self, value): 143 self._settings.pan_left = value 144 145 @property 146 def pan_top(self): 147 return self._settings.pan_top 148 149 @pan_top.setter 150 def pan_top(self, value): 151 self._settings.pan_top = value 152 153 154 class AuthoredNodeGraphViewController(NodeGraphViewController): 155 node_graph_component_class = AuthoredNodeGraphView 156 _node_view_controller_class = AuthoredNodeViewController 157 158 def __init__(self, node_graph_id): 159 self.selected_connection_point = None 160 self.on_selected_connection_point = signals.Signal('on_selected_connection_point') 161 self._node_graph_yaml = None 162 self._nodes_raw_dict = None 163 self._nodes_built_dict = None 164 self._nodes_object = None 165 self._has_changes = False 166 super(AuthoredNodeGraphViewController, self).__init__(node_graph_id) 167 168 def initialize(self): 169 from nodegraph.tools import load_node_graph_yaml 170 self._node_graph_yaml = load_node_graph_yaml(self.node_graph_id) 171 self._nodes_raw_dict = get_yaml_nodes_as_dict(self.node_graph_id) 172 self._nodes_built_dict = get_built_nodes_as_dict(self.node_graph_id) 173 self._nodes_object = None 174 self._has_changes = self._nodes_raw_dict != self._nodes_built_dict 175 176 @property 177 def nodes_data(self): 178 if self._nodes_object is None: 179 self._nodes_object = _get_nodes_as_object(self._nodes_raw_dict) 180 return self._nodes_object 181 182 @property 183 def can_edit(self): 184 return False 185 186 @property 187 def has_custom_graph(self): 188 from nodegraph.client.custom_graph import get_custom_node_graph 189 custom_node_graph_id = 'custom_{}'.format(self.node_graph_id) 190 return bool(get_custom_node_graph(custom_node_graph_id)) 191 192 def customize_graph(self, *args, **kwargs): 193 from nodegraph.client.custom_graph import customize_fsd_graph 194 custom_node_graph_id = customize_fsd_graph(self.node_graph_id) 195 open_node_graph(custom_node_graph_id) 196 197 def add_node(self, node_type_id, position, atom_type_id): 198 print('add_node', node_type_id, position, atom_type_id) 199 200 def duplicate_node(self, node_id): 201 print('duplicate_node', node_id) 202 203 def paste_from_clipboard(self, position, clipboard_data): 204 print('paste_from_clipboard', position) 205 206 def remove_nodes(self, node_ids): 207 print('remove_node', node_ids) 208 209 def add_node_connection(self, from_node_id, to_node_id, connection_id): 210 if 'input' not in get_node_type(self.nodes_data[to_node_id].nodeType).ports.inPorts: 211 return 212 if connection_id not in self.nodes_data[from_node_id]['connections']: 213 self.nodes_data[from_node_id]['connections'][connection_id] = [] 214 connections = self.nodes_data[from_node_id]['connections'][connection_id] 215 if to_node_id not in connections: 216 connections.append(to_node_id) 217 self.save() 218 219 def node_connection_clicked(self, connection_point): 220 print('node_connection_clicked', connection_point) 221 222 def clear_selected_connection_point(self): 223 pass 224 225 def save(self, *args, **kwargs): 226 print('save') 227 228 def reload_from_fsd(self, *args, **kwargs): 229 self._nodes_object = None 230 reload_node_graph_data() 231 self.on_update() 232 233 def build(self, *args, **kwargs): 234 print('build') 235 236 237 def _get_nodes_as_object(nodes_data): 238 from copy import deepcopy 239 from utillib import KeyVal 240 nodes_data = deepcopy(nodes_data) 241 for node_id in nodes_data: 242 nodes_data[node_id] = KeyVal(nodes_data[node_id]) 243 for parameter_id in nodes_data[node_id].nodeParameters: 244 value = nodes_data[node_id].nodeParameters[parameter_id].get('value', None) 245 connection = nodes_data[node_id].nodeParameters[parameter_id].get('connection', None) 246 if connection: 247 connection = KeyVal(connection) 248 nodes_data[node_id].nodeParameters[parameter_id] = KeyVal(value=value, connection=connection) 249 250 if 'atom_id' in nodes_data[node_id].nodeParameters: 251 for parameter_id in nodes_data[node_id].atomParameters: 252 value = nodes_data[node_id].atomParameters[parameter_id].get('value', None) 253 connection = nodes_data[node_id].atomParameters[parameter_id].get('connection', None) 254 if connection: 255 connection = KeyVal(connection) 256 nodes_data[node_id].atomParameters[parameter_id] = KeyVal(value=value, connection=connection) 257 258 return nodes_data 259 260 261 def get_new_node_id(): 262 import uuid 263 return str(uuid.uuid4()) 264 265 266 def open_node_graph(node_graph_id): 267 from nodegraph.client.ui.window import NodeGraphEditorWindow 268 NodeGraphEditorWindow.Open(node_graph_id=node_graph_id)