Formatting in edit menu + search fixes

This commit is contained in:
downthecrop 2025-09-15 22:43:41 -07:00
parent ea724777ae
commit 973149e859
4 changed files with 125 additions and 123 deletions

Binary file not shown.

View file

@ -54,7 +54,7 @@ open class SearchField(
text = text.dropLast(1)
}
} else if (e.keyChar == '\n') {
onSearch(text)
triggerSearch()
} else {
text += e.keyChar
}
@ -93,7 +93,6 @@ open class SearchField(
override fun mouseClicked(e: MouseEvent) {
if (e.x > width - 20 && e.y < 20) {
text = ""
onSearch(text)
SwingUtilities.invokeLater {
repaint()
}
@ -155,6 +154,15 @@ open class SearchField(
text = newText
repaint()
}
fun getText(): String = text
}
private fun triggerSearch() {
val query = text.trim()
if (query.isNotEmpty()) {
text = query
repaint()
onSearch(query)
}
}
}

View file

@ -8,17 +8,17 @@ import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
import KondoKit.views.XPTrackerView.wrappedWidget
import KondoKit.components.PopupMenuComponent
import KondoKit.components.ProgressBar
import KondoKit.plugin.Companion.useLiveGEPrices
import KondoKit.plugin.Companion.WIDGET_COLOR
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
import KondoKit.plugin.Companion.WIDGET_COLOR
import KondoKit.plugin.Companion.primaryColor
import KondoKit.plugin.Companion.registerDrawAction
import KondoKit.plugin.Companion.secondaryColor
import KondoKit.plugin.Companion.useLiveGEPrices
import KondoKit.plugin.StateManager.focusedView
import KondoKit.views.OnKillingBlowNPCCallback
import KondoKit.views.OnPostClientTickCallback
import plugin.api.API
import rt4.*
import java.awt.*
@ -36,6 +36,7 @@ import kotlin.math.ceil
object LootTrackerView : View, OnPostClientTickCallback, OnKillingBlowNPCCallback {
private const val SNAPSHOT_LIFESPAN = 10
const val BAG_ICON = 900
const val OPEN_BAG = 777
val npcDeathSnapshots = mutableMapOf<Int, GroundSnapshot>()
var gePriceMap = loadGEPrices()
const val VIEW_NAME = "LOOT_TRACKER_VIEW"
@ -46,7 +47,7 @@ object LootTrackerView : View, OnPostClientTickCallback, OnKillingBlowNPCCallbac
private var customToolTipWindow: JWindow? = null
var lootTrackerView: JPanel? = null
override val name: String = VIEW_NAME
override val iconSpriteId: Int = BAG_ICON
override val iconSpriteId: Int = OPEN_BAG
override val panel: JPanel
get() = lootTrackerView ?: JPanel()
@ -532,13 +533,13 @@ object LootTrackerView : View, OnPostClientTickCallback, OnKillingBlowNPCCallbac
val popupMenu = PopupMenuComponent()
val rFont = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
popupMenu.background = KondoKit.plugin.Companion.POPUP_BACKGROUND
popupMenu.background = POPUP_BACKGROUND
// Create menu items with custom font and colors
val menuItem1 = JMenuItem("Remove").apply {
font = rFont // Set custom font
background = KondoKit.plugin.Companion.POPUP_BACKGROUND // Dark background for item
foreground = KondoKit.plugin.Companion.POPUP_FOREGROUND // Light text color for item
background = POPUP_BACKGROUND // Dark background for item
foreground = POPUP_FOREGROUND // Light text color for item
}
popupMenu.add(menuItem1)
menuItem1.addActionListener {
@ -571,8 +572,8 @@ object LootTrackerView : View, OnPostClientTickCallback, OnKillingBlowNPCCallbac
// Create menu items with custom font and colors
val menuItem1 = JMenuItem("Reset Loot Tracker").apply {
font = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
background = KondoKit.plugin.Companion.POPUP_BACKGROUND
foreground = KondoKit.plugin.Companion.POPUP_FOREGROUND
background = POPUP_BACKGROUND
foreground = POPUP_FOREGROUND
}
popupMenu.add(menuItem1)
menuItem1.addActionListener {

View file

@ -7,8 +7,11 @@ import KondoKit.components.ReflectiveEditorComponents.GitLabPlugin
import KondoKit.components.ReflectiveEditorComponents.GitLabPluginFetcher
import KondoKit.Helpers.showToast
import KondoKit.plugin
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
import KondoKit.plugin.Companion.WRENCH_ICON
import KondoKit.plugin.Companion.secondaryColor
import plugin.Plugin
import plugin.PluginInfo
@ -20,7 +23,6 @@ import java.io.File
import java.util.*
import javax.imageio.ImageIO
import javax.swing.*
import javax.swing.border.AbstractBorder
import kotlin.math.ceil
/*
@ -33,23 +35,17 @@ import kotlin.math.ceil
object ReflectiveEditorView : View {
var reflectiveEditorView: JPanel? = null
private val loadedPlugins: MutableList<String> = mutableListOf()
const val VIEW_NAME = "REFLECTIVE_EDITOR_VIEW"
const val PLUGIN_LIST_VIEW = "PLUGIN_LIST"
const val PLUGIN_DETAIL_VIEW = "PLUGIN_DETAIL"
val pluginsDirectory: File = File(GlobalJsonConfig.instance.pluginsFolder)
// GitLab API configuration
private const val GITLAB_ACCESS_TOKEN = "glpat-dE2Cs2e4b32-H7c9oGuS"
private const val GITLAB_PROJECT_ID = "38297322"
private const val GITLAB_BRANCH = "master"
// Store fetched GitLab plugins
private var gitLabPlugins: List<GitLabPlugin> = listOf()
// Store the cog icon to be reused
private var cogIcon: Icon? = null
private fun loadCogIcon() {
try {
val imageStream = this::class.java.getResourceAsStream("res/cog.png")
@ -62,18 +58,19 @@ object ReflectiveEditorView : View {
e.printStackTrace()
}
}
// Card layout for switching between views within the reflective editor view
private lateinit var cardLayout: CardLayout
private lateinit var mainPanel: JPanel
private var currentPluginInfo: PluginInfo? = null
private var currentPlugin: Plugin? = null
// Search text for filtering plugins
private var pluginSearchText: String = ""
private var searchFieldWrapper: JPanel? = null
override val name: String = VIEW_NAME
override val iconSpriteId: Int = KondoKit.plugin.WRENCH_ICON
override val iconSpriteId: Int = WRENCH_ICON
override val panel: JPanel
get() = reflectiveEditorView ?: JPanel()
@ -84,11 +81,11 @@ object ReflectiveEditorView : View {
override fun registerFunctions() {
// Reflective editor functions are handled within the view itself
}
fun createReflectiveEditorView() {
// Load the cog icon once
loadCogIcon()
// Create the main panel with card layout
cardLayout = CardLayout()
mainPanel = JPanel(cardLayout)
@ -96,25 +93,25 @@ object ReflectiveEditorView : View {
mainPanel.border = BorderFactory.createEmptyBorder(0, 0, 0, 0)
// Help minimize flicker during dynamic swaps
mainPanel.isDoubleBuffered = true
// Create the plugin list view
val pluginListView = createPluginListView()
pluginListView.name = PLUGIN_LIST_VIEW
mainPanel.add(pluginListView, PLUGIN_LIST_VIEW)
// Create a placeholder for the plugin detail view
val pluginDetailView = BaseView(PLUGIN_DETAIL_VIEW).apply {
layout = BorderLayout()
background = VIEW_BACKGROUND_COLOR
}
mainPanel.add(pluginDetailView, PLUGIN_DETAIL_VIEW)
// Set the reflectiveEditorView to our main panel
reflectiveEditorView = mainPanel
// Show the plugin list view by default
cardLayout.show(mainPanel, PLUGIN_LIST_VIEW)
// Fetch GitLab plugins in the background
GitLabPluginFetcher.fetchGitLabPlugins { plugins ->
gitLabPlugins = plugins
@ -135,8 +132,8 @@ object ReflectiveEditorView : View {
addPlugins(reflectiveEditorView!!)
}
}
val searchFieldWrapper = JPanel().apply {
val searchFieldWrapperPanel = JPanel().apply {
layout = BoxLayout(this, BoxLayout.X_AXIS)
background = VIEW_BACKGROUND_COLOR
preferredSize = Dimension(230, 30)
@ -145,9 +142,10 @@ object ReflectiveEditorView : View {
alignmentX = Component.CENTER_ALIGNMENT
add(searchField)
}
searchFieldWrapper = searchFieldWrapperPanel
panel.add(Box.createVerticalStrut(10)) // Spacer
panel.add(searchFieldWrapper)
panel.add(searchFieldWrapperPanel)
panel.add(Box.createVerticalStrut(10)) // Spacer
try {
@ -159,36 +157,36 @@ object ReflectiveEditorView : View {
// Separate plugins with and without exposed attributes
val pluginsWithExposed = mutableListOf<Pair<PluginInfo, Plugin>>()
val pluginsWithoutExposed = mutableListOf<Pair<PluginInfo, Plugin>>()
for ((pluginInfo, plugin) in loadedPlugins) {
val exposedFields = (plugin as Plugin).javaClass.declaredFields.filter { field ->
field.annotations.any { annotation ->
annotation.annotationClass.simpleName == "Exposed"
}
}
// Apply search filter
val pluginName = plugin.javaClass.`package`.name
if (pluginSearchText.isBlank() || pluginName.contains(pluginSearchText, ignoreCase = true)) {
if (exposedFields.isNotEmpty()) {
pluginsWithExposed.add(pluginInfo as PluginInfo to plugin as Plugin)
pluginsWithExposed.add(pluginInfo as PluginInfo to plugin)
} else {
pluginsWithoutExposed.add(pluginInfo as PluginInfo to plugin as Plugin)
pluginsWithoutExposed.add(pluginInfo as PluginInfo to plugin)
}
}
}
// Sort both lists by package name
pluginsWithExposed.sortBy { it.second.javaClass.`package`.name }
pluginsWithoutExposed.sortBy { it.second.javaClass.`package`.name }
// Add plugins with exposed attributes first
for ((pluginInfo, plugin) in pluginsWithExposed) {
val pluginPanel = createPluginItemPanel(pluginInfo, plugin)
panel.add(pluginPanel)
panel.add(Box.createVerticalStrut(5))
}
// Add a separator if we have plugins with exposed attributes
if (pluginsWithExposed.isNotEmpty() && pluginsWithoutExposed.isNotEmpty()) {
val separator = JPanel()
@ -198,7 +196,7 @@ object ReflectiveEditorView : View {
panel.add(separator)
panel.add(Box.createVerticalStrut(5))
}
// Add plugins without exposed attributes
for ((pluginInfo, plugin) in pluginsWithoutExposed) {
val pluginPanel = createPluginItemPanel(pluginInfo, plugin)
@ -208,12 +206,12 @@ object ReflectiveEditorView : View {
} catch (e: Exception) {
e.printStackTrace()
}
// Add disabled plugins to the list (filtered by search text)
val disabledDir = File(pluginsDirectory, "disabled")
if (disabledDir.exists() && disabledDir.isDirectory) {
val disabledPlugins = disabledDir.listFiles { file -> file.isDirectory } ?: arrayOf()
// Add disabled plugins to the list without exposed attributes (filtered by search text)
for (pluginDir in disabledPlugins.sortedBy { it.name }) {
// Apply search filter
@ -224,16 +222,16 @@ object ReflectiveEditorView : View {
}
}
}
// Add a section for available plugins from GitLab that are not installed
// Only show this section when there's a search term
if (pluginSearchText.isNotBlank()) {
val matchingGitLabPlugins = gitLabPlugins.filter { plugin ->
plugin.pluginProperties != null &&
(plugin.path.contains(pluginSearchText, ignoreCase = true) ||
plugin.pluginProperties!!.description.contains(pluginSearchText, ignoreCase = true))
plugin.pluginProperties != null &&
(plugin.path.contains(pluginSearchText, ignoreCase = true) ||
plugin.pluginProperties.description.contains(pluginSearchText, ignoreCase = true))
}
if (matchingGitLabPlugins.isNotEmpty()) {
// Add a separator
val separator = JPanel()
@ -243,17 +241,17 @@ object ReflectiveEditorView : View {
panel.add(Box.createVerticalStrut(10))
panel.add(separator)
panel.add(Box.createVerticalStrut(5))
// Add a header for available plugins
val headerPanel = JPanel(FlowLayout(FlowLayout.LEFT))
headerPanel.background = VIEW_BACKGROUND_COLOR
val headerLabel = JLabel("Available Plugins")
headerLabel.foreground = plugin.Companion.secondaryColor
headerLabel.foreground = secondaryColor
headerLabel.font = Font("RuneScape Small", Font.BOLD, 16)
headerPanel.add(headerLabel)
panel.add(headerPanel)
panel.add(Box.createVerticalStrut(5))
// Add matching GitLab plugins
for (gitLabPlugin in matchingGitLabPlugins) {
val pluginPanel = createGitLabPluginItemPanel(gitLabPlugin)
@ -262,42 +260,42 @@ object ReflectiveEditorView : View {
}
}
}
// Wrap the panel in a ScrollablePanel for custom scrolling
val scrollablePanel = ScrollablePanel(panel)
// Reset scroll position to top
SwingUtilities.invokeLater {
// For ScrollablePanel, we need to reset the internal offset
resetScrollablePanel(scrollablePanel)
}
val container = JPanel(BorderLayout())
container.background = VIEW_BACKGROUND_COLOR
container.add(scrollablePanel, BorderLayout.CENTER)
return container
}
private fun createPluginItemPanel(pluginInfo: PluginInfo, plugin: Plugin): JPanel {
val panel = JPanel(BorderLayout())
panel.background = KondoKit.plugin.Companion.WIDGET_COLOR
panel.background = WIDGET_COLOR
panel.border = BorderFactory.createEmptyBorder(10, 10, 10, 10)
panel.maximumSize = Dimension(220, 60)
// Plugin name and version (using package name as in original implementation)
val packageName = plugin.javaClass.`package`.name
val nameLabel = JLabel(packageName)
nameLabel.foreground = KondoKit.plugin.Companion.secondaryColor
nameLabel.foreground = secondaryColor
nameLabel.font = Font("RuneScape Small", Font.PLAIN, 16)
// Check if plugin has exposed attributes
val exposedFields = plugin.javaClass.declaredFields.filter { field ->
field.annotations.any { annotation ->
annotation.annotationClass.simpleName == "Exposed"
}
}
// Edit button (only show if plugin has exposed attributes)
val editButton = if (exposedFields.isNotEmpty()) {
val button = JButton()
@ -306,8 +304,8 @@ object ReflectiveEditorView : View {
} else {
button.text = "Edit"
}
button.background = KondoKit.plugin.Companion.TITLE_BAR_COLOR
button.foreground = KondoKit.plugin.Companion.secondaryColor
button.background = TITLE_BAR_COLOR
button.foreground = secondaryColor
button.font = Font("RuneScape Small", Font.PLAIN, 14)
button.addActionListener {
showPluginDetails(pluginInfo, plugin)
@ -316,41 +314,41 @@ object ReflectiveEditorView : View {
} else {
null
}
// Plugin toggle switch (iOS style)
val toggleSwitch = createToggleSwitch(plugin, pluginInfo)
// Layout
val infoPanel = JPanel(BorderLayout())
infoPanel.background = KondoKit.plugin.Companion.WIDGET_COLOR
infoPanel.background = WIDGET_COLOR
infoPanel.add(nameLabel, BorderLayout.WEST)
val controlsPanel = JPanel(FlowLayout(FlowLayout.RIGHT, 5, 0))
controlsPanel.background = KondoKit.plugin.Companion.WIDGET_COLOR
controlsPanel.background = WIDGET_COLOR
// Add edit button first (left side of controls)
editButton?.let { controlsPanel.add(it) }
// Add toggle switch second (right side of controls)
controlsPanel.add(toggleSwitch)
panel.add(infoPanel, BorderLayout.CENTER)
panel.add(controlsPanel, BorderLayout.EAST)
return panel
}
private fun createDisabledPluginItemPanel(pluginName: String): JPanel {
val panel = JPanel(BorderLayout())
panel.background = plugin.Companion.WIDGET_COLOR
panel.background = WIDGET_COLOR
panel.border = BorderFactory.createEmptyBorder(10, 10, 10, 10)
panel.maximumSize = Dimension(220, 60)
// Plugin name
val nameLabel = JLabel(pluginName)
nameLabel.foreground = plugin.Companion.secondaryColor
nameLabel.foreground = secondaryColor
nameLabel.font = Font("RuneScape Small", Font.PLAIN, 16)
// Plugin toggle switch (iOS style) - initially off for disabled plugins
val toggleSwitch = ToggleSwitch()
toggleSwitch.setActivated(false)
@ -363,55 +361,55 @@ object ReflectiveEditorView : View {
toggleSwitch.setActivated(false)
}
}
// Layout
val infoPanel = JPanel(BorderLayout())
infoPanel.background = plugin.Companion.WIDGET_COLOR
infoPanel.background = WIDGET_COLOR
infoPanel.add(nameLabel, BorderLayout.WEST)
val controlsPanel = JPanel(FlowLayout(FlowLayout.RIGHT, 5, 0))
controlsPanel.background = plugin.Companion.WIDGET_COLOR
controlsPanel.background = WIDGET_COLOR
controlsPanel.add(toggleSwitch)
panel.add(infoPanel, BorderLayout.CENTER)
panel.add(controlsPanel, BorderLayout.EAST)
return panel
}
private fun createGitLabPluginItemPanel(gitLabPlugin: GitLabPlugin): JPanel {
val panel = JPanel(BorderLayout())
panel.background = plugin.Companion.WIDGET_COLOR
panel.background = WIDGET_COLOR
panel.border = BorderFactory.createEmptyBorder(10, 10, 10, 10)
panel.maximumSize = Dimension(220, 60)
// Plugin name
val nameLabel = JLabel(gitLabPlugin.path)
nameLabel.foreground = plugin.Companion.secondaryColor
nameLabel.foreground = secondaryColor
nameLabel.font = Font("RuneScape Small", Font.PLAIN, 16)
// Download button (placeholder for now)
val downloadButton = JButton("Download")
downloadButton.background = plugin.Companion.TITLE_BAR_COLOR
downloadButton.foreground = plugin.Companion.secondaryColor
downloadButton.background = TITLE_BAR_COLOR
downloadButton.foreground = secondaryColor
downloadButton.font = Font("RuneScape Small", Font.PLAIN, 14)
downloadButton.addActionListener {
// TODO: Implement download functionality
showToast(mainPanel, "Download functionality not yet implemented", JOptionPane.INFORMATION_MESSAGE)
}
// Plugin toggle switch (iOS style) - initially off for GitLab plugins
val toggleSwitch = ToggleSwitch()
toggleSwitch.setActivated(false)
toggleSwitch.isEnabled = false // Disable toggle for GitLab plugins until downloaded
// Layout
val infoPanel = JPanel(BorderLayout())
infoPanel.background = plugin.Companion.WIDGET_COLOR
infoPanel.background = WIDGET_COLOR
infoPanel.add(nameLabel, BorderLayout.WEST)
val controlsPanel = JPanel(FlowLayout(FlowLayout.RIGHT, 5, 0))
controlsPanel.background = plugin.Companion.WIDGET_COLOR
controlsPanel.background = WIDGET_COLOR
controlsPanel.add(downloadButton)
controlsPanel.add(toggleSwitch)
@ -543,6 +541,8 @@ object ReflectiveEditorView : View {
private fun showPluginDetails(pluginInfo: PluginInfo, plugin: Plugin) {
currentPluginInfo = pluginInfo
currentPlugin = plugin
searchFieldWrapper?.isVisible = false
// Remove the existing detail view if it exists
val existingDetailView = mainPanel.components.find { it.name == PLUGIN_DETAIL_VIEW }
@ -556,8 +556,9 @@ object ReflectiveEditorView : View {
detailView.background = VIEW_BACKGROUND_COLOR
// Header with back button
//$packageName v${pluginInfo.version} should be
val headerPanel = ViewHeader(" v${pluginInfo.version}", 40).apply {
val packageName = plugin.javaClass.`package`.name
val headerPanel = ViewHeader("$packageName v${pluginInfo.version}", 40).apply {
border = BorderFactory.createEmptyBorder(5, 10, 5, 10)
}
@ -570,10 +571,10 @@ object ReflectiveEditorView : View {
findAndResetScrollablePanel(listView)
}
}
searchFieldWrapper?.isVisible = true
cardLayout.show(mainPanel, PLUGIN_LIST_VIEW)
}
val packageName = plugin.javaClass.`package`.name
headerPanel.add(backButton, BorderLayout.WEST)
@ -585,17 +586,20 @@ object ReflectiveEditorView : View {
// Add plugin info
val infoPanel = JPanel(BorderLayout())
infoPanel.background = KondoKit.plugin.Companion.WIDGET_COLOR
infoPanel.background = WIDGET_COLOR
infoPanel.border = BorderFactory.createEmptyBorder(10, 10, 10, 10)
infoPanel.maximumSize = Dimension(Int.MAX_VALUE, 80)
val infoText = """
Version: ${pluginInfo.version}
Author: ${pluginInfo.author}
Description: ${pluginInfo.description}
""".trimIndent()
<html>
Version: ${pluginInfo.version}<br>
Author: ${pluginInfo.author}<br>
Description: ${pluginInfo.description}
</html>
""".trimIndent()
val infoLabel = LabelComponent(infoText).apply {
val infoLabel = LabelComponent(infoText, isHtml = true).apply {
font = Font("RuneScape Small", Font.PLAIN, 14)
}
infoPanel.add(infoLabel, BorderLayout.CENTER)
@ -659,6 +663,7 @@ object ReflectiveEditorView : View {
cardLayout.show(mainPanel, PLUGIN_LIST_VIEW)
// Revalidate/repaint once at the end
searchFieldWrapper?.isVisible = true
mainPanel.revalidate()
mainPanel.repaint()
} finally {
@ -750,16 +755,4 @@ object ReflectiveEditorView : View {
}
}
}
// Custom border for rounded components
class RoundedBorder(radius: Int) : AbstractBorder() {
private val radius = radius
override fun paintBorder(c: Component, g: Graphics, x: Int, y: Int, width: Int, height: Int) {
val g2 = g as Graphics2D
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
g2.setColor(c.background)
g2.fillRoundRect(x, y, width - 1, height - 1, radius, radius)
}
}
}