This page describes how to create icons for the WPS-Wizard icon engine. One of the key features of the engine is that you don't have to paint every single icon in an image manipulation application. Instead there is support for icon composing which means you build your image using several parts which are blended together. For example one choses a base icon and another image is resized and painted on top of that one and maybe additional text is added. The resulting image is not stored as an icon on the users system but only the paint commands are recorded in an initialization file and the image is constructed on the fly as soon as the icon is loaded by the system.
The images used for compositing have PNG format so alpha blending can be used.
Note: when talking about 'icon' in the following text an icon built by the icon engine is meant not one of the default eCS system icons.
This tutorial is mainly intended for icon package creators. Some of the techniques described here are useful when changing object icons, too.
How icons are stored
The engine uses paint commands recorded in an initialization file which are interpreted during icon loading. A pointer to the folder holding this ini file is stored in the users ini file OS2.INI:
Application key name: IconTheme Key name: IconFolder Contents: Path to folder holding the INI file
Be sure to keep the spelling for the keys.
Format of the initialization file
The name of the initialization file must be:
All images used for composing icons are located in the directory holding the ini file or a subdirectory of it. The engine uses the ini file loction as an anchor and searches all parts referenced in paint commands relative to this anchor point.
Icons are searched based on the objects class name and the object ID. Custom icons created from the settings notebook of an object are referenced using a numeric key. This is not described here.
For every class in the system there may be a unique icon. This is used when no object specific icon can be found.
Application key name: Class name, e.g. CWDataFile, WPFolder, AMouse Key names: Various, will be described later Contents: Paint commands and references to files
Note that the application key name must reflect the exact spelling of the class.
For an object specific icon the object ID is used as the application key:
Application key name: Object ID, e.g. <XWP_SCREEN>, <WP_OS2SYS>, <WP_DESKTOP> Key names: Various, will be described later Contents: Paint commands and references to files
The application key must be exactly like the ID, this includes the opening and closing braces.
The Search order for icons is the following:
- Object specific icon referenced by numeric ID
- Object specific icon referenced by object ID
- Class specific icon referenced by class name
- Object specific eCS icon
- Class specific eCS icon
As can be seen the icon engine will fall back to the eCS icon handling when no engine icon can be found.
Before diving into the topic it's useful to know some basics about how painting is done.
- The icon engine uses a base image as a surface on which subsequent drawing commands are applied (note that there are other ways to define the base surface).
- The resulting surface has exactly the size of the base image.
- All factors or values are floating point numbers usually running from 0.0 to 1.0.
- Coordinates are also floating point numbers.
- 0.0 0.0 is the upper left corner.
- Keys referenced by commands are case sensitive.
- Commands are always lowercase.
Creating an icon using compositing
The easiest way to create an icon for the engine is combining several icons to form a new image. The following sections will step through this compositing process. As an example the image for the multimedia folder from the Noia Warm icon set will be used.
(Note that this icon is scaled to 120x120 pixels)
1. Create the initialization file entry
At the moment creating icons which are part of an icon package is a little bit cumbersome. Changing existing icons is done as usual from the icon page of the settings notebook.
The multimedia folder has the object ID <MMPM2_FOLDER>. If you have XWorkplace installed you may use the Details button on the icon page to query the ID of every object. Using an ini editor (eCS comes with regedit2.exe) enter the following into the ini file.
The path to the referenced image is relative to the place where the ini file is located.
After putting the path to the folder holding the ini file into your os2.ini (see above) restart the WPS (I already mentioned that creating themes is a little bit cumbersome...). Your multimedia folder should have the generic folder icon now.
2. Enhancing the base image
From now on things are way easier. Open the settings notebook of the multimedia folder object, go to the icon page and press the Browse button. A folder window will open which contains a single object labeled as <MMPM2_FOLDER>.
There is only one single object because the ini file only contains one entry for now. If you have an icon package installed the folder contains all defined icons for the package in question which may be several hundred.
Normally one would just drag one of the predefined icons to the icon page to assign a new icon but we intend to create a new one so we will use the icon editor to change the predefined icon shape.
Note that you won't do that when just editing the icon of some random object. In that case the Edit button on the icon page is used like for normal eCS icon management.
Double click on the object to show the settings notebook. Click the Edit button and the icon editor will be started.
The editor is basically a specialized ini file editor with a preview function for the images. On the left you have a listbox with the currently defined keys, the bottom text field shows the data associated with the selected key and on the right you find a preview area. Pressing the Repaint button will take the provided data from the keys and create the preview image.
Adding an overlay image
As mentioned early an icon will be created by composing it from several images.
Click New to create a new key with the following data.
Key name: OverlayImage Data: apps\kcmsound.png
Repainting the preview does not show any effect. So what's missing?
The icon engine uses paint commands describing the shape of the resulting icon which are interpreted during icon loading. Up to now no such commands are specified.
Create another key:
Key name: CairoCommands Data: <ctxt>save</><scale>0.01 0.01</><imgkey>OverlayImage # 1</><ctxt>restore</>
The spelling of the key must be exactly like shown here.
This results in the following icon with an overlay image.
The commands in detail
<ctxt>save/restore</>: Save and restore the current paint context.
The icon engine holds internal data defining the current colors, fonts, angle of rotation etc. Some paint commands alter this information in a global way. To preserve a set state the <ctxt> command can be used. It stores all the data on a stack and any changes will be reverted when issuing a <ctx>restore</>.
It is save to have several of these commands in a set of commands. Make sure every save has an associated restore.
<scale>xsize ysize</>: Apply scaling to the next set of commands.
The values xsize and ysize are factors between 0.0 and 1.0. They specify the size of the items which will be painted afterwards. Note that this scaling is a global setting and will be applied to all paint commands which follow. Use <ctxt>save</> to save current scaling settings. Note that the factors usually have to be rather small. A value of 1.0 does not mean current icon size but is way bigger.
<imgkey>imgname # alpha</>: Paint an image specified by the key 'imgname' on the current surface with an alpha level of 'alpha'.
This command will paint an image at the current position with the current scaling. The value of alpha may run from 0.0 to 1.0 where 1.0 means completely opaque while 0.0 means completely translucent. imgname is the name of a key in the ini file specifiying the image file to be used. The path is a relative one as known from the 'Image' key. Note that the spelling of the key is important and references to keys belonging to other icons are not possible.
In this example slight changes are made to the paint commands. The alpha value was reduced and the scaling factors increased.
Key name: CairoCommands Data: <ctxt>save</><scale>0.015 0.015</><imgkey>OverlayImage # 0.5</><ctxt>restore</>
This icon is the result.
Adding another overlay image
Click New to create another key with the following data.
Key name: OverlayImage2 Data: apps\multimedia.png
As expected clicking the Repaint button will not show a new image because the necessary paint commands referencing the new image are missing.
The necessary commands are shown below.
Key name: CairoCommands Data: <ctxt>save</><transl>0 0.2</><scale>0.01 0.01</><imgkey>OverlayImage # 1</><ctxt>restore</> <ctxt>save</><transl>0.4 0.3</><scale>0.01 0.01</><imgkey>OverlayImage2 # 1</><ctxt>restore</>
Additional commands in detail
<transl>x y</>: Specify the position for the next paint command.
X and y specify the position on the surface where subsequent painting will take place. 0.0 0.0 is the upper left corner. The values may run from 0.0 to 1.0.
The resulting icon shows that images are drawn in the order they are described in the painting commands. Thus the speaker image (!OverlayImage2) is painted on the very top.
Each of the image commands is surounded by <ctxt>save</> and <ctxt>restore</>. This facilitates correct scaling and positioning. An example shows this.
Key name: CairoCommands Data: <ctxt>save</><transl>0 0.2</><scale>0.01 0.01</><imgkey>OverlayImage # 1</> <transl>0.4 0.3</><scale>0.01 0.01</><imgkey>OverlayImage2 # 1</><ctxt>restore</>
Using only one block of context save commands (which is pointless because no further painting is done) yields the following icon.
Where is the second overlay image gone?
It's actually still kind of there but you can't see it because it is scaled two times by 0.01 and thus won't be painted anymore (it's size is smaller than a single pixel). The reason is the way scaling (and positioning using the <transl> command) works. The scaling is applied once to the drawing context and will work on all subsequent paint commands. The same goes for the translate command which moves the current drawing context in space. So the first scale command resizes all the following images by 0.01. The second scale comand resizes again by 0.01 for the then following images (that is !OverlayImage2). The scaling also influences the translate commands which are also global.
So to get the same icon as before the commands have to be like the following.
Key name: CairoCommands Data: <ctxt>save</><transl>0 0.2</><scale>0.01 0.01</><imgkey>OverlayImage # 1</> <transl>40 10</><imgkey>OverlayImage2 # 1</><ctxt>restore</>
Note how the second scale command is removed and the values of the translate command are increased bei 100 to compensate for the very first scaling. Additionally the values of the second translate command are offsets added to the first <transl>0 0.2</> because both translate commands work on the second overlay picture.
Calculating the correct factors and offsets may become tricky when using a lot of commands so the <ctxt> command comes in handy in the end. Interpreting the command string and assembling the final icon may use slightly more time for the longer sequence but this only happens once when loading the icon and thus doesn't cause much harm.
As shown creating new icons from a set of predefined images isn't exactly rocket science. This small tutorial gave a short run on how to do it with minimal effort. Using this blueprint a majority of eCS icons can be created just by changing the base image, the overlay images and the given commands.
The icon engine offers way more features which are described here.
Note that the new icon will only be shown after a WPS restart.