Difference between revisions of "Introduction To Auto Windows"

From CEGUI Wiki - Crazy Eddie's GUI System (Open Source)
Jump to: navigation, search
m (Bot: Automated text replacement (-<code>[:space:]?<cpp/>(.*?)</code> +<syntaxhighlight lang="cpp">\1</syntaxhighlight>))
m (Lets use <source> instead of <syntaxhighlight>, it is much less typo-prone)
Line 60: Line 60:
 
Sticking with the the FrameWindow, you might want to hear about mouse clicks on the title bar and assign a scripted event handler. Your code could look something similar to this:
 
Sticking with the the FrameWindow, you might want to hear about mouse clicks on the title bar and assign a scripted event handler. Your code could look something similar to this:
  
<syntaxhighlight lang="cpp">
+
<source lang="cpp">
 
...
 
...
 
// get access to the titlebar attached to the frame window "myFrameWindow"
 
// get access to the titlebar attached to the frame window "myFrameWindow"
Line 68: Line 68:
 
titlebar->subscribeScriptedEvent("MouseClick", "handleTitlebarClick");
 
titlebar->subscribeScriptedEvent("MouseClick", "handleTitlebarClick");
 
...
 
...
</syntaxhighlight>
+
</source>
  
 
This is very nice, but requires some code compilation so could be hard to play with and tweak. What we really want to be doing is attaching our event handler from within the layout file like we would in the case of a "normal" window. The CEGUI layout system provides a means for us to target auto windows within the layout file with the <AutoWindow> tag.
 
This is very nice, but requires some code compilation so could be hard to play with and tweak. What we really want to be doing is attaching our event handler from within the layout file like we would in the case of a "normal" window. The CEGUI layout system provides a means for us to target auto windows within the layout file with the <AutoWindow> tag.
Line 164: Line 164:
  
 
This code snippet shows how you might load in the schemes:
 
This code snippet shows how you might load in the schemes:
<syntaxhighlight lang="cpp">
+
<source lang="cpp">
 
...
 
...
 
// Note that in order for this to work you need to have loaded the normal
 
// Note that in order for this to work you need to have loaded the normal
Line 173: Line 173:
 
SchemeManager::getSingleton().loadScheme("NewFrameWindow.scheme");
 
SchemeManager::getSingleton().loadScheme("NewFrameWindow.scheme");
 
...
 
...
</syntaxhighlight>
+
</source>
  
 
==== NewFrameWindow.scheme ====
 
==== NewFrameWindow.scheme ====

Revision as of 11:21, 28 February 2011

Introduction

The purpose of this article is to highlight the "Auto Window" and demonstrate a couple of the advanced possibilities that they enable within Crazy Eddie's GUI System. The article will introduce the concept of the auto window, show where it is used in the unmodified system, and then go on to demonstrate how the developer can make use of the same ideas to solve certain problems.


What is an Auto Window?

If you have used CEGUI at all, chances are that you have already used auto windows without knowing it; combo boxes, all the list widgets, and even the scroll bar and frame window are all compound widgets made up of multiple component widgets - those component widgets are classed as auto windows.

An auto window is basically a widget that is created as a child component of another widget type, as defined in the LookNFeel skin by the use of the <Child> tag. Many of the core widgets have requirements for auto windows that must be specified - the frame window for example requires that a titlebar and close button be specified.

It is possible that there may be confusion in relation to LookNFeel specifications and window Layout specifications. It appears there is some crossover of functionality since both provide a means for setting properties, specifying child widgets, and so on; be assured there actually isn't any crossover. The parts of the system that deal with LookNFeel and Layouts are operating at totally different levels. One potentially useful way to look at these two parts of the system is to consider the LookNFeel to specify a class (or maybe a template) for a widget, whilst the Layouts define and specify actual instances of those classes.


An Existing Example

The first thing we will do is take a look at an existing example. Here is how the titlebar is specified for the WindowsLook frame window:

...
<Child type="WindowsLook/Titlebar" nameSuffix="__auto_titlebar__">
    <Area>
        <Dim type="LeftEdge">
            <AbsoluteDim value="0" />
        </Dim>
        <Dim type="TopEdge">
            <AbsoluteDim value="0" />
        </Dim>
        <Dim type="RightEdge">
            <UnifiedDim scale="1" type="RightEdge" />
        </Dim>
        <Dim type="Height">
            <FontDim type="LineSpacing">
                <DimOperator op="Multiply">
                    <AbsoluteDim value="1.5" />
                </DimOperator>
            </FontDim>
        </Dim>
    </Area>
    <Property name="AlwaysOnTop" value="False" />
</Child>
...

Since this whole concept may be new to many readers, lets take this first example one part at a time.

To open the definition we use the <Child> tag. Here we need to supply two attributes to specify the type of window to be created and a name suffix to be used. This is telling the system that whenever a widget using this WidgetLook (in this case "WindowsLook/FrameWindow") is created, it should create and attach a child window of the specified type ("WindowsLook/Titlebar") and name that child by appending the given suffix ("__auto_titlebar__") to the base widget name.

In this example, if you create a "WindowsLook/Framewindow" with the name "myWindow", the system will automatically have created a "WindowsLook/Titlebar" named "myWindow__auto_titlebar__" and added it as a child to "myWindow".

Next we can see an <Area> tag. The content in here defines the area that this child is to occupy within its parent (meaning all positions are relative to the parent's position, and scale co-ordinate components are fractions of the size of the parent).

In this example the the title bar is positioned at absolute location (0,0) - so is at the top left of the parent. The right edge is is specified as being a scale value of 1, which means the right edge will always be attached to the right edge of the parent. The height is specified as being 1.5 times the linespacing value of the current font.

Finally we see a <Property> tag. We can list properties here to specify 'defaults' to be used for the component widget in instances of the widget being defined. This provides a means to override default settings that may previously have been specified either in the core system code, or in the WidgetLook for the type being embedded.

In this example we are ensuring that the titlebar is used with the always on top setting disabled.

Note that we have skimmed over some of the specifics of this definition - this article is not intended as a tutorial on the Falagard system itself, just one specific capability of it.


Accessing Auto Windows

Now we know what an auto window is and generally how they are created, you may be able to see that it is possible to access these windows directly - afterall they are actually the same as any other child window, just automatically created by the system.

Sticking with the the FrameWindow, you might want to hear about mouse clicks on the title bar and assign a scripted event handler. Your code could look something similar to this:

...
// get access to the titlebar attached to the frame window "myFrameWindow"
Window* titlebar = WindowManager::getSingleton().getWindow("myFrameWindow__auto_titlebar__");
 
// attach a scripted event handler to process mouse clicks
titlebar->subscribeScriptedEvent("MouseClick", "handleTitlebarClick");
...

This is very nice, but requires some code compilation so could be hard to play with and tweak. What we really want to be doing is attaching our event handler from within the layout file like we would in the case of a "normal" window. The CEGUI layout system provides a means for us to target auto windows within the layout file with the <AutoWindow> tag.

The AutoWindow tag takes a single attribute "NameSuffix" which specifies the name suffix of the auto window we wish to target (if we continue our example, this would be "__auto_titlebar__" to target the titlebar of a FrameWindow). The AutoWindow tag may then then contain LayoutImport (yes, you really can import an entire layout as content for an auto window), Property, Event, and other Window and AutoWindow (to target auto windows of auto windows!) tags.

Thus, to attach a scripted event handler to the title bar of a frame window in a layout you could do this:

...
<Window Type="WindowsLook/FrameWindow" Name="myFrameWindow" >
    <Property Name="Text" Value="Auto Window Example" />
    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
    <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.25,0},{0.8,0},{0.8,0}}" />

    <AutoWindow NameSuffix="__auto_titlebar__" >
        <Event Name="MouseClick" Function="handleTitlebarClick" />
    </AutoWindow>

</Window>
...

Reiterating, along with the Event tag you could just as easily have specified Property tags to modify the options set for the title bar, or even Window tags to add an extra button for example. The AutoWindow tag effectively allows us to do an auto window anything we can do with a normal window.


Making Your Own Auto Windows

As already mentioned, various compound widgets in the system have specified requirements for auto windows that must be supplied within the LookNFeel. What you need to consider is that these requirements are a minimum and not an absolute. This affords us the possibility of specifying, via the <Child> tag, additional auto windows of our choosing in the LookNFeel. Effectively this unties our hands and gives total freedom to create any number of new widgets by combining other widgets in various ways. Obviously there will be cases where supporting systems and code are required, but the basic composition and layout of these widgets can be entirely specified in XML.

One of the weaknesses of the FrameWindow as it stands at the moment is that developer added content, that is your buttons and other widgets, are added to the frame window relative to the top-left corner and on an equal standing to the title bar. This can lead to situations where your content is sometimes partially obscured by the titlebar, this can especially be the case if the user may re-size the frame window - things may look fine at the initial size, but quickly go awry when the window is made smaller.

One work around to the frame window issue is to add an absolutely positioned container window in the layout and have the content added to that. On the surface this seems like an ideal solution, but in reality has more issues of its own since it does not allow your layout to remain resolution neutral (2 pixels at 640 x 480 are much larger physically than they are at, say, 1024 x 768). Additionally, changing the size of the titlebar font would not automatically re-size the 'content pane' and so you would need additional processing for that. Ultimately the whole concept breaks down as being not worth the cost.

What is needed is a solution that can remain resolution independent, have some kind of absolute positioning, but also react to changes in the parent window. All of these criteria are met by the basic provisions of the Falagard system and the auto window approach will give us a reasonable solution.

The rest of the article will develop a frame window type that has a separate client area or content window. Note that the solution developed is not a panacea; there are still potential issues surrounding enabling and disabling of the title bar and window frame, though generally the solution presented will be useful to many.


Example Project - NewFrameWindow

Basically what we are going to do is to create a new FrameWindow type that uses the auto window system to add a DefaultWindow which covers what is commonly known as the 'client area' of the frame window; that is the area within the window frame and title bar. We can then target content into this client area auto window within layout files.

First let us define a couple of criteria that this new auto window must meet as far as position and size:

  • The top edge needs to be glued to the bottom edge of the title bar at all times.
  • The other edges need to be within the window sizing frame at all times.

Ok, that seems fairly straight forwards, lets make a start. We'll define the new auto window and its parts outside of any WidgetLook to begin with, this will enable us to focus on the important aspects of what we are doing. At the end the final thing is presented in full along with other supporting material.

First provide the Child tag structure:

<Child type="DefaultWindow" nameSuffix="__auto_clientarea__">
</Child>

Note that the suffix could, in reality, be anything you choose; the use "__auto_<whatever>__" is just the established idiom used within CEGUI itself - so we just continue that here.

Now we need to establish the area to be used by the client area window according to our specifications above. In order to do what is needed we need two pieces of information; the location of the bottom edge of the title bar, and the size of the sizing border. Both are easily obtained. The WidgetDim element in Falagard allows us to extract information about the location of another widget, and the PropertyDim allows us to extract a setting from the parent window.

We now define the area for the client area window as follows:

<Area>
    <Dim type="LeftEdge">
        <PropertyDim name="SizingBorderThickness" />
    </Dim>
    <Dim type="TopEdge">
        <WidgetDim widget="__auto_titlebar__" dimension="BottomEdge" />
    </Dim>
    <Dim type="RightEdge">
        <UnifiedDim scale="1" type="RightEdge">
            <DimOperator op="Subtract">
                <PropertyDim name="SizingBorderThickness" />
            </DimOperator>
        </UnifiedDim>
    </Dim>
    <Dim type="BottomEdge">
        <UnifiedDim scale="1" type="BottomEdge">
            <DimOperator op="Subtract">
                <PropertyDim name="SizingBorderThickness" />
            </DimOperator>
        </UnifiedDim>
    </Dim>
</Area>

We require no additional settings or options for this window.

To utilise the client area in a layout we now can use XML such as:

<AutoWindow NameSuffix="__auto_clientarea__" >
    <Window Type="WindowsLook/Button" Name="myButton">
        <Property Name="UnifiedAreaRect" Value="{{0.02,0},{0.01,0},{0.98,0},{0.2,0}}" />
        <Property Name="Text" Value="Engage!" />
    </Window>
</AutoWindow>


Putting It Together

In order that you can make use of such a new frame window it all needs to be presented to the system in some way. You could just modify the existing WindowsLook.looknfeel XML file and that would be fine. However, in this section we present the solution in such a way it can be used as an 'add-in' widget which can be used in addition to the existing WindowsLook widgets. This is just one way of doing it, various possibilities exist for the advanced user.

We have the following two files:

  • NewFrameWindow.scheme - specifies the required binding to make the widget available in the system
  • NewFrameWindow.looknfeel - specifies the LookNFeel specification for the new frame window type

This code snippet shows how you might load in the schemes:

...
// Note that in order for this to work you need to have loaded the normal
// WindowsLook.scheme.
SchemeManager::getSingleton().loadScheme("WindowsLook.scheme");
 
// Load in a scheme to setup our new frame window type
SchemeManager::getSingleton().loadScheme("NewFrameWindow.scheme");
...

NewFrameWindow.scheme

<?xml version="1.0" ?>
<GUIScheme Name="WindowsLookAdditions">
    <LookNFeel Filename="NewFrameWindow.looknfeel" />
    <WindowSet Filename="CEGUIFalagardWRBase" />

    <FalagardMapping WindowType="WindowsLook/NewFrameWindow"
                     TargetType="CEGUI/FrameWindow"
                     Renderer="Falagard/FrameWindow"
                     LookNFeel="WindowsLook/NewFrameWindow" />

</GUIScheme>

NewFrameWindow.looknfeel

<?xml version="1.0" ?>
<Falagard>
    <WidgetLook name="WindowsLook/NewFrameWindow">
        <PropertyLinkDefinition name="CaptionColour" widget="__auto_titlebar__" targetProperty="CaptionColour" initialValue="FF000000" />
        <PropertyLinkDefinition name="TitlebarFont" widget="__auto_titlebar__" targetProperty="Font" />
        <Property name="NSSizingCursorImage" value="set:WindowsLook image:MouseNoSoCursor" />
        <Property name="EWSizingCursorImage" value="set:WindowsLook image:MouseEsWeCursor" />
        <Property name="NWSESizingCursorImage" value="set:WindowsLook image:MouseNwSeCursor" />
        <Property name="NESWSizingCursorImage" value="set:WindowsLook image:MouseNeSwCursor" />
        <NamedArea name="ClientWithTitleWithFrame">
            <Area>
                <Dim type="LeftEdge">
                    <ImageDim imageset="WindowsLook" image="WindowFrameLeft" dimension="Width" />
                </Dim>
                <Dim type="TopEdge">
                    <WidgetDim widget="__auto_titlebar__" dimension="BottomEdge" />
                </Dim>
                <Dim type="RightEdge">
                    <UnifiedDim scale="1" type="RightEdge">
                        <DimOperator op="Subtract">
                            <ImageDim imageset="WindowsLook" image="WindowFrameRight" dimension="Width" />
                        </DimOperator>
                    </UnifiedDim>
                </Dim>
                <Dim type="BottomEdge">
                    <UnifiedDim scale="1" type="BottomEdge">
                        <DimOperator op="Subtract">
                            <ImageDim imageset="WindowsLook" image="WindowFrameBottom" dimension="Height" />
                        </DimOperator>
                    </UnifiedDim>
                </Dim>
            </Area>
        </NamedArea>
        <NamedArea name="ClientWithTitleNoFrame">
            <Area>
                <Dim type="LeftEdge">
                    <AbsoluteDim value="0" />
                </Dim>
                <Dim type="TopEdge">
                    <WidgetDim widget="__auto_titlebar__" dimension="BottomEdge" />
                </Dim>
                <Dim type="RightEdge">
                    <UnifiedDim scale="1" type="RightEdge" />
                </Dim>
                <Dim type="BottomEdge">
                    <UnifiedDim scale="1" type="BottomEdge" />
                </Dim>
            </Area>
        </NamedArea>
        <NamedArea name="ClientNoTitleWithFrame">
            <Area>
                <Dim type="LeftEdge">
                    <ImageDim imageset="WindowsLook" image="WindowFrameLeft" dimension="Width" />
                </Dim>
                <Dim type="TopEdge">
                    <ImageDim imageset="WindowsLook" image="WindowFrameTop" dimension="Height" />
                </Dim>
                <Dim type="RightEdge">
                    <UnifiedDim scale="1" type="RightEdge">
                        <DimOperator op="Subtract">
                            <ImageDim imageset="WindowsLook" image="WindowFrameRight" dimension="Width" />
                        </DimOperator>
                    </UnifiedDim>
                </Dim>
                <Dim type="BottomEdge">
                    <UnifiedDim scale="1" type="BottomEdge">
                        <DimOperator op="Subtract">
                            <ImageDim imageset="WindowsLook" image="WindowFrameBottom" dimension="Height" />
                        </DimOperator>
                    </UnifiedDim>
                </Dim>
            </Area>
        </NamedArea>
        <NamedArea name="ClientNoTitleNoFrame">
            <Area>
                <Dim type="LeftEdge">
                    <AbsoluteDim value="0" />
                </Dim>
                <Dim type="TopEdge">
                    <AbsoluteDim value="0" />
                </Dim>
                <Dim type="RightEdge">
                    <UnifiedDim scale="1" type="RightEdge" />
                </Dim>
                <Dim type="BottomEdge">
                    <UnifiedDim scale="1" type="BottomEdge" />
                </Dim>
            </Area>
        </NamedArea>
        <Child type="DefaultWindow" nameSuffix="__auto_clientarea__">
            <Area>
                <Dim type="LeftEdge">
                    <PropertyDim name="SizingBorderThickness" />
                </Dim>
                <Dim type="TopEdge">
                    <WidgetDim widget="__auto_titlebar__" dimension="BottomEdge" />
                </Dim>
                <Dim type="RightEdge">
                    <UnifiedDim scale="1" type="RightEdge">
                        <DimOperator op="Subtract">
                            <PropertyDim name="SizingBorderThickness" />
                        </DimOperator>
                    </UnifiedDim>
                </Dim>
                <Dim type="BottomEdge">
                    <UnifiedDim scale="1" type="BottomEdge">
                        <DimOperator op="Subtract">
                            <PropertyDim name="SizingBorderThickness" />
                        </DimOperator>
                    </UnifiedDim>
                </Dim>
            </Area>
        </Child>
        <Child type="WindowsLook/Titlebar" nameSuffix="__auto_titlebar__">
            <Area>
                <Dim type="LeftEdge">
                    <AbsoluteDim value="0" />
                </Dim>
                <Dim type="TopEdge">
                    <AbsoluteDim value="0" />
                </Dim>
                <Dim type="RightEdge">
                    <UnifiedDim scale="1" type="RightEdge" />
                </Dim>
                <Dim type="Height">
                    <FontDim widget="__auto_titlebar__" type="LineSpacing">
                        <DimOperator op="Multiply">
                            <AbsoluteDim value="1.5" />
                        </DimOperator>
                    </FontDim>
                </Dim>
            </Area>
            <Property name="AlwaysOnTop" value="False" />
        </Child>
        <Child type="WindowsLook/SystemButton" nameSuffix="__auto_closebutton__">
            <Area>
                <Dim type="LeftEdge">
                    <UnifiedDim scale="1" type="LeftEdge">
                        <DimOperator op="Subtract">
                            <AbsoluteDim value="0.5">
                                <DimOperator op="Multiply">
                                    <ImageDim imageset="WindowsLook" image="CloseButtonNormal" dimension="Width">
                                        <DimOperator op="Add">
                                            <WidgetDim widget="__auto_titlebar__" dimension="Height" />
                                        </DimOperator>
                                    </ImageDim>
                                </DimOperator>
                            </AbsoluteDim>
                        </DimOperator>
                    </UnifiedDim>
                </Dim>
                <Dim type="TopEdge">
                    <WidgetDim widget="__auto_titlebar__" dimension="Height">
                        <DimOperator op="Subtract">
                            <AbsoluteDim value="0.5">
                                <DimOperator op="Multiply">
                                    <WidgetDim widget="__auto_titlebar__" dimension="Height">
                                        <DimOperator op="Add">
                                            <ImageDim imageset="WindowsLook" image="CloseButtonNormal" dimension="Height" />
                                        </DimOperator>
                                    </WidgetDim>
                                </DimOperator>
                            </AbsoluteDim>
                        </DimOperator>
                    </WidgetDim>
                </Dim>
                <Dim type="Width">
                    <ImageDim imageset="WindowsLook" image="CloseButtonNormal" dimension="Width" />
                </Dim>
                <Dim type="Height">
                    <ImageDim imageset="WindowsLook" image="CloseButtonNormal" dimension="Height" />
                </Dim>
            </Area>
            <Property name="AlwaysOnTop" value="True" />
            <Property name="NormalImage" value="set:WindowsLook image:CloseButtonNormal" />
            <Property name="HoverImage" value="set:WindowsLook image:CloseButtonHover" />
            <Property name="PushedImage" value="set:WindowsLook image:CloseButtonPushed" />
        </Child>
        <ImagerySection name="withtitle_frame">
            <FrameComponent>
                <Area>
                    <Dim type="LeftEdge">
                        <AbsoluteDim value="0" />
                    </Dim>
                    <Dim type="TopEdge">
                        <WidgetDim widget="__auto_titlebar__" dimension="Height" />
                    </Dim>
                    <Dim type="RightEdge">
                        <UnifiedDim scale="1" type="RightEdge" />
                    </Dim>
                    <Dim type="BottomEdge">
                        <UnifiedDim scale="1" type="BottomEdge" />
                    </Dim>
                </Area>
                <Image type="BottomLeftCorner" imageset="WindowsLook" image="WindowFrameBottomLeft" />
                <Image type="BottomRightCorner" imageset="WindowsLook" image="WindowFrameBottomRight" />
                <Image type="LeftEdge" imageset="WindowsLook" image="WindowFrameLeft" />
                <Image type="RightEdge" imageset="WindowsLook" image="WindowFrameRight" />
                <Image type="BottomEdge" imageset="WindowsLook" image="WindowFrameBottom" />
            </FrameComponent>
        </ImagerySection>
        <ImagerySection name="notitle_frame">
            <FrameComponent>
                <Area>
                    <Dim type="LeftEdge">
                        <AbsoluteDim value="0" />
                    </Dim>
                    <Dim type="TopEdge">
                        <AbsoluteDim value="0" />
                    </Dim>
                    <Dim type="RightEdge">
                        <UnifiedDim scale="1" type="RightEdge" />
                    </Dim>
                    <Dim type="BottomEdge">
                        <UnifiedDim scale="1" type="BottomEdge" />
                    </Dim>
                </Area>
                <Image type="TopLeftCorner" imageset="WindowsLook" image="WindowFrameTopLeft" />
                <Image type="TopRightCorner" imageset="WindowsLook" image="WindowFrameTopRight" />
                <Image type="BottomLeftCorner" imageset="WindowsLook" image="WindowFrameBottomLeft" />
                <Image type="BottomRightCorner" imageset="WindowsLook" image="WindowFrameBottomRight" />
                <Image type="LeftEdge" imageset="WindowsLook" image="WindowFrameLeft" />
                <Image type="TopEdge" imageset="WindowsLook" image="WindowFrameTop" />
                <Image type="RightEdge" imageset="WindowsLook" image="WindowFrameRight" />
                <Image type="BottomEdge" imageset="WindowsLook" image="WindowFrameBottom" />
            </FrameComponent>
        </ImagerySection>
        <ImagerySection name="withtitle_withframe_client_area">
            <Colours topLeft="FFDFDFF5" topRight="FFDFEFF5" bottomLeft="FFF4F3F5" bottomRight="FFF0F0F5" />
            <ImageryComponent>
                <Area>
                    <Dim type="LeftEdge">
                        <ImageDim imageset="WindowsLook" image="WindowFrameLeft" dimension="Width" />
                    </Dim>
                    <Dim type="TopEdge">
                        <WidgetDim widget="__auto_titlebar__" dimension="Height" />
                    </Dim>
                    <Dim type="RightEdge">
                        <UnifiedDim scale="1" type="RightEdge">
                            <DimOperator op="Subtract">
                                <ImageDim imageset="WindowsLook" image="WindowFrameRight" dimension="Width" />
                            </DimOperator>
                        </UnifiedDim>
                    </Dim>
                    <Dim type="BottomEdge">
                        <UnifiedDim scale="1" type="BottomEdge">
                            <DimOperator op="Subtract">
                                <ImageDim imageset="WindowsLook" image="WindowFrameBottom" dimension="Height" />
                            </DimOperator>
                        </UnifiedDim>
                    </Dim>
                </Area>
                <Image imageset="WindowsLook" image="Background" />
                <VertFormat type="Stretched" />
                <HorzFormat type="Stretched" />
            </ImageryComponent>
        </ImagerySection>
        <ImagerySection name="notitle_withframe_client_area">
            <Colours topLeft="FFDFDFF5" topRight="FFDFEFF5" bottomLeft="FFF4F3F5" bottomRight="FFF0F0F5" />
            <ImageryComponent>
                <Area>
                    <Dim type="LeftEdge">
                        <ImageDim imageset="WindowsLook" image="WindowFrameLeft" dimension="Width" />
                    </Dim>
                    <Dim type="TopEdge">
                        <ImageDim imageset="WindowsLook" image="WindowFrameTop" dimension="Height" />
                    </Dim>
                    <Dim type="RightEdge">
                        <UnifiedDim scale="1" type="RightEdge">
                            <DimOperator op="Subtract">
                                <ImageDim imageset="WindowsLook" image="WindowFrameRight" dimension="Width" />
                            </DimOperator>
                        </UnifiedDim>
                    </Dim>
                    <Dim type="BottomEdge">
                        <UnifiedDim scale="1" type="BottomEdge">
                            <DimOperator op="Subtract">
                                <ImageDim imageset="WindowsLook" image="WindowFrameBottom" dimension="Height" />
                            </DimOperator>
                        </UnifiedDim>
                    </Dim>
                </Area>
                <Image imageset="WindowsLook" image="Background" />
                <VertFormat type="Stretched" />
                <HorzFormat type="Stretched" />
            </ImageryComponent>
        </ImagerySection>
        <ImagerySection name="withtitle_noframe_client_area">
            <Colours topLeft="FFDFDFF5" topRight="FFDFEFF5" bottomLeft="FFF4F3F5" bottomRight="FFF0F0F5" />
            <ImageryComponent>
                <Area>
                    <Dim type="LeftEdge">
                        <AbsoluteDim value="0" />
                    </Dim>
                    <Dim type="TopEdge">
                        <WidgetDim widget="__auto_titlebar__" dimension="Height" />
                    </Dim>
                    <Dim type="RightEdge">
                        <UnifiedDim scale="1" type="RightEdge" />
                    </Dim>
                    <Dim type="BottomEdge">
                        <UnifiedDim scale="1" type="BottomEdge" />
                    </Dim>
                </Area>
                <Image imageset="WindowsLook" image="Background" />
                <VertFormat type="Stretched" />
                <HorzFormat type="Stretched" />
            </ImageryComponent>
        </ImagerySection>
        <ImagerySection name="notitle_noframe_client_area">
            <Colours topLeft="FFDFDFF5" topRight="FFDFEFF5" bottomLeft="FFF4F3F5" bottomRight="FFF0F0F5" />
            <ImageryComponent>
                <Area>
                    <Dim type="LeftEdge">
                        <AbsoluteDim value="0" />
                    </Dim>
                    <Dim type="TopEdge">
                        <AbsoluteDim value="0" />
                    </Dim>
                    <Dim type="RightEdge">
                        <UnifiedDim scale="1" type="RightEdge" />
                    </Dim>
                    <Dim type="BottomEdge">
                        <UnifiedDim scale="1" type="BottomEdge" />
                    </Dim>
                </Area>
                <Image imageset="WindowsLook" image="Background" />
                <VertFormat type="Stretched" />
                <HorzFormat type="Stretched" />
            </ImageryComponent>
        </ImagerySection>
        <StateImagery name="ActiveWithTitleWithFrame">
            <Layer>
                <Section section="withtitle_frame">
                    <Colours topLeft="FFA7C7FF" topRight="FFA7C7FF" bottomLeft="FFA7C7FF" bottomRight="FFA7C7FF" />
                </Section>
                <Section section="withtitle_withframe_client_area" />
            </Layer>
        </StateImagery>
        <StateImagery name="InactiveWithTitleWithFrame">
            <Layer>
                <Section section="withtitle_frame">
                    <Colours topLeft="FFEFEFEF" topRight="FFEFEFEF" bottomLeft="FFEFEFEF" bottomRight="FFEFEFEF" />
                </Section>
                <Section section="withtitle_withframe_client_area" />
            </Layer>
        </StateImagery>
        <StateImagery name="DisabledWithTitleWithFrame">
            <Layer>
                <Section section="withtitle_frame">
                    <Colours topLeft="FFEFEFEF" topRight="FFEFEFEF" bottomLeft="FFEFEFEF" bottomRight="FFEFEFEF" />
                </Section>
                <Section section="withtitle_withframe_client_area" />
            </Layer>
        </StateImagery>
        <StateImagery name="ActiveWithTitleNoFrame">
            <Layer>
                <Section section="withtitle_noframe_client_area" />
            </Layer>
        </StateImagery>
        <StateImagery name="InactiveWithTitleNoFrame">
            <Layer>
                <Section section="withtitle_noframe_client_area" />
            </Layer>
        </StateImagery>
        <StateImagery name="DisabledWithTitleNoFrame">
            <Layer>
                <Section section="withtitle_noframe_client_area" />
            </Layer>
        </StateImagery>
        <StateImagery name="ActiveNoTitleWithFrame">
            <Layer>
                <Section section="notitle_frame">
                    <Colours topLeft="FFA7C7FF" topRight="FFA7C7FF" bottomLeft="FFA7C7FF" bottomRight="FFA7C7FF" />
                </Section>
                <Section section="notitle_withframe_client_area" />
            </Layer>
        </StateImagery>
        <StateImagery name="InactiveNoTitleWithFrame">
            <Layer>
                <Section section="notitle_frame">
                    <Colours topLeft="FFEFEFEF" topRight="FFEFEFEF" bottomLeft="FFEFEFEF" bottomRight="FFEFEFEF" />
                </Section>
                <Section section="notitle_withframe_client_area" />
            </Layer>
        </StateImagery>
        <StateImagery name="DisabledNoTitleWithFrame">
            <Layer>
                <Section section="notitle_frame">
                    <Colours topLeft="FFEFEFEF" topRight="FFEFEFEF" bottomLeft="FFEFEFEF" bottomRight="FFEFEFEF" />
                </Section>
                <Section section="notitle_withframe_client_area" />
            </Layer>
        </StateImagery>
        <StateImagery name="ActiveNoTitleNoFrame">
            <Layer>
                <Section section="notitle_noframe_client_area" />
            </Layer>
        </StateImagery>
        <StateImagery name="InactiveNoTitleNoFrame">
            <Layer>
                <Section section="notitle_noframe_client_area" />
            </Layer>
        </StateImagery>
        <StateImagery name="DisabledNoTitleNoFrame">
            <Layer>
                <Section section="notitle_noframe_client_area" />
            </Layer>
        </StateImagery>
    </WidgetLook>
</Falagard>


Test layout file

<?xml version="1.0" encoding="UTF-8"?>
<GUILayout>
<Window Type="DefaultGUISheet" Name="root">

    <Window Type="WindowsLook/NewFrameWindow" Name="myFrameWindow">
        <Property Name="UnifiedPosition" Value="{{0.1,0},{0.1,0}}" />
        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
        <Property Name="UnifiedMinSize" Value="{{0,128},{0,128}}" />
        <Property Name="UnifiedSize" Value="{{0.4,0},{0.5,0}}" />
        <Property Name="Text" Value="Demo of seperate client area." />

        <AutoWindow NameSuffix="__auto_clientarea__" >
            <Window Type="WindowsLook/Button" Name="myFrameWindow/Button1">
                <Property Name="UnifiedAreaRect" Value="{{0.02,0},{0.01,0},{0.98,0},{0.15,0}}" />
                <Property Name="Text" Value="A Button" />
            </Window>
            <Window Type="WindowsLook/Button" Name="myFrameWindow/Button2">
                <Property Name="UnifiedAreaRect" Value="{{0.04,0},{0.6,0},{0.96,0},{0.75,0}}" />
                <Property Name="Text" Value="Another Button" />
            </Window>
        </AutoWindow>

    </Window>
</Window>
</GUILayout>


Conclusion

In this article you have seen what an auto window is, how the system uses them "out of the box", and how you can utilise the same system to extend widgets to perform differently. You have also seen how to target these auto windows from c++ code and also from layout XML files.

CrazyEddie