home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-09-27 | 30.3 KB | 1,177 lines |
- # $Header: P:/source/ppee/macros/windows.pev 1.110 26 Sep 1990 17:04:58 skipr $
-
- ##############################################################################
- #
- # Sage Software - POLYTRON Division
- # 1700 NW 167th Place
- # Beaverton, OR 97006
- #
- # Copyright 1990, Sage Software, Inc.
- #
- # Permission is hereby granted for licensed users of Sage Professional
- # Editor and PolyAwk to copy and modify this source code for their own
- # personal use. These derivative works may be distributed only to other
- # licensed Sage Professional Editor and PolyAwk users. All other usage
- # is prohibited without express written permission from Sage Software.
- #
- ##############################################################################
-
- #### $Workfile: windows.pel $: support for windows
-
- #### symbolic window flag values
- #
- global WINDOW_COLLAPSED= 0x0000 # window collapsed
- global WINDOW_NORMAL = 0x0001 # window normal
- global WINDOW_EXPANDED = 0x0002 # window expanded
- global WINDOW_HIDDEN = 0x0003 # window state: one of the above
- global WINDOW_ZOOM = 0x0003 # window state: one of the above
-
- global WINDOW_SYSTEM = 0x0004 # window is a "system" window
-
- global WINDOW_BORDERS = 0x00F0 # all border & scroll-bar bits (for toggle_borders)
- global WINDOW_BORDER = 0x0080 # border present w/out scroll-bars (used for Menus)
- global WINDOW_SB_RIGHT = 0x0010 # border w/scroll bar right
- global WINDOW_SB_BELOW = 0x0020 # border w/scroll bar below
- global WINDOW_SB_LEFT = 0x0040 # border w/scroll bar left
-
- global WINDOW_CHARS = 0x0300 # character mapping bits
- global WINDOW_IBM = 0x0000 # non-ascii as IBM chars
- global WINDOW_OCTAL = 0x0100 # non-ascii as OCTAL
- global WINDOW_HEX = 0x0200 # non-ascii as HEX
- # (if both HEX and OCTAL are specified,
- # result is UNDEFINED (currently it is
- # the same as if neither is specified))
-
- global WINDOW_CARAT = 0x0800 # display control chars as ^X
-
- global WINDOW_TITLEA = 0x1000 # title bar above/top of window
- global WINDOW_TITLEB = 0x2000 # title bar below/bottom of window
- # (TITLEB is ignored if TITLEA or if
- # SB_BELOW are specified)
- global WINDOW_TITLE = 0x3000 # title bar above/top of window
-
- global WINDOW_RULER = 0x4000 # visible tab ruler
-
- global WINDOW_HEADERS = 0x7000 # titles and tab ruler
-
-
- # some useful combinations:
-
- global WINDOW_NOBORDER = 0x0000 # no border, no title, no nothing
- global WINDOW_NOTITLE = 0x0000 # no title
- global WINDOW_STANDARD = 0x1090 # title and border w/scroll bar right (SPE default)
- global WINDOW_PLAIN = 0x1080 # title and plain border (Brief default)
- global WINDOW_SB_RIGHTB = 0x0030 # border w/scroll bar right & below
- global WINDOW_SB_LEFTB = 0x0060 # border w/scroll bar left & below
- global WINDOW_MENU = 0x1084 # system window w/ title, plain border
- global WINDOW_MENU0 = 0x0084 # system window w/ plain border, no title
-
- # user definable window flags
- global DOS_WINDOW_FLAG = 0x00020000;
-
- # System primitives allow windows as small as 1x1.
- # This package enforces a larger minimum window size:
-
- global WINDOW_MIN_WIDTH = 12
- global WINDOW_MIN_HEIGHT = 2
-
-
- #--------------------------------------------------------------
- # Windows
- #--------------------------------------------------------------
-
- ### window creation/deletion
-
- ### create a window, using mouse if enabled, otherwise keyboard
- #
-
- function make_window(){ #PUBLIC #VOID
- if( mouse_enabled && mouse_available ) {
- current_window = create_window()
- attach_window_buffer( current_window, current_buffer )
- color_current_window() # maybe change its color
- } else {
- current_window = create_medium_window()
- attach_window_buffer( current_window, current_buffer )
- adjust_window()
- }
- }
-
- ### create a window, with all per-window attributes set to "standard" values
- #
- # an optional fifth argument sets the window flags
- #
- # this code can generate 2 window-changed events because
- # the new window has to temporarily become current so the attributes
- # can be changed.
- #
- function create_factory_window( x, y, xl, yl, flags ){ #PUBLIC #VOID
- local win, fg, bg
- local old = current_window
- local oldlineformat = default_linenumber_format;
-
- if( argcount() < 5 )
- flags = default_window_flags
-
-
- default_linenumber_format = ""
- win = create_window( x, y, xl, yl, flags )
- default_linenumber_format = oldlineformat;
-
- if( win ){
- current_window = win
-
- # initialize BAR_COLOR, HBAR_COLOR, and SHADOW_COLOR
- init_menu_colors()
-
- # reset visible attributes, depending on display in use
- color_text = \
- color_border = BAR_COLOR
- color_highlight = HBAR_COLOR
- color_linenumbers = \
- color_title = TBAR_COLOR
-
- visible_newlines = \
- visible_virtual_lines = \
- visible_end_buffer = \
- visible_spaces = \
- visible_tabs = \
- visible_virtual_spaces = ""
-
- scroll_context_top = \
- scroll_context_left = \
- scroll_context_right = \
- scroll_context_bottom = \
- window_page_offset = \
- window_page_overlap = 0
-
- scroll_unit_horizontal = \
- scroll_unit_vertical = \
- scroll_means_pan = 1
-
- if ( window_valid( old ))
- current_window = old
- }
-
- return win
- }
-
- ## factory_prompt()
- #
- # Enhanced prompt function creates a factory window containing the
- # dialog window. This is used in cases where the prompt line is
- # accompanied by a one-line instructional message.
- #
- # Arguments:
- # instructMsg - contains the text of the instruction message
- # historyTitle - the name of the history category
- # prefix - the text to display before the input area
- # cmd - the default value for prompt response
- #
- # Return value:
- # the response to prompt()
- #
- global function factory_prompt( instructMsg, historyTitle, prefix, cmd ) { #PUBLIC #VOID
- local priorDialogWindow
- local instructionWindow
- local priorColorMessages = color_messages
-
- # create the outside window
- instructionWindow = create_factory_window( \
- 2, (display_height / 2) - 2, \
- 76, 4, \
- WINDOW_BORDER )
-
- if ( !instructionWindow ) {
- return 0
- }
-
- # temporarily remove dialog window if one exists
- if (( priorDialogWindow = dialog_window )) {
- toggle_dialog( 0 )
- }
-
- dialog_window = create_window( \
- 3, display_height / 2, \
- 74, 1, \
- WINDOW_SYSTEM )
-
- current_window = instructionWindow
- window_cursor_x = 0
- window_cursor_y = 0
- write_window( instructMsg )
-
- color_messages = color_text
-
- # give a chance to edit the command
- cmd = prompt_history( historyTitle, prefix, cmd )
-
- # restore dialog window
- delete_window( instructionWindow )
- delete_window( dialog_window )
-
- color_messages = priorColorMessages
-
- if (priorDialogWindow) {
- toggle_dialog(1)
- }
-
- return cmd
- }
-
- ## create a 1/4 sized window in the middle of the screen:
- #
- function create_medium_window(){
- local w1
- local w2 = current_window
-
- w1 = create_window( display_width / 4,
- display_height / 4,
- display_width / 2,
- display_height / 2 )
- if ( w1 ) {
- current_window = w1
- color_current_window() # maybe change its color
- current_window = w2
- }
-
- return w1
- }
-
-
- ## bleep and return 1 if current_window is a system window
- # current_window by default
- function is_system_window(){ #PUBLIC #VOID
- if( !current_window || and( window_flags, WINDOW_SYSTEM )){
- beep()
- return 1
- }
- return 0
- }
-
- ## delete a window and it's attached buffer, if any
- # this routine navigates around a common programming hazard when
- # deleting temporary windows with attached buffers
- # (the order of the deletes is very important)
- #
- function delete_window_and_buffer( win ){
- local oldwin = current_window
-
- if( argcount())
- assign_current_window( win )
- else
- win = current_window
-
- delete_buffer( current_buffer )
- delete_window( current_window )
-
- if( oldwin != win )
- assign_current_window( oldwin )
- }
-
- ## delete_window function to be bound to function keys
- # it protects the user from accidently having a system window
- # such as the dialog window becoming current or being deleted.
- #
- # delete_tiled_window offers similar protection
- #
- function delete_window_key(){ #PUBLIC #VOID
- if( is_system_window())
- return
- delete_window()
- if( and( window_flags, WINDOW_SYSTEM ))
- next_window()
- }
-
- ## delete a "tiled" window; if any window is adjacent, expand the adjacent
- # window to fill the space vacated by the window being deleted.
- # If multiple windows are adjacent, only one is expanded.
- # Adjacent windows are considered in the following order, and
- # the first one encountered gets expanded: above, below, left & right.
- #
- # This code works even when no windows exist.
-
- function delete_tiled_window( w ){ #PUBLIC #INT
- local flags, x0, y0, x1, y1
- local ww, joined
-
- if( is_system_window())
- return
-
- ww = current_window # save entry value
-
- if( argcount() && window_valid( w ))
- current_window = w # temporary change to get coordinates
- else
- w = current_window # current_window is the one to delete
-
- x0 = window_x0 # corner coordinates of ...
- y0 = window_y0 # ... window to be deleted
- x1 = x0 + window_width - 1
- y1 = y0 + window_height - 1
- flags = window_flags
-
- assign_current_window( ww ) # restore value on entry
-
- # if( and( flags, WINDOW_SYSTEM ))
- # error( "delete_tiled_window cannot delete system windows" )
-
- # look at all windows except w for adjacency to w
-
- do {
- if( current_window != w )
- joined = joinIfAdjacent( x0, y0, x1, y1 )
- if( joined )
- break
- next_window()
- } while( ww != current_window )
-
- delete_window( w )
- if( and( window_flags, WINDOW_SYSTEM ))
- next_window()
-
- return joined
- }
-
- # this function tests to see if current_window has an entire edge in common
- # with the window specified by the arguments. If so, current_window
- # is expanded to fill the to-be vacated space.
- #
- # A more general and arguably better algorithm would adjust windows
- # that share only part of an adjacent edge, perhaps as a second pass.
- #
-
- local function joinIfAdjacent( x0, y0, x1, y1 ){
- local cx0 = window_x0
- local cy0 = window_y0
- local cx1 = cx0 + window_width - 1
- local cy1 = cy0 + window_height - 1
-
-
- if( is_system_window() || !and( window_flags, WINDOW_ZOOM))
- return 0
-
- if( x0 == cx0 && x1 == cx1 ){
- if( cy1 + 1 == y0 ){ # above
- frame_window( x0, cy0, window_width, y1 - cy0 + 1 )
- return 1
- } else if( y1 + 1 == cy0 ){ # below
- frame_window( x0, y0, window_width, cy1 - y0 + 1 )
- return 1
- }
- } else if( y0 == cy0 && y1 == cy1 ){
- if( cx1 + 1 == x0 ){ # left
- frame_window( cx0, cy0, x1 - cx0 + 1, window_height )
- return 1
- } else if( x1 + 1 == cx0 ){ # right
- frame_window( x0, y0, cx1 - x0 + 1, window_height )
- return 1
- }
- }
-
- return 0
- }
-
-
- function create_tiled_window( pct, vert ){ #PUBLIC #VOID
- if( vert ){
- split_window_vertical( window_width * pct / 100 )
- } else {
- split_window_horizontal( window_height * pct / 100 )
- }
- }
-
-
-
- function split_window_horizontal( height ){ #PUBLIC #VOID
- local x0 = window_x0
- local y0 = window_y0
- local xex = window_width
- local yex0 = ( height > 0 ? height : window_height / 2 )
- local yex1 = window_height - yex0
- local y1 = y0 + yex0 # - 1
- local w1
-
- if( is_system_window())
- return FALSE
-
- if( yex0 < WINDOW_MIN_HEIGHT || yex1 < WINDOW_MIN_HEIGHT ){
- warning( "window would be too small" )
- return FALSE;
- }
-
- # shrink current window and create a new one
-
- frame_window( x0, y0, xex, yex0 )
- w1 = create_window( x0, y1, xex, yex1 )
- if ( w1 ) {
- current_window = w1
- color_current_window() # maybe change its color
- attach_window_buffer( current_window, current_buffer )
- } else {
- warning( "unable to create window" )
- return FALSE;
- }
-
- return TRUE;
- }
-
- function split_window_vertical( width ){ #PUBLIC #VOID
- local x0 = window_x0
- local y0 = window_y0
- local yex = window_height
- local xex0 = ( width > 0 ? width : window_width / 2 )
- local xex1 = window_width - xex0
- local x1 = x0 + xex0 # - 1
- local w1
-
- if( is_system_window())
- return FALSE
-
- if( xex0 < WINDOW_MIN_WIDTH || xex1 < WINDOW_MIN_WIDTH ){
- warning( "window would be too small" )
- return FALSE;
- }
-
- # shrink existing and create a new one
-
- frame_window( x0, y0, xex0, yex )
- w1 = create_window( x1, y0, xex1, yex )
- if ( w1 ) {
- current_window = w1
- color_current_window() # maybe change its color
- attach_window_buffer( current_window, current_buffer )
- } else {
- warning( "unable to create window" )
- return FALSE;
- }
-
- return TRUE;
- }
-
-
- # toggle the presence of a standard 1-line bottom-of-the-screen dialog window,
- # and adjust adjacent windows. If a dialog window is present but not in
- # the right place, it is toggled-off, but adjacent windows are not
- # adjusted.
-
- local prev_dialog_x0;
- local prev_dialog_y0;
- local prev_dialog_xExt;
- local prev_dialog_yExt;
-
- function toggle_dialog( selection ){ #PUBLIC #VOID
- local priorWindow = current_window
- local w
- local y1 = display_height - 1
- local cw = current_window;
- local def_col_text = default_color_text;
-
- if ( argcount() < 1 )
- selection = !dialog_window
- else
- selection = 0+selection
-
- if ( selection && !dialog_window ) {
-
- ## create a permanent dialog window at the bottom of
- ## the screen
-
-
- default_color_text = color_messages;
-
- if (prev_dialog_xExt && prev_dialog_yExt)
- dialog_window = create_window( prev_dialog_x0, prev_dialog_y0, \
- prev_dialog_xExt, prev_dialog_yExt, \
- WINDOW_SYSTEM )
- else
- dialog_window = create_window( 0, y1, \
- display_width, 1, \
- WINDOW_SYSTEM )
-
-
- default_color_text = def_col_text;
-
- # allow all messages to be displayed
- message_level = 0
-
- # adjust all non_system windows
-
- if ( !next_window() || and( window_flags, WINDOW_SYSTEM ) ) {
- # only system windows are present
- return
- }
-
- w = current_window
- do {
- next_window()
- if ( window_y0 + window_height - 1 == y1 ) {
- # shorten window by 1 line:
- frame_window( \
- window_x0, window_y0, \
- window_width, y1 - window_y0 )
- }
- } while( w != current_window )
-
- } else if( !selection && dialog_window ){
-
- ## delete any existing dialog window and substitute
- ## a pop-up dialog window
-
- if ( priorWindow == dialog_window ) {
- priorWindow = 0
- }
-
- current_window = dialog_window;
- prev_dialog_x0 = window_x0;
- prev_dialog_y0 = window_y0;
- prev_dialog_xExt = window_width;
- prev_dialog_yExt = window_height;
- assign_current_window( cw );
-
- delete_window( dialog_window )
-
- # allow only notify(), warning(), error() but not message()
- # to pop-up in dialog window
- message_level = 1
-
- # adjust all non_system windows
-
- if ( !next_window() || and( window_flags, WINDOW_SYSTEM ) ) {
- # only system windows are present
- return
- }
-
- w = current_window
- do {
- next_window()
- if ( window_y0 + window_height == y1 ) {
- if ( and( window_flags, WINDOW_ZOOM )){
- # lengthen window by 1 line:
- frame_window( \
- window_x0, window_y0, \
- window_width, y1 - window_y0 + 1 )
- }
- }
- } while( w != current_window )
- }
-
- if ( priorWindow ) {
- current_window = priorWindow
- }
- }
-
-
- global time_window = 0 # time_window id
- global clock_on = FALSE # current clock setting
- local TIME_LENGTH = 16 # amount of ctime() you want to see
- #local CTIME_LENGTH = 19 # length of ctime() return string
- local clock_id = 0 # function id of display_time()
- local ctime_start = 1 # first char index in ctime() string
-
- global function toggle_clock( on ){ #PUBLIC #VOID
- local old_clock = clock_on
-
- clock_on = (argcount() < 1 ) ? !clock_on : 0+on
-
- if ( clock_on != old_clock ) {
- if (clock_on) {
- time_window = create_window( \
- display_width-TIME_LENGTH, \
- display_height-1, \
- TIME_LENGTH, 1, \
- WINDOW_SYSTEM )
-
- attach_event_handler( EVENT_IDLE_TIME, \
- clock_id = function_id( "display_time" ))
- prev_idle_time = idle_time - 1;
- seconds = 60;
- displayit = 1;
- } else {
- delete_event( EVENT_IDLE_TIME, clock_id )
- delete_window( time_window )
- time_window = 0
- }
- }
- return clock_on
- }
-
- local displayit = 0;
- local prev_idle_time = 0;
- local seconds = 0;
-
- function display_time() {
- if ((idle_time != prev_idle_time) || displayit) {
- prev_idle_time = idle_time;
- if ((seconds++ > 20) || displayit) {
- displayit = 0;
- seconds = 0;
- write_window( \
- substr( ctime(), ctime_start, TIME_LENGTH ), time_window )
- display_update()
- }
- }
- }
-
- global function shrink_windows_down_1(){
- local priorWindow = current_window
- local w
-
- if ( !next_window() || and( window_flags, WINDOW_SYSTEM ) ) {
- # only system windows are present
- return
- }
-
- w = current_window
- do {
- next_window()
- if( window_y0 == 0 ){
- # shorten window by 1 line:
- frame_window( \
- window_x0, window_y0+1, \
- window_width, window_height - 1 )
- }
- } while( w != current_window )
-
- if ( priorWindow ) {
- current_window = priorWindow
- }
- }
-
- global function grow_windows_up_1(){
- local priorWindow = current_window
- local w
-
- if ( !next_window() || and( window_flags, WINDOW_SYSTEM ) ) {
- # only system windows are present
- return
- }
-
- w = current_window
- do {
- next_window()
- if( window_y0 == 1 ){
- # shorten them by 1 line:
- frame_window( \
- window_x0, 0, \
- window_width, window_height + 1 )
- }
- } while( w != current_window )
-
- if ( priorWindow ) {
- current_window = priorWindow
- }
- }
-
-
-
- local dialog_nesting = 0
- local dialog_was_off = 0
- local dialog_prev_cur
-
- # make sure there is a dialog window for a series of interactions.
-
- function begin_dialog(){
- if( dialog_nesting++ == 0 \
- && ( dialog_was_off = !dialog_window )){
- dialog_prev_cur = current_window
- popup_dialog()
- }
- }
-
- # remove the dialog window, if any, that was created by begin_dialog()
- function end_dialog(){
- if( dialog_nesting > 0 \
- && --dialog_nesting == 0 \
- && dialog_was_off ){
- assign_current_window( dialog_prev_cur )
- delete_window( dialog_window )
- }
- }
-
- # Create a dialog window in the same location and of the same
- # size as a pop-up dialog box would be.
- local function popup_dialog(){
- local screenThird = display_height / 3
- local cursor_y
-
- # attempt to avoid the current cursor position
- cursor_y = window_y0 + window_text_y0 + (current_line - window_first)
- if (cursor_y < screenThird) {
- cursor_y = screenThird * 2
- } else if (cursor_y > screenThird * 2) {
- cursor_y = screenThird
- } else {
- cursor_y = display_height * 2 / 3 + 2
- }
-
- dialog_window = create_window( \
- 2, cursor_y, \
- display_width - 4, 3, \
- WINDOW_MENU0 )
- }
-
- # toggle line numbers in the current window
-
- global nominal_linenumber_format = "%5d "
-
- function toggle_linenumbers( selection ){
-
- if( is_system_window())
- return FALSE
-
- if( argcount() < 1 )
- selection = !linenumber_format
-
- if( 0+selection )
- linenumber_format = nominal_linenumber_format
- else
- linenumber_format = ""
- }
-
- ## toggle presence/absence of borders
- #
- # Toggle_borders accepts an optional argument:
- # true => set borders to their nominal value
- # false => remove borders and titles.
- # If the argument is omitted, the borders are "toggled".
- #
- # Since there are several border styles we cannot simply toggle bits.
- # Instead, we save the border setting when it is turned off, and
- # restore the previously saved setting when toggeling it on.
- #
- # When there are multiple border styles, and current_window is changed
- # between calls to toggle_border, the effect may be to transfer border
- # styles from window to window.
- #
- # If borders are to be turned-off by default, then nominal_border_flags
- # should be set in addition to default_window_flags.
-
- global nominal_border_flags = WINDOW_STANDARD
-
- function toggle_borders( selection ){ #PUBLIC #VOID
- local border_flags = WINDOW_BORDERS + WINDOW_HEADERS
- local noborders = and( window_flags, not( border_flags ))
- local borders = and( window_flags, border_flags )
-
- if( is_system_window())
- return FALSE
-
- if( argcount() < 1 )
- selection = !borders # toggle if no arg
-
- if( 0+selection ){ # restore nominal borders
- window_flags = nominal_border_flags
-
- } else { # remove nominal borders
- nominal_border_flags = window_flags
- window_flags = noborders
- }
- }
-
- ### window resizing, positioning & scrolling
-
-
- function larger_window(){
- local wz = and( window_flags, WINDOW_ZOOM )
-
- if( is_system_window())
- return FALSE
-
- if( wz == WINDOW_COLLAPSED )
- restore_window()
- else if( wz == WINDOW_NORMAL )
- expand_window()
- }
-
- function smaller_window(){
- local wz = and( window_flags, WINDOW_ZOOM )
-
- if( is_system_window())
- return FALSE
-
- if( wz == WINDOW_EXPANDED )
- restore_window()
- else if( wz == WINDOW_NORMAL )
- collapse_window()
- }
-
- function scroll_down_1(){
- scroll_vertical( 1, scroll_or_pan())
- }
-
- function scroll_up_1(){
- scroll_vertical( -1, scroll_or_pan())
- }
-
- function scroll_down_half(){
- local h = window_height / 2
- scroll_vertical(( h <= 0 ? 1 : h ), scroll_or_pan())
- }
-
- function scroll_up_half(){
- local h = window_height / 2
- scroll_vertical( -( h <= 0 ? 1 : h ), scroll_or_pan())
- }
-
- function scroll_left_1(){
- scroll_horizontal( -1, scroll_or_pan())
- }
-
- function scroll_right_1(){
- scroll_horizontal( 1, scroll_or_pan())
- }
-
- # these functions reposition the window so that the current line is
- # in the indicated position (if possible):
-
- global function scroll_window_top( n ){ #PUBLIC #VOID
- if( n >= window_text_height )
- n = window_text_height - 1
- scroll_vertical( distance_to_window_top() - n, scroll_or_pan())
- }
-
- global function scroll_window_bottom( n ){ #PUBLIC #VOID
- if( n >= window_text_height )
- n = window_text_height - 1
- scroll_vertical( - distance_to_window_bottom() + n, scroll_or_pan())
- }
-
- global function scroll_window_middle( n ){ #PUBLIC #VOID
-
- # arguably should guard against too large values of abs(n)
-
- scroll_vertical( -distance_to_window_middle() - n, scroll_or_pan())
- }
-
- ## center_cursor
- # similar to scroll_window_middle but never changes the position in
- # the buffer (i.e. current_line or current_column). This function is
- # useful for restoring a convenient window orientation when the cursor
- # has drifted too far to the top or bottom.
- #
- global function center_cursor(){ #PUBLIC #VOID
- local save_context_top = scroll_context_top
- scroll_context_top = 0
-
- # (following removed because it was too slow)
- ## use row if specified, otherwise center the cursor vertically
- #if ( argcount() ) {
- # if ( row >= window_text_height ) {
- # row = window_text_height - 1
- # }
- #} else {
- # row = shiftr( window_text_height, 1 )
- #}
-
- scroll_vertical( current_line - window_first - shiftr( window_text_height, 1 ), 0 )
-
- scroll_context_top = save_context_top
- }
-
-
- ## scroll_or_pan -- determine to scroll or pan by
- # interrogating the scroll_means_pan status and
- # complementing it if the SCROLL_LOCK key is pressed
- #
- global function scroll_or_pan(){
- local smp = !scroll_means_pan # !! smp default should be reversed
- return xor_scroll_lock( smp )
- }
-
- ## interrogate status of scroll-lock key
-
- function scroll_lock_status(){
- return !!and( keyboard_flags, KB_SCROLL_LOCK )
- }
-
- ## xor the argument with scroll_lock_status()
-
- function xor_scroll_lock( var ){
- return xor( var, scroll_lock_status())
- }
-
- ### distances from the cursor to current_window's borders
- # these are relative to a position within the window to the given edge.
- # if the cursor happens to be outside window-borders the values may
- # be negative.
-
- function distance_to_window_top(){ #PUBLIC #INT
- return current_line - window_first
- }
-
- function distance_to_window_bottom(){ #PUBLIC #INT
- return window_first + window_text_height - current_line - 1
- }
-
- function distance_to_window_left(){ #PUBLIC #INT
- return current_column - window_margin - 1
- }
-
- function distance_to_window_right(){ #PUBLIC #INT
- return window_margin + window_text_width - current_column
- }
-
- # This function lacks symmetry with the four above. We eventually may need
- # to distinguish between horizontal, vertical and combined centering. For
- # now we only need vertical motion, and this computes the quantity, m,
- # such that current_line += m
- # and scroll_vertical( m )
- # both put the current line into the middle of the screen.
- #
- function distance_to_window_middle(){
- # message( "wf: %d, wth: %d, line=%d", \
- # window_first, \
- # window_text_height, \
- # current_line )
-
- return window_first + window_text_height / 2 - current_line
- }
-
- ### window/buffer organization
-
- ## collapse all windows but the current to an orderly array of icons
-
- function organize_windows(){ #PUBLIC #VOID
- local x = 2
- local y = 1
- local dx = 16
- local dy = 2
- local w = current_window
-
- do {
- if( !and( window_flags, WINDOW_SYSTEM )){
- collapse_window()
- move_window( x, y )
- y += dy
- if( y >= display_height - 1 ){
- y = 1
- x += dx
- }
- }
- next_window( "", 1 )
- } while( w != current_window ) # restores current_window
- }
-
- ## create an icon for each buffer not already contained in a window
- # and then organize the resulting windows. The windows and
- # icons are initially created all on top of each other.
- #
- function organize_buffers(){ #PUBLIC #VOID
- local w
- local b
- local use
-
- if ( !(w = current_window))
- return
-
- do {
- if ( !and( window_flags, WINDOW_SYSTEM ) ) {
- use[ window_name ]++
- }
- next_window( "", 1 )
- } while( w != current_window )
-
- b = current_buffer
- do {
- if ( !and( buffer_flags, BUFFER_SYSTEM ) &&
- !( buffer_name in use )) {
- attach_window_buffer( \
- create_medium_window(), \
- current_buffer )
- collapse_window()
- }
- next_buffer( "", 1 )
- } while( b != current_buffer )
-
- organize_windows()
-
- assign_current_window( w )
- current_buffer = b
- }
-
-
- ### fine-grain window positioning & resizing -- mouse alternates
- #
- # These functions support moving and resizing windows via the keypad.
- #
-
- ##
-
- local adjust_position # true if moving, false if resizing
- local adjust_keymap # keymap to use to adjust windows
-
-
- ## resize or move a window (opposite if scroll lock is on)
- #
- # xor( pos, scroll_lock_status()) => moving
- # xor( !pos, scroll_lock_status()) => resizing (default if called from keymap)
-
- function adjust_window( pos ){ #PUBLIC #VOID
- local prev_keymap = current_keymap
- local x0 = window_x0 # save current window pos/size
- local y0 = window_y0
- local w = window_width
- local h = window_height
- local tempDialog
-
- if ( is_system_window()) {
- return FALSE
- }
-
- adjust_position = !!pos
-
- if( !adjust_keymap ){
- current_keymap = adjust_keymap = create_keymap( empty_keymap )
- assign_key( "<Up>", "adjust_window_key 0 -1" )
- assign_key( "<Down>", "adjust_window_key 0 1" )
- assign_key( "<Right>", "adjust_window_key 1 0" )
- assign_key( "<Left>", "adjust_window_key -1 0" )
- assign_key( "<Enter>", "process_end 0" )
- assign_key( "<Esc>", "process_end 1" )
- } else {
- current_keymap = adjust_keymap
- }
-
- # create a temporary dialog window at the bottom of the screen
- if ( !dialog_window ) {
- dialog_window = tempDialog = create_window( \
- 0, display_height - 1, \
- display_width, 1, \
- WINDOW_SYSTEM )
- }
- notify( "Use arrow keys to adjust window, ENTER to accept, and ESC to cancel." )
- raise_window( dialog_window )
-
- # process the keymap defined above
- if( 0+process_begin() ) { # canceled...
- message( "Window adjustment canceled." )
- frame_window( x0, y0, w, h ) # restore window pos/size
- } else { # accepted...
- message( "" )
- }
-
- # remove the temporary dialog window if we created one
- if ( tempDialog ) {
- delete_window( dialog_window )
- }
-
- # restore the original keymap
- current_keymap = prev_keymap
- }
-
- function adjust_window_key( x, y ){
- if( xor_scroll_lock( adjust_position )) # move
- frame_window( window_x0 + x, \
- window_y0 + y, \
- window_width, \
- window_height )
- else # resize
- frame_window( window_x0, \
- window_y0, \
- window_width + x, \
- window_height + y )
- }
-
-
-
- ## show_visibles()
- #
- # This function displays all tabs, spaces, newline chars, etc. which
- # are accessible via visible_xxx variables.
-
- global function show_visibles() { #PUBLIC #VOID
- visible_virtual_lines = "~"
- visible_end_buffer = ""
- visible_newlines = "■"
- visible_spaces = "·"
- visible_tabs = ""
- visible_virtual_spaces = " "
- }
-
- ## reset_visibles()
- #
- # This function resets all of the "visible" representations for
- # otherwise non-printing attributes to their less visible defaults.
-
- function reset_visibles() { #PUBLIC #VOID
- visible_virtual_lines = ""
- visible_end_buffer = ""
- visible_newlines = ""
- visible_spaces = " "
- visible_tabs = " "
- visible_virtual_spaces = " "
- default_visible_virtual_lines = ""
- default_visible_end_buffer = ""
- default_visible_newlines = ""
- default_visible_spaces = " "
- default_visible_tabs = " "
- default_visible_virtual_spaces = " "
- }
-
-
- ## valid_window()
- #
- # given a window id, return TRUE if it is a valid window, otherwise FALSE
- #
- function valid_window( winid ){
- return (winid && read_window( 1, winid )) ? TRUE : FALSE;
- }
-
- ## assign_current_window()
- #
- # assign a window id to the current window iff the window id is valid
- #
- function assign_current_window( winid ){
- if (window_valid( winid ))
- current_window = winid;
- }
-
- ## toggle_window_zoom()
- #
- # toggles the WINDOW_EXPANDED bit in the window_flags. This
- # has the effect of alternately expanding and restoring the size
- # of the current window.
- #
- global function toggle_window_zoom() {
- local x = 0;
- local y = 0;
- local xExt = display_width;
- local yExt = display_height;
- local cw = current_window;
-
- if ( and(window_flags,WINDOW_EXPANDED) )
- restore_window()
- else {
- expand_window()
-
- if (help_resident) {
- x = 0;
- y = 1;
- yExt--;
- }
- if (dialog_window) {
- current_window = dialog_window;
- if (window_y0 == display_height-1)
- yExt--;
- assign_current_window( cw );
- }
- frame_window( x, y, xExt, yExt );
- }
- }
-
- global function next_window_key(){ #PUBLIC #VOID
- local cw = current_window;
- while( (next_window() != cw) &&
- (and( window_flags,WINDOW_ZOOM) == WINDOW_HIDDEN))
- continue;
- }
-
- global function prev_window_key(){ #PUBLIC #VOID
- local cw = current_window;
- while( (prev_window() != cw) &&
- (and( window_flags,WINDOW_ZOOM) == WINDOW_HIDDEN))
- continue;
- }
-
-