TabControl Bugs & Questions

rubasurex

08-02-2009 09:08:37

I've been setting up a TabControl for my editor and have found what appears to be some bugs. I may just be doing something wrong, but I'll list them anyway just in case.

1. Calling resetToDefault() in TabPageDesc does not appear to reset the underlying textDesc. Each time I create a new tab (reusing the TabPageDesc), it uses the text of the previous tab and then appends the text for the new tab. To work around this, I have to also call resetToDefault() on the underlying textDesc. I haven't had to do this with any other control.

2. Clicking on a tab in the tab control does not appear to handle the mouse down event, but instead allows the event to pass through to my editor, which causes the scene underneath to be modified. I believe this is being caused because there are no user-defined mouse down events for the tab, so the injectMouseButtonDown method returns false. The mouse up event is handled however as this selects the tab.

3. addWidgetEventHandler for TabPage appears to do nothing. I tried to add a mouse up and mouse down event and mWidgetEventHandlers is empty after the calls.

4. Clicking anywhere on a tab page allows the input to pass through, which causes a problem as it interacts with the scene below the tab page. I think that any mouse up/down events over a tab page should be discarded by QuickGUI and the injectMouseButtonDown and injectMouseButtonUp methods should return true.

I think that any mouse down/up events over a solid control (i.e. button, tab page, window, etc...) should always be "handled" by QuickGUI even if it does nothing. Otherwise you end up with mouse events interacting with your scene underneath the widgets. I just tried a window widget and it also allows input to pass through it. If I click anywhere in the window, or a try resizing it, or moving it, my editor modifies the scene underneath it.

The only exception to this that I can think of is transparent container controls such as sheets and widgets that have no input interaction such as labels and the tab control (except for the actual tabs themselves of course).

On a side note, I have a couple of questions.

1. Is it possible to create separators in a menu? You know how if you go to the File menu in Visual Studio for example, you can see the horizontal separators between logical groups of menu items.

2. I would like to use icons (i.e. small 32x32 images) on buttons and tabs in the tab control rather than text. Is this possible? Is there somewhere to set an image to be used on a button or a tab?

3. What is the correct way to remove a texture from a widget. For example, I want a tab control that has no visible presence (i.e. no texture). I just want to see the tab pages. I have gone into the TabControl skintypes file and set the Texture property to nothing. That seem to do the trick, but I just wanted to make sure that is the "correct" way to do it.

4. Is there a way to control the width of tabs? I find that they are very narrow (i.e. only as wide as the text in them). At the moment I'm just adding extra white space padding to make the tabs wider.

5. Is there a slider control? I couldn't find one, but I just thought I'd ask.

kungfoomasta

08-02-2009 20:22:36

Thanks for providing feedback, its definately welcome!

@1: Thats a bug, I've fixed it now.

@2: I modified the code so that the tab is selected on mouse button down. I also saw that I don't give access to the TabPage's Tab widget. I didn't give access to the Tab widget, but I added some wrapper functions to allow modification of the Tab Text.

@3: The implementation of the TabPage is a little tricky. What I did was have the TabPage act as a container for a Panel and a Tab (Label), but instead of the TabPage inheritting from a ContainerWidget, it inherits from a Panel widget. This allows the TabPage to inherit all the createX widget functions from the Panel interface. I overrode a function so that all children added to the TabPage actually get added to the Panel child. I will override the addition of handlers so that they work against the child panel, so that the integration of the child panel is more seamless.

@4: Agreed. I've updated some of my code, and also realized that the [mouse down/up/click/double click/triple click] injections should simply return true if the cursor is over a widget. I've updated the "findWidgetAtPoint" functions, so now if your Sheet is transparent, its possible that the manager will not detect the mouse as over any widget. (Assuming you're mouse is over the sheet, and the sheet is transparent at that location. GUIManager::getWidgetUnderMouseCursor will return NULL)


@1: I know what you mean, but I didn't get around to implementing these. If I get some time I can add them in. I have not tried/tested this, but you could try to put in a placeholder in your app by using a MenuLabel with -------- as the text, and disabling the MenuLabel. Then clicking on it should do nothing, and it will give an idea of how separators will feel in the menu.

@2: Very good idea with the icons for tabs. I will add in support for this, it should be a simple modification to the Skin definition and onDraw method. Note that the tab width is dictated by the Tab's Text length, so you will need to add spaces to get the desired width.

In regards to skinning in general, I would recommend reading the QuickGUI Skinning tutorial from the wiki, its fairly short and covers all the basics. For buttons, open up "Button.SkinTypes". You can add your own Skin definition for the Button class, or modify the existing default one provided. If you create your own, for example named "rubasurex", you can make use of this by either setting the "widget_skinTypeName" property in the Desc, or after creation using Widget::setSkinType("rubasurex");

@3: I haven't made any firm rules here, you could try setting the texture name to empty string as you have done, or the way I do it (ie its tested more), delete all the fields from the SkinElement definition. Here is an example:

Before:

SkinElement default
{
Border_Bottom 2
Border_Left 2
Border_Right 2
Border_Top 2
Texture qgui.button.png
TileBackground false
TileBorders true
}


After:

SkinElement default
{
}


@4: Right now its dependent on text width, I can add in a field to specify a buffer afterwards.

@5: The HScrollBar and VScrollBar has nice features where you can specify the layout of the buttons shown on the screen: 2 up/down, 1 up/down, no up/down, up/down on bottom only, up/down on top only. Modifying these properties, you can get a ScrollBar with no buttons, just a slider. I never really advertised this feature, but I put time into implementing it, and I think its pretty cool at least. :wink:

Again thanks for the post, I've made a lot of updates to the code base. :D

rubasurex

08-02-2009 23:56:44

@4: Agreed. I've updated some of my code, and also realized that the [mouse down/up/click/double click/triple click] injections should simply return true if the cursor is over a widget. I've updated the "findWidgetAtPoint" functions, so now if your Sheet is transparent, its possible that the manager will not detect the mouse as over any widget. (Assuming you're mouse is over the sheet, and the sheet is transparent at that location. GUIManager::getWidgetUnderMouseCursor will return NULL)
OK, so does that mean if you create a widget with a transparent area (i.e. it has a hole in it, or rounded corners), that the mouse events with pass through when over these pixels. I think that would be a fantastic way of handling it if possible. This would allow you to create widgets in virtually any shape.

kungfoomasta

09-02-2009 04:47:14

Yep, transparency picking has been available for a while, but I found a bug when dealing with SkinElements that were empty, such as the Sheet. You can toggle transparency picking via the widget_transparencyPicking property.

kungfoomasta

10-02-2009 18:30:31

rubasurex,

I noticed that in my PlayPen, the Context Menu for the Sheet never appears, because the Sheet is all transparent, and so the GUIManager doesn't detect any widget underneath the cursor. What I'm thinking is, for your editor couldn't you create an event handler such that mouse button down/up/click/double/triple events on the Sheet get sent to your editor application?

[edit] I guess this isn't really an issue, I could disable transparency picking for my sheet, and it would always get detected. In my editor/game/projects I'll probably disable transparency picking, and create a handler so that mouse events on the sheet will perform actions in the application. [/edit]