122 lines
3.6 KiB
Python
122 lines
3.6 KiB
Python
import numbers
|
|
import os
|
|
import logging
|
|
from pathlib import Path
|
|
|
|
from qtpy import QtGui, QtCore
|
|
from qtpy.QtGui import QPageLayout
|
|
from qtpy.QtPrintSupport import QPrinter
|
|
|
|
from . import Constants
|
|
|
|
log = logging.getLogger(f"grc.application.{__name__}")
|
|
|
|
|
|
def get_rotated_coordinate(coor, rotation):
|
|
"""
|
|
Rotate the coordinate by the given rotation.
|
|
Args:
|
|
coor: the coordinate x, y tuple
|
|
rotation: the angle in degrees
|
|
Returns:
|
|
the rotated coordinates
|
|
"""
|
|
# handles negative angles
|
|
rotation = (rotation + 360) % 360
|
|
if rotation not in Constants.POSSIBLE_ROTATIONS:
|
|
raise ValueError('unusable rotation angle "%s"' % str(rotation))
|
|
# determine the number of degrees to rotate
|
|
cos_r, sin_r = {
|
|
0: (1, 0),
|
|
90: (0, 1),
|
|
180: (-1, 0),
|
|
270: (0, -1),
|
|
}[rotation]
|
|
x, y = coor
|
|
return x * cos_r + y * sin_r, -x * sin_r + y * cos_r
|
|
|
|
|
|
def num_to_str(num):
|
|
""" Display logic for numbers """
|
|
def eng_notation(value, fmt='g'):
|
|
"""Convert a number to a string in engineering notation. E.g., 5e-9 -> 5n"""
|
|
template = '{:' + fmt + '}{}'
|
|
magnitude = abs(value)
|
|
for exp, symbol in zip(range(9, -15 - 1, -3), 'GMk munpf'):
|
|
factor = 10 ** exp
|
|
if magnitude >= factor:
|
|
return template.format(value / factor, symbol.strip())
|
|
return template.format(value, '')
|
|
|
|
if isinstance(num, numbers.Complex):
|
|
num = complex(num) # Cast to python complex
|
|
if num == 0:
|
|
return '0'
|
|
output = eng_notation(num.real) if num.real else ''
|
|
output += eng_notation(num.imag, '+g' if output else 'g') + \
|
|
'j' if num.imag else ''
|
|
return output
|
|
else:
|
|
return str(num)
|
|
|
|
|
|
_nproc = None
|
|
|
|
|
|
def get_cmake_nproc():
|
|
""" Get number of cmake processes for C++ flowgraphs """
|
|
global _nproc # Cached result
|
|
if _nproc:
|
|
return _nproc
|
|
try:
|
|
# See https://docs.python.org/3.8/library/os.html#os.cpu_count
|
|
_nproc = len(os.sched_getaffinity(0))
|
|
except:
|
|
_nproc = os.cpu_count()
|
|
if not _nproc:
|
|
_nproc = 1
|
|
|
|
_nproc = max(_nproc // 2 - 1, 1)
|
|
return _nproc
|
|
|
|
|
|
def make_screenshot(fg_view, file_path, transparent_bg=False):
|
|
if not file_path:
|
|
return
|
|
file_path = Path(file_path)
|
|
|
|
target_rect = fg_view.scene().sceneRect() # Float
|
|
source_rect = target_rect.toRect() # Converted to int
|
|
|
|
if file_path.suffix == ".png":
|
|
|
|
pixmap = QtGui.QPixmap(source_rect.size())
|
|
painter = QtGui.QPainter(pixmap)
|
|
|
|
fg_view.render(painter, target_rect, source_rect)
|
|
pixmap.save(str(file_path), "PNG")
|
|
painter.end()
|
|
elif file_path.suffix == ".svg":
|
|
try:
|
|
from qtpy import QtSvg
|
|
except ImportError:
|
|
log.error("Missing (Python-)QtSvg! Please install it or export as PNG instead.")
|
|
return
|
|
|
|
generator = QtSvg.QSvgGenerator()
|
|
generator.setFileName(str(file_path))
|
|
painter = QtGui.QPainter(generator)
|
|
fg_view.render(painter, target_rect, source_rect)
|
|
painter.end()
|
|
elif file_path.suffix == ".pdf":
|
|
pdf_printer = QPrinter(QPrinter.PrinterMode.ScreenResolution)
|
|
pdf_printer.setOutputFormat(QPrinter.OutputFormat.PdfFormat)
|
|
page_layout = QPageLayout()
|
|
page_layout.setOrientation(QPageLayout.Landscape)
|
|
pdf_printer.setPageLayout(page_layout)
|
|
pdf_printer.setOutputFileName(str(file_path))
|
|
painter = QtGui.QPainter(pdf_printer)
|
|
fg_view.render(painter, pdf_printer.pageRect(QPrinter.Unit.DevicePixel), source_rect)
|
|
painter.end()
|
|
return
|