This project is read-only.

FlatGuiVisualizer

The FlatGuiVisualizer renders your control tree to the screen using a plain old SpriteBatch. The looks of the GUI are controlled by a skin that is defined through an XML file using a very simple format that should allow anyone to customize a GUI design without even reading this page ;)

SuaveSkinGui.png

Skin file format

The skins are checked against a schema upon loading, so you will immediately know when you break something instead of getting a silent failure later on.

All skins declare the resources they use in a special 'resources' section:
<?xml version="1.0" encoding="utf-8" ?>
<skin
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="skin.xsd"
  name="MySkin"
>

  <!--
    Resources used to draw GUI elements using this skin
  -->
  <resources>
    <font name="MyDefaultFont" contentPath="Content/Fonts/MyFont" />
    <bitmap name="MySkinBitmap" contentPath="Content/Bitmaps/MySkin" />
  </resources>

  <!-- ...more... -->

</skin>

The <skin /> tag is mandatory and encloses the whole skin definition, but that's about all it does. Next, you can see the <resources /> section, where a <font /> and a <bitmap /> are defined. Both are assigned a name of your choice (this name is needed later on in the file for referring to the resource) and a path from which they can be loaded. These paths are passed on to the FlatGuiVisualizer's ContentManager, so in this example, you would have to add a MyFont.spritefont and MySkin.png to your game's Content project (just like you would if you wanted to use those assets yourself).

Next is the <frames /> element, which describes how your controls should look:
<?xml version="1.0" encoding="utf-8" ?>
<skin
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="skin.xsd"
  name="MySkin"
>

  <!-- ...resources... -->

  <frames>

    <!-- Frame used for a pushbutton in its normal state -->
    <frame name="button.normal">
      <!-- ...more... -->
    </frame>

    <!-- Frame used to draw a vertical rail for a scroll bar -->
    <frame name="rail.vertical">
      <!-- ...more... -->
    </frame>

    <!-- Frame used to draw a vertical slider on a scroll bar -->
    <frame name="slider.vertical.normal">
      <!-- ...more... -->
    </frame>

  </frames>

</skin>

The smallest graphical building block for the FlatGuiVisualizer is the ''frame''. A frame basically works like a bitmap, but when you stretch it, it will not simply resize but instead keep its border intact and only stretch its center area. Check your browser window: when you resize it, the title bar will not become larger or smaller, nor will the window borders. So the borders have a fixed size, while the window's inner area changes in size. Frames are like that.

Frames have a upper-left-corner bitmap, an upper-border bitmap, an upper-right-corner bitmap, a center bitmap and so on. But these bitmaps aren't mandatory. You can make a frame that only has a center bitmap, therefore stretching in its whole without borders. Or you can make a frame that consists of the upper-left-corner bitmap only, meaning it will never be resized.

Frames also define places where text should be rendered onto them. For example, a window frame might place its text in the title bar area and a button frame would make the text appear in its center.

A control is built from one or more frames. A button, for example, needs only one frame, whereas a scroll bar already needs four: one for the up-arrow, one for the down-arrow, one for the background and one for the movable slider.
<?xml version="1.0" encoding="utf-8" ?>
<skin
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="skin.xsd"
  name="MySkin"
>

  <!-- ...resources... -->

  <frames>

    <!-- Frame used for a pushbutton in its normal state -->
    <frame name="button.normal">
      <region source="MySkinBitmap" hplacement="left" vplacement="top" x="1" y="62" w="4" h="4" />
      <region source="MySkinBitmap" hplacement="stretch" vplacement="top" x="5" y="62" w="11" h="4" />
      <region source="MySkinBitmap" hplacement="right" vplacement="top" x="16" y="62" w="3" h="4" />
      <region source="MySkinBitmap" hplacement="left" vplacement="stretch" x="1" y="66" w="4" h="6" />
      <region source="MySkinBitmap" hplacement="stretch" vplacement="stretch" x="5" y="66" w="11" h="6" />
      <region source="MySkinBitmap" hplacement="right" vplacement="stretch" x="16" y="66" w="3" h="6" />
      <region source="MySkinBitmap" hplacement="left" vplacement="bottom" x="1" y="72" w="4" h="3" />
      <region source="MySkinBitmap" hplacement="stretch" vplacement="bottom" x="5" y="72" w="11" h="3" />
      <region source="MySkinBitmap" hplacement="right" vplacement="bottom" x="16" y="72" w="3" h="3" />
      <text font="MyDefaultFont" hplacement="center" vplacement="center" color="#000000" />
    </frame>

  </frames>

</skin>

As you can see, a <frame /> contains <region /> and <text /> elements to tell the FlatGuiVisualizer where bitmaps and text should be rendered into the frame.

The source attribute of the <frame /> elements is a reference to the resource name we assigned earlier in the skin file. The hplacement and vplacement attributes describe where the bitmap should be put in the frame. Each axis can either name a side the bitmap should dock to or stretch to make the bitmap stretch to match the frame's size in that dimension. The x, y, w and h attributes tell the FlatGuiVisualizer where to find the bitmap on the skin image.

For fast rendering, you want to add all the bitmaps used in your frames to one large skin image so that the GraphicsDevice can render everything in one go (using different texture coordinates to blit the different bitmaps) instead of having switch forth and back between different skin images.

The <text /> element works very similar, its font attribute references the font name you assigned to a font earlier in your skin file. Text color is controlled exclusively by the frame to give the artist complete control over the GUI's colors instead of spreading the visual design between code and skin file.

Last edited Sep 21, 2009 at 8:57 AM by Cygon, version 5

Comments

kingcoyote Aug 4, 2013 at 8:26 PM 
This documentation appears to be incorrect. While trying to set up a FlatGuiVisualizer, I kept getting an exception regarding the MySkinBitmap file not being found. After poking around for a bit, I saw that it was looking at "Content/Content/Bitmaps/MySkin.xnb". When I adjusted the xml file to remove Content from the file location, it worked.

It seems as though it is assuming Content as the root folder, and adding Content in your xml will only confuse it.