home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR8 / TDE32.ZIP / PULL.C < prev    next >
C/C++ Source or Header  |  1993-11-13  |  8KB  |  290 lines

  1. /*
  2.  * These functions do the pop-up pull-down command menus.
  3.  *
  4.  * Being stupid, I can't remember what half the function keys do.
  5.  *  Fortunately, it is very easy to write a pop-up pull-down command menu
  6.  *  to run editor commands.  Being lazy, I didn't implement CUA style menus,
  7.  *  because we can provide most of the CUA benefits with a single hot-key.
  8.  *  Also, dumb UNIX terminals don't have a lot function keys to spare.
  9.  *
  10.  * New editor name:  TDE, the Thomson-Davis Editor.
  11.  * Author:           Frank Davis
  12.  * Date:             June 5, 1991, version 1.0
  13.  * Date:             July 29, 1991, version 1.1
  14.  * Date:             October 5, 1991, version 1.2
  15.  * Date:             January 20, 1992, version 1.3
  16.  * Date:             February 17, 1992, version 1.4
  17.  * Date:             April 1, 1992, version 1.5
  18.  * Date:             June 5, 1992, version 2.0
  19.  * Date:             October 31, 1992, version 2.1
  20.  * Date:             April 1, 1993, version 2.2
  21.  * Date:             June 5, 1993, version 3.0
  22.  * Date:             August 29, 1993, version 3.1
  23.  * Date:             November 13, 1993, version 3.2
  24.  *
  25.  * This code is released into the public domain, Frank Davis.
  26.  *    You may distribute it freely.
  27.  */
  28.  
  29. #include "tdestr.h"
  30. #include "common.h"
  31. #include "define.h"
  32. #include "tdefunc.h"
  33.  
  34.  
  35. static int saved_major = 0;
  36. static int saved_minor = 0;
  37.  
  38.  
  39. /*
  40.  * Name:    main_pull_down
  41.  * Purpose: show pull down menu and call function if needed
  42.  * Date:    November 13, 1993
  43.  * Passed:  window:  current window
  44.  * Notes:   keep a record of the last menu choice in local global variables.
  45.  */
  46. int  main_pull_down( TDE_WIN *window )
  47. {
  48. int rc;
  49. int ch;
  50. int row;
  51. int major_choice;
  52. int minor_choice;
  53. #if defined( __UNIX__ )
  54.  chtype display_buff[MAX_COLS+2];       /* chtype is defined in curses.h */
  55. #else
  56.  char display_buff[(MAX_COLS+2)*2];
  57. #endif
  58.  
  59.    rc = ERROR;
  60.    row = 0;
  61.    major_choice = saved_major;
  62.    minor_choice = saved_minor;
  63.    save_screen_line( 0, row, display_buff );
  64.    ch = lite_bar_menu( &major_choice, &minor_choice );
  65.    restore_screen_line( 0, row, display_buff );
  66.    saved_major = major_choice;
  67.    saved_minor = minor_choice;
  68.    if (ch == Rturn) {
  69.       g_status.command = menu[major_choice].minor[minor_choice].minor_func;
  70.       g_status.control_break = FALSE;
  71.       if (g_status.command >= 0 && g_status.command < NUM_FUNCS)
  72.          rc = (*do_it[g_status.command])( window );
  73.       else
  74.          rc = ERROR;
  75.    }
  76.    return( rc );
  77. }
  78.  
  79.  
  80. /*
  81.  * Name:    lite_bar_menu
  82.  * Purpose: handle major menu choices
  83.  * Date:    November 13, 1993
  84.  * Passed:  maj: pointer to menu bar choice
  85.  *          min: pointer to function under menu
  86.  * Returns: last key pressed
  87.  * Notes:   set the menu structures
  88.  */
  89. int lite_bar_menu( int *maj, int *min )
  90. {
  91. int  major_col[MAJOR];
  92. int  major_width[MAJOR];
  93. int  col;
  94. int  row;
  95. int  wid;
  96. int  ch;
  97. char blanks[MAX_COLS+2];
  98.  
  99.    /*
  100.     * put the pull-down menu on the first line of screen.
  101.     */
  102.    col = row = 0;
  103.    memset( blanks, ' ', g_display.ncols );
  104.    blanks[g_display.ncols] = '\0';
  105.    s_output( blanks, row, col, g_display.head_color );
  106.    get_bar_spacing( col+1, major_col, major_width );
  107.    draw_lite_head( row, major_col );
  108.  
  109.    xygoto( -1, -1 );
  110.    get_minor_counts( );
  111.    ch = -1;
  112.    while (ch != AbortCommand  &&  ch != Rturn) {
  113.       if (ch == CharRight) {
  114.          hlight_line( major_col[*maj], row, major_width[*maj], g_display.mode_color );
  115.          ++*maj;
  116.          if (*maj >= MAJOR)
  117.             *maj = 0;
  118.          *min = 0;
  119.          ch = -1;
  120.       } else if (ch == CharLeft) {
  121.          hlight_line( major_col[*maj], row, major_width[*maj], g_display.mode_color );
  122.          --*maj;
  123.          if (*maj < 0)
  124.             *maj = MAJOR - 1;
  125.          *min = 0;
  126.          ch = -1;
  127.       }
  128.  
  129.       hlight_line( major_col[*maj], row, major_width[*maj], g_display.block_color );
  130.  
  131.       col = major_col[*maj];
  132.       wid = strlen( menu[*maj].minor[0].minor_name );
  133.       if (col + wid + 2 > g_display.ncols - 1)
  134.          col = g_display.ncols - 1 - wid;
  135.       *min = pull_me( *maj, *min, row+1, col, &ch );
  136.    }
  137.    return( ch );
  138. }
  139.  
  140.  
  141. /*
  142.  * Name:    pull_me
  143.  * Purpose: move cursor up and down the menu bar
  144.  * Date:    November 13, 1993
  145.  * Passed:  maj: main menu bar choice
  146.  *          min: subfunction choice
  147.  *          row: row to begin vertical choice
  148.  *          col: column to begin vertical choice
  149.  *          ch:  pointer to current key
  150.  * Returns: last key pressed
  151.  * Notes:   save the text under the pulled down menu
  152.  */
  153. int  pull_me( int maj, int min, int row, int col, int *ch )
  154. {
  155. int  i;
  156. int  minor_width;
  157. int  cnt;
  158. int  select;
  159. int  begin;
  160. int  end;
  161. #if defined( __UNIX__ )
  162.  chtype *buffer;
  163. #else
  164.  int  *buffer;
  165. #endif
  166.  
  167.    cnt = menu[maj].minor_cnt;
  168.  
  169.    /*
  170.     * find first valid minor selection.
  171.     */
  172.    for (begin=0; menu[maj].minor[begin].minor_func < 0; begin++);
  173.  
  174.    /*
  175.     * find last valid minor selection
  176.     */
  177.    for (end=cnt-1; menu[maj].minor[end].minor_func < 0; end--);
  178.  
  179.    minor_width = strlen( menu[maj].minor[0].minor_name );
  180.  
  181.    select = min;
  182.    if (menu[maj].minor[select].minor_func < 0) {
  183.       select = begin;
  184.       while (menu[maj].minor[select].minor_func < 0)
  185.          ++select;
  186.    }
  187.  
  188. #if defined( __UNIX__ )
  189.    buffer = (chtype *)malloc( minor_width * cnt * sizeof(chtype) );
  190. #else
  191.    buffer = (int *)malloc( minor_width * cnt * sizeof(int) );
  192. #endif
  193.    if (buffer != NULL) {
  194.       save_minor_area( buffer, minor_width, cnt, row, col );
  195.       for (i=0; i< cnt; i++)
  196.          s_output( menu[maj].minor[i].minor_name, row+i, col, g_display.help_color );
  197.  
  198.       hlight_line( col+1, row+select, minor_width-2, g_display.hilited_file );
  199.       while (*ch != AbortCommand && *ch != CharRight &&
  200.                            *ch != CharLeft && *ch != Rturn) {
  201.          if (*ch == LineDown) {
  202.             hlight_line( col+1, row+select, minor_width-2, g_display.help_color );
  203.             ++select;
  204.             while (menu[maj].minor[select].minor_func < 0)
  205.                ++select;
  206.             if (select >= cnt)
  207.                select = begin;
  208.             hlight_line( col+1, row+select, minor_width-2, g_display.hilited_file );
  209.          } else if (*ch == LineUp) {
  210.             hlight_line( col+1, row+select, minor_width-2, g_display.help_color );
  211.             --select;
  212.             while (menu[maj].minor[select].minor_func < 0)
  213.                --select;
  214.             if (select < 0)
  215.                select = end;
  216.             hlight_line( col+1, row+select, minor_width-2, g_display.hilited_file );
  217.          }
  218.  
  219. #if defined( __UNIX__ )
  220.          refresh( );
  221. #endif
  222.  
  223.          *ch = getkey( );
  224.          *ch = getfunc( *ch );
  225.          if (*ch == ESC)
  226.             *ch = AbortCommand;
  227.       }
  228.       restore_minor_area( buffer, minor_width, cnt, row, col );
  229.       free( buffer );
  230.    } else {
  231.       select = -1;
  232.       *ch = AbortCommand;
  233.    }
  234.    return( select );
  235. }
  236.  
  237.  
  238. /*
  239.  * Name:    get_bar_spacing
  240.  * Purpose: calculate headings for main menu choices
  241.  * Date:    November 13, 1993
  242.  * Passed:  col: col of first menu choice
  243.  *          major_col: column to display each menu heading
  244.  *          major_width: width of each menu heading
  245.  * Notes:   assume 6 spaces between the menu items
  246.  */
  247. void get_bar_spacing( int col, int major_col[], int major_width[] )
  248. {
  249. int i, j;
  250.  
  251.    for (i=j=0; i< MAJOR; i++) {
  252.       major_col[i] = col+j;
  253.       major_width[i] = strlen( menu[i].major_name );
  254.       j += major_width[i] + 6;
  255.    }
  256. }
  257.  
  258.  
  259. /*
  260.  * Name:    draw_lite_head
  261.  * Purpose: slap the main menu choices on the lite bar
  262.  * Date:    November 13, 1993
  263.  * Passed:  row: lite bar row
  264.  *          major_col: column to display each menu heading
  265.  */
  266. void draw_lite_head( int row, int major_col[] )
  267. {
  268. int i;
  269.  
  270.    for (i=0; i< MAJOR; i++)
  271.       s_output( menu[i].major_name, row, major_col[i], g_display.mode_color );
  272. }
  273.  
  274.  
  275. /*
  276.  * Name:    get_minor_counts
  277.  * Purpose: find number of items under each main menu
  278.  * Date:    November 13, 1993
  279.  */
  280. void get_minor_counts( void )
  281. {
  282. int i;
  283. int cnt;
  284.  
  285.    for (i=0; i<MAJOR; i++) {
  286.       for (cnt=0; menu[i].minor[cnt].minor_name != NULL; cnt++);
  287.       menu[i].minor_cnt = cnt;
  288.    }
  289. }
  290.