This article could use improved formatting.
You can help by cleaning up the wikicode to improve the appearance of the article.

SharpE Skin Documentation


SharpBar? (the SharpE toolbar component) can be fully customized and skinned.
This document will help you to understand how the skin system works so that you can create your own SharpE skins.

The skin system developed for SharpE is a bitmap layer-based rendering system. A skin defines a rendering path from the top-most bitmap layer to the bottom layer. These layers fully support transparency and alpha blending. Therefore, all images used in a skin must be saved in PNG format with transparency (32bit PNG). We also recommend you save the PNG files with the normal RGB color palette (not grayscale!).

Besides the SharpBar? background there are several other components used by SharpBar? modules which can be skinned. That is why a SharpE skin can consist of many different and independent component skins. The xml for a skin contains several sections, one for each component that is skinned. Each component can have a different structure.

Some examples of components you can skin:

  • button
  • progress bar
  • taskbar item
  • edit box

Detailed information about each component's skin structure can be found in the Skin Component section.

One of the more exciting features of the skinning system is its support for "skin schemes". SharpE supports the use of color schemes which allow each skin to use completely different colors. It's not a required part of a skin, but supporting scheme colors in your skin is a great feature and highly recommended. With schemes, you control the skin, but the end-user can define the colors of the skin. More detailed information can be found in the Colors section.


Colors

Each color used by a skin can be customized. They are defined in your scheme.xml file, which contains a list of all colors used by your skin. For each color, the list contains properties for Name, Replacement Tag, Description and Default.

Name: the name of the skin portion to be colored.
Tag: the variable you will use to refer to that portion of the skin.
Info/Description: describe what is being colored in plain language.
Default: the default color assigned to this skin portion.

Example file: (scheme.xml)

<?xml version="1.0" encoding="iso-8859-1"?>
<SharpESkinScheme>
  <item>
    <Name>Background</Name>
    <Tag>$Background</Tag>
    <Info>The SharpBar background color</Info>
    <Default>10395294</Default>
  </item>
  <item>
    <Name>Background Text</Name>
    <Tag>$BackgroundText</Tag>
    <Info>Text color for all text</Info>
    <Default>0</Default>
  </item>
</SharpESkinScheme>

You use the colors defined here in the <color> properties of the skin file by writing the replacement tag.

After your skin has been loaded, the user can change all the colors defined in this file. If you define a $Background and another $BackgroundText? color then the user will be able to create and use personal color schemes changing those two colors. This allows for a great deal of flexibility for the user, who can then match your skin to his or her personal tastes.


Skin File

Your whole skin is defined in one file - the skin.xml file.

All your component skins are stored in this file, which means that each item in this xml file represents one skinable component. If you are going to add your SharpBar? skin then you add this as a new <sharpbar> item to this file. The actual content you have to add for the component skin item is different for each component and detailed informations can be found in the 'Skin Components' {add link} section.

Example file: (skin.xml)

<?xml version="1.0" encoding="iso-8859-1"?>
<SharpESkin>
  <sharpbar>
  ...
  </sharpbar>
  <taskitem>
  ...
  </taskitem> 
  <button
  ...
  </button>
</SharpESkin> 

Component skins every skin should have are:

  • sharpbar
  • taskitem
  • button
  • menu
  • menuitem
  • minithrobber
  • font (default label properties)
  • progressbar
  • edit (edit box skin)


Skin Parts

(How to skin any component) Creating a skin for a component follows a layer based rendering path system. You define the location and dimension of all images used for the component skin. The skin system will then render all used layers beginning with the top most layer.

By default each created layer if fully transparent filled with RGBA(0,0,0,0).

A simple example of how rendering of the layers works:
Layer Rendering

Creating layers in xml is done by adding Skin Parts to your component skin. Each skin part represents one layer and all the properties of the layer are set by directly adding properties to the <skinpart> item in xml.

Available properties for all skin parts are:

<ID>

The ID is like a name for a layer.
This property is not required and you should only set this for layers which you are going to animate.

<location>

The x and y location.

example: <location>0,0</location>

<dimension>

Dimension of the layer.
If the dimension of the layer is different from the dimension of the <image> property then the image will be either stretched or tiled over the whole dimension. By default the image will be stretched. To change this to tiled draw mode see the <drawmode> property.

example: <dimension>12,6</dimension>

<image>

The path to the .PNG image which will be loaded into the layer. The path to the filename is relative to the skin directory.

example: <image>images\background.png</image>

<drawmode>

Stretched or tiled draw mode for layers where dimension is different from image size. The default value if the property isn't set is stretched draw mode.

examples:
<drawmode>tile</drawmode>
<drawmode>stretch</drawmode>

<layermode>

Blend mode for the used layer. Use this property to set a special combine/blend mode for when the layer is painted on top of the other layers. The default value is normal alpha blending ('blend').

example: <layermode>Subtract</layermode>

Possible values

Blend
Default blend mode. Blends two images using a defined transparency value
Add
Lightens the image by using the lightness values of the colors in the selected layer to lighten the colors of underlying layers. Light colors produce the most lightening; black has no effect.
Subtract
Darkens the image by using the darkness values of the colors in the selected layer to darken the colors of the underlying layers.
Min
Displays pixels in the selected layer that are darker than the underlying layers. Pixels lighter than the underlying layers disappear.
Max
Displays pixels in the selected layer that are lighter than the underlying layers. Pixels darker than the underlying layers disappear.
Difference
Subtracts the color of the selected layer from the color of the underlying layers. This blend mode produces the same result regardless of the order of layers within the Layers palette.
Exclusion
Subtracts the color of the selected layer from the color of the underlying layers
(no image available)Modulation
No idea what this is? Maybe remove? -Lcgreen 10/30/06, 11:49am

<color>

Sets the blend color used for blending the whole layer. Any color set in this property will blend the whole layer to this color. The blending intensity for each pixel is defined by the brightness of the pixel itself.

A pixel with RGB(128,128,128) will be directly blended to the blend color. Any pixel with higher RGB value will be blended to a brighter blend color depending on the difference of the RGB value to RGB(128,128,128). The limits of this are RGB(255,255,255) which is white and RGB(0,0,0,0) which is black.

$colorreplaces the color with the scheme color of the same tag. See the 'Colors' section for details
RGB(R,G,B)creates a color based on the given red, green and blue value. All three values go from 0 to 255
RGBRGB as single color integer value
HSV(H,S,V)Hue, Saturation, Value based color. The H value ranges from 0 to 360. Both S and V values range from 0 to 100 (in %)
HSL(H,S,L)Hue, Saturation, Lightness based color. The H value ranges from 0 to 360. Both S and L values range from 0 to 100 (in %)
CMYK(C,M,Y,K)Cyan, Magenta, Yellow, Black based color. All four values range from 0 to 100 (in %)
HEX(RGB)color based on RGB as hex values ranging from 0 to FF

examples: <color>$Background</color>
<color>RGB(0,128,255)</color>
<color>281277</color>
<color>HSV(180,60,80)</color>
<color>HSL(140,10,20)</color>
<color>CMYK(0,0,0,0)</color>
<color>HEX(FFAA00)</color>

<alpha>

The master alpha value for the layer. By using this master alpha property you can reduce the alpha value of all pixels. A pixel with a base alpha value of 128 and a layer master alpha of 128 will be display with an alpha value of 64 on the screen. The master alpha value ranges from 0 to 255.

example: <alpha>200</alpha>

<gradienttype>

Sets the gradient type the layer will be filled with. By default a horizontal gradient will be used. The gradient will be painted on top of the used image! Use a blank .PNG if you want to only have a gradient layer.

examples:
<gradienttype>vertical</gradienttype>
<gradienttype>horizontal</horizontal>

<gradientalpha>

Sets the start and end alpha for the used gradient. Both alpha values range from 0 to 255. The default alpha values are 0,0 which means that no gradient is painted if this property does not exist.

example:
<gradientalpha>128,255<gradientalpha>

<gradientcolor>

Sets the start and end color for the used gradient. Possible color values are the same as the for the <color> property. The default color is black.

Example Skin Part

An example how a skin part looks like in the xml files is shown below. This example is taken from one of the default skins showing the drawing of the SharpBar? background.

<skinpart>
  <location>0,0</location>
  <dimension>6,30</dimension>
  <image>images/bar-left.png</image>
  <color>$Background</color>
</skinpart>
<skinpart>
  <location>6,0</location>
  <dimension>w-12,30</dimension>
  <image>images/bar-middle.png</image>
  <color>$Background</color>
</skinpart>
<skinpart>
  <location>w-6,0</location>
  <dimension>6,30</dimension>
  <image>images/bar-right.png</image>
  <color>$Background</color>
</skinpart>


Mathematical Expression

It is possible to use simple mathematical expressions for all <location> and <dimension> properties of skin parts or components. The skin system provides some basic variables such as width and height of the component which can be combined with numbers or other variables by using '+' or '-'. For component skins using a caption defined by a <text> property additional variables for getting text width and height are supported.

Generic Variables

hHeight of the component
wWidth of the component

Special Variables (for components using text only!)

cwx coordinate for centered text. (Clientarea width - Text width) div 2
chy coordinate for centered text. (Clientarea height - Text height) div 2
twText width
thText height
twh(Text width) div 2
thh(Text height) div 2

examples:
<dimension>w,h</dimension>
<dimension>w-3,h-3</dimension>
<location>w-6,0</location>
<location>cw-1,ch</location> (as location for a <text> property)

Text Properties

Some components will need a text or caption to be painted. The text properties for a skin component are defined in a <text> tag under the skin components root XML key. For most components with different drawing states it's also possible to define different text properties for each state or to overwrite single text properties.

The following properties are available for all <text> tags:

locationx and y coordinate for the top left of the text
nametext name
sizetext size
colortext color (using schemeable colors tags like $Text is possible)
boldbold font style (0/1)
italicitalic font style (0/1)
underlineunderline font style (0/1)
shadowuse text shadows (0/1)
shadowcolorshadow color (using schemeable colors tags like $TextShadow? is possible)
shadowalphaalpha value for the painted text shadow

The <location> property is supporting some special variables for text alignment. See the mathematical expressions section for details.

example: (taken from a button component skin)

<button>
  <text>
    <location>cw-1,ch</location>
    <name>Small Fonts</name>
    <size>7</size>
    <color>$Text</color>
    <shadow>1</shadow>
    <shadowcolor>$TextShadow</shadowcolor>
    <shadowtype>Right</shadowtype>
    <shadowalpha>196</shadowalpha>
  </text>
   ...
  <down>
    <text>
      <location>cw-2,ch+1</location> // <--- overwrite the location text property to move it by one pixel
    </text>
    ...
  </down>
  ...
</button>

Component Skins

As described earlier you have to create skins for all the different skinnable components. The structure of those component skins is different for each component and some components might also need some special properties. Besides this some components might have multiple drawing states such like <normal>,<down>,<hover>,... so you might have to create different skins for those states too. This section will describe the structure and special properties for all the the standard components.

SharpBar?

Skin for the SharpBar? background and the main SharpBar? throbber

Special properties

dimensioncomponent dimension, always set the x value to 'w' because of the dynamic width of the bar. The y value sets the bar height
fsmod'full screen mod', specifies the left and right cut off in pixels if the left and/or right border of the bar is touching a screen edge
sbmod// might be removed later
paxoffsets'plugin area x offsets', sets the left (first value) and right (second value) offsets (padding) for the module area
payoffsets'plugin area y offsets', sets the top (first value) and bottom (second value) offsets (padding) for the module area
enablevflip// might be removed later
specialhideformUse a special (fully transparent) window for hiding the bar by clicking on the screen edge. Set this property to 1 (enabled) if your skin is using shadows or other transparent areas at the screen borders. Otherwise set to 0 to disable the usage of a special clickable bar hide window.

Skin elements
The SharpBar? has two different elements defined by the skin. First the bar background itself covered in the <bar> tag and second the design of the main throbber in the <throbber> tag.

The SharpBar? background itself doesn't have any other drawing states. So all skin parts are directly under the <bar> tag. example: (SharpBar? skin)

<bar>
  <dimension>w,h</dimension>
  <!-- Skin Parts -->
</bar>

The throbber skin has three drawing states: <normal>, <hover>, <down> and you can set the location and dimension of the component with the <location> and <dimension> properties. example: (Throbber skin)

<throbber>
  <location>3,4</location>
  <dimension>6,20</dimension>
  <normal>
    <!-- Skin Parts -->
  </normal>
  <hover>
     <!-- Skin Parts -->
  </hover>
  <down>
    <!-- Skin Parts -->
  </down>
</throbber>

Example for a complete SharpBar? skin:

<sharpbar>
  <dimension>w,28</dimension>
  <fsmod>0,0</fsmod>
  <paxoffsets>15,8</paxoffsets>
  <payoffsets>3,3</payoffsets>
  <specialhideform>1</specialhideform>
  <bar>
    <!-- SharpBar skin -->
  </bar>
  <throbber>
    <!-- Throbber skin -->
  </throbber>
</sharpbar>

MiniThrobber?

Skin for the modification/settings button of each SharpBar? module

Special properties

dimensioncomponent dimension. Always use fixed values for width and height since all mini throbbers will have the exact same size.
locationThe second coordinate defines the top position of each mini throbber (default is 0). The first value is not used.

The mini throbber skin has three drawing states: <normal>, <hover>, and <down>.

example:

<minithrobber>
  <dimension>5,5</dimension>
  <location>0,4</location>
  <normal>
    <!-- Skin Parts -->
  </normal>
  <hover>
    <!-- Skin Parts -->
  </hover>
  <down>
    <!-- Skin Parts -->
  </down>
</minithrobber>

Button

Skin for all buttons used by SharpBar? modules.

Special properties

dimensioncomponent dimension. Always use 'w' af first value because the buttons are dynamic in width. The second value can be a fixed number specifying the default button height.
locationThe second coordinate defines the top position of each button (default is 0). The first value is not used.
iconlroffsetIcon left/right offset. Use this and the icontboffset property to adjust icon position and size if the icons are off place or too big.
icontboffsetIcon top/bottom offset.
OnNormalMouseEnter?Animation script executed when the mouse enters the component
OnNormalMouseLeave?Animation script executed when the mouse is leaving the component

The button skin has four drawing states (<normal>, <hover>, <down>, <disabled>) and it can display text caption.

example:

<button>
  <text>
    <!-- Text properties -->
  </text>
  <location>0,1</location>
  <dimension>w,19</dimension>
  <iconlroffset>3,2</iconlroffset>
  <icontboffset>3,2</icontboffset>
  <OnNormalMouseEnter>Scripts\ButtonNormalMouseEnter.skinscript</OnNormalMouseEnter>
  <OnNormalMouseLeave>Scripts\ButtonNormalMouseLeave.skinscript</OnNormalMouseLeave>
  <normal>
    <!-- Skin Parts -->
  </normal>
  <hover>
    <!-- Skin Parts -->
  </hover>
  <down>
    <!-- Skin Parts -->
  </down>
  <disabled>
    <!-- Skin Parts -->
  </disabled>
</button>

Font (Labels)

The font skin element isn't a directly skinable component. This tag is used to define the default font settings for labels. You can not specify any skin parts for the font skin element. All you can do is define <text> properties as explained above in the Text Properties section.

A label can use one of three different text styles. Those three styles are 'small','medium','big'.

The second value of the <location> property is used to set the top position of full sized labels for SharpBar?. Note that not all labels are using this value, only modules using labels which are supposed to be centered in the bar middle should make use of this <location> property.

example:

<font>
  <small>
    <size>6</size>
    <name>Small Fonts</name>
    <bold>0</bold>
    <color>$Text</color>
    <location>0,1</location>
  </small>
  <medium>
    <name>Verdana</name>
    <size>8</size>
    <bold>1</bold>
    <color>$Text</color>
    <location>0,-1</location>
  </medium>
  <big>
    <name>Verdana</name>
    <size>10</size>
    <bold>1</bold>
    <color>$Text</color>
    <location>0,-3</location>
  </big>
</font>

Edit Box

Skin for the edit box component.

Special properties

dimensioncomponent dimension. Always use 'w' as value for width because of the dynamic width of this component. For height a fixed value should be used.
locationThe second coordinate defines the top position of the edit box (default is 0). The first value is not used.
editxoffsetsLeft and right offset from the borders where the edit area begins and ends
edityoffsetsTop and bottom offset from the borders where the edit area begins and ends

The edit box skin has four drawing states: <normal>, <focus>, <hover>, <disabled>. (The <focus> state is used while the edit box has the keyboard focus).

example:

<edit>
  <dimension>w,19</dimension>
  <location>0,1</location>
  <editxoffsets>3,3</editxoffsets>
  <edityoffsets>3,3</edityoffsets>
  <normal>
    <!-- Skin Parts -->
  </normal>
  <focus>
    <!-- Skin Parts -->
  </focus>
  <hover>
    <!-- Skin Parts -->
  </hover>
  <disabled>
    <!-- Skin Parts -->
  </disabled>
</edit>


Custom Skin Settings

Some of the SharpBar? modules support custom skin based settings. This means that a skin can overwrite certain settings of a module (default settings, icons, colors, …). Doing this isn’t required by any skin. But it’s highly recommend because by adding custom skin settings you can make some of the modules match your skin even better.

Using custom skin settings is done by creating a custom.xml file in the directory of your skin. Under the root item of this xml file you have to create one XML item for each module for which you want to add custom skin settings.

There are no other rules about the content of this file because everything you can change is defined by the modules itself. There are even modules which don’t support custom skin settings at all.

So far the following modules support custom skin settings:

Taskbar <taskbar>

Properties

minalliconpath to a custom minimize all icon
maxalliconpath to a custom maximize all icon

example:

<taskbar>
  <minallicon>images\Modules\Taskbar\minall.png</minallicon> 
  <maxallicon>images\Modules\Taskbar\maxall.png</maxallicon>
</taskbar> 

iDrop <idrop>

Note: This may be out of date as the iDrop module gets rewritten. (glacialfury, 19 March 2007)

Properties

backgroundpath to a custom drop zone icon
blendcolorblend color for the icon specified in the background property (remove this property if you don’t want any blend effect)

example:

<idrop> 
  <background>images\Modules\iDrop\Background.png</background> 
  <blendcolor>$Border</blendcolor>
</idrop>

CPU Monitor <cpumonitor>

All custom settings for this module are the default settings. They will be applied on the first time a module is added or if the skin is loaded for the first time.

Properties

fgcolorforeground color
bgcolorbackground color
bordercolorborder color
fgalphaforeground color alpha value
bgalphabackground color alpha value
border alphaborder color alpha value

example:

<cpumonitor> 
   <fgcolor>$Text</fgcolor> 
   <bgcolor>$Background</bgcolor> 
   <bordercolor>$Border</bordercolor> 
   <fgalpha>178</fgalpha> 
   <bgalpha>0</bgalpha> 
   <borderalpha>154</borderalpha> 
</cpumonitor>

SystemTray <systemtray>

All custom settings for this module are the default settings. They will be applied on the first time a module is added or if the skin is loaded for the first time.

Properties

showbackgrounddisplay the solid background color (0 = False | -1 = True)
showborderdisplay the border (0 = False | -1 = True)
colorblendcolor blend the icons (0 = False | -1 = True)
backgroundcolorbackground color
backgroundalphabackground color alpha value
bordercolorborder color
borderalphaborder color alpha value
blendcoloricon blending color
blendalphastrength of the icon blending (255 = 100% | 0 = 0%)
iconalphaalpha value for the tray icons

example:

<systemtray> 
  <showbackground>0</showbackground> 
  <showborder>-1</showborder> 
  <colorblend>-1</colorblend> 
  <backgroundcolor>$Background</backgroundcolor> 
  <backgroundalpha>0</backgroundalpha> 
  <bordercolor>$Border</bordercolor> 
  <borderalpha>154</borderalpha> 
  <blendcolor>$Border</blendcolor> 
  <blendalpha>255</blendalpha> 
  <iconalpha>204</iconalpha> 
</systemtray>  


Animation System

The SharpE Skin system supports the dynamic scripting of custom skin events like MouseEnter or MouseLeave. It is possible to simply link a SharpE Skin Script file to those events for all components which are supporting animations. With those event based custom scripts it’s possible to create simple animations for a skin. For example if you want to add a mouse hover animation to your skin you simply assign two scripts to the MouseEnter and MouseLeave event. The scripts are saved in separate files in a \Scripts\ sub directory of your skin. Linking a script to an event is done by assigning the script file to the event of the skin component in your skin.xml file.

The scripted animations are done by modifying the properties of the skin parts, therefore the skin system provides some predefined functions for modifying layer properties. Those functions can be used in a complex Pascal/Delphi based scripting language. So in the end for creating nice and smooth animations you are creating pascal scripts which are modifying your skin layers.

Keep in mind that each script can only access the skin parts of the skin component the script is assigned to. This also means that it can also only access the skin parts of the skin component state to which the script is assigned. For example your script for MouseEnter which is assigned to the ‘Normal’ state of a component skin can not modify the skin parts of the ‘Down’ state. However if the Normal and Down skin parts have the same structure and if the skin parts have the same IDs/names then it’s possible to use the same script for both component states.

Structure of .SkinScript files

An animation script is saved in ‘.skinscript’ files and only one single animation is stored in each file. The structure of the file must follow some predefined rules which are described below.

The header of each skin script file must contain the following lines:

  unit SkinScript; 
  interface 
  function InitAnimation : integer; 
  function OnAnimate : boolean; 
  implementation 
  // code that implements InitAnimation
  // code that implements OnAnimate

Without those header lines the skin system doesn’t know that the file is a valid skin script and therefore the whole file won’t be used. As you can see below the ‘interface’ part a consists of two functions.

  function InitAnimation : integer;  
  function OnAnimate : boolean; 

The code for those two functions is placed right below the header under the ‘implementation’ section.

The InitAnimation? function is called to initialize the animation and to set the animation update inverval. The result value of this function tells the skin system the update interval for this animation in milliseconds.

For example to set an update interval of 30ms add this to your skin scripts:

  function InitAnimation : integer; 
  begin 
    result := 30; 
  end; 

The second OnAnimate? function is the script itself which is executed every time the animation should update. If you have set the update interval to 30ms then this functions contains the code which is executed every 30ms.

The result value of this functions defines if the animation should continue or if it is finished. (result = True -> continue). This means that you have to check if the end condition of your animation is reached each time OnAnimate? is called.

Modfying properties of your skin parts is possible by using the predefined skin animation functions. For using those functions all the skin parts which are going to be modified must have an ID (Name) property because access to any skin part is based on it’s unique ID.

The following example script shows how you can animate the alpha value of a skin part called ‘background’ from 128 to 255:

function OnAnimate : boolean; 
  begin 
    IncreaseAlpha('Background',32);   
    // End Condidition 
    if GetAlpha('Background') >= 255 then  
    begin 
      // End Condition for this animation reached 
      SetAlpha('Background',255); 
      result := false; // stop the animation 
    end else result := true; // end condition not reached – continue 
  end; 

This example script increases the alpha value of the skin part with ID ‘background’ by 32 every 30ms. If the alpha value of this skin part is getting bigger than 255 then the animation is finished (result := false;).

Available Skin functions

Tool functions:

Value functions: (Functions for getting the value of a skin part property):

Modify Functions: (for modyfing the value of a skin part property)

Linking Skin Scripts

Linking your skin script to the skin events is done in the skin.xml file. The linking is done at the top of the component skin (before the actual component states with the skin parts) where you also define <dimension> and <location>.

The following events are supported right now:

TaskItem?

(full, compact, minimal)

example:

<OnNormalMouseEnter>Scripts\TaskItemNormalMouseEnter.skinscript</OnNormalMouseEnter> 
<OnNormalMouseLeave>Scripts\TaskItemNormalMouseLeave.skinscript</OnNormalMouseLeave> 
<OnDownMouseEnter>Scripts\TaskItemNormalMouseEnter.skinscript</OnDownMouseEnter> 
<OnDownMouseLeave>Scripts\TaskItemNormalMouseLeave.skinscript</OnDownMouseLeave> 
<OnHighlightStepStart>Scripts\TaskItemHighlightStart.skinscript</OnHighlightStepStart> 
<OnHighlightStepEnd>Scripts\TaskItemHighlightEnd.skinscript</OnHighlightStepEnd> 

Button

example:

<OnNormalMouseEnter>Scripts\ButtonNormalMouseEnter.skinscript</OnNormalMouseEnter> 
<OnNormalMouseLeave>Scripts\ButtonNormalMouseLeave.skinscript</OnNormalMouseLeave>

Attachments