Game Development Community

MouseEnter for a t2dImageMapDatablock? Is it possible?

by Dave Calabrese · in Torque Game Builder · 11/03/2006 (1:30 pm) · 14 replies

Reading through various online forum posts, it seems like it should be possible to have a 'onMouseEnter' event for a t2dImageMapDatablock object. However, whenever I do this, I can't seem to get a callback to occur. I have tried a few different methods:


1.) Name my object 'testBox' then use the function:
function testBox::onMouseEnter( %this, %mod, %worldPos, %mouseClicks )
{
error(" this = " @ %this);
error(" Mod = " @ %mod);
error("Mouse Over Detected! Hull Breach!");
}
Results: Nothing is ever posted to the console.


2.) Use the sceneWindow2D to list everything I'm over:
function sceneWindow2D::onMouseEnter( %this, %mod, %worldPos, %mouseClicks )
{
error(" this = " @ %this);
error(" Mod = " @ %mod);
error("Mouse Over Detected! Hull Breach!");
}
Results: The only object it over posts to the console (under the 'this' echo) is the sceneWindow2D itself.


3.) Try and apply this function to the datablock itself. So if my datablock is named myImageSprite...
function myImageSprite::onMouseEnter( %this, %mod, %worldPos, %mouseClicks )
{
error(" this = " @ %this);
error(" Mod = " @ %mod);
error("Mouse Over Detected! Hull Breach!");
}
Results: Nothing is ever posted to the console.


What other means are there to achieve this? In laymans terms to explain what I am doing, pretend I am trying to make a button with a mouseover event without using the GUI. What am I missing to make that happen?

#1
11/03/2006 (1:57 pm)
You need to do a getIsPointInObject call on the object you want to check. Your best bet would be to use onMouseMove, not onMouseEnter. You still need to do it off the sceneWindow2D object.

Example:
function sceneWindow2D::onMouseMove(%this, %modifier, %worldPosition, %clicks)
   {
      if(testBox.getIsPointInObject(getWord(%worldPosition, 0), getWord(%worldPosition, 1)))
         {
            error("Mouse Over Detected! Hull Breach!");
         }
    }
#2
11/03/2006 (2:45 pm)
@Dave: It all looks good, but you're probably missing one thing:

//call this on the object to make sure it will get events

%this.setUseMouseEvents(true);
   
//call this somewhere or else it won't work 
// make sure the scene window is set to send mouse events to objects

if(!sceneWindow2D.getUseObjectMouseEvents()) 
   sceneWindow2D.setUseObjectMouseEvents(true);

That should do it :)
#3
11/03/2006 (2:53 pm)
@Tom: I tried that, but it didn't seem to work. The code looked like this:

if(!sceneWindow2D.getUseObjectMouseEvents()) 
   sceneWindow2D.setUseObjectMouseEvents(true);

testButton.setUseMouseEvents(true);

function testButton::onMouseEnter( %this, %mod, %worldPos, %mouseClicks )
{
	error(" this = " @ %this);
	error(" Mod = " @ %mod);	
	error("Mouse Over Detected! Hull Breach!");
}

No luck there. =/


@Eric: This solution worked! Thank you!
#4
11/03/2006 (3:17 pm)
SetUseMouseEvents works on an actual object, not the namespace, so for it to work, you'd have to put that line in a function in the namespace, like testButton::onLevelLoaded.
#5
11/03/2006 (3:24 pm)
@Tom: Trying some modified code, but it still isn't working:

if(!sceneWindow2D.getUseObjectMouseEvents()) 
   sceneWindow2D.setUseObjectMouseEvents(true);

function testButton::onLevelLoaded( %this )
{
	testButton.setUseMouseEvents(true);
}

function testButton::onMouseEnter( %this, %mod, %worldPos, %mouseClicks )
{
	error(" this = " @ %this);
	error(" Mod = " @ %mod);	
	error("Mouse Over Detected! Hull Breach!");
}

(I'd honestly rather do something like this as it's a much more elegant solution for having multiple objects to deal with...)
#6
11/03/2006 (3:32 pm)
You're still calling the method off of the namespace, not the object. Try this:

if(!sceneWindow2D.getUseObjectMouseEvents()) 
   sceneWindow2D.setUseObjectMouseEvents(true);

function testButton::onLevelLoaded( %this )
{
	%this.setUseMouseEvents(true);
}

function testButton::onMouseEnter( %this, %mod, %worldPos, %mouseClicks )
{
	error(" this = " @ %this);
	error(" Mod = " @ %mod);	
	error("Mouse Over Detected! Hull Breach!");
}

Make sure that your onLevelLoaded method is getting called... If it isn't, then you need to make sure you are setting the class on the testButton object correctly...
#7
11/03/2006 (3:45 pm)
Okay, so I'm thinking there has got to be something else going on here. That code still didn't work, and I added an error statement to the 'onLevelLoaded' method to make sure it was getting called. My code now looks like this:

if(!sceneWindow2D.getUseObjectMouseEvents()) 
   sceneWindow2D.setUseObjectMouseEvents(true);

function testButton::onLevelLoaded( %this )
{
	error("@@@ Loaded!");
	%this.setUseMouseEvents(true);
}

function testButton::onMouseEnter( %this, %mod, %worldPos, %mouseClicks )
{
	error(" this = " @ %this);
	error(" Mod = " @ %mod);	
	error("Mouse Over Detected! Hull Breach!");
}

What else could cause this to fail? I've got the object on a layer higher than everything else, the 'Use Mouse Events' checkbox is clicked in the editor, it's set to receive any kinds of collision including the 'callback' checkmark...
#8
11/03/2006 (3:55 pm)
OK, got your issue... I don't know if you are a pro user or not, but the issue is that the onMouseEnter event is not forwarded to objects, only the window...

A pretty easy code change if you are a pro user... otherwise you may be stuck doing it the way I outlined in my first post...
#9
11/03/2006 (3:58 pm)
Oh yeah...forgot that it's not there...
#10
11/03/2006 (4:00 pm)
I own the engine code if that's what you mean, so I could probably search through and change it. C++ isn't my strong point, but if it's an easy fix I may be able to hunt it down.

Thanks guys!
#11
11/03/2006 (4:02 pm)
I'll save you the trouble... in t2dSceneWindow.cc find:

//-----------------------------------------------------------------------------
// Mouse Event Handler.
// NOTE:-   This isn't handled by the event-dispatcher as it's only really
//          relevant to the window-events, not potential object-events.
//-----------------------------------------------------------------------------
void t2dSceneWindow::onMouseEnter( const GuiEvent& event )
{
    // Send Windows Mouse Event.
    sendWindowMouseEvent("onMouseEnter", event);
}


//-----------------------------------------------------------------------------
// Mouse Event Handler.
// NOTE:-   This isn't handled by the event-dispatcher as it's only really
//          relevant to the window-events, not potential object-events.
//-----------------------------------------------------------------------------
void t2dSceneWindow::onMouseLeave( const GuiEvent& event )
{
    // Send Windows Mouse Event.
    sendWindowMouseEvent("onMouseLeave", event);
}

Change to look like:
//-----------------------------------------------------------------------------
// Mouse Event Handler.
// NOTE:-   This isn't handled by the event-dispatcher as it's only really
//          relevant to the window-events, not potential object-events.
//-----------------------------------------------------------------------------
void t2dSceneWindow::onMouseEnter( const GuiEvent& event )
{
    // Send Windows Mouse Event.
    dispatchMouseEvent("onMouseEnter", event);
}


//-----------------------------------------------------------------------------
// Mouse Event Handler.
// NOTE:-   This isn't handled by the event-dispatcher as it's only really
//          relevant to the window-events, not potential object-events.
//-----------------------------------------------------------------------------
void t2dSceneWindow::onMouseLeave( const GuiEvent& event )
{
    // Send Windows Mouse Event.
    dispatchMouseEvent("onMouseLeave", event);
}

That should work for you...
#12
11/03/2006 (4:16 pm)
Uggh... that, unfortunately, still did not work... compiled the engine with the above change, and still nothing happened when I mouse-overed the object. =/

I think I'm just going to have to find another way to do this, probably using GUI code...

Thanks for all your help, guys!
#13
11/03/2006 (4:30 pm)
Okay, I got it to work, using the original method mentioned, and was able to make it a little more (I hope) elegant.

First, I'm using this function:

function sceneWindow2D::onMouseMove(%this, %modifier, %worldPosition, %clicks)
{
	%objectCount = $currentScreenGUI.mouseObjects.getCount();
	for(%obj = 1; %obj <= %objectCount; %obj++)
	{
	  %thisObject = $currentScreenGUI.mouseObjects.getObject( (%obj) - 1);
	
      if((%thisObject).getIsPointInObject(getWord(%worldPosition, 0), getWord(%worldPosition, 1)))
         {
			if( !$MouseOverObject )
			{
            	error("Mouse Over Detected! Hull Breach!");
				$MouseOverObject = true;
			}
         }
	  else if ($MouseOverObject)
	   {
		 $MouseOverObject = false;
		 error("@@@ Leaving Object");
	   }
	  else
	    return;
	}
}

Then, at the start of each scene, I run code that basically does this:
$currentScreenGui = new scriptObject();
   $currentScreenGUI.mouseObjects = new simSet();
   $currentScreenGUI.mouseObjects.add(testButton);

Then it's able to handle it on a per-scene basis instead of game-wide, and does exactly what I want it to do.
#14
11/03/2006 (5:06 pm)
Sounds good... I'd like to have that callback functionality for some other things I'm doing though, so I'll take a much closer look at it and I'm sure I can get it working. I'll be sure and let you know once I do...