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.
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.

-- 
Cin mailing list
Cin@lists.cinelerra-gg.org
https://lists.cinelerra-gg.org/mailman/listinfo/cin

Reply via email to