Skip to content

Commit f1bda5d

Browse files
committed
feat: Add event statistics on dashboard and add calculate level logic based on total xp
1 parent 618fd8c commit f1bda5d

File tree

1 file changed

+153
-9
lines changed

1 file changed

+153
-9
lines changed
Lines changed: 153 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,174 @@
11
package com.github.ilovegamecoding.intellijcodexp.toolWindow
22

3+
import com.github.ilovegamecoding.intellijcodexp.StringUtil
34
import com.github.ilovegamecoding.intellijcodexp.form.CodeXPDashboard
4-
import com.intellij.openapi.diagnostic.thisLogger
5+
import com.github.ilovegamecoding.intellijcodexp.listeners.CodeXPListener
6+
import com.github.ilovegamecoding.intellijcodexp.services.CodeXPService
7+
import com.intellij.openapi.application.ApplicationManager
58
import com.intellij.openapi.project.Project
69
import com.intellij.openapi.wm.ToolWindow
710
import com.intellij.openapi.wm.ToolWindowFactory
811
import com.intellij.ui.content.ContentFactory
12+
import java.awt.Font
13+
import java.awt.GridBagConstraints
14+
import java.awt.GridLayout
15+
import javax.swing.BorderFactory
16+
import javax.swing.JLabel
17+
import javax.swing.JPanel
18+
import javax.swing.event.DocumentEvent
19+
import javax.swing.event.DocumentListener
920

1021

1122
class CodeXPToolWindowFactory : ToolWindowFactory {
12-
private var codeXPDashboard = CodeXPDashboard()
23+
override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) {
24+
// Get the CodeXP service
25+
val codeXPService = ApplicationManager.getApplication().getService(CodeXPService::class.java)
1326

14-
init {
15-
thisLogger().warn("Don't forget to remove all non-needed sample code files with their corresponding registration entries in `plugin.xml`.")
16-
}
27+
// Create the dashboard
28+
val codeXPDashboard = CodeXPDashboard()
1729

18-
private val contentFactory = ContentFactory.SERVICE.getInstance()
30+
initializeUI(codeXPService, codeXPDashboard)
1931

20-
override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) {
32+
// Add the dashboard to the tool window
33+
val contentFactory = ContentFactory.SERVICE.getInstance()
2134
val content = contentFactory.createContent(codeXPDashboard.pMain, null, false)
2235
toolWindow.contentManager.addContent(content)
2336
}
2437

2538
override fun shouldBeAvailable(project: Project) = true
2639

27-
fun setXP(xp: Int) {
28-
codeXPDashboard.lblLevel.text = "$xp"
40+
/**
41+
* Initializes the UI of the dashboard.
42+
*
43+
* @param codeXPService The CodeXP service.
44+
* @param codeXPDashboard The CodeXP dashboard.
45+
*/
46+
private fun initializeUI(codeXPService: CodeXPService, codeXPDashboard: CodeXPDashboard) {
47+
// Listen to events from the CodeXP service
48+
val connection = ApplicationManager.getApplication().messageBus.connect()
49+
50+
val constraints = GridBagConstraints()
51+
constraints.weightx = 1.0
52+
constraints.fill = GridBagConstraints.HORIZONTAL
53+
val eventStatics = HashMap<CodeXPService.Event, JPanel>()
54+
CodeXPService.Event.values().forEachIndexed { index, event -> // Add ui for each event
55+
if (event != CodeXPService.Event.NONE) { // Ignore the NONE event type
56+
constraints.gridy = index
57+
58+
val pEvent = JPanel(GridLayout(1, 3))
59+
pEvent.border = BorderFactory.createEmptyBorder(0, 16, 8, 0)
60+
61+
val lblEventName = JLabel(event.name)
62+
lblEventName.font = Font("Noto Sans SemiBold", Font.PLAIN, 14)
63+
lblEventName.border = BorderFactory.createEmptyBorder(0, 32, 0, 0)
64+
65+
val lblEventReward = JLabel("+" + StringUtil.numberToStringWithCommas(event.xpValue) + " XP")
66+
lblEventReward.font = Font("Noto Sans SemiBold", Font.PLAIN, 14)
67+
lblEventReward.border = BorderFactory.createEmptyBorder(0, 32, 0, 0)
68+
69+
val lblEventCount =
70+
JLabel(StringUtil.numberToStringWithCommas(codeXPService.state.getEventCount(event)))
71+
lblEventCount.font = Font("Noto Sans Medium", Font.PLAIN, 14)
72+
lblEventCount.horizontalAlignment = JLabel.CENTER
73+
74+
pEvent.add(lblEventName)
75+
pEvent.add(lblEventReward)
76+
pEvent.add(lblEventCount)
77+
codeXPDashboard.pEventStatistics.add(pEvent, constraints)
78+
79+
eventStatics[event] = pEvent
80+
}
81+
}
82+
83+
// Update the dashboard when events occur
84+
connection.subscribe(CodeXPListener.CODEXP_EVENT, object : CodeXPListener {
85+
override fun eventOccurred(event: CodeXPService.Event) {
86+
(eventStatics[event]!!.getComponent(2) as JLabel).text =
87+
StringUtil.numberToStringWithCommas(codeXPService.state.getEventCount(event))
88+
updateXPInfo(codeXPService, codeXPDashboard)
89+
}
90+
})
91+
92+
codeXPDashboard.tfNickname.text = codeXPService.state.nickname
93+
codeXPDashboard.tfNickname.document.addDocumentListener(object : DocumentListener {
94+
override fun insertUpdate(e: DocumentEvent) {
95+
codeXPService.state.nickname = codeXPDashboard.tfNickname.text
96+
}
97+
98+
override fun removeUpdate(e: DocumentEvent) {
99+
codeXPService.state.nickname = codeXPDashboard.tfNickname.text
100+
}
101+
102+
override fun changedUpdate(e: DocumentEvent) {
103+
codeXPService.state.nickname = codeXPDashboard.tfNickname.text
104+
}
105+
})
106+
107+
updateXPInfo(codeXPService, codeXPDashboard)
108+
}
109+
110+
/**
111+
* Updates the XP info on the dashboard.
112+
*
113+
* @param codeXPService The CodeXP service.
114+
* @param codeXPDashboard The CodeXP dashboard.
115+
*/
116+
fun updateXPInfo(codeXPService: CodeXPService, codeXPDashboard: CodeXPDashboard) {
117+
val totalXP = codeXPService.state.xp
118+
codeXPDashboard.lblTotalXP.text = StringUtil.numberToStringWithCommas(totalXP)
119+
val (currentLevel, xpIntoCurrentLevel, progressToNextLevel) = calculateLevelAndProgress(
120+
totalXP
121+
)
122+
123+
codeXPDashboard.lblCurrentLevel.text = StringUtil.numberToStringWithCommas(currentLevel.toLong())
124+
codeXPDashboard.lblNextLevel.text = StringUtil.numberToStringWithCommas((currentLevel + 1).toLong())
125+
codeXPDashboard.lblCurrentLevelXP.text = StringUtil.numberToStringWithCommas(xpIntoCurrentLevel)
126+
codeXPDashboard.pbCurrentLevelProgress.value = progressToNextLevel
127+
codeXPDashboard.pbCurrentLevelProgress.string = "$progressToNextLevel %"
128+
codeXPDashboard.lblLevel.text = StringUtil.numberToStringWithCommas(currentLevel.toLong())
129+
}
130+
131+
/**
132+
* Level info data class.
133+
*/
134+
data class LevelInfo(
135+
/**
136+
* Current level.
137+
*/
138+
val currentLevel: Int,
139+
140+
/**
141+
* XP into the current level.
142+
*/
143+
val xpIntoCurrentLevel: Long,
144+
145+
/**
146+
* Progress to the next level.
147+
*/
148+
val progressToNextLevel: Int
149+
)
150+
151+
/**
152+
* Calculates the level and progress to the next level.
153+
*
154+
* @param totalXP The total XP.
155+
* @return The level info.
156+
*/
157+
fun calculateLevelAndProgress(totalXP: Long): LevelInfo {
158+
var level = 1
159+
var currentLevelXP = 300.0
160+
var xp = 300.0
161+
162+
while (totalXP >= xp) {
163+
level++
164+
currentLevelXP *= 1.05
165+
xp += currentLevelXP
166+
}
167+
168+
val xpIntoCurrentLevel = totalXP - (xp - currentLevelXP)
169+
val progress = (xpIntoCurrentLevel / currentLevelXP) * 100
170+
171+
return LevelInfo(level, xpIntoCurrentLevel.toLong(), progress.toInt())
29172
}
30173
}
174+

0 commit comments

Comments
 (0)