Come dovrebbe comportarsi "Annulla digitazione"?


12

Sto implementando un'app Java che include uno stack Annulla / Ripristina. Ho notato che alcune app (come TextEdit su Mac OS X) ti consentono di scegliere "Annulla digitazione" dal menu Modifica dopo aver digitato del testo. Vorrei implementare questo genere di cose anche nella mia app, ma sto davvero facendo fatica a trovare le linee guida su come dovrebbe comportarsi.

Con alcune prove ed errori, la mia ipotesi migliore su come si comporta Undo Typing di TextEdit è:

  • Quando l'utente digita un nuovo carattere (o digita la chiave di eliminazione), uniscilo al precedente elemento di digitazione Annulla se uno è in cima allo stack Annulla, a meno che non si verifichi una delle seguenti situazioni
  • Crea sempre un nuovo elemento Annulla digitazione dopo che l'utente continua a digitare dopo almeno 15 secondi di inattività
  • Crea sempre un nuovo elemento Annulla digitazione dopo che l'utente ha digitato per un lungo periodo di tempo e sono soddisfatte alcune condizioni (non è stato possibile capire se si basava sul tempo o sul conteggio dei caratteri).
  • Crea sempre un nuovo elemento Annulla digitazione quando viene selezionato qualsiasi testo e quindi eliminato o sovrascritto (selezionando il testo, non apportando una modifica, quindi tornare al punto di inserimento originale e continuare a digitare non lo attiva)

In pratica, la strategia di Apple sembra funzionare (almeno funziona per me quando scrivo), ma come notato dall'ultimo punto, non sono stato davvero in grado di capire le regole. Inoltre, sembra che altri programmi seguano regole diverse, come Microsoft Word. Google non ha creato un elenco definito di regole per l'implementazione di Annulla digitazione e non ho trovato alcuna best practice per come dovrebbe comportarsi. Quindi come dovrebbe comportarsi? O dipende solo dai capricci del programmatore?

EDIT: Solo per chiarire, non sono interessato ai dettagli di implementazione in questo momento. Sono particolarmente curioso di sapere se esiste un riferimento autorevole (ad es. Best practice o documento di interfaccia utente) che descriva questo o una descrizione di come viene implementato su più prodotti.


Il mio consiglio: comprimere le modifiche al punto in cui è ancora possibile ricostruire l'esatta sequenza di tasti premuti dalle informazioni di annullamento e non di più. Ad esempio, ciò significa che se l'utente digita qualcosa e usa immediatamente backspace per eliminarlo, dovrebbe esserci un punto di annullamento nel mezzo.
Ambroz Bizjak,

Forse potresti anche aggiungere un nuovo "Annulla elemento di digitazione" ogni volta che l'utente crea una nuova riga e forse ogni volta che la barra spaziatrice viene utilizzata immediatamente dopo l'immissione dei caratteri. IMO 15 secondi di tempo di attesa prima che un nuovo "Annulla digitazione elemento" potrebbe essere un po 'lungo, ma sono solo io. (Vorrei andare per circa 5 secondi)
user82529,

O forse "l'esatta sequenza di tasti premuti" dovrebbe essere rilassata allo "stato del testo dopo ogni modifica". L'idea è di impedire la perdita di qualsiasi testo a causa della compressione.
Ambroz Bizjak,

Mi sembra che TextEdit unisce spazi ed elimini con l'ultimo elemento Annulla digitazione, a condizione che le altre condizioni non siano soddisfatte. Quindi 124<delete>3, l'annullamento e la ripetizione comporta 123. Immagino che il vantaggio sia che si traduce nello stato finale del testo dell'utente, un po 'come il suggerimento sopra.
Thunderforge,

Hai già provato a cercare i brevetti? (Le regole sono generalmente codificate nel livello libreria, non esposte al codice utente.)
Donal Fellows

Risposte:


5

Se stai cercando una fonte autorevole, penso che il miglior materiale relativo a Mac sarà trovato nel documento Undo Architecture di Apple.

Non credo che troverai un elenco di regole su quando dovresti o non dovresti fondere gli eventi di annullamento. Ciò che sembra giusto per un'applicazione non avrà necessariamente senso per un'altra. Ad esempio, la combinazione di tasti combinati ha senso in un editor di testo perché l'utente vedrà probabilmente digitare un paragrafo come una singola azione e non come 539 azioni separate, e anche perché non si desidera che l'utente debba annullare 539 volte solo per ottenere al punto in cui si trovavano prima di scrivere quel paragrafo. Ma che dire delle operazioni di spostamento su una forma in un programma di disegno? O regolazioni sequenziali di un colore di riempimento? Potresti fare un buon caso per farli coalizzare o meno, a seconda della natura del tuo programma.

Crea sempre un nuovo elemento Annulla digitazione dopo che l'utente ha digitato per un lungo periodo di tempo e sono soddisfatte alcune condizioni (non è stato possibile capire se si basava sul tempo o sul conteggio dei caratteri).

Si basa sul salvataggio automatico. Fortunatamente per te, il codice sorgente di TextEdit è disponibile e ben commentato. Penso che se lo guardi, avrai un'idea migliore di cosa sta succedendo e perché. Per esempio:

- (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)];
 ...

So che hai detto che non sei ancora interessato ai dettagli dell'implementazione, ma guardando il modo in cui Apple ha implementato TextEdit può informare le decisioni che prendi per la tua applicazione.


1
Penso che dichiarerò questa la migliore risposta. Apprezzo che tu abbia fornito il collegamento all'implementazione di Apple e un po 'di codice per l'esempio specifico che ho fornito. Penso che tu abbia ragione, in genere si basa sulle esigenze dell'applicazione e nessuno ha davvero fatto uno sforzo per standardizzare quali sono quelle esigenze e come affrontarle.
Thunderforge,

1

sul keydown -> il timer che rappresenta il tuo inattività inizia

su keydown / timer in esecuzione -> reset timer

su keydown / nessun timer in esecuzione -> riaggiustare i blocchi di celle per preparare un nuovo stato preservato quando cambiano posizione

il timer inattivo si esaurisce -> Stabilisce un nuovo stato di annullamento

Non tracciavo le identità dei tasti premuti. Mi dividerei in blocchi di testo cellulare (in base al conteggio dei caratteri) che ti consentono di tracciare la posizione per offset dalle posizioni iniziali della cella più vicina in modo da non dover salvare l'intero stato di un romanzo tolstoy ogni volta che un timer inattivo si esaurisce . Regolare nuovamente questi offset quando le celle prima che altre celle vengano modificate è la parte difficile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.