/*** 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 ); }
/*** Move the cursor according to mouse click ***/ void click(Project p, WORD x, WORD y, BYTE update) { WORD xp = (x-gui.left) / XSIZE, yp = (y-gui.top) / YSIZE; LINE *ln; if(!p->ccp.select) inv_curs(p, FALSE); p->nbl = p->top_line + yp; for(ln=p->show; ln->next && yp; yp--,ln=ln->next); /* There was no lines, where we've clicked */ p->nbl -= yp; p->edited = ln; p->nbrwc = p->nbrc = xp+p->left_pos; xp = curs_visible(p,p->top_line); if(xp!=p->left_pos) scroll_xy(p, xp, p->top_line, FALSE); draw_info( p ); RP->Mask = gui.selmask; /* Set starting selection point */ if( update ) { ln->flags = FIRSTSEL | LASTSEL; p->ccp.xc = p->ccp.xp = p->ccp.startsel = p->ccp.endsel = p->nbrc; p->ccp.yc = p->ccp.yp = p->nbl; p->ccp.cline = p->ccp.line = ln; } }
/*** 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 ); } }
/*** Scroll display according to right prop gadget ***/ void scroll_disp(Project p, BOOL adjust) { ULONG pos = ((struct PropInfo *)((struct Gadget*)Prop)->SpecialInfo)->VertPot * (p->max_lines - gui.nbline) / MAXPOT; if(p->max_lines>gui.nbline && pos!=p->top_line) { if(p->ccp.select) /* If selection mode is on, don't move cursor */ p->ycurs-=(pos-p->top_line)*YSIZE, scroll_xy(p, p->left_pos, pos, adjust); else /* Be sure cursor is always in the edit area */ inv_curs(p,FALSE), scroll_xy(p, curs_visible(p,pos), pos, adjust), inv_curs(p,TRUE); } }
/*** 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 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)); } }
/*** Remove part of a line ***/ void cut_line(Project p, BYTE mode) { /* Is there something to do? */ if( (mode==0 && p->nbc==0) || (mode==1 && p->nbc==p->edited->size)) return; if( rem_chars(&p->undo, p->edited, mode ? p->nbc : 0, (mode ? p->edited->size : p->nbc)-1) ) { /* Recompute cursor position */ if(mode==0) { inv_curs(p,FALSE); p->nbc=p->nbrc=p->nbrwc=0; if(p->left_pos!=0) scroll_xy(p, 0, p->top_line, FALSE); p->xcurs=gui.left; draw_info(p); } REDRAW_CURLINE(p); inv_curs(p,TRUE); } else ThrowError(Wnd, ErrMsg(ERR_NOMEM)); }
/*** 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 ); }
/*** One pos right ***/ void curs_right(Project p, BYTE word) { if(p->nbc < p->edited->size) { inv_curs(p,FALSE); if(word) p->nbc = forward_word(p->edited, p->nbc); else p->nbc++; p->nbrwc = p->nbrc = x2pos(p->edited, p->nbc); p->xcurs = (p->nbrc-p->left_pos) * XSIZE + gui.left; /* Move the cursor */ /* Is it gone outside edit area? */ if(p->nbrc>=p->left_pos+gui.nbcol) scroll_xy(p, adjust_leftpos(p, gui.xstep), p->top_line, FALSE); if(p->ccp.select) move_selection(p, p->nbrc, p->nbl); inv_curs(p,TRUE); draw_info( p ); } else if(p->edited->next) { /* jump down to next line */ p->nbrwc = 0; curs_down(p); } }
/*** Move cursor to the left ***/ void curs_left(Project p, BYTE word) { register LINE *prev; if(p->nbc != 0) { inv_curs(p,FALSE); if(word) p->nbc = backward_word(p->edited, p->nbc-1); else p->nbc--; p->nbrwc = p->nbrc = x2pos(p->edited, p->nbc); p->xcurs = (p->nbrc-p->left_pos) * XSIZE + gui.left; /* Is it gone outside edit area? */ if(p->nbrc<p->left_pos) scroll_xy(p, adjust_leftpos(p, -gui.xstep), p->top_line, FALSE); if(p->ccp.select) move_selection(p, p->nbrc, p->nbl); inv_curs(p,TRUE); draw_info( p ); } else if( ( prev = p->edited->prev ) ) { /* jump up */ p->nbrwc = x2pos(prev, prev->size); curs_up(p); } }