From b61f4da214529b7e313c93dc07656856b61fe01b Mon Sep 17 00:00:00 2001 From: downthecrop Date: Fri, 19 Sep 2025 22:07:17 -0700 Subject: [PATCH] Working table editor --- .../src/main/kotlin/FooTextPlugin/plugin.kt | 4 - .../KondoKit/components/SettingsPanel.kt | 106 ++++++++++++++++-- 2 files changed, 97 insertions(+), 13 deletions(-) diff --git a/plugin-playground/src/main/kotlin/FooTextPlugin/plugin.kt b/plugin-playground/src/main/kotlin/FooTextPlugin/plugin.kt index e1c2bd8..d6539f5 100644 --- a/plugin-playground/src/main/kotlin/FooTextPlugin/plugin.kt +++ b/plugin-playground/src/main/kotlin/FooTextPlugin/plugin.kt @@ -37,10 +37,6 @@ class plugin : Plugin() { // Local storage for username matches to avoid API calls @Exposed(description = "Username to account type mappings (0=Normal, 1=IM, 2=HCIM, 3=UIM)") private var usernameMatches = HashMap() - - // Not used anymore - keeping for reference - // @Exposed(description = "Manual username entries (format: username:accountType, e.g., 'example:1')") - // private var manualEntries = listOf() private var ACCOUNT_TYPE = 0 diff --git a/plugin-playground/src/main/kotlin/KondoKit/components/SettingsPanel.kt b/plugin-playground/src/main/kotlin/KondoKit/components/SettingsPanel.kt index 1cdf9f4..ca0d461 100644 --- a/plugin-playground/src/main/kotlin/KondoKit/components/SettingsPanel.kt +++ b/plugin-playground/src/main/kotlin/KondoKit/components/SettingsPanel.kt @@ -212,11 +212,39 @@ 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 + } + } ?: "" + // Create title label val titleLabel = JLabel("${field.name} (Key-Value Pairs)").apply { foreground = secondaryColor font = Font("RuneScape Small", Font.TRUETYPE_FONT, 16) alignmentX = Component.LEFT_ALIGNMENT + + // Add mouse listener to the label only if a description is available + if (description.isNotBlank()) { + cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR) + addMouseListener(object : MouseAdapter() { + override fun mouseEntered(e: MouseEvent) { + showCustomToolTip(description, this@apply) + } + + override fun mouseExited(e: MouseEvent) { + SettingsPanel.customToolTipWindow?.isVisible = false + } + }) + } } // Get the current HashMap value @@ -309,24 +337,84 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() { // Apply button val applyButton = JButton("Apply Changes").apply { - maximumSize = Dimension(220, 30) + maximumSize = Dimension(120, 30) addActionListener { try { // Create a new HashMap from the table data // We need to determine the key and value types from the field's generic type - val newHashMap = HashMap() + val newHashMap = 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()) { - // Try to convert the value to the appropriate type - val convertedValue = try { - // For now, we'll keep everything as strings - // In the future, we could parse based on the generic type information - value + 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 which is what FooTextPlugin uses + if (field.genericType.toString().contains("java.util.HashMap") || + field.genericType.toString().contains("HashMap") || + field.genericType.toString().contains("HashMap")) { + try { + val intValue = value.toInt() + // For FooTextPlugin, account types should be 0-3 + if (field.declaringClass.simpleName == "plugin" && + field.declaringClass.`package`.name.contains("FooTextPlugin")) { + if (intValue < 0 || intValue > 3) { + Helpers.showToast( + this@SettingsPanel, + "Account type for '$key' should be 0-3. Using 0 as default.", + JOptionPane.WARNING_MESSAGE + ) + 0 + } else { + intValue + } + } else { + intValue + } + } catch (e: NumberFormatException) { + Helpers.showToast( + this@SettingsPanel, + "Invalid number format for key '$key': '$value'. Using 0 as default.", + JOptionPane.WARNING_MESSAGE + ) + 0 + } + } + // For other numeric types + else if (field.genericType.toString().contains("java.lang.Integer") || + field.genericType.toString().contains("int")) { + value.toInt() + } + else if (field.genericType.toString().contains("java.lang.Double") || + field.genericType.toString().contains("double")) { + value.toDouble() + } + else if (field.genericType.toString().contains("java.lang.Float") || + field.genericType.toString().contains("float")) { + value.toFloat() + } + else if (field.genericType.toString().contains("java.lang.Boolean") || + field.genericType.toString().contains("boolean")) { + value.toBoolean() + } + // Default to string for other types + else { + value + } } catch (e: Exception) { - value // fallback to string + // If conversion fails, keep as string + value } newHashMap[key] = convertedValue }