New Theme Engine
From SkyOS
Contents
|
Themeing
The SkyOS Theme engine is very powerful, making it possible to theme almost every widget, using freeform windows with any shape, full or partial transparency, translucent windows, etc.
In SkyOS, Themeing can be done in two different ways.
- You can either create a complete new Theme DLL and do the entire drawing of all themeable parts yourself using the SkyGI C++ API.
- You can use the Style Theme which itself is highly customizable using Theme settings files which can be edited with the DataCollectionEditor and a collection of Images. Using this method you can fully theme SkyOS, without the need to write even a single line of source code.
This document will handle the second case, when using the Style Theme, only.
Settings
Every theme must have a DataCollection file called Content.
This DataCollection contains name of actual setting files, which are also just DataCollections, inside the same directory.
This DataCollection files contain the actual theme settings. By using multiple DataCollections it is very easy to just exchange the look of single components.
Create a new Theme
- Copy /boot/system/plugins/themes/styles/windui to a new folder, e.g. Copy /boot/system/plugins/themes/styles/macos.
It is important that you copy an already existing working theme, else SkyGI will refuse to load it.
- Modify /boot/system/plugins/themes/styles/macos/Content, /boot/system/plugins/themes/styles/macos/Settings*and the images as you desire.
Testing
By default, every application starts with the Style Theme and the WindUI theme style applied. You can use a different theme styles for an application by specifing the THEME environment variable. For instance, if you have created a new theme style folder called 'macos', open a terminal and simply type:
export THEME=macos ./myapp
Transparency
The transparency for various themeable parts like the window border, titlebar, buttons, ... comes directly from the bitmap itself. So if you use a 32bpp .ICO image for lets say the TitleBar you can make it transparent using the alpha value. (transparency can be applied for each individual pixel from 0 (opaque) to 255 (fully transparent))
MS Visual Styles
The SkyOS Theme Engine is very similar to Microsofts Visual Styles (e.g. the XP and Vista Theme data). Using ResBuild you can open such windows styles and even extract bitmaps and settings which can be used by SkyOS.
Images
All images are .ICO 32bit images. Many image files contain multiple images. Although .PNG, .JPG, .GIF and .BMP could be used too, .ICO image files are the fastest to parse and display. (additionally you can store multiple images inside one .ICO file, which is also required)
Theme configuration description
Brush object
A Brush object is used at various places and defines a SkyGI C++ BrushAssembly object which is used to draw either a border or the background.
Properties
| Key | Details |
|---|---|
| Type | Specifies the brush type which can either by 'Solid' or 'Image' |
| SolidColor | If the brush type is solid this property defines the actual color |
| Image | Specifies the path to the image to use if type is set to 'Image' |
| SizingType | 'Stetch', 'Tile' or 'Fixed'. Only used if background type is 'Image' |
| SizingMargins | Specifies the margin used when the image must be resized. (left, top, right, bottom). This is used to only strech or tile the content and correctly draw the border. Internally
the Brush.Image will be splitted to either three or nine images, used to correctly draw the border and optionally fill the content. (See Fill Property) |
| Width | Specifies the width for a Solid brush. (If Fill is false the Width is used to draw a border with a width of Brush.Width pixels. Has no effect if type is Image |
| Fill | Specifies if the brush should be used to fill. If Fill is false, only the border (width == Brush.Image for Solid brushes, width == SizingMargins for Image brushes) gets drawn. |
Frame Window
Description
The FrameWindow defines to outer frame of a "normal" window, this is a window having a Border, a TitleBar and an optional StatusBar. The FrameWindow Border consists of at least three images, one for the left, one for the right and one for the bottom border. The top border (the TitleBar) gets defined by the TitleBar properties. (The reason why there is one bitmap for each border side is performance only. Although technically it would be possible to use a single image with margin splits, it would be rather slow too. By using three images the CPU amount required to compute the border images is minimal).
Properties
| Key | Additional States | Details |
|---|---|---|
| FrameWindow.Border.Left.Brush | inactive | Brush used to draw the left side of the window frame |
| FrameWindow.Border.Left.ContentSize | Specifies the width of pixels the border should be painted to with this brush. The not affected region will be drawn with the general FrameWindow brush | |
| FrameWindow.Border.Left.Width | Specifies the width of the border | |
| FrameWindow.Border.Left.Transparent | If set, the frame will be drawn using alpha blit. (This means that the frame can be made transparent or have partial transparency as alpha values) | |
| FrameWindow.Border.Right.Brush | inactive | Brush used to draw the right side of the window frame |
| FrameWindow.Border.Right.ContentSize | Specifies the width of pixels the border should be painted to with this brush. The not affected region will be drawn with the general FrameWindow brush | |
| FrameWindow.Border.Right.Width | Specifies the width of the border | |
| FrameWindow.Border.Right.Transparent | If set, the frame will be drawn using alpha blit. (This means that the frame can be made transparent or have partial transparency as alpha values) | |
| FrameWindow.Border.Bottom.Brush | inactive | Brush used to draw the bottom side of the window frame |
| FrameWindow.Border.Bottom.ContentSize | Specifies the width of pixels the border should be painted to with this brush. The not affected region will be drawn with the general FrameWindow brush | |
| FrameWindow.Border.Bottom.Width | Specifies the width of the border | |
| FrameWindow.Border.Bottom.Transparent | If set, the frame will be drawn using alpha blit. (This means that the frame can be made transparent or have partial transparency as alpha values) | |
| FrameWindow.Background.Brush | inactive | Brush used to draw the background the window frame |
| FrameWindow.Background.InnerFrame.Margin | Not used yet | |
| FrameWindow.Background.InnerFrame.SolidColor | Color of the inner frame (which seperates the view from the border, titlebar, menu and statusbar) | |
| FrameWindow.MinimumSize.Width | The minimum width an application window (which has a default frame and a titlebar) should have | |
| FrameWindow.MinimumSize.Height | The minimum height an application window (which has a default frame and a titlebar) should have | |
| FrameWindow.Thin.SolidColor | Specifies the color to use for thin frame windows (e.g. PopupMenu) | |
| FrameWindow.MiscColor | Color which can be used by applications to draw elements matching the framecolor as best as possible. (e.g. can be used to draw elements in solid gray if the frame consists of gray images only) |
TitleBar
Description
Properties
| Key | Additional States | Details |
|---|---|---|
| TitleBar.Background.Brush | inactive | Brush used to draw the background of the titlebar |
| TitleBar.Height | Specifies the height of the titlebar | |
| TitleBar.Transparent | If set, the titlebar will be drawn using alpha blit. (This means that the titlebar can be made transparent or have transprency as alpha values) | |
| TitleBar.Caption.Background.Brush | inactive | Brush used to draw the background of the caption in the titlebar |
| TitleBar.Caption.TextColor | inactive | TextColor to use the the windows title |
| TitleBar.Caption.Height | inactive | Height of the title |
| TitleBar.Caption.Align | Specifies where to align the title caption (this includes the actual caption background and text) | |
| TitleBar.Caption.Margin | Specifies the margin used for the caption background | |
| TitleBar.Caption.TextMargin | Specifies the margin used for the text inside the caption background | |
| TitleBar.Caption.Font.File | inactive | Font file to use for the title |
| TitleBar.Caption.Font.Size | inactive | Font size to use for the title |
| TitleBar.Icons.Width | Width for each icon (including an optional gap, can be larger than actual icon) | |
| TitleBar.Icons.Align | Specifies where to align the icons | |
| TitleBar.Icons.Margin | Specifies the margin used for the icons (offset from border or caption background) | |
| TitleBar.Icon.Close.Image | Specifies Image File with various icons in it, in following order: inactive rest, active rest, inactive hover, active hover, inactive pressed, active pressed | |
| TitleBar.Icon.Max.Image | Specifies Image File with various icons in it, in following order: inactive rest, active rest, inactive hover, active hover, inactive pressed, active pressed | |
| TitleBar.Icon.Min.Image | Specifies Image File with various icons in it, in following order: inactive rest, active rest, inactive hover, active hover, inactive pressed, active pressed | |
| TitleBar.Icon.Help.Image | Specifies Image File with various icons in it, in following order: inactive rest, active rest, inactive hover, active hover, inactive pressed, active pressed |
ClientWindow
Description
Properties
| Key | Additional States | Details |
|---|---|---|
| ClientWindow.Brush | Brush used to draw the background of client windows |
StatusBar
Description
Properties
| Key | Additional States | Details |
|---|---|---|
| StatusBar.Brush | (inactive) | Brush used to draw the background of the statusbar |
| StatusBar.Height | Specifies the height of the StatusBar | |
| StatusBar.Grip.Image | Image used to draw the resize grip. (will be drawn right/top aligned always) | |
| StatusBar.Transparent | (inactive) | If set, the statusbar will be drawn using alpha blit. (This means that the statusbar can be made transparent or have partial transparency as alpha values) |
ProgressBar
Description
Properties
| Key | Additional States | Details |
|---|---|---|
| ProgressBar.Border.Brush | Brush used to draw the border | |
| ProgressBar.Brush | Brush used to draw the actuall progress bar. (inside the border) | |
| ProgressBar.Margin | Margin used to offset the progress bar inside the border | |
| ProgressBar.Height | Height of the progress bar |
EditFields
Description
Properties
| Key | Additional States | Details |
|---|---|---|
| Edit.Brush | Brush used to draw the border and background of edit fields |
Button
Description
Properties
| Key | Additional States | Details |
|---|---|---|
| Button.Brush | (down) (focus) | Brush used to draw the border and background for buttons |
| Button.Height | Height of the button |
ScrollBar
Description
Properties
| Key | Additional States | Details |
|---|---|---|
| ScrollBar.Background.Brush | (vertical) (horizontal) | Brush used to draw the background for scrollbar (including the frame) |
| ScrollBar.Indicator.Brush | (vertical) (horizontal) | Brush used to draw the indicator for scrollbar (including the frame) |
| ScrollBar.Button.Brush | (top) (left) (right) (bottom) | Brush used to draw the left, top, right, bottom buttons (including the frame) |
| ScrollBar.Size | Size of the scrollbar (width for vertical and height for horizontal scrollbars) |
ListView
Description
Properties
| Key | Additional States | Details |
|---|---|---|
| ListView.Border.Brush | Brush used to draw the background and border for the ListView |
Splitter
Description
Properties
| Key | Additional States | Details |
|---|---|---|
| Splitter.Grip.Image | (vertical) (horizontal) | Defines the Splitter Grip Image |
TreeView
Description
Properties
| Key | Additional States | Details |
|---|---|---|
| TreeView.Image | (expanded) (collapsed) | Defines the Image for nodes expanded/collapsed state |
Menu
Description
Properties
| Key | Additional States | Details |
|---|---|---|
| Menu.ChildArrow.Image | Defines the image used to draw the child menu indicator for popup menus |
CheckBox
Description
Properties
| Key | Additional States | Details |
|---|---|---|
| CheckBox.Image | An image file with four images in it for each state. (rest, clicked, rest/inactive, clicked/inactive) |
RadioButton
Description
Properties
| Key | Additional States | Details |
|---|---|---|
| RadioButton.Image | An image file with two different radiobutton images (rest, clicked) |
Group
Description
Properties
| Key | Additional States | Details |
|---|---|---|
| Group.Border.Brush | Brush defining the border for a group view |
TabView
Description
Properties
| Key | Additional States | Details |
|---|---|---|
| TabView.Header.Height | Height of the header | |
| TabView.Text.Margin | Margin to position text and image inside an header element | |
| TabView.Brush | Brush (must be an image brush) with 8 icons defining the various tab header images (normal middle, clicked middle, normal left, clicked left, normal right, clicked right, normal single, clicked single) |
Panel
Description
Properties
| Key | Additional States | Details |
|---|---|---|
| Panel.Background.Brush | Defines the shape and brush for the panel background | |
| Panel.Height | Defines the height of the panel window | |
| Panel.ContentHeight | Defines the actual height of the visible panel content | |
| Panel.Button.Image | (active), (inactive) | Defines the active and inactive brush/border used to display an active or inactive application button |
| Panel.Plugins.Brush | Defines the background for the panel plugin area | |
| Panel.Background.Right.Use | Use a separate brush for the right side of the panel. (the area where open programs are displayed) | |
| Panel.Background.Right.Brush | Brush for the right side of the panel |
Different states
In order to use the correct themable appearance the theme engine will try to get the theme keys in following order:
- Get key for control in current state (e.g. Button.BackgroundImage(disabled))
- Get key for control (e.g. Button.BackgroundImage)
The first found key will be used.
Example
Configuration File
Following configuration example (exported with/from DataCollection Editor) features a theme style which looks like WindUI.
FrameWindow.Border.Left.Brush.Type STRING Image FrameWindow.Border.Left.Brush.SolidColor COLOR #00525252 FrameWindow.Border.Left.Brush.Image STRING FrameBorderLeft.ico FrameWindow.Border.Left.Brush.Image(inactive) STRING FrameBorderLeft(inactive).ico FrameWindow.Border.Left.Brush.SizingMargins RECT 0,0,0,0 FrameWindow.Border.Left.Brush.SizingType STRING Tile FrameWindow.Border.Left.Width INT32 10 FrameWindow.Border.Left.ContentSize INT32 10 FrameWindow.Border.Left.ContentSize(inactive) INT32 10 FrameWindow.Border.Left.Transparent BOOL false FrameWindow.Border.Left.Transparent(inactive) BOOL true FrameWindow.Border.Right.Brush.Type STRING Image FrameWindow.Border.Right.Brush.SolidColor COLOR #00525252 FrameWindow.Border.Right.Brush.Image STRING FrameBorderRight.ico FrameWindow.Border.Right.Brush.Image(inactive) STRING FrameBorderRight(inactive).ico FrameWindow.Border.Right.Brush.SizingMargins RECT 0,0,0,0 FrameWindow.Border.Right.Brush.SizingType STRING Tile FrameWindow.Border.Right.Width INT32 10 FrameWindow.Border.Right.ContentSize INT32 10 FrameWindow.Border.Right.ContentSize(inactive) INT32 10 FrameWindow.Border.Right.Transparent BOOL false FrameWindow.Border.Right.Transparent(inactive) BOOL true FrameWindow.Border.Bottom.Brush.Type STRING Image FrameWindow.Border.Bottom.Brush.SolidColor COLOR #00525252 FrameWindow.Border.Bottom.Brush.Image STRING FrameBorderBottom.ico FrameWindow.Border.Bottom.Brush.Image(inactive) STRING FrameBorderBottom(inactive).ico FrameWindow.Border.Bottom.Brush.SizingMargins RECT 2,0,2,0 FrameWindow.Border.Bottom.Brush.SizingType STRING Tile FrameWindow.Border.Bottom.Width INT32 10 FrameWindow.Border.Bottom.ContentSize INT32 10 FrameWindow.Border.Bottom.ContentSize(inactive) INT32 10 FrameWindow.Border.Bottom.Transparent BOOL false FrameWindow.Border.Bottom.Transparent(inactive) BOOL false FrameWindow.Background.Brush.Type STRING Solid FrameWindow.Background.Brush.SolidColor COLOR #00C1C1C1 FrameWindow.Background.Brush.Image STRING FrameBackground.ico FrameWindow.Background.Brush.SizingType STRING Tile FrameWindow.MinimumSize.Width INT32 170 FrameWindow.MinimumSize.Height INT32 100 FrameWindow.InnerFrame.Margin INT32 0 FrameWindow.InnerFrame.SolidColor COLOR #00777777 FrameWindow.DefaultBackground.SolidColor COLOR #00777777 ClientWindow.Background.Brush.Type STRING Solid ClientWindow.Background.Brush.SolidColor COLOR #00EBEBEB ClientWindow.Background.Brush.Image STRING ClientBackground.ico ClientWindow.Background.Brush.SizingType STRING Tile TitleBar.Background.Brush.Type STRING Image TitleBar.Background.Brush.Image STRING TitleBarBackground.ico TitleBar.Background.Brush.Image(inactive) STRING TitleBarBackground(inactive).ico TitleBar.Background.Brush.SizingMargins RECT 5,0,5,0 TitleBar.Background.Brush.SizingType STRING Tile TitleBar.Height INT32 26 TitleBar.Transparent BOOL true TitleBar.Transparent(inactive) BOOL true TitleBar.Caption.Background.Brush.Type STRING Image TitleBar.Caption.Background.Brush.Image STRING TitleBarCaptionBackground.ico TitleBar.Caption.Background.Brush.SizingMargins RECT 5,0,5,0 TitleBar.Caption.Background.Brush.SizingType STRING Tile TitleBar.Caption.Background.Brush.Image(inactive) STRING TitleBarCaptionBackground(inactive).ico TitleBar.Caption.TextColor COLOR #00FFFFFF TitleBar.Caption.TextColor(inactive) COLOR #00202020 TitleBar.Caption.Height INT32 26 TitleBar.Caption.Align STRING Center TitleBar.Caption.TextMargin RECT 5,2,5,5 TitleBar.Caption.Margin RECT 10,0,10,0 TitleBar.Icons.Width INT32 20 TitleBar.Icons.Margin RECT 10,3,0,0 TitleBar.Icons.Align STRING Right TitleBar.Icon.Close.Image STRING IconClose.ico TitleBar.Icon.Max.Image STRING IconMax.ico TitleBar.Icon.Min.Image STRING IconMin.ico TitleBar.Icon.Help.Image STRING IconHelp.ico StatusBar.Brush.Type STRING Image StatusBar.Brush.SolidColor COLOR #00525252 StatusBar.Brush.Image STRING StatusBar.ico StatusBar.Brush.Image(inactive) STRING StatusBar(inactive).ico StatusBar.Brush.SizingMargins RECT 2,0,2,0 StatusBar.Brush.SizingType STRING Tile StatusBar.Height INT32 15 StatusBar.Grip.Image STRING StatusBarGrip.ico StatusBar.Transparent BOOL false StatusBar.Transparent(inactive) BOOL false Button.Brush.Type STRING Image Button.Brush.SolidColor COLOR #00525252 Button.Brush.Image STRING Button.ico Button.Brush.Image(down) STRING Button(down).ico Button.Brush.Image(focus) STRING Button(focus).ico Button.Brush.SizingMargins RECT 4,0,4,0 Button.Brush.SizingType STRING Tile Button.Height INT32 22 Edit.Brush.Type STRING Image Edit.Brush.SolidColor COLOR #00525252 Edit.Brush.Image STRING EditField.ico Edit.Brush.SizingMargins RECT 2,2,2,2 Edit.Brush.SizingType STRING Tile Edit.Brush.Fill INT32 0 ProgressBar.Border.Brush.Type STRING Solid ProgressBar.Border.Brush.SolidColor COLOR #007D7D7D ProgressBar.Border.Brush.Width INT32 1 ProgressBar.Border.Brush.Fill INT32 0 ProgressBar.Brush.Type STRING Image ProgressBar.Brush.Image STRING ProgressBarFill.ico ProgressBar.Brush.SizingType STRING Tile ProgressBar.Margin RECT 2,2,2,2 ProgressBar.Height INT32 19 ScrollBar.Background.Brush.Type STRING Image ScrollBar.Background.Brush.Image(vertical) STRING ScrollBarBackground(vertical).ico ScrollBar.Background.Brush.Image(horizontal) STRING ScrollBarBackground(horizontal).ico ScrollBar.Background.Brush.SizingMargins(vertical) RECT 0,1,0,1 ScrollBar.Background.Brush.SizingMargins(horizontal) RECT 1,0,1,0 ScrollBar.Background.Brush.SizingType STRING Tile ScrollBar.Indicator.Brush.Type STRING Image ScrollBar.Indicator.Brush.Image(vertical) STRING ScrollBarIndicator(vertical).ico ScrollBar.Indicator.Brush.Image(horizontal) STRING ScrollBarIndicator(horizontal).ico ScrollBar.Indicator.Brush.SizingMargins(vertical) RECT 0,6,0,6 ScrollBar.Indicator.Brush.SizingMargins(horizontal) RECT 6,0,6,0 ScrollBar.Indicator.Brush.SizingType STRING Tile ScrollBar.Button.Brush.Type STRING Image ScrollBar.Button.Brush.Image(top) STRING ScrollBarButton(top).ico ScrollBar.Button.Brush.Image(bottom) STRING ScrollBarButton(bottom).ico ScrollBar.Button.Brush.Image(left) STRING ScrollBarButton(left).ico ScrollBar.Button.Brush.Image(right) STRING ScrollBarButton(right).ico ScrollBar.Size INT32 17 ListView.Border.Brush.Type STRING Solid ListView.Border.Brush.SolidColor COLOR #007D7D7D ListView.Border.Brush.Width INT32 1 ListView.Border.Brush.Fill INT32 0 ListView.Header.Height INT32 14 ListView.Header.Brush.Type STRING Image ListView.Header.Brush.Image STRING ListViewHeader.ico ListView.Header.Brush.SizingType STRING Tile Splitter.Grip.Image(vertical) STRING SplitterGrip(vertical).ico Splitter.Grip.Image(horizontal) STRING SplitterGrip(horizontal).ico TreeView.Image(expanded) STRING TreeView(expanded).ico TreeView.Image(collapsed) STRING TreeView(collapsed).ico Menu.ChildArrow.Image STRING MenuChildArrow.ico CheckBox.Image STRING CheckBox.ico RadioButton.Image STRING RadioButton.ico TabView.Header.Height INT32 20 TabView.Brush.Type STRING Image TabView.Brush.Image STRING TabView.ico TabView.Brush.SizingMargins RECT 5,0,5,0 TabView.Brush.SizingType STRING Tile TabView.Text.Margin RECT 5,0,5,0 Group.Border.Brush.Type STRING Image Group.Border.Brush.Image STRING GroupBox.ico Group.Border.Brush.SizingMargins RECT 4,4,4,4 Group.Border.Brush.SizingType STRING Tile Group.Border.Brush.Fill INT32 0 Panel.Background.Brush.Type STRING Image Panel.Background.Brush.Image STRING PanelBackground.ico Panel.Background.Brush.SizingMargins RECT 10,0,10,0 Panel.Background.Brush.SizingType STRING Tile Panel.Height INT32 33 Panel.Button.Image(active) STRING PanelButton(active).ico Panel.Button.Image(inactive) STRING PanelButton(inactive).ico Panel.Plugins.Brush.Type STRING Image Panel.Plugins.Brush.Image STRING PanelPluginsBackground.ico Panel.Plugins.Brush.SizingMargins RECT 10,0,10,0 Panel.Plugins.Brush.SizingType STRING Tile
Mockups and Samples
A MacOS like theme made in 3 minutes.
A little wood-skin which can be archived with just modifying six images
The default WindUI skin with transparent borders for inactive windows
The default panel
The default panel in different colors
A themed panel using a different window shape and different icons
A preliminary screenshot of a new theme (Royal) being created

