mirror of
https://gitlab.com/2009scape/rt4-client.git
synced 2025-12-09 16:45:46 -07:00
158 lines
5.3 KiB
Kotlin
158 lines
5.3 KiB
Kotlin
package KondoKit
|
|
|
|
import KondoKit.plugin.Companion.SCROLL_BAR_COLOR
|
|
import KondoKit.plugin.Companion.VIEW_BACKGROUND_COLOR
|
|
import rt4.GameShell.frame
|
|
import java.awt.Graphics
|
|
import java.awt.Graphics2D
|
|
import java.awt.Rectangle
|
|
import java.awt.event.*
|
|
import java.util.*
|
|
import javax.swing.JPanel
|
|
import javax.swing.SwingUtilities
|
|
|
|
class ScrollablePanel(private val content: JPanel) : JPanel() {
|
|
private var lastMouseY = 0
|
|
private var currentOffsetY = 0
|
|
private var scrollbarHeight = 0
|
|
private var scrollbarY = 0
|
|
private var showScrollbar = false
|
|
private var draggingScrollPill = false
|
|
|
|
// Define a buffer for the view height (extra space for smoother scrolling)
|
|
private val viewBuffer = -30
|
|
|
|
init {
|
|
layout = null
|
|
background = VIEW_BACKGROUND_COLOR // Color.red color can be set to debug
|
|
|
|
// Initial content bounds
|
|
content.bounds = Rectangle(0, 0, 242, content.preferredSize.height.coerceAtLeast(frame.height + viewBuffer))
|
|
add(content)
|
|
|
|
// Add listeners for scrolling interactions
|
|
addMouseListener(object : MouseAdapter() {
|
|
override fun mousePressed(e: MouseEvent) {
|
|
lastMouseY = e.y
|
|
if (showScrollbar && e.x in (242 - 10)..242 && e.y in scrollbarY..(scrollbarY + scrollbarHeight)) {
|
|
draggingScrollPill = true
|
|
}
|
|
}
|
|
|
|
override fun mouseReleased(e: MouseEvent) {
|
|
draggingScrollPill = false
|
|
}
|
|
})
|
|
|
|
addMouseMotionListener(object : MouseMotionAdapter() {
|
|
override fun mouseDragged(e: MouseEvent) {
|
|
val deltaY = e.y - lastMouseY
|
|
if (draggingScrollPill && showScrollbar) {
|
|
val viewHeight = frame.height
|
|
val contentHeight = content.height
|
|
val scrollRatio = contentHeight.toDouble() / viewHeight
|
|
scrollContent((deltaY * scrollRatio).toInt())
|
|
} else if (showScrollbar) {
|
|
scrollContent(deltaY)
|
|
}
|
|
lastMouseY = e.y
|
|
}
|
|
})
|
|
|
|
addMouseWheelListener { e ->
|
|
if (showScrollbar) {
|
|
scrollContent(-e.wheelRotation * 20)
|
|
}
|
|
}
|
|
|
|
// Timer to periodically check and update scrollbar status
|
|
Timer().schedule(object : TimerTask() {
|
|
override fun run() {
|
|
updateScrollbar()
|
|
}
|
|
}, 0, 1000)
|
|
|
|
// Component listener for resizing the frame
|
|
frame.addComponentListener(object : ComponentAdapter() {
|
|
override fun componentResized(e: ComponentEvent) {
|
|
handleResize()
|
|
}
|
|
})
|
|
}
|
|
|
|
private fun handleResize() {
|
|
SwingUtilities.invokeLater{
|
|
// Ensure the ScrollablePanel resizes with the frame
|
|
bounds = Rectangle(0, 0, 242, frame.height)
|
|
|
|
// Dynamically update content bounds and scrollbar on frame resize with buffer
|
|
content.bounds = Rectangle(0, 0, 242, content.preferredSize.height.coerceAtLeast(frame.height + viewBuffer))
|
|
showScrollbar = content.height > frame.height
|
|
|
|
currentOffsetY = 0
|
|
|
|
content.setLocation(0, currentOffsetY)
|
|
updateScrollbar()
|
|
|
|
revalidate()
|
|
repaint()
|
|
}
|
|
}
|
|
|
|
private fun scrollContent(deltaY: Int) {
|
|
if (!showScrollbar) {
|
|
currentOffsetY = 0
|
|
content.setLocation(0, currentOffsetY)
|
|
return
|
|
}
|
|
SwingUtilities.invokeLater {
|
|
currentOffsetY += deltaY
|
|
|
|
// Apply buffer to maxOffset
|
|
val maxOffset = (frame.height - content.height + viewBuffer).coerceAtMost(0)
|
|
currentOffsetY = currentOffsetY.coerceAtMost(0).coerceAtLeast(maxOffset)
|
|
|
|
content.setLocation(0, currentOffsetY)
|
|
|
|
val contentHeight = content.height
|
|
val viewHeight = frame.height + viewBuffer
|
|
val scrollableRatio = viewHeight.toDouble() / contentHeight
|
|
scrollbarY = ((-currentOffsetY / contentHeight.toDouble()) * viewHeight).toInt()
|
|
scrollbarHeight = (viewHeight * scrollableRatio).toInt().coerceAtLeast(20)
|
|
repaint()
|
|
}
|
|
}
|
|
|
|
private fun updateScrollbar() {
|
|
SwingUtilities.invokeLater {
|
|
showScrollbar = content.height > frame.height
|
|
|
|
val contentHeight = content.height
|
|
val viewHeight = frame.height + viewBuffer
|
|
|
|
if (showScrollbar) {
|
|
val scrollableRatio = viewHeight.toDouble() / contentHeight
|
|
scrollbarY = ((-currentOffsetY / contentHeight.toDouble()) * viewHeight).toInt()
|
|
scrollbarHeight = (viewHeight * scrollableRatio).toInt().coerceAtLeast(20)
|
|
} else {
|
|
scrollbarY = 0
|
|
scrollbarHeight = 0
|
|
}
|
|
repaint()
|
|
}
|
|
}
|
|
|
|
override fun paintComponent(g: Graphics) {
|
|
super.paintComponent(g)
|
|
}
|
|
|
|
override fun paintChildren(g: Graphics) {
|
|
super.paintChildren(g)
|
|
if (showScrollbar) {
|
|
val g2 = g as Graphics2D
|
|
val scrollbarX = 238
|
|
g2.color = SCROLL_BAR_COLOR
|
|
g2.fillRect(scrollbarX, scrollbarY, 2, scrollbarHeight)
|
|
}
|
|
}
|
|
}
|