Game Development Community

GUI Question

by David Wilson · in Torque Game Engine · 05/10/2004 (3:13 pm) · 17 replies

I'm wondering if there's an easy way to make one part of the screen change it's picture when you put your mouse over a button on another part of the screen?

For example, for my main menu gui, I have buttons underneath a video screen. I would like to swap pictures inside the screen as the use puts the mouse over one of the buttons.

I thought I was being slick by making large transparent buttons where "button_n" did not contain the image but "button_h" did, this doesn't work because the extents must be so big that all the button overlap.

Anyone have any ideas?

#1
05/10/2004 (3:43 pm)
Take a look at the demo app (not starter.fps but the demo directory) and how they did the buttons. They do a mouse over event, highlighting the button when you hover. I don't have the code in front of me so not sure if it's accomplished with multiple images but might be something to look at.
#2
05/10/2004 (4:01 pm)
Thanks Bill, that one is in fact using multiple images, you are right. "button_n" and "button_h" for example, I assume the 'n' is for normal and the 'h' is for "hover".

It's not what I want to do though. I'm still digging through forum posts and resources right now to see if it's already been done.
#3
05/11/2004 (6:07 am)
I stopped looking after 27 pages of threads with "GUI" in the title. If someone has done it, it should have shown up before then. (I think?)

So last night I started digging into the code a little bit. Not being a good prgrammer, this could take awhile - but it's fun to see the results.

I've added a "_p" (for picture) along with the "_n, _h, _d and _i."

I put a picture in the proper place, with the proper name (_p), and when you hold the mouse over a button, it does render the corresponding picture.

The only issue left is to make the bounds and position change dynamically, so the picture can be placed wherever you need it. It currently shrinks and renders the picture within the "mBounds.point" and "mBounds.extent" of the original button.

I'm guessing I need to store the original "mBounds" in the case of a "HiLight", swap them to the correct numbers for the picture, and return them to what they were after that case is done.

Also, I think in order to do this, I'll have to add a "PicturePosition" and "PictureBounds" to the GuiBitmapButtonCtrl.

This is where I'm at if anyones interested. Also if you have any pointers for me, or comments I'm happy to hear them.
#4
05/11/2004 (6:11 am)
I Think you're taking the long way around on this one :)

In theory all you really need to do is check for a mouseover event on one spot, then when that occurs just set the image value on another spot.

If i'm understanding what you want to do. Could just make GuiBitmapCtrl pass mouseover events to the scrpit (It might already). The rest could already be scripted I think.
#5
05/11/2004 (6:37 am)
Mouseover? Isn't that how it changes states already? I'm just trying to hook into that. I did search for "mouseover" and "mouse over", in forums and resources, and I came up with this which may help me.

www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=4971
#6
05/11/2004 (6:41 am)
Even that is more complicated then neccesary.

Really all you need is something like this:

function MyControl:onMouseOver(%this, %x, %y)
{
     MyOtherControl.setImage("newImage.bmp");
}

Give me about a half hour and i'll check the gui controls to see what needs to be added. It should be trivial.
#7
05/11/2004 (6:52 am)
I saw "mMouseOver" in the code near where I was hacking away, but I didn't think to implement it the way you are.

I *think* what you are saying is to make the "video screen" a seperate control altogether, then have the mMouseOver change it's image?

Hmmmmmm... Sounds better then what I was doing.
#8
05/11/2004 (7:10 am)
Yes. You want to keep them seperate. Otherwise its hacky :)

The only change you needed was to allow you to react to mouse over events in script. The rest was already doable. So here you go. Enjoy.

In engine/gui/guiControl.cc

Find the functions:
void GuiControl::onMouseEnter(const GuiEvent &)
and
void GuiControl::onMouseLeave(const GuiEvent &)

And replace them both with the following code:
void GuiControl::onMouseEnter(const GuiEvent &event)
{
   if (!mAwake)
      return;

   Con::executef(this, 1, "onMouseEnter");
}

void GuiControl::onMouseLeave(const GuiEvent &event)
{
   if (!mAwake)
      return;

   Con::executef(this, 1, "onMouseLeave");
}

Compile.

Next add two GuiBitmap controls to your menu. One for the Video screen and oen for the control at the bottom. You can of course add more than one control on the bottom but i'm doing just one as an example. I'm going to call the video screen "myBitmapVideo" and the control underneath it "myBitmapController". Add those controls then in script do this:

function myBitmapController::onMouseEnter(%this)
{
     echo("on mouse enter"); // for debug reasons
     myBitmapVideo.setBitmap("path/to/mynewbitmap.jpg");
}
function myBitmapController::onMouseLeave(%this)
{
     // You can use this event to change the image again if needed
     // when the mouse leaves the control area.
}
#9
05/11/2004 (7:26 am)
Digesting...
#10
05/11/2004 (8:06 am)
OK, I understand it now and I have it half-way working. One more question...

In order to make the new "myBitmapController" act as a button, I'll have to follow along what you did here and add an event to handle "onMouseDown" in both the guiControl.cc as well as the script. Correct?
#11
05/11/2004 (8:21 am)
Ahh you want it to be an actual button. I didin't realize that. You *should* be able to just make it a GuiBitmapButtonCtrl or GuiButtonCtrl without any further changes and it shoudl work. That was my reasoning behind making the change sin the base control. The MouseLEave and MouseEnter events should work with ALL control types.
#12
05/11/2004 (8:53 am)
Yeah, I'll mess around with the bitmapbuttonctrl.

Yesterday I downloaded the evaluation version of Paint Shop Pro, and spent a good 12 hours going through tutorials etc... I think I'm going to buy it, I like it so far.

Anyways here are 2 WIP shots of what you helped me with:

gallery.cybertarp.com/albums/userpics/17258/Interface_up.jpg

and

gallery.cybertarp.com/albums/userpics/17258/Interface_down.jpg

I need to make nicer buttons etc...


I see you are looking for a 2D concept artist. That's way out of my league, I'm not much of an artist at all but if I can help you in any way with interfaces or whatever, please let me know.

Thanks
David

*edit*

The text doesn't look that bad in torque, thats the jpeg compression I suppose.
#13
05/11/2004 (9:16 am)
Just a follow up:

I had to add the: Con::executef (this, 1,onMouseEnter");

and the: Con::executef (this, 1, "onMouseLeave");

to the GuiButtonBaseCtrl.cc to get it to work with GuiButtonBitmpCtrl's
#14
05/11/2004 (9:32 am)
Odd.

That's a pretty neat looking UI for something you just whipped up :)
#15
05/12/2004 (9:36 pm)
I am confused by this thread. I have a button I made with GuiButtonBitmapCtrl. I have a bitmap for _n (normal) that looks like lava. For _h (hover) I have one that is that same with the brightness increased. For _d (depressed) it is the same bitmap as the first except I bump mapped it to give more depth to it. Finally I have one that I did a clothify on it to make it look deselectible for the _i. When I place my mouse over the button it changes to the the _h bitmap. When I depress it changes it to the _d bitmap. When I use another button to toggle the active attribute (setActive) it shows the _i bitmap.

How is what you are doing different than the built in hover using _h? It seems to me that you did not need to write any scripting at all. Are you cycling through a bunch of bitmaps for an animation? That would definitely be cool, but all I see are two bitmaps, with one changing when you hover.

While writing this I think I answered my own question. You are using the mouseover of the center area to change the bitmap outside the button extents area. Okay, that makes sense. You know you could use the avi widget and look for a mouse down to act as a button. The mouseover event could trigger the animation. This could make for a cool rotation of the text into view. A mouseonexit (?) could cause it to rotate out of view and fade. Lots of cool possibilities.

Thanks,
Frank
#16
08/29/2005 (1:38 pm)
Thanks, I was trying to get buttons to work onMouseEnter and onMouseLeave.
I also had to add the:
Con::executef (this, 1,onMouseEnter");
and the:
Con::executef (this, 1, "onMouseLeave");
to the GuiButtonBaseCtrl.cc to get it to work with myButtons.

you might also try adding this somewhere and watch what the console prints:
function GuiBitmapButtonCtrl::onMouseEnter(%this){
  echo("onMouseEnter %this = " @ %this);
  echo("%this = " @ %this.getName());
}
function GuiBitmapButtonCtrl::onMouseLeave(%this){
  echo("onMouseLeave %this = " @ %this);
  echo("%this = " @ %this.getName());
}
#17
12/31/2007 (3:06 pm)
Just thought I'd mention, because it gave me a fair amount of trouble, that the naming convention that worked for me was like:

test.png_h.png

In the console I was getting messages like this when I just used, say, "test_h.png":

Could not locate texture: singularity/client/ui/test.png_h

I would just have "test" as the bitmap value in the gui script code. Strange. But it's working now so who cares? :-)