from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, QLabel, QColorDialog, QScrollArea, QFrame, QSplitter, QMainWindow, QMessageBox ) from PyQt6.QtGui import QColor, QAction, QKeySequence from PyQt6.QtSvgWidgets import QSvgWidget from PyQt6.QtCore import Qt from svg_parser import SvgColorParser class ColorSwatch(QFrame): def __init__(self, tag, color_hex, on_click): super().__init__() self.tag = tag self.color_hex = color_hex self.on_click = on_click self.setFrameStyle(QFrame.Shape.StyledPanel | QFrame.Shadow.Raised) self.setLineWidth(1) layout = QHBoxLayout() self.setLayout(layout) self.lbl_tag = QLabel(tag) self.lbl_color = QLabel(color_hex) self.swatch = QLabel() self.swatch.setFixedSize(30, 30) self.swatch.setAutoFillBackground(True) self.update_swatch_color(color_hex) layout.addWidget(self.swatch) layout.addWidget(self.lbl_tag) layout.addWidget(self.lbl_color) layout.addStretch() def update_swatch_color(self, hex_color): self.color_hex = hex_color self.lbl_color.setText(hex_color) self.swatch.setStyleSheet(f"background-color: {hex_color}; border: 1px solid black;") def mousePressEvent(self, event): if event.button() == Qt.MouseButton.LeftButton: self.on_click(self.tag, self.color_hex, self) class MainWindow(QMainWindow): def __init__(self, svg_path): super().__init__() self.setWindowTitle(f"SVG Color Editor - {svg_path}") self.resize(800, 600) self.parser = SvgColorParser(svg_path) self.svg_path = svg_path self.setup_ui() self.setup_menu() if not self.parser.colors: QMessageBox.warning(self, "No Colors Found", "No ColorScheme tags were found in the SVG file.") def setup_menu(self): menubar = self.menuBar() edit_menu = menubar.addMenu("Edit") self.undo_action = QAction("Undo", self) self.undo_action.setShortcut(QKeySequence.StandardKey.Undo) self.undo_action.triggered.connect(self.undo) edit_menu.addAction(self.undo_action) self.redo_action = QAction("Redo", self) self.redo_action.setShortcut(QKeySequence.StandardKey.Redo) self.redo_action.triggered.connect(self.redo) edit_menu.addAction(self.redo_action) def setup_ui(self): central_widget = QWidget() self.setCentralWidget(central_widget) main_layout = QVBoxLayout(central_widget) splitter = QSplitter(Qt.Orientation.Horizontal) main_layout.addWidget(splitter) # Left Panel - Colors scroll_area = QScrollArea() scroll_area.setWidgetResizable(True) self.colors_widget = QWidget() self.colors_layout = QVBoxLayout(self.colors_widget) scroll_area.setWidget(self.colors_widget) splitter.addWidget(scroll_area) # Right Panel - SVG Preview preview_container = QWidget() preview_layout = QVBoxLayout(preview_container) self.svg_widget = QSvgWidget(str(self.svg_path)) self.svg_widget.renderer().setAspectRatioMode(Qt.AspectRatioMode.KeepAspectRatio) preview_layout.addWidget(self.svg_widget) splitter.addWidget(preview_container) splitter.setSizes([350, 450]) self.populate_colors() def populate_colors(self): # Clear layout while self.colors_layout.count(): item = self.colors_layout.takeAt(0) widget = item.widget() if widget: widget.deleteLater() for tag, color in self.parser.colors.items(): swatch = ColorSwatch(tag, color, self.on_swatch_click) self.colors_layout.addWidget(swatch) self.colors_layout.addStretch() def on_swatch_click(self, tag, current_color, swatch_widget): color = QColorDialog.getColor(QColor(current_color), self, f"Select Color for {tag}") if color.isValid(): new_hex = color.name() # Returns #RRGGBB self.parser.update_color(tag, new_hex) swatch_widget.update_swatch_color(new_hex) self.refresh_preview() self.populate_colors() def refresh_preview(self): self.svg_widget.load(self.parser.content.encode('utf-8')) def undo(self): if self.parser.undo(): self.refresh_preview() self.populate_colors() def redo(self): if self.parser.redo(): self.refresh_preview() self.populate_colors()