mirror of
https://gitlab.com/2009scape/rt4-client.git
synced 2025-12-10 10:20:44 -07:00
reorganize
This commit is contained in:
parent
529f0c22b0
commit
cf6bb51d2c
20 changed files with 815 additions and 411 deletions
|
|
@ -0,0 +1,45 @@
|
|||
package KondoKit.components
|
||||
|
||||
import KondoKit.plugin.Companion.TITLE_BAR_COLOR
|
||||
import KondoKit.plugin.Companion.WIDGET_COLOR
|
||||
import KondoKit.plugin.Companion.secondaryColor
|
||||
import java.awt.*
|
||||
import javax.swing.*
|
||||
|
||||
class ButtonPanel(
|
||||
private val alignment: Int = FlowLayout.CENTER,
|
||||
private val hgap: Int = 5,
|
||||
private val vgap: Int = 0
|
||||
) : JPanel() {
|
||||
|
||||
init {
|
||||
layout = FlowLayout(alignment, hgap, vgap)
|
||||
background = WIDGET_COLOR
|
||||
}
|
||||
|
||||
fun addButton(text: String, action: () -> Unit): JButton {
|
||||
val button = JButton(text).apply {
|
||||
background = TITLE_BAR_COLOR
|
||||
foreground = secondaryColor
|
||||
font = Font("RuneScape Small", Font.PLAIN, 14)
|
||||
addActionListener {
|
||||
action()
|
||||
}
|
||||
}
|
||||
add(button)
|
||||
return button
|
||||
}
|
||||
|
||||
fun addIcon(icon: Icon, action: () -> Unit): JButton {
|
||||
val button = JButton(icon).apply {
|
||||
background = TITLE_BAR_COLOR
|
||||
foreground = secondaryColor
|
||||
font = Font("RuneScape Small", Font.PLAIN, 14)
|
||||
addActionListener {
|
||||
action()
|
||||
}
|
||||
}
|
||||
add(button)
|
||||
return button
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package KondoKit.components
|
||||
|
||||
import KondoKit.ImageCanvas
|
||||
import KondoKit.SpriteToBufferedImage
|
||||
import KondoKit.plugin.Companion.WIDGET_COLOR
|
||||
import KondoKit.plugin.Companion.primaryColor
|
||||
import KondoKit.plugin.Companion.secondaryColor
|
||||
import plugin.api.API
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Color
|
||||
import java.awt.Dimension
|
||||
import javax.swing.BorderFactory
|
||||
import javax.swing.JPanel
|
||||
|
||||
class IconComponent(
|
||||
spriteId: Int,
|
||||
private val iconWidth: Int = 25,
|
||||
private val iconHeight: Int = 23,
|
||||
private val useThemeColors: Boolean = true,
|
||||
private val tint: Color? = null,
|
||||
private val grayscale: Boolean = false,
|
||||
private val brightnessBoost: Float = 1.0f
|
||||
) : JPanel() {
|
||||
|
||||
private val imageCanvas: ImageCanvas
|
||||
|
||||
init {
|
||||
layout = BorderLayout()
|
||||
background = if (useThemeColors) WIDGET_COLOR else Color.WHITE
|
||||
|
||||
val bufferedImageSprite = SpriteToBufferedImage.getBufferedImageFromSprite(
|
||||
API.GetSprite(spriteId),
|
||||
tint,
|
||||
grayscale,
|
||||
brightnessBoost
|
||||
)
|
||||
|
||||
imageCanvas = ImageCanvas(bufferedImageSprite).apply {
|
||||
val size = Dimension(iconWidth, iconHeight)
|
||||
preferredSize = size
|
||||
maximumSize = size
|
||||
minimumSize = size
|
||||
background = if (useThemeColors) WIDGET_COLOR else Color.WHITE
|
||||
}
|
||||
|
||||
add(imageCanvas, BorderLayout.CENTER)
|
||||
border = BorderFactory.createEmptyBorder(2, 2, 2, 2)
|
||||
}
|
||||
|
||||
fun updateFillColor(color: Color) {
|
||||
imageCanvas.fillColor = color
|
||||
background = color
|
||||
imageCanvas.repaint()
|
||||
repaint()
|
||||
}
|
||||
|
||||
fun applyThemeColors() {
|
||||
updateFillColor(WIDGET_COLOR)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package KondoKit.components
|
||||
|
||||
import KondoKit.Helpers.formatHtmlLabelText
|
||||
import KondoKit.plugin.Companion.primaryColor
|
||||
import KondoKit.plugin.Companion.secondaryColor
|
||||
import java.awt.Font
|
||||
import java.awt.Color
|
||||
import javax.swing.JLabel
|
||||
import javax.swing.SwingConstants
|
||||
|
||||
class LabelComponent(
|
||||
text: String = "",
|
||||
private val isHtml: Boolean = false,
|
||||
private val alignment: Int = SwingConstants.LEFT
|
||||
) : JLabel() {
|
||||
|
||||
init {
|
||||
this.text = text
|
||||
this.horizontalAlignment = alignment
|
||||
this.font = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
||||
}
|
||||
|
||||
fun updateText(plainText: String, color: Color = secondaryColor) {
|
||||
this.text = plainText
|
||||
this.foreground = color
|
||||
}
|
||||
|
||||
fun updateHtmlText(text1: String, color1: Color = primaryColor, text2: String = "", color2: Color = secondaryColor) {
|
||||
this.text = formatHtmlLabelText(text1, color1, text2, color2)
|
||||
}
|
||||
|
||||
fun setAsHeader() {
|
||||
font = Font("RuneScape Small", Font.BOLD, 16)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package KondoKit.components
|
||||
|
||||
import KondoKit.plugin.Companion.POPUP_BACKGROUND
|
||||
import KondoKit.plugin.Companion.POPUP_FOREGROUND
|
||||
import java.awt.Font
|
||||
import javax.swing.JMenuItem
|
||||
import javax.swing.JPopupMenu
|
||||
|
||||
class PopupMenuComponent : JPopupMenu() {
|
||||
|
||||
init {
|
||||
background = POPUP_BACKGROUND
|
||||
}
|
||||
|
||||
fun addMenuItem(text: String, action: () -> Unit): JMenuItem {
|
||||
val menuItem = JMenuItem(text).apply {
|
||||
font = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
||||
background = POPUP_BACKGROUND
|
||||
foreground = POPUP_FOREGROUND
|
||||
addActionListener {
|
||||
action()
|
||||
}
|
||||
}
|
||||
add(menuItem)
|
||||
return menuItem
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package KondoKit.components
|
||||
|
||||
import KondoKit.plugin.Companion.PROGRESS_BAR_FILL
|
||||
import KondoKit.plugin.Companion.secondaryColor
|
||||
import java.awt.Canvas
|
||||
import java.awt.Color
|
||||
import java.awt.Dimension
|
||||
import java.awt.Font
|
||||
import java.awt.Graphics
|
||||
|
||||
class ProgressBar(
|
||||
private var progress: Double,
|
||||
private val barColor: Color,
|
||||
private var currentLevel: Int = 0,
|
||||
private var nextLevel: Int = 1
|
||||
) : Canvas() {
|
||||
|
||||
init {
|
||||
font = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
||||
}
|
||||
|
||||
override fun paint(g: Graphics) {
|
||||
super.paint(g)
|
||||
|
||||
// Draw the filled part of the progress bar
|
||||
g.color = barColor
|
||||
val width = (progress * this.width / 100).toInt()
|
||||
g.fillRect(0, 0, width, this.height)
|
||||
|
||||
// Draw the unfilled part of the progress bar
|
||||
g.color = PROGRESS_BAR_FILL
|
||||
g.fillRect(width, 0, this.width - width, this.height)
|
||||
|
||||
// Variables for text position
|
||||
val textY = this.height / 2 + 6
|
||||
|
||||
// Draw the current level on the far left
|
||||
drawTextWithShadow(g, "Lvl. $currentLevel", 5, textY, secondaryColor)
|
||||
|
||||
// Draw the percentage in the middle
|
||||
val percentageText = String.format("%.2f%%", progress)
|
||||
val percentageWidth = g.fontMetrics.stringWidth(percentageText)
|
||||
drawTextWithShadow(g, percentageText, (this.width - percentageWidth) / 2, textY, secondaryColor)
|
||||
|
||||
// Draw the next level on the far right
|
||||
val nextLevelText = "Lvl. $nextLevel"
|
||||
val nextLevelWidth = g.fontMetrics.stringWidth(nextLevelText)
|
||||
drawTextWithShadow(g, nextLevelText, this.width - nextLevelWidth - 5, textY, secondaryColor)
|
||||
}
|
||||
|
||||
override fun getPreferredSize(): Dimension {
|
||||
return Dimension(220, 16) // Force the height to 16px, width can be anything appropriate
|
||||
}
|
||||
|
||||
override fun getMinimumSize(): Dimension {
|
||||
return Dimension(220, 16) // Force the minimum height to 16px, width can be smaller
|
||||
}
|
||||
|
||||
fun updateProgress(newProgress: Double, currentLevel: Int, nextLevel: Int, isVisible : Boolean) {
|
||||
this.progress = newProgress
|
||||
this.currentLevel = currentLevel
|
||||
this.nextLevel = nextLevel
|
||||
if(isVisible)
|
||||
repaint()
|
||||
}
|
||||
|
||||
// Helper function to draw text with a shadow effect
|
||||
private fun drawTextWithShadow(g: Graphics, text: String, x: Int, y: Int, textColor: Color) {
|
||||
// Draw shadow (black text with -1 x and -1 y offset)
|
||||
g.color = Color(0, 0, 0)
|
||||
g.drawString(text, x + 1, y + 1)
|
||||
|
||||
// Draw actual text on top
|
||||
g.color = textColor
|
||||
g.drawString(text, x, y)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
package KondoKit.components.ReflectiveEditorComponents
|
||||
|
||||
import KondoKit.ImageCanvas
|
||||
import KondoKit.plugin
|
||||
import KondoKit.plugin.Companion.WIDGET_COLOR
|
||||
import KondoKit.plugin.Companion.secondaryColor
|
||||
import plugin.api.API
|
||||
import java.awt.*
|
||||
import java.awt.datatransfer.DataFlavor
|
||||
import java.awt.event.ActionEvent
|
||||
import java.awt.event.ActionListener
|
||||
import java.awt.event.KeyAdapter
|
||||
import java.awt.event.KeyEvent
|
||||
import java.awt.event.MouseAdapter
|
||||
import java.awt.event.MouseEvent
|
||||
import java.awt.image.BufferedImage
|
||||
import javax.imageio.ImageIO
|
||||
import javax.swing.*
|
||||
|
||||
class CustomSearchField(private val parentPanel: JPanel, private val onSearch: (String) -> Unit) : Canvas() {
|
||||
private var cursorVisible: Boolean = true
|
||||
private var text: String = ""
|
||||
|
||||
private val bufferedImageSprite = getBufferedImageFromSprite(API.GetSprite(1423)) // MAG_SPRITE
|
||||
private val imageCanvas = bufferedImageSprite.let {
|
||||
ImageCanvas(it).apply {
|
||||
preferredSize = Dimension(12, 12) // ICON_DIMENSION_SMALL
|
||||
size = preferredSize
|
||||
minimumSize = preferredSize
|
||||
maximumSize = preferredSize
|
||||
fillColor = WIDGET_COLOR
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
preferredSize = Dimension(230, 30) // SEARCH_FIELD_DIMENSION
|
||||
background = WIDGET_COLOR // COLOR_BACKGROUND_DARK
|
||||
foreground = secondaryColor // COLOR_FOREGROUND_LIGHT
|
||||
font = Font("Arial", Font.PLAIN, 14) // FONT_ARIAL_PLAIN_14
|
||||
minimumSize = preferredSize
|
||||
maximumSize = preferredSize
|
||||
|
||||
addKeyListener(object : KeyAdapter() {
|
||||
override fun keyTyped(e: KeyEvent) {
|
||||
// Prevent null character from being typed on Ctrl+A & Ctrl+V
|
||||
if (e.isControlDown && (e.keyChar == '\u0001' || e.keyChar == '\u0016')) {
|
||||
e.consume()
|
||||
return
|
||||
}
|
||||
if (e.keyChar == '\b') {
|
||||
if (text.isNotEmpty()) {
|
||||
text = text.dropLast(1)
|
||||
}
|
||||
} else if (e.keyChar == '\n') {
|
||||
onSearch(text)
|
||||
} else {
|
||||
text += e.keyChar
|
||||
}
|
||||
SwingUtilities.invokeLater {
|
||||
repaint()
|
||||
}
|
||||
}
|
||||
override fun keyPressed(e: KeyEvent) {
|
||||
if (e.isControlDown) {
|
||||
when (e.keyCode) {
|
||||
KeyEvent.VK_A -> {
|
||||
text = ""
|
||||
SwingUtilities.invokeLater {
|
||||
repaint()
|
||||
}
|
||||
}
|
||||
KeyEvent.VK_V -> {
|
||||
val clipboard = Toolkit.getDefaultToolkit().systemClipboard
|
||||
val pasteText = clipboard.getData(DataFlavor.stringFlavor) as String
|
||||
text += pasteText
|
||||
SwingUtilities.invokeLater {
|
||||
repaint()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
addMouseListener(object : MouseAdapter() {
|
||||
override fun mouseClicked(e: MouseEvent) {
|
||||
if (e.x > width - 20 && e.y < 20) {
|
||||
text = ""
|
||||
onSearch(text)
|
||||
SwingUtilities.invokeLater {
|
||||
repaint()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
javax.swing.Timer(500, ActionListener { _ ->
|
||||
cursorVisible = !cursorVisible
|
||||
if (plugin.StateManager.focusedView == "REFLECTIVE_EDITOR_VIEW")
|
||||
SwingUtilities.invokeLater {
|
||||
repaint()
|
||||
}
|
||||
}).start()
|
||||
}
|
||||
|
||||
override fun paint(g: Graphics) {
|
||||
super.paint(g)
|
||||
g.color = foreground
|
||||
g.font = font
|
||||
|
||||
val fm = g.fontMetrics
|
||||
val cursorX = fm.stringWidth(text) + 30
|
||||
|
||||
// Draw magnifying glass icon
|
||||
imageCanvas.let { canvas ->
|
||||
val imgG = g.create(5, 5, canvas.width, canvas.height)
|
||||
canvas.paint(imgG)
|
||||
imgG.dispose()
|
||||
}
|
||||
|
||||
// Use a local copy of the text to avoid threading issues
|
||||
val currentText = text
|
||||
|
||||
// Draw placeholder text if field is empty, otherwise draw actual text
|
||||
if (currentText == "") {
|
||||
g.color = Color.GRAY // Use a lighter color for placeholder text
|
||||
g.drawString("Search plugins...", 30, 20)
|
||||
} else {
|
||||
g.color = foreground // Use normal color for actual text
|
||||
g.drawString(currentText, 30, 20)
|
||||
}
|
||||
|
||||
if (cursorVisible && hasFocus()) {
|
||||
g.color = foreground
|
||||
g.drawLine(cursorX, 5, cursorX, 25)
|
||||
}
|
||||
|
||||
// Only draw the "x" button if there's text
|
||||
if (currentText != "") {
|
||||
g.color = Color.RED
|
||||
g.drawString("x", width - 20, 20)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBufferedImageFromSprite(sprite: Any?): BufferedImage {
|
||||
// This is a simplified version - you might need to adjust based on your actual implementation
|
||||
// For now, let's just return a placeholder image
|
||||
val image = BufferedImage(12, 12, BufferedImage.TYPE_INT_ARGB)
|
||||
val g2d = image.createGraphics()
|
||||
g2d.color = Color.GRAY
|
||||
g2d.fillOval(2, 2, 8, 8)
|
||||
g2d.drawLine(8, 8, 11, 11)
|
||||
g2d.dispose()
|
||||
return image
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package KondoKit.components.ReflectiveEditorComponents
|
||||
|
||||
data class GitLabPlugin(
|
||||
val id: String,
|
||||
val path: String,
|
||||
val pluginProperties: PluginProperties?,
|
||||
val pluginError: String?
|
||||
)
|
||||
|
||||
data class PluginProperties(
|
||||
val author: String,
|
||||
val version: String,
|
||||
val description: String
|
||||
)
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
package KondoKit.components.ReflectiveEditorComponents
|
||||
|
||||
import KondoKit.views.ReflectiveEditorView
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonObject
|
||||
import java.awt.EventQueue
|
||||
import java.io.BufferedReader
|
||||
import java.io.InputStreamReader
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URL
|
||||
import javax.swing.SwingUtilities
|
||||
|
||||
object GitLabPluginFetcher {
|
||||
private const val GITLAB_ACCESS_TOKEN = "glpat-dE2Cs2e4b32-H7c9oGuS"
|
||||
private const val GITLAB_PROJECT_ID = "38297322"
|
||||
private const val GITLAB_BRANCH = "master"
|
||||
|
||||
// Function to fetch plugins from GitLab
|
||||
fun fetchGitLabPlugins(onComplete: (List<GitLabPlugin>) -> Unit) {
|
||||
Thread {
|
||||
try {
|
||||
val plugins = mutableListOf<GitLabPlugin>()
|
||||
val apiUrl = "https://gitlab.com/api/v4/projects/${GITLAB_PROJECT_ID}/repository/tree?ref=${GITLAB_BRANCH}"
|
||||
|
||||
// Create URL connection
|
||||
val url = URL(apiUrl)
|
||||
val connection = url.openConnection() as HttpURLConnection
|
||||
connection.requestMethod = "GET"
|
||||
connection.setRequestProperty("PRIVATE-TOKEN", GITLAB_ACCESS_TOKEN)
|
||||
|
||||
// Read response
|
||||
val responseCode = connection.responseCode
|
||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||
val reader = BufferedReader(InputStreamReader(connection.inputStream))
|
||||
val response = reader.use { it.readText() }
|
||||
|
||||
// Parse JSON response
|
||||
val gson = Gson()
|
||||
val treeItems = gson.fromJson(response, Array::class.java)
|
||||
|
||||
// Filter for directories (trees)
|
||||
for (item in treeItems) {
|
||||
val jsonObject = item as JsonObject
|
||||
if (jsonObject["type"].asString == "tree") {
|
||||
val folderId = jsonObject["id"].asString
|
||||
val folderPath = jsonObject["path"].asString
|
||||
|
||||
try {
|
||||
val pluginProperties = fetchPluginProperties(folderPath)
|
||||
plugins.add(GitLabPlugin(folderId, folderPath, pluginProperties, null))
|
||||
} catch (e: Exception) {
|
||||
plugins.add(GitLabPlugin(folderId, folderPath, null, "Error fetching plugin.properties"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update on UI thread
|
||||
SwingUtilities.invokeLater {
|
||||
onComplete(plugins)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
SwingUtilities.invokeLater {
|
||||
onComplete(emptyList())
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
// Function to fetch plugin.properties from a specific folder
|
||||
private fun fetchPluginProperties(folderPath: String): PluginProperties {
|
||||
val pluginFilePath = "$folderPath/plugin.properties"
|
||||
val pluginUrl = "https://gitlab.com/api/v4/projects/${GITLAB_PROJECT_ID}/repository/files/${pluginFilePath.replace("/", "%2F")}/raw?ref=${GITLAB_BRANCH}"
|
||||
|
||||
// Create URL connection
|
||||
val url = URL(pluginUrl)
|
||||
val connection = url.openConnection() as HttpURLConnection
|
||||
connection.requestMethod = "GET"
|
||||
connection.setRequestProperty("PRIVATE-TOKEN", GITLAB_ACCESS_TOKEN)
|
||||
|
||||
// Read response
|
||||
val responseCode = connection.responseCode
|
||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||
val reader = BufferedReader(InputStreamReader(connection.inputStream))
|
||||
val rawContent = reader.use { it.readText() }
|
||||
|
||||
return parseProperties(rawContent)
|
||||
} else {
|
||||
throw Exception("Plugin file not found for folder: $folderPath")
|
||||
}
|
||||
}
|
||||
|
||||
// Function to parse plugin.properties content
|
||||
private fun parseProperties(content: String): PluginProperties {
|
||||
val lines = content.split("\n")
|
||||
var author = "Unknown"
|
||||
var version = "Unknown"
|
||||
var description = "No description available"
|
||||
|
||||
for (line in lines) {
|
||||
val parts = line.split("=")
|
||||
if (parts.size == 2) {
|
||||
val key = parts[0].trim()
|
||||
val value = parts[1].replace("\"", "").replace("'", "").trim()
|
||||
|
||||
when {
|
||||
key.startsWith("AUTHOR", ignoreCase = true) -> author = value
|
||||
key.startsWith("VERSION", ignoreCase = true) -> version = value
|
||||
key.startsWith("DESCRIPTION", ignoreCase = true) -> description = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PluginProperties(author, version, description)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
package KondoKit.components
|
||||
|
||||
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
|
||||
private var lastSize = 0
|
||||
|
||||
// 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()
|
||||
if(lastSize != content.preferredSize.height.coerceAtLeast(frame.height + viewBuffer))
|
||||
handleResize()
|
||||
}
|
||||
}, 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
|
||||
lastSize = content.preferredSize.height.coerceAtLeast(frame.height + viewBuffer)
|
||||
content.bounds = Rectangle(0, 0, 242, lastSize)
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
package KondoKit.components
|
||||
|
||||
import KondoKit.ImageCanvas
|
||||
import KondoKit.SpriteToBufferedImage
|
||||
import KondoKit.plugin.Companion.WIDGET_COLOR
|
||||
import KondoKit.plugin.Companion.secondaryColor
|
||||
import plugin.api.API
|
||||
import java.awt.*
|
||||
import java.awt.datatransfer.DataFlavor
|
||||
import java.awt.event.*
|
||||
import javax.swing.*
|
||||
|
||||
open class SearchField(
|
||||
private val onSearch: (String) -> Unit,
|
||||
private val placeholderText: String = "Search...",
|
||||
private val fieldWidth: Int = 230,
|
||||
private val fieldHeight: Int = 30
|
||||
) : Canvas() {
|
||||
|
||||
private var cursorVisible: Boolean = true
|
||||
private var text: String = ""
|
||||
|
||||
private val bufferedImageSprite = SpriteToBufferedImage.getBufferedImageFromSprite(API.GetSprite(1423)) // MAG_SPRITE
|
||||
private val imageCanvas = bufferedImageSprite.let {
|
||||
ImageCanvas(it).apply {
|
||||
preferredSize = Dimension(12, 12)
|
||||
size = preferredSize
|
||||
minimumSize = preferredSize
|
||||
maximumSize = preferredSize
|
||||
fillColor = WIDGET_COLOR
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
val dimension = Dimension(fieldWidth, fieldHeight)
|
||||
preferredSize = dimension
|
||||
background = WIDGET_COLOR
|
||||
foreground = secondaryColor
|
||||
font = Font("Arial", Font.PLAIN, 14)
|
||||
minimumSize = dimension
|
||||
maximumSize = dimension
|
||||
|
||||
addKeyListener(object : KeyAdapter() {
|
||||
override fun keyTyped(e: KeyEvent) {
|
||||
// Prevent null character from being typed on Ctrl+A & Ctrl+V
|
||||
if (e.isControlDown && (e.keyChar == '\u0001' || e.keyChar == '\u0016')) {
|
||||
e.consume()
|
||||
return
|
||||
}
|
||||
if (e.keyChar == '\b') {
|
||||
if (text.isNotEmpty()) {
|
||||
text = text.dropLast(1)
|
||||
}
|
||||
} else if (e.keyChar == '\n') {
|
||||
onSearch(text)
|
||||
} else {
|
||||
text += e.keyChar
|
||||
}
|
||||
SwingUtilities.invokeLater {
|
||||
repaint()
|
||||
}
|
||||
}
|
||||
|
||||
override fun keyPressed(e: KeyEvent) {
|
||||
if (e.isControlDown) {
|
||||
when (e.keyCode) {
|
||||
KeyEvent.VK_A -> {
|
||||
text = ""
|
||||
SwingUtilities.invokeLater {
|
||||
repaint()
|
||||
}
|
||||
}
|
||||
KeyEvent.VK_V -> {
|
||||
try {
|
||||
val clipboard = Toolkit.getDefaultToolkit().systemClipboard
|
||||
val pasteText = clipboard.getData(DataFlavor.stringFlavor) as String
|
||||
text += pasteText
|
||||
SwingUtilities.invokeLater {
|
||||
repaint()
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
// Ignore clipboard errors
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
addMouseListener(object : MouseAdapter() {
|
||||
override fun mouseClicked(e: MouseEvent) {
|
||||
if (e.x > width - 20 && e.y < 20) {
|
||||
text = ""
|
||||
onSearch(text)
|
||||
SwingUtilities.invokeLater {
|
||||
repaint()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Timer(500) { _ ->
|
||||
cursorVisible = !cursorVisible
|
||||
SwingUtilities.invokeLater {
|
||||
repaint()
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
override fun paint(g: Graphics) {
|
||||
super.paint(g)
|
||||
g.color = foreground
|
||||
g.font = font
|
||||
|
||||
val fm = g.fontMetrics
|
||||
val cursorX = fm.stringWidth(text) + 30
|
||||
|
||||
// Draw magnifying glass icon
|
||||
imageCanvas.let { canvas ->
|
||||
val imgG = g.create(5, 5, canvas.width, canvas.height)
|
||||
canvas.paint(imgG)
|
||||
imgG.dispose()
|
||||
}
|
||||
|
||||
// Use a local copy of the text to avoid threading issues
|
||||
val currentText = text
|
||||
|
||||
// Draw placeholder text if field is empty, otherwise draw actual text
|
||||
if (currentText.isEmpty()) {
|
||||
g.color = Color.GRAY // Use a lighter color for placeholder text
|
||||
g.drawString(placeholderText, 30, 20)
|
||||
} else {
|
||||
g.color = foreground // Use normal color for actual text
|
||||
g.drawString(currentText, 30, 20)
|
||||
}
|
||||
|
||||
if (cursorVisible && hasFocus()) {
|
||||
g.color = foreground
|
||||
g.drawLine(cursorX, 5, cursorX, 25)
|
||||
}
|
||||
|
||||
// Only draw the "x" button if there's text
|
||||
if (currentText.isNotEmpty()) {
|
||||
g.color = Color.RED
|
||||
g.drawString("x", width - 20, 20)
|
||||
}
|
||||
}
|
||||
|
||||
fun setText(newText: String) {
|
||||
text = newText
|
||||
repaint()
|
||||
}
|
||||
|
||||
fun getText(): String = text
|
||||
}
|
||||
|
|
@ -0,0 +1,231 @@
|
|||
package KondoKit.components
|
||||
|
||||
import KondoKit.Helpers
|
||||
import KondoKit.Helpers.FieldNotifier
|
||||
import KondoKit.plugin.Companion.WIDGET_COLOR
|
||||
import KondoKit.plugin.Companion.primaryColor
|
||||
import KondoKit.plugin.Companion.secondaryColor
|
||||
import plugin.Plugin
|
||||
import java.awt.*
|
||||
import java.awt.event.MouseAdapter
|
||||
import java.awt.event.MouseEvent
|
||||
import java.util.*
|
||||
import java.util.Timer
|
||||
import javax.swing.*
|
||||
|
||||
class SettingsPanel(private val plugin: Plugin) : JPanel() {
|
||||
|
||||
init {
|
||||
layout = BoxLayout(this, BoxLayout.Y_AXIS)
|
||||
background = WIDGET_COLOR
|
||||
border = BorderFactory.createEmptyBorder(10, 10, 10, 10)
|
||||
}
|
||||
|
||||
fun addSettingsFromPlugin() {
|
||||
val fieldNotifier = FieldNotifier(plugin)
|
||||
val exposedFields = plugin.javaClass.declaredFields.filter { field ->
|
||||
field.annotations.any { annotation ->
|
||||
annotation.annotationClass.simpleName == "Exposed"
|
||||
}
|
||||
}
|
||||
|
||||
if (exposedFields.isNotEmpty()) {
|
||||
for (field in exposedFields) {
|
||||
field.isAccessible = true
|
||||
|
||||
// Get the "Exposed" annotation specifically and retrieve its description, if available
|
||||
val exposedAnnotation = field.annotations.firstOrNull { annotation ->
|
||||
annotation.annotationClass.simpleName == "Exposed"
|
||||
}
|
||||
|
||||
val description = exposedAnnotation?.let { annotation ->
|
||||
try {
|
||||
val descriptionField = annotation.annotationClass.java.getMethod("description")
|
||||
descriptionField.invoke(annotation) as String
|
||||
} catch (e: NoSuchMethodException) {
|
||||
"" // No description method, return empty string
|
||||
}
|
||||
} ?: ""
|
||||
|
||||
val fieldPanel = JPanel().apply {
|
||||
layout = GridBagLayout()
|
||||
background = WIDGET_COLOR
|
||||
foreground = secondaryColor
|
||||
border = BorderFactory.createEmptyBorder(5, 0, 5, 0)
|
||||
maximumSize = Dimension(Int.MAX_VALUE, 50)
|
||||
}
|
||||
|
||||
val gbc = GridBagConstraints().apply {
|
||||
insets = Insets(0, 5, 0, 5)
|
||||
}
|
||||
|
||||
val label = JLabel(field.name.capitalize()).apply {
|
||||
foreground = secondaryColor
|
||||
font = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
||||
}
|
||||
gbc.gridx = 0
|
||||
gbc.gridy = 0
|
||||
gbc.weightx = 0.0
|
||||
gbc.anchor = GridBagConstraints.WEST
|
||||
fieldPanel.add(label, gbc)
|
||||
|
||||
// Create appropriate input component based on field type
|
||||
val inputComponent: JComponent = when {
|
||||
field.type == Boolean::class.javaPrimitiveType || field.type == java.lang.Boolean::class.java ->
|
||||
JCheckBox().apply {
|
||||
isSelected = field.get(plugin) as Boolean
|
||||
}
|
||||
|
||||
field.type.isEnum ->
|
||||
JComboBox((field.type.enumConstants as Array<Enum<*>>)).apply {
|
||||
selectedItem = field.get(plugin)
|
||||
}
|
||||
|
||||
field.type == Int::class.javaPrimitiveType || field.type == Integer::class.java ->
|
||||
JSpinner(SpinnerNumberModel(field.get(plugin) as Int, Int.MIN_VALUE, Int.MAX_VALUE, 1))
|
||||
|
||||
field.type == Float::class.javaPrimitiveType ||
|
||||
field.type == Double::class.javaPrimitiveType ||
|
||||
field.type == java.lang.Float::class.java ||
|
||||
field.type == java.lang.Double::class.java ->
|
||||
JSpinner(SpinnerNumberModel((field.get(plugin) as Number).toDouble(), -Double.MAX_VALUE, Double.MAX_VALUE, 0.1))
|
||||
|
||||
else ->
|
||||
JTextField(field.get(plugin)?.toString() ?: "")
|
||||
}
|
||||
|
||||
// Add mouse listener to the label only if a description is available
|
||||
if (description.isNotBlank()) {
|
||||
label.cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)
|
||||
label.addMouseListener(object : MouseAdapter() {
|
||||
override fun mouseEntered(e: MouseEvent) {
|
||||
showCustomToolTip(description, label)
|
||||
}
|
||||
|
||||
override fun mouseExited(e: MouseEvent) {
|
||||
customToolTipWindow?.isVisible = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
gbc.gridx = 1
|
||||
gbc.gridy = 0
|
||||
gbc.weightx = 1.0
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL
|
||||
fieldPanel.add(inputComponent, gbc)
|
||||
|
||||
val applyButton = JButton("\u2714").apply {
|
||||
maximumSize = Dimension(Int.MAX_VALUE, 8)
|
||||
}
|
||||
gbc.gridx = 2
|
||||
gbc.gridy = 0
|
||||
gbc.weightx = 0.0
|
||||
gbc.fill = GridBagConstraints.NONE
|
||||
applyButton.addActionListener {
|
||||
try {
|
||||
val newValue = when (inputComponent) {
|
||||
is JCheckBox -> inputComponent.isSelected
|
||||
is JComboBox<*> -> inputComponent.selectedItem
|
||||
is JSpinner -> inputComponent.value
|
||||
is JTextField -> Helpers.convertValue(field.type, field.genericType, inputComponent.text)
|
||||
else -> throw IllegalArgumentException("Unsupported input component type")
|
||||
}
|
||||
fieldNotifier.setFieldValue(field, newValue)
|
||||
Helpers.showToast(
|
||||
this@SettingsPanel,
|
||||
"${field.name} updated successfully!"
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Helpers.showToast(
|
||||
this@SettingsPanel,
|
||||
"Failed to update ${field.name}: ${e.message}",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fieldPanel.add(applyButton, gbc)
|
||||
add(fieldPanel)
|
||||
|
||||
// Track field changes in real-time and update UI
|
||||
var previousValue = field.get(plugin)?.toString()
|
||||
val timer = Timer()
|
||||
timer.schedule(object : TimerTask() {
|
||||
override fun run() {
|
||||
val currentValue = field.get(plugin)?.toString()
|
||||
if (currentValue != previousValue) {
|
||||
previousValue = currentValue
|
||||
SwingUtilities.invokeLater {
|
||||
// Update the inputComponent based on the new value
|
||||
when (inputComponent) {
|
||||
is JCheckBox -> inputComponent.isSelected = field.get(plugin) as Boolean
|
||||
is JComboBox<*> -> inputComponent.selectedItem = field.get(plugin)
|
||||
is JSpinner -> inputComponent.value = field.get(plugin)
|
||||
is JTextField -> inputComponent.text = field.get(plugin)?.toString() ?: ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 0, 1000) // Poll every 1000 milliseconds (1 second)
|
||||
}
|
||||
|
||||
if (exposedFields.isNotEmpty()) {
|
||||
add(Box.createVerticalStrut(5))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
var customToolTipWindow: JWindow? = null
|
||||
|
||||
fun showCustomToolTip(text: String, component: JComponent) {
|
||||
val _font = Font("RuneScape Small", Font.PLAIN, 16)
|
||||
val maxWidth = 150
|
||||
val lineHeight = 16
|
||||
|
||||
// Create a dummy JLabel to get FontMetrics for the font used in the tooltip
|
||||
val dummyLabel = JLabel()
|
||||
dummyLabel.font = _font
|
||||
val fontMetrics = dummyLabel.getFontMetrics(_font)
|
||||
|
||||
// Calculate the approximate width of the text
|
||||
val textWidth = fontMetrics.stringWidth(text)
|
||||
|
||||
// Calculate the number of lines required based on the text width and max tooltip width
|
||||
val numberOfLines = Math.ceil(textWidth.toDouble() / maxWidth).toInt()
|
||||
|
||||
// Calculate the required height of the tooltip
|
||||
val requiredHeight = numberOfLines * lineHeight + 6 // Adding some padding
|
||||
|
||||
if (customToolTipWindow == null) {
|
||||
customToolTipWindow = JWindow().apply {
|
||||
val bgColor = Helpers.colorToHex(KondoKit.plugin.Companion.TOOLTIP_BACKGROUND)
|
||||
val textColor = Helpers.colorToHex(KondoKit.plugin.Companion.secondaryColor)
|
||||
contentPane = JLabel("<html><div style='color: $textColor; background-color: $bgColor; padding: 3px; word-break: break-all;'>$text</div></html>").apply {
|
||||
border = BorderFactory.createLineBorder(Color.BLACK)
|
||||
isOpaque = true
|
||||
background = KondoKit.plugin.Companion.TOOLTIP_BACKGROUND
|
||||
foreground = Color.WHITE
|
||||
font = _font
|
||||
maximumSize = Dimension(maxWidth, Int.MAX_VALUE)
|
||||
preferredSize = Dimension(maxWidth, requiredHeight)
|
||||
}
|
||||
pack()
|
||||
}
|
||||
} else {
|
||||
// Update the tooltip text
|
||||
val label = customToolTipWindow!!.contentPane as JLabel
|
||||
val bgColor = Helpers.colorToHex(KondoKit.plugin.Companion.TOOLTIP_BACKGROUND)
|
||||
val textColor = Helpers.colorToHex(KondoKit.plugin.Companion.secondaryColor)
|
||||
label.text = "<html><div style='color: $textColor; background-color: $bgColor; padding: 3px; word-break: break-all;'>$text</div></html>"
|
||||
label.preferredSize = Dimension(maxWidth, requiredHeight)
|
||||
customToolTipWindow!!.pack()
|
||||
}
|
||||
|
||||
// Position the tooltip near the component
|
||||
val locationOnScreen = component.locationOnScreen
|
||||
customToolTipWindow!!.setLocation(locationOnScreen.x, locationOnScreen.y + 15)
|
||||
customToolTipWindow!!.isVisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
package KondoKit.components
|
||||
|
||||
import java.awt.*
|
||||
import java.awt.event.MouseAdapter
|
||||
import java.awt.event.MouseEvent
|
||||
import java.awt.image.BufferedImage
|
||||
import javax.swing.JPanel
|
||||
|
||||
class ToggleSwitch : JPanel() {
|
||||
private var activated = false
|
||||
private var switchColor = Color(200, 200, 200)
|
||||
private var buttonColor = Color(255, 255, 255)
|
||||
private var borderColor = Color(50, 50, 50)
|
||||
private var activeSwitch = Color(0, 125, 255)
|
||||
private var puffer: BufferedImage? = null
|
||||
private var g: Graphics2D? = null
|
||||
|
||||
var onToggleListener: ((Boolean) -> Unit)? = null
|
||||
|
||||
init {
|
||||
isVisible = true
|
||||
addMouseListener(object : MouseAdapter() {
|
||||
override fun mouseReleased(arg0: MouseEvent) {
|
||||
activated = !activated
|
||||
onToggleListener?.invoke(activated)
|
||||
repaint()
|
||||
}
|
||||
})
|
||||
cursor = Cursor(Cursor.HAND_CURSOR)
|
||||
preferredSize = Dimension(32, 20)
|
||||
maximumSize = Dimension(32, 20)
|
||||
minimumSize = Dimension(32, 20)
|
||||
isOpaque = false // Make the panel background transparent
|
||||
}
|
||||
|
||||
override fun paint(gr: Graphics) {
|
||||
if (g == null || puffer?.width != width || puffer?.height != height) {
|
||||
puffer = BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB)
|
||||
g = puffer?.createGraphics()
|
||||
val rh = RenderingHints(
|
||||
RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON
|
||||
)
|
||||
g?.setRenderingHints(rh)
|
||||
}
|
||||
|
||||
// Clear the buffer with transparent background
|
||||
g?.color = Color(0, 0, 0, 0)
|
||||
g?.fillRect(0, 0, width, height)
|
||||
|
||||
// Draw the track with circular ends (rounded rectangle)
|
||||
val trackHeight = height - 2
|
||||
val trackWidth = width - 2
|
||||
val trackArc = trackHeight // Makes it fully rounded at the ends
|
||||
|
||||
g?.color = if (activated) activeSwitch else switchColor
|
||||
g?.fillRoundRect(1, 1, trackWidth, trackHeight, trackArc, trackArc)
|
||||
g?.color = borderColor
|
||||
g?.drawRoundRect(1, 1, trackWidth, trackHeight, trackArc, trackArc)
|
||||
|
||||
// Draw the thumb (circular button)
|
||||
val thumbDiameter = trackHeight - 4
|
||||
val thumbX = if (activated) {
|
||||
width - thumbDiameter - 3 // Right side when activated
|
||||
} else {
|
||||
3 // Left side when not activated
|
||||
}
|
||||
val thumbY = (height - thumbDiameter) / 2
|
||||
|
||||
g?.color = buttonColor
|
||||
g?.fillOval(thumbX, thumbY, thumbDiameter, thumbDiameter)
|
||||
g?.color = borderColor
|
||||
g?.drawOval(thumbX, thumbY, thumbDiameter, thumbDiameter)
|
||||
|
||||
gr.drawImage(puffer, 0, 0, null)
|
||||
}
|
||||
|
||||
fun isActivated(): Boolean {
|
||||
return activated
|
||||
}
|
||||
|
||||
fun setActivated(activated: Boolean) {
|
||||
this.activated = activated
|
||||
repaint()
|
||||
}
|
||||
|
||||
fun getSwitchColor(): Color {
|
||||
return switchColor
|
||||
}
|
||||
|
||||
/**
|
||||
* Unactivated Background Color of switch
|
||||
*/
|
||||
fun setSwitchColor(switchColor: Color) {
|
||||
this.switchColor = switchColor
|
||||
}
|
||||
|
||||
fun getButtonColor(): Color {
|
||||
return buttonColor
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch-Button color
|
||||
*/
|
||||
fun setButtonColor(buttonColor: Color) {
|
||||
this.buttonColor = buttonColor
|
||||
}
|
||||
|
||||
fun getBorderColor(): Color {
|
||||
return borderColor
|
||||
}
|
||||
|
||||
/**
|
||||
* Border-color of whole switch and switch-button
|
||||
*/
|
||||
fun setBorderColor(borderColor: Color) {
|
||||
this.borderColor = borderColor
|
||||
}
|
||||
|
||||
fun getActiveSwitch(): Color {
|
||||
return activeSwitch
|
||||
}
|
||||
|
||||
fun setActiveSwitch(activeSwitch: Color) {
|
||||
this.activeSwitch = activeSwitch
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package KondoKit.components
|
||||
|
||||
import KondoKit.plugin.Companion.TITLE_BAR_COLOR
|
||||
import KondoKit.plugin.Companion.secondaryColor
|
||||
import java.awt.*
|
||||
import javax.swing.*
|
||||
|
||||
class ViewHeader(
|
||||
title: String,
|
||||
private val headerHeight: Int = 40
|
||||
) : JPanel() {
|
||||
|
||||
private val titleLabel = JLabel(title)
|
||||
|
||||
init {
|
||||
background = TITLE_BAR_COLOR
|
||||
preferredSize = Dimension(Int.MAX_VALUE, headerHeight)
|
||||
border = BorderFactory.createEmptyBorder(5, 10, 5, 10)
|
||||
layout = BorderLayout()
|
||||
|
||||
titleLabel.foreground = secondaryColor
|
||||
titleLabel.font = Font("RuneScape Small", Font.PLAIN, 16)
|
||||
titleLabel.horizontalAlignment = SwingConstants.CENTER
|
||||
|
||||
add(titleLabel, BorderLayout.CENTER)
|
||||
}
|
||||
|
||||
fun setTitle(title: String) {
|
||||
titleLabel.text = title
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package KondoKit.components
|
||||
|
||||
import KondoKit.plugin.Companion.WIDGET_COLOR
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Dimension
|
||||
import javax.swing.BorderFactory
|
||||
import javax.swing.JPanel
|
||||
|
||||
class WidgetPanel(
|
||||
private val widgetWidth: Int = 220,
|
||||
private val widgetHeight: Int = 50,
|
||||
private val addDefaultPadding: Boolean = true
|
||||
) : JPanel() {
|
||||
|
||||
init {
|
||||
layout = BorderLayout(5, 5)
|
||||
background = WIDGET_COLOR
|
||||
|
||||
val size = Dimension(widgetWidth, widgetHeight)
|
||||
preferredSize = size
|
||||
maximumSize = size
|
||||
minimumSize = size
|
||||
|
||||
if (addDefaultPadding) {
|
||||
border = BorderFactory.createEmptyBorder(5, 5, 5, 5)
|
||||
}
|
||||
}
|
||||
|
||||
fun setFixedSize(width: Int, height: Int) {
|
||||
val size = Dimension(width, height)
|
||||
preferredSize = size
|
||||
maximumSize = size
|
||||
minimumSize = size
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue