home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / p2demo21.exe / PEL / LINEDRAW.PEL < prev    next >
Text File  |  1995-03-13  |  17KB  |  568 lines

  1. # $Header:   P:\source\wmacros\linedraw.pev   1.7   13 Mar 1995 13:17:54   PFHDWM0  $
  2.  
  3. ##############################################################################
  4. #
  5. #           Compuware Corporation
  6. #           31440 Northwestern Highway
  7. #           Farmington Hills, Michigan 48334-2564
  8. #
  9. #   This source code listing contains information that is
  10. #   proprietary to Compuware Corporation and may not be copied
  11. #   duplicated, translated, transmitted, stored, retrieved
  12. #   or in any manner or by any method conveyed or disclosed
  13. #   to a third party or parties without express written
  14. #   permission from Compuware Corporation.
  15. #
  16. #  
  17. ##############################################################################
  18.  
  19. #### $Workfile:   linedraw.pel  $: Line drawing binding code
  20. #
  21. #
  22.  
  23. #
  24. # The function linedraw() is used to enable 'line drawing' mode by executing 
  25. # the function toggle_drawing() with a line style. Once activated the Numpad 
  26. # arrow keys will be changed to draw lines. An optional parameter to 
  27. # toggle_drawing() sets the style of line drawing characters to one of 4 
  28. # styles (default is style 1). This version differs from the original Sage 
  29. # editor in that the changes to the Numpad arrow keys are global instead of 
  30. # being restricted to the current buffer.  Invoking toggle_drawing() a second 
  31. # time with no parameters, or linedraw() with a 0 (zero) parameter turns off
  32. # line drawing and restores the original Numpad keys.
  33. #
  34. # The function linedraw() prompts for a style if one is not provided and can
  35. # be assigned to a key.
  36. #
  37. # The keys defined are:
  38. #  Num Left, Right, Up and Down: insert linedraw character and move in
  39. #                               specified direction.
  40. #  Num 5: insert arrow pointing in the last used direction.
  41. #  Ctrl-Num-Left, Right, Up and Down: insert arrow character pointing in the
  42. #                                     specified direction, then move.
  43. #
  44.  
  45. local ld_Keymap = 0;
  46.  
  47. local up_array
  48. local down_array
  49. local left_array
  50. local right_array
  51.  
  52. local arrow_array
  53. local last_dir = 4
  54.  
  55. local t_char_array
  56. local b_char_array
  57. local r_char_array
  58. local l_char_array
  59.  
  60. local VERT_C   = 1
  61. local HORZ_C   = 2
  62.  
  63. local NO_C  = 0
  64. local TOP_C = 1
  65. local LEFT_C   = 2
  66. local BOT_C = 4
  67. local RIGHT_C  = 8
  68.  
  69.  
  70. global function linedraw( style )
  71. {
  72.    if (argcount() < 1)
  73.       style = prompt("Select style: 1 = ─┼─, 2 = ▀█▀, 3 = -+-, 4 = ═╬═: ", "1",
  74.                      "linedraw_dialog");
  75.  
  76.    if (style != "")  # style will be NULL string for escape.
  77.    {
  78.       if (style+0 >= 0 && style+0 < 5)
  79.          toggle_drawing( style );
  80.       else
  81.          notify("Invalid linedrawing style selected")
  82.    }
  83. }
  84.  
  85. #
  86. # init_lines() sets the characters for the type of lines to be drawn.
  87. # The line styles are determined by borderStyle in the following manner:
  88. #
  89. #    1              2               3              4
  90. #      ┌───┬───┐      █▀▀▀█▀▀▀█       +---+---+      ╔═══╦═══╗
  91. #      │   │   │      █   █   █       |   |   |      ║   ║   ║
  92. #      ├───┼───┤      █▀▀▀█▀▀▀█       +---+---+      ╠═══╬═══╣
  93. #      │   │   │      █   █   █       |   |   |      ║   ║   ║
  94. #      └───┴───┘      ▀▀▀▀▀▀▀▀▀       +---+---+      ╚═══╩═══╝
  95. #
  96. local function init_lines( borderStyle )
  97. {                                       
  98.    local v_bar = 179    # │
  99.    local h_bar = 196    # ─
  100.    local tl_corner = 218      # ┌
  101.    local tr_corner = 191      # ┐
  102.    local ll_corner = 192      # └
  103.    local lr_corner = 217      # ┘
  104.    local x_inter  = 197    # ┼
  105.    local t_inter = 193     # ┴
  106.    local b_inter = 194     # ┬
  107.    local l_inter = 180     # ┤
  108.    local r_inter = 195     # ├
  109.                                     
  110.    if (borderStyle == 2)            
  111.    {                                
  112. #      v_bar = 179    # │
  113. #      h_bar = 205    # ═
  114. #      tl_corner = 213      # ╒
  115. #      tr_corner = 184      # ╕
  116. #      ll_corner = 212      # ╘
  117. #      lr_corner = 190      # ╛
  118. #      x_inter  = 216    # ╪
  119. #      t_inter = 207     # ╧
  120. #      b_inter = 209     # ╤
  121. #      l_inter = 181     # ╡
  122. #      r_inter = 198     # ╞
  123.       v_bar = 219       # █         
  124.                                     
  125.       h_bar = 223       # ▀         
  126.       tl_corner = 219               
  127.       tr_corner = 219               
  128.       ll_corner = 223               
  129.       lr_corner = 223               
  130.       x_inter  = 219                
  131.       t_inter = 223                 
  132.       b_inter = 219                 
  133.       l_inter = 219                 
  134.       r_inter = 219                 
  135.    } 
  136.    else if (borderStyle == 3) 
  137.    {
  138. #      v_bar = 186    # ║
  139. #      h_bar = 196    # ─
  140. #      tl_corner = 214      # ╓
  141. #      tr_corner = 183      # ╖
  142. #      ll_corner = 211      # ╙
  143. #      lr_corner = 189      # ╜
  144. #      x_inter  = 215    # ╫
  145. #      t_inter = 208     # ╨
  146. #      b_inter = 210     # ╥
  147. #      l_inter = 182     # ╢
  148. #      r_inter = 199     # ╟
  149.       v_bar = 124    # ║
  150.       h_bar = 45    # ─
  151.       tl_corner = 43      # ╓
  152.       tr_corner = 43      # ╖
  153.       ll_corner = 43      # ╙
  154.       lr_corner = 43      # ╜
  155.       x_inter  = 43    # ╫
  156.       t_inter = 43     # ╨
  157.       b_inter = 43     # ╥
  158.       l_inter = 43     # ╢
  159.       r_inter = 43     # ╟
  160.    } 
  161.    else if (borderStyle == 4) 
  162.    {
  163.       v_bar = 186    # ║
  164.       h_bar = 205    # ═
  165.       tl_corner = 201      # ╔
  166.       tr_corner = 187      # ╗
  167.       ll_corner = 200      # ╚
  168.       lr_corner = 188      # ╝
  169.       x_inter  = 206    # ╬
  170.       t_inter = 202     # ╩
  171.       b_inter = 203     # ╦
  172.       l_inter = 185     # ╣
  173.       r_inter = 204     # ╠
  174.    } 
  175.    else 
  176.    {
  177.       v_bar = 179    # │
  178.       h_bar = 196    # ─
  179.       tl_corner = 218      # ┌
  180.       tr_corner = 191      # ┐
  181.       ll_corner = 192      # └
  182.       lr_corner = 217      # ┘
  183.       x_inter  = 197    # ┼
  184.       t_inter = 193     # ┴
  185.       b_inter = 194     # ┬
  186.       l_inter = 180     # ┤
  187.       r_inter = 195     # ├
  188.    }
  189.  
  190.    arrow_array[1] = 30  # up
  191.    arrow_array[2] = 31  # down
  192.    arrow_array[3] = 17  # left
  193.    arrow_array[4] = 16  # right
  194.  
  195.    up_array[ chr(h_bar) ] = HORZ_C;
  196.    up_array[ chr(v_bar) ] = VERT_C;
  197.    up_array[ chr(tl_corner) ] = VERT_C;
  198.    up_array[ chr(tr_corner) ] = VERT_C;
  199.    up_array[ chr(ll_corner) ] = HORZ_C;
  200.    up_array[ chr(lr_corner) ] = HORZ_C;
  201.    up_array[ chr(x_inter) ] = VERT_C;
  202.    up_array[ chr(t_inter) ] = HORZ_C;
  203.    up_array[ chr(b_inter) ] = VERT_C;
  204.    up_array[ chr(l_inter) ] = VERT_C;
  205.    up_array[ chr(r_inter) ] = VERT_C;
  206.    
  207.    down_array[ chr(h_bar) ] = HORZ_C;
  208.    down_array[ chr(v_bar) ] = VERT_C;
  209.    down_array[ chr(tl_corner) ] = HORZ_C;
  210.    down_array[ chr(tr_corner) ] = HORZ_C;
  211.    down_array[ chr(ll_corner) ] = VERT_C;
  212.    down_array[ chr(lr_corner) ] = VERT_C;
  213.    down_array[ chr(x_inter) ] = VERT_C;
  214.    down_array[ chr(t_inter) ] = VERT_C;
  215.    down_array[ chr(b_inter) ] = HORZ_C;
  216.    down_array[ chr(l_inter) ] = VERT_C;
  217.    down_array[ chr(r_inter) ] = VERT_C;
  218.  
  219.    left_array[ chr(h_bar) ] = HORZ_C;
  220.    left_array[ chr(v_bar) ] = VERT_C;
  221.    left_array[ chr(tl_corner) ] = HORZ_C;
  222.    left_array[ chr(tr_corner) ] = VERT_C;
  223.    left_array[ chr(ll_corner) ] = HORZ_C;
  224.    left_array[ chr(lr_corner) ] = VERT_C;
  225.    left_array[ chr(x_inter) ] = HORZ_C;
  226.    left_array[ chr(t_inter) ] = HORZ_C;
  227.    left_array[ chr(b_inter) ] = HORZ_C;
  228.    left_array[ chr(l_inter) ] = VERT_C;
  229.    left_array[ chr(r_inter) ] = HORZ_C;
  230.  
  231.    right_array[ chr(h_bar) ] = HORZ_C;
  232.    right_array[ chr(v_bar) ] = VERT_C;
  233.    right_array[ chr(tl_corner) ] = VERT_C;
  234.    right_array[ chr(tr_corner) ] = HORZ_C;
  235.    right_array[ chr(ll_corner) ] = VERT_C;
  236.    right_array[ chr(lr_corner) ] = HORZ_C;
  237.    right_array[ chr(x_inter) ] = HORZ_C;
  238.    right_array[ chr(t_inter) ] = HORZ_C;
  239.    right_array[ chr(b_inter) ] = HORZ_C;
  240.    right_array[ chr(l_inter) ] = HORZ_C;
  241.    right_array[ chr(r_inter) ] = VERT_C;
  242.  
  243.    t_char_array[ 0 ] = v_bar        # "│"
  244.    t_char_array[ 1 ] = v_bar        # "│"
  245.    t_char_array[ 2 ] = lr_corner       # "┘"
  246.    t_char_array[ 3 ] = lr_corner       # "┘"
  247.    t_char_array[ 4 ] = v_bar        # "│"
  248.    t_char_array[ 5 ] = v_bar        # "│"
  249.    t_char_array[ 6 ] = l_inter         # "┤"
  250.    t_char_array[ 7 ] = l_inter         # "┤"
  251.    t_char_array[ 8 ] = ll_corner       # "└"
  252.    t_char_array[ 9 ] = ll_corner       # "└"
  253.    t_char_array[ 10 ] = t_inter        # "┴"
  254.    t_char_array[ 11 ] = t_inter        # "┴"
  255.    t_char_array[ 12 ] = r_inter        # "├"
  256.    t_char_array[ 13 ] = r_inter        # "├"
  257.    t_char_array[ 14 ] = x_inter        # "┼"
  258.    t_char_array[ 15 ] = x_inter        # "┼"
  259.  
  260.    l_char_array[ 0 ] = h_bar        # "─"
  261.    l_char_array[ 1 ] = lr_corner       # "┘"
  262.    l_char_array[ 2 ] = h_bar        # "─"
  263.    l_char_array[ 3 ] = lr_corner       # "┘"
  264.    l_char_array[ 4 ] = tr_corner       # "┐"
  265.    l_char_array[ 5 ] = l_inter         # "┤"
  266.    l_char_array[ 6 ] = tr_corner       # "┐"
  267.    l_char_array[ 7 ] = l_inter         # "┤"
  268.    l_char_array[ 8 ] = h_bar        # "─"
  269.    l_char_array[ 9 ] = t_inter         # "┴"
  270.    l_char_array[ 10 ] = h_bar          # "─"
  271.    l_char_array[ 11 ] = t_inter        # "┴"
  272.    l_char_array[ 12 ] = b_inter        # "┬"
  273.    l_char_array[ 13 ] = x_inter        # "┼"
  274.    l_char_array[ 14 ] = b_inter        # "┬"
  275.    l_char_array[ 15 ] = x_inter        # "┼"
  276.  
  277.    b_char_array[ 0 ] = v_bar        # "│"
  278.    b_char_array[ 1 ] = v_bar        # "│"
  279.    b_char_array[ 2 ] = tr_corner       # "┐"
  280.    b_char_array[ 3 ] = l_inter         # "┤"
  281.    b_char_array[ 4 ] = v_bar        # "│"
  282.    b_char_array[ 5 ] = v_bar        # "│"
  283.    b_char_array[ 6 ] = tr_corner       # "┐"
  284.    b_char_array[ 7 ] = l_inter         # "┤"
  285.    b_char_array[ 8 ] = tl_corner       # "┌"
  286.    b_char_array[ 9 ] = r_inter         # "├"
  287.    b_char_array[ 10 ] = b_inter        # "┬"
  288.    b_char_array[ 11 ] = x_inter        # "┼"
  289.    b_char_array[ 12 ] = tl_corner         # "┌"
  290.    b_char_array[ 13 ] = r_inter        # "├"
  291.    b_char_array[ 14 ] = b_inter        # "┬"
  292.    b_char_array[ 15 ] = x_inter        # "┼"
  293.  
  294.    r_char_array[ 0 ] = h_bar        # "─"
  295.    r_char_array[ 1 ] = ll_corner       # "└"
  296.    r_char_array[ 2 ] = h_bar        # "─"
  297.    r_char_array[ 3 ] = t_inter         # "┴"
  298.    r_char_array[ 4 ] = tl_corner       # "┌"
  299.    r_char_array[ 5 ] = r_inter         # "├"
  300.    r_char_array[ 6 ] = b_inter         # "┬"
  301.    r_char_array[ 7 ] = x_inter         # "┼"
  302.    r_char_array[ 8 ] = h_bar        # "─"
  303.    r_char_array[ 9 ] = ll_corner       # "└"
  304.    r_char_array[ 10 ] = h_bar       # "─"
  305.    r_char_array[ 11 ] = t_inter        # "┴"
  306.    r_char_array[ 12 ] = tl_corner         # "┌"
  307.    r_char_array[ 13 ] = r_inter        # "├"
  308.    r_char_array[ 14 ] = b_inter        # "┬"
  309.    r_char_array[ 15 ] = x_inter        # "┼"
  310. }
  311.  
  312. #
  313. # getlevel()
  314. # This function checks the characters in the buffer surrounding the
  315. # one to be drawn to see if any of them are also linedrawing characters.
  316. # This info is used to determine if a junction or corner character
  317. # should be drawn.
  318. #
  319. local function getlevel()
  320. {
  321.    local ch1 = ""    # char above
  322.    local ch2 = ""    # char to the left
  323.    local ch3 = ""    # char below
  324.    local ch4 = ""    # char to the right
  325.    local cc;
  326.    local level = NO_C;     # 0 = no surrounding character
  327.                            # 1 = top char needs to connect
  328.                            # 2 = left char needs to connect
  329.                            # 4 = bottom char needs to connect
  330.                            # 8 = right char needs to connect
  331.  
  332.    if ( up() )
  333.    {
  334.       ch1 = read_buffer( 1 );
  335.       down();
  336.    }
  337.    if ( left() ) 
  338.    {
  339.       ch2 = read_buffer( 1 );
  340.       right()
  341.    }
  342.    cc = current_column;
  343.    if ( down() ) 
  344.    {
  345.       if (current_column == cc )
  346.          ch3 = read_buffer( 1 );
  347.       up();
  348.    }
  349.    current_column = cc;
  350.  
  351.    if ( right() ) 
  352.    {
  353.       ch4 = read_buffer( 1 );
  354.       left();
  355.    }
  356.  
  357.    if (ch1 in up_array)
  358.       if (up_array[ ch1 ] == VERT_C)
  359.          level += TOP_C
  360.    if (ch2 in left_array)
  361.       if (left_array[ ch2 ] == HORZ_C)
  362.          level += LEFT_C
  363.    if (ch3 in down_array)
  364.       if (down_array[ ch3 ] == VERT_C)
  365.          level += BOT_C
  366.    if (ch4 in right_array)
  367.       if (right_array[ ch4 ] == HORZ_C)
  368.          level += RIGHT_C
  369.  
  370.    return level;
  371. }
  372.  
  373.  
  374. #
  375. # ld_move(dir, arrow_flag)
  376. #
  377. # dir: 1 = up, 2 = down, 3 = left, 4 = right, 0 = last
  378. # arrow_flag: 1 = draw arrow, 0 = draw line
  379. #
  380. global function ld_move(dir, arrow_flag)
  381. {
  382.    local flags = reset_buffer_flags();
  383.    
  384.    if (!dir)
  385.       dir = last_dir # default move right
  386.    else
  387.       last_dir = dir
  388.       
  389.    if (dir == 1)
  390.    {
  391.       insert_key( arrow_flag ? arrow_array[dir] : t_char_array[ getlevel() ] );
  392.       left(1);
  393.       up(1);
  394.    }
  395.    else if (dir == 2)
  396.    {
  397.       insert_key( arrow_flag ? arrow_array[dir] : b_char_array[ getlevel() ] );
  398.       ld_down()
  399.    }
  400.    else if (dir == 3)
  401.    {
  402.       insert_key( arrow_flag ? arrow_array[dir] : l_char_array[ getlevel() ] );
  403.       left( 2 );
  404.    }
  405.    else if (dir == 4)
  406.    {
  407.       insert_key( arrow_flag ? arrow_array[dir] : r_char_array[ getlevel() ] );
  408.    }                 
  409.    else
  410.       beep()
  411.    
  412.    reset_buffer_flags( flags );
  413. }
  414.  
  415. local function ld_down()
  416. {
  417.    local cc;
  418.    
  419.    left(1);
  420.    cc = current_column;
  421.    if (!down(1) || cc != current_column)
  422.    {    # allow drawing past eof
  423.       save_position();
  424.       goto_eol();
  425.       insert_newline();
  426.       restore_position( 1 );
  427.       down(1);
  428.    }
  429.    current_column = cc;
  430. }
  431.  
  432. #
  433. # reset_buffer_flags()
  434. #
  435. # Sets the required buffer flags for line drawing mode and
  436. # returns the current flags so they can be reset later.
  437. # This function is called by all the motion keys so that the flags
  438. # are always set properly.
  439. #
  440.  
  441. local function reset_buffer_flags( bf )
  442. {
  443.    local    flags;
  444.  
  445.    if (argcount())
  446.    {
  447.       buffer_flags = or(and( buffer_flags, 
  448.          not(BUFFER_TABS_TO_SPACES + BUFFER_OVERTYPE_MODE)),
  449.          bf );
  450.    } 
  451.    else 
  452.    {
  453.       flags = and( buffer_flags,
  454.                BUFFER_TABS_TO_SPACES + 
  455.                BUFFER_OVERTYPE_MODE  +
  456.                BUFFER_WP_ENABLED +
  457.                BUFFER_REAL_SPACE_ONLY +
  458.                BUFFER_SNAP_TO_EOL );
  459.           
  460.       buffer_flags = and(buffer_flags, not( flags ));
  461.  
  462.       buffer_flags = or(buffer_flags, 
  463.          BUFFER_TABS_TO_SPACES + BUFFER_OVERTYPE_MODE);
  464.  
  465.       return flags;
  466.    }
  467. }
  468.  
  469.  
  470. #
  471. # toggle_drawing() 
  472. #
  473. # toggles the line drawing capability assigned to
  474. # the shift-arrow keys.  The lineStyle parameter is passed on to init_lines
  475. # if it is different from the last call.
  476. #
  477. global function toggle_drawing( style )
  478. {
  479.    local ld_lineStyle = 0     # set to 1 - 4 to choose style
  480.    local inLineDrawMode = 0   # set to 1 if we are activating line
  481.                               # drawing mode.
  482.  
  483.    # If no line drawing keymap created then make one based on the
  484.    # current keymap with the numpad arrow keys reassigned.
  485.    # When line drawing mode is active, this keymap will be used
  486.    # for all buffers.
  487.    if (!ld_Keymap) 
  488.    {
  489.       # Create a new keymap intilized from the current_keymap
  490.       # Set current keymap to the newly created map and assign
  491.       # new key values. Then reset the current_keymap.
  492.       ld_Keymap = create_keymap( current_keymap );
  493.  
  494.       if( ld_Keymap )
  495.       {
  496.          push_keymap( ld_Keymap );
  497.          # Assign Keys
  498.          assign_key( "<Num-Up>", "ld_move 1" );
  499.          assign_key( "<Num-Down>", "ld_move 2" );
  500.          assign_key( "<Num-Left>", "ld_move 3" );
  501.          assign_key( "<Num-Right>", "ld_move 4" );
  502.          assign_key( "<Num-5>", "ld_move 0 1" );
  503.          assign_key( "<Ctrl-Num-Up>", "ld_move 1 1" );
  504.          assign_key( "<Ctrl-Num-Down>", "ld_move 2 1" );
  505.          assign_key( "<Ctrl-Num-Left>", "ld_move 3 1" );
  506.          assign_key( "<Ctrl-Num-Right>", "ld_move 4 1" );
  507.          
  508.          pop_keymap()
  509.       } 
  510.    }
  511.    
  512.    #
  513.    # get the current line drawing mode.
  514.    # inLineDrawMode is assigned 0 or 1
  515.    #
  516.    inLineDrawMode = (ld_Keymap == current_keymap);
  517.  
  518.    #
  519.    # toggle or set the mode
  520.    #
  521.    if( argcount() < 1 )
  522.    {
  523.       inLineDrawMode = !inLineDrawMode;    # toggle the mode value
  524.    }
  525.    else if (style == 0)
  526.    {
  527.       inLineDrawMode = 0;
  528.    }
  529.    else 
  530.    {
  531.       inLineDrawMode = 1;
  532.       ld_lineStyle = 0+style;
  533.    }
  534.  
  535.    if ( !inLineDrawMode )
  536.    {
  537.       # If we are deactivating line drawing, and the current keymap
  538.       # is the line drawing keymap, then restore the original keymap
  539.       if (current_keymap == ld_Keymap)
  540.          pop_keymap();
  541.  
  542.       notify( "Line drawing keys inactive. ");
  543.       beep();
  544.    } 
  545.    else 
  546.    {
  547.       # If we are activating line drawing, and it is not already
  548.       # active, save the current keymap and make the line drawing
  549.       # keymap current.
  550.       if (!ld_Keymap)
  551.       {
  552.          warning("Invalid line drawing keymap")
  553.       }
  554.       else
  555.       {
  556.       if (current_keymap != ld_Keymap)
  557.          push_keymap( ld_Keymap );
  558.  
  559.       # Set the line style
  560.       init_lines( ld_lineStyle );
  561.       notify( "Line drawing keys active. ");
  562.       beep();
  563.       }
  564.    }
  565. }
  566.  
  567.