1 /***********************************************************************/
2 /* SCROLL.C - SCROLL commands                                          */
3 /* This file contains all commands that can be assigned to function    */
4 /* keys or typed on the command line.                                  */
5 /***********************************************************************/
6 /*
7  * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
8  * Copyright (C) 1991-2013 Mark Hessling
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of
13  * the License, or any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to:
22  *
23  *    The Free Software Foundation, Inc.
24  *    675 Mass Ave,
25  *    Cambridge, MA 02139 USA.
26  *
27  *
28  * If you make modifications to this software that you feel increases
29  * it usefulness for the rest of the community, please email the
30  * changes, enhancements, bug fixes as well as any and all ideas to me.
31  * This software is going to be maintained and enhanced as deemed
32  * necessary by the community.
33  *
34  * Mark Hessling, mark@rexx.org  http://www.rexx.org/
35  */
36 
37 
38 #include <the.h>
39 #include <proto.h>
40 
41 /***********************************************************************/
42 #ifdef HAVE_PROTO
scroll_page(short direction,LINETYPE num_pages,bool scrollbar)43 short scroll_page(short direction,LINETYPE num_pages,bool scrollbar)
44 #else
45 short scroll_page(direction,num_pages,scrollbar)
46 short direction;
47 LINETYPE num_pages;
48 bool scrollbar;
49 #endif
50 /***********************************************************************/
51 {
52    short y=0,x=0,save_y=0,rc;
53    bool save_scroll_cursor_stay=scroll_cursor_stay;
54 
55    TRACE_FUNCTION("scroll.c:  scroll_page");
56    /*
57     * If scrolling backward and already on TOF, return.
58     * If scrolling forward and already on EOF, return.
59     */
60    if ((direction == DIRECTION_BACKWARD
61       && CURRENT_TOF)
62    ||  (direction == DIRECTION_FORWARD
63       && CURRENT_BOF))
64    {
65       TRACE_RETURN();
66       return(RC_TOF_EOF_REACHED);
67    }
68    /*
69     * If scrolling via the scroll bars, ALWAYS leave the cursor on the
70     * screen line.
71     */
72    if (scrollbar)
73       save_scroll_cursor_stay = TRUE;
74    /*
75     * Get current focus row if cursor is to stay on current focus line...
76     */
77    if (save_scroll_cursor_stay)
78       save_y = get_row_for_focus_line(current_screen,CURRENT_VIEW->focus_line,CURRENT_VIEW->current_row);
79    /*
80     * Find the new current line, num_pages away...
81     */
82    post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
83    CURRENT_VIEW->current_line = find_next_current_line(num_pages,direction);
84    build_screen(current_screen);
85    if (save_scroll_cursor_stay)
86    {
87       save_y = get_row_for_tof_eof(save_y,current_screen);
88       CURRENT_VIEW->focus_line = CURRENT_SCREEN.sl[save_y].line_number;
89       pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
90       build_screen(current_screen);
91    }
92    else
93    {
94       CURRENT_VIEW->focus_line = calculate_focus_line(CURRENT_VIEW->focus_line, CURRENT_VIEW->current_line);
95       pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
96    }
97    /*
98     * If curses has started, display screen and sort out cursor position..
99     */
100    if (curses_started)
101    {
102       getyx(CURRENT_WINDOW,y,x);
103       display_screen(current_screen);
104       if (CURRENT_VIEW->current_window != WINDOW_COMMAND)
105       {
106          y = get_row_for_focus_line(current_screen,CURRENT_VIEW->focus_line, CURRENT_VIEW->current_row);
107          wmove(CURRENT_WINDOW,y,x);
108          if (scrollbar)
109             wrefresh(CURRENT_WINDOW);
110       }
111    }
112    if (CURRENT_TOF || CURRENT_BOF)
113       rc = RC_TOF_EOF_REACHED;
114    else
115       rc = RC_OK;
116    TRACE_RETURN();
117    return rc;
118 }
119 /***********************************************************************/
120 #ifdef HAVE_PROTO
scroll_line(CHARTYPE curr_screen,VIEW_DETAILS * curr_view,short direction,LINETYPE num_lines,bool scrollbar,short escreen)121 short scroll_line( CHARTYPE curr_screen, VIEW_DETAILS *curr_view, short direction,LINETYPE num_lines,bool scrollbar,short escreen)
122 #else
123 short scroll_line( curr_screen, curr_view, direction, num_lines, scrollbar, escreen )
124 CHARTYPE curr_screen;
125 VIEW_DETAILS *curr_view;
126 short direction;
127 LINETYPE num_lines;
128 bool scrollbar;
129 short escreen;
130 #endif
131 /***********************************************************************/
132 {
133    short rc=RC_OK;
134    unsigned short x=0,y=0,iscrollbar=scrollbar;
135    bool on_file_edge=FALSE,on_screen_edge=FALSE;
136    short number_focus_rows=0;
137    bool leave_cursor=FALSE;
138    LINETYPE new_focus_line=0L,new_current_line=0L,edge_line=0L;
139    LINETYPE longy=0L,longx=0L;
140    ROWTYPE yoff1=0,yoff2=0;
141    chtype color_filearea = set_colour( curr_view->file_for_view->attr+ATTR_FILEAREA );
142    chtype color_cursorline = set_colour( curr_view->file_for_view->attr+ATTR_CURSORLINE );
143 
144    TRACE_FUNCTION("scroll.c:  scroll_line");
145    /*
146     * If this function is called via scrollbar...
147     * If scrolling backward and already on TOF, return.
148     * If scrolling forward and already on EOF, return.
149     */
150    if ( scrollbar )
151    {
152       if ( ( direction == DIRECTION_BACKWARD && CURRENT_TOF )
153       ||   ( direction == DIRECTION_FORWARD && CURRENT_BOF ) )
154       {
155          TRACE_RETURN();
156          return(RC_TOF_EOF_REACHED);
157       }
158    }
159    calculate_scroll_values( curr_screen, curr_view, &number_focus_rows, &new_focus_line, &new_current_line, &on_screen_edge,&on_file_edge, &leave_cursor,direction );
160    switch( iscrollbar )
161    {
162       case FALSE:
163          getyx( SCREEN_WINDOW(curr_screen), y, x );
164          if ( direction == DIRECTION_FORWARD )
165          {
166             edge_line = curr_view->file_for_view->number_lines+1L;
167             yoff1 = y - ((leave_cursor) ? 0 : 1);
168             yoff2 = y + number_focus_rows;
169          }
170          else
171          {
172             edge_line = 0L;
173             yoff1 = y + ((leave_cursor) ? 0 : 1);
174             yoff2 = y - number_focus_rows;
175          }
176          /*
177           * If the cursor is on the edge of the window or on the edge of the
178           * file and tabbing to the command line is set, tab to the command line
179           * provided the command line is ON.
180           */
181          if ( escreen == CURSOR_SCREEN
182          &&  ( on_screen_edge || on_file_edge ) )
183          {
184             if ( SCREEN_WINDOW_COMMAND(curr_screen) == NULL )
185             {
186                getyx( SCREEN_WINDOW(curr_screen), y, x );
187                if ( direction == DIRECTION_FORWARD )
188                   rc = find_first_focus_line( curr_screen, &y );
189                else
190                   rc = find_last_focus_line( curr_screen, &y );
191                if (rc == RC_OK)
192                {
193                   curr_view->focus_line = screen[curr_screen].sl[y].line_number;
194                   pre_process_line( curr_view, curr_view->focus_line, (LINE *)NULL );
195                   wmove(SCREEN_WINDOW( curr_screen), y, x );
196                }
197                break;
198             }
199             THEcursor_cmdline( curr_screen, curr_view, 1 );
200             break;
201          }
202          /*
203           * If the cursor is on the edge of the file...
204           */
205          if ( on_file_edge )
206          {
207             /*
208              * ... and the current row is the edge of the file, stay there.
209              */
210             if ( curr_view->current_line == edge_line )
211                break;
212             /*
213              * ... and the edge of the file is above or below the current row,
214              * scroll the window.
215              */
216             curr_view->current_line = new_current_line;
217             build_screen( curr_screen );
218             display_screen( curr_screen );
219             y = get_row_for_focus_line( curr_screen, curr_view->focus_line, curr_view->current_row );
220             wmove( SCREEN_WINDOW( curr_screen), y, x );
221             break;
222          }
223          /*
224           * If on the edge of the window, scroll the window.
225           */
226          if ( on_screen_edge )
227          {
228             curr_view->current_line = new_current_line;
229             post_process_line( curr_view, curr_view->focus_line, (LINE *)NULL, TRUE );
230             curr_view->focus_line = new_focus_line;
231             pre_process_line( curr_view, curr_view->focus_line, (LINE *)NULL );
232             build_screen( curr_screen );
233             display_screen( curr_screen );
234             wmove( SCREEN_WINDOW(curr_screen), yoff1, x );
235             break;
236          }
237          /*
238           * We are in the middle of the window, so just move the cursor up or
239           * down 1 line.
240           */
241          wmove( SCREEN_WINDOW(curr_screen), yoff2, x );
242          rc = post_process_line( curr_view, curr_view->focus_line, (LINE *)NULL, TRUE );
243          curr_view->focus_line = new_focus_line;
244          pre_process_line( curr_view, curr_view->focus_line, (LINE *)NULL );
245          build_screen( curr_screen );
246          if ( ( curr_view->highlight
247          &&  rc != RC_NO_LINES_CHANGED )
248             || ( color_filearea != color_cursorline ) )
249          {
250             display_screen( curr_screen );
251          }
252          break;
253     case TRUE:
254          if (curr_view->current_window != WINDOW_COMMAND)
255             get_cursor_position( &longy, &longx, &new_focus_line, &new_current_line );
256          rc = advance_current_line( (direction == DIRECTION_FORWARD) ? num_lines : -num_lines );
257          if ( curr_view->current_window != WINDOW_COMMAND )
258          {
259             THEcursor_move( curr_screen, curr_view, TRUE, TRUE, (short)longy, (short)longx );
260             show_heading( curr_screen );
261             if ( curr_view->id_line )
262                wnoutrefresh( SCREEN_WINDOW_IDLINE(curr_screen) );
263             wrefresh( SCREEN_WINDOW(curr_screen) );
264          }
265          break;
266    }
267    if ( VIEW_FOCUS_TOF(curr_view) || VIEW_FOCUS_BOF(curr_view) )
268       rc = RC_TOF_EOF_REACHED;
269    else
270       rc = RC_OK;
271    TRACE_RETURN();
272    return rc;
273 }
274