J'implémente une application Java qui inclut une pile Annuler / Rétablir. J'ai remarqué que certaines applications (telles que TextEdit sur Mac OS X) vous permettent de choisir "Annuler la saisie" dans le menu Edition après avoir tapé du texte. J'aimerais également implémenter ce genre de chose dans mon application, mais j'ai beaucoup de mal à trouver des directives sur la façon dont elle devrait se comporter.
Avec quelques essais et erreurs, ma meilleure estimation du comportement de TextEdit Undo Typing est:
- Lorsque l'utilisateur tape un nouveau caractère (ou tape la clé de suppression), fusionnez-le dans l'élément de frappe d'annulation précédent si l'un se trouve en haut de la pile d'annulation, sauf si l'une des situations suivantes se produit
- Créez toujours un nouvel élément Annuler la frappe après que l'utilisateur continue de taper après au moins 15 secondes d'inactivité
- Créez toujours un nouvel élément Annuler la frappe après que l'utilisateur a tapé pendant une longue période et qu'une condition est remplie (impossible de déterminer si cela était basé sur le temps ou sur le nombre de caractères).
- Créez toujours un nouvel élément Annuler la frappe lorsqu'un texte est sélectionné, puis supprimé ou écrasé (sélectionner du texte, ne pas apporter de modification, puis revenir au point d'insertion d'origine et continuer à taper ne déclenche pas cela)
Dans la pratique, la stratégie d'Apple semble fonctionner (au moins, elle fonctionne pour moi lorsque je tape), mais comme indiqué par le dernier point, je n'ai pas vraiment pu comprendre les règles. En outre, il semble que d'autres programmes suivent des règles différentes, telles que Microsoft Word. Google n'a pas fourni de liste définie de règles pour toute implémentation de la fonction d'annulation de la frappe et je n'ai trouvé aucune meilleure pratique sur la façon dont il devrait se comporter. Alors, comment devrait-il se comporter? Ou est-ce juste aux caprices du programmeur?
EDIT: Juste pour clarifier, je ne suis pas intéressé par les détails de mise en œuvre pour le moment. Je suis particulièrement curieux de savoir s'il existe ou non une référence faisant autorité (par exemple, les meilleures pratiques ou un document d'interface utilisateur) décrivant cela ou une description de la façon dont il est mis en œuvre sur plusieurs produits.
la source
124<delete>3
, l'annuler et le refaire entraîne123
. Je suppose que l'avantage de ceci est qu'il en résulte l'état final du texte de l'utilisateur, un peu comme la suggestion ci-dessus.Réponses:
Si vous recherchez une source faisant autorité, je pense que le meilleur matériel lié à Mac se trouve dans le document Annuler l'architecture d'Apple.
Je ne pense pas que vous allez trouver une liste de règles sur le moment où vous devez ou non fusionner les événements d'annulation, cependant. Ce qui convient à une application n'aura pas nécessairement de sens pour une autre. Par exemple, la coalescence des frappes est logique dans un éditeur de texte car l'utilisateur verra probablement la saisie d'un paragraphe comme une action unique et non comme 539 actions distinctes, et aussi parce que vous ne voulez pas que l'utilisateur doive annuler 539 fois juste pour obtenir au point où ils en étaient avant de taper ce paragraphe. Mais qu'en est-il des opérations de déplacement sur une forme dans un programme de dessin? Ou des ajustements séquentiels à une couleur de remplissage? Vous pourriez faire un bon argument en faveur de leur fusion ou non, selon la nature de votre programme.
Il est basé sur l'enregistrement automatique. Heureusement pour vous, le code source de TextEdit est disponible et bien commenté. Je pense que si vous y jetez un œil, vous aurez une meilleure idée de ce qui se passe et pourquoi. Par exemple:
Je sais que vous avez dit que vous n'êtes pas encore intéressé par les détails de la mise en œuvre, mais en regardant la façon dont Apple a implémenté TextEdit peut éclairer les décisions que vous prenez pour votre propre application.
la source
au keydown -> minuterie représentant vos démarrages inactifs
sur keydown / timer-running -> reset timer
sur keydown / pas de temporisation -> réajuster les blocs de cellules pour se préparer à un nouvel état préservé lorsque la position change
la minuterie d'inactivité est épuisée -> Établir un nouvel état d'annulation
Je ne suivrais pas les identités des touches. Je me diviserais en blocs cellulaires de texte (par nombre de caractères) qui vous permettent de suivre la position par décalages à partir des positions de départ de la cellule la plus proche afin que vous n'ayez pas à enregistrer l'intégralité de l'état d'un roman tolstoy à chaque fois qu'une minuterie inactive s'épuise . Réajuster ces décalages lorsque les cellules avant que d'autres cellules ne soient modifiées est la partie délicate.
la source