11package com.github.akshayashokcode.devfocus.toolWindow
22
3+ import com.github.akshayashokcode.devfocus.model.PomodoroMode
34import com.github.akshayashokcode.devfocus.model.PomodoroSettings
45import com.github.akshayashokcode.devfocus.services.pomodoro.PomodoroTimerService
6+ import com.github.akshayashokcode.devfocus.ui.components.CircularTimerPanel
7+ import com.github.akshayashokcode.devfocus.ui.components.SessionIndicatorPanel
58import com.github.akshayashokcode.devfocus.ui.settings.PomodoroSettingsPanel
69import com.intellij.openapi.project.Project
710import com.intellij.ui.components.JBPanel
811import kotlinx.coroutines.*
912import kotlinx.coroutines.flow.collectLatest
10- import java.awt.BorderLayout
11- import java.awt.FlowLayout
13+ import java.awt.*
1214import javax.swing.*
1315
1416class PomodoroToolWindowPanel (private val project : Project ) : JBPanel<JBPanel<*>>(BorderLayout ()) {
1517
1618 private val timerService = project.getService(PomodoroTimerService ::class .java) ? : error(" PomodoroTimerService not available" )
1719
18- private val timeLabel = JLabel (" 25:00" ).apply {
20+ // Mode selector
21+ private val modeComboBox = JComboBox (PomodoroMode .entries.toTypedArray()).apply {
22+ selectedItem = PomodoroMode .CLASSIC
23+ }
24+
25+ // Info label showing current mode settings
26+ private val infoLabel = JLabel (" 📊 25 min work • 5 min break" ).apply {
1927 horizontalAlignment = SwingConstants .CENTER
20- font = font.deriveFont(32f )
28+ font = font.deriveFont(Font . PLAIN , 12f )
2129 }
2230
31+ // Circular timer display
32+ private val circularTimer = CircularTimerPanel ()
33+
34+ // Session indicator with tomato icons
35+ private val sessionIndicator = SessionIndicatorPanel ()
36+
37+ // Control buttons
2338 private val startButton = JButton (" Start" )
2439 private val pauseButton = JButton (" Pause" )
2540 private val resetButton = JButton (" Reset" )
2641
42+ // Custom settings panel (only visible when Custom mode selected)
2743 private val settingsPanel = PomodoroSettingsPanel { session, breakTime, sessions ->
28- timerService.applySettings(PomodoroSettings (session, breakTime, sessions))
44+ timerService.applySettings(PomodoroSettings (PomodoroMode .CUSTOM , session, breakTime, sessions))
45+ updateInfoLabel(session, breakTime)
46+ updateProgressBar(sessions)
2947 }
3048
3149 private val scope = CoroutineScope (Dispatchers .Default )
3250 private var stateJob: Job ? = null
3351 private var timeJob: Job ? = null
52+ private var sessionJob: Job ? = null
3453
3554 init {
36- val buttonPanel = JPanel (FlowLayout ()).apply {
55+ buildUI()
56+ setupListeners()
57+ observeTimer()
58+ updateSettingsPanelVisibility()
59+ }
60+
61+ private fun buildUI () {
62+ // Top panel with mode selector
63+ val topPanel = JPanel (BorderLayout (5 , 5 )).apply {
64+ border = BorderFactory .createEmptyBorder(10 , 10 , 5 , 10 )
65+ add(modeComboBox, BorderLayout .CENTER )
66+ }
67+
68+ // Info panel
69+ val infoPanel = JPanel (FlowLayout (FlowLayout .CENTER )).apply {
70+ add(infoLabel)
71+ }
72+
73+ // Timer panel
74+ val timerPanel = JPanel (BorderLayout ()).apply {
75+ border = BorderFactory .createEmptyBorder(20 , 10 , 20 , 10 )
76+ add(circularTimer, BorderLayout .CENTER )
77+ }
78+
79+ // Progress panel
80+ val progressPanel = JPanel (BorderLayout (5 , 5 )).apply {
81+ border = BorderFactory .createEmptyBorder(0 , 20 , 10 , 20 )
82+ add(sessionIndicator, BorderLayout .CENTER )
83+ }
84+
85+ // Button panel
86+ val buttonPanel = JPanel (FlowLayout (FlowLayout .CENTER , 10 , 5 )).apply {
3787 add(startButton)
3888 add(pauseButton)
3989 add(resetButton)
4090 }
4191
42- val centerPanel = JPanel (BorderLayout ()).apply {
43- add(timeLabel, BorderLayout .CENTER )
44- add(buttonPanel, BorderLayout .SOUTH )
92+ // Center content
93+ val centerPanel = JPanel ().apply {
94+ layout = BoxLayout (this , BoxLayout .Y_AXIS )
95+ add(infoPanel)
96+ add(timerPanel)
97+ add(progressPanel)
98+ add(buttonPanel)
4599 }
46100
101+ add(topPanel, BorderLayout .NORTH )
47102 add(centerPanel, BorderLayout .CENTER )
48103 add(settingsPanel, BorderLayout .SOUTH )
49-
50- setupListeners()
51- observeTimer()
52104 }
53105
54106 private fun setupListeners () {
55107 startButton.addActionListener { timerService.start() }
56108 pauseButton.addActionListener { timerService.pause() }
57109 resetButton.addActionListener { timerService.reset() }
110+
111+ modeComboBox.addActionListener {
112+ val selectedMode = modeComboBox.selectedItem as PomodoroMode
113+ if (selectedMode != PomodoroMode .CUSTOM ) {
114+ timerService.applyMode(selectedMode)
115+ updateInfoLabel(selectedMode.sessionMinutes, selectedMode.breakMinutes)
116+ updateProgressBar(selectedMode.sessionsPerRound)
117+ }
118+ updateSettingsPanelVisibility()
119+ }
120+ }
121+
122+ private fun updateSettingsPanelVisibility () {
123+ val isCustom = modeComboBox.selectedItem == PomodoroMode .CUSTOM
124+ settingsPanel.isVisible = isCustom
125+ revalidate()
126+ repaint()
127+ }
128+
129+ private fun updateInfoLabel (sessionMin : Int , breakMin : Int ) {
130+ infoLabel.text = " 📊 $sessionMin min work • $breakMin min break"
131+ }
132+
133+ private fun updateProgressBar (totalSessions : Int ) {
134+ sessionIndicator.updateSessions(timerService.currentSession.value, totalSessions)
58135 }
59136
60137 private fun observeTimer () {
61138 timeJob = scope.launch {
62- timerService.timeLeft.collectLatest {
139+ timerService.timeLeft.collectLatest { time ->
63140 SwingUtilities .invokeLater {
64- timeLabel.text = it
141+ val progress = timerService.getProgress()
142+ circularTimer.updateTimer(time, progress, false )
65143 }
66144 }
67145 }
@@ -72,6 +150,17 @@ class PomodoroToolWindowPanel(private val project: Project) : JBPanel<JBPanel<*>
72150 startButton.isEnabled = it != PomodoroTimerService .TimerState .RUNNING
73151 pauseButton.isEnabled = it == PomodoroTimerService .TimerState .RUNNING
74152 resetButton.isEnabled = it != PomodoroTimerService .TimerState .IDLE
153+ // Disable mode selector when timer is active (running or paused)
154+ modeComboBox.isEnabled = it == PomodoroTimerService .TimerState .IDLE
155+ }
156+ }
157+ }
158+
159+ sessionJob = scope.launch {
160+ timerService.currentSession.collectLatest { session ->
161+ SwingUtilities .invokeLater {
162+ val settings = timerService.getSettings()
163+ sessionIndicator.updateSessions(session, settings.sessionsPerRound)
75164 }
76165 }
77166 }
@@ -80,6 +169,7 @@ class PomodoroToolWindowPanel(private val project: Project) : JBPanel<JBPanel<*>
80169 fun dispose () {
81170 stateJob?.cancel()
82171 timeJob?.cancel()
172+ sessionJob?.cancel()
83173 scope.cancel()
84174 }
85175}
0 commit comments