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