initial commit
This commit is contained in:
320
tools/sboot-03/src/editor.c
Normal file
320
tools/sboot-03/src/editor.c
Normal file
@@ -0,0 +1,320 @@
|
||||
|
||||
#include <tos.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "gui.h"
|
||||
#include "editor.h"
|
||||
#include "keys.h"
|
||||
|
||||
struct s_edit_buf edit_buf;
|
||||
|
||||
int edit_buf_init( struct s_edit_buf * buf )
|
||||
{
|
||||
memset( (char*)buf, 0, sizeof(struct s_edit_buf) );
|
||||
buf->blocksize = EDIT_BUF_DEFAULT_BLOCKSIZE;
|
||||
edit_buf_destroy( buf );
|
||||
buf->data = malloc( buf->blocksize );
|
||||
if( buf->data == NULL )
|
||||
return( 1 );
|
||||
buf->size = buf->blocksize;
|
||||
buf->data[0] = 0;
|
||||
buf->used = 1;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
void edit_buf_destroy( struct s_edit_buf * buf )
|
||||
{
|
||||
if( buf->data )
|
||||
free( buf->data );
|
||||
|
||||
buf->data = NULL;
|
||||
}
|
||||
|
||||
void edit_buf_alloc( struct s_edit_buf * buf, int amount )
|
||||
{
|
||||
int blocks = 1;
|
||||
|
||||
if( buf->size < (buf->used + amount)+1 ){
|
||||
if( amount > buf->blocksize)
|
||||
blocks = (amount / buf->blocksize)+1;
|
||||
buf->data = realloc( buf->data, buf->size+(buf->blocksize*blocks));
|
||||
buf->size += (buf->blocksize*blocks);
|
||||
}
|
||||
}
|
||||
|
||||
long edit_buf_find_linestart( struct s_edit_buf * buf, long curpos, long skip, long direction )
|
||||
{
|
||||
long i;
|
||||
|
||||
if( direction == 0 )
|
||||
return( -1 );
|
||||
|
||||
if( buf == NULL)
|
||||
return( -1 );
|
||||
|
||||
if( curpos > buf->used-1 )
|
||||
return( buf->used-1 );
|
||||
|
||||
if( skip > 0 ) {
|
||||
curpos = edit_buf_find_linestart( buf, curpos, 0, direction );
|
||||
skip--;
|
||||
if( curpos > 0 && skip >0 ){
|
||||
return( edit_buf_find_linestart( buf, curpos, skip, direction ) );
|
||||
}
|
||||
|
||||
return( curpos );
|
||||
}
|
||||
|
||||
curpos += direction;
|
||||
if( direction > 0 && curpos <= 0 ) {
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
for( i=curpos; i>=1; i=i+direction){
|
||||
if(buf->data[i] == 10 || buf->data[i] == 13 || buf->data[i] == 0 ){
|
||||
return( i ) ;
|
||||
}
|
||||
}
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
void edit_buf_redraw( struct s_edit_buf * buf )
|
||||
{
|
||||
char * out = " ";
|
||||
int cury = 1;
|
||||
int curx = 0;
|
||||
int curline = 1;
|
||||
int i=0;
|
||||
int len;
|
||||
long lines_limit;
|
||||
long lines_done=0;
|
||||
short inv=0;
|
||||
|
||||
len = strlen( buf->data );
|
||||
lines_limit = c_rows-2;
|
||||
|
||||
#ifndef WITHOUT_GFX
|
||||
cury = 4;
|
||||
lines_limit -= 3;
|
||||
#endif
|
||||
|
||||
if( i >= buf->redraw_start_at_char )
|
||||
fillspace(0, cury, c_cols, 0);
|
||||
for( i = 0; i<=len; i++ ) {
|
||||
if( buf->data[i] == 13 || buf->data[i] == 10 ) {
|
||||
if( i >= buf->redraw_start_at_char ){
|
||||
fillspace(curx, cury, c_cols, 0);
|
||||
if( buf->cursor == i )
|
||||
textxy( curx, cury, 1, " " );
|
||||
lines_done++;
|
||||
if( lines_done >= lines_limit )
|
||||
break;
|
||||
}
|
||||
curx = 0;
|
||||
cury++;
|
||||
if( cury > c_rows-2 )
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
if( buf->scroll_y < cury && curx < c_cols-1 )
|
||||
{
|
||||
*out = buf->data[i];
|
||||
if( *out == 0 )
|
||||
*out = ' ';
|
||||
if( i == buf->cursor )
|
||||
inv = 1;
|
||||
if( i >= buf->redraw_start_at_char ){
|
||||
textxy( curx, cury, inv, out );
|
||||
}
|
||||
if( inv == 1 )
|
||||
inv = 0;
|
||||
if( buf->data[i] == 0 ){
|
||||
break;
|
||||
}
|
||||
}
|
||||
curx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void edit_buf_insert(
|
||||
struct s_edit_buf * buf,
|
||||
unsigned char * c
|
||||
)
|
||||
{
|
||||
int i, pos;
|
||||
int len = strlen( c );
|
||||
edit_buf_alloc( buf, len );
|
||||
memmove(
|
||||
&buf->data[buf->cursor+len],
|
||||
&buf->data[buf->cursor],
|
||||
strlen(&buf->data[buf->cursor])
|
||||
);
|
||||
for( i=0; i<len; i++) {
|
||||
pos = buf->cursor+i;
|
||||
if( c[i] == 13 || c[i] == 10 ) {
|
||||
buf->lines++;
|
||||
}
|
||||
buf->data[pos] = c[i];
|
||||
buf->used++;
|
||||
}
|
||||
buf->data[buf->used-1] = 0;
|
||||
buf->redraw_start_at_char = (buf->cursor>0 ) ? buf->cursor-1 : 0;
|
||||
buf->redraw_limit_lines = -1; /* newline may cause reflow */
|
||||
buf->cursor += len;
|
||||
edit_buf_redraw( buf );
|
||||
}
|
||||
|
||||
void edit_buf_remove( struct s_edit_buf * buf )
|
||||
{
|
||||
buf->used--;
|
||||
}
|
||||
|
||||
char * edit_text( char * title, char * text )
|
||||
{
|
||||
short code, key;
|
||||
char ascii, sh;
|
||||
char exit = 0;
|
||||
int i=0, x=0, z=0;
|
||||
char ig=0;
|
||||
char tmp[3]="";
|
||||
char * result=NULL;
|
||||
long nextbest;
|
||||
long maybest;
|
||||
|
||||
draw_info("ESC=Exit without save, F2=Save");
|
||||
for( i=1; i<c_rows-1; i++ ){
|
||||
fillspace(0, i, c_cols, 0);
|
||||
}
|
||||
draw_title( title );
|
||||
|
||||
edit_buf_init( (struct s_edit_buf*)&edit_buf );
|
||||
edit_buf_insert( &edit_buf, text );
|
||||
|
||||
do{
|
||||
ig = 0;
|
||||
key = getkey(&sh, &code, &ascii);
|
||||
switch( code ){
|
||||
|
||||
case ESC:
|
||||
exit = 1;
|
||||
break;
|
||||
|
||||
case F1_BASE+1*0x100:
|
||||
/*case CTRL_S: */
|
||||
/*if( ascii == ){*/
|
||||
result = edit_buf.data;
|
||||
exit = 1;
|
||||
/*}*/
|
||||
break;
|
||||
|
||||
case BACKSPACE:
|
||||
ig = 1;
|
||||
if( edit_buf.cursor > 0 ) {
|
||||
edit_buf.cursor--;
|
||||
edit_buf.redraw_limit_lines = 2;
|
||||
edit_buf.redraw_start_at_char = edit_buf.cursor;
|
||||
edit_buf_redraw( &edit_buf );
|
||||
edit_buf.cursor++;
|
||||
memmove( &edit_buf.data[edit_buf.cursor-1],
|
||||
&edit_buf.data[edit_buf.cursor],
|
||||
strlen(&edit_buf.data[edit_buf.cursor])+1
|
||||
);
|
||||
edit_buf.cursor--;
|
||||
edit_buf.redraw_start_at_char = (edit_buf.cursor>0 ) ? edit_buf.cursor-1 : 0;
|
||||
edit_buf.redraw_limit_lines = -1;
|
||||
edit_buf.used--;
|
||||
edit_buf.data[edit_buf.used-1] = 0;
|
||||
edit_buf_redraw( &edit_buf );
|
||||
}
|
||||
break;
|
||||
|
||||
case CURS_UP:
|
||||
ig = 1;
|
||||
nextbest = edit_buf_find_linestart( &edit_buf, edit_buf.cursor, 0, -1);
|
||||
maybest = edit_buf_find_linestart( &edit_buf, nextbest-1, 0, -1);
|
||||
if( nextbest != -1 && maybest < nextbest && maybest >= 0 ) {
|
||||
if( maybest+(edit_buf.cursor-nextbest) < nextbest ){
|
||||
nextbest = maybest+(edit_buf.cursor-nextbest);
|
||||
}
|
||||
}
|
||||
if( nextbest > -1 ) {
|
||||
edit_buf.redraw_start_at_char = nextbest;
|
||||
edit_buf.redraw_limit_lines = 4;
|
||||
edit_buf.cursor = nextbest;
|
||||
edit_buf_redraw( &edit_buf );
|
||||
}
|
||||
break;
|
||||
|
||||
case CURS_DOWN:
|
||||
ig = 1;
|
||||
z = edit_buf_find_linestart( &edit_buf, edit_buf.cursor, 0, -1);
|
||||
if( z>=0 ){
|
||||
z = edit_buf.cursor-z;
|
||||
} else {
|
||||
z = 0;
|
||||
}
|
||||
nextbest = edit_buf_find_linestart( &edit_buf, edit_buf.cursor-1, 0, +1);
|
||||
if( nextbest != -1 ) {
|
||||
maybest = edit_buf_find_linestart( &edit_buf, nextbest+1, 0, +1);
|
||||
nextbest += z;
|
||||
if( nextbest > maybest ) {
|
||||
nextbest = maybest;
|
||||
}
|
||||
if( nextbest > -1 ) {
|
||||
edit_buf.redraw_start_at_char = edit_buf.cursor;
|
||||
edit_buf.redraw_limit_lines = 4;
|
||||
edit_buf.cursor = nextbest;
|
||||
edit_buf_redraw( &edit_buf );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CURS_LEFT:
|
||||
if( edit_buf.cursor > 0 ){
|
||||
edit_buf.cursor--;
|
||||
edit_buf.redraw_limit_lines = 2;
|
||||
edit_buf.redraw_start_at_char = edit_buf.cursor;
|
||||
edit_buf_redraw( &edit_buf );
|
||||
}
|
||||
ig = 1;
|
||||
break;
|
||||
|
||||
case CURS_RIGHT:
|
||||
if( edit_buf.cursor < edit_buf.used-1 ){
|
||||
edit_buf.redraw_start_at_char = edit_buf.cursor;
|
||||
edit_buf.cursor++;
|
||||
edit_buf.redraw_limit_lines = 2;
|
||||
edit_buf_redraw( &edit_buf );
|
||||
}
|
||||
ig = 1;
|
||||
break;
|
||||
|
||||
|
||||
default: break;
|
||||
}
|
||||
if( ig == 1 || exit == 1 )
|
||||
continue;
|
||||
|
||||
if( (char)key == 0 )
|
||||
continue;
|
||||
if( key == 13 )
|
||||
key = 10;
|
||||
*tmp = (char)key;
|
||||
edit_buf_insert( &edit_buf, tmp );
|
||||
|
||||
} while( exit != 1 );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
void end_edit_text( )
|
||||
{
|
||||
edit_buf_destroy( &edit_buf );
|
||||
}
|
||||
Reference in New Issue
Block a user