-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Overview
Implement a practice timer that adapts its display format based on elapsed time (M:SS for sessions under an hour, H:MM:SS for longer sessions). The timer will use a toggle button that switches between play and pause states, creating an intuitive and clean interface for students.
Current State
The specification outlines the need for a basic session timer in Phase 1 (MVP). No timer implementation currently exists.
Requirements
Timer Display
The timer should show elapsed practice time in a format that adapts to the duration:
- Under 60 minutes: "M:SS" (e.g., "5:23")
- Over 60 minutes: "H:MM:SS" (e.g., "1:05:23")
- No leading zeros for the leftmost digit
- Updates every second while running
Controls
The interface will feature two buttons:
-
Toggle Button (Play/Pause)
- Single button that alternates between two states
- Shows play icon (▶) when timer is paused
- Shows pause icon (⏸) when timer is running
- Icon always indicates the next available action
-
Reset Button
- Returns timer to 0
- Enabled only when elapsed time is greater than 0
Technical Implementation
The implementation uses a single boolean state variable to manage the timer's running state, making the code clear and maintainable. Here's the GDScript implementation:
extends Node
# Core state variables
var playing: bool = false
var elapsed_seconds: int = 0
# Preload button textures
@onready var play_texture = preload("res://assets/play_icon.png")
@onready var pause_texture = preload("res://assets/pause_icon.png")
# Node references
@onready var timer: Timer = $Timer
@onready var time_label: Label = $TimeLabel
@onready var toggle_button: TextureButton = $ToggleButton
@onready var reset_button: TextureButton = $ResetButton
func _ready() -> void:
# Initialize UI state
update_toggle_button()
timer.timeout.connect(_on_timer_timeout)
reset_button.disabled = true
func _on_toggle_pressed() -> void:
# Toggle between play and pause states
playing = !playing
# Update timer and button states
timer.paused = !playing
update_toggle_button()
func _on_reset_pressed() -> void:
# Reset timer state
elapsed_seconds = 0
playing = false
# Update UI
update_display()
update_toggle_button()
reset_button.disabled = true
timer.paused = true
func _on_timer_timeout() -> void:
elapsed_seconds += 1
update_display()
reset_button.disabled = false
func update_toggle_button() -> void:
# Update button icon to show next available action
toggle_button.texture_normal = pause_texture if playing else play_texture
func update_display() -> void:
# Format display based on elapsed time
if elapsed_seconds < 3600:
# Under one hour: M:SS
var minutes := elapsed_seconds / 60
var seconds := elapsed_seconds % 60
time_label.text = "%d:%02d" % [minutes, seconds]
else:
# Over one hour: H:MM:SS
var hours := elapsed_seconds / 3600
var minutes := (elapsed_seconds % 3600) / 60
var seconds := elapsed_seconds % 60
time_label.text = "%d:%02d:%02d" % [hours, minutes, seconds]
Scene Setup
Create a scene with the following node structure:
Timer (Root Node)
├── Timer (Node)
├── TimeLabel (Label)
├── ToggleButton (TextureButton)
└── ResetButton (TextureButton)
The Timer node should be configured with:
- One-second timeout
- Autostart disabled
- Process mode set to handle pausing
Design Benefits
The toggle button pattern offers several advantages:
-
Simplified State Management: Using a single
playing
boolean as the source of truth makes the code easier to maintain and debug. The timer's state is always clear and consistent. -
Intuitive User Interface: The button always shows the next available action, making it immediately clear to students what will happen when they click. This reduces the cognitive load during practice sessions.
-
Clean Code Structure: The toggle pattern clearly identifies the relationship between the user action (button press), state change (playing boolean), and visual feedback (button icon), making the code flow easy to follow.
Testing Requirements
-
Toggle Functionality
- Button correctly alternates between play and pause states
- Icon updates to show the next available action
- Timer starts and stops appropriately
-
Timer Display
- Correct format for times under one hour
- Proper transition to H:MM:SS at one hour
- Accurate timekeeping
-
Reset Functionality
- Returns to 0 and updates display
- Disables reset button when timer is at 0
- Properly resets playing state and button icon
Success Criteria
- Timer accurately tracks practice time
- Toggle button provides clear, intuitive control
- Display format adapts appropriately to elapsed time
- Interface responds immediately to user input