MythUI Theme Development

From MythTV Official Wiki
Revision as of 22:02, 7 March 2009 by George Nassas (talk | contribs) (The textarea widget: Allcenter is a valid alignment.)

Jump to: navigation, search

Overview

As of MythTV version .22, the theme engine is much more flexible and robust. This guide will serve as a comprehensive reference for developing a MythTV theme, including documentation of all available MythTV widgets and the basic XML files that must be completed to have a working theme.

Terminology

Conceptually, MythTV themes are fairly simple. They are a series of XML theme files, and any associated media called by those files such as images. Within each XML theme file, individual screens in MythTV are defined as windows. Each window contains MythUI Widgets, and the widgets contain various attributes. Take this simple example of a MythUI theme file:

<mythuitheme>
    <window name="MyFirstWindow">
        <textarea name="MyFirstTextArea">
            <area>0,0,1280,720</area>
            <font>basesmall</font>
            <value>This is some text!</value>
        </textarea>
    </window>
</mythuitheme>

Let's discuss the code we just looked at. Every tag in XML must be opened and closed, just like in HTML. If you don't match all of your tags, your theme will not work! Every MythUI theme file (with one exception to be explained later) opens with the <mythuitheme> tag and ends with </mythuitheme>. Inside of the theme, we defined a window called "MyFirstWindow." Inside of that window, we created a textarea widget with three attributes, area, font, and value. How each of these things works will be explained in a bit, but this is the most basic kind of structure found in every themed screen in MythTV.

Inheritance

A key component of the MythUI theme engine is the concept of inheritance. As each widget has a name, every similar widget thereafter can inherit from that name. Take, for example, this basic definition of a font:

<font name="MyFirstFont" face="Frutiger LT Std">
    <size>16</size>
    <color>#FFFFFF</color>
</font>

Don't worry, we'll explain how all this works later. But to illustrate the concept of inheritance, let's say somewhere later in my theme you want to define another font, and you want it to be exactly the same as the one above, except for a different color. This is made incredibly simple through inheritance.

<font name="MyFirstFontBlack" from="MyFirstFont">
    <color>#000000</color>
</font>

The font we just defined inherits the face and size from the first one, but redefines the color! As our definitions become more and more complex, inheritance will save us tons of work!

Preassigned Names

So, you might be asking, "how do I tell MythTV which information goes into which box?" Well, in addition to being able to name your own widgets and place information wherever you like, each screen in myth has preassigned names that it expects to find and use to display information. As an example, there will be a textarea in the "Watch Recordings" screen called called title. This hook is what Myth is looking for to insert the title. Consider this example:

<textarea name="title" from="MyFirstTextArea">
    <area>100,200,300,50</area>
    <font>MyFirstFontBlack</font>
</textarea>

Now we're seeing several of the concepts we've discussed in action. We've created a textarea widget with a name of "title." "Title" is one of the preassigned names used in several screens in MythTV including the Video browser and the Watch Recordings screen, among others. Myth will intelligently insert the title value for an object or selected item into this text area since it's on the lookout for a text area called "title." We also see the use of inheritance here with from="MyFirstTextArea". In this example, our themer has defined a basic text area elsewhere called MyFirstTextArea, and wants to use the attributes he assigned there in this text area. Rather than assigning the face, size, shadow, outline, etc. all over again, he simply uses inheritance to pull all those definitions in to this text area. Finally, we see that the themer has used the font name we created above, MyFirstFontBlack.

Best Practices

It's important for both your sanity and code sharing to make your themes legible. The commonly used practice in Myth themes is to indent each nested tag four spaces (NOT a tab). So, the most simple example of this coding style is something like:

<textarea name="MyCodingStyleExample">
    <area>0,0,100,50</area>
    <font>MyFirstFontBlack</font>
    <value>Wow!  Look at how clean this is!</value>
</textarea>

From the above example, it's simple to see what attributes "belong" to which widget. It's also best to leave a blank space between each widget in your theme file so that they are independent logical units. Here's an example:

<textarea name="title" from="basetextarea">
    <area>20,10,710,80</area>
    <font>baselarge</font>
</textarea>
                
<textarea name="director" from="basetextarea">
    <area>160,65,350,35</area>
    <font>basesmallyellow</font>
</textarea>

If you keep these simple practices in mind when creating your theme, it will be much simpler for both you and those you share the theme with to understand how it works.

Creating your first MythUI Theme File

Let's go through the creation of the most basic of all MythTV theme files to reinforce our understanding of terminology and basic XML.

themeinfo.xml

The themeinfo is the one exception to the rule about all MythUI themes opening and closing with <mythuitheme>. The themeinfo uses the following format:

<themeinfo>
    <name>LoremIpsumTheme</name>
    <aspect>16:9</aspect>
    <author>
        <name>Loren J. Ipsum</name>
        <email>lorenj@ipsum.com</email>
    </author>

    <types>
        <type>UI</type>
    </types>

    <baseres>1920x1080</baseres>

    <version>
        <major>1</major>
        <minor>1</minor>
    </version>

    <detail>
        <thumbnail name="preview">preview.jpg</thumbnail>
        <description>We're defining a basic theme.  This is going to be fun!</description>
        <errata>Use this space for notes!</errata>
    </detail>
</themeinfo>

Let's briefly look at what each attribute in the themeinfo.xml file does.

<name>: This is the name of your theme as will be displayed in the theme selection menu.

<aspect>: This is the aspect ratio of your theme. Myth does not currently use this value for calculations, so this is purely informational.

<author>: This contains two subattributes, <name> and <email>. they provide identifying information about the theme's author(s).

<types>: This contains one subattribute, <type>. It defines what type of theme this is. There are three eligible types, UI, OSD, and menu. UI themes are overall myth themes. OSD themes govern the on-screen display during video playback. Menu themes define the tree structure of Myth's menus. A theme can contain multiple types (UI and OSD, UI and menu, etc.) and thus there can be multiple <type> definitions.

<baseres>: This is the value that myth uses to parse all the coordinates in your theme. It is the number of coordinates you are giving yourself to work with and the resolution you are targeting with your theme. We'll talk more about this later when talking about the <area> attribute.

<version>: This contains two subattributes, <major> and <minor>. They define the Major and Minor version numbers of your theme. In the example above, the version is defined as "1.1".

<detail>: This has three subattributes, <thumbnail>, <description>, and <errata>. <thumbnail> defines an image in your theme directory to act as a preview in the Theme selection dialog. <description> describes the theme. <errata> can be used for notes and license information for your theme.

If you've been following along, congratulations, you've finished your first Myth theme element!

MythUI Widget Types

In this section, we'll explore the widgets that you can use in a MythUI theme, and explain how each of them works. You'll see an example of each widget in action, and a discussion of the possible attributes and how they work.

Global Attributes

Before discussing individual widgets, let's discuss attributes which will apply to almost all of the widgets we will use.

name Each widget in MythUI must have a name defined in the widget's opening tag. It must be a unique name within the window. Names can be either hard-coded values (whose widget images or text will be filled dynamically by myth) or unique values assigned by the themer (whose widget images or text are statically assigned by the themer).
area The most commonly used attribute of any widget is <area>. As the name implies, it sets the location and size of a widget. <area> takes four arguments. They are:
<area>posx,posy,width,height</area>

Myth coordinates are calculated from the upper left corner of the screen (position 0,0). In our themeinfo.xml file, we defined the <baseres> attribute, which defines the screen space we intend to work with. This does not mean that it will only work on this resolution! It simply tells MythTV how to reckon the coordinates. On a 1280x720 theme, 128 pixels is 10% of the screen. If one were to use the theme on a 1920x1080 screen, Myth is intelligent enough to still place the item 10% across the screen. In short, baseres establishes the relative coordinate system that you intend to use in your theme, not a fixed resolution at which it will operate. So, to create a widget 500 pixels right of the top left, 200 pixels down, and with a size of 300x100, we would use:

<area>500,200,300,100<area>

In cases where area is defined for a sub-attribute, e.g. for an image within a button, the area is reckoned from the top-left of the parent attribute rather than the top-left of the screen.

position <position> is a lot like <area>, except it does not scale the widget. It looks like this:
<position>posx,posy</position>

Position might be used in a few circumstances. If you want to place an image on the screen, but leave it at native resolution, or if you want to place a widget on the screen, but use the size of the definition it inherits from, you might use position. Here's an example of the position tag placing a widget or image at location 650x400:

<position>650,400<position>
alpha <alpha> is a very exciting effect that affects the transparency/opacity of a widget or image. It uses the following format:
<alpha>number value 0-255</alpha>

<alpha> sets the transparency from 0 (totally transparent) to 255 (totally solid). This allows for great and subtle see-through effects. If you don't set an alpha value, the widget or image will be 100% opaque. Here's an example of an item set to 50% opacity:

<alpha>128</alpha>
alphapulse <alphapulse> is another exciting transparency/opacity effect that allows text or images to cycle through various levels of opacity. It uses the following format:
<alphapulse min="number value 0-255" max="number value 0-255"  change="number speed of cycling" />

You'll notice that alphapulse has a slightly different format than other XML or HTML-style tags. Since alphapulse takes multiple arguments, they're all built into the one tag, which indicates it has no paired tag by closing with "/>". Min is the minimum transparency value in the cycle. Max is the maximum transparency value in the cycle. Change sets the speed at which the cycling occurs. It is best to keep this value in single digits, or the pulse may become indistinguishable. Here is an example of a widget or image pulsing between half and full opacity with a slow, steady speed of change:

<alphapulse min="128" max="255" change="2"/>

Font definitions

While not specifically a widget, font definitions share much in common with widget definitions, and are thus included here. Here's a complete font definition:

<font name="normal" face="Arial">
    <size>11</size>
    <color>#ffffff</color>
    <shadowcolor>#000000</shadowcolor>
    <shadowoffset>2,2</shadowoffset>
    <shadowalpha>64</shadowalpha>
    <outlinecolor>#888888</outlinecolor>
    <outlinesize>2</outlinesize>
    <outlinealpha>64</outlinealpha>
    <bold>yes</bold>
    <italics>yes</italics>
    <underline>yes</underline>
</font>


face The font face is the Plain english name of a font installed on the system. The font can be installed systemwide, in the MythTV share directory, or in the root directory of your theme.
size Size is the font size used.
color Color is the hexadecimal value for the color of the font.
shadowcolor Shadowcolor is the hexadecimal color value used for the drop shadow behind the text.
shadowoffset Shadowoffset is the coordinate offset for the drop shadow. In our example, the drop shadow would be two pixels to the right, and two pixels down from the text.
shadowalpha Shadowalpha sets the opacity of the drop shadow, with a value from 0-255
outlinecolor Outlinecolor is a hexadecimal color value for an outline around the text.
outlinesize Outlinesize is the pixel radius of a text outline.
outlinealpha Outlinealpha sets the opacity of the text outline.
bold, italics, underline Bold, italics, and underline all have boolean values of yes or no and change the text in the expected fashion.

The textarea widget

An example of a textarea.

The textarea widget is the simplest widget in MythUI. It will place a text area on the screen which can either be filled by the themer or (by using the name= tag) dynamically filled by MythTV. For purposes of simplicity, let's look at all the attributes which can be used in a textarea widget and then discuss each one.

<textarea name="MyFirstTextArea">
    <area>x,y,w,h</area>
    <case>upper</case>
    <font>MyFirstFontBlack</font>
    <cutdown>yes</cutdown>
    <multiline>yes</multiline>
    <align>left,top</align>
    <colorcycle start="#000000" end="#ffffff" steps="255"/>
    <value>I've created my first widget!</value>
</textarea>

MythUI widgets are always opened with their widget type as the tag. So, we start our textarea widget and give it a name with <textarea name="MyFirstTextArea">. Let's look at each attribute.

area As explained above, this attribute sets the location and size of our text area. You could also use <position> if inheriting from another text area (by adding from="name ofothertextarea" to the textarea tag).
case This sets the capitalization of our text area. If not set, the text area will follow normal capitalization. Valid values are upper and lower.
font A font name as defined earlier in the same UI file or in base.xml. In our example, we are using MyFirstFontBlack which we discussed defining earlier.
cutdown If the textarea runs over the defined area, the cutdown attribute will truncate it with ellipsis, "...". If you are concerned that a value inserted by myth will be too long for the text area you have assigned, you may want to set cutdown to "yes". Default behavior is to not cut down text.
multiline The multiline attribute wraps text onto a new line if it runs out of space.
align Aligns the text in both horizontal and vertical directions. Valid values are: left, right, top, bottom, hcenter, vcenter, center and allcenter. Center and allcenter are synonyms..
colorcycle An attribute very like alphapulse, except the cycle is between colors instead of opacities. Colors in MythTV are always in hexadecimal format. The above example will cycle between white and black, with 255 steps in between. The cycling occurs at approximately 30 steps per second. Thus, our example will complete in just under eight seconds.
value Value is the attribute which sets the text to appear in the textarea. It is optional. In a text area which Myth is not filling in, it can be any text you wish to set. In a Myth-filled box, it will be the "fallback" value. If myth has no text to insert, the user will see this value instead. In a few instances, various variables can be inserted for the value to allow for compound text areas which include multiple pieces of information in a format of the themer's choosing, like %TITLE%, %SUBTITLE%, %DATE%, %STARS%, etc.

The imagetype widget

An example of a imagetype (with a mask, and another imagetype overlaid).

The imagetype widget is another very simple widget. It takes a filename as input, applies masks, crops, and other manipulations, and displays it on the screen. Just as with the textarea widget, certain hardcoded name values on certain screens can be dynamically filled by MythTV.

<imagetype name="MyFirstImage">
    <filename>imagefile.png</filename>
    <area>300,200,210,70>
    <alpha>150</alpha>
    <preserveaspect>true</preserveaspect>
    <crop>x,y,w,h</crop>
    <mask>mymaskfile.png</mask>
    <reflection axis="horizontal" shear="24" scale="85" length="35" />
    <grayscale>true</grayscale>

<!-- Animation attributes (used instead of filename or gradient)-->

    <filepattern low="0" high="30">imagefile%1.png</filepattern>
    <delay>500</delay>

<!-- Gradient attribute (used instead of filename or filepattern)-->

    <gradient start="#999999" end="#333333" alpha="255" />

</imagetype>

An imagetype widget must have (one of) a filename, filepattern, or gradient. All the other attributes are optional. An imagetype will also take all global attributes such as area, position, alpha, and alphapulse.

filename The filename attribute sets a filename for the image relative to the root of the theme directory. You can place an image in a subdirectory and include it in the filename value, like:
<filename>path/to/filename.png</filename>

As with the textarea widget, if the imagetype is dynamically filled by MythTV and there is a filename set, the file will be the "fallback" when Myth has no value to insert.

preserveaspect preserveaspect will scale the image to the size specified, but will retain the original aspect ratio by leaving empty space within the defined area. This option is excellent for posters with variable sizes and aspects, or places where both a screenshot or fixed image might appear.
crop Acrop, as evidenced by the name, crops the image to the specified x/y value, width, and height. This is useful for preview images which might have closed-captioning garbage.
mask mask allows a second image to be set to alpha-mask the original. This is a black and transparent image of identical size to the imagetype area, where black is visible and transparent will be masked. This allows for smooth edges and exotic shapes to your image. Masks cannot be resized or scaled.
reflection reflection is an attribute which casts a reflection of the imagetype along either the horizontal or vertical axis. Valid values for axis are horizontal and vertical. Shear is the angle of the reflection as a percentage value, from 0-100. Scale is the severity ("squishedness") of the reflection as a percentage value, from 0-100. Length is the size of the draw reflection compared to the size of the original image as a percentage value, from 0-100.
grayscale grayscale determines whether a colour image should be displayed as grayscale instead.
filepattern filepattern allows for simple flipbook animations. The low and high values define the first and last image numbers in a the series, and the "%1" in the filename is the place where the number variable is inserted. So, for a flipbook animation that cycles from myfile1.png to myfile99.png, the filepattern would look like:
<filepattern low="1" high="99">myfile%1.png</filepattern>
delay delay is the time interval between cels in your flipbook animation. It is an integer value and defines the speed at which the animation is cycled.
gradient gradient (predictably) creates a gradient rather than an image. It takes a start color value (in hexadecimal) and an end color value, as well as an alpha level from 0-255.

The statetype widget

The statetype widget is a special widget used for an image, button, or other element that behaves or looks differently according to its status. An example of a statetype would be a button item which can be either selected or unselected. Statetypes are also used in menu watermark images (discussed in the menu-ui.xml article). The most important new attribute introduced in the statetype is a state. Each state represents how a statetype behaves under a given condition.

<statetype name="blah">
    <area>10,10,100,100</area>
    <showempty>yes</showempty>
    <state name="selected">
        <position>20,15</position>
        <imagetype name="selectimage">
            <filename>selectimage.png</filename>
        </imagetype>
    </state>
    <state name="normal">
       <imagetype name="normalimage">
           <filename>normalimage.png</filename>
       </imagetype>
    </state>
</statetype>
state The state attribute defines the behavior of a single state in the statetype (which is a collection of states). Instead of name, some states use the type attribute. The names are unique depending on the context of the statetype. Commonly used state names are selected, unselected, active, and inactive. Type will always be on, off, half, or full. Which types are used depends on the context of the statetype. In the example, if the item were selected, the "selectimage.png" image would be displayed. If it were unselected, the "normalimage.png" image would be displayed. This is the simplest example of a statetype, but each state can has its own position, images, text, and virtually anything you can imagine!
showempty The showempty attribute specifies that any empty state should still be displayed (as empty).

The button widget

An example of a button (which is also an example of a statetype).

The button widget is the definition of an individual button item.

<button name="MyFirstButton">
    <position>0,0</position>
    <statetype name="buttonstate">
        <state name="active">
            <imagetype name="background">
                <area>0,0,150,35</area>
                <filename>buttonbackground.png</filename>
            </imagetype>
            <textarea name="text">
                <area>5,5,140,30</area>
                <align>allcenter</align>
                <font>basemedium</font>
                <font state="selected">basemedium</font>
                <font state="disabled">basemediumgrey</font>
            </textarea>
        </state>
        <state name="selected" from="active">
            <imagetype name="background">
                <area>0,0,150,35</area>
                <filename>buttonbackground_selected.png</filename>
                <alphapulse min="200" max="255" change="1"/>
            </imagetype>
        </state>
        <state name="disabled" from="active" />
        <state name="pushed" from="active">
            <imagetype name="background">
                <area>0,0,150,35</area>
                <filename>buttonbackground.png</filename>
                <alpha>255</alpha>
            </imagetype>
            <textarea name="text">
                <position>8,8</position>
            </textarea>
        </state>
    </statetype>
</button>

After all of that text, there is absolutely nothing new about a button! No special attributes, no new material. The button widget contains a single statetype, buttonstate. The statetype contains four states, active, selected, disabled, and pushed. active is a unselected button in an active buttonlist. selected is the selected item in an active buttonlist. disabled is an unselected button in an inactive button list or a "greyed out" button. pushed is the "down" state of a button (mid-push). Each state must contain (or inherit) the textarea text.

You may notice above the use of inheritance and the use of states in a font declaration. These font states carry over into the following state attributes and change the fonts of each type accordingly.

button statetypes

Statetype Name Included States Optional named attributes:
buttonstate active textarea - text
selected textarea - text
disabled textarea - text
pushed textarea - text

The buttonlist widget

An example of a buttonlist.

The buttonlist widget is a series of dynamically-filled buttons. It is one of the most commonly used of all widgets, and is primarily built out of other widgets.

<buttonlist name="MyFirstButtonlist">
    <area>0,0,349,250</area>
    <layout>vertical</layout>
    <spacing>3</spacing>
    <scrollstyle>free</scrollstyle>
    <wrapstyle>items</wrapstyle>
    <buttonarea>0,0,100%,97%</buttonarea>
    <statetype name="buttonitem">
        <state name="active">
            <area>0,0,100%,30</area>
            <imagetype name="buttonbackground">
                <filename>buttonbackground.png</filename>
            </imagetype>
            <textarea name="buttontext">
                <area>5,10,85%,30</area>
                <font>basesmall</font>
                <cutdown>yes</cutdown>
                <align>left,vcenter</align>
            </textarea>
            <statetype name="buttoncheck">
                <position>91%,5</position>
                <state type="off">
                    <imagetype name="checkoff">
                        <filename>lb-check-empty.png</filename>
                    </imagetype>
                </state>
                <state type="half">
                   <imagetype name="checkhalf">
                        <filename>lb-check-half.png</filename>
                    </imagetype>
                </state>
                <state type="full">
                    <imagetype name="checkfull">
                        <filename>lb-check-full.png</filename>
                    </imagetype>
                </state>
            </statetype>
            <imagetype name="buttonarrow">
                <position>92%,11</position>
                <filename>rightarrow.png</filename>
            </imagetype>
        </state>
        <state name="selected" from="active">
            <imagetype name="buttonbackground">
                <filename>buttonbackground_selected.png</filename>
                <alphapulse min="200" max="255" change="1"/>
            </imagetype>
        </state>
        <state name="inactive" from="active">
            <imagetype name="buttonbackground">
                <filename>buttonbackground_selected.png</filename>
                <alpha>127</alpha>
            </imagetype>
            <textarea name="buttontext">
                <font>basesmallgrey</font>
            </textarea>
        </state>
    </statetype>
    <statetype name="upscrollarrow">
        <position>10,97%</position>
        <state type="off">
            <imagetype name="upon">
                <filename>uparrow.png</filename>
                <alpha>90</alpha>
            </imagetype>
        </state>
        <state type="full">
            <imagetype name="upoff">
                <filename>uparrow.png</filename>
            </imagetype>
        </state>
    </statetype>
    <statetype name="downscrollarrow">
        <position>40,97%</position>
        <state type="off">
            <imagetype name="dnon">
                <filename>downarrow.png</filename>
                <alpha>90</alpha>
            </imagetype>
        </state>
        <state type="full">
            <imagetype name="dnoff">
                <filename>downarrow.png</filename>
            </imagetype>
        </state>
    </statetype>
</buttonlist>

A buttonlist is an extremely commonly used widget. It is a series of buttons which are dynamically filled depending on their context. It is also one of the most complicated widget structures in MythUI. A buttonlist widget contains the following structure, which is largely self-explanatory. The checkoff, checkhalf, and checkfull states pertain to those buttons which contain checkboxes (like in the MythMusic playlist).

layout Valid values for layout in a buttonlist are horizontal, vertical, and grid.
spacing Spacing is an attribute to set a pixel value to reserve between each button in a button list.
scrollstyle Scrollstyle sets the scrolling behavior of the buttonlist. Valid options are center (selected item is always in the center) and free Selector freely moves through the list.
wrapstyle Wrapstyle sets the wrapping behavior of the buttonlist. Valid options are items (scrolling past the last item scrolls to the first and vice versa), selection and none (no wrap).

buttonlist statetypes

Statetype Name Included States Sub-statetype (if any) Included States
buttonitem active buttoncheck checkoff
checkhalf
checkfull
selected buttoncheck checkoff
checkhalf
checkfull
inactive buttoncheck checkoff
checkhalf
checkfull
upscrollarrow full
off
downscrollarrow full
off

Additionally, each state in buttonitem can take a textarea named buttontext for the button's text and an imagetype called buttonarrow to indicate the button contains a submenu.

The buttontree widget

An example of a buttontree.

The buttontree widget is essentially a wrapper widget to contains a pre-set number of buttonlists. It is used in various places, notably the MythVideo List View.

<buttontree name="MyFirstButtontree">
    <area>20,347,1240,266</area>
    <numlists>3</numlists>
    <spacing>6</spacing>
    <buttonlist name="listtemplate" from="basebuttonlist" />
</buttontree>
The buttontree contains a buttonlist item named listtemplate.
numlist The numlist attribute sets the number of buttonlists to be laid out horizontally.
spacing The spacing attribute sets a number of buffer pixels between each buttonlist.

The textedit widget

We've discussed how to display text, but how do we accomplish text entry? The answer is through use of the textedit widget.

<textedit name="MyFirstTextEdit">
    <area>0,0,287,28</area>
    <statetype name="background">
        <state name="active">
            <imagetype name="background">
                <filename>textedit_background.png</filename>
            </imagetype>
        </state>
        <state name="selected">
            <imagetype name="background">
                <filename>textedit_background_selected.png</filename>
            </imagetype>
        </state>
        <state name="inactive">
            <imagetype name="background">
                <filename>textedit_background.png</filename>
            </imagetype>
        </state>
    </statetype>
    <imagetype name="cursor">
        <filename>cursor.png</filename>
    </imagetype>
    <textarea name="text">
        <area>3,5,281,22</area>
        <font>basesmallblack</font>
    </textarea>
</textedit>

Again we see that complicated widgets are actually just collections of simple widgets. The textedit widget includes a statetype named background. The statetype contains three states named active, selected, and inactive. active is a functional but not highlighted textedit widget. selected is an active, highlighted textedit widget. inactive is a "greyed out" or unusable textedit widget.

We complete the widget by defining an imagetype for the cursor in the textarea called cursor, and a textarea called text for where the actual text will be entered.

textedit statetypes

Statetype Name Included States
background active
selected
inactive


The checkbox widget

The checkbox widget is the definition of a checkbox.

<checkbox name="MyFirstCheckBox">
    <area>0,0,30,30</area>
    <statetype name="background">
        <state name="active">
            <imagetype name="background">
                <filename>unchecked.png</filename>
            </imagetype>
        </state>
        <state name="selected">
            <imagetype name="background">
                <filename>checkbox_background_selected.png</filename>
            </imagetype>
        </state>
        <state name="disabled" />
    </statetype>
    <statetype name="checkstate">
        <area>0,0,30,30</area>
        <state type="off" />
        <state type="half">
            <imagetype name="background">
                <filename>checked_selected.png</filename>
            </imagetype>
        </state>
        <state type="full">
            <imagetype name="mark">
                <filename>checked.png</filename>
            </imagetype>
        </state>
    </statetype>
</checkbox>

Yet another widget built out of less complicated widgets. The checkbox widget starts by defining a statetype called background. background contains three states, active, selected and disabled. Active is a functional checkbox which is not highlighted. Selected is a functional, highlighted checkbox. Disabled is a non-functional "greyed out" checkbox.

checkbox contains a second statetype called checkstate. This is a set of three states to indicate the fill status of the checkbox. The states are off, half and full. Off is a completely unfilled checkbox. Half is a half-checked box. Full is a fully checked checkbox. Note that the background statetype uses "name" states and the checkstate statetype uses "type" states as discussed above in statetype.

checkbox statetypes

Statetype Name Included States
background active
selected
disabled
checkstate off
half
full


The spinbox widget

The spinbox widget is the definition of a spinbox. A spinbox is a selection box containing multiple values which can be scrolled through. A spinbox is just a special type of buttonlist with helper functions to fill it with dynamic values.

<spinbox name="MyFirstSpinBox">
    <area>0,0,90,40</area>
    <layout>horizontal</layout>
    <statetype name="buttonitem">
        <state name="active">
            <area>0,0,70,40</area>
            <imagetype name="buttonbackground">
                <filename>spinbox_background.png</filename>
            </imagetype>
            <textarea name="buttontext">
                <area>5,5,55,30</area>
                <font>basesmall</font>
                <cutdown>yes</cutdown>
                <align>right,vcenter</align>
            </textarea>
        </state>
        <state name="selected" from="active">
            <imagetype name="buttonbackground">
                <filename>spinbox_background_selected.png</filename>
            </imagetype>
        </state>
        <state name="inactive" from="active">
            <imagetype name="buttonbackground">
                <filename>spinbox_background_inactive.png</filename>
            </imagetype>
        </state>
    </statetype>
    <statetype name="downscrollarrow">
        <position>75,2</position>
        <state type="off">
            <imagetype name="dnon">
                <filename>lb-rtarrow-reg.png</filename>
            </imagetype>
        </state>
        <state type="full">
            <imagetype name="dnoff">
                <filename>lb-rtarrow-sel.png</filename>
            </imagetype>
        </state>
    </statetype>
    <statetype name="upscrollarrow">
        <position>75,21</position>
        <state type="off">
            <imagetype name="upon">
                <filename>lb-ltarrow-reg.png</filename>
            </imagetype>
        </state>
        <state type="full">
            <imagetype name="upoff">
                <filename>lb-ltarrow-sel.png</filename>
            </imagetype>
        </state>
    </statetype>
</spinbox>

No new elements in the spinbox. It can have a <layout> of horizontal (right and left keys scroll through values) or vertical (up and down keys scroll through values). The spinbox contains three statetypes named buttonitem (the button itself), downscrollarrow (the down arrow) and upscrollarrow (the up arrow). buttonitem contains three states, active (available but not highlighted), selected (available and highlighted) and inactive (unavailable, unhighlighted). Each state in buttonitem should contain (or inherit) a buttontext textarea. upscrollarrow and downscrollarrow each contain two states (using the type= attribute), full and off.

spinbox statetypes

Statetype Name Included States State must contain:
buttonitem active textarea - buttontext
selected textarea - buttontext
inactive textarea - buttontext
upscrollarrow full
off
downscrollarrow full
off

The progressbar widget

The progressbar widget defines exactly what it sounds like, a progress bar when loading screens, for the web browser, et cetera.

    <progressbar name="MyFirstProgressbar">
        <area>0,0,10,10</area>
        <layout>horizontal</layout>
        <style>reveal</style>
        <imagetype name="background">
            <filename>progressbar_background.png</filename>
        </imagetype>
        <imagetype name="progressimage">
            <filename>progressbar_fill.png</filename>
        </imagetype>
    </progressbar>
layout A progressbar can be laid out as horizontal and vertical.
style The style attribute sets the type of progressbar. The options are reveal and slide. Reveal places the progressimage imagetype onscreen, but invisible, and reveals it as the item loads. Slide puts slides the progressimage imagetype into the area as the item loads.

The progressimage imagetype must be defined.

The clock widget

An example of a clock (composited with a few imagetypes).

The clock widget allows you to put a clock showing the system time in your theme. It takes all of the global attributes, font definitions, and behaves otherwise like a normal textarea, except it allows the themer to set the time format.

<clock name="clock">
    <area>565,700,158,25</area>
    <font>clock</font>
    <format>%DATE%, %TIME%</format>
    <secondflash>yes</secondflash>
    <align>center</align>
    <alpha>255</alpha>
</clock>
format The format attribute allows the themer to set the time format. Valid options are %TIME%, %DATE%, and %SHORTDATE%.
secondflash The secondflash attribute sets whether or not the colon in the clock flashes every second. Valid options are yes and no. Default behavior is not to flash.

The webbrowser widget

An example of a webbrowser widget (as used in mythbrowser).

The webbrowser widget allows you to embed a web browser window in most Myth screens. Note that Qt's embedded WebKit browser is fairly limited at this time, and Flash/plugin based windows will not work. HTML and most javascript will work.

<webbrowser name="MyFirstWebBrowser">
    <area>500,200,300,300</area>
    <url>http://www.google.com/</url>
    <zoom>1.4<zoom>
    <background color="#000000" alpha="255" />
</webbrowser>
url The url attribute specifies the web address to open in the widget.
zoom The zoom attribute magnifies the page in the widget. 1.0 is the default, non-zoomed value.
background The background attribute sets the background color for any page without one explicitly set. It takes a hexadecimal color for "color" and an integer value from 0-255 for "alpha."

Required MythUI Theme Files

base.xml

The base.xml file is the first file loaded by your theme. The base.xml file is the core definitions for each widget in your theme. Here you will define popup menus, font names, progress bars, dropdown menus, and all the other basic widgets used in the Myth UI. The base.xml file is a fantastic place to put all the definitions you intend to use later, which you can then call by name.

Optional MythUI Theme Files

browser-ui.xml

The browser-ui.xml file governs the layout and behavior of the MythBrowser Plugin and its associated settings screens.

gallery-ui.xml

The gallery-ui.xml file governs the layout and behavior of the MythGallery Plugin and its associated settings screens.

movies-ui.xml

The movies-ui.xml file governs the layout and behavior of the MythMovies Plugin and its associated settings screens.

news-ui.xml

The news-ui.xml file governs the layout and behavior of the MythNews Plugin and its associated settings screens.

video-ui.xml

The video-ui.xml file governs the layout and behavior of the MythVideo Plugin and its associated settings screens.

Testing Your Theme

During development it's helpful to make iterative changes and observe the results without having to exit and restart the frontend each time. You can trigger a theme reload by sending the USR1 signal to a mythfrontend process. On Linux this is as easy as:

kill -USR1 $(pidof mythfrontend)

This feature became available with version .21.

Alternatively, you may bind a key to the RELOADTHEME jump point using the Edit Keys menu.