Scan

Faire jouer une vidéo sur Microsoft Surface. Déposer Microsoft Surface sur la vitre du scanner. Numériser.

surface scan 5x7

Play a video on Microsoft Surface. Place Microsoft Surface on the scanner bed. Scan.

Paintual, nouvelle interface presque prête

Parce que je suis trop heureux d’avoir enfin franchi ce problème d’interface qui m’a causé tant d’ennuis, voici un avant-goût de la nouvelle interface avec le code de Synergy (voir posts précédents). Je trouve que c’est plus beau et il y a des barres latérales qui se contractent pour laisser plus de place à la surface de dessin. Mais il y a aussi des pépins de rendu que j’ai à régler comme on peut voir dans la petite vidéo ci-dessous.

Ce qui manque au code de Synergy qui existait dans le code de XCeed Avalon, c’est un événement qui est déclenché à chaque fois que le focus change de document (que ce soit une plage de dessin ou un formulaire de saisie de données), chose que j’ai ajoutée un peut à la va vite dans Synergy. Ça va me demander aussi de changer le code du gestionnaire de la VisualPropertyPage, portion de code qui voit à ce que son contenu soit synchrone avec la plage de dessin correspondante et aussi qui empêche d’afficher deux instances de la VisualPropertyPage.

J’ai hâte de retourner au coeur du code de dessin mais les fonctionnalités d’interface que je tente d’ajouter pour l’instant m’apparaissent essentielles pour créer un programme un tant soit peu utilisable.

* * *

Because I’m too happy to have finally overcome this interface problem that was cause to so much trouble, here is a taste of the new interface using Synergy’s code (see previous posts). I find it more appealing, less cluttered, and there are sidebars that collapse to allow more space for the drawing surface. But there are also glitches that I have to fix as can be seen in the short video above.

What is missing from the Synergy code that existed in the XCeed Avalon component is an event that is triggered each time the focus changes document (whether it’s a drawing surface or a form), something that I added by fiddling Synergy’s code. It also requires me to change the code of the VisualPropertyPage manager, code that ensures that its content is synchronous with the corresponding drawing surface and also prevents the display of two instances of the VisualPropertyPage.

I cannot wait to get back to the the drawing code core, but the interface features I’m trying to add for the moment seem essential to me to create a program that has a minimum of user friendliness.

Paintual, interface

J’ai eu le goût à nouveau de voir si je pouvais régler le problème des “docking windows” pour lequel j’avais opté pour la solution de la composante Avalon de XCeed ( https://archive.codeplex.com/?p=avalondock ) qui ne me satisfaisait pas entièrement. J’avais trouvé le code de Ashish Kaila, son projet Synergy ( https://www.codeproject.com/Articles/140209/Building-a-Docking-Window-Management-Solution-in-W ) qui avait des options qui m’intéressaient davantage mais, si on se souvient (voir ici), je n’arrivais pas à l’utiliser dans mon projet.

Cette fois-ci, j’ai réussi, sans toutefois savoir pourquoi ça fonctionne alors que la fois d’avant ça ne voulait pas. Je devrai faire des recherches. Ce n’est pas une bonne idée d’inclure du code qui marche, qui marche pas, sans comprendre réellement pourquoi. Le jour où ça ne fonctionnera plus, je serai sérieusement embêté. La nouvelle importation du projet Synergy comporte tous les fichiers de l’exemple mis en ligne, y compris ce que je pense être un paquet de fichiers qui ne me sont pas utiles… quelque part là-dedans il y a la réponse à mon problème d’intégration. J’en parlerai à nouveau quand je trouverai.

Entre temps, je vais transposer le code du UI (interface utilisateur) de Avalon vers Synergy. Quand ça sera complété, une nouvelle version sera disponible sur GitHub.

D’ici là, vous pouvez jouer avec Visions of Chaos (le lien pour télécharger est tout au bas de la longue page du site). Le blogue qui y est lié vaut la peine d’être exploré en entier.

* * *

I decided to try again to see if I could solve the problem of docking windows for which I had opted for the solution of the Avalon component of XCeed (https://archive.codeplex.com/?p= avalondock) that did not satisfy me entirely. I had found Ashish Kaila’s code, his Synergy project (https://www.codeproject.com/Articles/140209/Building-a-Docking-Window-Management-Solution-in-W) that had options that were more interested but, if we remember (see here), I was unable to get it to work in my project.

This time I managed to get it working without exactly knowing why. I will have to do some research. It’s not a good idea to include code that works, then doesn’t and so on, while not really understanding why. The day it will not work, I will be seriously annoyed. The new Synergy project import includes all the files from the example posted online, including a bunch of file for which I do not see at first any use to my project… somewhere in those files is the answer to my integration problem. I’ll talk about it again when I find it.

In the meantime, I’m going to adapt the UI code that works with the Avalon component to get it to work with Synergy. When completed, a new version will be available on GitHub.

Until then, you can play with Visions of Chaos (the link to download is at the very bottom of the long page of the site). The related blog is also worth exploring in full.

 

Paintual, déblocage

J’ai enfin réussi à me sortir du problème où je n’arrivais pas à faire fonctionner la VisualPropertyPage lorsqu’il y avait plusieurs images chargées dans l’application. Dans le détail (mais pas trop), quand un utilisateur ouvrait une image et sélectionnait un outil (dans le cas qui m’intéresse pour l’instant est le QuickExtract [pouvoir sélectionner plusieurs fragments d’une image et les sauvegarder chacun avec un nom de fichier séquentiel]) et entrait les paramètres dans la VisualPropertyPage, qu’il ouvrait une deuxième image et entrait d’autres paramètres, le fait de retourner à la première image faisait perdre les paramètres sélectionnés grrrrr!

Je suis resté coincé longtemps tout simplement parce qu’une gestion d’événement, en l’occurrence le changement de focus d’une image vers une autre, n’était pas pris en charge par la bonne classe, c’est-à-dire que j’arrivais bien à lancer un événement “hé! l’utilisateur a mis le focus sur cette image-ci”  mais le code qui répondait et devait mettre à jour les infos dans la VisualPropertyPage n’était pas à la bonne place, ce qui occasionnait un paquet d’embrouilles que je tentais de résoudre et, finalement, en composant le diagramme de séquence UML pour mieux visualiser le tout, la solution toute simple m’a sauté aux yeux.

Les paramètres entrés dans la VisualPropertyPage sont passés aux propriétés de l’instance de l’outil ou de l’effet en cours. Je pouvais, pour les récupérer par la suite, simplement interroger ces propriétés, mais c’était devoir réinterroger les attributs de ces propriétés (ceux qui servent à construire la série de contrôles visuels de la VisualPropertyPage) et donc utiliser la réflexion (un processus très flexible et polyvalent mais plus lent). J’ai plutôt opté pour stocker les paramètres dans une collection séparée, pensant m’éviter l’utilisation abusive de la réflexion… un peu inutilement puisque de toute façon, reconstruire les contrôles de la VisualPropertyPage à chaque changement de focus demande d’interroger les attributs. Même si pour l’instant l’ensemble fonctionne, ça laisse beaucoup de place à améliorations.

Dans la vidéo ci-dessous on voit l’ouverture de deux images, l’entrée de paramètres différents pour chacune d’elles (sauvegarde des sélections dans des répertoires différents et attribution d’un préfixe unique pour chacune). On voit aussi qu’on peut passer d’une image à l’autre et les paramètres “suivent”.

Prochaine étape: profiter de cet outil que je viens de créer et, enfin, produire les centaines de fragments, d’extraits pour créer d’autres images. Probablement que si je m’étais tout simplement attelé à Photoshop et copié/sauvegardé les sélections j’aurais terminé en moins de temps que ce qui m’en a pris pour coder cette fonctionnalité. Il y de ces plaisirs de faire qui tombent dans l’irrationnel 🙂

Entre temps, la nouvelle version 0.0.5 est disponible sur GitHub 🙂

* * *

I finally managed to find a solution to the problem where I could not get the VisualPropertyPage running when there were several images loaded in the application. In detail (but not too much), when a user opened an image and selected a tool (in the case that interests me for now is the QuickExtract [select multiple fragments of an image and save each with a sequential file name]) and entered the parameters in the VisualPropertyPage, when another image is loaded and new parameters are entered, returning to the first image looses its parameter values grrrrr!

I was stuck for a long time simply because an event handler, in this case the change of focus from one image to another, was not supported by the right class, that is even if I had managed to launch an event “hey, the user has focused on this image” but the code that handled it and was responsible to update the information in the VisualPropertyPage was not in the right place, which caused the need to over-manage the code with multiple ambiguous states I was struggling to solve and finally, by composing the UML sequence diagram to visualize the whole thing, the simple solution revealed itself to me.

Parameters entered in the VisualPropertyPage are passed to the properties of the instance of the current tool or effect. In order to retrieve the values later, I could have simply queried these properties, but it was necessary to re-interrogate the attributes of these properties (those used to build the series of visual controls of the VisualPropertyPage) and therefore use reflection (a very flexible and versatile functionality but slower). I have instead opted to store the parameter values in a separate collection, thinking I could avoid to use reflection… a bit unnecessarily since, anyway, rebuilding the controls of the VisualPropertyPage at each change of focus request does require to query the attributes. Even if for now the whole thing works, there remains a lot of room for improvement.

In the video above we can see the opening of two images, the entry of different parameter values for each of them (saving selections in different directories and assigning a unique prefix for each). We also see that we can go from one image to another and the parameters are appropriately updated in the VisualPropertyPage.

Next step: enjoy this tool of mine and finally extract hundreds of image fragments, and save them to create new images. Probably if I had just used Photoshop and copied/saved the selections I would have finished in less time than what took me to code this feature. This is a case where working on something for the mere pleasure of it does fall into the irrational 🙂

Meanwhile, the new version 0.0.5 is available on GitHub 🙂