Faster loading XP Widgets, file loading heleprs and XP widget resetting

This commit is contained in:
downthecrop 2025-08-19 23:56:25 -07:00
parent 7f09263209
commit 7cc56d0e53
5 changed files with 255 additions and 99 deletions

View file

@ -164,11 +164,15 @@ class plugin : Plugin() {
override fun OnPluginsReloaded(): Boolean {
if (!initialized) return true
updateDisplaySettings()
frame.remove(rightPanelWrapper)
frame.layout = BorderLayout()
rightPanelWrapper?.let { frame.add(it, BorderLayout.EAST) }
frame.revalidate()
// Ensure Swing updates happen on the EDT to avoid flicker
SwingUtilities.invokeLater {
updateDisplaySettings()
frame.remove(rightPanelWrapper)
frame.layout = BorderLayout()
rightPanelWrapper?.let { frame.add(it, BorderLayout.EAST) }
frame.revalidate()
frame.repaint()
}
pluginsReloaded = true
reloadInterfaces = true
return true
@ -179,25 +183,47 @@ class plugin : Plugin() {
initialXP[skillId] = xp
return
}
var xpWidget = xpWidgets[skillId]
if (xpWidget != null) {
updateWidget(xpWidget, xp)
} else {
val previousXp = initialXP[skillId] ?: xp
if (xp == initialXP[skillId]) return
val previousXpSnapshot = initialXP[skillId] ?: xp
if (xp == initialXP[skillId]) return
xpWidget = createXPWidget(skillId, previousXp)
xpWidgets[skillId] = xpWidget
val ensureOnEdt = Runnable {
var xpWidget = xpWidgets[skillId]
if (xpWidget != null) {
updateWidget(xpWidget, xp)
} else {
xpWidget = createXPWidget(skillId, previousXpSnapshot)
xpWidgets[skillId] = xpWidget
xpTrackerView?.add(wrappedWidget(xpWidget.container))
xpTrackerView?.add(Box.createVerticalStrut(5))
val wrapped = wrappedWidget(xpWidget.container)
// Attach per-widget remove menu
val popupMenu = XPTrackerView.removeXPWidgetMenu(wrapped, skillId)
val rightClickListener = object : MouseAdapter() {
override fun mousePressed(e: MouseEvent) {
if (e.isPopupTrigger) popupMenu.show(e.component, e.x, e.y)
}
override fun mouseReleased(e: MouseEvent) {
if (e.isPopupTrigger) popupMenu.show(e.component, e.x, e.y)
}
}
Helpers.addMouseListenerToAll(wrapped, rightClickListener)
wrapped.addMouseListener(rightClickListener)
if(focusedView == XPTrackerView.VIEW_NAME) {
xpTrackerView?.revalidate()
xpTrackerView?.repaint()
xpTrackerView?.add(wrapped)
xpTrackerView?.add(Box.createVerticalStrut(5))
if(focusedView == XPTrackerView.VIEW_NAME) {
xpTrackerView?.revalidate()
xpTrackerView?.repaint()
}
updateWidget(xpWidget, xp)
}
}
updateWidget(xpWidget, xp)
if (SwingUtilities.isEventDispatchThread()) {
ensureOnEdt.run()
} else {
SwingUtilities.invokeLater(ensureOnEdt)
}
}
@ -208,7 +234,10 @@ class plugin : Plugin() {
}
if (pluginsReloaded) {
reflectiveEditorView?.let { addPlugins(it) }
// Rebuild the reflective editor UI on the EDT and in one batch
SwingUtilities.invokeLater {
reflectiveEditorView?.let { addPlugins(it) }
}
pluginsReloaded = false
}
@ -481,15 +510,24 @@ class plugin : Plugin() {
verticalScrollBarPolicy = JScrollPane.VERTICAL_SCROLLBAR_NEVER
}
frame.layout = BorderLayout()
rightPanelWrapper?.let {
frame.add(it, BorderLayout.EAST)
val desiredView = if (launchMinimized) HIDDEN_VIEW else XPTrackerView.VIEW_NAME
// Commit layout synchronously on the EDT to avoid initial misplacement
val commit = Runnable {
frame.layout = BorderLayout()
rightPanelWrapper?.let { frame.add(it, BorderLayout.EAST) }
setActiveView(desiredView)
frame.validate()
frame.repaint()
}
if(launchMinimized){
setActiveView(HIDDEN_VIEW)
if (SwingUtilities.isEventDispatchThread()) {
commit.run()
} else {
setActiveView(XPTrackerView.VIEW_NAME)
try {
javax.swing.SwingUtilities.invokeAndWait(commit)
} catch (e: Exception) {
// Fallback to async if invokeAndWait fails for any reason
SwingUtilities.invokeLater(commit)
}
}
initialized = true
pluginsReloaded = true
@ -497,29 +535,55 @@ class plugin : Plugin() {
}
private fun setActiveView(viewName: String) {
// Handle the visibility of the main content panel
if (viewName == HIDDEN_VIEW) {
mainContentPanel.isVisible = false
} else {
if (!mainContentPanel.isVisible) {
mainContentPanel.isVisible = true
val runUpdate: () -> Unit = {
// Track visibility change to decide if we need to resize/reload interfaces
val wasVisible = mainContentPanel.isVisible
// Handle the visibility of the main content panel and card switch
if (viewName == HIDDEN_VIEW) {
mainContentPanel.isVisible = false
} else {
if (!mainContentPanel.isVisible) {
mainContentPanel.isVisible = true
}
cardLayout.show(mainContentPanel, viewName)
}
cardLayout.show(mainContentPanel, viewName)
val visibilityChanged = wasVisible != mainContentPanel.isVisible
// Batch painting to avoid intermediate repaints
rightPanelWrapper?.ignoreRepaint = true
try {
if (visibilityChanged) {
// Only touch layout and client interfaces if width actually changes
updateDisplaySettings()
reloadInterfaces = true
rightPanelWrapper?.revalidate()
frame?.validate()
} else {
// Just a card switch; avoid full frame revalidate
mainContentPanel.revalidate()
}
} finally {
rightPanelWrapper?.ignoreRepaint = false
}
// Targeted repaint for snappy feedback
if (visibilityChanged) {
rightPanelWrapper?.repaint()
frame?.repaint()
} else {
mainContentPanel.repaint()
}
focusedView = viewName
}
reloadInterfaces = true
updateDisplaySettings()
// Revalidate and repaint necessary panels
mainContentPanel.revalidate()
rightPanelWrapper?.revalidate()
frame?.revalidate()
mainContentPanel.repaint()
rightPanelWrapper?.repaint()
frame?.repaint()
focusedView = viewName
if (SwingUtilities.isEventDispatchThread()) {
runUpdate()
} else {
SwingUtilities.invokeLater { runUpdate() }
}
}
private fun createNavButton(spriteId: Int, viewName: String): JPanel {
@ -666,7 +730,7 @@ class plugin : Plugin() {
}
private fun loadFont(): Font? {
val fontStream = plugin::class.java.getResourceAsStream("res/runescape_small.ttf")
val fontStream = Helpers.openResource("res/runescape_small.ttf")
return if (fontStream != null) {
try {
val font = Font.createFont(Font.TRUETYPE_FONT, fontStream)