mirror of
https://gitlab.com/2009scape/rt4-client.git
synced 2025-12-15 02:50:23 -07:00
More helpers/DRY
This commit is contained in:
parent
573e579643
commit
47e545cbc7
17 changed files with 264 additions and 289 deletions
|
|
@ -0,0 +1,14 @@
|
|||
package KondoKit
|
||||
|
||||
import java.awt.Component
|
||||
import java.awt.Dimension
|
||||
|
||||
fun <T : Component> T.setFixedSize(width: Int, height: Int): T =
|
||||
setFixedSize(Dimension(width, height))
|
||||
|
||||
fun <T : Component> T.setFixedSize(size: Dimension): T {
|
||||
preferredSize = size
|
||||
minimumSize = size
|
||||
maximumSize = size
|
||||
return this
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@ import java.lang.reflect.Type
|
|||
import java.util.*
|
||||
import java.util.Timer
|
||||
import javax.swing.*
|
||||
import KondoKit.setFixedSize
|
||||
|
||||
object Helpers {
|
||||
// Convenience helper for loading resources relative to the KondoKit plugin class
|
||||
|
|
@ -35,9 +36,7 @@ object Helpers {
|
|||
componentPosition: String = BorderLayout.NORTH
|
||||
): ImageCanvasComponents {
|
||||
val imageCanvas = ImageCanvas(bufferedImage).apply {
|
||||
preferredSize = size
|
||||
minimumSize = size
|
||||
maximumSize = size
|
||||
setFixedSize(size)
|
||||
this.size = size
|
||||
this.background = background
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import KondoKit.ViewConstants
|
|||
import KondoKit.plugin.Companion.TITLE_BAR_COLOR
|
||||
import KondoKit.plugin.Companion.WIDGET_COLOR
|
||||
import KondoKit.plugin.Companion.secondaryColor
|
||||
import KondoKit.components.UiStyler.button
|
||||
import KondoKit.components.UiStyler.ButtonDefaults
|
||||
import java.awt.*
|
||||
import javax.swing.*
|
||||
|
||||
|
|
@ -18,29 +20,25 @@ class ButtonPanel(
|
|||
background = WIDGET_COLOR
|
||||
}
|
||||
|
||||
fun addButton(text: String, action: () -> Unit): JButton {
|
||||
val button = JButton(text).apply {
|
||||
background = TITLE_BAR_COLOR
|
||||
foreground = secondaryColor
|
||||
fun addButton(text: String, action: () -> Unit): JButton =
|
||||
createAndAddButton(text = text, action = action)
|
||||
|
||||
fun addIcon(icon: Icon, action: () -> Unit): JButton =
|
||||
createAndAddButton(icon = icon, action = action)
|
||||
|
||||
private fun createAndAddButton(
|
||||
text: String? = null,
|
||||
icon: Icon? = null,
|
||||
action: () -> Unit
|
||||
): JButton {
|
||||
val defaults = ButtonDefaults(
|
||||
background = TITLE_BAR_COLOR,
|
||||
foreground = secondaryColor,
|
||||
font = ViewConstants.FONT_RUNESCAPE_SMALL_14
|
||||
addActionListener {
|
||||
action()
|
||||
}
|
||||
)
|
||||
|
||||
return button(text = text, icon = icon, defaults = defaults, onClick = action).also {
|
||||
add(it)
|
||||
}
|
||||
add(button)
|
||||
return button
|
||||
}
|
||||
|
||||
fun addIcon(icon: Icon, action: () -> Unit): JButton {
|
||||
val button = JButton(icon).apply {
|
||||
background = TITLE_BAR_COLOR
|
||||
foreground = secondaryColor
|
||||
font = ViewConstants.FONT_RUNESCAPE_SMALL_14
|
||||
addActionListener {
|
||||
action()
|
||||
}
|
||||
}
|
||||
add(button)
|
||||
return button
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ package KondoKit.components
|
|||
|
||||
import KondoKit.ImageCanvas
|
||||
import KondoKit.SpriteToBufferedImage
|
||||
import KondoKit.setFixedSize
|
||||
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
|
||||
|
||||
|
|
@ -36,10 +36,7 @@ class IconComponent(
|
|||
)
|
||||
|
||||
imageCanvas = ImageCanvas(bufferedImageSprite).apply {
|
||||
val size = Dimension(iconWidth, iconHeight)
|
||||
preferredSize = size
|
||||
maximumSize = size
|
||||
minimumSize = size
|
||||
setFixedSize(iconWidth, iconHeight)
|
||||
background = if (useThemeColors) WIDGET_COLOR else Color.WHITE
|
||||
}
|
||||
|
||||
|
|
@ -57,4 +54,4 @@ class IconComponent(
|
|||
fun applyThemeColors() {
|
||||
updateFillColor(WIDGET_COLOR)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
package KondoKit.components
|
||||
|
||||
import KondoKit.ViewConstants
|
||||
import KondoKit.components.UiStyler.menuItem
|
||||
import KondoKit.plugin.Companion.POPUP_BACKGROUND
|
||||
import KondoKit.plugin.Companion.POPUP_FOREGROUND
|
||||
import javax.swing.JMenuItem
|
||||
import javax.swing.JPopupMenu
|
||||
|
||||
|
|
@ -13,15 +12,8 @@ class PopupMenuComponent : JPopupMenu() {
|
|||
}
|
||||
|
||||
fun addMenuItem(text: String, action: () -> Unit): JMenuItem {
|
||||
val menuItem = JMenuItem(text).apply {
|
||||
font = ViewConstants.FONT_RUNESCAPE_SMALL_16
|
||||
background = POPUP_BACKGROUND
|
||||
foreground = POPUP_FOREGROUND
|
||||
addActionListener {
|
||||
action()
|
||||
}
|
||||
}
|
||||
add(menuItem)
|
||||
return menuItem
|
||||
val item = menuItem(text = text, onClick = action)
|
||||
add(item)
|
||||
return item
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package KondoKit.components
|
|||
import KondoKit.ImageCanvas
|
||||
import KondoKit.ViewConstants
|
||||
import KondoKit.SpriteToBufferedImage
|
||||
import KondoKit.setFixedSize
|
||||
import KondoKit.plugin.Companion.WIDGET_COLOR
|
||||
import KondoKit.plugin.Companion.secondaryColor
|
||||
import KondoKit.plugin.StateManager.focusedView
|
||||
|
|
@ -27,22 +28,18 @@ class SearchField(
|
|||
private val bufferedImageSprite = SpriteToBufferedImage.getBufferedImageFromSprite(API.GetSprite(1423)) // MAG_SPRITE
|
||||
private val imageCanvas = bufferedImageSprite.let {
|
||||
ImageCanvas(it).apply {
|
||||
preferredSize = ViewConstants.DIMENSION_SMALL_ICON
|
||||
setFixedSize(ViewConstants.DIMENSION_SMALL_ICON)
|
||||
size = preferredSize
|
||||
minimumSize = preferredSize
|
||||
maximumSize = preferredSize
|
||||
fillColor = WIDGET_COLOR
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
val dimension = Dimension(fieldWidth, fieldHeight)
|
||||
preferredSize = dimension
|
||||
setFixedSize(dimension)
|
||||
background = WIDGET_COLOR
|
||||
foreground = secondaryColor
|
||||
font = ViewConstants.FONT_ARIAL_PLAIN_14
|
||||
minimumSize = dimension
|
||||
maximumSize = dimension
|
||||
|
||||
isFocusable = true
|
||||
focusTraversalKeysEnabled = false
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package KondoKit.components
|
|||
import KondoKit.Helpers
|
||||
import KondoKit.Helpers.FieldNotifier
|
||||
import KondoKit.ViewConstants
|
||||
import KondoKit.components.UiStyler
|
||||
import KondoKit.setFixedSize
|
||||
import KondoKit.plugin.Companion.WIDGET_COLOR
|
||||
import KondoKit.plugin.Companion.primaryColor
|
||||
import KondoKit.plugin.Companion.secondaryColor
|
||||
|
|
@ -10,6 +12,7 @@ import plugin.Plugin
|
|||
import java.awt.*
|
||||
import java.awt.event.MouseAdapter
|
||||
import java.awt.event.MouseEvent
|
||||
import java.lang.reflect.Field
|
||||
import java.util.*
|
||||
import java.util.Timer
|
||||
import javax.swing.*
|
||||
|
|
@ -36,18 +39,7 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
|
|||
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 description = field.exposedDescription()
|
||||
|
||||
val fieldPanel = JPanel().apply {
|
||||
layout = GridBagLayout()
|
||||
|
|
@ -104,7 +96,7 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
|
|||
}
|
||||
|
||||
// Check if the field is a HashMap
|
||||
field.type == HashMap::class.java || field.type.simpleName == "HashMap" -> {
|
||||
field.isHashMapType() -> {
|
||||
inputComponent = createHashMapEditor(field, plugin, fieldNotifier)
|
||||
isHashMapEditor = true
|
||||
}
|
||||
|
|
@ -141,42 +133,45 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
|
|||
fieldPanel.add(inputComponent, gbc)
|
||||
|
||||
// Add apply button for non-HashMap editors
|
||||
val applyButton = JButton("\u2714").apply {
|
||||
maximumSize = Dimension(Int.MAX_VALUE, 8)
|
||||
val applyButton = UiStyler.button(
|
||||
text = "\u2714",
|
||||
onClick = {
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
).also {
|
||||
it.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 (skip HashMap fields)
|
||||
if (field.type != HashMap::class.java && field.type.simpleName != "HashMap") {
|
||||
if (!field.isHashMapType()) {
|
||||
var previousValue = field.get(plugin)?.toString()
|
||||
val timer = Timer()
|
||||
timer.schedule(object : TimerTask() {
|
||||
|
|
@ -205,7 +200,7 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun createHashMapEditor(field: java.lang.reflect.Field, plugin: Plugin, fieldNotifier: FieldNotifier): JComponent {
|
||||
private fun createHashMapEditor(field: Field, plugin: Plugin, fieldNotifier: FieldNotifier): JComponent {
|
||||
// Create a panel to hold the table and buttons
|
||||
val editorPanel = JPanel()
|
||||
editorPanel.layout = BoxLayout(editorPanel, BoxLayout.Y_AXIS)
|
||||
|
|
@ -213,19 +208,7 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
|
|||
editorPanel.border = BorderFactory.createEmptyBorder(5, 0, 5, 0)
|
||||
editorPanel.maximumSize = Dimension(Int.MAX_VALUE, 250)
|
||||
|
||||
// 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 description = field.exposedDescription()
|
||||
|
||||
// Create title label
|
||||
val titleLabel = JLabel("${field.name} (Key-Value Pairs)").apply {
|
||||
|
|
@ -288,9 +271,7 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
|
|||
|
||||
// Create a scroll pane for the table with fixed size
|
||||
val scrollPane = JScrollPane(table).apply {
|
||||
preferredSize = Dimension(Int.MAX_VALUE, 150)
|
||||
maximumSize = preferredSize
|
||||
minimumSize = preferredSize
|
||||
setFixedSize(Dimension(Int.MAX_VALUE, 150))
|
||||
background = WIDGET_COLOR
|
||||
verticalScrollBarPolicy = JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
|
||||
horizontalScrollBarPolicy = JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
|
||||
|
|
@ -304,9 +285,9 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
|
|||
}
|
||||
|
||||
// Add button
|
||||
val addButton = JButton("+").apply {
|
||||
maximumSize = Dimension(40, 30)
|
||||
addActionListener {
|
||||
val addButton = UiStyler.button(
|
||||
text = "+",
|
||||
onClick = {
|
||||
val vector = java.util.Vector<Any>()
|
||||
vector.add("")
|
||||
vector.add("")
|
||||
|
|
@ -317,12 +298,14 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
|
|||
table.editCellAt(newRow, 0)
|
||||
table.editorComponent?.requestFocus()
|
||||
}
|
||||
).apply {
|
||||
setFixedSize(40, 30)
|
||||
}
|
||||
|
||||
|
||||
// Remove button
|
||||
val removeButton = JButton("-").apply {
|
||||
maximumSize = Dimension(40, 30)
|
||||
addActionListener {
|
||||
val removeButton = UiStyler.button(
|
||||
text = "-",
|
||||
onClick = {
|
||||
val selectedRow = table.selectedRow
|
||||
if (selectedRow >= 0) {
|
||||
tableModel.removeRow(selectedRow)
|
||||
|
|
@ -334,51 +317,53 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
|
|||
)
|
||||
}
|
||||
}
|
||||
).apply {
|
||||
setFixedSize(40, 30)
|
||||
}
|
||||
|
||||
|
||||
// Apply button
|
||||
val applyButton = JButton("Apply Changes").apply {
|
||||
maximumSize = Dimension(120, 30)
|
||||
addActionListener {
|
||||
val applyButton = UiStyler.button(
|
||||
text = "Apply Changes",
|
||||
onClick = {
|
||||
try {
|
||||
// Commit any active cell editing before reading values
|
||||
if (table.isEditing) {
|
||||
table.cellEditor.stopCellEditing()
|
||||
}
|
||||
|
||||
|
||||
// Get the current HashMap from the field and modify it in place
|
||||
val currentHashMap = field.get(plugin) as? HashMap<Any, Any> ?: HashMap<Any, Any>()
|
||||
|
||||
|
||||
// Clear the current HashMap
|
||||
currentHashMap.clear()
|
||||
|
||||
|
||||
// Add the new entries from the table to the existing HashMap
|
||||
for (i in 0 until tableModel.rowCount) {
|
||||
val key = tableModel.getValueAt(i, 0).toString()
|
||||
val value = tableModel.getValueAt(i, 1).toString()
|
||||
// Only add non-empty keys
|
||||
if (key.isNotBlank()) {
|
||||
// Skip empty values
|
||||
if (value.isBlank()) {
|
||||
Helpers.showToast(
|
||||
this@SettingsPanel,
|
||||
"Skipping entry with empty value for key '$key'",
|
||||
JOptionPane.WARNING_MESSAGE
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
// Try to convert the value to the appropriate type based on the field's generic type
|
||||
val convertedValue = try {
|
||||
// For HashMap<String, Int> - treat all HashMap<String, Int> fields the same way regardless of plugin
|
||||
val fieldTypeName = field.genericType.toString()
|
||||
if (fieldTypeName.contains("java.util.HashMap<java.lang.String, java.lang.Integer>") ||
|
||||
fieldTypeName.contains("HashMap<String, Int>") ||
|
||||
fieldTypeName.contains("HashMap<String, Integer>")) {
|
||||
|
||||
if (key.isBlank()) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (value.isBlank()) {
|
||||
Helpers.showToast(
|
||||
this@SettingsPanel,
|
||||
"Skipping entry with empty value for key '$key'",
|
||||
JOptionPane.WARNING_MESSAGE
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
val convertedValue = try {
|
||||
val fieldTypeName = field.genericType.toString()
|
||||
when {
|
||||
fieldTypeName.contains("java.util.HashMap<java.lang.String, java.lang.Integer>") ||
|
||||
fieldTypeName.contains("HashMap<String, Int>") ||
|
||||
fieldTypeName.contains("HashMap<String, Integer>") -> {
|
||||
try {
|
||||
val intValue = value.toInt()
|
||||
intValue
|
||||
} catch (e: NumberFormatException) {
|
||||
value.toInt()
|
||||
} catch (numberFormat: NumberFormatException) {
|
||||
Helpers.showToast(
|
||||
this@SettingsPanel,
|
||||
"Invalid number format for key '$key': '$value'. Using 0 as default.",
|
||||
|
|
@ -386,38 +371,20 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
|
|||
)
|
||||
0
|
||||
}
|
||||
}
|
||||
// For other numeric types
|
||||
else if (fieldTypeName.contains("java.lang.Integer") ||
|
||||
fieldTypeName.contains("int")) {
|
||||
value.toInt()
|
||||
}
|
||||
else if (fieldTypeName.contains("java.lang.Double") ||
|
||||
fieldTypeName.contains("double")) {
|
||||
value.toDouble()
|
||||
}
|
||||
else if (fieldTypeName.contains("java.lang.Float") ||
|
||||
fieldTypeName.contains("float")) {
|
||||
value.toFloat()
|
||||
}
|
||||
else if (fieldTypeName.contains("java.lang.Boolean") ||
|
||||
fieldTypeName.contains("boolean")) {
|
||||
value.toBoolean()
|
||||
}
|
||||
// Default to string for other types
|
||||
else {
|
||||
value
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// If conversion fails, keep as string
|
||||
value
|
||||
fieldTypeName.contains("java.lang.Integer") || fieldTypeName.contains("int") -> value.toInt()
|
||||
fieldTypeName.contains("java.lang.Double") || fieldTypeName.contains("double") -> value.toDouble()
|
||||
fieldTypeName.contains("java.lang.Float") || fieldTypeName.contains("float") -> value.toFloat()
|
||||
fieldTypeName.contains("java.lang.Boolean") || fieldTypeName.contains("boolean") -> value.toBoolean()
|
||||
else -> value
|
||||
}
|
||||
currentHashMap[key] = convertedValue
|
||||
} catch (e: Exception) {
|
||||
value
|
||||
}
|
||||
|
||||
currentHashMap[key] = convertedValue
|
||||
}
|
||||
|
||||
// Update the field to trigger notifications (even though the reference is the same)
|
||||
// This ensures OnKondoValueUpdated() gets called if it exists
|
||||
|
||||
fieldNotifier.setFieldValue(field, currentHashMap)
|
||||
Helpers.showToast(
|
||||
this@SettingsPanel,
|
||||
|
|
@ -431,6 +398,8 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
|
|||
)
|
||||
}
|
||||
}
|
||||
).apply {
|
||||
setFixedSize(120, 30)
|
||||
}
|
||||
|
||||
buttonsPanel.add(addButton)
|
||||
|
|
@ -447,7 +416,24 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
|
|||
|
||||
return editorPanel
|
||||
}
|
||||
|
||||
|
||||
private fun Field.exposedDescription(): String {
|
||||
val exposedAnnotation = annotations.firstOrNull {
|
||||
it.annotationClass.simpleName == "Exposed"
|
||||
} ?: return ""
|
||||
|
||||
return try {
|
||||
val descriptionMethod = exposedAnnotation.annotationClass.java.getMethod("description")
|
||||
descriptionMethod.invoke(exposedAnnotation) as? String ?: ""
|
||||
} catch (_: Exception) {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
private fun Field.isHashMapType(): Boolean {
|
||||
return type == HashMap::class.java || type.simpleName == "HashMap"
|
||||
}
|
||||
|
||||
companion object {
|
||||
var customToolTipWindow: JWindow? = null
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import KondoKit.plugin.Companion.PROGRESS_BAR_FILL
|
|||
import KondoKit.plugin.Companion.WIDGET_COLOR
|
||||
import KondoKit.plugin.Companion.primaryColor
|
||||
import KondoKit.plugin.Companion.secondaryColor
|
||||
import KondoKit.setFixedSize
|
||||
import java.awt.*
|
||||
import java.awt.event.MouseAdapter
|
||||
import java.awt.event.MouseEvent
|
||||
|
|
@ -32,9 +33,7 @@ class ToggleSwitch : JPanel() {
|
|||
}
|
||||
})
|
||||
cursor = Cursor(Cursor.HAND_CURSOR)
|
||||
preferredSize = ViewConstants.TOGGLE_SWITCH_SIZE
|
||||
maximumSize = ViewConstants.TOGGLE_SWITCH_SIZE
|
||||
minimumSize = ViewConstants.TOGGLE_SWITCH_SIZE
|
||||
setFixedSize(ViewConstants.TOGGLE_SWITCH_SIZE)
|
||||
isOpaque = false // Make the panel background transparent
|
||||
}
|
||||
|
||||
|
|
@ -129,4 +128,4 @@ class ToggleSwitch : JPanel() {
|
|||
fun setActiveSwitch(activeSwitch: Color) {
|
||||
this.activeSwitch = activeSwitch
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
package KondoKit.components
|
||||
|
||||
import KondoKit.ViewConstants
|
||||
import KondoKit.plugin.Companion.POPUP_BACKGROUND
|
||||
import KondoKit.plugin.Companion.POPUP_FOREGROUND
|
||||
import KondoKit.plugin.Companion.TITLE_BAR_COLOR
|
||||
import KondoKit.plugin.Companion.secondaryColor
|
||||
import java.awt.Color
|
||||
import java.awt.Font
|
||||
import java.awt.Insets
|
||||
import javax.swing.AbstractButton
|
||||
import javax.swing.Icon
|
||||
import javax.swing.JButton
|
||||
import javax.swing.JMenuItem
|
||||
|
||||
/**
|
||||
* Centralises common Swing styling so buttons and menu items share a
|
||||
* consistent look and the setup code remains in one place.
|
||||
*/
|
||||
object UiStyler {
|
||||
|
||||
data class ButtonDefaults(
|
||||
val background: Color = TITLE_BAR_COLOR,
|
||||
val foreground: Color = secondaryColor,
|
||||
val font: Font = ViewConstants.FONT_RUNESCAPE_SMALL_14,
|
||||
val margin: Insets? = null
|
||||
)
|
||||
|
||||
data class MenuItemDefaults(
|
||||
val background: Color = POPUP_BACKGROUND,
|
||||
val foreground: Color = POPUP_FOREGROUND,
|
||||
val font: Font = ViewConstants.FONT_RUNESCAPE_SMALL_16
|
||||
)
|
||||
|
||||
fun <T : AbstractButton> T.applyDefaults(
|
||||
defaults: ButtonDefaults = ButtonDefaults(),
|
||||
onClick: (() -> Unit)? = null
|
||||
): T {
|
||||
background = defaults.background
|
||||
foreground = defaults.foreground
|
||||
font = defaults.font
|
||||
defaults.margin?.let { margin = it }
|
||||
onClick?.let { addActionListener { _ -> it() } }
|
||||
return this
|
||||
}
|
||||
|
||||
fun button(
|
||||
text: String? = null,
|
||||
icon: Icon? = null,
|
||||
defaults: ButtonDefaults = ButtonDefaults(),
|
||||
onClick: (() -> Unit)? = null
|
||||
): JButton {
|
||||
return JButton().apply {
|
||||
text?.let { this.text = it }
|
||||
icon?.let { this.icon = it }
|
||||
isOpaque = true
|
||||
applyDefaults(defaults, onClick)
|
||||
}
|
||||
}
|
||||
|
||||
fun menuItem(
|
||||
text: String,
|
||||
defaults: MenuItemDefaults = MenuItemDefaults(),
|
||||
onClick: (() -> Unit)? = null
|
||||
): JMenuItem {
|
||||
return JMenuItem(text).apply {
|
||||
background = defaults.background
|
||||
foreground = defaults.foreground
|
||||
font = defaults.font
|
||||
onClick?.let { addActionListener { _ -> it() } }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package KondoKit.components
|
||||
|
||||
import KondoKit.ViewConstants
|
||||
import KondoKit.setFixedSize
|
||||
import KondoKit.plugin.Companion.TITLE_BAR_COLOR
|
||||
import KondoKit.plugin.Companion.secondaryColor
|
||||
import java.awt.*
|
||||
|
|
@ -15,7 +16,7 @@ class ViewHeader(
|
|||
|
||||
init {
|
||||
background = TITLE_BAR_COLOR
|
||||
preferredSize = Dimension(Int.MAX_VALUE, headerHeight)
|
||||
setFixedSize(Int.MAX_VALUE, headerHeight)
|
||||
border = BorderFactory.createEmptyBorder(5, 10, 5, 10)
|
||||
layout = BorderLayout()
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package KondoKit.components
|
|||
|
||||
import KondoKit.ViewConstants
|
||||
import KondoKit.plugin.Companion.WIDGET_COLOR
|
||||
import KondoKit.setFixedSize
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Dimension
|
||||
import javax.swing.BorderFactory
|
||||
|
|
@ -25,9 +26,7 @@ class WidgetPanel(
|
|||
background = WIDGET_COLOR
|
||||
|
||||
val size = Dimension(widgetWidth, widgetHeight)
|
||||
preferredSize = size
|
||||
maximumSize = size
|
||||
minimumSize = size
|
||||
setFixedSize(size)
|
||||
|
||||
val top = paddingTop ?: if (addDefaultPadding) 5 else 0
|
||||
val left = paddingLeft ?: if (addDefaultPadding) 5 else 0
|
||||
|
|
@ -39,8 +38,6 @@ class WidgetPanel(
|
|||
|
||||
fun setFixedSize(width: Int, height: Int) {
|
||||
val size = Dimension(width, height)
|
||||
preferredSize = size
|
||||
maximumSize = size
|
||||
minimumSize = size
|
||||
this@WidgetPanel.setFixedSize(size)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -608,26 +608,20 @@ class plugin : Plugin() {
|
|||
// ImageCanvas with forced size
|
||||
val imageCanvas = ImageCanvas(bufferedImageSprite).apply {
|
||||
background = WIDGET_COLOR
|
||||
preferredSize = imageSize
|
||||
maximumSize = imageSize
|
||||
minimumSize = imageSize
|
||||
setFixedSize(imageSize)
|
||||
}
|
||||
|
||||
// Wrapping the ImageCanvas in another JPanel to prevent stretching
|
||||
val imageCanvasWrapper = JPanel().apply {
|
||||
layout = GridBagLayout() // Keeps the layout of the wrapped panel minimal
|
||||
preferredSize = imageSize
|
||||
maximumSize = imageSize
|
||||
minimumSize = imageSize
|
||||
setFixedSize(imageSize)
|
||||
isOpaque = false // No background for the wrapper
|
||||
add(imageCanvas) // Adding ImageCanvas directly, layout won't stretch it
|
||||
}
|
||||
|
||||
val panelButton = JPanel().apply {
|
||||
layout = GridBagLayout()
|
||||
preferredSize = buttonSize
|
||||
maximumSize = buttonSize
|
||||
minimumSize = buttonSize
|
||||
setFixedSize(buttonSize)
|
||||
background = WIDGET_COLOR
|
||||
isOpaque = true
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package KondoKit.views
|
|||
|
||||
import KondoKit.ViewConstants
|
||||
import KondoKit.plugin.Companion.VIEW_BACKGROUND_COLOR
|
||||
import java.awt.Dimension
|
||||
import KondoKit.setFixedSize
|
||||
import javax.swing.BorderFactory
|
||||
import javax.swing.Box
|
||||
import javax.swing.BoxLayout
|
||||
|
|
@ -26,9 +26,6 @@ open class BaseView(
|
|||
}
|
||||
|
||||
fun setViewSize(height: Int) {
|
||||
val dimension = Dimension(preferredWidth, height)
|
||||
preferredSize = dimension
|
||||
maximumSize = dimension
|
||||
minimumSize = dimension
|
||||
setFixedSize(preferredWidth, height)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,12 +6,11 @@ import KondoKit.Helpers.formatHtmlLabelText
|
|||
import KondoKit.ImageCanvas
|
||||
import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
|
||||
import KondoKit.ViewConstants
|
||||
import KondoKit.setFixedSize
|
||||
import KondoKit.views.XPTrackerView.wrappedWidget
|
||||
import KondoKit.components.PopupMenuComponent
|
||||
import KondoKit.components.ProgressBar
|
||||
import KondoKit.components.WidgetPanel
|
||||
import KondoKit.plugin.Companion.POPUP_BACKGROUND
|
||||
import KondoKit.plugin.Companion.POPUP_FOREGROUND
|
||||
import KondoKit.plugin.Companion.TITLE_BAR_COLOR
|
||||
import KondoKit.plugin.Companion.TOOLTIP_BACKGROUND
|
||||
import KondoKit.plugin.Companion.TOTAL_XP_WIDGET_SIZE
|
||||
|
|
@ -24,6 +23,7 @@ import KondoKit.plugin.StateManager.focusedView
|
|||
import plugin.api.API
|
||||
import rt4.*
|
||||
import java.awt.*
|
||||
import java.awt.Component
|
||||
import java.awt.Font
|
||||
import java.awt.event.MouseAdapter
|
||||
import java.awt.event.MouseEvent
|
||||
|
|
@ -252,10 +252,8 @@ object LootTrackerView : View, OnPostClientTickCallback, OnKillingBlowNPCCallbac
|
|||
val rowsNeeded = ceil(totalItems / 6.0).toInt()
|
||||
val lootPanelHeight = rowsNeeded * (40)
|
||||
|
||||
val size = Dimension(lootPanel.width,lootPanelHeight+32)
|
||||
lootPanel.parent.preferredSize = size
|
||||
lootPanel.parent.minimumSize = size
|
||||
lootPanel.parent.maximumSize = size
|
||||
val size = Dimension(lootPanel.width, lootPanelHeight + 32)
|
||||
(lootPanel.parent as? Component)?.setFixedSize(size)
|
||||
lootPanel.parent.revalidate()
|
||||
lootPanel.parent.repaint()
|
||||
lootPanel.revalidate()
|
||||
|
|
@ -275,16 +273,11 @@ object LootTrackerView : View, OnPostClientTickCallback, OnKillingBlowNPCCallbac
|
|||
|
||||
// Create the panel for the item
|
||||
val itemPanel = FixedSizePanel(Dimension(36, 32)).apply {
|
||||
preferredSize = Dimension(36, 32)
|
||||
background = WIDGET_COLOR
|
||||
minimumSize = preferredSize
|
||||
maximumSize = preferredSize
|
||||
|
||||
val imageCanvas = ImageCanvas(bufferedImageSprite).apply {
|
||||
preferredSize = Dimension(36, 32)
|
||||
setFixedSize(36, 32)
|
||||
background = WIDGET_COLOR
|
||||
minimumSize = preferredSize
|
||||
maximumSize = preferredSize
|
||||
}
|
||||
|
||||
// Add the imageCanvas to the panel
|
||||
|
|
@ -476,9 +469,7 @@ object LootTrackerView : View, OnPostClientTickCallback, OnKillingBlowNPCCallbac
|
|||
val labelPanel = JPanel(BorderLayout()).apply {
|
||||
background = TITLE_BAR_COLOR
|
||||
border = BorderFactory.createEmptyBorder(5, 5, 5, 5)
|
||||
maximumSize = Dimension(ViewConstants.DEFAULT_WIDGET_SIZE.width, 24)
|
||||
minimumSize = maximumSize
|
||||
preferredSize = maximumSize
|
||||
setFixedSize(ViewConstants.DEFAULT_WIDGET_SIZE.width, 24)
|
||||
}
|
||||
|
||||
val killCount = npcKillCounts.getOrPut(npcName) { 0 }
|
||||
|
|
@ -536,18 +527,7 @@ object LootTrackerView : View, OnPostClientTickCallback, OnKillingBlowNPCCallbac
|
|||
private fun removeLootFrameMenu(toRemove: JPanel, npcName: String): JPopupMenu {
|
||||
// Create a popup menu
|
||||
val popupMenu = PopupMenuComponent()
|
||||
val rFont = ViewConstants.FONT_RUNESCAPE_SMALL_16
|
||||
|
||||
popupMenu.background = POPUP_BACKGROUND
|
||||
|
||||
// Create menu items with custom font and colors
|
||||
val menuItem1 = JMenuItem("Remove").apply {
|
||||
font = rFont // Set custom font
|
||||
background = POPUP_BACKGROUND // Dark background for item
|
||||
foreground = POPUP_FOREGROUND // Light text color for item
|
||||
}
|
||||
popupMenu.add(menuItem1)
|
||||
menuItem1.addActionListener {
|
||||
popupMenu.addMenuItem("Remove") {
|
||||
lootItemPanels[npcName]?.clear()
|
||||
npcKillCounts[npcName] = 0
|
||||
lootTrackerView?.let { parent ->
|
||||
|
|
@ -574,14 +554,7 @@ object LootTrackerView : View, OnPostClientTickCallback, OnKillingBlowNPCCallbac
|
|||
// Create a popup menu
|
||||
val popupMenu = PopupMenuComponent()
|
||||
|
||||
// Create menu items with custom font and colors
|
||||
val menuItem1 = JMenuItem("Reset Loot Tracker").apply {
|
||||
font = ViewConstants.FONT_RUNESCAPE_SMALL_16
|
||||
background = POPUP_BACKGROUND
|
||||
foreground = POPUP_FOREGROUND
|
||||
}
|
||||
popupMenu.add(menuItem1)
|
||||
menuItem1.addActionListener {
|
||||
popupMenu.addMenuItem("Reset Loot Tracker") {
|
||||
registerDrawAction {
|
||||
resetLootTracker()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ import KondoKit.Helpers
|
|||
import KondoKit.components.*
|
||||
import KondoKit.ViewConstants
|
||||
import KondoKit.views.ViewLayoutHelpers.createSearchFieldSection
|
||||
import KondoKit.setFixedSize
|
||||
import KondoKit.pluginmanager.GitLabPlugin
|
||||
import KondoKit.pluginmanager.GitLabPluginFetcher
|
||||
import KondoKit.pluginmanager.PluginDownloadManager
|
||||
import KondoKit.pluginmanager.PluginProperties
|
||||
import KondoKit.pluginmanager.PluginInfoWithStatus
|
||||
import KondoKit.Helpers.showToast
|
||||
import KondoKit.plugin.Companion.TITLE_BAR_COLOR
|
||||
import KondoKit.plugin.Companion.TOOLTIP_BACKGROUND
|
||||
import KondoKit.plugin.Companion.VIEW_BACKGROUND_COLOR
|
||||
import KondoKit.plugin.Companion.WIDGET_COLOR
|
||||
|
|
@ -304,17 +304,10 @@ object ReflectiveEditorView : View {
|
|||
}
|
||||
|
||||
// Edit button (only show if plugin has exposed attributes)
|
||||
val editButton = if (exposedFields.isNotEmpty()) {
|
||||
val button = JButton("Edit")
|
||||
button.background = TITLE_BAR_COLOR
|
||||
button.foreground = secondaryColor
|
||||
button.font = ViewConstants.FONT_RUNESCAPE_SMALL_14
|
||||
button.addActionListener {
|
||||
val editButton = exposedFields.takeIf { it.isNotEmpty() }?.let {
|
||||
UiStyler.button(text = "Edit") {
|
||||
showPluginDetails(pluginInfo, plugin)
|
||||
}
|
||||
button
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
// Plugin toggle switch (iOS style) - skip for KondoKit since it should always be on
|
||||
|
|
@ -324,8 +317,7 @@ object ReflectiveEditorView : View {
|
|||
// Create a placeholder component that takes the same space but is invisible
|
||||
val placeholder = JPanel()
|
||||
placeholder.background = WIDGET_COLOR
|
||||
placeholder.preferredSize = ViewConstants.TOGGLE_PLACEHOLDER_SIZE
|
||||
placeholder.maximumSize = ViewConstants.TOGGLE_PLACEHOLDER_SIZE
|
||||
placeholder.setFixedSize(ViewConstants.TOGGLE_PLACEHOLDER_SIZE)
|
||||
placeholder.isVisible = false
|
||||
placeholder
|
||||
}
|
||||
|
|
@ -417,10 +409,7 @@ object ReflectiveEditorView : View {
|
|||
nameLabel.font = ViewConstants.FONT_RUNESCAPE_SMALL_PLAIN_16
|
||||
|
||||
// Action button based on plugin status
|
||||
val actionButton = JButton()
|
||||
actionButton.background = TITLE_BAR_COLOR
|
||||
actionButton.foreground = secondaryColor
|
||||
actionButton.font = ViewConstants.FONT_RUNESCAPE_SMALL_14
|
||||
val actionButton = UiStyler.button()
|
||||
|
||||
// Progress bar for downloads
|
||||
val progressBar = JProgressBar(0, 100)
|
||||
|
|
|
|||
|
|
@ -77,14 +77,3 @@ object ViewLayoutHelpers {
|
|||
fun Container.addVerticalSpacing(pixels: Int) {
|
||||
add(Box.createVerticalStrut(pixels))
|
||||
}
|
||||
|
||||
fun <T : Component> T.setFixedSize(width: Int, height: Int): T {
|
||||
return setFixedSize(Dimension(width, height))
|
||||
}
|
||||
|
||||
fun <T : Component> T.setFixedSize(size: Dimension): T {
|
||||
preferredSize = size
|
||||
minimumSize = size
|
||||
maximumSize = size
|
||||
return this
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import KondoKit.Helpers.getProgressBarColor
|
|||
import KondoKit.Helpers.getSpriteId
|
||||
import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
|
||||
import KondoKit.ViewConstants
|
||||
import KondoKit.setFixedSize
|
||||
import KondoKit.XPTable
|
||||
import KondoKit.components.PopupMenuComponent
|
||||
import KondoKit.components.ProgressBar
|
||||
|
|
@ -18,8 +19,6 @@ import KondoKit.plugin.Companion.TOTAL_XP_WIDGET_SIZE
|
|||
import KondoKit.plugin.Companion.WIDGET_COLOR
|
||||
import KondoKit.plugin.Companion.WIDGET_SIZE
|
||||
import KondoKit.plugin
|
||||
import KondoKit.plugin.Companion.POPUP_BACKGROUND
|
||||
import KondoKit.plugin.Companion.POPUP_FOREGROUND
|
||||
import KondoKit.plugin.Companion.playerXPMultiplier
|
||||
import KondoKit.plugin.Companion.primaryColor
|
||||
import KondoKit.plugin.Companion.secondaryColor
|
||||
|
|
@ -126,12 +125,6 @@ object XPTrackerView : View, OnUpdateCallback, OnXPUpdateCallback {
|
|||
}
|
||||
}
|
||||
|
||||
private fun createMenuItem(text: String): JMenuItem = JMenuItem(text).apply {
|
||||
font = widgetFont
|
||||
background = POPUP_BACKGROUND
|
||||
foreground = POPUP_FOREGROUND
|
||||
}
|
||||
|
||||
private fun getSkillIcon(skillId: Int): BufferedImage {
|
||||
return skillIconCache[skillId] ?: getBufferedImageFromSprite(API.GetSprite(getSpriteId(skillId))).also {
|
||||
skillIconCache[skillId] = it
|
||||
|
|
@ -366,24 +359,16 @@ object XPTrackerView : View, OnUpdateCallback, OnXPUpdateCallback {
|
|||
|
||||
fun createResetMenu(): JPopupMenu {
|
||||
val popupMenu = PopupMenuComponent()
|
||||
|
||||
val resetItem = createMenuItem("Reset Tracker")
|
||||
popupMenu.add(resetItem)
|
||||
|
||||
resetItem.addActionListener { plugin.registerDrawAction { resetXPTracker(xpTrackerView!!) } }
|
||||
popupMenu.addMenuItem("Reset Tracker") {
|
||||
plugin.registerDrawAction { resetXPTracker(xpTrackerView!!) }
|
||||
}
|
||||
return popupMenu
|
||||
}
|
||||
|
||||
fun removeXPWidgetMenu(toRemove: Container, skillId: Int): JPopupMenu {
|
||||
val popupMenu = PopupMenuComponent()
|
||||
|
||||
val resetItem = createMenuItem("Reset")
|
||||
popupMenu.add(resetItem)
|
||||
|
||||
val removeItem = createMenuItem("Remove")
|
||||
popupMenu.add(removeItem)
|
||||
|
||||
resetItem.addActionListener {
|
||||
popupMenu.addMenuItem("Reset") {
|
||||
xpWidgets[skillId]?.let { widget ->
|
||||
// Baseline at current XP and clear per-widget counters
|
||||
initialXP[skillId] = widget.previousXp
|
||||
|
|
@ -395,7 +380,7 @@ object XPTrackerView : View, OnUpdateCallback, OnXPUpdateCallback {
|
|||
}
|
||||
}
|
||||
|
||||
removeItem.addActionListener {
|
||||
popupMenu.addMenuItem("Remove") {
|
||||
// Reset the per-skill baseline to the current XP so next widget starts fresh
|
||||
xpWidgets[skillId]?.let { widget ->
|
||||
initialXP[skillId] = widget.previousXp
|
||||
|
|
@ -440,9 +425,7 @@ object XPTrackerView : View, OnUpdateCallback, OnXPUpdateCallback {
|
|||
val actionsLabel = createMetricLabel(actionsTitle)
|
||||
|
||||
val progressBar = ProgressBar(0.0, getProgressBarColor(skillId)).apply {
|
||||
preferredSize = Dimension(160, 22)
|
||||
minimumSize = preferredSize
|
||||
maximumSize = preferredSize
|
||||
setFixedSize(160, 22)
|
||||
}
|
||||
|
||||
val progressPanel = JPanel(BorderLayout()).apply {
|
||||
|
|
@ -484,15 +467,11 @@ object XPTrackerView : View, OnUpdateCallback, OnXPUpdateCallback {
|
|||
)
|
||||
val outerPanel = JPanel(GridBagLayout()).apply {
|
||||
background = WIDGET_COLOR
|
||||
preferredSize = outerPanelSize
|
||||
maximumSize = outerPanelSize
|
||||
minimumSize = outerPanelSize
|
||||
setFixedSize(outerPanelSize)
|
||||
}
|
||||
val innerPanel = JPanel(BorderLayout()).apply {
|
||||
background = WIDGET_COLOR
|
||||
preferredSize = component.preferredSize
|
||||
maximumSize = component.preferredSize
|
||||
minimumSize = component.preferredSize
|
||||
setFixedSize(component.preferredSize)
|
||||
add(component, BorderLayout.CENTER)
|
||||
}
|
||||
val gbc = GridBagConstraints().apply {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue