Knobs are the fundamentals of all user interface elements available to NUKE Ops. They provide mechanisms for user interaction in both the Viewer and the Properties panels, along with storing and accessing data in the NUKE script file.
In previous sections, we’ve come across various subsets of the knobs on offer and their capabilities. In this section we’ll take a look at the full range of built in knobs offered, their usage and customisation options, and then move on to building custom knobs from scratch.
Knobs fall into three broad categories:
Using the first type involves declaring appropriate data storage as a member variable of the Op, initialising it in the Op constructor and then passing it by address on knob creation. The member variable is subsequently synchronised with the interface value before multithreaded data access calls, such as engine(). At other times the knob object itself can be accessed using knob(“<name>”), though bear in mind this should be done only from calls in the main thread. Note that the knob does not directly employ the variable passed for internal storage, rather it is used during the knob’s call to set the default value and for synchronization.
The second type is obviously pretty simple - call the appropriate knob constructor and you’re good to go.
Working with the final type is generally fairly specific to the knob in question, but normally follows the same basic form. All of these knobs have a ‘<knobname>I.h’ header file associated with them which provides the various methods that particular knob offers. Each of these uses a knob pointer dependent on class, which is obtained from the knob pointer using a knob-><knobname> call. Most of these knobs need to be configured on creation, so you’ll often need to use a snippet similar to the following:
Knob* tableKnob = Table_knob(f, "Table_knob");
if (f.makeKnobs()) {
Table_KnobI* tableKnobI = tableKnob->tableKnob();
tableKnobI->addColumn("col1", "col1", Table_KnobI::FloatColumn, true);
tableKnobI->addColumn("col1", "col1", Table_KnobI::FloatColumn, true);
}
Here the Knob_Callback (named f) is used to determine if the knobs call is in creation mode, and then only when in this mode is the Table_knob object manipulated.
All knobs, with the exception of one or two layout types, take a name char* on construction. This means the knob can be:
An additional ‘label’ char* can be provided so that the interface panel can use a different string to the full name (generally for brevity). In the NUKE interface, the name is obtained by hovering over a control - the first entry on a tooltip is always a bold formatted name for that knob.
Good practice when creating knob names includes: