pygui add in cut functionality, currently not including configurations
This commit is contained in:
parent
efa5506c80
commit
54eab4576d
4 changed files with 72 additions and 60 deletions
|
@ -1061,31 +1061,32 @@ class CoreClient:
|
|||
self.canvas_nodes[_to].core_node.services[:] = services
|
||||
logging.debug("copying node %s service to node %s", _from, _to)
|
||||
|
||||
def copy_node_config(self, _from: int, _to: int):
|
||||
node_type = self.canvas_nodes[_from].core_node.type
|
||||
def copy_node_config(self, src_node: core_pb2.Node, dst_id: int):
|
||||
node_type = src_node.type
|
||||
if node_type == core_pb2.NodeType.DEFAULT:
|
||||
services = self.canvas_nodes[_from].core_node.services
|
||||
self.canvas_nodes[_to].core_node.services[:] = services
|
||||
config = self.service_configs.get(_from)
|
||||
services = src_node.services
|
||||
dst_node = self.canvas_nodes[dst_id]
|
||||
dst_node.core_node.services[:] = services
|
||||
config = self.service_configs.get(src_node.id)
|
||||
if config:
|
||||
self.service_configs[_to] = config
|
||||
file_configs = self.file_configs.get(_from)
|
||||
self.service_configs[dst_id] = config
|
||||
file_configs = self.file_configs.get(src_node.id)
|
||||
if file_configs:
|
||||
for key, value in file_configs.items():
|
||||
if _to not in self.file_configs:
|
||||
self.file_configs[_to] = {}
|
||||
self.file_configs[_to][key] = value
|
||||
if dst_id not in self.file_configs:
|
||||
self.file_configs[dst_id] = {}
|
||||
self.file_configs[dst_id][key] = value
|
||||
elif node_type == core_pb2.NodeType.WIRELESS_LAN:
|
||||
config = self.wlan_configs.get(_from)
|
||||
config = self.wlan_configs.get(src_node.id)
|
||||
if config:
|
||||
self.wlan_configs[_to] = config
|
||||
config = self.mobility_configs.get(_from)
|
||||
self.wlan_configs[dst_id] = config
|
||||
config = self.mobility_configs.get(src_node.id)
|
||||
if config:
|
||||
self.mobility_configs[_to] = config
|
||||
self.mobility_configs[dst_id] = config
|
||||
elif node_type == core_pb2.NodeType.EMANE:
|
||||
config = self.emane_model_configs.get(_from)
|
||||
config = self.emane_model_configs.get(src_node.id)
|
||||
if config:
|
||||
self.emane_model_configs[_to] = config
|
||||
self.emane_model_configs[dst_id] = config
|
||||
|
||||
def service_been_modified(self, node_id: int) -> bool:
|
||||
return node_id in self.modified_service_nodes
|
||||
|
|
|
@ -894,61 +894,63 @@ class CanvasGraph(tk.Canvas):
|
|||
self.core.create_link(edge, source, dest)
|
||||
|
||||
def copy(self):
|
||||
if self.app.core.is_runtime():
|
||||
if self.core.is_runtime():
|
||||
logging.info("copy is disabled during runtime state")
|
||||
return
|
||||
if self.selection:
|
||||
logging.debug("to copy %s nodes", len(self.selection))
|
||||
self.to_copy = self.selection.keys()
|
||||
logging.info("to copy nodes: %s", self.selection)
|
||||
self.to_copy.clear()
|
||||
for node_id in self.selection.keys():
|
||||
canvas_node = self.nodes[node_id]
|
||||
self.to_copy.append(canvas_node)
|
||||
|
||||
def paste(self):
|
||||
if self.app.core.is_runtime():
|
||||
if self.core.is_runtime():
|
||||
logging.info("paste is disabled during runtime state")
|
||||
return
|
||||
# maps original node canvas id to copy node canvas id
|
||||
copy_map = {}
|
||||
# the edges that will be copy over
|
||||
to_copy_edges = []
|
||||
for canvas_nid in self.to_copy:
|
||||
core_node = self.nodes[canvas_nid].core_node
|
||||
for canvas_node in self.to_copy:
|
||||
core_node = canvas_node.core_node
|
||||
actual_x = core_node.position.x + 50
|
||||
actual_y = core_node.position.y + 50
|
||||
scaled_x, scaled_y = self.get_scaled_coords(actual_x, actual_y)
|
||||
|
||||
copy = self.core.create_node(
|
||||
actual_x, actual_y, core_node.type, core_node.model
|
||||
)
|
||||
node = CanvasNode(
|
||||
self.master, scaled_x, scaled_y, copy, self.nodes[canvas_nid].image
|
||||
)
|
||||
node = CanvasNode(self.master, scaled_x, scaled_y, copy, canvas_node.image)
|
||||
|
||||
# add new node to modified_service_nodes set if that set contains the
|
||||
# to_copy node
|
||||
if self.app.core.service_been_modified(core_node.id):
|
||||
self.app.core.modified_service_nodes.add(copy.id)
|
||||
if self.core.service_been_modified(core_node.id):
|
||||
self.core.modified_service_nodes.add(copy.id)
|
||||
|
||||
copy_map[canvas_nid] = node.id
|
||||
copy_map[canvas_node.id] = node.id
|
||||
self.core.canvas_nodes[copy.id] = node
|
||||
self.nodes[node.id] = node
|
||||
self.core.copy_node_config(core_node.id, copy.id)
|
||||
|
||||
edges = self.nodes[canvas_nid].edges
|
||||
for edge in edges:
|
||||
self.core.copy_node_config(core_node, copy.id)
|
||||
for edge in canvas_node.edges:
|
||||
if edge.src not in self.to_copy or edge.dst not in self.to_copy:
|
||||
if canvas_nid == edge.src:
|
||||
self.create_edge(node, self.nodes[edge.dst])
|
||||
elif canvas_nid == edge.dst:
|
||||
self.create_edge(self.nodes[edge.src], node)
|
||||
if canvas_node.id == edge.src:
|
||||
dst_node = self.nodes[edge.dst]
|
||||
self.create_edge(node, dst_node)
|
||||
elif canvas_node.id == edge.dst:
|
||||
src_node = self.nodes[edge.src]
|
||||
self.create_edge(src_node, node)
|
||||
else:
|
||||
to_copy_edges.append(edge)
|
||||
|
||||
# copy link and link config
|
||||
for edge in to_copy_edges:
|
||||
source_node_copy = self.nodes[copy_map[edge.token[0]]]
|
||||
dest_node_copy = self.nodes[copy_map[edge.token[1]]]
|
||||
self.create_edge(source_node_copy, dest_node_copy)
|
||||
copy_edge = self.edges[
|
||||
create_edge_token(source_node_copy.id, dest_node_copy.id)
|
||||
]
|
||||
src_node_id = copy_map[edge.token[0]]
|
||||
dst_node_id = copy_map[edge.token[1]]
|
||||
src_node_copy = self.nodes[src_node_id]
|
||||
dst_node_copy = self.nodes[dst_node_id]
|
||||
self.create_edge(src_node_copy, dst_node_copy)
|
||||
token = create_edge_token(src_node_copy.id, dst_node_copy.id)
|
||||
copy_edge = self.edges[token]
|
||||
copy_link = copy_edge.link
|
||||
options = edge.link.options
|
||||
copy_link.options.CopyFrom(options)
|
||||
|
|
|
@ -225,12 +225,16 @@ class CanvasNode:
|
|||
context.add_command(label="Select Members", state=tk.DISABLED)
|
||||
edit_menu = tk.Menu(context)
|
||||
themes.style_menu(edit_menu)
|
||||
edit_menu.add_command(label="Cut", state=tk.DISABLED)
|
||||
edit_menu.add_command(label="Cut", command=self.click_cut)
|
||||
edit_menu.add_command(label="Copy", command=self.canvas_copy)
|
||||
edit_menu.add_command(label="Delete", command=self.canvas_delete)
|
||||
context.add_cascade(label="Edit", menu=edit_menu)
|
||||
return context
|
||||
|
||||
def click_cut(self) -> None:
|
||||
self.canvas_copy()
|
||||
self.canvas_delete()
|
||||
|
||||
def canvas_delete(self) -> None:
|
||||
self.canvas.clear_selection()
|
||||
self.canvas.selection[self.id] = self
|
||||
|
|
|
@ -103,14 +103,14 @@ class Menubar(tk.Menu):
|
|||
menu.add_command(label="Undo", accelerator="Ctrl+Z", state=tk.DISABLED)
|
||||
menu.add_command(label="Redo", accelerator="Ctrl+Y", state=tk.DISABLED)
|
||||
menu.add_separator()
|
||||
menu.add_command(label="Cut", accelerator="Ctrl+X", state=tk.DISABLED)
|
||||
menu.add_command(label="Cut", accelerator="Ctrl+X", command=self.click_cut)
|
||||
menu.add_command(label="Copy", accelerator="Ctrl+C", command=self.click_copy)
|
||||
menu.add_command(label="Paste", accelerator="Ctrl+V", command=self.click_paste)
|
||||
menu.add_command(
|
||||
label="Delete", accelerator="Ctrl+D", command=self.click_delete
|
||||
)
|
||||
self.add_cascade(label="Edit", menu=menu)
|
||||
|
||||
self.app.master.bind_all("<Control-x>", self.click_cut)
|
||||
self.app.master.bind_all("<Control-c>", self.click_copy)
|
||||
self.app.master.bind_all("<Control-v>", self.click_paste)
|
||||
self.app.master.bind_all("<Control-d>", self.click_delete)
|
||||
|
@ -343,16 +343,17 @@ class Menubar(tk.Menu):
|
|||
self.app.menubar.update_recent_files()
|
||||
|
||||
def change_menubar_item_state(self, is_runtime: bool) -> None:
|
||||
for i in range(self.edit_menu.index("end")):
|
||||
labels = {"Copy", "Paste", "Delete", "Cut"}
|
||||
for i in range(self.edit_menu.index(tk.END) + 1):
|
||||
try:
|
||||
label_name = self.edit_menu.entrycget(i, "label")
|
||||
if label_name in ["Copy", "Paste"]:
|
||||
if is_runtime:
|
||||
self.edit_menu.entryconfig(i, state="disabled")
|
||||
else:
|
||||
self.edit_menu.entryconfig(i, state="normal")
|
||||
label = self.edit_menu.entrycget(i, "label")
|
||||
logging.info("menu label: %s", label)
|
||||
if label not in labels:
|
||||
continue
|
||||
state = tk.DISABLED if is_runtime else tk.NORMAL
|
||||
self.edit_menu.entryconfig(i, state=state)
|
||||
except tk.TclError:
|
||||
logging.debug("Ignore separators")
|
||||
pass
|
||||
|
||||
def prompt_save_running_session(self, quit_app: bool = False) -> None:
|
||||
"""
|
||||
|
@ -410,13 +411,17 @@ class Menubar(tk.Menu):
|
|||
dialog.show()
|
||||
|
||||
def click_copy(self, _event: tk.Event = None) -> None:
|
||||
self.app.canvas.copy()
|
||||
self.canvas.copy()
|
||||
|
||||
def click_paste(self, _event: tk.Event = None) -> None:
|
||||
self.app.canvas.paste()
|
||||
self.canvas.paste()
|
||||
|
||||
def click_delete(self, _event: tk.Event = None) -> None:
|
||||
self.app.canvas.delete_selected_objects()
|
||||
self.canvas.delete_selected_objects()
|
||||
|
||||
def click_cut(self, _event: tk.Event = None) -> None:
|
||||
self.canvas.copy()
|
||||
self.canvas.delete_selected_objects()
|
||||
|
||||
def click_session_options(self) -> None:
|
||||
logging.debug("Click options")
|
||||
|
@ -444,14 +449,14 @@ class Menubar(tk.Menu):
|
|||
dialog.show()
|
||||
|
||||
def click_autogrid(self) -> None:
|
||||
width, height = self.app.canvas.current_dimensions
|
||||
width, height = self.canvas.current_dimensions
|
||||
padding = (ICON_SIZE / 2) + 10
|
||||
layout_size = padding + ICON_SIZE
|
||||
col_count = width // layout_size
|
||||
logging.info(
|
||||
"auto grid layout: dimens(%s, %s) col(%s)", width, height, col_count
|
||||
"auto grid layout: dimension(%s, %s) col(%s)", width, height, col_count
|
||||
)
|
||||
for i, node in enumerate(self.app.canvas.nodes.values()):
|
||||
for i, node in enumerate(self.canvas.nodes.values()):
|
||||
col = i % col_count
|
||||
row = i // col_count
|
||||
x = (col * layout_size) + padding
|
||||
|
|
Loading…
Add table
Reference in a new issue