IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Implémenter un système de raccourcis clavier pour mon application


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club Avatar de lilivve
    Homme Profil pro
    Creative coding
    Inscrit en
    Mars 2018
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Creative coding
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mars 2018
    Messages : 7
    Par défaut Implémenter un système de raccourcis clavier pour mon application
    Bonjour,

    Je suis en train de réfléchir à comment ajouter des raccourcis claviers configurables à mon programme. N'étant pas le premier à vouloir faire ceci j'ai cherché sur le net des tutos, frameworks, bibliothèques mais sans résultat. Peut-être aurais-je ici des pistes pour ne pas réinventer la roue!

    Ce que je sais déjà faire:
    - Ecouter les touches pressées
    - Associer une touche à par exemple une std::function<void()> et appeler cette fonction quand la touche est pressée.

    Ma question est au niveau de la conception de mon système de gestion des raccourcis. J'explique le système que j'imagine:

    Il y a des classes avec des méthodes publiques, et des objets instances de ces classes.
    On peut associer certaines méthodes de certains de ces objets à des raccourcis clavier, et modifier ces raccourcis pendant l'exécution (et du coup que l'utilisateur puisse le faire).

    Il y a plusieurs "jeux" de raccourcis claviers. Selon l'état de l'application tel ou tel jeu de raccourcis est actif. Une même touche peut donc, selon les jeux actifs, déclencher l'appel de différentes méthodes.
    Il y a au moins un jeu de base, actif tout le temps, qui contient les raccourcis généraux de pilotage global de l'application (la fermer, basculer entre ses états principaux, afficher ou cacher certaines fenêtres, etc).
    Et il y a des jeux de raccourcis supplémentaires, spécifiques à l'état de l'application. Par exemple quand l'application est en train de lire des vidéos la touche espace fait le play/pause, mais plus tard quand l'application est en mode enregistrement du son du microphone la touche espace déclenche ou stoppe cet enregistrement.
    Plusieurs jeux de raccourcis supplémentaires peuvent être actifs en même temps.
    Donc, quand une touche est enfoncée, le programme déclenche la fonction associée dans le jeu de raccourcis globaux. S'il n'y a pas de fonction associée dans ce jeu elle cherche s'il y a une fonction associée dans un des autres jeux, et l'exécute.

    Les objets répondant aux touches peuvent être créés et détruits pendant l'exécution du programme. La méthode d'un objet associée à une touche doit donc être appelée uniquement si l'objet existe, bien sûr.

    Les objets peuvent recevoir le focus. Dans un même jeu de raccourcis, plusieurs objets peuvent associer une méthode à une même touche. Quand la touche est pressée c'est l'objet qui a le focus qui aura sa méthode associée exécutée.

    Il doit être possible de sauvegarder et charger les jeux de raccourcis sur le disque, de préférence sous forme texte (qui soit donc éditable à la main).

    Donc voilà, je suis en train de me demander comment articuler tout cela, avec donc la sensation d'être en train de coder quelques chose qui l'a déjà été par d'autres. Est-ce que quelqu'un aurait une piste d'implémentation, un pattern à proposer ? En même temps j'ai l'impression que ma question est complexe...
    Merci

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Salut,

    cote structure, un truc sympa pourrait etre une std::map<Bind, Callback> avec Bind quelque chose comme par exemple struct Bind { std::vector<Button> }; qui contient les boutons qui doivent etre presses pour activer le raccourci et Callback pourrait etre using Callback = std::function<void(void)>;.
    La partie la plus difficile c'est de creer ce Bind dynqmiauement pendant l'execution si tu as des combinaisons plus complexes que modifier+1 bouton puisque les timings sont jamais parfaits.
    Ensuite si tu comptes avoir differents niveaux et priorites, faut placer et tester ces elements aux endroits correspondants, en partant du focus puis traversant les parents iterativement jusqu'a ce qu'un d'eux interceptent et activent une action.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre du Club Avatar de lilivve
    Homme Profil pro
    Creative coding
    Inscrit en
    Mars 2018
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Creative coding
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mars 2018
    Messages : 7
    Par défaut
    Merci pour ta réponse Bousk,

    Après plusieurs jours j'en suis arrivé à quelque chose qui semble satisfaisant pour mon usage. Le principe est que j'ai d'une part une table des raccourcis existants de l'application:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::unordered_multimap< keyboard::Stroke, CallbackID > shortcuts ;
    où pour le moment CallbackID est une string et où keyboard::Stroke est ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Stroke
    {
    	public:
    		int keyCode = 0 ;
    		bool ctrlModifier = false ;
    		bool majModifier = false ;
    		bool altModifier = false ;
    		std::string text ;                // Une représentation de la touche en texte, par exemple "Ctrl+A"
    }
    Et que d'autre part j'ai une table des callbacks existants qui associe chaque raccourci clavier à la fonction qu'il doit appeler:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::unordered_map< CallbackID, Callback > bindings ;
    Un Callback étant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class Callback
    {
    	public:
    		CallbackID id ;
    		typedef std::function< void ( ) > function ;          // La fonction a exécuter 
    		typedef std::function< bool ( ) > precondition ;    // Une fonction qui doit renvoyer true pour que la fonction soit exécutée
    }
    (je ne montre pas tout le code, juste ce qu'il faut pour expliquer le principe)

    Quand une touche est pressée je regarde dans la première table shortcuts si des CallbackID lui sont associés. Je regarde ensuite dans la table bindings si les Callback qui ont ces ID existent. Pour ceux-ci, je commence par regarder parmi ceux qui ont une precondition définie, et j'exécute la function du premier Callback dont la precondition renvoie true. Si je n'en trouve pas j'exécute alors la function du premier Callback qui n'a pas de precondition.

    Le découplage en deux tables, shortcuts et bindings complique mais à deux avantages:
    - Je peux sauvegarder sur le disque la table shortcuts, ensemble des raccourcis de l'application, sous une forme texte que je peux éventuellement éditer à la main, et charger au lancement du programme.
    - Je peux instancier des objets à n'importe quel moment de la vie de l'application, et ces objets peuvent déclarer leurs callbacks dans la table bindings, et les rendre accessibles. Quand un objet censé répondre à un raccourci clavier n'existe pas il ne se passe rien.

    Un inconvénient est que je dois m'assurer de l'unicité de chaque CallbackID. En même temps si je veux pouvoir sauvegarder les raccourcis sous forme texte, il me semble que je dois forcément en passer par là.

    J'ai introduis la gestion du focus grâce à l'histoire de la precondition, qui pourra d'ailleurs servir à un autre usage. Je choisis alors de créer le Callback avec une precondition de ce genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    [ this ](){ return isFocused ; }
    C'est une gestion rudimentaire du focus, un objet a le focus ou ne l'a pas, et je n'ai pas de relation parent/enfant entre les différents objets qui ont des Callbacks, mais cela semble suffire à mes besoins.

    D'autre part j'ai en réalité plusieurs jeux de raccourcis, chacun avec sa table shortcuts, que je peux activer ou désactiver selon l'état de l'application. Ceci me permet d'avoir une même touche qui à un moment va déclencher une action, et plus tard une autre. Par exemple la touche espace pour du play/pause.

    S'il y a des remarques sur ce que j'ai commis, je suis preneur

  4. #4
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 512
    Par défaut
    J'ai l'impression que l'essence même du "raccourci" n'est pas dans ce machin.
    Un raccourci, c'est pour réduire le nombre d'actions à faire dans une IHM pour accélérer le travail.
    Sous Windows (du moins si l'on respecte les guidelines), ces raccourcis sont affichés explicitement dans les menus de fenêtre et les menus contextuels.
    Ici, je ne vois aucunement cette intégration graphique.
    Un framework comme les MFC intègre directement la gestion des raccourcis dans les utilitaires de création des interfaces graphiques.
    Rendre ces raccourcis "customisables", c'est juste rendre des composants graphiques (menuItems) "customisables".
    Il n'y a pas une tambouille en sous-marin pour les 0.001% des utilisateurs qui ont retenus les 18 modes de base des 25 jeux de raccourcis, avant qu'un plugin simplifie ce capharnaüm.

  5. #5
    Membre du Club Avatar de lilivve
    Homme Profil pro
    Creative coding
    Inscrit en
    Mars 2018
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Creative coding
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mars 2018
    Messages : 7
    Par défaut
    Merci pour tes remarques Bacelar,
    Les 0.001% des utilisateurs ça ne va pas faire beaucoup, vu qu'on est 2 à utiliser cette application !
    (c'est une application de régie son/vidéo/animations pour un spectacle).
    L'interface graphique est faite avec ImGui, et j'ai bien ajouté ce qu'il faut pour faire apparaitre les raccourcis à côté des divers boutons , et les modifier.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Créer raccourci (ShortCut) pour mon application
    Par cp-08jhu dans le forum Android
    Réponses: 2
    Dernier message: 12/10/2012, 11h53
  2. créer raccourci clavier pour une application console
    Par aurelien3030 dans le forum C#
    Réponses: 6
    Dernier message: 08/03/2011, 18h03
  3. Réponses: 8
    Dernier message: 04/01/2008, 16h46
  4. [eclipse 3.0.1]Raccourci clavier pour changer de fichier
    Par partyboy dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 04/11/2004, 15h06
  5. [] Raccourci clavier pour bouton d'une barre d'outil
    Par Sébastien dans le forum VB 6 et antérieur
    Réponses: 12
    Dernier message: 24/03/2003, 17h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo