/*** Move cursor to absolute position ***/ void move_to_line(Project p, ULONG nbline, char dirtiness) { ULONG newtop; if(!p->ccp.select) inv_curs(p,FALSE); /* Get the new top line */ { register ULONG old_nbl = p->nbl; p->nbl = nbline; newtop = center_vert(p); p->nbl = old_nbl; } set_cursor_line(p, nbline, newtop); if(dirtiness == LINE_AS_IS) scroll_xy(p, center_horiz(p), newtop, TRUE); else { /* Some lines are modified: redraw in one pass */ if( newtop == p->top_line ) { REDRAW_CURLINE(p); if( dirtiness == LINES_DIRTY ) scroll_up(p, p->edited->next, p->ycurs, center_horiz(p)), prop_adj(p); else if( p->left_pos != (newtop = center_horiz(p)) ) scroll_xy(p, newtop, p->top_line, FALSE); } else if( dirtiness == LINE_DIRTY ) scroll_xy(p, center_horiz(p), newtop, TRUE); else set_top_line(p, newtop, center_horiz(p)); } /* Move cursor or selection */ if(p->ccp.select) move_selection(p, p->nbrwc, p->nbl); inv_curs(p,TRUE); draw_info( p ); }
/*** Join two lines and strip spaces on the next ***/ void join_strip( Project p ) { LINE *ln; if((ln = p->edited->next) != NULL) { STRPTR data; ULONG i; inv_curs(p, FALSE); p->nbc = p->edited->size; for(i=0, data=ln->stream; TypeChar[*data] == SPACE && i<ln->size; i++, data++); reg_group_by(&p->undo); if(i != ln->size) { /* Do not add a blank if there is already one */ if( p->nbc > 0 && TypeChar[ p->edited->stream[ p->nbc-1 ] ] != SPACE ) add_char(&p->undo, p->edited, p->nbc, ' '); if( insert_str(&p->undo, p->edited, p->edited->size, data, ln->size-i) == 0 ) ThrowError(Wnd, ErrMsg(ERR_NOMEM)); } /* ln can't be the first */ del_line(&p->undo, NULL, ln); p->max_lines--; reg_group_by(&p->undo); prop_adj(p); /* Refresh screen */ p->nbrc = p->nbrwc = x2pos(p->edited, p->nbc); REDRAW_CURLINE( p ); draw_info( p ); scroll_up(p, p->edited->next, p->ycurs, center_horiz(p)); inv_curs(p,TRUE); } }
/*** Move cursor down/up one page ***/ void pg_updown(Project p, BYTE dir) { LONG newtop = p->top_line, newcrs; if(dir>0) /* One page down */ if(newtop+gui.nbline >= p->max_lines) newcrs = p->max_lines-1; else { newtop += gui.nbline; if(newtop+gui.nbline >= p->max_lines) newtop = p->max_lines - gui.nbline; newcrs = newtop - p->top_line + p->nbl; } else /* One page up */ if(newtop == 0) newcrs=0; else { newtop -= gui.nbline; if(newtop<0) newtop=0; newcrs = newtop - p->top_line + p->nbl; } if(newcrs != p->nbl) inv_curs(p,FALSE),set_cursor_line(p,newcrs,newtop); scroll_xy(p,center_horiz(p),newtop,TRUE); if(p->ccp.select) move_selection(p, p->nbrc, p->nbl); inv_curs(p,TRUE); draw_info( p ); }
/*** Jump the cursor far left or far right ***/ void jump_horiz(Project p, BYTE dir) { if( dir >= 0 ) { /* If cursor is already at rightmost position, scroll display */ if( p->nbrwc == p->left_pos+gui.nbcol-1 ) { p->nbrwc += gui.nbcol-1; } else p->nbrwc = p->left_pos+gui.nbcol-1; } else { /* Check if cursor is already at leftmost position */ if( p->nbrwc == p->left_pos ) { p->nbrwc = p->left_pos - (gui.nbcol-1); if( (LONG)p->nbrwc < 0 ) p->nbrwc = 0; } else p->nbrwc = p->left_pos; } inv_curs(p,FALSE); p->nbrc = adjust_rc(p->edited, p->nbrwc, &p->nbc, dir<0); p->xcurs = (p->nbrc-p->left_pos)*XSIZE + gui.left; { LONG newleft = center_horiz( p ); if( newleft != p->left_pos ) scroll_xy(p, newleft, p->top_line, 0); } /* Move selection or cursor? */ if(p->ccp.select) move_selection(p, p->nbrwc, p->nbl); inv_curs(p,TRUE); draw_info( p ); }
/*** Move cursor down ***/ void curs_down(Project p) { LINE *ln; if( ( ln = p->edited->next) ) { LONG newx; BYTE scroll=0; inv_curs(p, FALSE); /* Is the cursor at the bottom of the display? */ if( p->ycurs < gui.botcurs) p->ycurs += YSIZE; else scroll=1; p->nbl++; p->edited=ln; p->nbrc = adjust_rc(ln, p->nbrwc, &p->nbc, FALSE); p->xcurs = (p->nbrc-p->left_pos)*XSIZE + gui.left; /* Minimise calls to scroll_xy */ if((newx=center_horiz(p))!=p->left_pos || scroll) scroll_xy(p, newx, p->top_line+scroll, scroll); /* Update selection */ if(p->ccp.select) move_selection(p, p->nbrc, p->nbl); inv_curs(p, TRUE); draw_info( p ); } }
/*** Move cursor up ***/ void curs_up(Project p) { LINE *ln; if( ( ln = p->edited->prev) ) { LONG newx; BYTE scroll=0; inv_curs(p, FALSE); /* Is the cursor on top of display? */ if(p->ycurs > gui.topcurs) p->ycurs -= YSIZE; else scroll=1; p->nbl--; p->edited=ln; p->nbrc = adjust_rc(ln, p->nbrwc, &p->nbc, FALSE); p->xcurs = (p->nbrc-p->left_pos)*XSIZE + gui.left; /* If cursor exits edit area due to horizontal ** ** adjustment, scroll the display accordingly: */ if((newx=center_horiz(p))!=p->left_pos || scroll) scroll_xy(p, newx, p->top_line-scroll, scroll); /* Update selection */ if(p->ccp.select) move_selection(p, p->nbrc, p->nbl); inv_curs(p, TRUE); draw_info( p ); } }
/*** Remove the char before the cursor ***/ void back_space(Project p, BYTE word) { if(p->nbc!=0) { ULONG nbc = word ? backward_word(p->edited,p->nbc-1) : p->nbc-1; rem_chars(&p->undo, p->edited, nbc, p->nbc-1); /* Set cursor position and redraws it */ inv_curs(p,FALSE); REDRAW_CURLINE(p); p->nbrwc = p->nbrc = x2pos(p->edited, p->nbc=nbc); p->xcurs = (p->nbrc-p->left_pos)*XSIZE + gui.left; if( (nbc = center_horiz(p)) != p->left_pos ) scroll_xy(p, nbc, p->top_line, FALSE); inv_curs(p,TRUE); draw_info( p ); } else if(p->edited->prev != NULL) { p->edited = p->edited->prev; p->nbc = p->edited->size; /* Join previous and current line */ if( join_lines(&p->undo, p->edited, p->edited->next) ) { /* Move cursor to the end of previous line */ p->nbrwc = p->nbrc = x2pos(p->edited, p->nbc); p->max_lines--; p->nbl--; /* Require to scroll the display? */ inv_curs(p, FALSE); if(p->ycurs>gui.topcurs) scroll_up(p, p->edited->next, p->ycurs-=YSIZE, center_horiz(p)); else p->top_line--, p->show = p->edited, p->xcurs = (p->nbrc-p->left_pos)*XSIZE + gui.left; SetAPen(RP, pen.fg); REDRAW_CURLINE(p); /* Redraw the cursor: */ inv_curs(p,TRUE); draw_info(p); prop_adj(p); } else ThrowError(Wnd, ErrMsg(ERR_NOMEM)); } }
/*** Jump cursor to an absolute position in line (ie: beginning or end) ***/ void horiz_pos( Project p, ULONG newpos ) { if( newpos != p->nbrwc ) { inv_curs(p, FALSE); p->nbrc = adjust_rc(p->edited, p->nbrwc = newpos, &p->nbc, FALSE); scroll_xy(p, center_horiz(p), p->top_line, FALSE); p->xcurs = (p->nbrc-p->left_pos)*XSIZE + gui.left; if(p->ccp.select) move_selection(p, p->nbrwc, p->nbl); inv_curs(p, TRUE); draw_info( p ); } }
/*** Remove an entire line ***/ void amiga_k(Project p) { LINE *del = p->edited; if(p->ccp.select) return; /* In there a next line, move cursor to */ if( del->next ) { p->edited=del->next; p->max_lines--; if(p->show==del) p->show=del->next; prop_adj(p); } /* Adjust cursor position */ inv_curs(p,FALSE); del_line(&p->undo, &p->the_line, del); p->nbrc = adjust_rc(p->edited, p->nbrwc, &p->nbc, FALSE); REDRAW_CURLINE(p); scroll_up(p, p->edited->next, p->ycurs, center_horiz(p)); inv_curs(p,TRUE); }
/*** Be sure that cursor is always visible ***/ LONG curs_visible(Project p, LONG newtop) { if(p->nbl < newtop) { /* The cursor is above the top line */ p->ycurs = gui.topcurs; p->nbl = newtop; goto adj_edited; } else if(p->nbl >= newtop+gui.nbline) { register LONG nb; register LINE *ln; /* The cursor is below the bottom line */ p->nbl = newtop+gui.nbline-1; p->ycurs = gui.botcurs; adj_edited: for(ln=p->the_line, nb=p->nbl; nb--; ln=ln->next); if(ln) p->edited=ln; draw_info(p); } else /* Is between the top and bottom line */ p->ycurs = (p->nbl-newtop) * YSIZE+ gui.topcurs; /* Jump too far to the right? */ newtop=p->left_pos + gui.nbcol - 1; if(p->nbrc>newtop) p->nbrwc=newtop; /* Too far on the left */ if((newtop = p->nbrc<p->left_pos)) p->nbrwc=p->left_pos; /* Adjust cursor pos */ newtop = adjust_rc(p->edited, p->nbrwc, &p->nbc, newtop); if(p->nbrc != newtop) p->nbrc = newtop, draw_info(p); p->xcurs = (p->nbrc-p->left_pos)*XSIZE + gui.left; return center_horiz(p); }
/*** Jump the cursor at bottom or top of display ***/ void jump_vert(Project p, BYTE dir) { LONG newline, newtop=p->top_line; if( dir>=0 ) { /* Move cursor to bottom of display or scroll one page if it's already here */ newline=newtop+gui.nbline-1; if( p->nbl==newline ) newline+=gui.nbline, newtop+=gui.nbline; /* Want to jump after the last line? */ if(newline>=p->max_lines) { newline=p->max_lines-1; newtop=(p->top_line + gui.nbline > p->max_lines ? p->top_line : newline-gui.nbline+1); if(newtop<0) newtop=0; } } else { /* Same fight with reverse direction */ newline=newtop; if( p->nbl==newline ) { newtop-=gui.nbline; if(newtop<0) newtop=0; newline=newtop; } } /* Adjust display according to cursor position */ if(newline != p->nbl) { inv_curs(p,FALSE); set_cursor_line(p, newline, newtop); /* Set the selection flags before to scroll display */ if(p->ccp.select) move_selection(p, p->nbrwc, p->nbl); scroll_xy(p,center_horiz(p), newtop, TRUE); inv_curs(p,TRUE); draw_info( p ); } }
/*** Move cursor incrementally (paste) ***/ void move_cursor(Project p, LONG dx, LONG dy) { LINE *ln; LONG nb=dy; inv_curs(p, FALSE); if(nb < 0) for(ln=p->edited; nb++; ln=ln->prev); else for(ln=p->edited; nb--; ln=ln->next); p->edited = ln; p->nbl += dy; p->nbrwc = p->nbrc = x2pos(ln,p->nbc = dx); dx = center_horiz(p); /* Don't scroll if top_line changed! (whole redraw instead) */ if(dx != p->left_pos && dy == 0) scroll_xy(p, dx, p->top_line, TRUE); else { nb = center_vert(p) - p->top_line; for(p->top_line += nb,ln=p->show; nb--; ln=ln->next); p->show = ln; p->left_pos = dx; } p->ycurs = (p->nbl-p->top_line)*YSIZE + gui.topcurs; p->xcurs = (p->nbrc-p->left_pos)*XSIZE + gui.left; draw_info( p ); }