Rollover certain region in frame changing cursor question

Hey wxers,

What would be the most performance effective method of implementing the
mouse cursor changing when entering a certain x/y/width/height region?

I'm making a drawing application, and would like to change the cursor to
a hand when the user mouse-overs certain shapes when they are using the
Select tool. Every drawn shape has a polymorphic hit_test(x, y) method
but I'm guessing calling this method all the time when the user is just
moving the mouse (with no button pressed) could be too inefficient?

For example, a Text object:

    def find_extent(self):
        """Finds the width/height of the object's text"""
        dc = wx.WindowDC(self.board.gui)
        x = dc.GetMultiLineTextExtent(self.text, self.font)
        self.extent = x[0], x[1]

    def hit_test(self, x, y):
        width = self.x + self.extent[0]
        height = self.y + self.extent[1]

        if x > self.x and x < width and y > self.y and y < height:
            return True
        return False

or a Circle:

    def hit_test(self, x, y):
        val = ((x - self.x) * (x - self.x)) + ((y - self.y) * (y - self.y))
        if val <= (self.radius * self.radius) + self.thickness:
            return True
        return False

currently I'm responding to mouse down/motion/up events only if the
mouse has been dragging, which is why I foresee possibly doing the check
every mouse motion event is just too much. It would only occur if the
user has the Select tool selected, which would mean a lot of isinstance
checks.

Even nicer would be to change the cursor when the mouse is positioned at
exactly the edge of the shape (change to the 'drag and resize' icons) -
depending on whether it's a very corner or just edge of the line then
diagonal/horizontal/vertical resizers will be shown

I don't think the overhead would be excessive. Turn on the task
monitor
while dragging and see what the CPU load is. It depends on how many
objects we're talking about: 10? 1000? You could cache the last
object
hit and see if the mouse is still in it. This will sometimes save you
iterating through the list. You might also think about keeping the
objects
sorted by extent so you can pre-filter the hit tests.

HTH, Phil

···

On Jul 7, 9:21 am, Steven Sproat <spro...@gmail.com> wrote:

Hey wxers,

What would be the most performance effective method of implementing the
mouse cursor changing when entering a certain x/y/width/height region?

I'm making a drawing application, and would like to change the cursor to
a hand when the user mouse-overs certain shapes when they are using the
Select tool. Every drawn shape has a polymorphic hit_test(x, y) method
but I'm guessing calling this method all the time when the user is just
moving the mouse (with no button pressed) could be too inefficient?

For example, a Text object:

def find\_extent\(self\):
    &quot;&quot;&quot;Finds the width/height of the object&#39;s text&quot;&quot;&quot;
    dc = wx\.WindowDC\(self\.board\.gui\)
    x = dc\.GetMultiLineTextExtent\(self\.text, self\.font\)
    self\.extent = x\[0\], x\[1\]

def hit\_test\(self, x, y\):
    width = self\.x \+ self\.extent\[0\]
    height = self\.y \+ self\.extent\[1\]

    if x &gt; self\.x and x &lt; width and y &gt; self\.y and y &lt; height:
        return True
    return False

or a Circle:

def hit\_test\(self, x, y\):
    val = \(\(x \- self\.x\) \* \(x \- self\.x\)\) \+ \(\(y \- self\.y\) \* \(y \- self\.y\)\)
    if val &lt;= \(self\.radius \* self\.radius\) \+ self\.thickness:
        return True
    return False

currently I'm responding to mouse down/motion/up events only if the
mouse has been dragging, which is why I foresee possibly doing the check
every mouse motion event is just too much. It would only occur if the
user has the Select tool selected, which would mean a lot of isinstance
checks.

Even nicer would be to change the cursor when the mouse is positioned at
exactly the edge of the shape (change to the 'drag and resize' icons) -
depending on whether it's a very corner or just edge of the line then
diagonal/horizontal/vertical resizers will be shown