Skins/HowTo
From VFXPedia
This document describes the inner workings of a Fusion skin and the contents of the Fusion.skin definition file. It's not meant to be complete and it's reverse-engineered so any inaccuracies are not eyeon's fault :-)
Contents |
General
Hierarchy
Fusion's skin definitions (the file Fusion.skin) contains several sections for different parts of the interface. You don't have to specify every section or draw a bitmap for everything. Fusion's skin engine has a hierarchy, which is visible in the Preferences -> Appearance section. Skins are applied from top to bottom and simply override previous definitions. This means that you can create a Fusion.skin that just contains a custom button while using the rest of the GUI from Fusion's default skin.
BMP Files
Fusion uses bmp files for its skin. If you save them in Photoshop, proceed as follows:
- select the transparency of your layer (ctrl+click the thumbnail) and save it as a new channel.
- merge the image onto a black background.
- save as windows BMP 32 bits.
If you don't remove Photoshop's layer transparency (checker background), it will be replaced by white which is why you need to "premultiply" the image with a black background manually.
Intelligent Resize
BMP files will be resized using an intelligent algorithm. This allows to use a single picture of a small button an extend it to the required dimensions without losing sharpness. The algorithm will keep the edge pixels and extend the image using the pixels along the middle of each direction. Shrinking happens by preserving the edge pixels but skipping pixels in the middle.
Shrinking example: The SmallButton image is 22x22 pixels but if it gets re- used for the smaller "Pick" buttons, which are just 18 pixels hight, the rendered image will consist of the top 9 and bottom 9 rows of the BMP file. 4 rows of pixels in the middle are skipped.
Most icons don't have to be the size they have in Fusion's default skin. If they are larger, Fusion's GUI will sometimes adapt to that. Sometimes, however, they will be scaled down to fit.
Controls
Buttons
Buttons in Fusion exist in several varieties. Some are specified in the Controls/Button category. There's a "Medium", "Small" and "Tiny" subsection.
- "Medium" buttons are used in the spline editor and timeline views, as OK/cancel buttons in dialogs and for MultiButton input controls.
- "Small" buttons are used for the "pick" button (color picker or 3D transform)
- "Tiny" buttons are used for the expandable labels (the triangle icon is defined somewhere else though).
Each button needs 5 images: Normal, Selected, Disabled, Pushed and HoverMask. The selected button is usually the same as the normal one. Highlighting is done automatically by Fusion using the HoverMask. On mouse over, the button is drawn brighter and while the mouse button is held down it is drawn darker. If a MultiButton is clicked, it will be drawn in its "Pushed" state, usually this is blue in Fusion and looks slightly inset.
Button images are scaled automatically to their intended size using the intelligent resize algorithm described above.
The buttons of the time ruler are defined in a different section.
Checkbox
Hitbox specifies the area that reacts to mouse over and click events and thus the size and position of the checkbox and its label. This is the default hitbox of the Fusion 6.4 skin:
Data = { Hitbox = { 4, 3, -8, 15 }, },
- the first value specifies the left padding of the hitbox inside the widget.
- the second value specifies the top padding of the hitbox inside the widget.
- the third value specifies the width of the hitbox. A negative value specifies a dynamic width which is calculated by subtracting the absolute value from the width of the whole widget.
- the fourth value specifies the height of the hitbox.
The widget area will have a 1 pixel border that is already treated as inside the widget area.
The checkbox icon will be drawn #1 and #2 pixels from the top/left corner of the widget area and have a size of #4 by #4 pixels (the bitmap will be stretched intelligently if it has a different size). It will get clipped if width (#3) is too small or #4 too big.
The checkmark will be drawn with a left margin of 1 pixel inside the hitbox.
The bottom padding seems to be hardcoded as 3 pixels. To make everything symmetrical and fit into the GUI, it's recommended to keep all the values and the size of your bmp files the same as in Fusion's default skin.
Sliders
Slider knobs are defined in two locations. The first one is in the obvious Controls / Slider category. A slider has a knob and a track bitmap. The track bitmap will be expanded horizontally like control window titles (see below). It also defines a "Reset" bitmap which is the small circle that denotes the default value once a slider has been changed.
This is the slider data table:
Data = { Size = { 100, 33 }, Hitbox = { 16, -18, -86, 16 }, Edit = { -54, -19, 52, 18 }, Label = { 3, 1, -65, 14 }, Reset = { 0, 1 }, },
The edit box is using negative x and y offsets which aligns it to the bottom/right corner of the widget area instead of the top/left one. For more about the hitbox coordinates please refer to the Checkbox section above.
The "Label" attribute defines the position of the text label. If it is missing, it will be positioned below the slider (which was the default look in early versions of Fusion). Fusion 6 changed this to be above the slider but this needs to be defined in the skin. As with the hitbox, a negative width value is interpreted as a right padding. The label area may contain two labels in which case one is left-aligned and the other is right-aligned (see the merge tool's Additive/Subtractive slider.)
Slider knobs are also defined in the Controls / Color category which defines the color wheel/picker widget. You can define your own bitmaps for the red, green, blue and alpha slider. The data table is more complex:
Data = { Hitbox = { 88, 19, -156, 14 }, HitboxBitmap = { 83, 22, -145, 6 }, Edit = { -54, 17, 52, 18 }, Label = { 6, 1, -12, 13 }, Button = { 4, 17, 60, 18 }, ColorLabel = { 70, 19, 16, 15 }, ColorGap = { 0, 20 }, ColorGapLast = { 0, 3 }, },
- Hitbox is the hitbox of the topmost color slider (usually red). It doesn't seem to align with the actual area that can be clicked so there must be some additional padding which might explain the different coordinates for HitboxBitmap.
- Edit is the edit box to the right. A negative x value is interpreted as relative to the right edge of the widget area.
- Label is the position of the main text label while ColorLabel is the position of the first slider's label (usually "R" for red).
- Button defines the location and size of the tiny dropdown button that expands the whole color wheel.
- ColorGap defines the space between color sliders. A y value of 0 draws them all on top of each other.
- ColorGapLast defines additional padding below the last color slider.
ComboControls
ComboControls ("dropdowns") can't be styled with bitmaps except for the triangle icon. They probably get their bevel color from somewhere else as well. In Fusion's default skin file, there's only this data block which contains dimensions for a dropdown with label above ("vertical") or to the left ("horizontal"):
Data = { ComboVertical = { 3, 18, -6, 271 }, LabelVertical = { 6, 1, -9, 14 }, ComboHorizontal = { 100, 3, -104, 271 }, LabelHorizontal = { 6, 7, 80, 14 }, },
- The 1st and 2nd numbers once again denote the top/left padding.
- The 3rd number is the width. As previously described, a negative value is a dynamic width that depends on the width of the tool control panel.
- The 4th number is the height of the expanded dropdown menu. If it's too small for the number of menu items, a scrollbar will be added.
Gradient
A gradient control is like a color control with an extended data block:
Data = { Size = { 250, 168 }, Label = { 6, 1, -12, 13 }, MinButton = { 0, 15, -1, 39 }, MaxLabel = { -106, 59, 40, 15 }, MaxEdit = { -54, 57, 52, 18 }, Hitbox = { 88, 87, -156, 18 }, HitboxBitmap = { 83, 92, -145, 6 }, MaxButton = { 4, 87, 60, 18 }, Edit = { -54, 87, 52, 18 }, ColorLabel = { 70, 89, 16, 15 }, ColorGap = { 0, 20 }, ColorGapLast = { 0, 3 }, },
- 2nd value of the "Size" attribute specifies the height of the whole widget in its collapsed form. If the number is too small, the color sliders will be hidden behind the next input (gradient interpolation method multibutton).
- Label is the "Gradient" label at the top.
- MinButton seems to be the gradient image itself.
- MaxLabel is the "Position" label below that gradient and MaxEdit is its edit field.
- MaxButton is what "Button" was for the color control: the expander for the full color wheel.
- Hitbox, HitboxBitmap, ColorLabel, ColorGap and ColorGapLast are the same as for a color control.
Offset
Offset controls are the X/Y position inputs. They can't be styled with bitmaps. Their data block contains the positions for the first (X) and second (Y) input field and the position of its label.
Range
A range control is a bar with two handles on either side and is used to define a range of values. When used in a Loader tool, it also has special bitmaps to denote frame duplication or looping.
The bitmaps it needs are a track, two caps and differently colored bars. Those are tiled horizontally to stretch the bar to the required width.
Knob = { "Range\\RangePlain.bmp", "Range\\RangeGreen.bmp", "Range\\RangeBlue.bmp", "Range\\RangeDarkBlue.bmp", },
- The 1st bitmap is the default bar.
- The 2nd bitmap is used extends the gray bar in Loaders that are using the "Hold First Frame" or "Hold Last Frame" feature.
- The 3rd and 4th bitmap are alternated to indicate a looped clip in the Loader.
The track bitmap is used as a background image aligned to the whole widget. It will be tiled like window titles (see below) and needs to have all of its top, left and right padding included in the bitmap. This makes it different from slider track bitmaps which are aligned based on the slider's hitbox.
The RangeControl has the following data block:
Data = { Size = { 100, 34 }, Hitbox = { 62, 16, -125, 15 }, MinEdit = { 2, 14, 52, 18 }, MaxEdit = { -54, 14, 52, 18 }, Label = { 6, 1, -12, 14 }, RangeLabel = { 66, 4, -132, 14 }, },
- MinEdit and MaxEdit define the input fields to the left and to the right of the range bar.
- Label describes the area of the two labels above the input field. The first one will be left-aligned and the second one will be aligned to the right side of the box described by these coordinates (third value is negative to achieve a dynamic width).
- RangeLabel describes the area of the labels above the range bar itself. Depending on the attributes of the RangeControl, there can be a centered label or there can be three labels (left, center, right-aligned).
- The Hitbox describes the area where the range bar will be painted. It will contain both caps and the bar in between.
- The 2nd value of "Size" describes the height of the range widget and is used to define where the following input control will be painted.
Screw
Screw controls are like sliders but they don't have a specific start or end value. Most can move indefinitely. They have a main bitmap image which simply gets tiled horizontally to achieve the required width.
Screw controls have the following data table:
Data = { Size = { 100, 32 }, Hitbox = { 17, -14, -87, 11 }, Edit = { -54, -18, 52, 18 }, Label = { 6, 1, -60, 14 }, LeftOffset = { -13, -1 }, RightOffset = { -1, -1 }, Reset = { 0, 2 }, },
- Edit, Label and Reset are known from slider controls.
- LeftOffset and RightOffset are the positions of the left and right arrows, relative to the hitbox.
- Reset is the offset of the reset icon.
Titles
Control window titles have a different mechanism to stretch to any width. The bmp files have two red dots (r=255, g=0, b=0) and two green dots (r=0, g=255, b=0) in their first and last row respectively. These markers are used to mark the vertical pixel column that will be repeated to achieve the desired width.
The width of the bmp files themeselves doesn't matter. The height is 19 pixels by default but they can be larger. Control window titles have an arrow icon that is defined in two states (opened and closed) but if your title image already contains an icon (as is the case with the default Fusion 6.1 skin) you may replace these icons by transparent bitmaps.
The 'Title' section has the following data table:
Data = { ArrowPos = { 6, 6 }, TitlePos = { 24, 3 }, ModesPos = { -6, 3 }, },
The coordiantes are horizontal and vertical pixel offsets for the text labels and the modes icons (negative x value denotes a margin relative to the right edge of the widget area). The whole widget area is rendered with a 1 pixel margin inside the bevelled tool control panel. Fusion generates a dimmed version of the bitmaps for pass-through (disabled) tools.
The title icons (Locked, Info, and so on) are overlaid onto the title bar when the tool is locked, has a script or a comment. The Locked icon is also used as the button that locks/unlocks a tool. However, the DiskCacheIcon is only used for the tool title. The cache button's icon is taken from the Flow.Tiles category instead.
Flow
The flow section defines the colors of tools in the flow view as well as icons which are rendered onto tool tiles when a certain mode is enabled or a tool is locked or has comments. They are all miniature icons that will be renderd 11x11 pixels in size. Attention: the DiskCacheIcon is also used in the tool control panel and thus needs to be at least 16x16 pixels.
TimeSlider/Transport
This section defines the time ruler at the bottom and the playback controls that appear in the bottom right corner when you select a loader or saver. The playback icons are pretty self-explanatory. The buttons just differ from buttons in the control panels in certain ways. For one, the playback buttons are not generated by placing an icon over a gray or blue button template. Instead, each state (pushed, active, disabled, ...) needs to be supplied as custom bitmaps.
The buttons that have text on them are generated like tool buttons, however you can define custom bitmaps in this section. This might be useful and/or necessary to make sure that they have the same height as the playback buttons.
Toolbars
The toolbar background image needs to be 24 pixels high because it will be re- used for vertical toolbars. Separators and the draggable knob will be rendered internally by Fusion. The icons of the file and view bars are 16x15 pixels in size and have an alpha channel. They are combined in two strips, each exists as a cold (normal) and hot (mouse-over) state as FileBarHot/Cold.bmp and ViewBarHot/Cold.bmp. The disabled state (no comp opened) is rendered automatically.
The FileBar bitmap of Fusion's default skin is 16 pixels high, but only the first 15 are used. The reason for them not being 16x16 pixels is that Fusion renders a small drop-shadow on mouse over.
Icons
The icons section defines a variety of icons that are used throughout Fusion's GUI. Here are some of them:
- Icons.Browse is the folder icon that is used to browse for footage in a Loader or Saver.
- Icons.Tracker contains various icons for the Tracker tool. The forward/reverse buttons require cold and hot versions of the icon. However, Fusion will desaturate the cold version internally so you can get away with using the same icon twice. The track button icons in Fusion's theme are 40x24 pixels which is too large, forcing Fusion to scale them down. 33x17 pixel icons retain their sharpness.
- Icons for the file dialog need to be 16x16 pixels so they appear on their buttons without being scaled. The native size of the AddFavorite icon, however, is just 15x15 pixels.