2026-02-26 11:20:39 +00:00
|
|
|
import base64
|
|
|
|
|
|
|
|
|
|
from PySide6.QtCore import QPoint, QRect, Qt
|
|
|
|
|
from PySide6.QtGui import QFont, QFontInfo, QIcon, QPainter, QPixmap
|
|
|
|
|
from PySide6.QtSvg import QSvgRenderer
|
|
|
|
|
from PySide6.QtWidgets import (
|
|
|
|
|
QComboBox,
|
|
|
|
|
QGridLayout,
|
|
|
|
|
QGroupBox,
|
|
|
|
|
QHBoxLayout,
|
|
|
|
|
QLabel,
|
|
|
|
|
QPushButton,
|
|
|
|
|
QScrollArea,
|
|
|
|
|
QSizePolicy,
|
|
|
|
|
QSlider,
|
|
|
|
|
QSpacerItem,
|
|
|
|
|
QVBoxLayout,
|
|
|
|
|
QWidget,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# _icon_color_from_palette: function definition for ScanSlicer behavior.
|
2026-02-26 11:39:42 +00:00
|
|
|
def _icon_color_from_palette(palette):
|
|
|
|
|
if palette is None:
|
|
|
|
|
return "#f2f2f2"
|
|
|
|
|
|
|
|
|
|
button_text_color = palette.buttonText().color()
|
|
|
|
|
if button_text_color.isValid():
|
|
|
|
|
return button_text_color.name()
|
|
|
|
|
|
|
|
|
|
window_color = palette.window().color()
|
|
|
|
|
luma = (
|
|
|
|
|
(0.2126 * window_color.redF())
|
|
|
|
|
+ (0.7152 * window_color.greenF())
|
|
|
|
|
+ (0.0722 * window_color.blueF())
|
|
|
|
|
)
|
|
|
|
|
return "#1f1f1f" if luma >= 0.5 else "#f2f2f2"
|
2026-02-26 12:03:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
# icon_from_svg_data_url: function definition for ScanSlicer behavior.
|
|
|
|
|
def icon_from_svg_data_url(data_url, size=24, color_hex=None, palette=None):
|
|
|
|
|
prefix = "data:image/svg+xml;base64,"
|
|
|
|
|
if not data_url.startswith(prefix):
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
svg_bytes = base64.b64decode(data_url[len(prefix):], validate=True)
|
|
|
|
|
except Exception:
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
if color_hex is None:
|
|
|
|
|
color_hex = _icon_color_from_palette(palette)
|
|
|
|
|
|
|
|
|
|
# Most toolbar SVGs use "currentColor"; replace it with the resolved color.
|
|
|
|
|
if color_hex:
|
|
|
|
|
try:
|
|
|
|
|
svg_text = svg_bytes.decode("utf-8")
|
|
|
|
|
svg_text = svg_text.replace("currentColor", color_hex)
|
|
|
|
|
svg_text = svg_text.replace("currentcolor", color_hex)
|
|
|
|
|
svg_bytes = svg_text.encode("utf-8")
|
|
|
|
|
except UnicodeDecodeError:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
renderer = QSvgRenderer(svg_bytes)
|
|
|
|
|
if not renderer.isValid():
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
pixmap = QPixmap(size, size)
|
|
|
|
|
pixmap.fill(Qt.GlobalColor.transparent)
|
|
|
|
|
painter = QPainter(pixmap)
|
|
|
|
|
renderer.render(painter)
|
|
|
|
|
painter.end()
|
|
|
|
|
return QIcon(pixmap)
|
2026-02-26 12:15:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
# ScrollbarWheelOnlyScrollArea: class definition for ScanSlicer behavior.
|
|
|
|
|
class ScrollbarWheelOnlyScrollArea(QScrollArea):
|
|
|
|
|
# wheelEvent: function definition for ScanSlicer behavior.
|
|
|
|
|
def wheelEvent(self, event):
|
|
|
|
|
scrollbar = self.verticalScrollBar()
|
|
|
|
|
if scrollbar is None or not scrollbar.isVisible():
|
|
|
|
|
event.ignore()
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
global_pos = event.globalPosition().toPoint()
|
|
|
|
|
scrollbar_rect = QRect(scrollbar.mapToGlobal(QPoint(0, 0)), scrollbar.size())
|
|
|
|
|
if not scrollbar_rect.contains(global_pos):
|
|
|
|
|
event.ignore()
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
super().wheelEvent(event)
|