High DPI support: Scale Draft cursor to device pixel ratio

This commit is contained in:
Vanuan
2020-07-29 05:41:42 +03:00
committed by wmayer
parent 7a0aec1210
commit b53326b38c

View File

@@ -1111,6 +1111,44 @@ class Snapper:
if self.dim2.Distance:
self.dim2.on()
def get_cursor_size(self):
# TODO Unfortunately, there's no way to get the cursor size in Qt
# Either provide platform-specific implementation or make it a user preference
# This should be in device-independent pixels
return 32
def device_pixel_ratio(self):
device_pixel_ratio = 1
mw = Gui.getMainWindow()
for w in mw.findChild(QtGui.QMdiArea).findChildren(QtGui.QWidget):
if w.metaObject().className() == "SIM::Coin3D::Quarter::QuarterWidget":
device_pixel_ratio = w.devicePixelRatio()
return device_pixel_ratio
def get_cursor_with_tail(self, base_icon_name, tail_icon_name=None):
base_icon = QtGui.QPixmap(base_icon_name)
device_pixel_ratio = self.device_pixel_ratio()
full_icon_size = self.get_cursor_size()
new_icon_width = full_icon_size * device_pixel_ratio
new_icon_height = 0.75 * full_icon_size * device_pixel_ratio
new_icon = QtGui.QPixmap(new_icon_width, new_icon_height)
new_icon.fill(QtCore.Qt.transparent)
qp = QtGui.QPainter()
qp.begin(new_icon)
base_icon = base_icon.scaledToWidth(0.5 * full_icon_size * device_pixel_ratio)
qp.drawPixmap(0, 0, base_icon)
if tail_icon_name:
tail_icon_width = 0.5 * full_icon_size * device_pixel_ratio
tail_icon_x = 0.5 * full_icon_size * device_pixel_ratio
tail_icon_y = 0.25 * full_icon_size * device_pixel_ratio
tail_pixmap = QtGui.QPixmap(tail_icon_name).scaledToWidth(tail_icon_width)
qp.drawPixmap(QtCore.QPoint(tail_icon_x, tail_icon_y), tail_pixmap)
qp.end()
cur_hot_x = 0.25 * full_icon_size * device_pixel_ratio
cur_hot_y = 0.25 * full_icon_size * device_pixel_ratio
new_icon.setDevicePixelRatio(device_pixel_ratio)
cur = QtGui.QCursor(new_icon, cur_hot_x, cur_hot_y)
return cur
def setCursor(self, mode=None):
"""Set or reset the cursor to the given mode or resets."""
@@ -1128,24 +1166,17 @@ class Snapper:
self.cursorMode = None
else:
if mode != self.cursorMode:
baseicon = QtGui.QPixmap(":/icons/Draft_Cursor.svg")
newicon = QtGui.QPixmap(32, 24)
newicon.fill(QtCore.Qt.transparent)
qp = QtGui.QPainter()
qp.begin(newicon)
qp.drawPixmap(0, 0, baseicon)
base_icon_name = ":/icons/Draft_Cursor.svg"
tail_icon_name = None
if not (mode == 'passive'):
tp = QtGui.QPixmap(self.cursors[mode]).scaledToWidth(16)
qp.drawPixmap(QtCore.QPoint(16, 8), tp)
qp.end()
cur = QtGui.QCursor(newicon, 8, 8)
tail_icon_name = self.cursors[mode]
cur = self.get_cursor_with_tail(base_icon_name, tail_icon_name)
mw = Gui.getMainWindow()
for w in mw.findChild(QtGui.QMdiArea).findChildren(QtGui.QWidget):
if w.metaObject().className() == "SIM::Coin3D::Quarter::QuarterWidget":
w.setCursor(cur)
self.cursorMode = mode
def restack(self):
"""Lower the grid tracker so it doesn't obscure other objects."""
if self.grid: