Files
GameTime/.ideai/tickets/176/carnet.md

5.1 KiB

issueRef, version, updatedBy, updatedAt
issueRef version updatedBy updatedAt
#176 5
kind agent_id
agent 57695b92-24d0-4876-837c-76116e70a6ae
1785321673401

#176 — Cadrage UX (2026-07-29)

Statut : cadrage exploitable, nouveau lot, app téléphone, lib/presentation/workout_execution_screen.dart, widget _TimedStepBody (L2907-2963), rendu dans _CurrentStepPane (branche générale, L2811-2838, Expanded(child: step.type == time ? _TimedStepBody(...) : ...)).

Constat, vérifié en lecture directe

_TimedStepBody est placé dans un Expanded par son parent (toute la hauteur disponible lui est allouée), mais à l'intérieur de ce widget rien n'exploite cet espace :

Column(  // pas de mainAxisAlignment.center, pas de Expanded interne, pas de FittedBox
  children: [
    Text('Objectif : Xs'),
    Center(child: Text(remainingLabel, style: displayMedium)),  // taille fixe, non scalable
    if (!running) [...'Chrono prêt'..., FilledButton 'Lancer'],
  ],
)

Le Text(remainingLabel) a une taille de police fixe (displayMedium), la Column s'aligne en haut (comportement par défaut) : tout l'espace du Expanded non consommé par le contenu à taille naturelle reste vide en bas. Résultat : le chrono reste petit que le bouton Lancer soit visible ou non, et une fois le chrono démarré (running == true, le bloc Lancer/Chrono prêt disparaît), l'espace libéré n'est récupéré par personne — comportement exactement décrit par le ticket.

À comparer avec _RepsWithStopwatchScoreStepBody (L2965+) et le bloc Expanded → LayoutBuilder → FittedBox(scaleDown) → SizedBox(hauteur de référence fixe) déjà utilisé en L2740-2772 pour dimensionner un contenu à une zone variable : ce pattern existe déjà dans ce fichier, _TimedStepBody ne le reprend pas.

Comportement attendu

Le chrono (et le bouton Lancer quand il est visible) doivent occuper tout l'espace vertical disponible dans le Expanded parent, dans les deux états :

  • Avant démarrage (!running) : chrono + Chrono prêt (si prêt) + bouton Lancer, empilés et centrés, mis à l'échelle ensemble pour remplir la zone disponible (largeur et hauteur).
  • Après démarrage (running) : le bloc Chrono prêt/Lancer disparaît (inchangé), et le chrono seul se remet à l'échelle pour regrandir et occuper tout l'espace libéré — pas de saut brutal de layout, juste une nouvelle mise à l'échelle du même mécanisme.

Implémentation recommandée

Réutiliser le mécanisme FittedBox(fit: BoxFit.contain) déjà présent dans ce fichier (au lieu de BoxFit.scaleDown utilisé ailleurs, qui ne permet que de rétrécir — ici on veut aussi agrandir) :

Column(
  crossAxisAlignment: CrossAxisAlignment.stretch,
  children: [
    Text('Objectif : ${_formatShortSeconds(step.defaultTargetValue)}'),  // inchangé, taille fixe
    const SizedBox(height: 4),
    Expanded(                                    // NOUVEAU : réclame tout l'espace restant
      child: LayoutBuilder(
        builder: (context, c) => FittedBox(
          fit: BoxFit.contain,                    // scale up ET down, contrairement à scaleDown
          child: SizedBox(
            width: c.maxWidth,
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Text(remainingLabel, style: /* displayMedium, référence */),
                if (!running) ...[
                  const SizedBox(height: 8),
                  if (readyToStart) Text('Chrono prêt', ...),
                  const SizedBox(height: 4),
                  FilledButton.icon(onPressed: onStartTimer, icon: Icons.play_arrow, label: 'Lancer'),
                ],
              ],
            ),
          ),
        ),
      ),
    ),
  ],
)
  • Le FittedBox(BoxFit.contain) prend le bloc de référence (chrono seul, ou chrono + libellé + bouton selon l'état) et le met à l'échelle pour remplir exactement la largeur ET la hauteur du Expanded — c'est ce même mécanisme qui fait automatiquement grandir le chrono quand le bouton disparaît : le bloc de référence devient plus petit (moins d'enfants), donc le facteur d'échelle appliqué par FittedBox augmente pour combler le même espace disponible.
  • Le bouton Lancer grandit avec le reste (proportionnellement) tant qu'il est visible — cohérent avec la demande explicite du ticket (« chrono + bouton commencer prennent la place disponible »).
  • Point de vigilance dev : choisir une taille de référence (police du Text(remainingLabel), hauteur du bouton) qui donne un rendu correct au repos (échelle ≈ 1) sur la taille d'écran de référence du projet, quitte à ajuster ces valeurs empiriquement — le FittedBox absorbe l'écart, mais des proportions de référence déséquilibrées donneraient un mauvais rendu même mis à l'échelle. Ne pas plafonner l'échelle maximale (pas de scaleDown) : la demande explicite est que ça puisse grandir au-delà de la taille actuelle.
  • Ne touche pas au cas hasTimedWithManualScore (L2725-2809, _TimedStepWithManualScoreBody) : ce lot ne concerne que le chrono seul, sans score manuel, branche générale de _CurrentStepPane.