9.0 KiB
Analyse Comparative - Implémentation Roue Chromatique
📊 Comparaison des Approches
Solution Actuelle (Implémentée)
Type: Grille de boutons 12×12 simulant une roue HSL
Implémentation:
// Grille de boutons St.Button disposés en cercle
// Chaque bouton = une couleur HSL précalculée
const size = 12; // 12×12 = 144 cellules
const cellSize = 18px; // Boutons cliquables
// 113 couleurs effectivement affichées (cercle)
Avantages réels ✅:
- ✅ Fonctionne immédiatement (St.Button = composant natif éprouvé)
- ✅ Très stable (pas de gestion Canvas/Cairo complexe)
- ✅ Compatible GNOME 48 (API St bien documentée)
- ✅ Code simple (~70 lignes pour la roue)
- ✅ Débogage facile (chaque bouton = élément inspectable)
- ✅ Performance correcte (113 boutons statiques, pas de rendu temps réel)
Inconvénients ⚠️:
- ⚠️ Résolution limitée (113 couleurs vs. millions théoriques)
- ⚠️ Granularité fixe (pas de sélection entre deux boutons)
- ⚠️ Mémoire (113 objets St.Button créés)
- ⚠️ Pas de feedback visuel continu (pas de curseur sur la roue)
Option A Recommandée (Synthèse)
Type: Roue HSV custom avec Clutter.Canvas
Implémentation proposée:
// Canvas interactif avec rendu Cairo
const canvas = new Clutter.Canvas({ width: 200, height: 200 });
canvas.connect('draw', (canvas, cr) => {
// Dessiner roue HSV avec Cairo
// Pour chaque pixel: calculer H (angle) et S (rayon)
});
// Capturer clics et drag pour position continue
Avantages théoriques ✅:
- ✅ Résolution infinie (sélection pixel par pixel)
- ✅ Feedback visuel (curseur, preview en temps réel)
- ✅ Look professionnel (roue lisse, dégradés)
- ✅ Mémoire optimale (un seul canvas vs 113 boutons)
Inconvénients réels ⚠️:
- ⚠️ Complexité code (~200-300 lignes pour roue + interactions)
- ⚠️ Performance Cairo (rendu temps réel à optimiser)
- ⚠️ Bugs potentiels (gestion événements souris, edge cases)
- ⚠️ Maintenance (code custom à déboguer)
- ⚠️ Non fonctionnel actuellement (notre tentative St.DrawingArea a échoué)
🔬 Analyse de Notre Tentative Canvas (Échec)
Ce qui n'a pas fonctionné
Code initial:
const wheelCanvas = new St.DrawingArea({ width: 200, height: 200 });
wheelCanvas.connect('repaint', (area) => {
this._drawColorWheel(area); // Rendu Cairo
});
wheelCanvas.reactive = true;
wheelCanvas.connect('button-press-event', ...) // ❌ Jamais déclenché
Problèmes identifiés:
- St.DrawingArea non interactive sous GNOME Shell 48
- Événements souris ignorés malgré
reactive: true - Documentation manquante sur DrawingArea + events
Pourquoi Clutter.Canvas serait différent:
Clutter.Canvasest l'API officielle pour rendu customSt.DrawingAreaest un wrapper qui peut avoir des limitations- Nécessite parent
Clutter.Actoraveccontent = canvas
🎯 Recommandations par Cas d'Usage
Cas 1: Vous voulez que ça fonctionne MAINTENANT ✅
→ Gardez la grille de boutons actuelle
Raisons:
- Fonctionne déjà (testable immédiatement)
- 113 couleurs = largement suffisant pour un clavier RGB
- Code stable et maintenable
- Zéro risque de régression
Améliorations possibles:
- Augmenter la grille (14×14 = 153 couleurs, cellSize: 16px)
- Ajouter hover effect (bordure blanche au survol)
- Ajouter tooltip avec valeurs RGB sur chaque bouton
Cas 2: Vous voulez la "vraie" roue HSV (Option A) 🎨
→ Implémentez Clutter.Canvas
Plan d'action:
- Créer le canvas:
const canvas = new Clutter.Canvas({ width: 200, height: 200 });
const actor = new Clutter.Actor({
content: canvas,
width: 200,
height: 200,
reactive: true
});
-
Rendu Cairo (fonction
_drawHSVWheel):- Boucle polaire: angle (H) × rayon (S)
- Conversion HSV(H, S, 1.0) → RGB
- Cairo:
cr.setSourceRGB(r, g, b)+cr.arc(x, y, 1, 0, 2π)
-
Interactions:
actor.connect('button-press-event', (actor, event) => {
const [x, y] = event.get_coords();
// Convertir (x, y) → (angle, rayon) → (H, S)
// Appliquer couleur
});
- Optimisations:
- Cache l'image de la roue (redessiner uniquement le curseur)
- Utiliser
canvas.invalidate()au lieu de redessiner tout
Temps estimé: 4-6 heures de développement + debug
Risques:
- Événements souris mal gérés (comme avec DrawingArea)
- Performance dégradée si mal optimisé
- Bugs visuels (antialiasing, bords)
Cas 3: Vous voulez le meilleur des deux mondes 🌟
→ Approche hybride
Solution recommandée:
┌─────────────────────────────────┐
│ [Bouton] Roue | Sliders │ ← Toggle
├─────────────────────────────────┤
│ MODE ROUE: │
│ • Grille 12×12 (actuel) │ ← Sélection rapide
│ │
│ MODE SLIDERS: │
│ • Slider H (Hue): 0-360° │ ← Affinage précis
│ • Slider S (Sat): 0-100% │
│ • Slider V (Val): 0-100% │
│ │
│ Aperçu: [████] RGB(255,128,64) │
└─────────────────────────────────┘
Avantages:
- Roue pour sélection rapide visuelle
- Sliders HSV pour ajustement fin
- Deux modes répondent à tous les besoins
Code minimal:
// Ajouter 3 sliders HSV dans _buildRGBSliders()
const hueSlider = new Slider.Slider(hue / 360);
const satSlider = new Slider.Slider(sat);
const valSlider = new Slider.Slider(val);
// Callback: convertir HSV → RGB puis appliquer
📋 Décision Recommandée
Pour votre usage (clavier RGB ASUS):
Option finale: Conserver grille 12×12 + ajouter sliders HSV ✅
Justification:
-
Grille actuelle suffit largement:
- 113 couleurs > largement assez pour explorer la palette
- Clics directs = UX immédiate
- Stable et fonctionnel
-
Sliders HSV ajoutent la précision:
- Affiner une teinte exacte (H: 0-360°)
- Contrôler saturation (couleur vive vs pastel)
- Contrôler valeur/luminosité (sombre vs clair)
-
Pas besoin de Canvas custom:
- Trop complexe pour le bénéfice apporté
- Risque de bugs > gain UX marginal
- 113 couleurs + sliders HSV = 100% des besoins couverts
🔧 Plan d'Action Proposé
Étape 1: Améliorer la grille actuelle (30 min)
// Hover effect
button.connect('enter-event', () => {
button.style += 'border: 2px solid white;';
});
// Tooltip RGB
button.set_tooltip_text(`RGB(${rgb.r}, ${rgb.g}, ${rgb.b})`);
Étape 2: Ajouter sliders HSV (1-2h)
_buildHSVSliders() {
// Convertir RGB actuel → HSV
const hsv = this._rgbToHsv(this._currentR, this._currentG, this._currentB);
// 3 sliders H, S, V
const hSlider = this._createSlider('Teinte (H)', hsv.h, ...);
const sSlider = this._createSlider('Saturation (S)', hsv.s, ...);
const vSlider = this._createSlider('Luminosité (V)', hsv.v, ...);
// Callback: HSV → RGB puis appliquer
}
Étape 3: Mode toggle roue/HSV (30 min)
- Bouton de bascule: [Roue] ↔ [HSV]
- Même principe que roue ↔ RGB actuel
📊 Tableau Comparatif Final
| Critère | Grille Boutons (Actuel) | Canvas HSV (Option A) | Hybride Roue+HSV |
|---|---|---|---|
| Complexité code | ⭐⭐ (simple) | ⭐⭐⭐⭐⭐ (complexe) | ⭐⭐⭐ (moyenne) |
| Stabilité | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ (bugs possibles) | ⭐⭐⭐⭐⭐ |
| Précision couleur | ⭐⭐⭐ (113 couleurs) | ⭐⭐⭐⭐⭐ (infini) | ⭐⭐⭐⭐⭐ (roue+sliders) |
| UX visuelle | ⭐⭐⭐⭐ (clair) | ⭐⭐⭐⭐⭐ (magnifique) | ⭐⭐⭐⭐⭐ |
| Performance | ⭐⭐⭐⭐ | ⭐⭐⭐ (rendu temps réel) | ⭐⭐⭐⭐ |
| Temps dev | ✅ Fait | 4-6h | 2-3h |
| Maintenance | ⭐⭐⭐⭐⭐ | ⭐⭐ (code custom) | ⭐⭐⭐⭐ |
🎯 Conclusion
Recommandation Finale: Grille actuelle + Sliders HSV 🏆
Pourquoi:
- ✅ Temps de développement minimal (2-3h vs 4-6h Canvas)
- ✅ Stabilité maximale (composants St natifs)
- ✅ Précision totale (sliders HSV 0-360° / 0-100%)
- ✅ UX optimale (sélection rapide + affinage)
- ✅ Maintenabilité (code simple, pas de Cairo custom)
Prochaine étape: Souhaitez-vous que j'implémente les sliders HSV pour compléter la grille actuelle ?
Cela ajoutera:
- Slider Teinte (H): 0-360° avec dégradé arc-en-ciel
- Slider Saturation (S): 0-100% (gris → couleur vive)
- Slider Luminosité (V): 0-100% (noir → couleur claire)
- Mode toggle pour passer de Roue → HSV → RGB