Як слід діяти "Скасувати введення тексту"?


12

Я реалізую додаток Java, що включає стек скасування / повторення. Я помітив, що деякі програми (наприклад TextEdit на Mac OS X) дозволяють вибрати "Скасувати введення тексту" в меню "Редагувати" після введення тексту. Я також хотів би реалізувати таку річ у своєму додатку, але мені дуже важко знайти вказівки щодо того, як вона повинна вести себе.

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

  • Коли користувач вводить новий символ (або набирає ключ видалення), з'єднайте його з попереднім елементом Скасувати введення тексту, якщо він знаходиться у верхній частині стека скасування, якщо не трапляється одна з наступних ситуацій.
  • Завжди створюйте новий елемент «Скасувати введення тексту» після того, як користувач продовжить вводити принаймні 15 секунд бездіяльності
  • Завжди створюйте новий елемент Скасувати введення тексту після того, як користувач вводить протягом тривалого періоду часу та виконує якусь умову (не вдалося зрозуміти, чи це було на основі часу чи на основі кількості символів).
  • Завжди створюйте новий елемент Скасувати введення тексту, коли вибраний будь-який текст, а потім видалено або перезаписано (вибравши текст, не внести змін, потім повернутися до початкової точки вставки та продовжуючи вводити це не запускає)

На практиці стратегія Apple, здається, працює (принаймні, це працює для мене під час введення), але, як зазначалося в останньому пункті, я не зміг зрозуміти правила. Крім того, схоже, що інші програми дотримуються різних правил, таких як Microsoft Word. Google не створив визначений перелік правил для будь-якої реалізації функції скасування друку, і я не натрапив на кращі практики щодо того, як він повинен вести себе. То як воно має поводитися? Або це лише до примх програміста?

EDIT: Просто для уточнення, зараз мене не цікавлять деталі впровадження. Мені особливо цікаво, чи існує авторитетна довідка (наприклад, найкраща практика чи документ із користувальницьким інтерфейсом), що описує це чи опис того, як воно реалізується у кількох продуктах.


Моя пропозиція: стисніть модифікації до того моменту, коли ще можна відновити точну послідовність натиснутих клавіш із інформації про скасування, і не більше. Наприклад, це означає, що якщо користувач щось вводить і негайно використовує зворотний простір для його видалення, між ними повинна бути точка відміни.
Ambroz Bizjak

Можливо, ви також можете додати новий "Скасувати набір тексту" кожен раз, коли користувач створить новий рядок, а може бути, кожен раз, коли пробіл буде використаний відразу після введення символів. IMO 15 секунд часу очікування перед новим "Скасувати набір тексту" може бути трохи довгим, але це тільки я. (Я б пішов близько 5 секунд)
user82529

А може бути, "точну послідовність натиснутих клавіш" слід послабити до "стану тексту після кожної модифікації". Ідея полягає у тому, щоб не стиснути будь-якого тексту через стиснення.
Амброз Біжак

Мені здається, що TextEdit об'єднує пробіли та видаляє останній елемент Undo Typing, якщо інші умови не виконані. Отже 124<delete>3, після його скасування та повторного повторення це призведе до 123. Я здогадуюсь, що перевага цього полягає в тому, що це призводить до остаточного стану тексту користувача, дещо як вищенаведена пропозиція.
Грім

Ви ще намагалися шукати патенти? (Правила зазвичай кодуються в шарі бібліотеки, не піддаються коду користувача.)
Дональд

Відповіді:


5

Якщо ви шукаєте авторитетне джерело, я думаю, що найкращий матеріал, що стосується Mac, буде знайдений у документі Undo Architecture від Apple.

Я не думаю, що ви збираєтесь знайти список правил про те, коли вам слід чи не слід поєднувати скасування подій. Те, що вважається правильним для однієї програми, не обов'язково має сенс для іншого. Наприклад, поєднання натискань клавіш має сенс у текстовому редакторі, оскільки користувач, ймовірно, побачить введення абзацу як одну дію, а не як 539 окремих дій, а також тому, що ви не хочете, щоб користувач повинен був скасувати 539 разів просто для отримання до моменту, до якого вони були, перш ніж вони набрали цей абзац. А як щодо переміщення операцій над фігурою в програмі малювання? Або послідовні коригування кольору заливки? Ви можете зробити хороший випадок, коли вони поєднуються чи ні, залежно від характеру вашої програми.

Завжди створюйте новий елемент Скасувати введення тексту після того, як користувач вводить протягом тривалого періоду часу та виконує якусь умову (не вдалося зрозуміти, чи це було на основі часу чи на основі кількості символів).

Він заснований на автоматичному збереженні. Пощастило, вихідний код TextEdit доступний і добре прокоментований. Я думаю, що якщо ви поглянете на це, ви отримаєте краще уявлення про те, що відбувається і чому. Наприклад:

- (void)saveToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName forSaveOperation:(NSSaveOperationType)saveOperation completionHandler:(void (^)(NSError *error))handler {
    // Note that we do the breakUndoCoalescing call even during autosave, which 
    // means the user's undo of long typing will take them back to the last spot an 
    // autosave occured. This might seem confusing, and a more elaborate solution may 
    // be possible (cause an autosave without having to breakUndoCoalescing), but since 
    // this change is coming late in Leopard, we decided to go with the lower risk fix.
    [[self windowControllers] makeObjectsPerformSelector:@selector(breakUndoCoalescing)];
 ...

Я знаю, ви сказали, що ви ще не зацікавлені в деталях впровадження, але дивитесь на те, як реалізована Apple TextEdit може інформувати рішення, які ви приймаєте для власної програми.


1
Я думаю, що я оголошу це найкращою відповіддю. Я вдячний, що ви надали посилання на реалізацію Apple, а також якийсь код для конкретного прикладу, який я надав. Я думаю, що ти маєш рацію, але він, як правило, ґрунтується на потребах програми, і ніхто не намагався стандартизувати, що це за потреби, і як їх вирішити.
Грім

1

при натисканні клавіш -> починається таймер, що представляє ваші очікування

при натисканні клавіш / запуску таймера -> таймер скидання

при натисканні клавіш / відсутність запуску таймера -> перенастроювання блоків комірок, щоб підготуватися до нового збереженого стану під час зміни положення

таймер холостого ходу працює вниз -> Встановлення нового стану скасування

Я б не відстежував ідентифікацію клавіш. Я розділив би на стільникові текстові блоки (за кількістю символів), які дозволяють відстежувати позицію за зміщенням від початкових позицій найближчої комірки, тому вам не доведеться зберігати весь стан роману Tolstoy кожного разу, коли запущений таймер працює . Коригування цих компенсацій, коли комірки перед редагуванням інших комірок є складною частиною.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.