pygui: changes to support saving and loading canvas backgrounds to xml, canvas dimensions will apply globally

This commit is contained in:
Blake Harnden 2020-12-17 12:25:11 -08:00
parent 5d436dd94d
commit 4a8f8557a6
7 changed files with 123 additions and 108 deletions

View file

@ -37,11 +37,12 @@ if TYPE_CHECKING:
from core.gui.graph.manager import CanvasManager
from core.gui.coreclient import CoreClient
ZOOM_IN = 1.1
ZOOM_OUT = 0.9
ICON_SIZE = 48
MOVE_NODE_MODES = {GraphMode.NODE, GraphMode.SELECT}
MOVE_SHAPE_MODES = {GraphMode.ANNOTATION, GraphMode.SELECT}
ZOOM_IN: float = 1.1
ZOOM_OUT: float = 0.9
ICON_SIZE: int = 48
MOVE_NODE_MODES: Set[GraphMode] = {GraphMode.NODE, GraphMode.SELECT}
MOVE_SHAPE_MODES: Set[GraphMode] = {GraphMode.ANNOTATION, GraphMode.SELECT}
BACKGROUND_COLOR: str = "#cccccc"
class CanvasGraph(tk.Canvas):
@ -49,14 +50,15 @@ class CanvasGraph(tk.Canvas):
self,
master: tk.BaseWidget,
app: "Application",
canvas_manager: "CanvasManager",
manager: "CanvasManager",
core: "CoreClient",
_id: int,
dimensions: Tuple[int, int],
) -> None:
super().__init__(master, highlightthickness=0, background="#cccccc")
super().__init__(master, highlightthickness=0, background=BACKGROUND_COLOR)
self.id: int = _id
self.app: "Application" = app
self.manager: "CanvasManager" = canvas_manager
self.manager: "CanvasManager" = manager
self.core: "CoreClient" = core
self.selection: Dict[int, int] = {}
self.select_box: Optional[Shape] = None
@ -72,10 +74,7 @@ class CanvasGraph(tk.Canvas):
self.drawing_edge: Optional[CanvasEdge] = None
self.rect: Optional[int] = None
self.shape_drawing: bool = False
width = self.app.guiconfig.preferences.width
height = self.app.guiconfig.preferences.height
self.default_dimensions: Tuple[int, int] = (width, height)
self.current_dimensions: Tuple[int, int] = self.default_dimensions
self.current_dimensions: Tuple[int, int] = dimensions
self.ratio: float = 1.0
self.offset: Tuple[int, int] = (0, 0)
self.cursor: Tuple[int, int] = (0, 0)
@ -105,7 +104,7 @@ class CanvasGraph(tk.Canvas):
if self.rect is not None:
self.delete(self.rect)
if not dimensions:
dimensions = self.default_dimensions
dimensions = self.manager.default_dimensions
self.current_dimensions = dimensions
self.rect = self.create_rectangle(
0,
@ -845,7 +844,7 @@ class CanvasGraph(tk.Canvas):
self.tag_raise(tag)
def set_wallpaper(self, filename: Optional[str]) -> None:
logging.debug("setting wallpaper: %s", filename)
logging.info("setting canvas(%s) background: %s", self.id, filename)
if filename:
img = Image.open(filename)
self.wallpaper = img

View file

@ -52,6 +52,7 @@ class CanvasManager:
self.app.guiconfig.preferences.width,
self.app.guiconfig.preferences.height,
)
self.current_dimensions: Tuple[int, int] = self.default_dimensions
self.show_node_labels: ShowVar = ShowVar(self, tags.NODE_LABEL, value=True)
self.show_link_labels: ShowVar = ShowVar(self, tags.LINK_LABEL, value=True)
self.show_links: ShowVar = ShowVar(self, tags.EDGE, value=True)
@ -92,6 +93,12 @@ class CanvasManager:
def all(self) -> ValuesView[CanvasGraph]:
return self.canvases.values()
def get(self, canvas_id: int) -> CanvasGraph:
canvas = self.canvases.get(canvas_id)
if not canvas:
canvas = self.add_canvas(canvas_id)
return canvas
def add_canvas(self, canvas_id: int = None) -> CanvasGraph:
# create tab frame
tab = ttk.Frame(self.notebook, padding=0)
@ -102,11 +109,12 @@ class CanvasManager:
canvas_id = self._next_id()
self.notebook.add(tab, text=f"Canvas {canvas_id}")
unique_id = self.notebook.tabs()[-1]
logging.info("tab(%s) is %s", unique_id, canvas_id)
self.unique_ids[unique_id] = canvas_id
# create canvas
canvas = CanvasGraph(tab, self.app, self, self.core, canvas_id)
canvas = CanvasGraph(
tab, self.app, self, self.core, canvas_id, self.default_dimensions
)
canvas.grid(sticky=tk.NSEW)
self.canvases[canvas_id] = canvas
@ -148,22 +156,15 @@ class CanvasManager:
self.annotation_type = None
self.node_draw = None
if session.nodes:
self.draw_session(session)
else:
self.add_canvas()
# draw session
self.draw_session(session)
def draw_session(self, session: Session) -> None:
# create session nodes
for core_node in session.nodes.values():
# 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)
canvas = self.get(canvas_id)
# add node, avoiding ignored nodes
if NodeUtils.is_ignore_node(core_node.type):
continue
@ -185,8 +186,17 @@ class CanvasManager:
else:
logging.error("cant handle nodes linked between canvases")
# TODO: handle metadata
# self.core.parse_metadata(canvas)
# organize all canvases
# parse metadata and organize canvases
self.core.parse_metadata()
for canvas in self.canvases.values():
canvas.organize()
# create a default canvas if none were created prior
if not self.canvases:
self.add_canvas()
def redraw_canvases(self, dimensions: Tuple[int, int]) -> None:
for canvas in self.canvases.values():
canvas.redraw_canvas(dimensions)
if canvas.wallpaper:
canvas.redraw_wallpaper()

View file

@ -85,7 +85,7 @@ class Shape:
fill=self.shape_data.fill_color,
outline=self.shape_data.border_color,
width=self.shape_data.border_width,
state=self.canvas.show_annotations.state(),
state=self.app.manager.show_annotations.state(),
)
self.draw_shape_text()
elif self.shape_type == ShapeType.RECTANGLE:
@ -99,7 +99,7 @@ class Shape:
fill=self.shape_data.fill_color,
outline=self.shape_data.border_color,
width=self.shape_data.border_width,
state=self.canvas.show_annotations.state(),
state=self.app.manager.show_annotations.state(),
)
self.draw_shape_text()
elif self.shape_type == ShapeType.TEXT:
@ -111,7 +111,7 @@ class Shape:
text=self.shape_data.text,
fill=self.shape_data.text_color,
font=font,
state=self.canvas.show_annotations.state(),
state=self.app.manager.show_annotations.state(),
)
else:
logging.error("unknown shape type: %s", self.shape_type)
@ -139,7 +139,7 @@ class Shape:
text=self.shape_data.text,
fill=self.shape_data.text_color,
font=font,
state=self.canvas.show_annotations.state(),
state=self.app.manager.show_annotations.state(),
)
def shape_motion(self, x1: float, y1: float) -> None: