MouseDown Problems. Baffled. (Python)

Posted by Alca on Thu 29 Oct 2009 04:58 PM — 11 posts, 43,303 views.

#0
I'm toying around with hotspots, and I managed to get a button working just fine.

Then I decided I needed another button. Which also works.
Except for one thing.

I want my buttons to draw a different image on MouseDown, so it shows you're clicking on it. This worked just fine in my first version, but doesn't now.

Which is already weird, since my code hasn't changed.

However, it gets weirder.

When adding a world.Note to the function that handles the drawing of the 'clicked' image, it works. Splendidly. Deleting that world.Note reverses everything to its problematic state.

I'm baffled, as I have absolutely no idea what causes this.

Amended on Thu 29 Oct 2009 04:59 PM by Alca
Australia Forum Administrator #1
I'm no Python expert, but can you post the function in its working and not-working version (the part that handles the mousedown).

Isn't Python very spacing-conscious? Maybe by adding an extra line you changed the way it handled the function.

Also I would check the return code from the line that draws the image - if a drawing function fails it generally returns a non-zero error code.
#2
Adding an empty line doesn't solve the problem, unfortunately. Empty lines generally don't do much in Python, spaces do, and those are all fine.


This function doesn't work:


def Loot_MouseDown(flags, hotspot_id):
    Loot_ButtonClicked()
    return 0


This one does:


def Loot_MouseDown(flags, hotspot_id):
    world.Note("Check 1")
    Loot_ButtonClicked()
    return 0


This function is called as the hotspot "mousedown" handler, just so you know, though I don't see how that would change anything.

Loot_ButtonClicked() calls the following:


def Loot_ButtonClicked():
    world.WindowDrawImage(winid, "Loot1_clicked", 66, 1, 0, 0, 1, 0, 0, 0, 0)


It's definately not a drawing error. I don't even get an error, it just, you know, fails to work.

I'm going to try different names, maybe Python won't accept the current ones or something strange...

Edit:: my spacing seems to be off in this example, this is not the case in the actual code though.
Edit2:: added the code for Loot_ButtonClicked()
Amended on Thu 29 Oct 2009 10:20 PM by Nick Gammon
Australia Forum Administrator #3
Alca said:

Edit:: my spacing seems to be off in this example, this is not the case in the actual code though.


Template:codetag
To make your code more readable please use [code] tags as described here.


Is this code in a plugin? Hotspots only work in plugins.

Alca said:

It's definately not a drawing error. I don't even get an error, it just, you know, fails to work.


See:

Template:function=WindowDrawImage
WindowDrawImage

The documentation for the WindowDrawImage script function is available online. It is also in the MUSHclient help file.



That returns a non-zero code if it fails. You could test that code and display a message if it is not zero. That at least eliminates that possibility.

eg.


def Loot_ButtonClicked():
   iStatus = world.WindowDrawImage(winid, "Loot1_clicked", 66, 1, 0, 0, 1, 0, 0, 0, 0)
   if iStatus != 0:
    world.note ("Error code from WindowDrawImage: " + iStatus)


(or however you do it in Python).

However I can't really explain it. Maybe the Python experts here can.

Amended on Thu 29 Oct 2009 10:32 PM by Nick Gammon
#4
This code is entirely in a plugin. Error checking gives a zero, so no drawing error. Changing names didn't work either. For the moment, I'm stuck with adding an empty line via world.Note, but it's not aesthetically pleasing >.>

Next I'll try to work with one mousedown function with ifs for different hotspot_ids. Maybe that'll work.

Edit:: It didn't. However, I noticed that it does react to double-clicking. Checking my code now, maybe I'll find something. And if not, maybe I can code a solution now.

Edit2:: Bah. Stupid me. Somehow I managed to delete the WindowShow function that was supposed to be called. I still think it behaved weird, but at least now it works. Thanks for the help.
Amended on Fri 30 Oct 2009 01:59 PM by Alca
USA #5
Try adding a world.WindowShow("name") and a world.Repaint() to the function.

If WindowDrawImage follows with the other Window functions, you're actually manipulating a buffer and not the region of the screen itself. You'd need the WindowShow to "apply" the changes. After the changes are applied, they don't appear until the screen gets redrawn -- for example from a world.Note() or incoming text from the mud. Repaint should force an update.
Australia Forum Administrator #6
WindowShow should be enough. The repaint happens quite quickly, next time through the main event loop (unless there are other higher-priority events, like mouseclicks there). Getting into the habit of putting Repaint everywhere will slow the program down for no noticeable improvement.


Alca said:

I still think it behaved weird, but at least now it works.


It is quite valid to draw to offscreen windows, so automatically repainting the onscreen ones just because you draw an image would add an overhead that might not be justified.

BTW, had you simply covered the MUSHclient window up (eg. with a notepad) and uncovered it, that should have forced a repaint, making it more obvious that the problem was not some bizarre script issue, but that the window was not being redrawn.
Australia Forum Administrator #7
See this comment under WindowShow:

Quote:

Calling WindowShow forces a window refresh, so the screen will be updated with the new miniwindow (or absence, as the case may be).

If you have changed the miniwindow, you may not want to call WindowShow (in case they currently want it hidden). In this case you can call Redraw () instead, to cause the main output window to be redrawn, without changing the status of any miniwindows.

Australia Forum Administrator #8
I have amended the help file for the next version to make it more obvious that you need to call Redraw after changing a miniwindow's contents.
Australia Forum Administrator #9
Those documentation changes have now been applied to the online documentation here. For example:

Template:function=WindowDrawImage
WindowDrawImage

The documentation for the WindowDrawImage script function is available online. It is also in the MUSHclient help file.

#10
WindowShow() works splendidly. It was really a dumb error on my part. Because both double-clicking and adding a world.Note seemed to force the window to be redrawn, I just thought there was way more behind this than there actually is.

Thanks for all the help, guys. You must have way too much patience...