updates clean up setting wallpaper for graph canvas, updates to read metadata for canvas to display wallpaper from loaded xml file, update to allow reopening mobility player from node context

This commit is contained in:
Blake Harnden 2019-12-04 13:40:35 -08:00
parent 41a9b88189
commit 5a387537bb
5 changed files with 94 additions and 36 deletions

View file

@ -1,12 +1,14 @@
"""
Incorporate grpc into python tkinter GUI
"""
import json
import logging
import os
import time
from core.api.grpc import client, core_pb2
from coretk.dialogs.mobilityplayer import MobilityPlayerDialog
from coretk import appconfig
from coretk.dialogs.mobilityplayer import MobilityPlayer
from coretk.dialogs.sessions import SessionsDialog
from coretk.interface import InterfaceManager
from coretk.nodeutils import NodeDraw, NodeUtils
@ -141,6 +143,8 @@ class CoreClient:
logging.warning("unknown session event: %s", session_event)
elif event.HasField("node_event"):
self.handle_node_event(event.node_event)
elif event.HasField("config_event"):
logging.info("config event: %s", event)
else:
logging.info("unhandled event: %s", event)
@ -164,7 +168,7 @@ class CoreClient:
x = event.node.position.x
y = event.node.position.y
canvas_node = self.canvas_nodes[node_id]
canvas_node.move(x, y)
canvas_node.move(x, y, update=False)
def handle_throughputs(self, event):
interface_throughputs = event.interface_throughputs
@ -189,7 +193,6 @@ class CoreClient:
# get session data
response = self.client.get_session(self.session_id)
logging.info("joining session(%s): %s", self.session_id, response)
session = response.session
self.state = session.state
self.client.events(self.session_id, self.handle_events)
@ -235,9 +238,6 @@ class CoreClient:
node_id = int(_id / 1000)
self.set_emane_model_config(node_id, config.model, config.config, interface)
# draw session
self.app.canvas.reset_and_redraw(session)
# get node service config and file config
for node in session.nodes:
self.created_nodes.add(node.id)
@ -262,6 +262,13 @@ class CoreClient:
self.file_configs[node.id][service] = {}
self.file_configs[node.id][service][file] = response.data
# draw session
self.app.canvas.reset_and_redraw(session)
# get metadata
response = self.client.get_session_metadata(self.session_id)
self.parse_metadata(response.config)
if self.is_runtime():
self.app.toolbar.runtime_frame.tkraise()
else:
@ -271,6 +278,18 @@ class CoreClient:
def is_runtime(self):
return self.state == core_pb2.SessionState.RUNTIME
def parse_metadata(self, config):
# canvas settings
canvas_config = config.get("canvas")
if canvas_config:
logging.info("canvas metadata: %s", canvas_config)
canvas_config = json.loads(canvas_config)
wallpaper_style = canvas_config["wallpaper-style"]
self.app.canvas.scale_option.set(wallpaper_style)
wallpaper = canvas_config["wallpaper"]
wallpaper = str(appconfig.BACKGROUNDS_PATH.joinpath(wallpaper))
self.app.canvas.set_wallpaper(wallpaper)
def create_new_session(self):
"""
Create a new session
@ -372,9 +391,9 @@ class CoreClient:
# display mobility players
for node_id, config in self.mobility_configs.items():
canvas_node = self.canvas_nodes[node_id]
dialog = MobilityPlayerDialog(self.app, self.app, canvas_node, config)
dialog.show()
self.mobility_players[node_id] = dialog
mobility_player = MobilityPlayer(self.app, self.app, canvas_node, config)
mobility_player.show()
self.mobility_players[node_id] = mobility_player
def stop_session(self, session_id=None):
if not session_id:

View file

@ -269,7 +269,7 @@ router ospf6
<configuration name="annotation a0" value="{iconcoords {612.0 492.0}} {type text} {label {wireless network}} {labelcolor black} {fontfamily {Arial}} {fontsize {12}} {effects {bold}} {canvas c1}"/>
<configuration name="annotation a1" value="{iconcoords {142.0 112.0 393.0 291.0}} {type rectangle} {label {}} {labelcolor black} {fontfamily {Arial}} {fontsize {12}} {color #ebebde} {width 1} {border #ffffff} {rad 25} {canvas c1}"/>
<configuration name="annotation a2" value="{iconcoords {492.0 384.0}} {type text} {label {gateway}} {labelcolor black} {fontfamily {Arial}} {fontsize {12}} {effects {bold}} {canvas c1}"/>
<configuration name="canvas c1" value="{name {Canvas1}} {wallpaper-style {upperleft}} {wallpaper {sample1-bg.gif}}"/>
<configuration name="canvas" value='{"name": "Canvas1", "wallpaper-style": 1, "wallpaper": "sample1-bg.gif"}'/>
<configuration name="global_options" value="interface_names=no ip_addresses=yes ipv6_addresses=no node_labels=yes link_labels=yes show_api=no background_images=no annotations=yes grid=no traffic_start=0"/>
</session_metadata>
<default_services>

View file

@ -5,14 +5,11 @@ import logging
import tkinter as tk
from tkinter import filedialog, ttk
from PIL import Image
from coretk.appconfig import BACKGROUNDS_PATH
from coretk.dialogs.dialog import Dialog
from coretk.images import Images
PADX = 5
ABOVE_WALLPAPER = ["edge", "linkinfo", "wireless", "antenna", "nodename", "node"]
class CanvasBackgroundDialog(Dialog):
@ -178,23 +175,11 @@ class CanvasBackgroundDialog(Dialog):
filename = self.filename.get()
if not filename:
self.canvas.delete(self.canvas.wallpaper_id)
self.canvas.wallpaper = None
self.canvas.wallpaper_file = None
self.destroy()
return
try:
img = Image.open(filename)
self.canvas.wallpaper = img
self.canvas.wallpaper_file = filename
self.canvas.redraw()
for component in ABOVE_WALLPAPER:
self.canvas.tag_raise(component)
filename = None
try:
self.canvas.set_wallpaper(filename)
except FileNotFoundError:
logging.error("invalid background: %s", filename)
if self.canvas.wallpaper_id:
self.canvas.delete(self.canvas.wallpaper_id)
self.canvas.wallpaper_id = None
self.canvas.wallpaper_file = None
self.destroy()

View file

@ -1,7 +1,7 @@
import tkinter as tk
from tkinter import ttk
from core.api.grpc import core_pb2
from core.api.grpc.core_pb2 import MobilityAction
from coretk.dialogs.dialog import Dialog
from coretk.images import ImageEnum, Images
@ -9,6 +9,42 @@ PAD = 5
ICON_SIZE = 16
class MobilityPlayer:
def __init__(self, master, app, canvas_node, config):
self.master = master
self.app = app
self.canvas_node = canvas_node
self.config = config
self.dialog = None
self.state = None
def show(self):
if self.dialog:
self.dialog.destroy()
self.dialog = MobilityPlayerDialog(
self.master, self.app, self.canvas_node, self.config
)
if self.state == MobilityAction.START:
self.set_play()
elif self.state == MobilityAction.PAUSE:
self.set_pause()
else:
self.set_stop()
self.dialog.show()
def set_play(self):
self.dialog.set_play()
self.state = MobilityAction.START
def set_pause(self):
self.dialog.set_pause()
self.state = MobilityAction.PAUSE
def set_stop(self):
self.dialog.set_stop()
self.state = MobilityAction.STOP
class MobilityPlayerDialog(Dialog):
def __init__(self, master, app, canvas_node, config):
super().__init__(
@ -88,19 +124,19 @@ class MobilityPlayerDialog(Dialog):
self.set_play()
session_id = self.app.core.session_id
self.app.core.client.mobility_action(
session_id, self.node.id, core_pb2.MobilityAction.START
session_id, self.node.id, MobilityAction.START
)
def click_pause(self):
self.set_pause()
session_id = self.app.core.session_id
self.app.core.client.mobility_action(
session_id, self.node.id, core_pb2.MobilityAction.PAUSE
session_id, self.node.id, MobilityAction.PAUSE
)
def click_stop(self):
self.set_stop()
session_id = self.app.core.session_id
self.app.core.client.mobility_action(
session_id, self.node.id, core_pb2.MobilityAction.STOP
session_id, self.node.id, MobilityAction.STOP
)

View file

@ -3,7 +3,7 @@ import logging
import tkinter as tk
from tkinter import font
from PIL import ImageTk
from PIL import Image, ImageTk
from core.api.grpc import core_pb2
from core.api.grpc.core_pb2 import NodeType
@ -21,6 +21,7 @@ from coretk.nodeutils import NodeUtils
from coretk.shape import Shape
NODE_TEXT_OFFSET = 5
ABOVE_WALLPAPER = ["edge", "linkinfo", "wireless", "antenna", "nodename", "node"]
class GraphMode(enum.Enum):
@ -583,6 +584,21 @@ class CanvasGraph(tk.Canvas):
else:
self.itemconfig("gridline", state=tk.HIDDEN)
def set_wallpaper(self, filename):
logging.info("setting wallpaper: %s", filename)
if filename is not None:
img = Image.open(filename)
self.wallpaper = img
self.wallpaper_file = filename
self.redraw()
for component in ABOVE_WALLPAPER:
self.tag_raise(component)
else:
if self.wallpaper_id is not None:
self.delete(self.wallpaper_id)
self.wallpaper = None
self.wallpaper_file = None
def is_selection_mode(self):
return self.mode == GraphMode.SELECT
@ -696,7 +712,7 @@ class CanvasNode:
self.canvas.itemconfig(self.id, image=self.image)
self.canvas.itemconfig(self.text_id, text=self.core_node.name)
def move(self, x, y):
def move(self, x, y, update=True):
old_x = self.core_node.position.x
old_y = self.core_node.position.y
x_offset = x - old_x
@ -720,7 +736,7 @@ class CanvasNode:
self.canvas.coords(edge.id, x, y, x2, y2)
else:
self.canvas.coords(edge.id, x1, y1, x, y)
if self.app.core.is_runtime():
if self.app.core.is_runtime() and update:
self.app.core.edit_node(self.core_node.id, int(x), int(y))
def on_enter(self, event):
@ -784,6 +800,8 @@ class CanvasNode:
def show_mobility_player(self):
self.canvas.context = None
mobility_player = self.app.core.mobility_players[self.core_node.id]
mobility_player.show()
def show_emane_config(self):
self.canvas.context = None