Fix search users

This commit is contained in:
downthecrop 2025-10-21 21:13:27 -07:00
parent 215263a129
commit df091ac94b
5 changed files with 32 additions and 197 deletions

View file

@ -1,172 +0,0 @@
package KondoKit.components
import KondoKit.ImageCanvas
import KondoKit.SpriteToBufferedImage
import KondoKit.plugin.Companion.WIDGET_COLOR
import KondoKit.plugin.Companion.secondaryColor
import KondoKit.plugin.StateManager.focusedView
import plugin.api.API
import java.awt.*
import java.awt.datatransfer.DataFlavor
import java.awt.event.*
import javax.swing.*
class CustomSearchField(
private val parentPanel: JPanel,
private val onSearch: (String) -> Unit,
private val placeholderText: String = "Search plugins...",
private val fieldWidth: Int = 230,
private val fieldHeight: Int = 30,
private val viewName: String? = "REFLECTIVE_EDITOR_VIEW" // Default to the original behavior
) : 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') {
triggerSearch()
} else {
text += e.keyChar
}
SwingUtilities.invokeLater {
repaint()
}
}
override fun keyPressed(e: KeyEvent) {
if (e.isControlDown) {
when (e.keyCode) {
KeyEvent.VK_A -> {
// They probably want to clear the search box
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 = ""
SwingUtilities.invokeLater {
repaint()
}
}
}
})
Timer(500) { _ ->
cursorVisible = !cursorVisible
// Only repaint if the view is active or if viewName is not specified
if (viewName == null || focusedView == viewName) {
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
private fun triggerSearch() {
val query = text.trim()
if (query.isNotEmpty()) {
text = query
repaint()
onSearch(query)
} else {
onSearch(query) // Call with empty string for clearing filters
}
}
}

View file

@ -11,12 +11,13 @@ import java.awt.datatransfer.DataFlavor
import java.awt.event.* import java.awt.event.*
import javax.swing.* import javax.swing.*
open class SearchField( class SearchField(
protected val onSearch: (String) -> Unit, private val parentPanel: JPanel,
private val onSearch: (String) -> Unit,
private val placeholderText: String = "Search...", private val placeholderText: String = "Search...",
private val fieldWidth: Int = 230, private val fieldWidth: Int = 230,
private val fieldHeight: Int = 30, private val fieldHeight: Int = 30,
private val viewName: String? = null private val viewName: String? = ""
) : Canvas() { ) : Canvas() {
private var cursorVisible: Boolean = true private var cursorVisible: Boolean = true
@ -81,9 +82,7 @@ open class SearchField(
SwingUtilities.invokeLater { SwingUtilities.invokeLater {
repaint() repaint()
} }
} catch (ex: Exception) { } catch (_: Exception) { }
// Ignore clipboard errors
}
} }
} }
} }
@ -91,9 +90,11 @@ open class SearchField(
}) })
addMouseListener(object : MouseAdapter() { addMouseListener(object : MouseAdapter() {
// Clicked the search field 'x' button
override fun mouseClicked(e: MouseEvent) { override fun mouseClicked(e: MouseEvent) {
if (e.x > width - 20 && e.y < 20) { if (e.x > width - 20 && e.y < 20) {
text = "" text = ""
triggerSearch()
SwingUtilities.invokeLater { SwingUtilities.invokeLater {
repaint() repaint()
} }
@ -132,10 +133,10 @@ open class SearchField(
// Draw placeholder text if field is empty, otherwise draw actual text // Draw placeholder text if field is empty, otherwise draw actual text
if (currentText.isEmpty()) { if (currentText.isEmpty()) {
g.color = Color.GRAY // Use a lighter color for placeholder text g.color = Color.GRAY // lighter color for placeholder
g.drawString(placeholderText, 30, 20) g.drawString(placeholderText, 30, 20)
} else { } else {
g.color = foreground // Use normal color for actual text g.color = foreground // normal color for user entered text
g.drawString(currentText, 30, 20) g.drawString(currentText, 30, 20)
} }
@ -164,6 +165,8 @@ open class SearchField(
text = query text = query
repaint() repaint()
onSearch(query) onSearch(query)
} else {
onSearch(query) // Call with empty string for clearing filters
} }
} }
} }

View file

@ -4,17 +4,14 @@ import KondoKit.Helpers.getSpriteId
import KondoKit.Helpers.showToast import KondoKit.Helpers.showToast
import KondoKit.ImageCanvas import KondoKit.ImageCanvas
import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
import KondoKit.components.CustomSearchField
import KondoKit.components.LabelComponent
import KondoKit.components.SearchField import KondoKit.components.SearchField
import KondoKit.components.LabelComponent
import KondoKit.plugin.Companion.WIDGET_COLOR import KondoKit.plugin.Companion.WIDGET_COLOR
import KondoKit.plugin.Companion.VIEW_BACKGROUND_COLOR import KondoKit.plugin.Companion.VIEW_BACKGROUND_COLOR
import KondoKit.plugin.Companion.POPUP_FOREGROUND import KondoKit.plugin.Companion.POPUP_FOREGROUND
import KondoKit.plugin.Companion.secondaryColor import KondoKit.plugin.Companion.secondaryColor
import KondoKit.plugin.Companion.primaryColor import KondoKit.plugin.Companion.primaryColor
import KondoKit.plugin.Companion.TOOLTIP_BACKGROUND import KondoKit.plugin.Companion.TOOLTIP_BACKGROUND
import KondoKit.views.HiscoresView.VIEW_NAME
import KondoKit.views.HiscoresView.hiScoreView
import com.google.gson.Gson import com.google.gson.Gson
import plugin.api.API import plugin.api.API
import rt4.Sprites import rt4.Sprites
@ -64,6 +61,7 @@ object HiscoresView : View {
const val VIEW_NAME = "HISCORE_SEARCH_VIEW" const val VIEW_NAME = "HISCORE_SEARCH_VIEW"
var hiScoreView: JPanel? = null var hiScoreView: JPanel? = null
var customSearchField: SearchField? = null
override val name: String = VIEW_NAME override val name: String = VIEW_NAME
override val iconSpriteId: Int = Constants.MAG_SPRITE override val iconSpriteId: Int = Constants.MAG_SPRITE
@ -84,7 +82,7 @@ object HiscoresView : View {
setViewSize(Constants.HISCORE_PANEL_DIMENSION.height) setViewSize(Constants.HISCORE_PANEL_DIMENSION.height)
} }
val customSearchField = CustomSearchField( customSearchField = SearchField(
hiscorePanel, hiscorePanel,
{ username -> { username ->
searchPlayerForHiscores(username, hiscorePanel) searchPlayerForHiscores(username, hiscorePanel)
@ -94,6 +92,8 @@ object HiscoresView : View {
30, 30,
VIEW_NAME VIEW_NAME
) )
val searchField = customSearchField!!
val searchFieldWrapper = JPanel().apply { val searchFieldWrapper = JPanel().apply {
layout = BoxLayout(this, BoxLayout.X_AXIS) layout = BoxLayout(this, BoxLayout.X_AXIS)
@ -102,7 +102,7 @@ object HiscoresView : View {
maximumSize = preferredSize maximumSize = preferredSize
minimumSize = preferredSize minimumSize = preferredSize
alignmentX = Component.CENTER_ALIGNMENT alignmentX = Component.CENTER_ALIGNMENT
add(customSearchField) add(searchField)
} }
val searchPanel = JPanel().apply { val searchPanel = JPanel().apply {
@ -253,13 +253,16 @@ object HiscoresView : View {
// Function to search for players in hiscores, extracted from the old inner class // Function to search for players in hiscores, extracted from the old inner class
fun searchPlayerForHiscores(username: String, hiscoresPanel: JPanel) { fun searchPlayerForHiscores(username: String, hiscoresPanel: JPanel) {
if(username.isEmpty() || username.length < 3) {
// Skip on no value
return
}
val cleanUsername = username.replace(" ", "_") val cleanUsername = username.replace(" ", "_")
// Note: We can't call setText on the CustomSearchField because it now doesn't have that method
// The text is already set when the user presses enter in the search field
val apiUrl = "http://api.2009scape.org:3000/hiscores/playerSkills/1/${cleanUsername.toLowerCase()}" val apiUrl = "http://api.2009scape.org:3000/hiscores/playerSkills/1/${cleanUsername.toLowerCase()}"
// Find the updateHiscoresView function or update the display customSearchField?.setText(username)
// For now, we'll just call the main updateHiscoresView method if it's accessible
updateHiscoresViewStandalone(hiscoresPanel, null, "Searching...") updateHiscoresViewStandalone(hiscoresPanel, null, "Searching...")
Thread { Thread {
@ -280,6 +283,9 @@ object HiscoresView : View {
SwingUtilities.invokeLater { SwingUtilities.invokeLater {
updatePlayerDataStandalone(response, username, hiscoresPanel) updatePlayerDataStandalone(response, username, hiscoresPanel)
// Example of how to use setText now that the search field is accessible:
// customSearchField?.setText(username) // You could set the text to the searched username
} }
} else { } else {
SwingUtilities.invokeLater { SwingUtilities.invokeLater {

View file

@ -2,7 +2,7 @@ package KondoKit.views
import KondoKit.Helpers import KondoKit.Helpers
import KondoKit.components.* import KondoKit.components.*
import KondoKit.components.CustomSearchField import KondoKit.components.SearchField
import KondoKit.pluginmanager.GitLabPlugin import KondoKit.pluginmanager.GitLabPlugin
import KondoKit.pluginmanager.GitLabPluginFetcher import KondoKit.pluginmanager.GitLabPluginFetcher
import KondoKit.pluginmanager.PluginDownloadManager import KondoKit.pluginmanager.PluginDownloadManager
@ -51,7 +51,7 @@ object ReflectiveEditorView : View {
private var cogIcon: Icon? = null private var cogIcon: Icon? = null
private var searchField: CustomSearchField? = null private var searchField: SearchField? = null
// Flag for scheduled plugin reload to avoid crashes // Flag for scheduled plugin reload to avoid crashes
private var reloadPlugins = false private var reloadPlugins = false
@ -133,7 +133,7 @@ object ReflectiveEditorView : View {
panel.layout = BoxLayout(panel, BoxLayout.Y_AXIS) panel.layout = BoxLayout(panel, BoxLayout.Y_AXIS)
panel.background = VIEW_BACKGROUND_COLOR panel.background = VIEW_BACKGROUND_COLOR
val searchField = CustomSearchField( val searchField = SearchField(
parentPanel = panel, parentPanel = panel,
onSearch = { searchText -> onSearch = { searchText ->
pluginSearchText = searchText pluginSearchText = searchText

View file

@ -341,9 +341,7 @@ object XPTrackerView : View, OnUpdateCallback, OnXPUpdateCallback {
for (i in 0 until 24) { for (i in 0 until 24) {
getSkillIcon(i) getSkillIcon(i)
} }
} catch (_: Exception) { } catch (_: Exception) { }
// Ignore preload errors; fallback at use time
}
} }