pygui: refactored images.py and fixed issue with recreating a default config.yaml every time the gui was started
This commit is contained in:
parent
47ac4c850d
commit
a6fadb76cc
16 changed files with 96 additions and 103 deletions
|
@ -7,7 +7,7 @@ from typing import Any, Dict, Optional, Type
|
|||
|
||||
import grpc
|
||||
|
||||
from core.gui import appconfig
|
||||
from core.gui import appconfig, images
|
||||
from core.gui import nodeutils as nutils
|
||||
from core.gui import themes
|
||||
from core.gui.appconfig import GuiConfig
|
||||
|
@ -16,7 +16,7 @@ from core.gui.dialogs.error import ErrorDialog
|
|||
from core.gui.frames.base import InfoFrameBase
|
||||
from core.gui.frames.default import DefaultInfoFrame
|
||||
from core.gui.graph.manager import CanvasManager
|
||||
from core.gui.images import ImageEnum, Images
|
||||
from core.gui.images import ImageEnum
|
||||
from core.gui.menubar import Menubar
|
||||
from core.gui.statusbar import StatusBar
|
||||
from core.gui.themes import PADY
|
||||
|
@ -78,7 +78,7 @@ class Application(ttk.Frame):
|
|||
self.master.title("CORE")
|
||||
self.center()
|
||||
self.master.protocol("WM_DELETE_WINDOW", self.on_closing)
|
||||
image = Images.get(ImageEnum.CORE, 16)
|
||||
image = images.from_enum(ImageEnum.CORE, width=images.DIALOG_SIZE)
|
||||
self.master.tk.call("wm", "iconphoto", self.master._w, image)
|
||||
self.master.option_add("*tearOff", tk.FALSE)
|
||||
self.setup_file_dialogs()
|
||||
|
@ -197,10 +197,10 @@ class Application(ttk.Frame):
|
|||
self.toolbar.set_design()
|
||||
|
||||
def get_icon(self, image_enum: ImageEnum, width: int) -> PhotoImage:
|
||||
return Images.get(image_enum, int(width * self.app_scale))
|
||||
return images.from_enum(image_enum, width=width, scale=self.app_scale)
|
||||
|
||||
def get_custom_icon(self, image_file: str, width: int) -> PhotoImage:
|
||||
return Images.get_custom(image_file, int(width * self.app_scale))
|
||||
return images.from_name(image_file, width=width, scale=self.app_scale)
|
||||
|
||||
def close(self) -> None:
|
||||
self.master.destroy()
|
||||
|
|
|
@ -206,20 +206,19 @@ def check_directory() -> None:
|
|||
MOBILITY_PATH.mkdir(exist_ok=True)
|
||||
XMLS_PATH.mkdir(exist_ok=True)
|
||||
SCRIPT_PATH.mkdir(exist_ok=True)
|
||||
|
||||
copy_files(LOCAL_ICONS_PATH, ICONS_PATH)
|
||||
copy_files(LOCAL_BACKGROUND_PATH, BACKGROUNDS_PATH)
|
||||
copy_files(LOCAL_XMLS_PATH, XMLS_PATH)
|
||||
copy_files(LOCAL_MOBILITY_PATH, MOBILITY_PATH)
|
||||
|
||||
terminal = find_terminal()
|
||||
if "EDITOR" in os.environ:
|
||||
editor = EDITORS[0]
|
||||
else:
|
||||
editor = EDITORS[1]
|
||||
preferences = PreferencesConfig(editor, terminal)
|
||||
config = GuiConfig(preferences=preferences)
|
||||
save(config)
|
||||
if not CONFIG_PATH.exists():
|
||||
terminal = find_terminal()
|
||||
if "EDITOR" in os.environ:
|
||||
editor = EDITORS[0]
|
||||
else:
|
||||
editor = EDITORS[1]
|
||||
preferences = PreferencesConfig(editor, terminal)
|
||||
config = GuiConfig(preferences=preferences)
|
||||
save(config)
|
||||
|
||||
|
||||
def read() -> GuiConfig:
|
||||
|
|
|
@ -6,10 +6,10 @@ import tkinter as tk
|
|||
from tkinter import ttk
|
||||
from typing import TYPE_CHECKING, List, Optional
|
||||
|
||||
from core.gui import images
|
||||
from core.gui.appconfig import BACKGROUNDS_PATH
|
||||
from core.gui.dialogs.dialog import Dialog
|
||||
from core.gui.graph.graph import CanvasGraph
|
||||
from core.gui.images import Images
|
||||
from core.gui.themes import PADX, PADY
|
||||
from core.gui.widgets import image_chooser
|
||||
|
||||
|
@ -132,7 +132,7 @@ class CanvasWallpaperDialog(Dialog):
|
|||
self.draw_preview()
|
||||
|
||||
def draw_preview(self) -> None:
|
||||
image = Images.create(self.filename.get(), 250, 135)
|
||||
image = images.from_file(self.filename.get(), width=250, height=135)
|
||||
self.image_label.config(image=image)
|
||||
self.image_label.image = image
|
||||
|
||||
|
|
|
@ -6,10 +6,9 @@ from typing import TYPE_CHECKING, Optional, Set
|
|||
|
||||
from PIL.ImageTk import PhotoImage
|
||||
|
||||
from core.gui import nodeutils
|
||||
from core.gui import images
|
||||
from core.gui.appconfig import ICONS_PATH, CustomNode
|
||||
from core.gui.dialogs.dialog import Dialog
|
||||
from core.gui.images import Images
|
||||
from core.gui.nodeutils import NodeDraw
|
||||
from core.gui.themes import FRAME_PAD, PADX, PADY
|
||||
from core.gui.widgets import CheckboxList, ListboxScroll, image_chooser
|
||||
|
@ -190,7 +189,7 @@ class CustomNodesDialog(Dialog):
|
|||
def click_icon(self) -> None:
|
||||
file_path = image_chooser(self, ICONS_PATH)
|
||||
if file_path:
|
||||
image = Images.create(file_path, nodeutils.ICON_SIZE)
|
||||
image = images.from_file(file_path, width=images.NODE_SIZE)
|
||||
self.image = image
|
||||
self.image_file = file_path
|
||||
self.image_button.config(image=self.image)
|
||||
|
|
|
@ -2,7 +2,8 @@ import tkinter as tk
|
|||
from tkinter import ttk
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from core.gui.images import ImageEnum, Images
|
||||
from core.gui import images
|
||||
from core.gui.images import ImageEnum
|
||||
from core.gui.themes import DIALOG_PAD
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
@ -25,7 +26,7 @@ class Dialog(tk.Toplevel):
|
|||
self.modal: bool = modal
|
||||
self.title(title)
|
||||
self.protocol("WM_DELETE_WINDOW", self.destroy)
|
||||
image = Images.get(ImageEnum.CORE, 16)
|
||||
image = images.from_enum(ImageEnum.CORE, width=images.DIALOG_SIZE)
|
||||
self.tk.call("wm", "iconphoto", self._w, image)
|
||||
self.columnconfigure(0, weight=1)
|
||||
self.rowconfigure(0, weight=1)
|
||||
|
|
|
@ -9,8 +9,9 @@ from typing import TYPE_CHECKING, Dict, List, Optional
|
|||
import grpc
|
||||
|
||||
from core.api.grpc.wrappers import ConfigOption, Node
|
||||
from core.gui import images
|
||||
from core.gui.dialogs.dialog import Dialog
|
||||
from core.gui.images import ImageEnum, Images
|
||||
from core.gui.images import ImageEnum
|
||||
from core.gui.themes import PADX, PADY
|
||||
from core.gui.widgets import ConfigFrame
|
||||
|
||||
|
@ -143,7 +144,7 @@ class EmaneConfigDialog(Dialog):
|
|||
)
|
||||
label.grid(pady=PADY)
|
||||
|
||||
image = Images.get(ImageEnum.EDITNODE, 16)
|
||||
image = images.from_enum(ImageEnum.EDITNODE, width=images.BUTTON_SIZE)
|
||||
button = ttk.Button(
|
||||
self.top,
|
||||
image=image,
|
||||
|
@ -181,7 +182,7 @@ class EmaneConfigDialog(Dialog):
|
|||
for i in range(2):
|
||||
frame.columnconfigure(i, weight=1)
|
||||
|
||||
image = Images.get(ImageEnum.EDITNODE, 16)
|
||||
image = images.from_enum(ImageEnum.EDITNODE, width=images.BUTTON_SIZE)
|
||||
self.emane_model_button = ttk.Button(
|
||||
frame,
|
||||
text=f"{self.emane_model.get()} options",
|
||||
|
@ -192,7 +193,7 @@ class EmaneConfigDialog(Dialog):
|
|||
self.emane_model_button.image = image
|
||||
self.emane_model_button.grid(row=0, column=0, padx=PADX, sticky=tk.EW)
|
||||
|
||||
image = Images.get(ImageEnum.EDITNODE, 16)
|
||||
image = images.from_enum(ImageEnum.EDITNODE, width=images.BUTTON_SIZE)
|
||||
button = ttk.Button(
|
||||
frame,
|
||||
text="EMANE options",
|
||||
|
|
|
@ -2,8 +2,9 @@ import tkinter as tk
|
|||
from tkinter import ttk
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from core.gui import images
|
||||
from core.gui.dialogs.dialog import Dialog
|
||||
from core.gui.images import ImageEnum, Images
|
||||
from core.gui.images import ImageEnum
|
||||
from core.gui.themes import PADY
|
||||
from core.gui.widgets import CodeText
|
||||
|
||||
|
@ -22,7 +23,7 @@ class ErrorDialog(Dialog):
|
|||
def draw(self) -> None:
|
||||
self.top.columnconfigure(0, weight=1)
|
||||
self.top.rowconfigure(1, weight=1)
|
||||
image = Images.get(ImageEnum.ERROR, 24)
|
||||
image = images.from_enum(ImageEnum.ERROR, width=images.ERROR_SIZE)
|
||||
label = ttk.Label(
|
||||
self.top, text=self.title, image=image, compound=tk.LEFT, anchor=tk.CENTER
|
||||
)
|
||||
|
|
|
@ -8,12 +8,12 @@ import netaddr
|
|||
from PIL.ImageTk import PhotoImage
|
||||
|
||||
from core.api.grpc.wrappers import Interface, Node
|
||||
from core.gui import images
|
||||
from core.gui import nodeutils as nutils
|
||||
from core.gui import validation
|
||||
from core.gui.appconfig import ICONS_PATH
|
||||
from core.gui.dialogs.dialog import Dialog
|
||||
from core.gui.dialogs.emaneconfig import EmaneModelDialog
|
||||
from core.gui.images import Images
|
||||
from core.gui.themes import FRAME_PAD, PADX, PADY
|
||||
from core.gui.widgets import ListboxScroll, image_chooser
|
||||
|
||||
|
@ -371,7 +371,7 @@ class NodeConfigDialog(Dialog):
|
|||
def click_icon(self) -> None:
|
||||
file_path = image_chooser(self, ICONS_PATH)
|
||||
if file_path:
|
||||
self.image = Images.create(file_path, nutils.ICON_SIZE)
|
||||
self.image = images.from_file(file_path, width=images.NODE_SIZE)
|
||||
self.image_button.config(image=self.image)
|
||||
self.image_file = file_path
|
||||
|
||||
|
|
|
@ -8,9 +8,10 @@ import grpc
|
|||
from PIL.ImageTk import PhotoImage
|
||||
|
||||
from core.api.grpc.wrappers import Node, NodeServiceData, ServiceValidationMode
|
||||
from core.gui import images
|
||||
from core.gui.dialogs.copyserviceconfig import CopyServiceConfigDialog
|
||||
from core.gui.dialogs.dialog import Dialog
|
||||
from core.gui.images import ImageEnum, Images
|
||||
from core.gui.images import ImageEnum
|
||||
from core.gui.themes import FRAME_PAD, PADX, PADY
|
||||
from core.gui.widgets import CodeText, ListboxScroll
|
||||
|
||||
|
@ -179,7 +180,7 @@ class ServiceConfigDialog(Dialog):
|
|||
button.grid(row=0, column=0, sticky=tk.W, padx=PADX)
|
||||
entry = ttk.Entry(frame, state=tk.DISABLED)
|
||||
entry.grid(row=0, column=1, sticky=tk.EW, padx=PADX)
|
||||
image = Images.get(ImageEnum.FILEOPEN, 16)
|
||||
image = images.from_enum(ImageEnum.FILEOPEN, width=images.BUTTON_SIZE)
|
||||
button = ttk.Button(frame, image=image)
|
||||
button.image = image
|
||||
button.grid(row=0, column=2)
|
||||
|
@ -194,11 +195,11 @@ class ServiceConfigDialog(Dialog):
|
|||
value=2,
|
||||
)
|
||||
button.grid(row=0, column=0, sticky=tk.EW)
|
||||
image = Images.get(ImageEnum.FILEOPEN, 16)
|
||||
image = images.from_enum(ImageEnum.FILEOPEN, width=images.BUTTON_SIZE)
|
||||
button = ttk.Button(frame, image=image)
|
||||
button.image = image
|
||||
button.grid(row=0, column=1)
|
||||
image = Images.get(ImageEnum.DOCUMENTSAVE, 16)
|
||||
image = images.from_enum(ImageEnum.DOCUMENTSAVE, width=images.BUTTON_SIZE)
|
||||
button = ttk.Button(frame, image=image)
|
||||
button.image = image
|
||||
button.grid(row=0, column=2)
|
||||
|
|
|
@ -6,8 +6,9 @@ from typing import TYPE_CHECKING, List, Optional
|
|||
import grpc
|
||||
|
||||
from core.api.grpc.wrappers import SessionState, SessionSummary
|
||||
from core.gui import images
|
||||
from core.gui.dialogs.dialog import Dialog
|
||||
from core.gui.images import ImageEnum, Images
|
||||
from core.gui.images import ImageEnum
|
||||
from core.gui.task import ProgressTask
|
||||
from core.gui.themes import PADX, PADY
|
||||
|
||||
|
@ -108,14 +109,14 @@ class SessionsDialog(Dialog):
|
|||
frame.columnconfigure(i, weight=1)
|
||||
frame.grid(sticky=tk.EW)
|
||||
|
||||
image = Images.get(ImageEnum.DOCUMENTNEW, 16)
|
||||
image = images.from_enum(ImageEnum.DOCUMENTNEW, width=images.BUTTON_SIZE)
|
||||
b = ttk.Button(
|
||||
frame, image=image, text="New", compound=tk.LEFT, command=self.click_new
|
||||
)
|
||||
b.image = image
|
||||
b.grid(row=0, padx=PADX, sticky=tk.EW)
|
||||
|
||||
image = Images.get(ImageEnum.FILEOPEN, 16)
|
||||
image = images.from_enum(ImageEnum.FILEOPEN, width=images.BUTTON_SIZE)
|
||||
self.connect_button = ttk.Button(
|
||||
frame,
|
||||
image=image,
|
||||
|
@ -127,7 +128,7 @@ class SessionsDialog(Dialog):
|
|||
self.connect_button.image = image
|
||||
self.connect_button.grid(row=0, column=1, padx=PADX, sticky=tk.EW)
|
||||
|
||||
image = Images.get(ImageEnum.DELETE, 16)
|
||||
image = images.from_enum(ImageEnum.DELETE, width=images.BUTTON_SIZE)
|
||||
self.delete_button = ttk.Button(
|
||||
frame,
|
||||
image=image,
|
||||
|
@ -139,7 +140,7 @@ class SessionsDialog(Dialog):
|
|||
self.delete_button.image = image
|
||||
self.delete_button.grid(row=0, column=2, padx=PADX, sticky=tk.EW)
|
||||
|
||||
image = Images.get(ImageEnum.CANCEL, 16)
|
||||
image = images.from_enum(ImageEnum.CANCEL, width=images.BUTTON_SIZE)
|
||||
if self.is_start_app:
|
||||
b = ttk.Button(
|
||||
frame,
|
||||
|
|
|
@ -5,6 +5,7 @@ from tkinter import BooleanVar, messagebox, ttk
|
|||
from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, ValuesView
|
||||
|
||||
from core.api.grpc.wrappers import Link, LinkType, Node, Session, ThroughputsEvent
|
||||
from core.gui import images
|
||||
from core.gui import nodeutils as nutils
|
||||
from core.gui.graph import tags
|
||||
from core.gui.graph.edges import (
|
||||
|
@ -18,7 +19,7 @@ from core.gui.graph.graph import CanvasGraph
|
|||
from core.gui.graph.node import CanvasNode
|
||||
from core.gui.graph.shapeutils import ShapeType
|
||||
from core.gui.images import ImageEnum
|
||||
from core.gui.nodeutils import ICON_SIZE, NodeDraw
|
||||
from core.gui.nodeutils import NodeDraw
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.gui.app import Application
|
||||
|
@ -303,7 +304,7 @@ class CanvasManager:
|
|||
# if the gui can't find node's image, default to the "edit-node" image
|
||||
image = nutils.get_icon(core_node, self.app.guiconfig, self.app.app_scale)
|
||||
if not image:
|
||||
image = self.app.get_icon(ImageEnum.EDITNODE, ICON_SIZE)
|
||||
image = self.app.get_icon(ImageEnum.EDITNODE, images.NODE_SIZE)
|
||||
x = core_node.position.x
|
||||
y = core_node.position.y
|
||||
node = CanvasNode(self.app, canvas, x, y, core_node, image)
|
||||
|
|
|
@ -9,6 +9,7 @@ from PIL.ImageTk import PhotoImage
|
|||
|
||||
from core.api.grpc.services_pb2 import ServiceAction
|
||||
from core.api.grpc.wrappers import Interface, Node, NodeType
|
||||
from core.gui import images
|
||||
from core.gui import nodeutils as nutils
|
||||
from core.gui import themes
|
||||
from core.gui.dialogs.emaneconfig import EmaneConfigDialog
|
||||
|
@ -21,8 +22,7 @@ from core.gui.frames.node import NodeInfoFrame
|
|||
from core.gui.graph import tags
|
||||
from core.gui.graph.edges import CanvasEdge, CanvasWirelessEdge
|
||||
from core.gui.graph.tooltip import CanvasTooltip
|
||||
from core.gui.images import ImageEnum, Images
|
||||
from core.gui.nodeutils import ANTENNA_SIZE, ICON_SIZE
|
||||
from core.gui.images import ImageEnum
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.gui.app import Application
|
||||
|
@ -95,7 +95,7 @@ class CanvasNode:
|
|||
def add_antenna(self) -> None:
|
||||
x, y = self.position()
|
||||
offset = len(self.antennas) * 8 * self.app.app_scale
|
||||
img = self.app.get_icon(ImageEnum.ANTENNA, ANTENNA_SIZE)
|
||||
img = self.app.get_icon(ImageEnum.ANTENNA, images.ANTENNA_SIZE)
|
||||
antenna_id = self.canvas.create_image(
|
||||
x - 16 + offset,
|
||||
y - int(23 * self.app.app_scale),
|
||||
|
@ -389,7 +389,7 @@ class CanvasNode:
|
|||
def scale_antennas(self) -> None:
|
||||
for i in range(len(self.antennas)):
|
||||
antenna_id = self.antennas[i]
|
||||
image = self.app.get_icon(ImageEnum.ANTENNA, ANTENNA_SIZE)
|
||||
image = self.app.get_icon(ImageEnum.ANTENNA, images.ANTENNA_SIZE)
|
||||
self.canvas.itemconfig(antenna_id, image=image)
|
||||
self.antenna_images[antenna_id] = image
|
||||
node_x, node_y = self.canvas.coords(self.id)
|
||||
|
@ -403,7 +403,7 @@ class CanvasNode:
|
|||
logging.error(f"node icon does not exist: {icon_path}")
|
||||
return
|
||||
self.core_node.icon = icon_path
|
||||
self.image = Images.create(icon_path)
|
||||
self.image = images.from_file(icon_path, width=images.NODE_SIZE)
|
||||
self.canvas.itemconfig(self.id, image=self.image)
|
||||
|
||||
def is_linkable(self, node: "CanvasNode") -> bool:
|
||||
|
@ -492,7 +492,7 @@ class ShadowNode:
|
|||
self.node: "CanvasNode" = node
|
||||
self.id: Optional[int] = None
|
||||
self.text_id: Optional[int] = None
|
||||
self.image: PhotoImage = self.app.get_icon(ImageEnum.SHADOW, ICON_SIZE)
|
||||
self.image: PhotoImage = self.app.get_icon(ImageEnum.SHADOW, images.NODE_SIZE)
|
||||
self.draw()
|
||||
self.setup_bindings()
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
from enum import Enum
|
||||
from tkinter import messagebox
|
||||
from typing import Dict, Optional, Tuple
|
||||
|
||||
from PIL import Image
|
||||
|
@ -8,52 +7,43 @@ from PIL.ImageTk import PhotoImage
|
|||
from core.api.grpc.wrappers import NodeType
|
||||
from core.gui.appconfig import LOCAL_ICONS_PATH
|
||||
|
||||
ICON_SIZE: int = 48
|
||||
NODE_SIZE: int = 48
|
||||
ANTENNA_SIZE: int = 32
|
||||
BUTTON_SIZE: int = 16
|
||||
ERROR_SIZE: int = 24
|
||||
DIALOG_SIZE: int = 16
|
||||
IMAGES: Dict[str, str] = {}
|
||||
|
||||
|
||||
class Images:
|
||||
images: Dict[str, str] = {}
|
||||
def load_all() -> None:
|
||||
for image in LOCAL_ICONS_PATH.glob("*"):
|
||||
IMAGES[image.stem] = str(image)
|
||||
|
||||
@classmethod
|
||||
def create(
|
||||
cls, file_path: str, width: int = None, height: int = None
|
||||
) -> PhotoImage:
|
||||
if width is None:
|
||||
width = ICON_SIZE
|
||||
if height is None:
|
||||
height = width
|
||||
image = Image.open(file_path)
|
||||
image = image.resize((width, height), Image.ANTIALIAS)
|
||||
return PhotoImage(image)
|
||||
|
||||
@classmethod
|
||||
def load_all(cls) -> None:
|
||||
for image in LOCAL_ICONS_PATH.glob("*"):
|
||||
cls.images[image.stem] = str(image)
|
||||
def from_file(
|
||||
file_path: str, *, width: int, height: int = None, scale: float = 1.0
|
||||
) -> PhotoImage:
|
||||
if height is None:
|
||||
height = width
|
||||
width = int(width * scale)
|
||||
height = int(height * scale)
|
||||
image = Image.open(file_path)
|
||||
image = image.resize((width, height), Image.ANTIALIAS)
|
||||
return PhotoImage(image)
|
||||
|
||||
@classmethod
|
||||
def get(cls, image_enum: Enum, width: int, height: int = None) -> PhotoImage:
|
||||
file_path = cls.images[image_enum.value]
|
||||
return cls.create(file_path, width, height)
|
||||
|
||||
@classmethod
|
||||
def get_with_image_file(
|
||||
cls, stem: str, width: int, height: int = None
|
||||
) -> PhotoImage:
|
||||
file_path = cls.images[stem]
|
||||
return cls.create(file_path, width, height)
|
||||
def from_enum(
|
||||
image_enum: "ImageEnum", *, width: int, height: int = None, scale: float = 1.0
|
||||
) -> PhotoImage:
|
||||
file_path = IMAGES[image_enum.value]
|
||||
return from_file(file_path, width=width, height=height, scale=scale)
|
||||
|
||||
@classmethod
|
||||
def get_custom(cls, name: str, width: int, height: int = None) -> PhotoImage:
|
||||
try:
|
||||
file_path = cls.images[name]
|
||||
return cls.create(file_path, width, height)
|
||||
except KeyError:
|
||||
messagebox.showwarning(
|
||||
"Missing image file",
|
||||
f"{name}.png is missing at daemon/core/gui/data/icons, drop image "
|
||||
f"file at daemon/core/gui/data/icons and restart the gui",
|
||||
)
|
||||
|
||||
def from_name(
|
||||
name: str, *, width: int, height: int = None, scale: float = 1.0
|
||||
) -> PhotoImage:
|
||||
file_path = IMAGES[name]
|
||||
return from_file(file_path, width=width, height=height, scale=scale)
|
||||
|
||||
|
||||
class ImageEnum(Enum):
|
||||
|
|
|
@ -6,6 +6,7 @@ from functools import partial
|
|||
from tkinter import filedialog, messagebox
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from core.gui import images
|
||||
from core.gui.coreclient import CoreClient
|
||||
from core.gui.dialogs.about import AboutDialog
|
||||
from core.gui.dialogs.canvassizeandscale import SizeAndScaleDialog
|
||||
|
@ -23,7 +24,6 @@ from core.gui.dialogs.sessionoptions import SessionOptionsDialog
|
|||
from core.gui.dialogs.sessions import SessionsDialog
|
||||
from core.gui.dialogs.throughput import ThroughputDialog
|
||||
from core.gui.graph.manager import CanvasManager
|
||||
from core.gui.nodeutils import ICON_SIZE
|
||||
from core.gui.observers import ObserversMenu
|
||||
from core.gui.task import ProgressTask
|
||||
|
||||
|
@ -461,8 +461,8 @@ class Menubar(tk.Menu):
|
|||
|
||||
def click_autogrid(self) -> None:
|
||||
width, height = self.manager.current_dimensions
|
||||
padding = (ICON_SIZE / 2) + 10
|
||||
layout_size = padding + ICON_SIZE
|
||||
padding = (images.NODE_SIZE / 2) + 10
|
||||
layout_size = padding + images.NODE_SIZE
|
||||
col_count = width // layout_size
|
||||
logging.info(
|
||||
"auto grid layout: dimension(%s, %s) col(%s)", width, height, col_count
|
||||
|
|
|
@ -4,11 +4,9 @@ from typing import List, Optional, Set
|
|||
from PIL.ImageTk import PhotoImage
|
||||
|
||||
from core.api.grpc.wrappers import Node, NodeType
|
||||
from core.gui import images
|
||||
from core.gui.appconfig import CustomNode, GuiConfig
|
||||
from core.gui.images import ImageEnum, Images, TypeToImage
|
||||
|
||||
ICON_SIZE: int = 48
|
||||
ANTENNA_SIZE: int = 32
|
||||
from core.gui.images import ImageEnum, TypeToImage
|
||||
|
||||
NODES: List["NodeDraw"] = []
|
||||
NETWORK_NODES: List["NodeDraw"] = []
|
||||
|
@ -52,7 +50,7 @@ def setup() -> None:
|
|||
node_draw = NodeDraw.from_setup(image_enum, node_type, label)
|
||||
NETWORK_NODES.append(node_draw)
|
||||
NODE_ICONS[(node_type, None)] = node_draw.image
|
||||
ANTENNA_ICON = Images.get(ImageEnum.ANTENNA, ANTENNA_SIZE)
|
||||
ANTENNA_ICON = images.from_enum(ImageEnum.ANTENNA, width=images.ANTENNA_SIZE)
|
||||
|
||||
|
||||
def is_bridge(node: Node) -> bool:
|
||||
|
@ -114,19 +112,21 @@ def get_icon(node: Node, config: GuiConfig, scale: float) -> Optional[PhotoImage
|
|||
# node has defined a custom icon
|
||||
if node.icon:
|
||||
try:
|
||||
image = Images.create(node.icon, int(ICON_SIZE * scale))
|
||||
image = images.from_file(node.icon, width=images.NODE_SIZE, scale=scale)
|
||||
except OSError:
|
||||
logging.error("invalid icon: %s", node.icon)
|
||||
else:
|
||||
# attempt to find default type/model image
|
||||
image_enum = TypeToImage.get(node.type, node.model)
|
||||
if image_enum:
|
||||
image = Images.get(image_enum, int(ICON_SIZE * scale))
|
||||
image = images.from_enum(image_enum, width=images.NODE_SIZE, scale=scale)
|
||||
# attempt to find custom image file
|
||||
else:
|
||||
image_file = _get_image_file(config, node.model)
|
||||
if image_file:
|
||||
image = Images.get_with_image_file(image_file, int(ICON_SIZE * scale))
|
||||
image = images.from_name(
|
||||
image_file, width=images.NODE_SIZE, scale=scale
|
||||
)
|
||||
return image
|
||||
|
||||
|
||||
|
@ -152,7 +152,7 @@ class NodeDraw:
|
|||
) -> "NodeDraw":
|
||||
node_draw = NodeDraw()
|
||||
node_draw.image_enum = image_enum
|
||||
node_draw.image = Images.get(image_enum, ICON_SIZE)
|
||||
node_draw.image = images.from_enum(image_enum, width=images.NODE_SIZE)
|
||||
node_draw.node_type = node_type
|
||||
node_draw.label = label
|
||||
node_draw.model = model
|
||||
|
@ -164,7 +164,7 @@ class NodeDraw:
|
|||
node_draw = NodeDraw()
|
||||
node_draw.custom = True
|
||||
node_draw.image_file = custom_node.image
|
||||
node_draw.image = Images.get_custom(custom_node.image, ICON_SIZE)
|
||||
node_draw.image = images.from_name(custom_node.image, width=images.NODE_SIZE)
|
||||
node_draw.node_type = NodeType.DEFAULT
|
||||
node_draw.services = custom_node.services
|
||||
node_draw.label = custom_node.name
|
||||
|
|
|
@ -3,9 +3,8 @@ import argparse
|
|||
import logging
|
||||
from logging.handlers import TimedRotatingFileHandler
|
||||
|
||||
from core.gui import appconfig
|
||||
from core.gui import appconfig, images
|
||||
from core.gui.app import Application
|
||||
from core.gui.images import Images
|
||||
|
||||
if __name__ == "__main__":
|
||||
# parse flags
|
||||
|
@ -28,6 +27,6 @@ if __name__ == "__main__":
|
|||
logging.getLogger("PIL").setLevel(logging.ERROR)
|
||||
|
||||
# start app
|
||||
Images.load_all()
|
||||
images.load_all()
|
||||
app = Application(args.proxy, args.session)
|
||||
app.mainloop()
|
||||
|
|
Loading…
Reference in a new issue