[Cin] Cinelerra context help - a complete implementation

Andrea paz gamberucci.andrea at gmail.com
Mon May 10 10:52:35 CEST 2021


To put Context Help on the manual, I thought I would put it at the
beginning of chapter 18. I used sge's exact words with some cut-outs
and minor edits since they are clear and precise. Do you think it's
okay or is it better to do further editing?

PS: I have changed the position of "CD Ripper", thank you.
-------------- next part --------------
18.1 Help and Context Help

CinGG is a complex and feature-rich program. Using a guide is indispensable. The official manual (in English) can be found in PDF and HTML format:

www....
www....

From within the program, you can invoke Context Help, which references sections of the HTML manual. [* thanks to sge]

Context help can be requested from almost any Cinelerra window or subwindow by pointing with the mouse cursor on the GUI element of interest and pressing Alt+h. That HTML manual page will be shown via the configured web browser, which is assumed as most relevant to the GUI element being currently under the mouse pointer.
 
18.1.1 How it works

The hotkey to request context help is Alt+h. What particular help page is shown, depends on the mouse cursor location while Alt+h is pressed. Usually, when the mouse is located in some window or dialog, the help page related to the functionality of this window or dialog is shown. In this case the mouse can point either on some widget, or on an empty area in the window. In Cinelerra GUI there are several rich loaded windows, Timeline and Compositor for example. In such a case different help pages can be requested depending on the particular GUI element under the mouse. For example, pressing Alt+h while pointing on the Autos curve in a track would show help on automation keyframes, pointing on the Overlay mode button in the patchbay would show help on overlays, pointing on the camera control in Compositor would show help on camera and projector.

If no context dependent help page is found, the manual page of Contents itself is shown.

18.1.2 Requesting context help for plugins

There are following possibilities to request help page for the particular plugin of interest.

1) Pressing Alt+h with mouse in the dialog window of plugin settings

2) Pressing Alt+h while pointing with the mouse on the plugin bar in a track (or transition bar, or transition icon)

3) Pressing Alt+h while pointing on the plugin name (icon) in the Resources window. If plugin tooltips are on, help for the highlighted (plugin under mouse) is shown. If plugin tooltips are off, help for the selected plugin is shown (it is made so, because in the latter case it would be difficult to figure out, without a visual feedback, which particular item is currently under mouse).

4) Pressing Alt+h while pointing on the plugin name in the Attach Effect dialog

18.1.3 Requesting context help on Contour Shuttle

Contour Shuttle has no Alt+h, yeh. Nevertheless, its help page can be requested by simultaneous pressing both Alt keys (left and right) on the keyboard followed by pressing any button on the Contour Shuttle. Here, pressing both Alt keys is necessary due to the way of X11 to track the status of modifiers. To cancel this mode, press any single modifier key (Alt, Ctrl or Shift) once.

18.1.4 How it works, from the programmer's point of view

All class methods related to context help start with the common pattern "context_help" in their names. It is easy to get all their occurences in the code with the following command (example):

grep -F context_help `find . -name '*.[Ch]' -print`

The base functionality is defined in several BC_WindowBase class methods in guicast/bcwindowbase.C (search on "context_help"). All BC_Window's and BC_SubWindow's inherit these methods, and IMHO one can hardly imagine a reason to overload them anywhere.

For the simplest case of context help definition, it is sufficient to add the call to context_help_set_keyword() in the most inclusive widget constructor. If Alt+h is pressed with the mouse over this widget's window, its keypress_event() method (inherited from BC_WindowBase) will catch this hotkey, fetch the keyphrase defined by context_help_set_keyword() and call the doc/ContextManual.pl script with this keyphrase. Then ContextManual.pl script does the whole processing of the keyphrase given and calls web browser to display the found HTML manual page. The browser is called in background to prevent from blocking the calling Cinelerra thread.

An example from cinelerra/zoombar.C:
ZoomBar::ZoomBar(MWindow *mwindow, MWindowGUI *gui)
 : BC_SubWindow(...)
{
    this->gui = gui;
    this->mwindow = mwindow;
    context_help_set_keyword("Zoom Panel");
}

If Alt+h is pressed with the mouse over some subwindow (arbitrary depth) of the context_help_set_keyword() caller, the keypress_event() method of that subwindow catches the hotkey. Its own context help keyword, probably, will be empty. In this case the whole widget hierarchy is traced up to top_level widget, their context help keywords are checked, and the first nonempty keyword is used for context help.

This approach allows us to define the help keyword common to the whole dialog window with a bunch of diverse buttons with a single call to context_help_set_keyword(), without placing such a call into the each button constructor. And in the same time, this approach allows to assign different help keywords to GUI elements belonging to the same window but documented in different manual pages.

18.1.4.1 An example with several different help keywords from cinelerra/mwindowgui.C:

MWindowGUI::MWindowGUI(MWindow *mwindow)
 : BC_Window(_(PROGRAM_NAME ": Program"), ...)
{
    this->mwindow = mwindow;
    ...
    context_help_set_keyword("Program Window");
}
...
FFMpegToggle::FFMpegToggle(MWindow *mwindow, MButtons *mbuttons, int x, int y)
 : BC_Toggle(...)
{
    this->mwindow = mwindow;
    this->mbuttons = mbuttons;
    set_tooltip(get_value() ? FFMPEG_EARLY_TIP : FFMPEG_LATE_TIP);
    context_help_set_keyword("FFmpeg Early Probe Explanation");
}
...
StackButton::StackButton(MWindow *mwindow, int x, int y)
 : BC_GenericButton(x, y, mwindow->theme->stack_button_w, "0")
{
    this->mwindow = mwindow;
    set_tooltip(_("Close EDL"));
    context_help_set_keyword("OpenEDL");
}
...
ProxyToggle::ProxyToggle(MWindow *mwindow, MButtons *mbuttons, int x, int y)
 : BC_Toggle(...)
{
    this->mwindow = mwindow;
    this->mbuttons = mbuttons;
    ...
    context_help_set_keyword("Proxy");
}

If the widget we wish to add context help to, overloads keypress_event() of the base class with its own method, then it is necessary to introduce a small addition to its keypress_event() handler: the call to context_help_check_and_show() has to be added in a suitable place in the handler.

An example with context_help_check_and_show() from cinelerra/mbuttons.C:
int MButtons::keypress_event()
{
    int result = 0;
    if(!result) {
        result = transport->keypress_event();
    }
    if(!result) {
        result = context_help_check_and_show();
    }
    return result;
}

All the keypress handlers are not equal, therefore we provide different variants of the methods context_help_check_and_show() and context_help_show() (the latter for explicit checking on hotkey).

An example with context_help_show() from cinelerra/editpanel.C:
int EditPanelTcInt::keypress_event()
{
    if( get_keypress() == 'h' && alt_down() ) {
        context_help_show("Align Timecodes");
        return 1;
    }
    ...further processing...
    return 1;
}

A single example of much more sophisticated keypress_event() handler can be found in cinelerra/trackcanvas.C (search on context_help). The problem here was to track the particular object drawn on the canvas to figure out whose context help is to be requested. Another rare example of difficulty may appear when context help is desired for some GUI object which is not subclassed from BC_WindowBase.

ContextManual.pl looks for occurence of keyphrases in the following order:

1) In Contents.html
2) In Index.html
3) In all the CinelerraGG_Manual/*.html files via grep

Keyphrase matching is tried first exact and case sensitive, then partially and case insensitive. The special keyword "TOC" shows Contents, "IDX" shows Index. If the keyword starts with "FILE:", the filename after "FILE:" is extracted and that file is shown. You can look in the ContextManual.pl script text.

For debugging purposes the script can be called from command line. For this to work, the environment variable $CIN_DAT has to be set to the parent directory of doc.

18.1.4.2 Providing context help for plugins

In the simplest case, nothing has to be done at all. The plugin context help functionality introduced in cinelerra/pluginclient.C automatically assigns context help keyword from the plugin's title for all plugins subclassed from PluginClient. For this to work, the manual page documenting the plugin must be entitled identically to the programmatic title of the plugin. A special treatment can be necessary in the following cases:

1) Rendered effects are not subclasses of PluginClient and require an explicit context help definition via context_help_set_keyword()

2) Only the main plugin dialog inherits context help functionality from the parent class. If a plugin opens additional dialog windows, they probably require explicit context help definitions.

3) If the plugin title differs from its subsection title in the documentation, either its help keyword or the corresponding title in the manual should be renamed. Another possibility can be an addition to the %rewrite table in doc/ContextManual.pl.

4) If the plugin title contains some characters special for HTML and/or Perl regular expression syntax, the special characters have to be escaped. For example, the keyphrase corresponding to the title "Crop & Position (X/Y)" should be converted to "Crop & Position \\(X\\/Y\\)". Such a rewriting can be done either in the C++ code or in ContextManual.pl.



More information about the Cin mailing list