
To implement a GUI, there are a number of widgets provided in the support library (text edit box, rotary knob, slider, selector, pushbutton, checkbox, etc). Given that ItfWindowSlave interface, a plug-in can also implement custom widgets. The widgets, in turn, use the retained-mode scene graph to describe what they look like. Changing what's drawn typically means updating the text or image of an element on screen, or moving/scaling/rotating it. Because the host typically uses an accelerated graphics API to render the GUI, things like bitmap transparency and rotation are basically "free" (no extra cost).
The widgets are implemented entirely in terms of ItfElement (bitmap and text) and ItfWindowSlave. This means that an effect can provide a totally custom GUI using the same interfaces, without using the support library widget kit. Thus, the interfaces ItfElement, ItfText, ItfBitmap, ItfPolygon and ItfLineList make up the entirety of the interface exposed by the host, and ItfWindowSlave makes up the entirety of the interface exposed by the plug-in. The convenience classes that simplify programming with SAPS are not part of the formal interface specification, but part of the SAPS SDK.
The support library contains widgets to implement knobs etc. These widgets update values to the base effect by posting events to the parameters through the host. This allows the host to record events, providing parameter automation capability. While interaction with the mouse in real time cannot be done at sample accuracy, later editing, or interactions from hardware controllers such as MIDI keyboards or USB user interface surfaces can be sample precise from the get-go.
class ItfElement { public: /* Remove the element, and dispose it so it can't be used again. */ virtual void Dispose() = 0; /* Return the window the element is attached to, or NULL. */ virtual ItfWindow * Window() = 0; /* Remove the element from its window (if any), but keep it around (you can later add it back). */ virtual void Remove() = 0; /* Given a window coordinate, test whether the element was hit by that point, and if so, */ /* calculate element-relative coordinates (which is not trivial for rotated elements). */ virtual bool PointHit(Pixels x, Pixels y, Pixels *ox, Pixels *oy) = 0; /* Return the reference point, in element coordinates, around which the element is rotated and positioned. */ virtual void RefPoint(Pixels *ocx, Pixels *ocy) = 0; /* Set the reference point, in element coordinates, around which the element is rotated, and which is positioned with SetPosition(). */ virtual void SetRefPoint(Pixels cx, Pixels cy) = 0; /* Return the position, in window coordinates, of the reference point of the element. */ virtual void Position(Pixels *ox, Pixels *oy) = 0; /* Set the position, in window coordinates, of the reference point of the element. */ virtual void SetPosition(Pixels x, Pixels y) = 0; /* Return the size, in element coordinates, of the element. */ virtual void Extent(Pixels *ow, Pixels *oh) = 0; /* Return the rotation, in radians counter-clockwise, of the element. */ virtual Radians Rotation() = 0; /* Set the rotation, in radians counter-clockwise, of the element. */ virtual void SetRotation(Radians r) = 0; /* Return the tint of the element. The "add" value is added to each pixel, the "multiply" value is multiplied into each pixel. */ /* Note that these values may be greater than 1, or less than 0! */ virtual void Tint(Color *outAdd, Color *outMultiply) = 0; /* Set the tint. The "add" values are added to each pixel; the "multiply" value is multiplied into each pixel. */ virtual void SetTint(Color add, Color multiply) = 0; /* Turn off or on whether the slave should receive notifications about the mouse moving over this element. */ virtual void SetWantsMouse(bool wantsMouse) = 0; /* Return whether the slave should receive notifications about the mouse moving over this element. */ virtual bool WantsMouse() = 0; /* Aah! Some data in an interface! This data is for use by the effect/plug-in implementer, and not touched by the library or host. */ void *UserPtr; }; struct BitmapInfo { void const *Pixels; // Pointer to pixels. Pixels are stored in the BGRA byte order. size32 Pitch; // how many bytes per row (which may be more than 4 * width) size32 Width; // how many columns of pixels. Column 0 is at the left. size32 Height; // how many rows of data. Row 0 is at the top. }; class ItfBitmap { public: /* Return the element that can actually be added/positioned. */ virtual ItfElement * Element() = 0; /* Fill the bitmap with some data. */ virtual void SetData(BitmapInfo const &info, size32 left = 0, size32 top = 0) = 0; }; class ItfText { public: /* Return the Element that can actually be placed in the window. */ virtual ItfElement * Element() = 0; /* Update the text of the element. The original size constraints are still used. */ virtual void SetText(TextInfo const &info) = 0; /* Return the text */ virtual wchar_t const * Text() = 0; /* Given a point (in widget-relative coordinates), return which character that points at. */ /* This is offset half a character, to be properly used when drag-selecting text. */ virtual size32 CharacterFromPoint(Pixels x, Pixels y) = 0; /* How tall is a line in the current text? */ virtual Pixels LineHeight() = 0; /* Given a character index (from 0 to length-1), what is the rectangle that encloses that character? */ virtual void RectFromCharacter(size32 ix, Pixels *oLeft, Pixels *oRight, Pixels *oTop, Pixels *oBottom) = 0; /* Given a character index (from 0 to length-1), what line is that character part of? */ virtual size32 LineFromCharacter(size32 ix) = 0; virtual size32 LineCount() = 0; /* Given a line, what index does the character have that starts that line? */ virtual size32 LineStartCharacter(size32 line) = 0; /* Get the selection (highlighted area). If there is no selection, return false. */ virtual bool Selection(size32 *ostart, size32 *oend) = 0; /* Set the selection (highlighted area). */ virtual void SetSelection(size32 start, size32 end) = 0; }; enum TextAdjust { TextAdjustNormal = 0, TextAdjustCenter = 1, TextAdjustReverse = 2, }; struct TextInfo { size64 StructSize; // sizeof(TextInfo) wchar_t const *Text; // non-terminated string size32 Length; // wcslen(text) Pixels MaxWidth; // Maximum width. If 0, use window width. Pixels MaxHeight; // Maximum height. If 0, use infinite height. Pixels PointsSize; // How many points is the text? (9pt is small but readable; 12 pt is common) bool Bold; // Is the text fattened? bool Italic; // Is the text italic/slanted/oblique? bool Monospace; // Is the text monospace? bool FullRect; // Will the element always use the full rect specified by MaxWidth/MaxHeight, // even if it fits in a smaller rect? bool RightToLeft; // Is the text in a right-to-left script? bool TopToBottom; // Is the text in a top-to-bottom script? byte Adjust; // Normal (Left for Latin), Center, Reverse (Right for Latin) };