d-examples/source/examples/ncurses/password.d
Alexander Zhirov 273b38b49b
Добавлены примеры использования ncurses:
- Интерактивное консольное меню
- Консольное окно для ввода пароля
2025-05-15 19:57:03 +03:00

215 lines
8.9 KiB
D
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}