home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 16 / 16.iso / w / w055 / 4.ddi / SOURCES.LIF / HELP.PEL < prev    next >
Encoding:
Text File  |  1990-09-27  |  27.7 KB  |  1,053 lines

  1. # $Header:   P:/source/ppee/macros/help.pev   1.68   24 Sep 1990 17:24:50   skipr  $
  2.  
  3. ##############################################################################
  4. #
  5. #           Sage Software - POLYTRON Division
  6. #             1700 NW 167th Place
  7. #               Beaverton, OR 97006
  8. #
  9. #   Copyright 1990, Sage Software, Inc.
  10. #
  11. #   Permission is hereby granted for licensed users of Sage Professional
  12. #   Editor and PolyAwk to copy and modify this source code for their own
  13. #   personal use.  These derivative works may be distributed only to other
  14. #   licensed Sage Professional Editor and PolyAwk users.  All other usage
  15. #   is prohibited without express written permission from Sage Software.
  16. #
  17. ##############################################################################
  18.  
  19.  
  20. #### $Workfile:   help.pel  $: help menus
  21.  
  22.  
  23. global    BAR_COLOR    = 0x0030    # color of top bar line and pulldown windows
  24. global    HBAR_COLOR    = 0x004F    # color of highlighted items
  25. global    TBAR_COLOR    = 0x0013    # color of factory window title bar
  26. global    SHADOW_COLOR    = 0x0008    # color of window shadows
  27.  
  28. local    help_offsets;            # offsets of items on title bar
  29. local    help_length;            # lengths of each item on title bar
  30. local    help_list;            # list of all items in pulldown menus
  31. local    help_names;            # names on title bar
  32. local    help_names_length;        # length of all items on title bar
  33. local    help_heights;            # number of entries for each pulldown menu
  34. global    help_resident = 0        # 1 if help bar is to remain
  35.  
  36. local    MINUS = 45
  37. local    ALT_H = 0x2300
  38.  
  39. local    SEPARATOR = ""        # name separator in help file
  40. local    MAX_INDEX;        # number of entries on top line
  41. local    help_index;        # index into top line entries
  42. local    pulldown_index;        # index into pulldown menu
  43. local    pulldown_window = 0;    # current pulldown window
  44. local    pulldown_shadow = 0;    # current pulldown shadow window
  45. local    pulldown_width;        # width of text in current pulldown_window
  46. local    pulldown_height;    # height of text in current pulldown_window
  47. local    pulldown_x;        # starting x of pulldown window text
  48. local    pulldown_y;        # starting y of pulldown window text
  49. local    help_selection;        # if ENTER pressed, hold string of selection
  50. local    help_buffer = 0;    # buffer containing the help database
  51. local    help_calls;        # function names to call when a selection is made
  52. local    help_keymap;        # keymap to use during help
  53. local    help_window = 0;    # handle for top title bar
  54. local    help_mouse_handler_id=0;# id of mouse event handler
  55. local    helpInitialized = 0;    # indicates whether the help data structures
  56.                 # have been initialized
  57. local    save_last_window = 0;    # save the window before help was called
  58.  
  59.  
  60. local    item_window_x0 = 5    # current displayed help item coordinates
  61. local    item_window_y0 = 2
  62. local    item_window_width = 66
  63. local    item_window_height = 20
  64.  
  65.  
  66.  
  67. global menu_colors_initialized = 0;
  68.  
  69.  
  70. ## initialize menu and other system colors dependent upon the
  71. #    current display mode (7 = mono, !7 = assume color)
  72. #
  73. global function init_menu_colors(){
  74.  
  75.     if (!menu_colors_initialized) {
  76.         menu_colors_initialized = 1;
  77.  
  78.         # color of top bar line and pulldown windows
  79.         if (display_mode() == 7) {
  80.             # mono
  81.             BAR_COLOR    = 0x0007;
  82.             HBAR_COLOR   = 0x0070;
  83.             TBAR_COLOR   = 0x0070;
  84.             SHADOW_COLOR = 0x0007;
  85.         } else {
  86.             # color
  87.             BAR_COLOR    = 0x0030;
  88.             HBAR_COLOR   = 0x004F;
  89.             TBAR_COLOR   = and( default_color_text, 0xf0)    \
  90.                 ? 0x03                    \
  91.                 : 0x13
  92.             SHADOW_COLOR = 0x0008;
  93.         }
  94.     }
  95. }
  96.  
  97.  
  98.  
  99.  
  100. #--------------------------------------------------------------------------
  101. #
  102. # Help file format:
  103. #
  104. # Line
  105. #  1    Header line      - names that appear on title bar
  106. #  2    Menu items       - items for first name on line 1
  107. #  3    Function calls   - for items listed on line 2
  108. #  4    Menu items       - items for second name on line 1
  109. #  5    Function calls   - for items listed on line 4
  110. #  .
  111. #  .
  112. #  .
  113. #  2n   Menu items       - items for nth name on line 1
  114. #  2n+1 Function calls   - for items listed on line 2n
  115. #  2n+2 Menu headings    - names associated with information below
  116. #  2n+3 Menu information - any help info
  117. #   .
  118. #   .
  119. #   .
  120. #  2n+x
  121. #  2n+x+1 repeat lines 2n+2 to 2n+x
  122. #
  123. #
  124. # The field separator for all names is SEPARATOR ()
  125. #
  126. # "Header line"     - a list of names to appear on the top level title bar.
  127. # "Menu items"      - a list of names to appear in the pulldown window.
  128. #            The capital letter in each name can be used as an 
  129. #            excellerator key.  All names must be padded with 
  130. #            spaces to the same length or else the will appear
  131. #            scrambled when pulled down.
  132. # "Function calls"  - a list of function calls to make. If no call is to be 
  133. #            made, just leave it blank and add the field separator.
  134. #            If no function name is entered, the name that was 
  135. #            selected from a pulldown window is search for in
  136. #            the "Menu headings".  If one is found, the "Menu
  137. #            information" for that heading is displayed.
  138. # "Menu headings"   - a list of names that are associated with the "Menu
  139. #            information" listed below it; separated by .
  140. # "Menu information" - a text page (or more) of help information for the
  141. #            names listed in the associated "Menu headings" list.
  142. #
  143. #
  144. # To invoke a menu item directly from the title menu, leave the "Menu items"
  145. # blank but still add the function to invoke on the "Function calls" line.
  146. #----------------------------------------------------------------------------
  147.  
  148. ## invoke the help pulldown menus
  149. #
  150. global function help(){
  151.     pulldown_index = 0;
  152.     help_start( help_index > 0 ? help_index - 1 : 0);
  153. }
  154.  
  155.  
  156. ## install or remove the help title bar
  157. #
  158. #  0  == remove
  159. #  1  == install
  160. #  "" == toggle current setting
  161. #
  162. global function help_install( mode ){
  163.     local    resident = argcount() ? mode + 0 : !help_resident;
  164.     if (resident != help_resident) {
  165.         if (resident)
  166.             shrink_windows_down_1();
  167.         else
  168.             grow_windows_up_1();
  169.     }
  170.     help_resident = resident;
  171.     help_start( -1 );
  172. }
  173.  
  174. ## toggle the installation of the help menu bar
  175. #
  176. global function toggle_help( mode ){
  177.     if (argcount())
  178.         help_install( mode );
  179.     else
  180.         help_install();
  181. }
  182.  
  183.  
  184.  
  185. ## Initialize the help data structures to a given filename.
  186. #    No validation is made on the new file to ensure is actually
  187. #    is in the help file format.
  188. #
  189. global function help_init( fn ){
  190.     if (!argcount())
  191.         return;
  192.     help_install( fn );
  193. }
  194.  
  195. ## pulldown the index'th help item window immediately
  196. #
  197. global function help_immediate( index ){
  198.     pulldown_index = 1;
  199.     help_start( index );
  200. }
  201.  
  202.  
  203. #
  204. # Initialize the help data structures by opening the help file and
  205. # reading the initial title bar and pulldown selection names.
  206. #
  207. # This function can be called more than once with a different txtfile.
  208. # If txtfile == "" or none specified, the default name found in 
  209. # help_txt_name is used and searched for in the directory that
  210. # the environment variable SAGEEDIT points to.
  211. #
  212. local function help_initialize( txtfile ){
  213.     local    save_buffer = current_buffer;
  214.     local    names;
  215.     local    save_keymap = current_keymap;
  216.     local    i;
  217.     local    help_menu;
  218.     local    str;
  219.     local    eol_str;
  220.  
  221.  
  222.     init_menu_colors();
  223.  
  224.     # 
  225.     # free all of the previous data structures.
  226.     #
  227.     delete( help_names );
  228.     delete( help_calls );
  229.     delete( help_list );
  230.     delete( help_length );
  231.     delete( help_heights );
  232.     if (help_window)
  233.         delete_window( help_window );
  234.  
  235.     if (help_buffer)
  236.         delete_buffer( help_buffer );
  237.  
  238.     #
  239.     # try to open the help text file and put the data in a buffer
  240.     #
  241.     if (!argcount() || !txtfile) {
  242.         if ( !(txtfile = locate_sageedit_file(SAGEEDIT_FILE_HELP))) {
  243.             txtfile = editor_path( SAGEEDIT_FILE_HELP )
  244.         }
  245.     }
  246.  
  247.     eol_str = default_buffer_eol_string;
  248.     default_buffer_eol_string = "\r\n";
  249.     current_buffer = help_buffer = create_buffer( "", txtfile, 
  250.         BUFFER_READ_ONLY + BUFFER_NO_UNDO + BUFFER_SYSTEM );
  251.     default_buffer_eol_string = eol_str;
  252.  
  253.  
  254.     buffer_flags = and( buffer_flags, not(BUFFER_READ_ONLY) );
  255.     if (!buffer_size || !help_buffer) {
  256.         #
  257.         # the file is new, empty, or invalid
  258.         #
  259.         delete_buffer();
  260.         current_buffer = save_buffer;
  261.         warning( "No help available in file: %s", txtfile );
  262.         return FALSE;
  263.     }
  264.  
  265.     #
  266.     # read in the help header information.
  267.     #
  268.     MAX_INDEX = split( read_buffer(), help_names, SEPARATOR);
  269.     if (!MAX_INDEX) {
  270.         current_keymap = save_keymap;
  271.         current_buffer = save_buffer;
  272.         return FALSE;
  273.     }
  274.  
  275.     down();
  276.  
  277.     #
  278.     # initialize the lengths of each pulldown name and compute a total
  279.     # length of all names.
  280.     #
  281.     help_names_length = 0;
  282.     for (i in help_names)
  283.         help_names_length += (help_length[ i ] = length(help_names[i]));
  284.  
  285.     #
  286.     # read in all of the pulldown window items
  287.     #
  288.     for (i in help_names) {
  289.         #
  290.         # read in the pulldown names. They should already be padded
  291.         # with spaces to make them all the same length
  292.         #
  293.         help_list[i] = read_buffer();
  294.         help_heights[ i ] = gsub( "", "", help_list[i] );
  295.         down(1);
  296.         help_calls[ i ] = read_buffer();
  297.         down(1);
  298.     }
  299.  
  300.     #
  301.     # delete the header information from the buffer.
  302.     #
  303.     drop_anchor( NORMAL_SELECTION );
  304.     goto_buffer_top();
  305.     delete_chars();
  306.  
  307.     #
  308.     # create a keymap to use when the help is activated.
  309.     #
  310.     current_keymap = help_keymap = create_keymap( empty_keymap );
  311.  
  312.     assign_key( "<Up>",    "help_up" );
  313.     assign_key( "<Down>",    "help_down" );
  314.     assign_key( "<Left>",    "help_left" );
  315.     assign_key( "<Right>",    "help_right" );
  316.     assign_key( "<Esc>",    "help_esc" );
  317.     assign_key( "<Enter>",    "help_enter" );
  318.     assign_key( "<Keypad-Enter>",    "help_enter" );
  319.     assign_key( "<Alt-H>",    "help_enter" );
  320.  
  321.     assign_key( "#61440",  "left_press_help" )    # left press
  322.     assign_key( "#62208",  "left_release_help" )    # left release
  323.     assign_key( "#62976",  "left_click_help" )    # left click
  324.  
  325.     current_keymap = save_keymap;
  326.     current_buffer = save_buffer;
  327.  
  328.     return TRUE;
  329. }
  330.  
  331. #
  332. # help_start()
  333. #
  334. # Actually invoke the help system and display the top title bar
  335. # (if it isn't already).
  336. #
  337. # index >=  0 the pulldown menu to be displayed ( indices from 0..n )
  338. #    == -1 no pulldown, no highlight, just display title and return
  339. #
  340. local function help_start( index ) {
  341.     local   ch;
  342.     local    save_keymap;
  343.     local    save_window = current_window;
  344.     local    save_buffer = current_buffer;
  345.     local    save_buffer_keymap = buffer_keymap;
  346.     local    save_cursor_normal = cursor_normal;
  347.     local    save_cursor_virtual = cursor_virtual;
  348.     local    save_cursor_overtype = cursor_overtype;
  349.     local    save_cursor_virtual_overtype = cursor_virtual_overtype;
  350.     local    i;
  351.     local    unassign_key_event = function_id( "help_excellerator" )
  352.     local    spaces;
  353.     local    id_name;
  354.     local    more_help = 1;
  355.  
  356.     #
  357.     # delete the mouse event if there is one.
  358.     #
  359.     if (help_mouse_handler_id) {
  360.         delete_event( EVENT_NEW_CURNT_WINDOW, \
  361.             help_mouse_handler_id );
  362.         help_mouse_handler_id = 0;
  363.     }
  364.  
  365.  
  366.     #
  367.     # initialize the help data structures if they haven't been already
  368.     #
  369.     if ( !helpInitialized ) {
  370.         if ( !(helpInitialized = help_initialize()) ) {
  371.             restorePrevWindow();
  372.             return;
  373.         }
  374.     }
  375.  
  376.     # compute the amount of white space to go between each entry
  377.     i = MAX_INDEX > 1 ? MAX_INDEX - 1 : 1
  378.     spaces = (display_width - 1 - help_names_length) / i;
  379.  
  380.     help_selection = "";
  381.     pulldown_shadow = pulldown_window = 0;
  382.  
  383.     #
  384.     # create the top title bar window if it doesn't exist
  385.     #
  386.     if (help_window) {
  387.         current_window = help_window;
  388.     } else {
  389.         current_window = 
  390.         help_window =
  391.             create_factory_window( 0, 0, display_width, 1, WINDOW_NOBORDER + WINDOW_SYSTEM);
  392.     }
  393.     color_border = BAR_COLOR
  394.  
  395.  
  396.     #
  397.     # display the names in the title bar
  398.     #
  399.     display_update();
  400.     highlight_window( 0, 0, display_width, 1, BAR_COLOR, help_window );
  401.     window_cursor_x = 1;
  402.     window_cursor_y = 0;
  403.     for (i in help_names) {
  404.         help_offsets[ i ] = window_cursor_x;
  405.         write_window( help_names[ i ] );
  406.          window_cursor_x += spaces;
  407.     }
  408.  
  409.     #
  410.     # should a pulldown window be displayed?
  411.     #
  412.     if (index >= 0) {
  413.         # erase cursor
  414.         #
  415.         cursor_overtype = cursor_virtual_overtype = \
  416.             cursor_virtual = cursor_normal = 0x0FFFF;
  417.  
  418.         # help_indices run from 1 to n+1
  419.         help_index = 1 + index;
  420.  
  421.         help_show( help_index );
  422.  
  423.         while( more_help ) {
  424.             more_help = 0;
  425.             #
  426.             # swap keymaps and begin the help menu process
  427.             #
  428.             save_keymap = current_keymap;
  429.             current_keymap = buffer_keymap = help_keymap;
  430.             attach_event_handler( EVENT_UNASSGN_KEY, unassign_key_event );
  431.             process_begin();
  432.             delete_event( EVENT_UNASSGN_KEY, unassign_key_event );
  433.             current_keymap = save_keymap;
  434.  
  435.             #
  436.             # help is now done. Put back original keymap and restore 
  437.             # cursor.
  438.             #
  439.             buffer_keymap = save_buffer_keymap;
  440.             cursor_normal = save_cursor_normal;
  441.             cursor_virtual = save_cursor_virtual;
  442.             cursor_overtype = save_cursor_overtype;
  443.             cursor_virtual_overtype = save_cursor_virtual_overtype;
  444.             id_name = help_call_id();    # if an item was selected, what was is
  445.             if ((current_key == ALT_H) \
  446.                   || (help_selection && (id_name == ""))) {
  447.  
  448.                 # no associated function, try to display
  449.                 # some help information
  450.                 more_help = help_selection \
  451.                     ? display_help_item( help_selection ) \
  452.                     : TRUE;
  453.                 help_selection = "";
  454.             }
  455.         }
  456.         free_pulldown_window();        # free the pulldown window
  457.         help_xshow( help_index );    # clear highlighted title 
  458.     }
  459.  
  460.  
  461.  
  462.     if (window_valid(save_window)) {
  463.         current_window = save_window;        # restore original window.
  464.         current_buffer = save_buffer;
  465.     }
  466.  
  467.     # if the menu bar is NOT to remain, delete the window.
  468.      if (!(help_resident+0)) {
  469.          delete_window( help_window );
  470.          help_window = 0;
  471.      }
  472.  
  473.     restorePrevWindow();
  474.  
  475.      display_update()
  476.  
  477.     if (help_selection && (id_name != "")) {
  478.         # execute the associated function
  479.         execute_function( id_name );    
  480.     }
  481.  
  482.  
  483.     if (help_resident) {
  484.         #
  485.         # remain resident and install a mouse handler to
  486.         # allow invocation with a mouse
  487.         #
  488.         help_mouse_handler_id = function_id( "help_mouse_handler" );
  489.         attach_event_handler( EVENT_NEW_CURNT_WINDOW, help_mouse_handler_id );
  490.     }
  491. }
  492.  
  493.  
  494. ## <ESC> key was pressed from within a pulldown window.
  495. #
  496. # backup one level or exit if at the top level.
  497. #
  498. function help_esc(){
  499.     if (pulldown_window) {
  500.         free_pulldown_window();        # free the pulldown window
  501.         pulldown_index = 0;
  502.     } else {
  503.         process_end();
  504.     }
  505. }
  506.  
  507.  
  508. ## <Enter> key was pressed from within a pulldown window.
  509. #
  510. # Set "help_selection" to the name of the item which was pressed.
  511. #
  512. function help_enter(){
  513.     local    save_window = current_window;
  514.  
  515.     if (pulldown_index && pulldown_window) {
  516.         current_window = pulldown_window;
  517.  
  518.         window_cursor_x = 0;
  519.         window_cursor_y = pulldown_index - 1;
  520.         help_selection  = trim( read_window( pulldown_width ));
  521.  
  522.         assign_current_window( save_window );
  523.         process_end();
  524.     } else if (help_heights[ help_index ] == 0){
  525.         help_selection = help_names[ help_index ]
  526.         process_end();
  527.     } else {
  528.         help_down()
  529.     }
  530. }
  531.  
  532.  
  533.  
  534. ## process a down arrow press within a pulldown window
  535. #
  536. function help_down(){
  537.     help_vertical( (pulldown_index >= pulldown_height) \
  538.         ? 1 \
  539.         : pulldown_index + 1);
  540. }
  541.  
  542. ## process an up arrow press within a pulldown window
  543. #
  544. function help_up(){
  545.     help_vertical( (pulldown_index <= 1 ) \
  546.         ? pulldown_height \
  547.         : pulldown_index - 1);
  548. }
  549.  
  550.  
  551. ## move vertically within a pulldown window
  552. #
  553. # i == the i-th element in the window to display.
  554. #
  555. function help_vertical( i ){
  556.     if (pulldown_window) {
  557.         # a window is visible
  558.         if (pulldown_index) {
  559.             # an item is highlighted
  560.             highlight_window( 0, pulldown_index-1,    \
  561.                 pulldown_width, 1,         \
  562.                 BAR_COLOR, pulldown_window );
  563.             display_update();
  564.         }
  565.         pulldown_index = (i + 0);
  566.         if (pulldown_index) {
  567.             # a new item is to be highlighted
  568.             highlight_window( 0, pulldown_index-1,    \
  569.                 pulldown_width, 1,             \
  570.                 HBAR_COLOR, pulldown_window );
  571.             display_update();
  572.         }
  573.     } else {
  574.         # no pulldown window yet, display one now
  575.         # highlight the first item only if no left mouse press
  576.         if ( !and( mouse_buttons, LEFT_BUTTON ))
  577.             pulldown_index = 1;
  578.         help_pulldown( help_offsets[ help_index ], 1, help_index );
  579.     }
  580.     # flush_keyboard();
  581. }
  582.  
  583. ## Move left to a new pulldown window. Wrap if before left edge.
  584. #
  585. function help_left(){
  586.     if (pulldown_index)
  587.         pulldown_index = 1;
  588.     help_horizontal( -1 );
  589. }
  590.  
  591. ## Move right to a new pulldown window. Wrap if past the right edge.
  592. #
  593. function help_right(){
  594.     if (pulldown_index)
  595.         pulldown_index = 1;
  596.     help_horizontal( 1 );
  597. }
  598.  
  599. #
  600. # Move horizontally to a new pulldown window.
  601. #
  602. # i == the relative number of windows to move left or right.
  603. #
  604. function help_horizontal( i ){
  605.     help_xshow( help_index );
  606.     help_index += (i + 0);
  607.     if (help_index <= 0)
  608.         help_index = MAX_INDEX;
  609.     else if (help_index > MAX_INDEX)
  610.         help_index = 1;
  611.     help_show( help_index );
  612.     display_update();
  613.     # flush_keyboard();
  614. }
  615.  
  616. #
  617. # highlight the "help_index"-th name on the title bar and 
  618. # display a pulldown window if "pulldown_index > 0"
  619. #
  620. function help_show( help_index ){
  621.     highlight_window( help_offsets[help_index], 0, \
  622.             help_length[help_index], 1, HBAR_COLOR );
  623.     if (pulldown_index)
  624.         help_pulldown( help_offsets[ help_index ], 1, help_index );
  625. }
  626.  
  627. #
  628. # unhighlight the "help_index"-th name on the title bar and 
  629. #
  630. local function help_xshow( help_index ){
  631.     free_pulldown_window();
  632.     highlight_window( help_offsets[help_index], 0, \
  633.             help_length[help_index], 1, BAR_COLOR );
  634. }
  635.  
  636. #
  637. # help_pulldown(x,y,index)
  638. #
  639. # Display a pulldown window with all names.
  640. # If "pulldown_index" > 0, highlight that element in the window.
  641. #
  642. # index == the i-th window to pulldown
  643. # x     == left edge of window
  644. # y     == top line of window
  645. #
  646. local function help_pulldown( x, y, index ){
  647.     local    maxlength = 0;
  648.     local    save_window = current_window;
  649.     local    list = help_list[ index ];
  650.  
  651.     #
  652.     # determine the height and width of the window
  653.     #
  654.     pulldown_height = help_heights[ index ];
  655.  
  656.     free_pulldown_window();        # free any current pulldown window.
  657.  
  658.     if (pulldown_height == 0) {
  659.         pulldown_index = 1;
  660.         return
  661.     }
  662.  
  663.     pulldown_width = maxlength = length( list ) / pulldown_height;
  664.     maxlength += 2;        # add 2 for borders
  665.  
  666.     # adjust "x" so it fits on the display
  667.     if (x+maxlength > display_width)
  668.         x = display_width - maxlength;
  669.  
  670.  
  671.     #
  672.     # create a black pulldown shadow window
  673.     #
  674.     pulldown_shadow =
  675.     current_window  =
  676.         create_factory_window( x+1, y+1, maxlength, pulldown_height+2, WINDOW_NOBORDER );
  677.     color_text = 0x0000;
  678.  
  679.     #
  680.     # create the new pulldown window
  681.     #
  682.     pulldown_window = 
  683.     current_window  =
  684.         create_factory_window(  pulldown_x = x, 
  685.                 pulldown_y = y, 
  686.                 maxlength, 
  687.                 pulldown_height+2, 
  688.                 WINDOW_BORDER );
  689.     color_text = BAR_COLOR;
  690.     color_border = BAR_COLOR;
  691.  
  692.     #
  693.     # write the list of name to the window.
  694.     #
  695.     display_update();
  696.     window_cursor_x = window_cursor_y = 0;
  697.     write_window( list, pulldown_window );
  698.  
  699.     if (pulldown_index) {
  700.         #
  701.         # highlight an element in the window.
  702.         #
  703.         window_cursor_x = window_cursor_y = 0;
  704.         highlight_window( 0, 0, pulldown_width, 1, HBAR_COLOR );
  705.         # flush_keyboard();
  706.     }
  707.  
  708.     assign_current_window( save_window );
  709.     display_update();
  710. }
  711.  
  712. #
  713. # Free the current pulldown window and its shadow window (if they exist)
  714. #
  715. local function free_pulldown_window(){
  716.     if (pulldown_window) {
  717.         delete_window( pulldown_window );
  718.         delete_window( pulldown_shadow );
  719.     }
  720.     pulldown_shadow = pulldown_window = 0;
  721. }
  722.  
  723. #
  724. # determine what to do when an item is selected
  725. #
  726. # Returns:
  727. #    str id_name = the name of the associated function to execute.
  728. #            = "" if nothing to do.
  729. #
  730. local function help_call_id() {
  731.     local    help_call_array;
  732.     local    id_name;
  733.     local   index;
  734.  
  735.     #
  736.     # determine the associated function for the current 
  737.     # help_index and pulldown_index.
  738.     #
  739.     split( help_calls[ help_index ], help_call_array, SEPARATOR );
  740.     index = pulldown_index;
  741.     if (!index) index++;
  742.     id_name = (index in help_call_array)     \
  743.         ? help_call_array[ index ]    \
  744.         : ""
  745.     delete( help_call_array );
  746.     return id_name;    
  747. }
  748.  
  749. #
  750. # given a name, look through the remainder of the help file for
  751. # "" name "".  If one is found, display the help information for it.
  752. #
  753. global function display_help_item( name ){
  754.     local    save_buffer = current_buffer
  755.     local    found = FALSE;
  756.     local    first_line, last_line;
  757.     local    ch;
  758.     local     display_window;
  759.     local    display_buffer;
  760.     local    continue_help = FALSE;
  761.  
  762.  
  763.     if ( !helpInitialized )
  764.         if ( !(helpInitialized = help_initialize()) )
  765.             return;
  766.  
  767.     name = tolower(ltrim(trim( name )))
  768.  
  769.     current_buffer = help_buffer;
  770.     goto_buffer_top();
  771.     goto_bol();
  772.     if ( (found = search( "" name "", SEARCH_FORWARD+SEARCH_IGNORE_CASE )) ) {
  773.         #
  774.         # Help information exists for this name.
  775.         # Compute the number of lines from the current line + 1
  776.         # to the end of the help information (i.e. end of buffer
  777.         # or next help item).
  778.         #
  779.         down();
  780.         first_line = current_line;
  781.         if (search( "^", SEARCH_REGEX + SEARCH_FORWARD ))
  782.             # found next help item
  783.             last_line = current_line - 1;
  784.         else {
  785.             goto_buffer_bottom();
  786.             last_line = current_line;
  787.         }
  788.     }
  789.     current_buffer = save_buffer;
  790.  
  791.     if (found) {
  792.         #
  793.         # display the help information, but first transfer the
  794.         # data to a new buffer.
  795.         #
  796.         current_window = 
  797.         display_window = 
  798.             create_factory_window( item_window_x0,
  799.                 item_window_y0,
  800.                 item_window_width,
  801.                 item_window_height,
  802.                 WINDOW_SB_BELOW + WINDOW_SB_RIGHT + WINDOW_BORDER + WINDOW_SYSTEM );
  803.         current_buffer =
  804.         display_buffer = create_buffer( "", "", BUFFER_SYSTEM + BUFFER_NO_UNDO );
  805.         transfer( help_buffer, first_line, 1, last_line, 80 );
  806.         attach_window_buffer( display_window, display_buffer );
  807.         color_text = color_border = BAR_COLOR;
  808.         color_highlight = HBAR_COLOR;
  809.  
  810.         do {
  811.             #
  812.             # process all of the keys which are pressed while
  813.             # the help is displayed.
  814.             #
  815.             display_update();        # update the screen
  816.  
  817.             ch = getchar();
  818.  
  819.             if (ch == 0) {
  820.                 ch = getchar();        # expanded code, get rest of key
  821.                 if (ch == SCANCODE_DOWN) {
  822.                     scroll_vertical(1);
  823.                 } else if (ch == SCANCODE_UP) {
  824.                     scroll_vertical(-1);
  825.                 } else if (ch == SCANCODE_LEFT) {
  826.                     scroll_horizontal(-1);
  827.                 } else if (ch == SCANCODE_RIGHT) {
  828.                     scroll_horizontal(1);
  829.                 } else if (ch == SCANCODE_PGUP) {
  830.                     page_up();
  831.                 } else if (ch == SCANCODE_PGDN) {
  832.                     page_down();
  833.                 } else if (ch == SCANCODE_LEFT_PRESS) {
  834.                     if (window_contains( mouse_event_x, mouse_event_y ))
  835.                         if ( !and(mouse_position(1), MOUSE_LEFT ))
  836.                             left_press( 1 );
  837.                 } else if (ch == SCANCODE_RIGHT_PRESS) {
  838.                     if (window_contains( mouse_event_x, mouse_event_y ))
  839.                         if ( and(mouse_position(1), MOUSE_IN_TEXT ))
  840.                             dynamic_selection( COLUMN_SELECTION, RIGHT_BUTTON )
  841.                 }
  842.             } else {
  843.                 if (ch == ASCII_ESC) {
  844.                     continue_help = TRUE;
  845.                     break;
  846.                 } else if (ch == ASCII_CR) {
  847.                     #
  848.                     # copy any marked block to scrap
  849.                     # and return
  850.                     #
  851.                     if (region_type()) {
  852.                         copy_to_scrap();
  853.                         raise_anchor();
  854.                     }
  855.                     break;
  856.                 } else if ((ch == MINUS) || (ch == ASCII_BACKSPACE)) {
  857.                     continue_help = TRUE;
  858.                     break;
  859.                 }
  860.             }
  861.         } while (TRUE);
  862.  
  863.         #
  864.         # set coordinates for the next time this 
  865.         # window is displayed
  866.         #
  867.         item_window_x0 = window_x0
  868.         item_window_y0 = window_y0
  869.         item_window_width = window_width
  870.         item_window_height = window_height
  871.  
  872.         delete_buffer( display_buffer );
  873.         delete_window( display_window );
  874.         current_buffer = save_buffer;
  875.     } else {
  876.         warning( "No help available for: %s", name );
  877.     }
  878.     return continue_help;
  879. }
  880.  
  881. #
  882. # Process any characters which are pressed when a pulldown window is visible.
  883. # The processing includes searching through the list of elements with
  884. # an upper case character matching the character which was pressed.
  885. #
  886. function help_excellerator(){
  887.     local    save_window = current_window;
  888.     local    str;
  889.     local    index;
  890.     local    ch = and(current_key, 0x00FF);
  891.     local    i = 0;
  892.  
  893.     if (((ch >= 65) && (ch <= 90)) || ((ch >= 97) && (ch <= 122))) {
  894.         if (pulldown_window) {
  895.             current_window = pulldown_window;
  896.             window_cursor_x = window_cursor_y = 0;
  897.             str = read_window( pulldown_height * pulldown_width - 1);
  898.             index = cindex( str, toupper( chr( ch )))
  899.             if (index) {
  900.                 #
  901.                 # A match was found. Set pulldown index to 
  902.                 # that element and return to help processing
  903.                 #
  904.                 pulldown_index = (index / pulldown_width) + 1;
  905.                 current_key = 0;
  906.                 help_enter();
  907.             } else {
  908.                 beep();
  909.              }
  910.             assign_current_window( save_window );
  911.         } else {
  912.             str = toupper(chr(ch));
  913.             for (i in help_names) {
  914.                 if (index(help_names[i], str)) {
  915.                     help_horizontal(i - help_index)
  916.                     current_key = 0;
  917.                     help_vertical(1);
  918.                     break;
  919.                 }
  920.             }
  921.         }
  922.     }
  923. }
  924.  
  925. #------------ Mouse support ------------------------------------------------
  926.  
  927. #
  928. # Process left mouse button presses while the help menu is active.
  929. #
  930. function left_press_help(){
  931.     local    x;
  932.     local    y;
  933.     local    i;
  934.     local    wc;
  935.  
  936.     do {
  937.         wc = window_containing( x = mouse_display_x, y = mouse_display_y );
  938.         if ( wc == help_window ) {
  939.             #
  940.             # an item on the top title menu is now selected.
  941.             #
  942.             if (pulldown_window)
  943.                 help_vertical( 0 );    # clear pulldown highlight
  944.             i = MAX_INDEX;        # find title menu selection
  945.             while (x < help_offsets[i])
  946.                 i--;
  947.             if ( (i = (i ? i : 1) - help_index) ) {    # move left or right
  948.                 # raise the pulldown window.
  949.                 pulldown_index = 0;
  950.                 help_horizontal( i );
  951.                 help_pulldown( help_offsets[ help_index ], 1, \
  952.                     help_index );
  953.             }
  954.         } else if ( wc == pulldown_window ) {
  955.             #
  956.             # an item in the pulldown window is now selected
  957.             x -= pulldown_x;
  958.             if ((x <= 0) || (x > pulldown_width)) {
  959.                 help_vertical( 0 );
  960.             } else {
  961.                 y -= pulldown_y;
  962.                 if (y != pulldown_index) {
  963.                           if ((y <= 0) || (y > pulldown_height))
  964.                         y = 0;
  965.                     help_vertical( y );
  966.                 }
  967.             }
  968.         } else
  969.             # remove highlight within a pulldown window.
  970.             help_vertical( 0 );
  971.     } while (and(mouse_buttons,LEFT_BUTTON));
  972.  
  973.     #
  974.     # signal that the button was released.
  975.     # This may or may not be overkill if the keyboard buffer actually 
  976.     # receives a left_release button.
  977.     #
  978.     left_release_help();
  979. }
  980.  
  981. function left_click_help(){
  982.     left_press_help();
  983. }
  984.  
  985. function left_release_help(){
  986.     local    wc = window_containing( mouse_event_x, mouse_event_y );
  987.     if ((pulldown_window == 0) && (help_heights[ help_index ] != 0) )
  988.         help_pulldown( help_offsets[ help_index ], 1, help_index );
  989.     else if ( (wc == pulldown_window ) || (help_heights[ help_index ] == 0) )
  990.         help_enter();
  991.     else if ( wc != help_window )
  992.         process_end();
  993. }
  994.  
  995.  
  996. local    in_mouse_handler = FALSE;
  997.  
  998. ## Handle all current_window changes made while the help title bar is
  999. #    resident. When the help_window becomes current, invoke the 
  1000. #    help system.  Normally, clicking on the help_window will
  1001. #    not make it permanently current because it is a system window.
  1002. #
  1003. function help_mouse_handler(){
  1004.     local    i;
  1005.     local    x;
  1006.  
  1007.     #
  1008.     # avoid event calls to this function if left_press_help()
  1009.     # is called. help_start() will delete the event so in that
  1010.     # case, there's nothing to worry about
  1011.     #
  1012.     if ( ( !in_mouse_handler ) && 
  1013.         ( and(mouse_buttons, LEFT_BUTTON) || 
  1014.             (current_key == LEFT_CLICK) ||
  1015.             (current_key == LEFT_PRESS) )) {
  1016.         in_mouse_handler = TRUE;
  1017.  
  1018.         if ((current_window == help_window) && 
  1019.             window_contains(mouse_event_x, mouse_event_y, help_window )){
  1020.             i = MAX_INDEX;
  1021.             x = mouse_event_x;
  1022.             while (x < help_offsets[i--])
  1023.                 continue;
  1024.     
  1025.             pulldown_index = 1;
  1026.             if (and(mouse_buttons, LEFT_BUTTON))
  1027.                 ungetkey( 61440 );    # left_press
  1028.             help_start( i );
  1029.     
  1030.             # flush_keyboard();
  1031.         }
  1032.         in_mouse_handler = FALSE;
  1033.     }
  1034.     save_last_window = current_window;
  1035. }
  1036.  
  1037. ## restore the previous window before help was invoked. This may
  1038. #    be tricky if the previous window was deleted.
  1039. #
  1040. local function restorePrevWindow(){
  1041.     if (in_mouse_handler) {
  1042.         if (save_last_window)
  1043.             if (window_valid( save_last_window ))
  1044.                 current_window = save_last_window;
  1045.         if ( !save_last_window ||
  1046.                         (current_window != save_last_window) ||
  1047.             (current_window == help_window))
  1048.             # see if the save_last_window was deleted
  1049.             prev_window();
  1050.     }
  1051. }
  1052.  
  1053.