pipeline for adding a new window type

For help with anything that CEGUI doesn't offer straight out-of-the-box, e.g.:
- Implementation of new features, such as new Core classes, widgets, WindowRenderers, etc. ...
- Modification of any existing features for specific purposes
- Integration of CEGUI in new engines or frameworks and writing of new plugins (Renderer, Parser, ...) or modules

Moderators: CEGUI MVP, CEGUI Team

User avatar
granx
Quite a regular
Quite a regular
Posts: 80
Joined: Fri Apr 29, 2005 21:58

pipeline for adding a new window type

Postby granx » Fri Aug 05, 2005 21:45

If I want to make Windows with new functionality, what are the steps that I need? Does this change with the Falagard system? My initial take on it includes these steps:

1 - derive from a CEGUI::Window
2 - make a CEGUI::WindowFactory subclass for this new type of window
3 - provide properties for your subclass which will set any of the handles, similar to those of other CEGUI::Window classes.
4 - find where CEGUI registers their core supported WindowFactories and include yours there.
5 - extend the CEGUI::XMLParser(s) to support your properties, should be easy.
6 - provide support for your subclass in the 'WindowsLook' or other "look" libraries. this might be the hard part, because I believe it is the responsibility of these "look" libraries to pass instructions to the OpenGLRenderer, which is probably generalized to commands for lines and polygons.
7 - make a layout.xml which will try your new functionality.
8 - refine your logic for what you want to happen when the window is out of focus, inactive, destroyed, etc. You have control for these events in the virtual functions from the base class, CEGUI::Window.

Close?

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Re: pipeline for adding a new window type

Postby CrazyEddie » Sat Aug 06, 2005 08:26

It really depends upon exactly what you're after. But if you're creating a totally new widget, then much of what you have put is correct. I'll now make some notes on each of your points...

1) Yes, this is what to do for a totally new widget. If some other widget provides some, but not all, of what you want, you could derive from one of those classes instead.

2) Correct.

3) This is optional, though is very useful if you want to initialise your window via layouts (and script if your class is not directly bound).

4) If your widget does any rendering, the type should not be registered within CEGUIBase. Widgets that draw things go into the 'look' modules, and each look module has functions that handle the registration of new classes (see ./WidgetSets/TaharezLook/src/TLModule.cpp etc, for examples).

5) Not required. So long as your properties are correctly added to the widget type, the system is designed so that nobody ever has to touch the XML handling code - except when adding core functionality (which Properties are not).

6) Yes you need to do this for each look that you want to support, though consider the following points:

- a) If you're using CVS head code, I'd recommend the Falagard system - it enables you basically specify 'states' that must be provided in an XML skin - the XML skin takes care of describing exactly what must be drawn. 99% of the time rendering classes for Falagard are much simpler than their WindowsLook or TaharezLook counterparts. In new releases, the TaharezLook and WindowsLook modules will exist for compatibility reasons only - if ever there are new widgets written by us, they will likely be supported via Falagard only.

- b) If you do not go for Falagard, then your class draws 'Images' which is the level at which CEGUI operates. There are no lines or geometry as such, though you can form lines by stretching/tiling images as needed.

7) That's generally a good idea :)

8 ) Correct.

So to conclude. Yep, you've got the right general idea. The only 'fuzzy' areas seemed to be with Properties and Window registration, basically, for new window/widget types you should never have to modify any existing code in CEGUIBase - the interfaces provided are sufficient for all such needs :)

User avatar
granx
Quite a regular
Quite a regular
Posts: 80
Joined: Fri Apr 29, 2005 21:58

Re: pipeline for adding a new window type

Postby granx » Sat Aug 06, 2005 08:57

Hey CE,
Thanks for the tips. My comments about point 6 are from the fact that I wanted to make some really strange widgets, and I was curious if the current drawing features could accomodate these things.

1 - an analog clock (is a digital clock already possible?)
2 - a 2D minimap for my virtual world
3 - some weird windows that will have bullets, and the bullets will actually draw lines to bullets on other windows, like this one.

Image

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Re: pipeline for adding a new window type

Postby CrazyEddie » Mon Aug 08, 2005 08:50

Well, Some of this stuff is pretty much beyond what anybody has tried with CEGUI.

In effect, we have no real drawing support, so some things will require non-cegui code to do - basically anything that requires something other than a purely horizontal or vertical line.

So, it's not impossible, but definitely a challenge of the biggest order.

User avatar
granx
Quite a regular
Quite a regular
Posts: 80
Joined: Fri Apr 29, 2005 21:58

Re: pipeline for adding a new window type

Postby granx » Tue Aug 09, 2005 17:22

Hey CE,
That's cool, I just want to know HOW to do these things. I thought the community would appreciate any new widgets that I am developing on my own.

Does the pipeline shown here need to be modified? Where will I need to add support? What if I only care about the OpenGLRenderer and don't have the resources to implement these advanced widgets with the other renderers?

Also, what is the motivation for disabling RTTI with Falagard and the "Look" libraries?

Thanks, -granx

User avatar
granx
Quite a regular
Quite a regular
Posts: 80
Joined: Fri Apr 29, 2005 21:58

Re: pipeline for adding a new window type

Postby granx » Wed Aug 10, 2005 02:46

One more question that is in the context of this thread:

How can I implement my derived widget (derives from FrameWindow) such that it will hide whenever the parent window is not being displayed.

Here is the scenario:
I have a nice GUI being displayed, including an instance of my derived widget as a child of the sheet. Then, I decide to swap out the gui sheet so I can see an entirely new GUI, OH MY! The problem is that my derived widget's instance is still rendering. There was no event which informed my widget that its parent was no longer the gui sheet. :( If such an Event does exist, please tell me of its type and the onXXXX(const Event& e) handling function I need to overload. If such an Event does not exist, can you think of any tricks I can do when swapping the new GUI sheet? Maybe I should check the current GUI sheet to see if my widget is a child and hide it, then swap the new sheet in for the old one???

Thanks! :)

p.s. I think all my problems would be solved if calling ::hide() on a parent window also called hide() on its children. What do you think about supporting this?

User avatar
gcarlton
Just can't stay away
Just can't stay away
Posts: 149
Joined: Wed Jan 12, 2005 12:06

Re: pipeline for adding a new window type

Postby gcarlton » Wed Aug 10, 2005 03:58

This is a very interesting series of challenges. I'd be interested to see how you go implementing them! The main thing it looks like you need is rotation support for images and the ability for the render to draw lines - or perhaps rotated, stretched, images (using an image of a nice line segment).

If you are feeling brave, you could try out the rotation patch I submitted (just today). This is a cleaned up version of my earlier patch. Essentially its got my changes to rotate static images, at least for the D3D8 and D3D9 renderer - the opengl one accepts the rotation float but does nothing with it. The D3D8 and D3D9 render also allow custom allocation via a CEGUIAllocator class, which I found useful since it allocs/frees all the time every render.

No guarentees though, I'm must admit I find the whole patch process rather awkward due to my large number of changes across the board. ;)

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Re: pipeline for adding a new window type

Postby CrazyEddie » Wed Aug 10, 2005 08:43

The approach in the pipeline you posted is, as already stated, generally correct.

Basically what you need to do is add some mid-level classes to provide generic drawing functions (like 'drawLine' etc). These would then call appropriate supporting methods in the renderer class. I prefer this middle-man approach to having widgets call the renderer directly, this is basically because it then allows the any renderer support to be much lower-level, while maintaining decent abstractions in higher-level classes such as the widgets.

What would basically be cool is to add support to the renderer for non-quads - that is, the ability to specify arbitary geometry, and an CEGUI::Image to use for texturing it, and some other info such as tiled/stretched, and what have you. This then basically gives you the ability to draw lines and other things. Though I would say that any design for such things should be run past me and _mental_ first so you do not end up implementing something that does not meet out requirements for the system (if you wanted such extensions to be included into the core CEGUI, anyway).

To answer you other point:
A window / widget attached to a sheet will not be rendered if the sheet is not set in CEGUI::System as the active sheet. If you're getting any ohter behaviour your usage of the system must be incorrect somewhere.

CE.

User avatar
granx
Quite a regular
Quite a regular
Posts: 80
Joined: Fri Apr 29, 2005 21:58

Re: pipeline for adding a new window type

Postby granx » Wed Aug 10, 2005 18:16

To answer you other point:
A window / widget attached to a sheet will not be rendered if the sheet is not set in CEGUI::System as the active sheet. If you're getting any ohter behaviour your usage of the system must be incorrect somewhere.


Yeah, I hesitated to inform you that I am doing my own rendering because I do not want to extend the renderer or make a middle layer like you suggested until I can see that I will get good results. I did not mention it because I fully intend to revisit the middle layer issue, but would like to see *something* first (and remove something too ;).

Because I am doing my own rendering for these new widgets, I need an Event to tell me to stop :(. I could not find any logic to turn off rendering for my new widgets other than the recursive search for an instance of my new widget under the gui sheet that I am trying to remove for another gui sheet.

I just wanted to confirm that there is no Event that is sent when the System::setGUISheet() method is called.

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Re: pipeline for adding a new window type

Postby CrazyEddie » Thu Aug 11, 2005 13:28

From CEGUISystem.h:

Code: Select all

static const String EventGUISheetChanged;    //!< Name of event fired whenever the GUI sheet is changed.


If it's not firing then it's a bug.

User avatar
granx
Quite a regular
Quite a regular
Posts: 80
Joined: Fri Apr 29, 2005 21:58

Re: pipeline for adding a new window type

Postby granx » Thu Aug 11, 2005 17:58

OH WOW GREAT!!! Thanks, I was hoping this existed, but I wasn't sure where to look. I noticed that none of the virtual methods for handling Events we named accordingly. Which Window::onXXXXX(EventArg e) is supposed to handle this event? My widget needs to respond when the EventGUISheetChanged has been fired. How do I do this? Thanks, -granx

User avatar
lindquist
CEGUI Team (Retired)
Posts: 770
Joined: Mon Jan 24, 2005 21:20
Location: Copenhagen, Denmark

Re: pipeline for adding a new window type

Postby lindquist » Thu Aug 11, 2005 19:50

This is an event of System not window.
So you would subcribe to it with something like this:

Code: Select all

CEGUI::System::getSingleton().subscribeEvent(CEGUI::System::EventGUISheetChanged,Event::Subscriber(func,this));

User avatar
granx
Quite a regular
Quite a regular
Posts: 80
Joined: Fri Apr 29, 2005 21:58

Re: pipeline for adding a new window type

Postby granx » Tue Oct 04, 2005 02:55

OK. I know you are all sick of hearing me gripe about this, but I have to revisit this topic. Let's say I want to use CEGUI to do a cool preview window. This window will preview some geometry I am about to load into my game. The object will be spinning, imagine a car in a showroom. When I'm done looking at the preview window, I will hit the X button and close it. I definitely want CEGUI to be used for this window, and I definitely want it rendering each frame for the animation. HOW CAN I DO THIS WITH CEGUI? I think there needs to be some tutorials about what events of the parent class this widget will need to subscribe to, for example, parent's position and parent's resize events. I think this is something CEGUI should support, and I have not been let down by CEGUI as of yet, so I have faith it's already in the GUI system. Please help me find it. Thanks,
-granx :D

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Re: pipeline for adding a new window type

Postby CrazyEddie » Tue Oct 04, 2005 10:57

You need to render your 'active content' to a texture render target. You then use this texture to create a CEGUI Imageset dynamically in memory, and add an Image to that imageset that describes the area that you rendered your content to. This Image/Imageset can then be used to output the rendered content into a CEGUI window (like a StaticImage).

HTH

CE

User avatar
granx
Quite a regular
Quite a regular
Posts: 80
Joined: Fri Apr 29, 2005 21:58

Re: pipeline for adding a new window type

Postby granx » Tue Oct 25, 2005 05:20

Thanks for the response CE. I think I have close to what you outlined, but I need some help finishing.

Let me see if I have the general outline. To render something to a texture, I must use my renderer to create the texture, then tell the CEGUI::Renderer about this texture via a StaticImage widget. In code, I've done the following:

Code: Select all

CEGUI::Imageset* imgset = mGUI->CreateImageset("incode", mTarget->GetTexture() );

CEGUI::Window* siw = mGUI->CreateCEGUIWindow("WindowsLook/StaticImage", "incodeimage");


I can expand upon the 'CreateImageset' function, but I think I've already found a problem with the algorithm. What code do I need to write in order to attach an Image to the StaticImage widget? Maybe it would look like:

Code: Select all

CEGUI::StaticImage* statimg = static_cast<CEGUI::StaticImage*>( siw );
statimg->setImage(imgset->getName(),"unknown");


StaticImage::setImage takes, as the 2nd parameter, the name of the Image. This is completely unknown to me. I don't remember where in my algorithm I had an oppurtunity to name an Image, so I'm stuck again. Any advice would be much appreciated.

In case I missed an opportunity to name an Image when creating the Imageset, here is that code, which is experimental and possibly complete wrong ;) :

Code: Select all

CEGUI::Imageset* GuiMgr::CreateImageset(const std::string& name, osg::Texture2D* osgtex)
{
   osg::Image* osgimg = osgtex->getImage();

   CEGUI::Texture* cetex = CEGUI::System::getSingletonPtr()->getRenderer()->createTexture();
   cetex->loadFromMemory( osgimg->data(), osgimg->s(), osgimg->t() );

   CEGUI::ImagesetManager* mgr = CEGUI::ImagesetManager::getSingletonPtr();
   CEGUI::Imageset* imgset = mgr->createImageset(name,cetex);

   return imgset;
}


Return to “Modifications / Integrations / Customisations”

Who is online

Users browsing this forum: No registered users and 17 guests