Pārlūkot izejas kodu

wxGUI: more Python 3.10 fixes (#2050)

* wxGUI/gui_core: SpinCtrl widget require integer min, max param arg
* wxGUI/gui_core: add ConvertParamArgToInt mixin class for conversion args, kwargs float value to the int
* wxGUI/gui_core: Rect widget require integer x, y param arg
* wxGUI/gui_core: PseudoDC widget DrawRectangle method require integer x, y, width, height param arg
* wxGUI/psmap: wx.MemoryDC widget DrawBitmap method require integer x, y param arg
* wxGUI/psmap: wx.Rect widget Inflate method require integer dx, dy param arg
* wxGUI/gui_core: PseudoDC widget DrawBitmap method require integer x, y param arg
* wxGUI/gui_core: PseudoDC widget DrawCircle method require integer x, y, radius param arg
* wxGUI/gui_core: PseudoDC widget DrawLinePoint method require integer x1, y1, x2, y2 param arg
* wxGUI/gui_core: Rect widget CenterIn method require wx.Rect r param arg
* wxGUI/gui_core: PseudoDC widget SetIdBounds method require wx.Rect rect param arg

Co-authored-by: Tomas Zigo <tomas.zigo@slovanet.sk>
Anna Petrasova 3 gadi atpakaļ
vecāks
revīzija
b77f871dc2

+ 2 - 2
gui/wxpython/animation/frame.py

@@ -27,7 +27,7 @@ import grass.temporal as tgis
 from grass.exceptions import FatalError
 from core import globalvar
 from gui_core.widgets import IntegerValidator
-from gui_core.wrap import StaticText, TextCtrl
+from gui_core.wrap import StaticText, TextCtrl, Slider
 from core.gcmd import RunCommand, GWarning
 
 from animation.mapwindow import AnimationWindow
@@ -420,7 +420,7 @@ class AnimationSliderBase(wx.Panel):
     def __init__(self, parent):
         wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
         self.label1 = StaticText(self, id=wx.ID_ANY)
-        self.slider = wx.Slider(self, id=wx.ID_ANY, style=wx.SL_HORIZONTAL)
+        self.slider = Slider(self, id=wx.ID_ANY, style=wx.SL_HORIZONTAL)
         self.indexField = TextCtrl(
             self,
             id=wx.ID_ANY,

+ 1 - 1
gui/wxpython/animation/provider.py

@@ -851,7 +851,7 @@ def createNoDataBitmap(imageWidth, imageHeight, text="No data"):
         )
     )
     tw, th = dc.GetTextExtent(text)
-    dc.DrawText(text, (imageWidth - tw) / 2, (imageHeight - th) / 2)
+    dc.DrawText(text, (imageWidth - tw) // 2, (imageHeight - th) // 2)
     dc.SelectObject(wx.NullBitmap)
     return bitmap
 

+ 1 - 1
gui/wxpython/gmodeler/frame.py

@@ -1285,7 +1285,7 @@ class ModelCanvas(ogl.ShapeCanvas):
         self.SetDiagram(self.diagram)
         self.diagram.SetCanvas(self)
 
-        self.SetScrollbars(20, 20, 2000 / 20, 2000 / 20)
+        self.SetScrollbars(20, 20, 2000 // 20, 2000 // 20)
 
         self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
         self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)

+ 2 - 1
gui/wxpython/gui_core/dialogs.py

@@ -59,6 +59,7 @@ from gui_core.wrap import (
     HyperlinkCtrl,
     Menu,
     NewId,
+    Slider,
     SpinCtrl,
     StaticBox,
     StaticText,
@@ -1817,7 +1818,7 @@ class SetOpacityDialog(wx.Dialog):
         sizer = wx.BoxSizer(wx.VERTICAL)
 
         box = wx.GridBagSizer(vgap=5, hgap=5)
-        self.value = wx.Slider(
+        self.value = Slider(
             panel,
             id=wx.ID_ANY,
             value=int(self.opacity * 100),

+ 2 - 2
gui/wxpython/gui_core/forms.py

@@ -1417,8 +1417,8 @@ class CmdPanel(wx.Panel):
                         which_sizer.Add(win, proportion=0, flag=style, border=5)
 
                 elif p.get("type", "") == "integer":
-                    minValue = -1e9
-                    maxValue = 1e9
+                    minValue = int(-1e9)
+                    maxValue = int(1e9)
                     value = self._getValue(p)
 
                     win = SpinCtrl(

+ 9 - 8
gui/wxpython/gui_core/widgets.py

@@ -94,6 +94,7 @@ from core.debug import Debug
 from gui_core.wrap import (
     Button,
     SearchCtrl,
+    Slider,
     StaticText,
     StaticBox,
     TextCtrl,
@@ -426,12 +427,12 @@ class NumTextCtrl(TextCtrl):
         pass
 
 
-class FloatSlider(wx.Slider):
+class FloatSlider(Slider):
     """Class derived from wx.Slider for floats"""
 
     def __init__(self, **kwargs):
         Debug.msg(1, "FloatSlider.__init__()")
-        wx.Slider.__init__(self, **kwargs)
+        Slider.__init__(self, **kwargs)
         self.coef = 1.0
         # init range
         self.minValueOrig = 0
@@ -516,7 +517,7 @@ class SymbolButton(BitmapTextButton):
     def DrawRecord(self, dc, size):
         """Draw record symbol"""
         dc.SetBrush(wx.Brush(wx.Colour(255, 0, 0)))
-        dc.DrawCircle(size[0] / 2, size[1] / 2, size[0] / 2)
+        dc.DrawCircle(size[0] // 2, size[1] // 2, size[0] // 2)
 
     def DrawStop(self, dc, size):
         """Draw stop symbol"""
@@ -526,14 +527,14 @@ class SymbolButton(BitmapTextButton):
     def DrawPlay(self, dc, size):
         """Draw play symbol"""
         dc.SetBrush(wx.Brush(wx.Colour(0, 255, 0)))
-        points = (wx.Point(0, 0), wx.Point(0, size[1]), wx.Point(size[0], size[1] / 2))
+        points = (wx.Point(0, 0), wx.Point(0, size[1]), wx.Point(size[0], size[1] // 2))
         dc.DrawPolygon(points)
 
     def DrawPause(self, dc, size):
         """Draw pause symbol"""
         dc.SetBrush(wx.Brush(wx.Colour(50, 50, 50)))
-        dc.DrawRectangle(0, 0, 2 * size[0] / 5, size[1])
-        dc.DrawRectangle(3 * size[0] / 5, 0, 2 * size[0] / 5, size[1])
+        dc.DrawRectangle(0, 0, 2 * size[0] // 5, size[1])
+        dc.DrawRectangle(3 * size[0] // 5, 0, 2 * size[0] // 5, size[1])
 
 
 class StaticWrapText(GenStaticText):
@@ -1672,14 +1673,14 @@ class PictureComboBox(OwnerDrawnComboBox):
         # for painting the items in the popup
         bitmap = self.GetPictureBitmap(self.GetString(item))
         if bitmap:
-            dc.DrawBitmap(bitmap, r.x, r.y + (r.height - bitmap.GetHeight()) / 2)
+            dc.DrawBitmap(bitmap, r.x, r.y + (r.height - bitmap.GetHeight()) // 2)
             width = bitmap.GetWidth() + 10
         else:
             width = 0
         dc.DrawText(
             self.GetString(item),
             r.x + width,
-            (r.y + 0) + (r.height - dc.GetCharHeight()) / 2,
+            (r.y + 0) + (r.height - dc.GetCharHeight()) // 2,
         )
 
     def OnMeasureItem(self, item):

+ 66 - 7
gui/wxpython/gui_core/wrap.py

@@ -58,6 +58,27 @@ else:
     from wx import NewId  # noqa: F401
 
 
+def convertToInt(argsOrKwargs, roundVal=False):
+    """Convert args, kwargs float value to int
+
+    :param tuple/list/dict argsOrKwargs: args or kwargs
+    :param bool roundVal: True if you want round float value
+
+    return list or dict
+    """
+    result = {} if isinstance(argsOrKwargs, dict) else []
+    j = None
+    for i in argsOrKwargs:
+        if isinstance(result, dict):
+            i, j = argsOrKwargs[i], i
+        if isinstance(i, float):
+            if roundVal:
+                i = round(i)
+            i = int(i)
+        result.update({j: i}) if j else result.append(i)
+    return result
+
+
 def IsDark():
     """Detects if used theme is dark.
     Wraps wx method for different versions."""
@@ -143,6 +164,23 @@ class Panel(wx.Panel):
             wx.Panel.SetToolTipString(self, tip)
 
 
+class Slider(wx.Slider):
+    """Wrapper around wx.Slider to have more control
+    over the widget on different platforms/wxpython versions"""
+
+    def __init__(self, *args, **kwargs):
+        args = convertToInt(argsOrKwargs=args)
+        kwargs = convertToInt(argsOrKwargs=kwargs)
+
+        wx.Slider.__init__(self, *args, **kwargs)
+
+    def SetRange(self, minValue, maxValue):
+        wx.Slider.SetRange(self, int(minValue), int(maxValue))
+
+    def SetValue(self, value):
+        wx.Slider.SetValue(self, int(value))
+
+
 class SpinCtrl(wx.SpinCtrl):
     """Wrapper around wx.SpinCtrl to have more control
     over the widget on different platforms"""
@@ -150,6 +188,8 @@ class SpinCtrl(wx.SpinCtrl):
     gtk3MinSize = 130
 
     def __init__(self, *args, **kwargs):
+        args = convertToInt(argsOrKwargs=args)
+        kwargs = convertToInt(argsOrKwargs=kwargs)
         if gtk3:
             if "size" in kwargs:
                 kwargs["size"] = wx.Size(
@@ -600,11 +640,13 @@ class PseudoDC(wx.adv.PseudoDC if wxPythonPhoenix else wx.PseudoDC):
     def __init__(self, *args, **kwargs):
         super(PseudoDC, self).__init__(*args, **kwargs)
 
-    def DrawLinePoint(self, pt1, pt2):
+    def DrawLinePoint(self, *args, **kwargs):
+        args = convertToInt(argsOrKwargs=args, roundVal=True)
+        kwargs = convertToInt(argsOrKwargs=kwargs, roundVal=True)
         if wxPythonPhoenix:
-            super(PseudoDC, self).DrawLine(pt1, pt2)
+            super(PseudoDC, self).DrawLine(*args, **kwargs)
         else:
-            super(PseudoDC, self).DrawLinePoint(pt1, pt2)
+            super(PseudoDC, self).DrawLinePoint(*args, **kwargs)
 
     def DrawRectangleRect(self, rect):
         if wxPythonPhoenix:
@@ -620,6 +662,21 @@ class PseudoDC(wx.adv.PseudoDC if wxPythonPhoenix else wx.PseudoDC):
         if not wxPythonPhoenix:
             super(PseudoDC, self).EndDrawing()
 
+    def DrawRectangle(self, *args, **kwargs):
+        args = convertToInt(argsOrKwargs=args, roundVal=True)
+        kwargs = convertToInt(argsOrKwargs=kwargs, roundVal=True)
+        super(PseudoDC, self).DrawRectangle(*args, **kwargs)
+
+    def DrawBitmap(self, *args, **kwargs):
+        args = convertToInt(argsOrKwargs=args, roundVal=True)
+        kwargs = convertToInt(argsOrKwargs=kwargs, roundVal=True)
+        super(PseudoDC, self).DrawBitmap(*args, **kwargs)
+
+    def DrawCircle(self, *args, **kwargs):
+        args = convertToInt(argsOrKwargs=args, roundVal=True)
+        kwargs = convertToInt(argsOrKwargs=kwargs, roundVal=True)
+        super(PseudoDC, self).DrawCircle(*args, **kwargs)
+
 
 class ClientDC(wx.ClientDC):
     """Wrapper around wx.ClientDC to have more control
@@ -640,13 +697,15 @@ class Rect(wx.Rect):
     over the widget on different platforms/wxpython versions"""
 
     def __init__(self, *args, **kwargs):
+        args = convertToInt(argsOrKwargs=args)
+        kwargs = convertToInt(argsOrKwargs=kwargs)
         wx.Rect.__init__(self, *args, **kwargs)
 
     def ContainsXY(self, x, y):
         if wxPythonPhoenix:
-            return wx.Rect.Contains(self, x=x, y=y)
+            return wx.Rect.Contains(self, x=int(x), y=int(y))
         else:
-            return wx.Rect.ContainsXY(self, x, y)
+            return wx.Rect.ContainsXY(self, int(x), int(y))
 
     def ContainsRect(self, rect):
         if wxPythonPhoenix:
@@ -656,9 +715,9 @@ class Rect(wx.Rect):
 
     def OffsetXY(self, dx, dy):
         if wxPythonPhoenix:
-            return wx.Rect.Offset(self, dx, dy)
+            return wx.Rect.Offset(self, int(dx), int(dy))
         else:
-            return wx.Rect.OffsetXY(self, dx, dy)
+            return wx.Rect.OffsetXY(self, int(dx), int(dy))
 
 
 class CheckBox(wx.CheckBox):

+ 5 - 4
gui/wxpython/mapswipe/frame.py

@@ -23,6 +23,7 @@ import grass.script as grass
 
 from gui_core.mapdisp import DoubleMapPanel, FrameMixin
 from gui_core.dialogs import GetImageHandlers
+from gui_core.wrap import Slider
 from mapwin.base import MapWindowProperties
 from core.render import Map
 from mapdisp import statusbar as sb
@@ -64,8 +65,8 @@ class SwipeMapPanel(DoubleMapPanel):
         #
         self.splitter = MapSplitter(parent=self, id=wx.ID_ANY)
 
-        self.sliderH = wx.Slider(self, id=wx.ID_ANY, style=wx.SL_HORIZONTAL)
-        self.sliderV = wx.Slider(self, id=wx.ID_ANY, style=wx.SL_VERTICAL)
+        self.sliderH = Slider(self, id=wx.ID_ANY, style=wx.SL_HORIZONTAL)
+        self.sliderV = Slider(self, id=wx.ID_ANY, style=wx.SL_VERTICAL)
 
         self.mapWindowProperties = MapWindowProperties()
         self.mapWindowProperties.setValuesFromUserSettings()
@@ -684,10 +685,10 @@ class SwipeMapPanel(DoubleMapPanel):
         # hide/show slider
         if self.splitter.GetSplitMode() == wx.SPLIT_HORIZONTAL:
             self._mgr.GetPane("sliderV").Show(mode == "swipe")
-            size = self.splitter.GetSize()[1] / 2
+            size = self.splitter.GetSize()[1] // 2
         else:
             self._mgr.GetPane("sliderH").Show(mode == "swipe")
-            size = self.splitter.GetSize()[0] / 2
+            size = self.splitter.GetSize()[0] // 2
         # set sash in the middle
         self.splitter.SetSashPosition(size)
         self.slider.SetValue(size)

+ 11 - 10
gui/wxpython/nviz/tools.py

@@ -66,6 +66,7 @@ from gui_core.wrap import (
     ToggleButton,
     Button,
     TextCtrl,
+    Slider,
     StaticText,
     StaticBox,
     CheckListBox,
@@ -3060,7 +3061,7 @@ class NvizToolWindow(GNotebook):
         gridSizer.Add(label, pos=(4, 0), flag=wx.ALIGN_CENTER_VERTICAL)
         # sliders
         for i, coord in enumerate(("x1", "x2")):
-            slider = wx.Slider(
+            slider = Slider(
                 parent=panel, id=wx.ID_ANY, minValue=0, maxValue=100, value=0
             )
             self.win["volume"]["slice"]["slider_" + coord] = slider.GetId()
@@ -3069,7 +3070,7 @@ class NvizToolWindow(GNotebook):
             gridSizer.Add(slider, pos=(1, i + 1), flag=wx.ALIGN_CENTER | wx.EXPAND)
 
         for i, coord in enumerate(("y1", "y2")):
-            slider = wx.Slider(
+            slider = Slider(
                 parent=panel, id=wx.ID_ANY, minValue=0, maxValue=100, value=0
             )
             self.win["volume"]["slice"]["slider_" + coord] = slider.GetId()
@@ -3078,7 +3079,7 @@ class NvizToolWindow(GNotebook):
             gridSizer.Add(slider, pos=(2, i + 1), flag=wx.ALIGN_CENTER | wx.EXPAND)
 
         for i, coord in enumerate(("z1", "z2")):
-            slider = wx.Slider(
+            slider = Slider(
                 parent=panel, id=wx.ID_ANY, minValue=0, maxValue=100, value=0
             )
             self.win["volume"]["slice"]["slider_" + coord] = slider.GetId()
@@ -3157,7 +3158,7 @@ class NvizToolWindow(GNotebook):
         if floatSlider:
             slider = FloatSlider(**kwargs)
         else:
-            slider = wx.Slider(**kwargs)
+            slider = Slider(**kwargs)
 
         slider.SetName("slider")
         if bind[0]:
@@ -5144,10 +5145,10 @@ class NvizToolWindow(GNotebook):
 
         if pageId == "view":
             self.SetPage("view")
-            hmin = self.mapWindow.iview["height"]["min"]
-            hmax = self.mapWindow.iview["height"]["max"]
-            hval = self.mapWindow.iview["height"]["value"]
-            zmin = self.mapWindow.view["z-exag"]["min"]
+            hmin = int(self.mapWindow.iview["height"]["min"])
+            hmax = int(self.mapWindow.iview["height"]["max"])
+            hval = int(self.mapWindow.iview["height"]["value"])
+            zmin = int(self.mapWindow.view["z-exag"]["min"])
             zmax = self.mapWindow.view["z-exag"]["max"]
             zval = self.mapWindow.view["z-exag"]["value"]
 
@@ -5805,8 +5806,8 @@ class PositionWindow(Window):
             y = y * h
         self.pdc.Clear()
         self.pdc.BeginDrawing()
-        self.pdc.DrawLine(w / 2, h / 2, x, y)
-        self.pdc.DrawCircle(x, y, 5)
+        self.pdc.DrawLine(w // 2, h // 2, int(x), int(y))
+        self.pdc.DrawCircle(int(x), int(y), 5)
         self.pdc.EndDrawing()
 
     def OnPaint(self, event):

+ 4 - 4
gui/wxpython/psmap/dialogs.py

@@ -5283,7 +5283,7 @@ class TextDialog(PsmapDialog):
             self.effect["highlightCtrl"].SetValue(False)
             self.effect["highlightColor"].SetColour(convertRGB("grey"))
 
-        self.effect["highlightWidth"].SetValue(float(self.textDict["hwidth"]))
+        self.effect["highlightWidth"].SetValue(int(float(self.textDict["hwidth"])))
 
         if self.textDict["border"] is None:
             self.textDict["border"] = "none"
@@ -5294,7 +5294,7 @@ class TextDialog(PsmapDialog):
             self.effect["borderCtrl"].SetValue(False)
             self.effect["borderColor"].SetColour(convertRGB("black"))
 
-        self.effect["borderWidth"].SetValue(float(self.textDict["width"]))
+        self.effect["borderWidth"].SetValue(int(float(self.textDict["width"])))
 
         gridBagSizer.Add(
             self.effect["backgroundCtrl"],
@@ -6004,8 +6004,8 @@ class ImageDialog(PsmapDialog):
             dc.SelectObject(buffer)
             dc.SetBrush(dc.GetBrush())
             dc.Clear()
-            posX = self.previewSize[0] / 2 - bitmap.GetWidth() / 2
-            posY = self.previewSize[1] / 2 - bitmap.GetHeight() / 2
+            posX = self.previewSize[0] // 2 - bitmap.GetWidth() // 2
+            posY = self.previewSize[1] // 2 - bitmap.GetHeight() // 2
             dc.DrawBitmap(bitmap, posX, posY)
             self.imagePanel.image["preview"].SetBitmap(buffer)
             dc.SelectObject(wx.NullBitmap)

+ 16 - 15
gui/wxpython/psmap/frame.py

@@ -969,7 +969,7 @@ class PsMapFrame(wx.Frame):
         """creates a wx.Font object from selected postscript font. To be
         used for estimating bounding rectangle of text"""
 
-        fontsize = textDict["fontsize"] * self.canvas.currScale
+        fontsize = round(textDict["fontsize"] * self.canvas.currScale)
         fontface = textDict["font"].split("-")[0]
         try:
             fontstyle = textDict["font"].split("-")[1]
@@ -1459,8 +1459,9 @@ class PsMapBufferedWindow(wx.Window):
             units.convert(value=(rect.GetY() - pRecty), fromUnit=fromU, toUnit=toU)
             * scale
         )
-
-        return Rect2D(X, Y, Width, Height)
+        if canvasToPaper:
+            return Rect2D(X, Y, Width, Height)
+        return Rect2D(int(X), int(Y), int(Width), int(Height))
 
     def SetPage(self):
         """Sets and changes page, redraws paper"""
@@ -1481,7 +1482,7 @@ class PsMapBufferedWindow(wx.Window):
 
         x = cW / 2 - pW / 2
         y = cH / 2 - pH / 2
-        self.DrawPaper(Rect(x, y, pW, pH))
+        self.DrawPaper(Rect(int(x), int(y), int(pW), int(pH)))
 
     def modifyRectangle(self, r):
         """Recalculates rectangle not to have negative size"""
@@ -2347,7 +2348,7 @@ class PsMapBufferedWindow(wx.Window):
             bounds = self.pdcPaper.GetIdBounds(self.pageId)
         else:
             bounds = self.pdcImage.GetIdBounds(self.imageId)
-        zoomP = bounds.Inflate(bounds.width / 20, bounds.height / 20)
+        zoomP = bounds.Inflate(round(bounds.width / 20), round(bounds.height / 20))
         zoomFactor, view = self.ComputeZoom(zoomP)
         self.Zoom(zoomFactor, view)
 
@@ -2400,7 +2401,7 @@ class PsMapBufferedWindow(wx.Window):
             text = "\n".join(self.itemLabels[drawid])
             w, h, lh = dc.GetFullMultiLineTextExtent(text)
             textExtent = (w, h)
-            textRect = Rect(0, 0, *textExtent).CenterIn(bb)
+            textRect = Rect(0, 0, *textExtent).CenterIn(Rect(*bb))
             r = map(int, bb)
             while not Rect(*r).ContainsRect(textRect) and size >= 8:
                 size -= 2
@@ -2408,7 +2409,7 @@ class PsMapBufferedWindow(wx.Window):
                 dc.SetFont(font)
                 pdc.SetFont(font)
                 textExtent = dc.GetTextExtent(text)
-                textRect = Rect(0, 0, *textExtent).CenterIn(bb)
+                textRect = Rect(0, 0, *textExtent).CenterIn(Rect(*bb))
             pdc.SetTextForeground(wx.Colour(100, 100, 100, 200))
             pdc.SetBackgroundMode(wx.TRANSPARENT)
             pdc.DrawLabel(text=text, rect=textRect)
@@ -2417,9 +2418,9 @@ class PsMapBufferedWindow(wx.Window):
             pdc.DrawCircle(x=bb[0] + bb[2] / 2, y=bb[1] + bb[3] / 2, radius=bb[2] / 2)
 
         elif pdctype == "line":
-            pdc.DrawLinePoint(lineCoords[0], lineCoords[1])
+            pdc.DrawLinePoint(*lineCoords[0], *lineCoords[1])
 
-        pdc.SetIdBounds(drawid, bb)
+        pdc.SetIdBounds(drawid, Rect(*bb))
         pdc.EndDrawing()
         self.Refresh()
 
@@ -2565,7 +2566,7 @@ class PsMapBufferedWindow(wx.Window):
 
         self.pdcPaper.SetPen(self.pen["margins"])
         self.pdcPaper.SetBrush(self.brush["margins"])
-        self.pdcPaper.DrawRectangle(x, y, w, h)
+        self.pdcPaper.DrawRectangle(int(x), int(y), int(w), int(h))
 
         self.pdcPaper.SetIdBounds(self.pageId, rect)
         self.pdcPaper.EndDrawing()
@@ -2582,7 +2583,7 @@ class PsMapBufferedWindow(wx.Window):
         iH = iH * self.currScale
         x = cW / 2 - iW / 2
         y = cH / 2 - iH / 2
-        imageRect = Rect(x, y, iW, iH)
+        imageRect = Rect(int(x), int(y), int(iW), int(iH))
 
         return imageRect
 
@@ -2716,8 +2717,8 @@ class PsMapBufferedWindow(wx.Window):
     def ScaleRect(self, rect, scale):
         """Scale rectangle"""
         return Rect(
-            rect.GetLeft() * scale,
-            rect.GetTop() * scale,
-            rect.GetSize()[0] * scale,
-            rect.GetSize()[1] * scale,
+            int(rect.GetLeft() * scale),
+            int(rect.GetTop() * scale),
+            int(rect.GetSize()[0] * scale),
+            int(rect.GetSize()[1] * scale),
         )