added canvas to protobuf node messages, added node canvas id to grpc server handling, updating pygui to draw canvases based on joined session and add nodes to respective canvas
This commit is contained in:
parent
9621df6bc4
commit
b01249bb4e
5 changed files with 67 additions and 25 deletions
|
@ -67,6 +67,7 @@ def add_node_data(node_proto: core_pb2.Node) -> Tuple[NodeTypes, int, NodeOption
|
||||||
image=node_proto.image,
|
image=node_proto.image,
|
||||||
services=node_proto.services,
|
services=node_proto.services,
|
||||||
config_services=node_proto.config_services,
|
config_services=node_proto.config_services,
|
||||||
|
canvas=node_proto.canvas,
|
||||||
)
|
)
|
||||||
if node_proto.emane:
|
if node_proto.emane:
|
||||||
options.emane = node_proto.emane
|
options.emane = node_proto.emane
|
||||||
|
@ -290,6 +291,7 @@ def get_node_proto(session: Session, node: NodeBase) -> core_pb2.Node:
|
||||||
config_services=config_services,
|
config_services=config_services,
|
||||||
dir=node_dir,
|
dir=node_dir,
|
||||||
channel=channel,
|
channel=channel,
|
||||||
|
canvas=node.canvas,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -649,6 +649,7 @@ class Node:
|
||||||
geo: Geo = None
|
geo: Geo = None
|
||||||
dir: str = None
|
dir: str = None
|
||||||
channel: str = None
|
channel: str = None
|
||||||
|
canvas: int = None
|
||||||
|
|
||||||
# configurations
|
# configurations
|
||||||
emane_model_configs: Dict[
|
emane_model_configs: Dict[
|
||||||
|
@ -683,6 +684,7 @@ class Node:
|
||||||
geo=Geo.from_proto(proto.geo),
|
geo=Geo.from_proto(proto.geo),
|
||||||
dir=proto.dir,
|
dir=proto.dir,
|
||||||
channel=proto.channel,
|
channel=proto.channel,
|
||||||
|
canvas=proto.canvas,
|
||||||
)
|
)
|
||||||
|
|
||||||
def to_proto(self) -> core_pb2.Node:
|
def to_proto(self) -> core_pb2.Node:
|
||||||
|
@ -700,6 +702,7 @@ class Node:
|
||||||
server=self.server,
|
server=self.server,
|
||||||
dir=self.dir,
|
dir=self.dir,
|
||||||
channel=self.channel,
|
channel=self.channel,
|
||||||
|
canvas=self.canvas,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -704,6 +704,7 @@ class CanvasGraph(tk.Canvas):
|
||||||
)
|
)
|
||||||
if not core_node:
|
if not core_node:
|
||||||
return
|
return
|
||||||
|
core_node.canvas = self.id
|
||||||
try:
|
try:
|
||||||
image_enum = self.manager.node_draw.image_enum
|
image_enum = self.manager.node_draw.image_enum
|
||||||
self.manager.node_draw.image = self.app.get_icon(image_enum, ICON_SIZE)
|
self.manager.node_draw.image = self.app.get_icon(image_enum, ICON_SIZE)
|
||||||
|
|
|
@ -3,12 +3,12 @@ import tkinter as tk
|
||||||
from tkinter import BooleanVar, messagebox, ttk
|
from tkinter import BooleanVar, messagebox, ttk
|
||||||
from typing import TYPE_CHECKING, Dict, Optional, Set, Tuple, ValuesView
|
from typing import TYPE_CHECKING, Dict, Optional, Set, Tuple, ValuesView
|
||||||
|
|
||||||
from core.api.grpc.wrappers import Session
|
from core.api.grpc.wrappers import LinkType, Session
|
||||||
from core.gui.graph import tags
|
from core.gui.graph import tags
|
||||||
from core.gui.graph.enums import GraphMode
|
from core.gui.graph.enums import GraphMode
|
||||||
from core.gui.graph.graph import CanvasGraph
|
from core.gui.graph.graph import CanvasGraph
|
||||||
from core.gui.graph.shapeutils import ShapeType
|
from core.gui.graph.shapeutils import ShapeType
|
||||||
from core.gui.nodeutils import NodeDraw
|
from core.gui.nodeutils import NodeDraw, NodeUtils
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from core.gui.app import Application
|
from core.gui.app import Application
|
||||||
|
@ -79,35 +79,36 @@ class CanvasManager:
|
||||||
|
|
||||||
def _next_id(self) -> int:
|
def _next_id(self) -> int:
|
||||||
_id = 1
|
_id = 1
|
||||||
tab_ids = set(self.unique_ids.values())
|
canvas_ids = set(self.unique_ids.values())
|
||||||
while _id in tab_ids:
|
while _id in canvas_ids:
|
||||||
_id += 1
|
_id += 1
|
||||||
return _id
|
return _id
|
||||||
|
|
||||||
def current(self) -> CanvasGraph:
|
def current(self) -> CanvasGraph:
|
||||||
unique_id = self.notebook.select()
|
unique_id = self.notebook.select()
|
||||||
tab_id = self.unique_ids[unique_id]
|
canvas_id = self.unique_ids[unique_id]
|
||||||
return self.canvases[tab_id]
|
return self.canvases[canvas_id]
|
||||||
|
|
||||||
def all(self) -> ValuesView[CanvasGraph]:
|
def all(self) -> ValuesView[CanvasGraph]:
|
||||||
return self.canvases.values()
|
return self.canvases.values()
|
||||||
|
|
||||||
def add_canvas(self) -> CanvasGraph:
|
def add_canvas(self, canvas_id: int = None) -> CanvasGraph:
|
||||||
# create tab frame
|
# create tab frame
|
||||||
tab = ttk.Frame(self.notebook, padding=0)
|
tab = ttk.Frame(self.notebook, padding=0)
|
||||||
tab.grid(sticky=tk.NSEW)
|
tab.grid(sticky=tk.NSEW)
|
||||||
tab.columnconfigure(0, weight=1)
|
tab.columnconfigure(0, weight=1)
|
||||||
tab.rowconfigure(0, weight=1)
|
tab.rowconfigure(0, weight=1)
|
||||||
tab_id = self._next_id()
|
if canvas_id is None:
|
||||||
self.notebook.add(tab, text=f"Canvas {tab_id}")
|
canvas_id = self._next_id()
|
||||||
|
self.notebook.add(tab, text=f"Canvas {canvas_id}")
|
||||||
unique_id = self.notebook.tabs()[-1]
|
unique_id = self.notebook.tabs()[-1]
|
||||||
logging.info("tab(%s) is %s", unique_id, tab_id)
|
logging.info("tab(%s) is %s", unique_id, canvas_id)
|
||||||
self.unique_ids[unique_id] = tab_id
|
self.unique_ids[unique_id] = canvas_id
|
||||||
|
|
||||||
# create canvas
|
# create canvas
|
||||||
canvas = CanvasGraph(tab, self.app, self, self.core, tab_id)
|
canvas = CanvasGraph(tab, self.app, self, self.core, canvas_id)
|
||||||
canvas.grid(sticky=tk.NSEW)
|
canvas.grid(sticky=tk.NSEW)
|
||||||
self.canvases[tab_id] = canvas
|
self.canvases[canvas_id] = canvas
|
||||||
|
|
||||||
# add scrollbars
|
# add scrollbars
|
||||||
scroll_y = ttk.Scrollbar(tab, command=canvas.yview)
|
scroll_y = ttk.Scrollbar(tab, command=canvas.yview)
|
||||||
|
@ -124,14 +125,14 @@ class CanvasManager:
|
||||||
return
|
return
|
||||||
unique_id = self.notebook.select()
|
unique_id = self.notebook.select()
|
||||||
self.notebook.forget(unique_id)
|
self.notebook.forget(unique_id)
|
||||||
tab_id = self.unique_ids.pop(unique_id)
|
canvas_id = self.unique_ids.pop(unique_id)
|
||||||
self.canvases.pop(tab_id)
|
self.canvases.pop(canvas_id)
|
||||||
# TODO: handle clearing out canvas related nodes and links
|
# TODO: handle clearing out canvas related nodes and links from core client
|
||||||
|
|
||||||
def join(self, session: Session) -> None:
|
def join(self, session: Session) -> None:
|
||||||
# clear out all canvas
|
# clear out all canvas
|
||||||
for tab_id in self.notebook.tabs():
|
for canvas_id in self.notebook.tabs():
|
||||||
self.notebook.forget(tab_id)
|
self.notebook.forget(canvas_id)
|
||||||
self.canvases.clear()
|
self.canvases.clear()
|
||||||
|
|
||||||
# reset settings
|
# reset settings
|
||||||
|
@ -147,11 +148,45 @@ class CanvasManager:
|
||||||
self.annotation_type = None
|
self.annotation_type = None
|
||||||
self.node_draw = None
|
self.node_draw = None
|
||||||
|
|
||||||
# TODO: create and add nodes to all associated canvases
|
if session.nodes:
|
||||||
# draw initial tab(s) and session
|
self.draw_session(session)
|
||||||
canvas = self.add_canvas()
|
else:
|
||||||
|
self.add_canvas()
|
||||||
|
|
||||||
# draw session on canvas
|
def draw_session(self, session: Session) -> None:
|
||||||
canvas.reset_and_redraw(session)
|
# create session nodes
|
||||||
self.core.parse_metadata(canvas)
|
for core_node in session.nodes.values():
|
||||||
canvas.organize()
|
# get tab id for node
|
||||||
|
canvas_id = core_node.canvas if core_node.canvas > 0 else 1
|
||||||
|
|
||||||
|
# get or create canvas
|
||||||
|
canvas = self.canvases.get(canvas_id)
|
||||||
|
if not canvas:
|
||||||
|
canvas = self.add_canvas(canvas_id)
|
||||||
|
|
||||||
|
# add node, avoiding ignored nodes
|
||||||
|
if NodeUtils.is_ignore_node(core_node.type):
|
||||||
|
continue
|
||||||
|
logging.debug("drawing node: %s", core_node)
|
||||||
|
canvas.add_core_node(core_node)
|
||||||
|
|
||||||
|
# draw existing links
|
||||||
|
for link in session.links:
|
||||||
|
logging.debug("drawing link: %s", link)
|
||||||
|
node1 = self.core.get_canvas_node(link.node1_id)
|
||||||
|
node2 = self.core.get_canvas_node(link.node2_id)
|
||||||
|
# TODO: handle edges for nodes on different canvases
|
||||||
|
if node1.canvas == node2.canvas:
|
||||||
|
canvas = node1.canvas
|
||||||
|
if link.type == LinkType.WIRELESS:
|
||||||
|
canvas.add_wireless_edge(node1, node2, link)
|
||||||
|
else:
|
||||||
|
canvas.add_wired_edge(node1, node2, link)
|
||||||
|
else:
|
||||||
|
logging.error("cant handle nodes linked between canvases")
|
||||||
|
|
||||||
|
# TODO: handle metadata
|
||||||
|
# self.core.parse_metadata(canvas)
|
||||||
|
# organize all canvases
|
||||||
|
for canvas in self.canvases.values():
|
||||||
|
canvas.organize()
|
||||||
|
|
|
@ -752,6 +752,7 @@ message Node {
|
||||||
Geo geo = 12;
|
Geo geo = 12;
|
||||||
string dir = 13;
|
string dir = 13;
|
||||||
string channel = 14;
|
string channel = 14;
|
||||||
|
int32 canvas = 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Link {
|
message Link {
|
||||||
|
|
Loading…
Reference in a new issue