Merge pull request #509 from zarath/bugfix/zoom

enable to zoom out (not perfect yet)
pull/510/head
Holger Müller 2022-05-28 21:54:02 +02:00 zatwierdzone przez GitHub
commit f5afb78970
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
3 zmienionych plików z 73 dodań i 132 usunięć

Wyświetl plik

@ -219,6 +219,37 @@ class Chart(QtWidgets.QWidget):
self.dragbox.pos_start = (0, 0)
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):
raise NotImplementedError()
@ -266,9 +297,12 @@ class Chart(QtWidgets.QWidget):
self.swrMarkers.clear()
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.draw(x, y, color, str(number))
cmarker.draw(x, y, color, f"{number}")
def drawTitle(self, qp: QtGui.QPainter, position: QtCore.QPoint = None):
qp.setPen(Chart.color.text)

Wyświetl plik

@ -237,7 +237,8 @@ class FrequencyChart(Chart):
self.logarithmicY = logarithmic and self.logarithmicYAllowed()
self.update()
def logarithmicYAllowed(self) -> bool:
@staticmethod
def logarithmicYAllowed() -> bool:
return False
def setMinimumFrequency(self):
@ -380,38 +381,6 @@ class FrequencyChart(Chart):
val = -1 * ((absy / self.dim.height * self.span) - self.maxValue)
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):
val1 = self.valueAtPosition(y1)
val2 = self.valueAtPosition(y2)
@ -481,14 +450,12 @@ class FrequencyChart(Chart):
self.drawDragbog(qp)
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):
if (len(self.data) > 0 and
(self.data[0].freq > self.fstop or
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)):
if (self.data and self._data_oob(self.data) and
(not self.reference or self._data_oob(self.reference))):
# Data outside frequency range
qp.setBackgroundMode(QtCore.Qt.OpaqueMode)
qp.setBackground(Chart.color.background)
@ -707,16 +674,16 @@ class FrequencyChart(Chart):
self.topMargin + self.dim.height])
else:
return x, y
da = p2 - p1
db = p4 - p3
dp = p1 - p3
dap = np.array([-da[1], da[0]])
denom = np.dot(dap, db)
if denom != 0:
num = np.dot(dap, dp)
result = (num / denom.astype(float)) * db + p3
return result[0], result[1]
return x, y
return (((np.dot(dap, dp) / denom.astype(float)) * db + p3)[:2]
if denom
else (x, y))
def copy(self):
new_chart = super().copy()

Wyświetl plik

@ -290,7 +290,7 @@ class TDRChart(Chart):
ticks = math.floor((self.width() - self.leftMargin) / 100)
self.drawTitle(qp)
if len(self.tdrWindow.td) > 0:
if self.tdrWindow.td:
if self.fixedSpan:
max_length = max(0.1, self.maxDisplayLength)
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:
dashed_pen = QtGui.QPen(Chart.color.foreground, 1, QtCore.Qt.DashLine)
qp.setPen(dashed_pen)
top_left = QtCore.QPoint(self.dragbox.pos_start[0], self.dragbox.stateStart[1])
bottom_right = QtCore.QPoint(self.dragbox.pos[0], self.dragbox.stateCurrent[1])
rect = QtCore.QRect(top_left, bottom_right)
qp.drawRect(rect)
qp.drawRect(
QtCore.QRect(
QtCore.QPoint(*self.dragbox.pos_start),
QtCore.QPoint(*self.dragbox.pos)
)
)
qp.end()
@ -431,24 +433,24 @@ class TDRChart(Chart):
return 0
def lengthAtPosition(self, x, limit=True):
if len(self.tdrWindow.td) > 0:
width = self.width() - self.leftMargin - self.rightMargin
absx = x - self.leftMargin
if self.fixedSpan:
max_length = self.maxDisplayLength
min_length = self.minDisplayLength
x_step = (max_length - min_length) / width
else:
min_length = 0
max_length = self.tdrWindow.distance_axis[
math.ceil(len(self.tdrWindow.distance_axis) / 2)] / 2
x_step = max_length / width
if limit and absx < 0:
return min_length
if limit and absx > width:
return max_length
return absx * x_step + min_length
return 0
if not self.tdrWindow.td:
return 0
width = self.width() - self.leftMargin - self.rightMargin
absx = x - self.leftMargin
if self.fixedSpan:
max_length = self.maxDisplayLength
min_length = self.minDisplayLength
x_step = (max_length - min_length) / width
else:
min_length = 0
max_length = self.tdrWindow.distance_axis[
math.ceil(len(self.tdrWindow.distance_axis) / 2)] / 2
x_step = max_length / width
if limit and absx < 0:
return min_length
if limit and absx > width:
return max_length
return absx * x_step + min_length
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)
@ -470,68 +472,6 @@ class TDRChart(Chart):
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:
super().resizeEvent(a0)
self.dim.width = self.width() - self.leftMargin - self.rightMargin