Text fields and saving Icons to file
This commit is contained in:
@@ -4,14 +4,18 @@ from copy import deepcopy
|
||||
|
||||
from PySide6.QtCore import QEvent, QObject, Qt, Signal
|
||||
from PySide6.QtGui import QKeySequence, QPainter, QShortcut, QUndoCommand, QUndoStack, QWheelEvent, QShowEvent
|
||||
from PySide6.QtWidgets import QDialog, QGraphicsView, QMainWindow, QWidget
|
||||
from PySide6.QtWidgets import QDialog, QFileDialog, QGraphicsView, QMainWindow, QMessageBox, QWidget
|
||||
|
||||
from bedit_core.models import Port, PortID, SignalDirection
|
||||
from bedit_gui.models import Icon, Shape, ShapeID
|
||||
from bedit_gui.services import icon_files
|
||||
from bedit_gui.services.application_logging import get_logger
|
||||
from bedit_gui.ui.generated.ui_icon_editor_window import Ui_iconEditor
|
||||
from bedit_gui.views.icon_graphics_scene import IconGraphicsScene, RectangleCreationTool
|
||||
from bedit_gui.views.icon_graphics_scene import IconGraphicsScene, RectangleCreationTool, TextCreationTool
|
||||
from bedit_gui.views.shape_options_dialog import ShapeOptionsDialog
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class ChangeIconDraftCommand(QUndoCommand):
|
||||
def __init__(self, editor: IconEditorWindow, icon: Icon, text: str) -> None:
|
||||
@@ -102,10 +106,11 @@ class IconEditorWindow(QMainWindow):
|
||||
self.setWindowTitle("Icon Editor")
|
||||
self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
|
||||
self._icon = deepcopy(icon)
|
||||
self._ports = deepcopy(ports)
|
||||
|
||||
self.scene = IconGraphicsScene(self)
|
||||
self.scene.set_ports(ports)
|
||||
self._ensure_port_positions(ports)
|
||||
self.scene.set_ports(self._ports)
|
||||
self._ensure_port_positions(self._ports)
|
||||
self.scene.set_icon(self._icon)
|
||||
self.scene.port_moved.connect(self._port_moved)
|
||||
self.scene.shape_created.connect(self._shape_created)
|
||||
@@ -118,6 +123,8 @@ class IconEditorWindow(QMainWindow):
|
||||
self.ui.graphicsView.viewport().installEventFilter(self)
|
||||
self.ui.actionAdd_Rectangle.setCheckable(True)
|
||||
self.ui.actionAdd_Rectangle.triggered.connect(self._start_rectangle_tool)
|
||||
self.ui.actionAdd_Text.setCheckable(True)
|
||||
self.ui.actionAdd_Text.triggered.connect(self._start_text_tool)
|
||||
self.cancel_tool_shortcut = QShortcut(QKeySequence(Qt.Key.Key_Escape), self)
|
||||
self.cancel_tool_shortcut.activated.connect(self.scene.cancel_creation_tool)
|
||||
self.delete_shortcut = QShortcut(QKeySequence(Qt.Key.Key_Delete), self)
|
||||
@@ -135,6 +142,8 @@ class IconEditorWindow(QMainWindow):
|
||||
self.ui.actionUndo.triggered.connect(self.undo_stack.undo)
|
||||
self.ui.actionRedo.triggered.connect(self.undo_stack.redo)
|
||||
self.ui.actionSave.triggered.connect(self.save)
|
||||
self.ui.actionSave_to_File.triggered.connect(self.save_to_file)
|
||||
self.ui.actionOpen_from_File.triggered.connect(self.open_from_file)
|
||||
self.ui.actionCancel.triggered.connect(self.close)
|
||||
self.undo_stack.canUndoChanged.connect(self.ui.actionUndo.setEnabled)
|
||||
self.undo_stack.canRedoChanged.connect(self.ui.actionRedo.setEnabled)
|
||||
@@ -157,6 +166,32 @@ class IconEditorWindow(QMainWindow):
|
||||
self.saved.emit(self.icon())
|
||||
self.close()
|
||||
|
||||
def save_to_file(self) -> None:
|
||||
file_name, _ = QFileDialog.getSaveFileName(self, "Save Icon", "", "JSON files (*.json)")
|
||||
if not file_name:
|
||||
return
|
||||
path = file_name if file_name.lower().endswith(".json") else f"{file_name}.json"
|
||||
try:
|
||||
icon_files.save(self._icon, path)
|
||||
except (OSError, TypeError, ValueError) as exc:
|
||||
logger.exception("Could not save icon to %s", path)
|
||||
QMessageBox.critical(self, "Could not save icon", str(exc))
|
||||
return
|
||||
logger.info("Saved icon to: %s", path)
|
||||
|
||||
def open_from_file(self) -> None:
|
||||
file_name, _ = QFileDialog.getOpenFileName(self, "Open Icon", "", "JSON files (*.json)")
|
||||
if not file_name:
|
||||
return
|
||||
try:
|
||||
icon = icon_files.load(file_name)
|
||||
except (OSError, TypeError, ValueError) as exc:
|
||||
logger.exception("Could not open icon from %s", file_name)
|
||||
QMessageBox.critical(self, "Could not open icon", str(exc))
|
||||
return
|
||||
self.apply_change(icon, "Load icon from file")
|
||||
logger.info("Loaded icon from: %s", file_name)
|
||||
|
||||
def zoom_in(self) -> None:
|
||||
self._zoom(self.zoom_step)
|
||||
|
||||
@@ -187,6 +222,7 @@ class IconEditorWindow(QMainWindow):
|
||||
|
||||
def _set_icon(self, icon: Icon) -> None:
|
||||
self._icon = deepcopy(icon)
|
||||
self._ensure_port_positions(self._ports)
|
||||
self.scene.set_icon(self._icon)
|
||||
self.icon_changed.emit(self.icon())
|
||||
|
||||
@@ -268,10 +304,18 @@ class IconEditorWindow(QMainWindow):
|
||||
|
||||
def _start_rectangle_tool(self) -> None:
|
||||
layer = max((shape.layer for shape in self._icon.shapes.values()), default=-1) + 1
|
||||
self.ui.actionAdd_Text.setChecked(False)
|
||||
self.scene.set_creation_tool(RectangleCreationTool(self.scene, layer))
|
||||
|
||||
def _start_text_tool(self) -> None:
|
||||
layer = max((shape.layer for shape in self._icon.shapes.values()), default=-1) + 1
|
||||
self.ui.actionAdd_Rectangle.setChecked(False)
|
||||
self.scene.set_creation_tool(TextCreationTool(self.scene, layer))
|
||||
|
||||
def _tool_active_changed(self, active: bool) -> None:
|
||||
self.ui.actionAdd_Rectangle.setChecked(active)
|
||||
if not active:
|
||||
self.ui.actionAdd_Rectangle.setChecked(False)
|
||||
self.ui.actionAdd_Text.setChecked(False)
|
||||
cursor = Qt.CursorShape.CrossCursor if active else Qt.CursorShape.ArrowCursor
|
||||
self.ui.graphicsView.viewport().setCursor(cursor)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user