kopia lustrzana https://github.com/NanoVNA-Saver/nanovna-saver
enable to zoom out (not perfect yet)
rodzic
50ded6dcf3
commit
2821f4d08c
|
@ -219,6 +219,37 @@ class Chart(QtWidgets.QWidget):
|
||||||
self.dragbox.pos_start = (0, 0)
|
self.dragbox.pos_start = (0, 0)
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
|
||||||
|
def wheelEvent(self, a0: QtGui.QWheelEvent) -> None:
|
||||||
|
delta = a0.angleDelta().y()
|
||||||
|
if not delta or (not self.data and not self.reference):
|
||||||
|
a0.ignore()
|
||||||
|
return
|
||||||
|
modifiers = a0.modifiers()
|
||||||
|
|
||||||
|
zoom_x = modifiers != QtCore.Qt.ShiftModifier
|
||||||
|
zoom_y = modifiers != QtCore.Qt.ControlModifier
|
||||||
|
rate = -delta / 120
|
||||||
|
# zooming in 10% increments and 9% complementary
|
||||||
|
divisor = 10 if delta > 0 else 9
|
||||||
|
|
||||||
|
factor_x = rate * self.dim.width / divisor if zoom_x else 0
|
||||||
|
factor_y = rate * self.dim.height / divisor if zoom_y else 0
|
||||||
|
|
||||||
|
abs_x = max(0, a0.x() - self.leftMargin)
|
||||||
|
abs_y = max(0, a0.y() - self.topMargin)
|
||||||
|
|
||||||
|
ratio_x = abs_x / self.dim.width
|
||||||
|
ratio_y = abs_y / self.dim.height
|
||||||
|
|
||||||
|
self.zoomTo(
|
||||||
|
int(self.leftMargin + ratio_x * factor_x),
|
||||||
|
int(self.topMargin + ratio_y * factor_y),
|
||||||
|
int(self.leftMargin + self.dim.width - (1 - ratio_x) * factor_x),
|
||||||
|
int(self.topMargin + self.dim.height - (1 - ratio_y) * factor_y)
|
||||||
|
)
|
||||||
|
a0.accept()
|
||||||
|
|
||||||
def zoomTo(self, x1, y1, x2, y2):
|
def zoomTo(self, x1, y1, x2, y2):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@ -266,9 +297,12 @@ class Chart(QtWidgets.QWidget):
|
||||||
self.swrMarkers.clear()
|
self.swrMarkers.clear()
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def drawMarker(self, x, y, qp: QtGui.QPainter, color: QtGui.QColor, number=0):
|
@staticmethod
|
||||||
|
def drawMarker(x: int, y: int,
|
||||||
|
qp: QtGui.QPainter, color: QtGui.QColor,
|
||||||
|
number: int=0):
|
||||||
cmarker = ChartMarker(qp)
|
cmarker = ChartMarker(qp)
|
||||||
cmarker.draw(x, y, color, str(number))
|
cmarker.draw(x, y, color, f"{number}")
|
||||||
|
|
||||||
def drawTitle(self, qp: QtGui.QPainter, position: QtCore.QPoint = None):
|
def drawTitle(self, qp: QtGui.QPainter, position: QtCore.QPoint = None):
|
||||||
qp.setPen(Chart.color.text)
|
qp.setPen(Chart.color.text)
|
||||||
|
|
|
@ -237,7 +237,8 @@ class FrequencyChart(Chart):
|
||||||
self.logarithmicY = logarithmic and self.logarithmicYAllowed()
|
self.logarithmicY = logarithmic and self.logarithmicYAllowed()
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def logarithmicYAllowed(self) -> bool:
|
@staticmethod
|
||||||
|
def logarithmicYAllowed() -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def setMinimumFrequency(self):
|
def setMinimumFrequency(self):
|
||||||
|
@ -380,38 +381,6 @@ class FrequencyChart(Chart):
|
||||||
val = -1 * ((absy / self.dim.height * self.span) - self.maxValue)
|
val = -1 * ((absy / self.dim.height * self.span) - self.maxValue)
|
||||||
return [val * 10e11]
|
return [val * 10e11]
|
||||||
|
|
||||||
def wheelEvent(self, a0: QtGui.QWheelEvent) -> None:
|
|
||||||
if ((len(self.data) == 0 and len(self.reference) == 0) or
|
|
||||||
a0.angleDelta().y() == 0):
|
|
||||||
a0.ignore()
|
|
||||||
return
|
|
||||||
do_zoom_x = do_zoom_y = True
|
|
||||||
if a0.modifiers() == QtCore.Qt.ShiftModifier:
|
|
||||||
do_zoom_x = False
|
|
||||||
if a0.modifiers() == QtCore.Qt.ControlModifier:
|
|
||||||
do_zoom_y = False
|
|
||||||
self._wheel_zomm(
|
|
||||||
a0, do_zoom_x, do_zoom_y,
|
|
||||||
math.copysign(1, a0.angleDelta().y()))
|
|
||||||
|
|
||||||
def _wheel_zomm(self, a0, do_zoom_x, do_zoom_y, sign: int=1):
|
|
||||||
# Zoom in
|
|
||||||
a0.accept()
|
|
||||||
# Center of zoom = a0.x(), a0.y()
|
|
||||||
# We zoom in by 1/10 of the width/height.
|
|
||||||
rate = sign * a0.angleDelta().y() / 120
|
|
||||||
zoomx = rate * self.dim.width / 10 if do_zoom_x else 0
|
|
||||||
zoomy = rate * self.dim.height / 10 if do_zoom_y else 0
|
|
||||||
absx = max(0, a0.x() - self.leftMargin)
|
|
||||||
absy = max(0, a0.y() - self.topMargin)
|
|
||||||
ratiox = absx / self.dim.width
|
|
||||||
ratioy = absy / self.dim.height
|
|
||||||
p1x = int(self.leftMargin + ratiox * zoomx)
|
|
||||||
p1y = int(self.topMargin + ratioy * zoomy)
|
|
||||||
p2x = int(self.leftMargin + self.dim.width - (1 - ratiox) * zoomx)
|
|
||||||
p2y = int(self.topMargin + self.dim.height - (1 - ratioy) * zoomy)
|
|
||||||
self.zoomTo(p1x, p1y, p2x, p2y)
|
|
||||||
|
|
||||||
def zoomTo(self, x1, y1, x2, y2):
|
def zoomTo(self, x1, y1, x2, y2):
|
||||||
val1 = self.valueAtPosition(y1)
|
val1 = self.valueAtPosition(y1)
|
||||||
val2 = self.valueAtPosition(y2)
|
val2 = self.valueAtPosition(y2)
|
||||||
|
@ -481,14 +450,12 @@ class FrequencyChart(Chart):
|
||||||
self.drawDragbog(qp)
|
self.drawDragbog(qp)
|
||||||
qp.end()
|
qp.end()
|
||||||
|
|
||||||
|
def _data_oob(self, data: list[Datapoint]) -> bool:
|
||||||
|
return (data[0].freq > self.fstop or self.data[-1].freq < self.fstart)
|
||||||
|
|
||||||
def _check_frequency_boundaries(self, qp: QtGui.QPainter):
|
def _check_frequency_boundaries(self, qp: QtGui.QPainter):
|
||||||
if (len(self.data) > 0 and
|
if (self.data and self._data_oob(self.data) and
|
||||||
(self.data[0].freq > self.fstop or
|
(not self.reference or self._data_oob(self.reference))):
|
||||||
self.data[len(self.data) - 1].freq < self.fstart)
|
|
||||||
and
|
|
||||||
(len(self.reference) == 0 or
|
|
||||||
self.reference[0].freq > self.fstop or
|
|
||||||
self.reference[len(self.reference) - 1].freq < self.fstart)):
|
|
||||||
# Data outside frequency range
|
# Data outside frequency range
|
||||||
qp.setBackgroundMode(QtCore.Qt.OpaqueMode)
|
qp.setBackgroundMode(QtCore.Qt.OpaqueMode)
|
||||||
qp.setBackground(Chart.color.background)
|
qp.setBackground(Chart.color.background)
|
||||||
|
@ -707,16 +674,16 @@ class FrequencyChart(Chart):
|
||||||
self.topMargin + self.dim.height])
|
self.topMargin + self.dim.height])
|
||||||
else:
|
else:
|
||||||
return x, y
|
return x, y
|
||||||
|
|
||||||
da = p2 - p1
|
da = p2 - p1
|
||||||
db = p4 - p3
|
db = p4 - p3
|
||||||
dp = p1 - p3
|
dp = p1 - p3
|
||||||
dap = np.array([-da[1], da[0]])
|
dap = np.array([-da[1], da[0]])
|
||||||
denom = np.dot(dap, db)
|
denom = np.dot(dap, db)
|
||||||
if denom != 0:
|
|
||||||
num = np.dot(dap, dp)
|
return (((np.dot(dap, dp) / denom.astype(float)) * db + p3)[:2]
|
||||||
result = (num / denom.astype(float)) * db + p3
|
if denom
|
||||||
return result[0], result[1]
|
else (x, y))
|
||||||
return x, y
|
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
new_chart = super().copy()
|
new_chart = super().copy()
|
||||||
|
|
|
@ -290,7 +290,7 @@ class TDRChart(Chart):
|
||||||
ticks = math.floor((self.width() - self.leftMargin) / 100)
|
ticks = math.floor((self.width() - self.leftMargin) / 100)
|
||||||
self.drawTitle(qp)
|
self.drawTitle(qp)
|
||||||
|
|
||||||
if len(self.tdrWindow.td) > 0:
|
if self.tdrWindow.td:
|
||||||
if self.fixedSpan:
|
if self.fixedSpan:
|
||||||
max_length = max(0.1, self.maxDisplayLength)
|
max_length = max(0.1, self.maxDisplayLength)
|
||||||
max_index = np.searchsorted(self.tdrWindow.distance_axis, max_length * 2)
|
max_index = np.searchsorted(self.tdrWindow.distance_axis, max_length * 2)
|
||||||
|
@ -405,10 +405,12 @@ class TDRChart(Chart):
|
||||||
if self.dragbox.state and self.dragbox.pos[0] != -1:
|
if self.dragbox.state and self.dragbox.pos[0] != -1:
|
||||||
dashed_pen = QtGui.QPen(Chart.color.foreground, 1, QtCore.Qt.DashLine)
|
dashed_pen = QtGui.QPen(Chart.color.foreground, 1, QtCore.Qt.DashLine)
|
||||||
qp.setPen(dashed_pen)
|
qp.setPen(dashed_pen)
|
||||||
top_left = QtCore.QPoint(self.dragbox.pos_start[0], self.dragbox.stateStart[1])
|
qp.drawRect(
|
||||||
bottom_right = QtCore.QPoint(self.dragbox.pos[0], self.dragbox.stateCurrent[1])
|
QtCore.QRect(
|
||||||
rect = QtCore.QRect(top_left, bottom_right)
|
QtCore.QPoint(*self.dragbox.pos_start),
|
||||||
qp.drawRect(rect)
|
QtCore.QPoint(*self.dragbox.pos)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
qp.end()
|
qp.end()
|
||||||
|
|
||||||
|
@ -431,24 +433,24 @@ class TDRChart(Chart):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def lengthAtPosition(self, x, limit=True):
|
def lengthAtPosition(self, x, limit=True):
|
||||||
if len(self.tdrWindow.td) > 0:
|
if not self.tdrWindow.td:
|
||||||
width = self.width() - self.leftMargin - self.rightMargin
|
return 0
|
||||||
absx = x - self.leftMargin
|
width = self.width() - self.leftMargin - self.rightMargin
|
||||||
if self.fixedSpan:
|
absx = x - self.leftMargin
|
||||||
max_length = self.maxDisplayLength
|
if self.fixedSpan:
|
||||||
min_length = self.minDisplayLength
|
max_length = self.maxDisplayLength
|
||||||
x_step = (max_length - min_length) / width
|
min_length = self.minDisplayLength
|
||||||
else:
|
x_step = (max_length - min_length) / width
|
||||||
min_length = 0
|
else:
|
||||||
max_length = self.tdrWindow.distance_axis[
|
min_length = 0
|
||||||
math.ceil(len(self.tdrWindow.distance_axis) / 2)] / 2
|
max_length = self.tdrWindow.distance_axis[
|
||||||
x_step = max_length / width
|
math.ceil(len(self.tdrWindow.distance_axis) / 2)] / 2
|
||||||
if limit and absx < 0:
|
x_step = max_length / width
|
||||||
return min_length
|
if limit and absx < 0:
|
||||||
if limit and absx > width:
|
return min_length
|
||||||
return max_length
|
if limit and absx > width:
|
||||||
return absx * x_step + min_length
|
return max_length
|
||||||
return 0
|
return absx * x_step + min_length
|
||||||
|
|
||||||
def zoomTo(self, x1, y1, x2, y2):
|
def zoomTo(self, x1, y1, x2, y2):
|
||||||
logger.debug("Zoom to (x,y) by (x,y): (%d, %d) by (%d, %d)", x1, y1, x2, y2)
|
logger.debug("Zoom to (x,y) by (x,y): (%d, %d) by (%d, %d)", x1, y1, x2, y2)
|
||||||
|
@ -470,68 +472,6 @@ class TDRChart(Chart):
|
||||||
|
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def wheelEvent(self, a0: QtGui.QWheelEvent) -> None:
|
|
||||||
if len(self.tdrWindow.td) == 0:
|
|
||||||
a0.ignore()
|
|
||||||
return
|
|
||||||
chart_height = self.dim.height
|
|
||||||
chart_width = self.dim.width
|
|
||||||
do_zoom_x = do_zoom_y = True
|
|
||||||
if a0.modifiers() == QtCore.Qt.ShiftModifier:
|
|
||||||
do_zoom_x = False
|
|
||||||
if a0.modifiers() == QtCore.Qt.ControlModifier:
|
|
||||||
do_zoom_y = False
|
|
||||||
if a0.angleDelta().y() > 0:
|
|
||||||
# Zoom in
|
|
||||||
a0.accept()
|
|
||||||
# Center of zoom = a0.x(), a0.y()
|
|
||||||
# We zoom in by 1/10 of the width/height.
|
|
||||||
rate = a0.angleDelta().y() / 120
|
|
||||||
if do_zoom_x:
|
|
||||||
zoomx = rate * chart_width / 10
|
|
||||||
else:
|
|
||||||
zoomx = 0
|
|
||||||
if do_zoom_y:
|
|
||||||
zoomy = rate * chart_height / 10
|
|
||||||
else:
|
|
||||||
zoomy = 0
|
|
||||||
absx = max(0, a0.x() - self.leftMargin)
|
|
||||||
absy = max(0, a0.y() - self.topMargin)
|
|
||||||
ratiox = absx/chart_width
|
|
||||||
ratioy = absy/chart_height
|
|
||||||
# TODO: Change zoom to center on the mouse if possible,
|
|
||||||
# or extend box to the side that has room if not.
|
|
||||||
p1x = int(self.leftMargin + ratiox * zoomx)
|
|
||||||
p1y = int(self.topMargin + ratioy * zoomy)
|
|
||||||
p2x = int(self.leftMargin + chart_width - (1 - ratiox) * zoomx)
|
|
||||||
p2y = int(self.topMargin + chart_height - (1 - ratioy) * zoomy)
|
|
||||||
self.zoomTo(p1x, p1y, p2x, p2y)
|
|
||||||
elif a0.angleDelta().y() < 0:
|
|
||||||
# Zoom out
|
|
||||||
a0.accept()
|
|
||||||
# Center of zoom = a0.x(), a0.y()
|
|
||||||
# We zoom out by 1/9 of the width/height, to match zoom in.
|
|
||||||
rate = -a0.angleDelta().y() / 120
|
|
||||||
if do_zoom_x:
|
|
||||||
zoomx = rate * chart_width / 9
|
|
||||||
else:
|
|
||||||
zoomx = 0
|
|
||||||
if do_zoom_y:
|
|
||||||
zoomy = rate * chart_height / 9
|
|
||||||
else:
|
|
||||||
zoomy = 0
|
|
||||||
absx = max(0, a0.x() - self.leftMargin)
|
|
||||||
absy = max(0, a0.y() - self.topMargin)
|
|
||||||
ratiox = absx/chart_width
|
|
||||||
ratioy = absy/chart_height
|
|
||||||
p1x = int(self.leftMargin - ratiox * zoomx)
|
|
||||||
p1y = int(self.topMargin - ratioy * zoomy)
|
|
||||||
p2x = int(self.leftMargin + chart_width + (1 - ratiox) * zoomx)
|
|
||||||
p2y = int(self.topMargin + chart_height + (1 - ratioy) * zoomy)
|
|
||||||
self.zoomTo(p1x, p1y, p2x, p2y)
|
|
||||||
else:
|
|
||||||
a0.ignore()
|
|
||||||
|
|
||||||
def resizeEvent(self, a0: QtGui.QResizeEvent) -> None:
|
def resizeEvent(self, a0: QtGui.QResizeEvent) -> None:
|
||||||
super().resizeEvent(a0)
|
super().resizeEvent(a0)
|
||||||
self.dim.width = self.width() - self.leftMargin - self.rightMargin
|
self.dim.width = self.width() - self.leftMargin - self.rightMargin
|
||||||
|
|
Ładowanie…
Reference in New Issue