Chapitre 4

La construction de VOH v4

« 101 704 lignes »

Le marathon

Le développement de VOH v4 est un marathon. Pas un sprint de quelques semaines, mais un effort soutenu qui s'étale sur des dizaines de sessions de travail, numérotées comme des chapitres d'un feuilleton : Part 1, Part 2, Part 3... jusqu'à la Part 45 et au-delà. Chaque session suit le même rituel. David uploade le ZIP de la dernière version. Claude analyse le code, identifie l'état du projet, et David donne ses directives. Le développement avance par itérations rapides : une fonctionnalité, un test, un retour, une correction, une nouvelle fonctionnalité.

Le versionnement est précis, presque obsessionnel. Chaque modification est numérotée : 3.9.28, 3.11.0, 3.25.0, 3.31.x, 3.32.x, 3.33.3, 3.38.37, 3.38.83, 3.59.05, 3.84.00, 3.93.04... puis 4.03.85, 4.12.49, 4.13.00, 4.18.62, 4.18.72, 4.22.xx, 4.29.xx, 4.30.10, 4.32.20, 4.34.27. Chaque numéro raconte une histoire.

L'architecture

L'architecture de VOH v4 est ambitieuse. Le projet est structuré en deux couches principales :

Le Core (le moteur)
C'est le cœur du logiciel. Autonome, indépendant, il fonctionne seul sans l'interface utilisateur. Il gère tout ce qui touche à la logique métier : création et manipulation d'objets, rendu sur canvas, sélection, historique, clipboard, événements. Le Core est composé de 10 modules, chacun avec une responsabilité claire :
Core-EventEmitter.js        — Système pub/sub d'événements
Core-BaseObject.js          — Classe objet de base
Core-ObjectManager.js       — Gestion CRUD des objets
Core-SelectionManager.js    — Gestion de la sélection
Core-HistoryManager.js      — Undo/redo
Core-ClipboardManager.js    — Copier/couper/coller
Core-InteractionManager.js  — Souris, clavier, drag
Core-RenderEngine.js        — Rendu canvas multi-couches
Core-VisualObjectsHandler.js — Fichier principal, API publique
Core-CodeTranslations.js    — Génération de code multilingue
L'Editor (l'interface)
L'Editor dépend du Core, jamais l'inverse. C'est l'interface utilisateur complète : panneaux d'édition, modales, menus, barre d'outils, panneau de propriétés, système de traduction, gestion de fichiers. L'Editor est composé de 13 fichiers :
Editor.html              — Structure HTML et CSS principal
Ui-Properties.js         — Panneau de propriétés des objets
Ui-i18n.js               — Traductions (FR, EN, DE)
Ui-Modals.js             — Fenêtres modales
Ui-ContextMenu.js        — Menu clic droit
Ui-Files.js              — Import/export fichiers
Ui-Settings.js           — Paramètres du logiciel
Ui-Elements.js           — Éléments d'interface réutilisables
Ui-Events.js             — Gestion des événements UI
Ui-Panels.js             — Panneau des objets (TreeView)
Ui-Menus.js              — Menus principaux
Ui-Tools.js              — Outils (alignement, distribution)
Ui-App.js                — Initialisation de l'application

Cette séparation Core/Editor n'est pas un luxe architectural — c'est une décision stratégique. Le Core doit pouvoir être réutilisé dans d'autres contextes : un éditeur de niveaux de jeux, un designer d'interfaces, un éditeur d'organigrammes. L'Editor est juste UNE interface possible parmi d'autres.

Les grandes étapes

Le développement de la v4 peut se découper en grandes phases, chacune apportant son lot de fonctionnalités majeures :

Phase 1 : Les fondations (v3.x)
Le système de base est posé : création d'objets, déplacement, redimensionnement, sélection, undo/redo, sauvegarde JSON. Le Core est fonctionnel et autonome.
Phase 2 : La personnalisation visuelle
Les poignées deviennent personnalisables : 11 types sélectionnables (8 de redimensionnement + rotation + pivot + tout), 21 icônes vectorielles, dégradés et ombres configurables par poignée, curseurs personnalisés, presets de visibilité. Les labels apparaissent : texte BBCode, 9 positions prédéfinies, fond avec opacité/padding/arrondi, ombre portée. Les tooltips sont ajoutés : BBCode, multi-images (avant-plan et arrière-plan), double ombre (texte et cadre).
Phase 3 : Les images et le style avancé
Le système multi-images permet d'attacher plusieurs images par objet, chacune avec son propre z-index, sa rotation, son ombre. Les dégradés passent de 2 à 6 couleurs. Les dégradés radiaux sont ajoutés avec centre et rayon configurables.
Phase 4 : Le système d'épingle et les connexions
Le système d'épingle (pin) permet d'attacher un objet à un autre. Les connexions entre objets sont implémentées : lignes droites, courbes, coudes, avec points d'ancrage personnalisables, flèches, et labels.
Phase 5 : Les pages et l'interface avancée
Le système de pages permet d'avoir plusieurs « scènes » dans un même projet, chacune avec ses propres objets et son historique. L'InterfaceBuilder ajoute des contrôles HTML (boutons, sliders, inputs) au-dessus du canvas.
Phase 6 : L'export et la génération de code
Trois modes de génération de code : API seul, HTML + API, page HTML avec testeur intégré. L'utilisateur crée visuellement et récupère le code correspondant.
Phase 7 : Les données utilisateur et le format .voh
Le système userData permet de stocker 17 types de données personnalisées dans les objets. Le format de sauvegarde passe au ZIP (.voh) avec déduplication SHA-256 des médias pour optimiser la taille des fichiers.
Phase 8 : L'interpréteur et l'EventMaker
VOH sait générer du code. L'utilisateur crée ses objets visuellement, et le logiciel produit le code correspondant en trois modes : API seul, HTML + API (avec l'interface pages et panneaux), ou HTML avec testeur intégré. Mais un problème fondamental se pose : à quoi sert de générer du code si l'utilisateur ne peut rien en faire ?
Le fichier HTML généré en mode HTML + API contient des
balises <script src="../Core/..."> qui pointent vers les 16 modules Core. Si l'utilisateur ouvre ce fichier HTML tout seul, rien ne se passe — les fichiers Core ne sont pas là. Et les inclure dans le HTML signifierait distribuer le code source du Core en clair. Hors de question pour David — il veut protéger son code. D'où l'idée de l'interpréteur. Le concept est simple : un programme EXE autonome avec le Core caché à l'intérieur. L'utilisateur génère son fichier (sans le Core), le donne à l'interpréteur, et celui-ci l'exécute. Comme VLC.exe lit un fichier vidéo : le moteur est dans le lecteur, pas dans le fichier. Une option « Pour interpréteur VOH (sans Core) » est ajoutée dans le panneau Code, onglet HTML + API. Quand elle est cochée, le HTML est généré sans les scripts Core— il ne fonctionne qu&#x27;avec l&#x27;interpréteur. Un fichier VOH-Runtime.html est créé (v4.12.49). C'est un fichier HTML unique de 1,4 Mo avec les 16 modules Core intégrés. Deux modes : API (coller du code JavaScript et l'exécuter) et HTML (charger un export complet). Dans le navigateur, le mode API fonctionne parfaitement — le code s'exécute, les objets apparaissent sur le canvas. Mais le mode HTML coince. Quand le fichier HTML + API de l'utilisateur est chargé dans un iframe, celui-ci ne peut pas accéder au Core du parent. C'est une sandbox JavaScript — les deux pages sont isolées, elles ne se parlent pas. Le code API seul marche (il s'exécute directement dans le contexte du Core), mais le HTML avec l'interface (les panneaux, les pages, les contrôles) ne marche pas — il a besoin du Core et ne le trouve pas. David veut aussi un EXE, pas un fichier HTML. La tentative de compiler l'interpréteur avec Tauri ajoute une couche de problèmes : les chemins des fichiers Core se cassent une fois compilés, le drag & drop de fichiers sur l'EXE ne fonctionne pas. Une version « Constructor » à plat (tous les fichiers dans un seul dossier) est tentée pour contourner les problèmes de chemins. Ça n'aide pas assez. C'est l'un des moments les plus frustrants du développement de la v4. Le concept est bon, la motivation est claire (protéger le code + rendre les exports utilisables), mais la technique résiste. L'interpréteur reste fonctionnel pour le code API en mode navigateur, mais le mode HTML complet et le rêve de l'EXE autonome devront attendre la v5 et Neutralinojs. En parallèle, le prototype de l'EventMaker — un éditeur visuel de règles interactives, style RPG Maker — est créé comme preuve de concept pour la v5.

Le panneau de propriétés : un monstre de complexité

Le panneau de propriétés est peut-être la partie la plus complexe de l'interface. Chaque objet a des dizaines de propriétés modifiables : position, taille, rotation, couleurs, bordures, ombres, dégradés, images, labels, tooltips, poignées, ancres, contraintes, données personnalisées... Et tout doit fonctionner en multi-sélection. Quand l'utilisateur sélectionne plusieurs objets, le panneau doit afficher les valeurs communes et permettre de les modifier toutes en même temps.

Le Ui-Properties.js finit par devenir le plus gros fichier du projet, dépassant les 14 000 lignes. Un monstre qui gère des centaines de champs d'interface, chacun avec ses événements, ses validations, ses traductions dans 3 langues, ses tooltips, et son synchronisation avec le Core.

Les thèmes

VOH supporte 4 thèmes visuels pour son interface. Le thème « Doux » avec son accent #8292d4, son fond #f2f2f2 et ses panneaux crème #fff5eb est le favori de David. Un thème sombre est aussi disponible, avec des corrections spécifiques pour les fonds des champs de saisie.

Le système de thèmes est profond : pas juste des couleurs, mais des variables CSS complètes avec le préfixe --voh- qui contrôlent chaque élément de l'interface.

Les 3 langues

Tout le logiciel est traduit en français, anglais et allemand. Chaque label, chaque tooltip, chaque message d'erreur, chaque élément de l'interface. L'allemand est un hommage à STARGÅTE, le co-créateur d'Editors Factory.

Chaque nouveau champ ajouté doit être traduit dans les 3 langues avant la livraison. Pas après. Pas « on verra plus tard ». Avant.

La performance

Quand le canvas contient des centaines d'objets, la performance devient critique. Lors de la Part 31, un système de cache intelligent est implémenté pour réduire les allocations mémoire de 99.99% pendant les interactions souris. Le rendu est optimisé pour ne redessiner que ce qui a changé.

Avec 500 objets sur le canvas, le logiciel reste fluide — un résultat qui demande une attention constante aux détails d'implémentation : optimisation du DOM, pooling d'objets, évitement des allocations inutiles dans les boucles serrées.

Les chiffres

L'utilisateur de Windows 7

Un jour, un développeur nommé Mat.M sur le forum developpez.net s'intéresse à VOH. Il essaie l'exécutable. Ça plante.

Le diagnostic est rapide : Mat.M est sous Windows 7, un système d'exploitation qui n'est plus supporté par les technologies modernes. Il utilise Visual C++ 6.0 — un outil sorti en 1998 — et les DLLs nécessaires n'existent pas sur sa machine.

David est tiraillé. C'est son premier utilisateur externe qui teste réellement le logiciel. Mais adapter le code pour un OS mort serait une perte de temps colossale.

La décision est pragmatique : Windows 10 minimum. Mat.M comprendra — c'est un développeur expérimenté, il connaît la réalité des dépendances système. Et David ne peut pas se permettre de sacrifier des semaines de développement pour les 3% d'utilisateurs restés sur Windows 7.

Ce qui est intéressant, c'est que Mat.M reste intéressé par le projet. Un profil technique sérieux qui s'intéresse à VOH — c'est plutôt bon signe.

Les 8 formes d'objets et les 20 formes de poignées

VOH propose 8 formes d'objets de base que l'utilisateur peut placer sur le canvas : rectangle, ellipse, triangle, losange, pentagone, étoile, ligne et texte. Chaque forme est dessinée en vectoriel, avec bordure personnalisable, remplissage uni ou en dégradé, et ombres.

Les poignées d'objets ont encore plus de variété : 20 formes différentes, du simple carré au cercle en passant par le triangle, le losange, l'hexagone, l'étoile, et des formes plus exotiques. Les 21 icônes vectorielles (déplacement, redimensionnement, rotation, pivot, ancrage) accompagnent ces formes pour indiquer visuellement la fonction de chaque poignée.

Les 11 types de poignées sélectionnables sont : 8 poignées de redimensionnement (les 4 coins + les 4 milieux de bord), la poignée de rotation, la poignée pivot (centre de rotation), et « toutes » en même temps. Des presets de visibilité permettent d'activer rapidement des combinaisons courantes (coins seulement, bords seulement, tout).

Les contraintes

Chaque objet peut être soumis à des contraintes qui limitent ses transformations. Le système est granulaire :

Les modes de rotation

La rotation — cette fonctionnalité « impossible » selon STARGÅTE — est implémentée avec trois modes distincts :

Mode individuel (individual)
Chaque objet tourne autour de son propre pivot. Si trois objets sont sélectionnés, chacun tourne sur place.
Mode collectif (collective)
Tous les objets sélectionnés tournent autour du centre géométrique de la sélection, comme un groupe rigide.
Mode unifié (unified)
En multi-sélection, un seul pivot partagé est utilisé. L'utilisateur peut repositionner ce pivot commun.

Le menu contextuel avancé

Le clic droit sur le canvas ou sur un objet ouvre un menu contextuel riche avec des sous-menus en cascade :

L'opacité du remplissage et de la bordure

Ajoutée dans la version 4.18.62, cette fonctionnalité permet de régler l'opacité du remplissage et de la bordure indépendamment. Deux sliders dans l'interface contrôlent fillColorOpacity et strokeColorOpacity (de 0 à 1). L'opacité fonctionne aussi avec les dégradés, ce qui permet des effets visuels sophistiqués.

Le système userData en détail

Le panneau « Données » est un petit monde en soi. Il permet de stocker 17 types de données personnalisées dans chaque objet :

L'interface est soignée : menu contextuel sur chaque donnée, renommage par double-clic, badge de type coloré, affichage de la taille en Ko pour les fichiers et médias. 17 méthodes API complètent le système : setUserData, getUserData, removeUserData, hasUserData, clearUserData, getAllUserData, mergeUserData, getUserDataType, getUserDataKeys, getUserDataCount, copyUserData...

Les types sont détectés automatiquement quand c'est possible (un nombre reste un nombre, une couleur hexadécimale est identifiée), et l'utilisateur peut forcer le type explicitement pour les cas ambigus.

Le MediaStore et le format .voh

À l'origine, les projets VOH sont sauvegardés dans un simple fichier JSON. Ça fonctionne bien tant qu'il n'y a que des formes géométriques et du texte. Mais dès qu'on ajoute des images et des vidéos, le JSON explose : chaque média est converti en data URI Base64 et stocké directement dans le fichier. Un projet avec quelques vidéos produit un JSON de plusieurs centaines de mégaoctets — lent à sauvegarder, lent à charger, impossible à partager.

D'où le passage au format .voh : un fichier ZIP intelligent. Les données du projet (objets, propriétés, pages) restent en JSON à l'intérieur du ZIP, mais les médias sont extraits et stockés comme fichiers séparés dans l'archive, avec déduplication.

Le système utilise une double déduplication :

Les noms de fichiers sont lisibles : « Video_a1b2c3d4.mp4 » plutôt qu'un hash incompréhensible.

Une protection anti-crash mémoire a été ajoutée après qu'un projet avec 27 objets contenant chacun une vidéo de 58 Mo ait fait exploser la RAM. Les data URIs sont extraits et remplacés par des placeholders avant l'export, puis restaurés via try/finally.

La version Constructor

En parallèle de la version standard (avec ses dossiers Core/ et Editor/), une version « Constructor » est créée. C'est une version à structure plate — tous les fichiers dans un seul dossier, Editor.html renommé en index.html, chemins des scripts adaptés pour pointer vers la racine.

Cette version n'est pas destinée à la distribution. Elle existe uniquement pour David, afin de pouvoir compiler le projet avec Tauri et en faire un EXE de démonstration.

L'audit exhaustif du Core

Aux alentours de la version 4.18.72, David demande à Claude de relire l'intégralité du Core. Pas un survol, pas un résumé — une lecture ligne par ligne des 16 fichiers, soit environ 36 500 lignes de code. L'objectif : vérifier la qualité du code, traquer les bugs cachés, les incohérences, le code mort, avant de continuer à empiler des fonctionnalités dessus.

L'opération s'étale sur deux sessions (parts 38 et 39). Claude passe chaque fichier au peigne fin et produit un rapport détaillé.

Le bilan :

Cet audit est un moment charnière. C'est en regardant les 36 500 lignes au microscope que les limitations structurelles de la v4 deviennent évidentes : des fichiers trop gros, une API qui a grandi de manière organique sans plan global, des conventions incohérentes. C'est là que l'idée d'une refonte — la v5 — commence à germer sérieusement.