215 lines
8.9 KiB
D
215 lines
8.9 KiB
D
module examples.ncurses.password;
|
||
|
||
import std.conv; // Импорт модуля для преобразования типов
|
||
import std.string; // Импорт модуля для работы со строками
|
||
import std.stdio; // Импорт модуля для ввода-вывода
|
||
import deimos.ncurses; // Импорт библиотеки ncurses для работы с терминалом
|
||
import deimos.form; // Импорт библиотеки форм ncurses для создания полей ввода
|
||
import core.stdc.locale; // Импорт для работы с локализацией
|
||
|
||
// Определение констант для цветовых пар
|
||
enum
|
||
{
|
||
COLOR_WINDOW = 1, // Идентификатор цветовой пары для окна
|
||
COLOR_BACKGROUND = 2 // Идентификатор цветовой пары для фона
|
||
}
|
||
|
||
void passwordNcurses()
|
||
{
|
||
// Установка локали для корректного отображения символов (например, кириллицы)
|
||
setlocale(LC_ALL, "");
|
||
|
||
// Инициализация ncurses
|
||
initscr();
|
||
|
||
// Включение режима raw (сырой ввод, без обработки специальных символов)
|
||
raw();
|
||
|
||
// Отключение эха ввода (символы не отображаются при вводе)
|
||
noecho();
|
||
|
||
// Установка видимости курсора (2 — полностью видимый курсор)
|
||
curs_set(2);
|
||
|
||
// Инициализация цветового режима
|
||
start_color();
|
||
|
||
// Определение цветовых пар: текст/фон
|
||
init_pair(COLOR_WINDOW, COLOR_WHITE, COLOR_RED); // Белый текст на красном фоне
|
||
init_pair(COLOR_BACKGROUND, COLOR_WHITE, COLOR_BLUE); // Белый текст на синем фоне
|
||
|
||
// Получение размеров терминала (высота и ширина)
|
||
int width, height;
|
||
getmaxyx(stdscr, height, width);
|
||
|
||
// Установка фона для основного окна (stdscr) с использованием цветовой пары COLOR_BACKGROUND
|
||
bkgd(COLOR_PAIR(COLOR_BACKGROUND));
|
||
|
||
// Обновление экрана для отображения изменений
|
||
refresh();
|
||
|
||
// Создание нового окна размером 5x44, центрированного на экране
|
||
WINDOW* win = newwin(5, 44, height / 2 - 3, width / 2 - 22);
|
||
|
||
// Включение обработки специальных клавиш (например, Backspace) для окна
|
||
keypad(win, TRUE);
|
||
|
||
// Отрисовка рамки вокруг окна
|
||
box(win, 0, 0);
|
||
|
||
// Установка фона окна с использованием цветовой пары COLOR_WINDOW
|
||
wbkgd(win, COLOR_PAIR(COLOR_WINDOW));
|
||
|
||
// Обновление окна для отображения изменений
|
||
wrefresh(win);
|
||
|
||
// Создание массива полей формы (два поля: метка и поле ввода пароля)
|
||
FIELD*[3] fields;
|
||
|
||
// Поле для статической метки "Введите пароль:"
|
||
fields[0] = new_field(1, 16, 0, 2, 0, 0);
|
||
|
||
// Поле для ввода пароля
|
||
fields[1] = new_field(1, 20, 0, 18, 0, 0);
|
||
|
||
// Завершающий нулевой указатель для массива полей
|
||
fields[2] = null;
|
||
|
||
// Установка текста метки в первом поле
|
||
set_field_buffer(fields[0], 0, "Введите пароль:");
|
||
|
||
// Настройка первого поля: видимое, публичное, автопропуск (нельзя редактировать)
|
||
set_field_opts(fields[0], O_VISIBLE | O_PUBLIC | O_AUTOSKIP);
|
||
|
||
// Установка типа второго поля: регулярное выражение для валидации ввода
|
||
// Разрешены буквы, цифры, некоторые символы и пробелы
|
||
set_field_type(fields[1], TYPE_REGEXP, `^\**[-0-9A-Za-zА-Яа-я*,./!?%&#:$^_=+@~\]* *$`.ptr);
|
||
|
||
// Настройка второго поля: видимое, публичное, редактируемое, активно
|
||
set_field_opts(fields[1], O_VISIBLE | O_PUBLIC | O_EDIT | O_ACTIVE);
|
||
|
||
// Установка фона для первого поля (цветовая пара COLOR_WINDOW)
|
||
set_field_back(fields[0], COLOR_PAIR(COLOR_WINDOW));
|
||
|
||
// Установка фона и подчеркивания для второго поля
|
||
set_field_back(fields[1], COLOR_PAIR(COLOR_WINDOW) | A_UNDERLINE);
|
||
|
||
// Создание формы на основе массива полей
|
||
FORM* form = new_form(cast(FIELD**) fields);
|
||
|
||
// Установка основного окна для формы
|
||
set_form_win(form, win);
|
||
|
||
// Установка подокна для формы (область внутри окна для ввода)
|
||
set_form_sub(form, derwin(win, 1, 38, 2, 2));
|
||
|
||
// Отображение формы на экране
|
||
post_form(form);
|
||
|
||
// Обновление окна для отображения изменений
|
||
wrefresh(win);
|
||
|
||
// Переменная для хранения введенного пароля (в формате dstring для поддержки Unicode)
|
||
dstring password;
|
||
|
||
// Флаг для выхода из цикла ввода
|
||
bool stop = false;
|
||
|
||
// Переменная для хранения статуса операций с формой
|
||
int status;
|
||
|
||
// Переменная для хранения введенного символа
|
||
dchar ch;
|
||
|
||
// Переменная для хранения результата ввода
|
||
int ret;
|
||
|
||
// Основной цикл обработки ввода
|
||
while (!stop)
|
||
{
|
||
// Получение символа или кода клавиши из окна
|
||
ret = wget_wch(win, &ch);
|
||
|
||
switch (ret)
|
||
{
|
||
case KEY_CODE_YES: // Обработка специальных клавиш (например, Backspace)
|
||
switch (ch)
|
||
{
|
||
case KEY_BACKSPACE: // Нажата клавиша Backspace
|
||
// Удаление предыдущего символа из формы
|
||
form_driver_w(form, KEY_CODE_YES, REQ_DEL_PREV);
|
||
// Удаление последнего символа из строки пароля, если она не пуста
|
||
if (password.length)
|
||
password = password[0 .. $ - 1];
|
||
break;
|
||
default:
|
||
// Игнорирование других специальных клавиш
|
||
break;
|
||
}
|
||
break;
|
||
|
||
case OK: // Обработка обычных символов
|
||
switch (ch)
|
||
{
|
||
case KEY_BACKSPACE: // Нажата клавиша Backspace (альтернативный код)
|
||
// Удаление предыдущего символа из формы
|
||
form_driver_w(form, KEY_CODE_YES, REQ_DEL_PREV);
|
||
// Удаление последнего символа из строки пароля, если она не пуста
|
||
if (password.length)
|
||
password = password[0 .. $ - 1];
|
||
break;
|
||
case 32: // Пробел (игнорируется)
|
||
break;
|
||
case 10: // Нажата клавиша Enter
|
||
case KEY_ENTER: // Альтернативный код для Enter
|
||
// Установка флага для выхода из цикла
|
||
stop = true;
|
||
break;
|
||
default: // Обработка введенного символа
|
||
// Отправка символа в форму
|
||
status = form_driver_w(form, OK, ch);
|
||
if (status == OK) // Если символ принят
|
||
{
|
||
// Валидация содержимого поля
|
||
status = form_driver_w(form, KEY_CODE_YES, REQ_VALIDATION);
|
||
if (status == OK) // Если валидация прошла успешно
|
||
{
|
||
// Добавление символа в строку пароля
|
||
password ~= ch.to!dchar;
|
||
// Удаление последнего введенного символа
|
||
form_driver_w(form, KEY_CODE_YES, REQ_DEL_PREV);
|
||
// Замена введенного символа на '*' для маскировки
|
||
form_driver_w(form, OK, '*'.to!int);
|
||
}
|
||
else // Если валидация не прошла
|
||
{
|
||
// Удаление последнего введенного символа
|
||
status = form_driver_w(form, KEY_CODE_YES, REQ_DEL_PREV);
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
break;
|
||
|
||
default:
|
||
// Игнорирование других случаев
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Снятие формы с экрана
|
||
unpost_form(form);
|
||
|
||
// Освобождение памяти, занятой формой
|
||
free_form(form);
|
||
|
||
// Освобождение памяти, занятой полями
|
||
free_field(fields[0]);
|
||
free_field(fields[1]);
|
||
|
||
// Завершение работы ncurses и очистка экрана
|
||
endwin();
|
||
|
||
// Вывод введенного пароля в консоль
|
||
writefln("Password: %s\n", password);
|
||
}
|