Русский
Русский
English
Статистика
Реклама

Ввод текста

Из песочницы Клавиатура из пяти кнопок

30.10.2020 00:06:47 | Автор: admin
Графические интерфейсы штука удобная, но иногда их не хватает. Сделать удобный интерфейс это искусство и большая трата ресурсов. Поэтому в большинство программ можно попасть только через командную оболочку.

Интерфейс командной строки легко и удобно создавать, расширять функционал, не заботясь о пользователе.

Если надо что-то настроить, а нужного пункта в меню нет, то можно руками залезть в конфиг. Если нет доступа к конфигу, то приходится страдать.

Это я подвожу к тому, что даже имея графический интерфейс, текстовый может быть очень полезен, особенно если при разработке что-то не предусмотрели.

Размышления про клавиатуру в Flipper Zero вызвали вялотекущее обсуждение про оптимизацию способов ввода. Мне тоже нравятся велосипеды, поэтому вот пара диких идей.

Прокрутка с умной сортировкой


Будем отталкиваться от простого скролла символов.

Есть набираемый текст, навигация по тексту стрелки влево/вправо. Чтобы выбрать символ, листаем стрелками вверх/вниз линейный список из всех символов.

Это довольно неудобно, сделаем пару улучшений.

На основе введенного пользователем текста, будем собирать статистику по n-граммам символов. В самом простом случае, берем предыдущие 4 символа, сортируем таблицу символов по частоте использования с этой тетраграммой. Пользователь начинает листать вниз и быстрее находит нужный символ. При прокрутке вверх находится фиксированный набор служебных команд, вроде пробела, удаления предыдущего символа, переключения регистра и раскладки.

Для узкого спектра задач, такой способ сгодился бы, но для человека это все-таки слишком сложно. Приходится концентрировать внимание, чтобы не пропустить нужный знак, а это утомляет.

image

Троичная система


А что если просто запомнить расположение нужных диапазонов символов в юникоде?
Набираем код символа, подтверждаем, набираем следующий.

Имеем 5 кнопок. Если одну будем использовать для подтверждения ввода, вторую для стирания последнего разряда, остается 3 кнопки на цифры. Допустим, вверх 0, вправо 1, вниз 2.

Достаточно привыкнуть к троичной системе и выучить диапазоны нужных кодов. Удобство сомнительное, но привыкнуть к такому способу ввода, намного легче, чем зубрить морзянку. Есть некоторая избыточность, имеется возможность вводить все, от управляющих символов до эмодзи, но вряд-ли у кого-то будет нужда использовать более сотни букв и знаков пунктуации.

image

Двухмерный скролл


Расширим скролл в несколько рядов символов, отсортируем по частоте использования, таким образом, чтобы манхэттенское расстояние от стартовой точки до символа, было тем больше, чем он реже используется.

image

Получается намного удобней, никакой подготовки не требуется. Небогатый, интуитивно понятный интерфейс, вполне годится для маленького дисплея. В кнопочных телефонах подобным способом можно набирать всякие спецсимволы. Но сократив размер до одной строки, можно реализовать это и на совсем крохотных экранах.

image

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

Вот ссылка на код демки, используемой в посте

Подключается как питоновская библиотека, функция ternary опционально принимает строку для редактирования. Чтобы перейти из режима навигации, надо нажать стрелку вверх. В режиме редактирования набирается троичный код символа (вверх 0, вправо 1, вниз 2, влево стереть последний разряд, Enter подтвердить). Для выхода надо нажать Enter, функция вернет отредактированную строку.

В функции roll все намного проще стрелками выбираем символ, подтверждаем кнопкой Enter. В первой верхней строке: вставка табуляции, Shift, Backspace, пробел, перевод строки, Delete и Caps Lock.
Подробнее..

Перевод Может ли геймпад заменить клавиатуру? Пробуем программировать на стиках

10.08.2020 10:05:17 | Автор: admin
image

Введение


Для печати на клавиатуре необходимо неподвижно сидеть или стоять. Геймпады, в отличие от них, портативные и компактные. Управляя ими, можно ходить по комнате или прилечь на диван.

Из-за малого количества кнопок на геймпаде никто не рассматривал их как средство ввода объёмных текстов, например, в программировании.

Однако аналоговые стики (а у большинства геймпадов их два) имеют потенциал обеспечения бесконечного количества вариантов ввода. Вопрос сводится к выбору подходящих жестов для максимальной эффективности и минимального напряжения больших пальцев.

Для геймпадов существует множество способов ввода текста. Если вы когда-нибудь играли в консольные игры, то, скорее всего, использовали какой-то из них.


Экранный ввод текста в Legend of Zelda

В Legend of Zelda игрок должен по очереди выбирать буквы при помощи крестовины со стрелками и каждый раз нажимать кнопку подтверждения для добавления буквы в поле ввода текста.

С тех пор были разработаны более эффективные способы ввода. Если вас это заинтересовало, то прочитайте статью на Gamasutra.

К сожалению, все найденные мной способы ввода имеют два серьёзных изъяна, из-за которых они не подходят для серьёзной работы:

  • Они недостаточно быстры
  • Они требуют визуальной обратной связи

Потребность в скорости очевидна. Визуальная обратная связь неприемлема, потому что занимает драгоценное место на экране и отвлекает пользователя, а значит, мешает состоянию потока и замедляет работу.

Однако при отсутствии обратной связи все жесты необходимо запоминать и практиковать, пока вы не сможете вводить их с достаточной точностью. Видеоигры вряд ли смогут заставить пользователя потратить пару недель на обучение способу ввода текста, но для способа ввода текста, который можно применять в любой программе, такая цена является приемлемой, а само обучение напоминает освоение сенсорного ввода.

В этом посте я вкратце расскажу об этапах создания системы ввода текста для геймпадов, пригодной в качестве замены объёмного клавиатурного ввода.

Определяемся с жестами


Для начала я создал инструмент визуализации движения аналоговых стиков геймпада на основе pygame языка Python. Для наглядности я дополнил инструмент так, чтобы он не только показывал текущие позиции стиков, но и предыдущие позиции всё более светлых оттенков серого, чтобы вы видели траектории, по которым движутся стики.

На рисунке ниже показаны одновременные движения обоих аналоговых стиков внутрь, вверх, наружу, вниз, снова внутрь и обратно в центр.


Визуализация паттернов движения аналоговых стиков

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

С учётом этих ограничений я выяснил, что простейшим возможным вводом будет перемещение одного из стиков в любом направлении и обратно в центр.


Левый стик переместился вверх и обратно в центр

Сколько направлений и какие именно направления можно точно выбрать вслепую? Рассмотрим следующий пример.


Левый стик переместился вверх, вниз, в центр, влево и вправо, а правый стик двигался по диагонали

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

Следующими найденными простейшими способами ввода стали одноэтапные и двухэтапные круговые движения.


Левый стик переместился вверх, влево и обратно к центру


Левый стик переместился вверх, влево, вниз и обратно в центр

Учитывая все придуманные пока жесты, мы получили 4 + 8 + 8 = 20 вариантов ввода на каждом стике.

Разумеется, оба стика можно двигать одновременно, создавая комбинированные жесты ввода.


Оба стика одновременно движутся вверх и обратно к центру

При комбинировании жестов в сумме получается 20 * 20 + 20 + 20 = 440 вариантов ввода, чего, по-моему, более чем достаточно.

Кодирование жестов


Я разделил пространство ввода каждого стика на 4 сектора и присвоил каждому сектору число.

Input spaces divided into sectors

Пространства ввода, разделённые на сектора

Затем я задал пороговую область вокруг центра, помогающую определить, находится ли стик в нейтральном положении, или же в одном из секторов.


Круговая пороговая область вокруг центра

Как видите, радиус пороговой области довольно велик. При экспериментах я определил, что это наилучший радиус, обеспечивающий наименьшее количество ошибок.

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

Stick movements for input ((0,), (2, 3))

Перемещения стиков для ввода ((0,), (2, 3))

Привязка жестов к действиям


В данном случае действиями являются просто клавиши клавиатуры. Кнопки-триггеры геймпада можно привязать к клавишам Shift, Ctrl, Alt и Super, что будет удобно, потому что эти клавиши используются в сочетаниях (например, Ctrl-C).

Чтобы определить оптимальную привязку вводимого жеста и клавиши, я в течение нескольких недель записывал при помощи кейлоггера все нажатия клавиш и проанализировал частоту каждой клавиши.

Самые часто нажимаемые клавиши должны быть привязаны к простейшим (а значит, самым быстрым) жестам. Я оценивал сложность жеста сложением длин вводов каждого стика. Например, показанный выше ввод ((0,), (2, 3)) имеет сложность 1 + 2 = 3.

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

Следуя этой логике, я сначала сгенерировал все возможные варианты ввода с одного стика и сгруппировал их по сложности. Я посчитал количество вводов в группе каждой сложности и взял количество клавиш из отсортированного списка самых частых клавиш.

Моя цель заключалась в разделении этих клавиш на две группы, одна для ввода левым стиком, вторая правым. Для нахождения идеальных групп я создал граф, в котором узлы были клавишами, а взвешенные рёбра обозначали частоты комбинаций клавиш.

Я циклически удалял ребро с наименьшим весом, пока граф не стал двудольным. Если граф становился несвязанным, я рекурсивно применял к связанным компонентам алгоритм разбиения, а в конце объединял группы в независимые множества.

Рассмотрим следующий пример. Первая группа сложности состоит из всех вводов со сложностью 1, то есть ((0,), ()), ((1,), ()), ((2,), ()), ((3,), ()), ((), (0,)), ((), (1,)), ((), (2,)), ((), (3,)).

В этой группе 8 вводов, поэтому мы берём 8 самых частых клавиш из отсортированного списка. Это 'e', 'o', 't', 'a', 'i', 's', 'j', 'r'. Создаём граф с этими клавишами в качестве узлов и назначаем веса рёбрам между этими узлами, соответствующие частоте каждого сочетания клавиш.

Клавиши e и r сочетаются чаще всего, поэтому должны быть привязаны к разным стикам

При удалении слабых рёбер из графа он рано или поздно превращался в несвязанный.
The key j is frequent but isolated.

Клавиша j встречается часто, но она изолирована.

Возможно, вы недоумеваете, почему клавиша j является одной из 8 самых частых клавиш, но имеет такие слабые связи с остальными частыми клавишами. Причина заключается в том, что j активно используется при работе с VIM plus, в моей системе это часть комбинации горячих клавиш для переключения между окнами. Поэтому она чаще используется изолированно, чем в тексте.

Так как граф несвязанный, я продолжаю применять алгоритм к связанным компонентам. Подграф, состоящий только из узла j, уже является двудольным (j + пустое множество). Я рекурсивно применяю алгоритм к другому компоненту.
Component is bipartite after removing the weakest edges

После удаления самых слабых рёбер компонент становится двудольным

Затем компонент можно без проблем разделить на две группы без рёбер между узлами в группе.
Bipartite drawing of the component

Двудольная схема компонента

В конце я объединяю двудольные множества.
Final grouping for the first 8 keys

Группировка, получившаяся для первых 8 клавиш

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

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

Я применил пакет pyautogui языка Python для генерации клавиатурных событий при срабатывании действий.

Практика


Я использовал тот же тренажёр сенсорного ввода ktouch, которым уже пользовался для обучения печати на клавиатуре почти два десятка лет назад. Для этой цели я создал специализированные уроки.

Practising gamepad touch typing in ktouch

Практикуем аналоговый ввод на геймпаде в ktouch

Наблюдения


  • Хотя процесс Python, в котором запущена эта система ввода, обычно потреблял не больше 10% ресурсов процессора, если бы он должен был постоянно выполняться в фоновом режиме, то я бы реализовал его заново и оптимизировал на языке более низкого уровня, чтобы процессор мог заниматься более затратными задачаи.
  • После покупки геймпада DualShock4 я понял, то довольно точно могу выполнять диагональный ввод. Интеграция диагонального ввода уменьшит количество более сложных вариантов ввода, а значит, увеличит скорость.
  • После недели практики я могу печатать на геймпаде всего в два раза медленнее, чем на клавиатуре. Учитывая мою безумную скорость печати на клавиатуре, это совсем неплохо. Для дополнительной выгоды я использую оставшиеся варианты ввода, привязав их к специальным действиям, например, к горячим клавишам или операциям конкретных программ.
  • Похоже, сильнее всего напрягают большие пальцы круговые движения. Вероятно, стоит заменить их более долгими, но более прямыми вариантами ввода.
  • Напряжение больших пальцев снижается после практики. Однако в начале стоит практиковаться всего по несколько минут за раз.

Заключание


Всего за пару дней я создал эффективную систему ввода для геймпадов. Можно внести множество усовершенствований, однако эта проверка концепции демонстрирует, что эффективный ввод текста на геймпаде возможен. Код проекта выложен на github.
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru