EasyInput/EasyInput.c

272 lines
6.6 KiB
C

#include "EasyInput.h"
char *EI_input_string(int string_length, const char *chars_allowed)
{
char *string = (void*)(0);
EI_config *config = (void*)(0);
EI_cursor_settings cursor_settings;
unsigned int key = 0;
int i;
int char_deleted = 0;
int text_displacement = 0;
int cap = 0;
char arrow[] = {0xE6, 0x9A, 0};
// Get actual configuration
config = (EI_config*)EI_manage_config(EI_GET_ALL, 0);
// Allocate RAM for string
string = (char*)malloc(sizeof(char) * string_length + 1);
// Initialize string
for(i = 0; i <= string_length; i++) string[i] = 0;
// Setup cursor flash
switch(config->align)
{
default:
case EI_ALIGN_LEFT:
EI_Cursor_SetPosition(config->column, config->row);
break;
case EI_ALIGN_CENTER:
EI_Cursor_SetPosition(config->column + (config->box_length >> 1), config->row);
break;
case EI_ALIGN_RIGHT:
EI_Cursor_SetPosition(config->column + config->box_length - 1, config->row);
break;
}
if(config->start_mode == EI_ALPHA_LOCKED)
{
EI_KBD_PutKey(KEY_CTRL_SHIFT, 0);
GetKey(&key);
}
if(config->start_mode >= EI_ALPHA)
{
EI_KBD_PutKey(KEY_CTRL_ALPHA, 0);
GetKey(&key);
EI_Cursor_SetFlashOn(3);
}
else
{
EI_Cursor_SetFlashOn(0);
}
// Main loop
i = 0;
while(key != KEY_CTRL_EXE && key != KEY_CTRL_AC)
{
EI_Cursor_GetSettings(&cursor_settings);
if(cursor_settings.flashstyle == 3 && !cap)
EI_Cursor_SetFlashOn(4);
GetKey(&key); // Getting key pressed
switch(key) // Analyse key pressed
{
case KEY_CTRL_F1:
cap = !cap;
break;
case KEY_CTRL_DEL:
if(i > 0)
{
i--;
string[i] = 0;
char_deleted = 1;
}
break;
default:
// Give correct value to keys with a non-ascii return values
if(key == KEY_CHAR_PLUS) key = '+';
if(key == KEY_CHAR_MINUS || key == KEY_CHAR_PMINUS) key = '-';
if(key == KEY_CHAR_MULT) key = '*';
if(key == KEY_CHAR_DIV) key = '/';
if(key == KEY_CHAR_ANS) key = '_';
if(key == KEY_CTRL_XTT) key = '#';
if(key > 127) // KEY_CTRL_***, etc.
break;
if(key >= 'A' && key <= 'Z') key += !cap * 32; // Switch between caps
if(EI_check_char(key, chars_allowed) && EI_str_length(string) != string_length) // Add char if we can
{
string[i] = key;
i++;
}
}
switch(config->align) // Print string
{
default:
case EI_ALIGN_LEFT:
if(EI_str_length(string) < config->box_length)
{
EI_Cursor_SetPosition(config->column, config->row);
Print((unsigned char*)string);
if(char_deleted && EI_str_length(string) != config->box_length - 1)
{
Print((unsigned char*)" ");
EI_Cursor_SetPosition(cursor_settings.column - 2, config->row);
char_deleted = 0;
}
}
else
{
EI_Cursor_SetPosition(config->column, config->row);
Print((unsigned char*)arrow);
Print((unsigned char*)(string + EI_str_length(string) - config->box_length + 2));
}
break;
case EI_ALIGN_CENTER:
if(EI_str_length(string) < config->box_length)
{
if(char_deleted && EI_str_length(string) != config->box_length - 1 && (config->box_length - EI_str_length(string)) >> 1 != ((config->box_length - EI_str_length(string) - 1) >> 1))
{
EI_Cursor_SetPosition(config->column + ((config->box_length - EI_str_length(string)) >> 1) - 1, config->row);
Print((unsigned char*)" ");
Print((unsigned char*)string);
char_deleted = 0;
}
else if(char_deleted && EI_str_length(string) != config->box_length - 1 && (config->box_length - EI_str_length(string)) >> 1 == ((config->box_length - EI_str_length(string) - 1) >> 1))
{
EI_Cursor_SetPosition(config->column + ((config->box_length - EI_str_length(string)) >> 1), config->row);
Print((unsigned char*)string);
Print((unsigned char*)" ");
EI_Cursor_SetPosition(cursor_settings.column - 2, config->row);
char_deleted = 0;
}
else
{
EI_Cursor_SetPosition(config->column + ((config->box_length - EI_str_length(string)) >> 1), config->row);
Print((unsigned char*)string);
}
}
else
{
EI_Cursor_SetPosition(config->column, config->row);
Print((unsigned char*)arrow);
Print((unsigned char*)(string + EI_str_length(string) - config->box_length + 2));
}
break;
case EI_ALIGN_RIGHT:
if(EI_str_length(string) < config->box_length)
{
EI_Cursor_SetPosition(config->column + config->box_length - EI_str_length(string) - (char_deleted && EI_str_length(string) != config->box_length - 1) - 1, config->row);
if(char_deleted && EI_str_length(string) != config->box_length - 1)
{
Print((unsigned char*)" ");
char_deleted = 0;
}
Print((unsigned char*)string);
}
else
{
EI_Cursor_SetPosition(config->column, config->row);
Print((unsigned char*)arrow);
Print((unsigned char*)(string + EI_str_length(string) - config->box_length + 2));
}
break;
}
}
// Set off cursor mode
EI_Cursor_SetFlashOff();
// Return NULL in case of an input break
if(key == KEY_CTRL_AC)
{
free(string);
return (char*)(0);
}
// Return the string
return string;
}
const void *EI_manage_config(int parameter, int value)
{
static EI_config config;
if(value)
{
switch(parameter)
{
case EI_SET_COLUMN: config.column = value - 1;
break;
case EI_SET_ROW: config.row = value - 1;
break;
case EI_SET_BOX_LENGTH: config.box_length = (value < 3 ? 3 : value); // Minimal size is 3
break;
case EI_SET_ALIGN: config.align = value;
break;
case EI_SET_START_MODE: config.start_mode = value;
break;
case EI_SET_Aa_KEY: config.Aa_key = value;
break;
}
}
else
{
switch(parameter)
{
case EI_GET_ALL: return (const void*)(&config);
case EI_SET_COLUMN: return (const void*)&config.column;
case EI_SET_ROW: return (const void*)&config.row;
case EI_SET_BOX_LENGTH: return (const void*)&config.box_length;
case EI_SET_ALIGN: return (const void*)&config.align;
case EI_SET_START_MODE: return (const void*)&config.start_mode;
case EI_SET_Aa_KEY: return (const void*)&config.Aa_key;
}
}
return (void*)(0);
}
void EI_init(void)
{
EI_manage_config(EI_SET_COLUMN, 1);
EI_manage_config(EI_SET_ROW, 1);
EI_manage_config(EI_SET_ALIGN, EI_ALIGN_LEFT);
EI_manage_config(EI_SET_START_MODE, EI_ALPHA_LOCKED);
EI_manage_config(EI_SET_BOX_LENGTH, 21);
EI_manage_config(EI_SET_Aa_KEY, KEY_CTRL_F1);
}
int EI_str_length(const char *str)
{
int i = 0;
while(str[i]) i++;
return i;
}
int EI_check_char(char c, const char *chars_allowed)
{
int i = 0;
while(chars_allowed[i])
{
if(c == chars_allowed[i])
return 1;
i++;
}
return 0;
}