Показать сообщение отдельно
Старый 20.02.2011, 03:24   #1
YellowAfterlife
ПроЭктировщик
 
Аватар для YellowAfterlife
 
Регистрация: 19.02.2011
Сообщений: 134
Написано 81 полезных сообщений
(для 219 пользователей)
cInput, система для ввода текста в режиме Canvas

Это простая система позволяет реализовывать поля ввода текста во время графического режима. То есть вам не понадобится использовать не-очень-игровую стандартную форму ввода, или мучатся над ограничением набора вводимых символов.
В примере система работает аналогично стандартному вводу на телефонах Nokia, c единственной разницей в использовании * для стирания текста.

Кроме непосредственного ввода с выбором нужной буквы в зависимости от клавиши, поддерживается смена языков (как и редактирование набора букв для языка), и есть определенная оптимизация (включая определение надобности перерисовки экрана).

Система + пример реализации:
Скриншот:

Код (тег OFFTOP потому что spoilerа не вижу :\):
program cInput;
// Код системы
var // переменные системы:
    
en: array[0..11] of string; // англ. расскладка
    
enx: array[0..11] of string; // англ. расскладка (заглавные)
    
ru: array[0..11] of string; // русс. расскладка
    
rux: array[0..11] of string; // русс. расскладка (заглавные)
    
lanname: array[0..3] of string;
    
lan: integer; // текущий язык
    
lanc: integer; // количество языков
    
ke_input: string; // текущий ввод
    
ke_current: integer; // текущая кнопка
    
ke_select: integer; // буква под цифрой
    
ke_time: integer; // время ввода
    
ke_timex: integer; // макс. время ввода
// Функции системы:
{ iostart() - инициализация переменных системы
    Эту функцию нужно запустить до первого использования
    большинства других функций системы
, иначе может
    произойти что
-то ужасное.
} 
procedure iostart; begin
    lanc 
:= 0;
    
// Английский
    
en[0] := ' 0'; enx[0] := en[0];
    
en[1] := '.,?!' + chr(39) + '"1'; enx[1] := en[1];
    
en[2] := 'abc2'; enx[2] := 'ABC2';
    
en[3] := 'def3'; enx[3] := 'DEF3';
    
en[4] := 'ghi4'; enx[4] := 'GHI4';
    
en[5] := 'jkl5'; enx[5] := 'JKL5';
    
en[6] := 'mno6'; enx[6] := 'MNO6';
    
en[7] := 'pqrs7'; enx[7] := 'PQRS7';
    
en[8] := 'tuv8'; enx[8] := 'TUV8';
    
en[9] := 'wxyz9'; enx[9] := 'WXYZ9';
    
lanname[0] := 'en'; lanname[1] := 'EN'; lanc := lanc + 2;
    {
// Русский. Может не работать, поэтому закоментирован.
    
ru[0] := en[0]; rux[0] := ru[0];
    
ru[1] := en[1]; rux[1] := ru[1];
    
ru[2] := 'абвг2'; rux[2] := 'АБВГ2';
    
ru[3] := 'дежз3'; rux[3] := 'ДЕЖЗ3';
    
ru[4] := 'ийкл4'; rux[4] := 'ИЙКЛ4';
    
ru[5] := 'мноп5'; rux[5] := 'МНОП5';
    
ru[6] := 'РСТУ6'; rux[6] := 'РСТУ6';
    
ru[7] := 'фхцч7'; rux[7] := 'ФХЦЧ7';
    
ru[8] := 'шщъы8'; rux[8] := 'ШЩЪЫ8';
    
ru[9] := 'ьэюя9'; rux[9] := 'ЬЭЮЯ9';
    
lanname[2] := 'ru'; lanname[3] := 'RU'; lanc := lanc + 2;}
    
// Инициализация переменных:
    
lan := 0;
    
ke_timex := 10;
    
ke_input := '';
    
ke_current := -1;
    
ke_time := 0;
end;
{ 
keytoint(кнопка):индекс - преобразование индекса кнопки в число
    Преобразовует код кнопки 
(константу) в легко отличаемое число
    Возращает 0..9 для цифр
, 10 для *, 11 для #, -1 для прочего
}function keytoint(key: integer):integer; begin
    
if (key >= ke_key0) and (key <= ke_key9) then keytoint := key - ke_key0
    
else if (key = ke_star) then keytoint := 10;
    else if (
key = ke_pound) then keytoint := 11;
    else 
keytoint := -1;
end;
{ 
lanstr(индекс) - возращает строку для кнопки из текущего языка (lan)
    
индекс - индекс кнопки (полученный из keytoint)
}function 
lanstr(key:integer):string; begin
    
if key >= 0 then begin
        
if lan = 0 then lanstr := en[key]
        else if 
lan = 1 then lanstr := enx[key]
        else 
lanstr := '';
    
end else lanstr := '';
end;
{ 
lanlen(индекс) - возращает длину строки кнопки из текущего языка
    индекс 
- индекс кнопки (полученный из keytoint)
}function 
lanlen(key:integer):integer; begin
    lanlen 
:= length(lanstr(key))
end;
{ 
lanchr(индекс,номер) - возращает символ из строки кнопки ...
    
индекс - индекс кнопки (полученный из keytoint)
    
номер - номер символа в строке кнопки, желательно меньше ее длины.
}function 
lanchr(key:integer;ind:integer):char; begin
    lanchr 
:= getchar(lanstr(key),ind)
end;
{ 
iohandle - основная функция системы
    возращает
: надобность repaintа (boolean)
}function 
iohandle:boolean; var key:integer; begin
    key 
:= keytoint(getkeyclicked); // получаем последнюю клацнутую кнопку...
    
iohandle := false; // возращенное по умолчанию значение
    
if key >= 0 then begin // если что-то нажато
        
ke_time := 0; // сброс времени ввода
        
iohandle := true; // перерисовуем.
        
if key < 10 then begin // если нажата цифра
            
if key = ke_current then begin // выбор буквы\символа
                
ke_select := ke_select + 1;
                if 
ke_select >= lanlen(ke_current) then ke_select := 0;
            
end else begin // нажата другая кнопка
                
if ke_current >= 0 then
                    ke_input 
:= ke_input + lanchr(ke_current,ke_select);
                
ke_current := key;
                
ke_select := 0;
            
end;
        
end else if key = 10 then begin // звездочка (backspace)
            
            
if(ke_current >= 10)or(ke_current < 0)then
                
if length(ke_input) > 0 then
                    ke_input 
:= copy(ke_input, 0, length(ke_input)-1);
            
ke_current := -1;
            
ke_select := 0;
        
end else if key = 11 then begin // решетка (смена языка)
            
if ke_current >= 0 then // если начат ввод, ввести в строку
                
ke_input := ke_input + lanchr(ke_current,ke_select);
            
lan := lan + 1;
            if 
lan >= lanc then lan := 0;
            
ke_current := -1;
            
ke_select := 0;
        
end; // тут дописывать else if'ы для прочих кнопок
        // (после того как допишите их в keytoint)
    
end else begin
        
if ke_current >= 0 then begin
            ke_time 
:= ke_time + 1;
            if 
ke_time >= ke_timex then begin
                ke_time 
:= 0;
                
ke_input := ke_input + lanchr(ke_current,ke_select);
                
ke_current := -1;
                
ke_select := 0;
                
iohandle := true;
            
end;
        
end;
    
end;
end;
// Ниже идет демка
var    // переменные для демонстрации
    
s, z: string; // строки для вывода, проверки
    
x: integer; // x-координата
    
y: integer; // y-координата
    
c: command; // кнопка выхода
// Основная процедура прорисовки (для теста)
procedure maindraw; begin
    setcolor
(239, 235, 231);
    
fillrect(0, 0, getwidth, getheight);
    
setcolor(0, 0, 0);
    
x := 4;
    
y := 4;
    
s := 'Input: ' + ke_input;
    
drawtext(s,x,y); y := y + getstringheight(s);
    
z := lanstr(ke_current);
    if 
z <> '' then begin
        s 
:= '[' + copy(z, 0, ke_select);
        
drawtext(s,x,y); x := x + getstringwidth(s);
        
setcolor(255, 0, 0);
        
s := getchar(z, ke_select);
        
drawtext(s,x,y); x := x + getstringwidth(s);
        
setcolor(0, 0, 0);
        
s := copy(z, ke_select+1, length(z)) + ']';
        
drawtext(s,x,y); x := 4; y := y + getstringheight(s);
    
end else begin
        s 
:= '[ ]'; // 
        
drawtext(s,x,y); y := y + getstringheight(s);
    
end;
    
s := 'Language: ' + integertostring(lan) + ' ' + lanname[lan];
    
drawtext(s,x,y); y := y + getstringheight(s);
    
s := '* to erase, # to switch language';
    
drawtext(s,x,y); y := y + getstringheight(s);
    
repaint;
end;
// Основная программа
begin
    iostart
;
    
ke_input := '?';
    
// добавляем кнопку выхода:
    
c := createcommand('Exit', cm_exit, 1);
    
addcommand(c);
    
// основной цикл:
    
maindraw;
    
repeat
        
if iohandle then maindraw;
        
delay(100);
    
until getclickedcommand = c;
    
removecommand(c);
end. 
Удачи в использовании сего в вашних проэктах.
Увидеть текстовую благодарность в мою сторону в About'е вашей программы\игры, использующей сию систему, было бы тоже очень мило.
(Offline)
 
Ответить с цитированием
Эти 5 пользователя(ей) сказали Спасибо YellowAfterlife за это полезное сообщение:
DIMMON4IK (20.02.2011), m.ksy (21.02.2011), nokia_c3 (20.02.2011), odd (22.02.2011), Pyth_ON (20.07.2011)