home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / p2demo21.exe / PEL / WINDOWS.PEL < prev    next >
Text File  |  1995-03-16  |  34KB  |  1,211 lines

  1. # $Header:   P:\source\wmacros\windows.pev   1.55   16 Mar 1995 14:02:22   pfhmlw0  $
  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:   windows.pel  $: support for windows
  20.  
  21. #### symbolic window flag values
  22. #
  23. global  WINDOW_COLLAPSED    = 0x00000000 # window collapsed
  24. global  WINDOW_NORMAL       = 0x00000001 # window normal
  25. global  WINDOW_EXPANDED     = 0x00000002 # window expanded
  26. global  WINDOW_HIDDEN       = 0x00000003 # window state: one of the above
  27. global  WINDOW_ZOOM         = 0x00000003 # read-only window is zoomed
  28.                                     
  29. global  WINDOW_SYSTEM       = 0x00000004 # read-only window is a "system" window
  30. global  WINDOW_SHOW_SYSTEM  = 0x00000008 # allow system buffers to be visible
  31.            
  32. global  WINDOW_BORDERS      = 0x00000030 # all border flags
  33. global  WINDOW_NOBORDER     = 0x00000000 # no border, no title, no nothing
  34. global  WINDOW_NORM_BORDER  = 0x00000010 # non-sizing border 
  35. global  WINDOW_SIZE_BORDER  = 0x00000020 # sizing border 
  36.  
  37. global  WINDOW_SCROLLBARS   = 0x000000C0 # both scroll bars
  38. global  WINDOW_VERT_SB      = 0x00000040 # border w/scroll bar right
  39. global  WINDOW_HORIZ_SB     = 0x00000080 # border w/scroll bar below
  40.                                 
  41. global  WINDOW_TITLEBAR     = 0x00000F00 # all title bar flags
  42. global  WINDOW_NO_TITLE     = 0x00000000 # no title bar
  43. global  WINDOW_TITLE        = 0x00000100 # title bar visible
  44. global  WINDOW_SYS_MENU     = 0x00000200 # system menu 
  45. global  WINDOW_MIN_BOX      = 0x00000400 # min box 
  46. global  WINDOW_MAX_BOX      = 0x00000800 # max box 
  47.  
  48. global  WINDOW_CARAT        = 0x00001000 # display control chars as ^X
  49. global  WINDOW_CHARS        = 0x00006000 # non-ascii character mapping bits
  50. global  WINDOW_IBM          = 0x00000000 # non-ascii as IBM chars
  51. global  WINDOW_DUMP         = 0x00000000 # non-ascii as HEX dump (no \ or X)
  52. global  WINDOW_OCTAL        = 0x00002000 # non-ascii as OCTAL
  53. global  WINDOW_HEX          = 0x00004000 # non-ascii as HEX
  54. global  WINDOW_DEC          = 0x00006000 # non-ascii as DECIMAL
  55.  
  56. global  WINDOW_EXPAND_ALL   = 0x00020000 # expand all chars using the
  57.                                          # WINDOW_CHARS, not just ctrl chars.
  58.  
  59. global  WINDOW_ASCII_DUMP   = 0x00040000 # display as ASCII format dump
  60. global  WINDOW_IBM_DUMP     = 0x00080000 # display as IBM format dump
  61. global  WINDOW_EITHER_DUMP  = 0x000C0000 # display is in either dump format
  62.  
  63. global  WINDOW_NUM_SIDE     = 0x00100000 # cursor is on hex side of dump
  64.  
  65. global  WINDOW_DISPLAY_FULL_FILENAME = 0x00010000
  66.  
  67. # some useful combinations:
  68.  
  69. global  WINDOW_STANDARD_MDI = 0x00010FE1 # title and border w/scroll bar right 
  70. global  WINDOW_STANDARD_SDI = 0x000100C2 # no title and border
  71. global  WINDOW_STANDARD     = 0x000100C2 # no title and border
  72. global  WINDOW_PLAIN        = 0x00010111 # title and plain border 
  73. global  WINDOW_HEX_DUMP_MDI = 0x00050FE1 # ascii hex dump format for MDI Mode
  74. global  WINDOW_HEX_DUMP_SDI = 0x000500C2 # ascii hex dump format for SDI Mode
  75. global  WINDOW_HEX_DUMP     = 0x00050000 # ascii hex dump format (Only)
  76.  
  77. # user definable window flags
  78. global  DOS_WINDOW_FLAG     = 0x00200000;
  79.  
  80. # System primitives allow windows as small as 1x1.
  81. # This package enforces a larger minimum window size:
  82.  
  83. global WINDOW_MIN_WIDTH  = 12
  84. global WINDOW_MIN_HEIGHT = 2
  85.  
  86. #--------------------------------------------------------------
  87. # Windows
  88. #--------------------------------------------------------------
  89.  
  90. ### window creation/deletion
  91.  
  92. ## gui-style window creation
  93. #
  94.  
  95. #function gui_create_window()
  96. #{
  97. #   if ( window_width > window_height )
  98. #      split_window_horizontal()
  99. #   else
  100. #      split_window_vertical()
  101. #}
  102.  
  103. ### create a window, using mouse if enabled, otherwise keyboard
  104. #
  105.  
  106. function make_window()                                          #PUBLIC #VOID
  107. {
  108.    current_window = create_window()
  109.    attach_window_buffer( current_window, current_buffer )
  110. }
  111.  
  112. ## create a 1/4 sized window in the middle of the screen:
  113. #
  114. local function create_medium_window()
  115. {
  116.    local   w1
  117.  
  118.    w1 = create_window( display_width / 4, display_height / 4,
  119.                        display_width / 2, display_height / 2 )
  120.  
  121.    return w1
  122. }
  123.  
  124. ## bleep and return 1 if current_window is a system window
  125. #       current_window by default
  126. function is_system_window()                             #PUBLIC #VOID
  127. {
  128.    if( !current_window )
  129.       return 1
  130.  
  131.    else if( and( window_flags, WINDOW_SYSTEM ))
  132.    {
  133.       beep()
  134.       return 1
  135.    }
  136.    else
  137.       return 0
  138. }
  139.  
  140. ### create a window, with all per-window attributes set to "standard" values
  141. #
  142. #       an optional fifth argument sets the window flags
  143. #
  144. #       this code can generate 2 window-changed events because
  145. #       the new window has to temporarily become current so the attributes
  146. #       can be changed.
  147. #
  148. function create_factory_window( x, y, xl, yl, flags, parent )           #PUBLIC #VOID
  149. {
  150.    local win, fg, bg
  151.    local old = current_window
  152.    local oldlineformat = default_linenumber_format;
  153.  
  154.    if( argcount() < 5 )
  155.       flags = default_window_flags
  156.  
  157.    default_linenumber_format = ""
  158.  
  159.    if ( argcount() < 6 )
  160.       win = create_window( x, y, xl, yl, flags )
  161.    else
  162.       win = create_window( x, y, xl, yl, flags, parent )
  163.  
  164.    default_linenumber_format = oldlineformat;
  165.  
  166.    if( win )
  167.    {
  168.       current_window = win
  169.  
  170.       # reset visible attributes, depending on display in use
  171.       visible_newlines       = \
  172.       visible_virtual_lines  = \
  173.       visible_end_buffer     = \
  174.       visible_spaces         = \
  175.       visible_tabs           = \
  176.       visible_virtual_spaces = ""
  177.  
  178.       scroll_context_top     = \
  179.       scroll_context_left    = \
  180.       scroll_context_right   = \
  181.       scroll_context_bottom  = \
  182.       window_page_offset     = \
  183.       window_page_overlap    = 0
  184.  
  185.       scroll_unit_horizontal = \
  186.       scroll_unit_vertical   = \
  187.       scroll_means_pan       = 1
  188.  
  189.       if ( window_valid( old ))
  190.          current_window = old
  191.    }
  192.  
  193.    return win
  194. }
  195.  
  196. ## delete a window and it's attached buffer, if any
  197. #       this routine navigates around a common programming hazard when
  198. #       deleting temporary windows with attached buffers
  199. #       (the order of the deletes is very important)
  200. #
  201. function delete_window_and_buffer( win )
  202. {
  203.    local oldwin = current_window
  204.  
  205.    if( argcount())
  206.       assign_current_window( win )
  207.    else
  208.       win = current_window
  209.  
  210.    delete_buffer( current_buffer )
  211.    delete_window( current_window )
  212.  
  213.    if( oldwin != win )
  214.       assign_current_window( oldwin )
  215. }
  216.  
  217. ## delete_window function to be bound to function keys
  218. #       it protects the user from accidently having a system window
  219. #       becoming current or being deleted.
  220. #
  221. #       delete_tiled_window offers similar protection
  222. #
  223. function delete_window_key()                                    #PUBLIC #VOID
  224. {
  225.    if ( is_system_window() )
  226.       return
  227.    else
  228.    {
  229.       delete_window()
  230.       if ( and( window_flags, WINDOW_SYSTEM ))
  231.          next_window()
  232.    }
  233. }
  234.  
  235.  
  236. #function create_tiled_window( pct, vert )                       #PUBLIC #VOID
  237. #{
  238. #   if( vert )
  239. #      split_window_vertical( window_width * pct / 100 )
  240. #   else
  241. #      split_window_horizontal( window_height * pct / 100 )
  242. #}
  243.  
  244. function split_window_horizontal( height )                      #PUBLIC #VOID
  245. {
  246.    local newBuffer;
  247.    local x0     = window_x0
  248.    local y0     = window_y0
  249.    local xex    = window_width
  250.    local yex0   = ( argcount() && height > 0 ? height : window_height / 2 )
  251.    local yex1   = window_height - yex0
  252.    local y1     = y0 + yex0 # - 1
  253.    local w1
  254.  
  255.    if( is_system_window())
  256.       return FALSE
  257.  
  258.    else if ( !mdi_mode )
  259.    {
  260.       warning("Command only valid in MDI mode")
  261.       return FALSE
  262.    }
  263.  
  264.    if( yex0 < WINDOW_MIN_HEIGHT || yex1 < WINDOW_MIN_HEIGHT )
  265.    {
  266.       warning( "window would be too small" )
  267.       return FALSE;
  268.    }
  269.  
  270.    # shrink current window and create a new one using same window flags as
  271.    # the existing window
  272.    frame_window( x0, y0, xex, yex0 )
  273.    w1 = create_window( x0, y1, xex, yex1, window_flags )
  274.    if(mdi_mode == 2)
  275.       attach_menu_to_win(w1);
  276.  
  277.    if ( w1 )
  278.    {
  279.       # make w1 have the same settings a current_window and set 
  280.       # current window to w1
  281.       dup_window_state(w1)
  282.  
  283.       if(create_new_bufwin)
  284.       {
  285.          newBuffer = gui_new(1);
  286.          attach_window_buffer(current_window, create_buffer(newBuffer, newBuffer, 
  287.                                      or(default_buffer_flags, BUFFER_SCRATCH)) )
  288.       }
  289.       else
  290.          attach_window_buffer( current_window, current_buffer )
  291.       return TRUE;
  292.    }
  293.    else
  294.    {
  295.       warning( "unable to create window" )
  296.       return FALSE;
  297.    }
  298. }
  299.  
  300. function split_window_vertical( width )                         #PUBLIC #VOID
  301. {
  302.    local newBuffer;
  303.    local x0   = window_x0
  304.    local y0   = window_y0
  305.    local yex  = window_height
  306.    local xex0 = ( argcount() && width > 0 ? width : window_width / 2 )
  307.    local xex1 = window_width - xex0
  308.    local x1   = x0 + xex0 # - 1
  309.    local w1
  310.  
  311.    if( is_system_window())
  312.       return FALSE
  313.    else if ( !mdi_mode )
  314.    {
  315.       warning("Command only valid in MDI mode")
  316.       return FALSE
  317.    }
  318.  
  319.    if( xex0 < WINDOW_MIN_WIDTH || xex1 < WINDOW_MIN_WIDTH )
  320.    {
  321.       warning( "window would be too small" )
  322.       return FALSE;
  323.    }
  324.  
  325.    # shrink current window and create a new one using same window flags as
  326.    # the existing window
  327.    frame_window( x0, y0, xex0, yex )
  328.    w1 = create_window( x1, y0, xex1, yex, window_flags )
  329.    if(mdi_mode == 2)
  330.       attach_menu_to_win(w1);
  331.  
  332.    if ( w1 )
  333.    {
  334.       # make w1 have the same settings a current_window and set 
  335.       # current window to w1
  336.       dup_window_state(w1)
  337.  
  338.       if(create_new_bufwin)
  339.       {
  340.          newBuffer = gui_new(1);
  341.          attach_window_buffer(current_window, create_buffer(newBuffer, newBuffer, 
  342.                                      or(default_buffer_flags, BUFFER_SCRATCH)) )
  343.       }
  344.       else
  345.          attach_window_buffer( current_window, current_buffer )
  346.       return TRUE;
  347.    }
  348.    else
  349.    {
  350.       warning( "unable to create window" )
  351.       return FALSE;
  352.    }
  353. }
  354.  
  355.  
  356. #global function dup_window( curr_window, flags )
  357. #{
  358. #   local new_window
  359. #   local curr_buf    = current_buffer
  360. #   local height      = window_height
  361. #   local width       = window_width
  362. #   local x0          = window_x0
  363. #   local y0          = window_y0
  364. #
  365. #   # if flags are specified use them, otherwise use existing 
  366. #   # window flags
  367. #   if ( flags )
  368. #      new_window = create_window( x0, y0, width, height, flags) 
  369. #   else
  370. #      new_window = create_window( x0, y0, width, height, window_flags)
  371. #
  372. #   attach_window_buffer( new_window, curr_buf )
  373. #   dup_window_state(new_window)   
  374. #   return new_window
  375. #}
  376.  
  377. global function dup_window_state(w1)
  378. {
  379.    local old
  380.  
  381.    # save all current window settings
  382.    old.linenumber_format      = linenumber_format
  383.    old.color_window_fg        = color_window_fg 
  384.    old.color_window_bg        = color_window_bg 
  385.    
  386.    old.color_linenumbers_bg   = color_linenumbers_bg 
  387.    old.color_linenumbers_fg   = color_linenumbers_fg 
  388.    
  389.    old.color_linecommands_bg  = color_linecommands_bg 
  390.    old.color_linecommands_fg  = color_linecommands_fg 
  391.    
  392.    
  393.    old.scroll_context_top     = scroll_context_top
  394.    old.scroll_context_bottom  = scroll_context_bottom
  395.    old.scroll_context_right   = scroll_context_right
  396.    old.scroll_context_left    = scroll_context_left
  397.    old.scroll_unit_horizontal = scroll_unit_horizontal
  398.    old.scroll_unit_vertical   = scroll_unit_vertical
  399.    old.scroll_means_pan       = scroll_means_pan
  400.  
  401.    current_window = w1  
  402.  
  403.    # set all window settings the same as old window
  404.    linenumber_format       = old.linenumber_format
  405.    color_window_fg         = old.color_window_fg 
  406.    color_window_bg         = old.color_window_bg 
  407.    
  408.    color_linenumbers_bg    = old.color_linenumbers_bg 
  409.    color_linenumbers_fg    = old.color_linenumbers_fg 
  410.    
  411.    color_linecommands_bg   = old.color_linecommands_bg 
  412.    color_linecommands_fg   = old.color_linecommands_fg 
  413.    
  414.    
  415.    scroll_context_top      = old.scroll_context_top
  416.    scroll_context_bottom   = old.scroll_context_bottom
  417.    scroll_context_right    = old.scroll_context_right
  418.    scroll_context_left     = old.scroll_context_left
  419.    scroll_unit_horizontal  = old.scroll_unit_horizontal
  420.    scroll_unit_vertical    = old.scroll_unit_vertical
  421.    scroll_means_pan        = old.scroll_means_pan
  422. }
  423.  
  424. # toggle line commands in the current window
  425. #
  426. function toggle_linecommands( enable )
  427. {
  428.    if( argcount() < 1 )
  429.       enable = !linenumber_format
  430.  
  431.    linecommands_enabled = 0+enable
  432.    if( linecommands_enabled && current_window )
  433.       toggle_linenumbers( 1 )
  434. }
  435.  
  436. # toggle line numbers in the current window
  437. #
  438. global nominal_linenumber_format = "%06d%v"
  439.  
  440. function toggle_linenumbers( enable )
  441. {
  442.    local action 
  443.    
  444.    enable += 0;
  445.    if( (enable != 2) && is_system_window() )
  446.       return FALSE
  447.  
  448.    if( argcount() < 1 )
  449.       enable = !linenumber_format
  450.  
  451.    if ( linenumber_format )
  452.       nominal_linenumber_format = linenumber_format
  453.  
  454.    if( enable > 0 ) 
  455.       linenumber_format = nominal_linenumber_format
  456.    else  
  457.       linenumber_format = ""
  458.  
  459.    message( "Line numbers %s.", enable ? "on" : "off" )
  460. }
  461.  
  462. ## toggle presence/absence of borders
  463. #
  464. #       Toggle_borders accepts an optional argument:
  465. #               true => set borders to their nominal value
  466. #               false => remove borders and titles.
  467. #       If the argument is omitted, the borders are "toggled".
  468. #
  469. #       Since there are several border styles we cannot simply toggle bits.
  470. #       Instead, we save the border setting when it is turned off, and
  471. #       restore the previously saved setting when toggeling it on.
  472. #
  473. #       When there are multiple border styles, and current_window is changed
  474. #       between calls to toggle_border, the effect may be to transfer border
  475. #       styles from window to window.
  476. #
  477. #       If borders are to be turned-off by default, then nominal_border_flags
  478. #       should be set in addition to default_window_flags.
  479.  
  480. global nominal_border_flags = WINDOW_STANDARD
  481.  
  482. function toggle_borders( enable )                               #PUBLIC #VOID
  483. {
  484.    local border_flags = WINDOW_SIZE_BORDER + WINDOW_TITLEBAR
  485.    local noborders    = and( window_flags, not( border_flags ))
  486.    local borders      = and( window_flags,      border_flags )
  487.  
  488.    if( is_system_window())
  489.       return FALSE
  490.  
  491.    if( argcount() < 1 )
  492.       enable = !borders               # toggle if no arg
  493.  
  494.    if( 0+enable )                     # restore nominal borders
  495.    {
  496.       window_flags = nominal_border_flags
  497.    }
  498.    else                                # remove nominal borders
  499.    {
  500.       nominal_border_flags = window_flags
  501.       window_flags         = noborders
  502.    }
  503. }
  504.  
  505. ### toggle border
  506.  
  507. function set_win_border( bordertype )      #PUBLIC #VOID
  508. {
  509.    if( is_system_window())
  510.       return FALSE
  511.  
  512.    if ( argcount() < 1 )
  513.         return FALSE
  514.  
  515.    # clear any old window flags
  516.    window_flags = and( window_flags, not(WINDOW_BORDERS) )
  517.  
  518.    # set new window flags
  519.    window_flags = or( window_flags, bordertype )
  520.  
  521.    message( "Window borders set to %d.", bordertype )
  522. }
  523.  
  524. function toggle_min_box( on )
  525. {
  526.    if( is_system_window())
  527.       return FALSE
  528.  
  529.    if ( argcount() < 1 )
  530.       on = ! and( window_flags,    WINDOW_MIN_BOX )
  531.    else
  532.       on = 0+on
  533.  
  534.    #
  535.    # toggle the setting
  536.    #
  537.    if ( on )
  538.       window_flags      =  or( window_flags, WINDOW_MIN_BOX )
  539.    else
  540.       window_flags      = and( window_flags, not( WINDOW_MIN_BOX ))
  541.  
  542.    message( "Minimize box is %s.", on ? "on" : "off" )
  543.    return on
  544. }
  545.  
  546. function toggle_max_box( on )
  547. {
  548.    if( is_system_window())
  549.       return FALSE
  550.  
  551.    if ( argcount() < 1 )
  552.       on = ! and( window_flags,    WINDOW_MAX_BOX )
  553.    else
  554.       on = 0+on
  555.  
  556.    #
  557.    # toggle the setting
  558.    #
  559.    if ( on )
  560.       window_flags      =  or( window_flags, WINDOW_MAX_BOX )
  561.    else
  562.       window_flags      = and( window_flags, not( WINDOW_MAX_BOX ))
  563.  
  564.    message( "Maximize box is %s.", on ? "on" : "off" )
  565.    return on
  566. }
  567.  
  568.  
  569. function toggle_sys_menu( on )
  570. {
  571.    if( is_system_window())
  572.       return FALSE
  573.  
  574.    if ( argcount() < 1 )
  575.       on = ! and( window_flags,    WINDOW_SYS_MENU )
  576.    else
  577.       on = 0+on
  578.  
  579.    #
  580.    # toggle the setting
  581.    #
  582.    if ( on )
  583.       window_flags      =  or( window_flags, WINDOW_SYS_MENU )
  584.    else
  585.       window_flags      = and( window_flags, not( WINDOW_SYS_MENU ))
  586.  
  587.    message( "System menu is %s.", on ? "on" : "off" )
  588.    return on
  589. }
  590.  
  591.  
  592. ### toggle vertical scroll bars cursor
  593.  
  594. function toggle_win_pathinfo( on )
  595. {
  596.    if( is_system_window())
  597.       return FALSE
  598.  
  599.    if ( argcount() < 1 )
  600.       on = ! and( window_flags, WINDOW_DISPLAY_FULL_FILENAME )
  601.    else
  602.       on = 0+on
  603.  
  604.    #
  605.    # toggle the setting
  606.    #
  607.    if ( on )
  608.       window_flags = or( window_flags, WINDOW_DISPLAY_FULL_FILENAME )
  609.    else
  610.       window_flags = and( window_flags, not( WINDOW_DISPLAY_FULL_FILENAME ))
  611.  
  612.    update_current_caption()
  613.  
  614.    message( "Fully qualified path name on title bar is %s.", on ? "on" : "off" )
  615.    return on
  616. }
  617.  
  618. function toggle_win_vscroll( on )                           #PUBLIC #VOID
  619. {
  620.    if( is_system_window())
  621.       return FALSE
  622.  
  623.    if ( argcount() < 1 )
  624.       on = ! and( window_flags,    WINDOW_VERT_SB )
  625.    else
  626.       on = 0+on
  627.  
  628.    #
  629.    # toggle the setting
  630.    #
  631.    if ( on )
  632.       window_flags      =  or( window_flags, WINDOW_VERT_SB )
  633.    else
  634.       window_flags      = and( window_flags, not( WINDOW_VERT_SB ))
  635.  
  636.    message( "Vertical scroll bars %s.", on ? "on" : "off" )
  637.    return on
  638. }
  639.  
  640.  
  641. ### toggle horizontal scroll bars
  642.  
  643. function toggle_win_hscroll( on )                           #PUBLIC #VOID
  644. {
  645.    if( is_system_window())
  646.       return FALSE
  647.  
  648.    if ( argcount() < 1 )
  649.       on = ! and( window_flags, WINDOW_HORIZ_SB )
  650.    else
  651.       on = 0+on
  652.  
  653.    #
  654.    # toggle the setting
  655.    #
  656.    if ( on )
  657.       window_flags      =  or( window_flags, WINDOW_HORIZ_SB )
  658.    else
  659.       window_flags      = and( window_flags, not( WINDOW_HORIZ_SB ))
  660.  
  661.    message( "Horizontal scroll bars %s.", on ? "on" : "off" )
  662.    return on
  663. }
  664.  
  665. function toggle_scrollbars( enable )
  666. {
  667.    local action 
  668.  
  669.    enable += 0;
  670.    if( (enable != 2) && is_system_window() )
  671.       return FALSE
  672.  
  673.    if( argcount() < 1 )
  674.       enable = !and( window_flags, WINDOW_SCROLLBARS )
  675.  
  676.    if ( enable )
  677.       window_flags = or( window_flags, WINDOW_SCROLLBARS )
  678.    else
  679.       window_flags = and( window_flags, not(WINDOW_SCROLLBARS) )
  680.  
  681.    message( "Scroll bars %s.", enable ? "on" : "off" )
  682. }
  683.  
  684. ### toggle window titles
  685.  
  686. function toggle_win_title( on )                           #PUBLIC #VOID
  687. {
  688.    if( is_system_window())
  689.                 return FALSE
  690.  
  691.    if ( argcount() < 1 )
  692.       on = ! and( window_flags,    WINDOW_TITLE )
  693.    else
  694.       on = 0+on
  695.  
  696.    #
  697.    # toggle the setting
  698.    #
  699.    if ( on )
  700.                 window_flags      =  or( window_flags, WINDOW_TITLE )
  701.    else
  702.                 window_flags      = and( window_flags, not( WINDOW_TITLE ))
  703.  
  704.    message( "Window title %s.", on ? "on" : "off" )
  705.    return on
  706. }
  707.  
  708. ### window resizing, positioning & scrolling
  709.  
  710. function larger_window()
  711. {
  712.    local wz = and( window_flags, WINDOW_ZOOM )
  713.  
  714.    if( is_system_window())
  715.       return FALSE
  716.  
  717.    if( wz == WINDOW_COLLAPSED )
  718.       restore_window()
  719.  
  720.    else if( wz == WINDOW_NORMAL )
  721.       expand_window()
  722. }
  723.  
  724. function smaller_window()
  725. {
  726.    local wz = and( window_flags, WINDOW_ZOOM )
  727.  
  728.    if( is_system_window())
  729.       return FALSE
  730.  
  731.    if( wz == WINDOW_EXPANDED )
  732.       restore_window()
  733.  
  734.    else if( wz == WINDOW_NORMAL )
  735.       collapse_window()
  736. }
  737.  
  738. function scroll_down_1()
  739. {
  740.    scroll_vertical( 1, scroll_or_pan())
  741. }
  742.  
  743. function scroll_up_1()
  744. {
  745.    scroll_vertical( -1, scroll_or_pan())
  746. }
  747.  
  748. function scroll_down_half()
  749. {
  750.    local h = window_text_height / 2
  751.    scroll_vertical(( h <= 0 ? 1 : h ), scroll_or_pan())
  752. }
  753.  
  754. function scroll_up_half()
  755. {
  756.    local h = window_text_height / 2
  757.    scroll_vertical( -( h <= 0 ? 1 : h ), scroll_or_pan())
  758. }
  759.  
  760. function scroll_left_1()
  761. {
  762.    scroll_horizontal( -1, scroll_or_pan())
  763. }
  764.  
  765. function scroll_right_1()
  766. {
  767.    scroll_horizontal( 1, scroll_or_pan())
  768. }
  769.  
  770. # these functions reposition the window so that the current line is
  771. #       in the indicated position (if possible):
  772.  
  773. global function scroll_window_top( n )                          #PUBLIC #VOID
  774. {
  775.    if( n >= window_text_height )
  776.        n  = window_text_height - font_height
  777.  
  778.    scroll_vertical( distance_to_window_top() - n, scroll_or_pan())
  779. }
  780.  
  781. global function scroll_window_bottom( n )                       #PUBLIC #VOID
  782. {
  783.    if( n >= window_text_height )
  784.        n  = window_text_height - 1
  785.  
  786.    scroll_vertical( - distance_to_window_bottom() + n, scroll_or_pan())
  787. }
  788.  
  789. global function scroll_window_middle( n )                       #PUBLIC #VOID
  790. {
  791.    # arguably should guard against too large values of abs(n)
  792.  
  793.    scroll_vertical( -distance_to_window_middle() - n, scroll_or_pan())
  794. }
  795.  
  796. ## center_cursor
  797. #       similar to scroll_window_middle but never changes the position in
  798. #       the buffer (i.e. current_line or current_column).  This function is
  799. #       useful for restoring a convenient window orientation when the cursor
  800. #       has drifted too far to the top or bottom.
  801. #
  802. global function center_cursor()                                 #PUBLIC #VOID
  803. {
  804.    local   save_context_top = scroll_context_top
  805.    scroll_context_top = 0
  806.  
  807.    scroll_vertical( current_line - window_first - shiftr( window_text_height, 1 ), 0 )
  808.  
  809.    scroll_context_top = save_context_top
  810. }
  811.  
  812.  
  813. ## scroll_or_pan -- determine to scroll or pan by
  814. #       interrogating the scroll_means_pan status and
  815. #       complementing it if the SCROLL_LOCK key is pressed
  816. #
  817. global function scroll_or_pan()
  818. {
  819.    local smp = !scroll_means_pan   # !! smp default should be reversed
  820.    return xor_scroll_lock( smp )
  821. }
  822.  
  823. ## interrogate status of scroll-lock key
  824.  
  825. function scroll_lock_status()
  826. {
  827.  return !!and( keyboard_flags, KB_SCROLL_LOCK )
  828. ##!!?? above isn't working consistently
  829. #   return 0
  830. }
  831.  
  832. ## xor the argument with scroll_lock_status()
  833.  
  834. function xor_scroll_lock( var )
  835. {
  836.    return xor( var, scroll_lock_status())
  837. }
  838.  
  839. ### distances from the cursor to current_window's borders
  840. #       these are relative to a position within the window to the given edge.
  841. #       if the cursor happens to be outside window-borders the values may
  842. #       be negative.
  843.  
  844. function distance_to_window_top()                               #PUBLIC #INT
  845. {
  846.    return current_line - window_first
  847. }
  848.  
  849. function distance_to_window_bottom()                            #PUBLIC #INT
  850. {
  851.    return window_first + window_text_height - current_line - 1
  852. }
  853.  
  854. function distance_to_window_left()                              #PUBLIC #INT
  855. {
  856.    return current_column - window_margin - 1
  857. }
  858.  
  859. function distance_to_window_right()                             #PUBLIC #INT
  860. {
  861.    return window_margin + window_text_width - linenumber_width - current_column
  862. }
  863.  
  864. # This function lacks symmetry with the four above.  We eventually may need
  865. # to distinguish between horizontal, vertical and combined centering.  For
  866. # now we only need vertical motion, and this computes the quantity, m,
  867. # such that     current_line += m
  868. # and           scroll_vertical( m )
  869. # both put the current line into the middle of the screen.
  870. #
  871. function distance_to_window_middle()
  872. {
  873.    # message( "wf: %d, wth: %d, line=%d",          \
  874.    #       window_first,                           \
  875.    #       window_text_height,                     \
  876.    #       current_line )
  877.    
  878.    return window_first + window_text_height / 2 - current_line
  879. }
  880.  
  881. ### window/buffer organization
  882. #
  883. # collapse all windows to an orderly array of icons
  884. #
  885. global function organize_windows()                      #PUBLIC #VOID
  886. {
  887.    local   w
  888.    local   window_list
  889.    local   name
  890.    local   tie
  891.    local   n
  892.  
  893.    if ( !(w = current_window))
  894.       return
  895.  
  896.    do {
  897.       if( !and( window_flags, WINDOW_SYSTEM ))
  898.       {
  899.          name = window_name
  900.          tie = 1
  901.          while ( name in window_list )
  902.          {
  903.             # break ties in sorting order
  904.             name = window_name "~" tie++
  905.          }
  906.          collapse_window()
  907.          window_list[ name ] = current_window
  908.          n++
  909.       }
  910.       next_window( "", 1 )
  911.    } while( w != current_window )  # restores current_window
  912.  
  913.    relocate_icons( window_list, n )
  914. }
  915.  
  916. # create an icon for each non-system buffer and then organize the
  917. # resulting windows in filename order.  The windows and icons are
  918. # initially created all on top of each other.
  919. #
  920. global function organize_buffers()                      #PUBLIC #VOID
  921. {
  922.    local   w
  923.    local   b
  924.    local   window_list
  925.    local   n
  926.    local   dw
  927.  
  928.    if ( !(w = current_window))
  929.       return
  930.  
  931.    # get buffers already attached to windows
  932.    do {
  933.       if ( !and( window_flags, WINDOW_SYSTEM ))
  934.       {
  935.          if ( buffer_filename in window_list )
  936.          {
  937.             # remove redundant window
  938.             dw = current_window
  939.             next_window( "", 1 )
  940.             delete_window( dw )
  941.             continue
  942.          }
  943.          else
  944.          {
  945.             # iconize this window and add to the list
  946.             collapse_window()
  947.             window_list[ buffer_filename ] = current_window
  948.             n++
  949.          }
  950.       }
  951.       next_window( "", 1 )
  952.    } while( w != current_window )
  953.  
  954.    # create icons for all remaining non-system buffers
  955.    b = current_buffer
  956.    do {
  957.       if ( !and( buffer_flags, BUFFER_SYSTEM )        \
  958.         && !( buffer_filename in window_list ))
  959.       {
  960.          current_window = create_medium_window()
  961.          attach_window_buffer( current_window, current_buffer )
  962.          collapse_window()
  963.          window_list[ buffer_filename ] = current_window
  964.          n++
  965.          current_window = w
  966.       }
  967.       next_buffer( "", 1 )
  968.    } while( b != current_buffer )
  969.  
  970.    relocate_icons( window_list, n )
  971. }
  972.  
  973. # position icons in the order defined by array window_list
  974. #
  975. local function relocate_icons( window_list, n )
  976. {
  977.    local   prevWindow = current_window
  978.    local   start_x = 1
  979.    local   start_y = 1
  980.    local   dx = 16
  981.    local   dy = 2
  982.    local   x, y
  983.    local   i
  984.  
  985.    if ( !window_list || n < 1 || typeof( window_list ) != "array" )
  986.       return
  987.  
  988.    # if the number of windows is large, fill the screen more efficiently
  989.    if ( n > display_height/dy * display_width/dx )
  990.    {
  991.       start_x = 1
  992.       start_y = 0
  993.       dy = 1
  994.    }
  995.  
  996.    # position icons in a grid
  997.    x = start_x
  998.    y = start_y
  999.    for ( i in window_list )
  1000.    {
  1001.       current_window = window_list[ i ]
  1002.       move_window( x, y )
  1003.       y += dy
  1004.       if ( y >= display_height - 1 )
  1005.       {
  1006.          x += dx
  1007.          if ( x >= display_width - 14 )
  1008.          {
  1009.             start_x += 4
  1010.             x = start_x
  1011.          }
  1012.          y = start_y
  1013.       }
  1014.    }
  1015.  
  1016.    assign_current_window( prevWindow )
  1017. }
  1018.  
  1019. ### fine-grain window positioning & resizing -- mouse alternates
  1020. #
  1021. #       These functions support moving and resizing windows via the keypad.
  1022. #
  1023.  
  1024. ##
  1025.  
  1026. local   adjust_move_resize_flag         # true if moving, false if resizing
  1027. local   adjustWindowVars[]
  1028.  
  1029. ## resize or move a window (opposite if scroll lock is on)
  1030. #
  1031. #  xor(  pos, scroll_lock_status()) => moving
  1032. #  xor( !pos, scroll_lock_status()) => resizing (default if called from keymap)
  1033.  
  1034. global function adjust_window( pos )                    #PUBLIC #VOID
  1035. {
  1036.    local   windowZoom = and( window_flags, WINDOW_ZOOM )
  1037.  
  1038.    if ( is_system_window() )
  1039.       return FALSE
  1040.  
  1041.    # we don't move or resize an icon or expanded window
  1042.    restore_window()
  1043.  
  1044.    # save current window position and size
  1045.    adjustWindowVars[ "zoom" ]      = windowZoom
  1046.    adjustWindowVars[ "x" ]         = window_x0     
  1047.    adjustWindowVars[ "y" ]         = window_y0
  1048.    adjustWindowVars[ "w" ]         = window_width
  1049.    adjustWindowVars[ "h" ]         = window_height
  1050.  
  1051.    # save a flag indicating whether we should move or resize the window
  1052.    adjust_move_resize_flag = !!pos
  1053.  
  1054.    # define a keymap to use while resizing
  1055.    push_keymap( create_keymap( empty_keymap ))
  1056.  
  1057.    assign_key( "<Up>",     "adjust_window_key  0 -1" )
  1058.    assign_key( "<Down>",   "adjust_window_key  0  1" )
  1059.    assign_key( "<Right>",  "adjust_window_key  1  0" )
  1060.    assign_key( "<Left>",   "adjust_window_key -1  0" )
  1061.    assign_key( "<Enter>",  "adjust_window_exit 1" )
  1062.    assign_key( "<Esc>",    "adjust_window_exit 0" )
  1063.  
  1064.    # create a temporary status bar at the bottom of the screen
  1065.    optional_function( "enable_status_bar_messages" )
  1066.  
  1067.    notify( "Use arrow keys to adjust window, ENTER to accept, and ESC to cancel." )
  1068. }
  1069.  
  1070. function adjust_window_key( x, y )
  1071. {
  1072.    if ( xor_scroll_lock( adjust_move_resize_flag ))        # move
  1073.    {
  1074.       frame_window( window_x0 + x,    window_y0 + y,  \
  1075.                     window_width,     window_height   )
  1076.    }
  1077.    else                                                    # resize
  1078.    {
  1079.       frame_window( window_x0,        window_y0,        \
  1080.                     window_width + x, window_height + y )
  1081.    }
  1082. }
  1083.  
  1084. function adjust_window_exit( accept )
  1085. {
  1086.    local   x, y
  1087.    local   w, h
  1088.    local   zoom
  1089.  
  1090.    # restore the original keymap
  1091.    pop_keymap()
  1092.  
  1093.    # accept or cancel the new configuration
  1094.    if ( 0+accept )
  1095.       message( "" )
  1096.  
  1097.    else
  1098.    {
  1099.       # restore window pos/size
  1100.  
  1101.       x       = adjustWindowVars[ "x" ]
  1102.       y       = adjustWindowVars[ "y" ]
  1103.       w       = adjustWindowVars[ "w" ]
  1104.       h       = adjustWindowVars[ "h" ]
  1105.  
  1106.       frame_window( x, y, w, h )
  1107.  
  1108.       # restore window zoom state
  1109.  
  1110.       zoom    = adjustWindowVars[ "zoom" ]
  1111.  
  1112.       if ( zoom == WINDOW_COLLAPSED )
  1113.          collapse_window()
  1114.  
  1115.       else if ( zoom == WINDOW_EXPANDED )
  1116.          expand_window()
  1117.  
  1118.       message( "Window adjustment canceled." )
  1119.    }
  1120.  
  1121.    # deallocate the temp array
  1122.    delete( adjustWindowVars )
  1123.  
  1124.    # restore the status bar
  1125.    optional_function( "restore_status_bar" )
  1126. }
  1127.  
  1128.  
  1129. ## show_visibles()
  1130. #
  1131. #       This function displays all tabs, spaces, newline chars, etc. which
  1132. #       are accessible via visible_xxx variables.
  1133.  
  1134. global function show_visibles()                                 #PUBLIC #VOID
  1135. {
  1136.    visible_virtual_lines  = "~"
  1137.    visible_end_buffer     = ""
  1138.    visible_newlines       = "■"
  1139.    visible_spaces         = "·"
  1140.    visible_tabs           = ""
  1141.    visible_virtual_spaces = " "
  1142. }
  1143.  
  1144. ## reset_visibles()
  1145. #
  1146. #       This function resets all of the "visible" representations for
  1147. #       otherwise non-printing attributes to their less visible defaults.
  1148.  
  1149. function reset_visibles()                                       #PUBLIC #VOID
  1150. {
  1151.    visible_virtual_lines          = ""
  1152.    visible_end_buffer             = ""
  1153.    visible_newlines               = ""
  1154.    visible_spaces                 = " "
  1155.    visible_tabs                   = " "
  1156.    visible_virtual_spaces         = " "
  1157.    default_visible_virtual_lines  = ""
  1158.    default_visible_end_buffer     = ""
  1159.    default_visible_newlines       = ""
  1160.    default_visible_spaces         = " "
  1161.    default_visible_tabs           = " "
  1162.    default_visible_virtual_spaces = " "
  1163. }
  1164.  
  1165. ## assign_current_window()
  1166. #
  1167. #  assign a window id to the current window iff the window id is valid
  1168. #
  1169. function assign_current_window( winid )
  1170. {
  1171.    if (window_valid( winid ))
  1172.       current_window = winid;
  1173. }
  1174.  
  1175. ## toggle_window_zoom()
  1176. #
  1177. # toggles the WINDOW_EXPANDED bit in the window_flags.  This
  1178. # has the effect of alternately expanding and restoring the size
  1179. # of the current window.
  1180. #
  1181. global function toggle_window_zoom( expand )
  1182. {
  1183.    expand = ( argcount() < 1 ) ? !and( window_flags, WINDOW_EXPANDED ) \
  1184.                                : 0+expand
  1185.  
  1186.    if ( expand )
  1187.       expand_window()
  1188.    else
  1189.       restore_window()
  1190. }
  1191.  
  1192. global function next_window_key()                               #PUBLIC #VOID
  1193. {
  1194.    local   cw = current_window
  1195.    while( (next_window() != cw) &&
  1196.           and( window_flags,WINDOW_ZOOM) == WINDOW_HIDDEN )
  1197.    {
  1198.       continue;
  1199.    }
  1200. }
  1201.  
  1202. global function prev_window_key()                               #PUBLIC #VOID
  1203. {
  1204.    local   cw = current_window
  1205.    while( (prev_window() != cw) &&
  1206.           and( window_flags,WINDOW_ZOOM) == WINDOW_HIDDEN )
  1207.    {
  1208.       continue;
  1209.    }
  1210. }
  1211.