Window Z-ordering

Stardragon

07-04-2009 11:20:18

Hey there. It's been a few days since I last posted, which can only be a good thing, right? :D Anyway, I thought I'd drop by and throw in a screenshot of the project, complete with QuickGUI::GUI goodness. Mmm, sticky, chewy, GUI goodness. Hee.

[attachment=0]UI_test_1a.JPG[/attachment]
I do have a question, though. (Groan.) Is there a way to change the Z-ordering of Windows created within a Sheet, without changing the order in which they're created in the code? I've been making some changes lately and added a couple of new Windows, and one of the changes is moving the fader artefact from the Sheet itself to a Window - mostly because when you fade out the sheet you lose the mouse pointer as well. But as things are at the moment the fader Window is in front of the other Windows, and when it fades out, well, so does the mouse pointer (because it's behind, therefore hidden) and bang goes my nice GUI.

Any ideas?... :?

kungfoomasta

07-04-2009 18:37:54

Thanks for the screenshot! I really need to look into the vertical centering, I will review your email and use your materials this weekend, I'll make it a priority. (The text should really be vertically centered there, so I'll investigate)

You said the mouse disappears when the Sheet is faded? The Mouse is drawn on top of all QuickGUI elements, it shouldn't be possible for it to be covered, or affected, its a separate quad drawn above everything. How are you fading out the Sheet?

Sheet::bringToFront(Window* w);

No worries about asking questions, I want QuickGUI to have high usability. :)

Stardragon

07-04-2009 19:00:29

Ah... I completely missed that plainly visible and rather comprehensibly named function there. :oops: :)

I was fading out the Sheet with calls to Sheet->setRelativeOpacity(). My assumption was that since the mouse cursor was a child Widget it was getting faded out as something to do with the inheritance of opacity.

By the way, is there a Sheet->sendToBack() function? ;)

kungfoomasta

07-04-2009 19:09:18

Good call! I think I will add some convenience functions for users:

Sheet::sendToBack(Window* w);
Window::bringToFrom();
Window::sendToBack();


And just to clarify, the MouseCursor is not a widget, and not a part of any sheet. Even if you have no active Sheet set, the mouse will still be drawn, and you can move it about via injections.

Stardragon

07-04-2009 19:35:31

Must have been something I was doing wrong, then... My my, who'd've thought it?... :oops:

kungfoomasta

07-04-2009 20:28:27

Oh yah, I forgot to mention, the background level on that screenshot reminds me of an old NES game I played called "Snake Rattle n Roll". Pretty fun game!

Stardragon

08-04-2009 17:42:31

Hope you don't mind --- I sent you an email with a short clip of what's happening with the menu system & the game, and a copy of the code I'm using to drive the UI. I figured you might have a better idea of what's (not) going on if you can see stuff.

kungfoomasta

08-04-2009 18:51:29

No problem! I saw the video, even though there are some problems, I'm impressed at the work you've done! :D

After viewing the video a few times, I realized you're right about the mouse cursor, a simple bug for me to fix. Basically Each widget sets the opacity before it performs its drawing operations. The mouse doesn't explicitly set any opacity before drawing, which means the mouse will inherit whatever opacity the brush is configured with. :oops:

I also see a part where all the UI disappears underneath another image, is this intended? I don't know what you're trying to accomplish, the only issue I see is that the mouse should be visible at all times. Although I'll add some APIs so the mouse can have its opacity configurable as well.

Stardragon

08-04-2009 19:02:36

Thank you for the compliment! :)

Glad I wasn't totally apricots and mangoes about the mouse cursor bug. (Well, it makes a change from bananas.) Glad it's an easy fix. Let me know when it's done and I'll fire up the old tortoise again.

... gah. What a mental image. Tortoise on JATOs... I could have done without that. AAAAAANYWAY...

Which part is it where the UI 'disappears'?

BTW, did you see also the problem with the button states I've mentioned before? I haven't honestly had chance to try it in PlayPen and I know you couldn't replicate the problem yourself, but it's visible in that video clip.

kungfoomasta

08-04-2009 19:13:28

Now that you mention it, I see that also. :? I'm trying to look at your code, but I'm not familiar with how the "start_level" variable works:


void UI::main_new_game(const QuickGUI::EventArgs &args)
{
start_level=1;
}


I see a loop that continues while start_level is 0, but where is the action when it becomes 1 for example?

Also, can you paste the code you have for the function:

GUIManager::setActiveSheet

[edit]
Which part is it where the UI 'disappears'?

Between 15-19 seconds in the clip, I'm wondering if that is intended or not. (Its a brown image that covers entire screen for a few seconds, I don't see anything else)
[/edit]

[edit2]
What is JATO? Jet Assisted Take Off? :lol:
[/edit2]

Stardragon

08-04-2009 20:26:51

Replies in (some sort of) order :)

1. The start_level variable is a flag to the loop in UI::main_menu() indicating what should happen if it is non-zero. (I said it used some twisted logic. My brain isn't working straight lately.) If start_level>0, the game begins. If it is -1, the player has gone to the Select World screen and then clicked "Return to Main Menu". If it is -2, the player has elected to leave the game entirely. If you check the event handling code, which is commented, you should be able to track how it works.

2. The code for GUIManager::setActiveSheet() is part of my version of QuickGUI, 9.0.3b.


void GUIManager::setActiveSheet(Sheet* s)
{
mActiveSheet = s;
mWidgetUnderMouseCursor = mActiveSheet;
mLastClickedWidget = NULL;

if(mActiveSheet != NULL)
{
mActiveSheet->notifyViewport(&mViewportWidth,&mViewportHeight);

mActiveSheet->_setGUIManager(this);
}
}


3. Oh, ah. I see. What's supposed to happen there is that the screen should fade out to black as before, before the main menu reappears. I need to fix that. (What you can actually see is the game landscape for level 1, from the player's first-person POV.)

4. JATO = Jet Assisted Take-Off, yeah. :twisted:

kungfoomasta

08-04-2009 20:42:37

Here is the latest version of that function you posted:


void GUIManager::setActiveSheet(Sheet* s)
{
if(mActiveSheet != NULL)
{
if(mWidgetUnderMouseCursor != NULL)
{
// Create MouseEventArgs, for use with any fired events
MouseEventArgs args(mWidgetUnderMouseCursor);
args.position = mMouseCursor->getPosition();
args.buttonMask = mButtonMask;
args.keyModifiers = mKeyModifiers;

mWidgetUnderMouseCursor->fireWidgetEvent(WIDGET_EVENT_MOUSE_LEAVE,args);
}
}

mActiveSheet = s;
mWidgetUnderMouseCursor = mActiveSheet;
mLastClickedWidget = NULL;

if(mActiveSheet != NULL)
{
mActiveSheet->notifyViewport(&mViewportWidth,&mViewportHeight);

mActiveSheet->_setGUIManager(this);

// In the case where a sheet was unloaded, and later reloaded, make sure the Sheet is drawn correctly.
// For example, prevent the scenario where a particular button was in the "Over" state when unloaded, but on
// loading, should not be in the "Over" state because the cursor is not over the button.
injectMouseMove(0,0);
}
}


Try the latest zip and see if you get these problems. Although it was made clear to me that I made a small typo in one of the include statements, the details are in the release thread. :mrgreen:

[edit]
My comment isn't entirely accurate, the reason I injectMouseMove(0,0) is for the scenario where you load a Sheet and the mouse cursor is under a button, for example. We want the button to be in an "over" state in thise case.
[/edit]

Stardragon

08-04-2009 21:20:32

I've tried the 9.04 build and it crashed... see the thread. :?

Is it worth having some code somewhere that iterates through all Buttons, Labels, anything at all, and sets them to the Neutral state?... or, even better, having a (Widget*)last_triggered variable, so that when a window becomes active you can reset that Widget to a neutral state?

The problem seems to me to be that, after the event is triggered and the active Window is switched, QuickGUI completely forgets about that Window - as is quite correct, of course... but the upshot is that the Widget remains in the MouseOver state.

Stardragon

10-04-2009 21:56:06

Have you managed to have a look at the mouse draw code, at all?

I think it would still be good to be able to turn the mouse pointer on and off, set its transparency, etc... but it should only affect the pointer, of course... although the idea of having child objects hanging off the mouse is making my head spin somewhat :lol:

kungfoomasta

10-04-2009 22:17:19

oops, sorry! I did indeed fix this a while back, and added support so you can set the mouse cursor's opacity/transparency individually. Its in SVN.

Did the last zip I uploaded fix your issue witht he button stuck in the 'over' state? (it should)

Stardragon

11-04-2009 00:19:47

Yes, that seems to have been fixed now.

Is the SVN release in the zip, or should I download it all again?... I'm confused. I confuse easily :lol:

kungfoomasta

11-04-2009 00:57:35

the zip should have fixed the button issue, but the svn contains the fix for the mouse cursor transparency. The svn is the latest, obviously. You'd have to grab it and rebuild it all if you want the fix. :)

Stardragon

12-04-2009 01:56:17

I've downloaded the SVN version, and the mouse still fades in and out when I fade the windows. :( It seems to follow the transparency of whichever Window is at the front when I start the fade. :(

Sorry. :(

kungfoomasta

13-04-2009 08:01:56

ack! Somewhere along the way the code for the mouse cursor transparency got removed.. :? Must have been some weird issue when copying code from my work machine, or laptop, and committing on my tower.

Its committed now, and I've re-tested it to make sure the problem is fixed:

MouseCursor::get/setOpacity. Valid values: [0.0,1.0]

Sorry for the inconvenience! (don't hesitate to keep posting if the issue isn't fixed, same with everything else. :) )

Stardragon

13-04-2009 15:09:50

Thanks for the fix! :) And don't fret, any bugs I find, you'll be the first to know :D

Stardragon

14-04-2009 18:34:30

Here's a question: is it possible to set the background colour of an object just by passing in an RGBA value, or has there always got to be an image backdrop?

So, for example, imagine I had a Panel object on the screen which I wanted to represent a threat state, changing from green through amber to red. Can I just call Panel->setBackgroundColor(r, g, b), or do I need to set background skins?

EDIT (afterthought): Have you had any success on why the text isn't centering correctly?

kungfoomasta

14-04-2009 19:42:24

I think I can add in an API to set a Widget's color. The transparency code already does this somewhat, basically I'm setting the color to white and changing the alpha channel based on opacity. What would sound like an intuitive API for this feature?

Off the top of my head:
Widget::setColor(float r, float b, float g);
Widget::setDrawColor(float r, float b, float g);

Notice I don't include alpha channel, this is already covered in other APIs

Regarding the text, I haven't gotten to it, like I thought I would. :( I haven't forgotten about it, I will get to it, hopefully soon.

Stardragon

14-04-2009 19:59:35

Widget::setBaseColor(float r, float g, float b) ?...

I'm also curious as to why you set the backdrop to white before you change the alpha. If there's a base colour (which could default to white, certainly) then you won't want to be fiddling around with that when the transparency starts to change.

And re: text, no problems. :) I just thought I'd ask. :)

kungfoomasta

15-04-2009 06:23:35

ok, so I looked into it, and here is a screenshot:



And the corresponding code:


Root::getSingleton().setDefaultFontName("micross.20");

// Create Sheet
SheetDesc* sd = DescManager::getSingleton().getDefaultSheetDesc();
sd->widget_dimensions.size = Size(800,600);
mSheetFromFile = new Sheet(sd);
mGUIManager->setActiveSheet(mSheetFromFile);

Button* b = mSheetFromFile->createButton("Main Menu",Rect(50,50,250,50));
b->setTransparencyPicking(false);
b->setSkinType("sentinel");

b = mSheetFromFile->createButton("Main Menu",Rect(50,150,250,50));
b->setTransparencyPicking(false);
b->setSkinType("sentinel");
b->setFont("dalek.12");

b = mSheetFromFile->createButton("Main Menu",Rect(50,250,250,50));
b->setTransparencyPicking(false);
b->setSkinType("sentinel");
b->setFont("dalek.18");

b = mSheetFromFile->createButton("Main Menu",Rect(50,350,250,50));
b->setTransparencyPicking(false);
b->setSkinType("sentinel");
b->setFont("dalek.24");

b = mSheetFromFile->createButton("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890",Rect(50,450,700,50));
b->setTransparencyPicking(false);
b->setSkinType("sentinel");
b->setFont("dalek.18");

Text::saveFontTextureToFile("dalek.36","dalek.26.png");


As you can see, the default font appears to be centered differently than the dalek font. I'm not sure what the exact differences are, but one thing I noticed is that the lowercase letters do not have the same position vertically. That is, 'a', and 'A', do not sit on the same line.

The last line of code took the image generated by Ogre and saved it out to file:
http://stormsonggames.com/downloads/images/OgreForum/dalek.26.png

You'll most likely need an image editting program to view the font, the letters are white, on a transparent background. (hard to see)

So in short... I think the centering is some kind of issue with the font. I know you probably don't want to hear that.. but QuickGUI assumes all glyphs to be vertically centered, throughout all glyphs in the font. Here is a better example:

jjjjj

All of the j's are sitting on the same line. I don't know the technical term for it, I'm short on time tonight, and my brain fell asleep hours ago. :lol:

[edit]

Even better, simply open dalek.ttf and compare it against micross.ttf and you will see the difference. The dalek font is really crazy with its vertical positioning...

[/edit]

kungfoomasta

17-04-2009 18:50:42

Sorry for lateness, I've added in the feature you requested. (Although I haven't tested it.. :oops: )


/**
* Sets the color used to draw SkinElements of this widget.
* NOTE: The alpha channel is not used, it is affected only by the opacity attribute.
*/
void setBaseColor(Ogre::ColourValue cv);

/**
* Returns the color used to draw SkinElements of this widget.
* NOTE: The alpha channel is not used, it is affected only by the opacity attribute.
*/
Ogre::ColourValue getBaseColor();


Let me know if there are any problems or unexpected behavior

Stardragon

22-04-2009 00:46:04

Ooh. Niftiness! Thank you :)

Only problem is, those two functions aren't showing up in Intellisense... :? I've purged the IS database on my project, and I'm using the latest SVN of QuickGUI, but no joy. :(

Sorry... :(

kungfoomasta

22-04-2009 06:20:38

Did you do this, exactly?

1. Clean Project(s)
2. Close Visual Studio
3. Delete .ncb file
4. Open Visual Studio Solution
5. Rebuild Project(s)
6. Allow some additional time for intellisense to be updated

I've been programming with a half way working intellisense for the longest time. Just call the function anyway and hit compile. Let the force guide you. :wink:

Stardragon

22-04-2009 10:15:03

Your overconfidence is your weakness... ;) :P

(Ancient weapons and hokey religions are no replacement for a good blaster at your side, kid. :P )

I used the Force, and this is what happened:


1>------ Build started: Project: Sentinel, Configuration: Release Win32 ------
1>Compiling...
1>UI.cpp
1>..\src\UI.cpp(562) : error C2039: 'setBaseColor' : is not a member of 'QuickGUI::Widget'
1> d:\quickgui_9_04\quickgui\include\QuickGUIWidget.h(95) : see declaration of 'QuickGUI::Widget'
1>Build log was saved at "file://d:\University\03-1 Advanced Games Technologies\Sentinel\Sentinel\Release\BuildLog.htm"
1>Sentinel - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


Here's the source code:


QuickGUI::Widget* warning=windows[5]->findWidget("warning_light");
Ogre::ColourValue c;
c.r=0;
c.g=0;
c.b=0;
c.a=0;

switch(warn_state)
{
case 0:
c.g=1;
break;

case 1:
c.g=1;
c.r=1;
break;

case 2:
c.r=1;
break;
}

warning->setBaseColor(c);

kungfoomasta

22-04-2009 18:09:38

I just did an SVN update here at work, and sure enough, the code base has the function Widget::setBaseColor. I can only think of the following causes:

1. You don't have the latest revision of QuickGUI
2. You do have the latest code, but never rebuilt the library/dll

:P

Stardragon

22-04-2009 21:35:09

*sighs and facepaws*

One of these days I will

1. learn not to code when extremely tired
2. learn how to work an SVN client
3, 4, 5, 6, & 7. learn not to argue with the chap who made the software I'm using...

Thanks, KFM. *blushes* :D

kungfoomasta

23-04-2009 07:16:21

Why do I get the feeling you're going to be the death of me?

:lol:

Stardragon

23-04-2009 11:50:47

*isn't quite sure how to respond to that, so... just drinks coffee and swears at his shaders, for the nth time today*