mirror of
https://gitlab.com/2009scape/rt4-client.git
synced 2025-12-15 02:50:23 -07:00
Fix tooltip labels
This commit is contained in:
parent
5bb81c7bd3
commit
5240963743
7 changed files with 135 additions and 156 deletions
|
|
@ -4,105 +4,85 @@ import KondoKit.pluginmanager.GitLabPlugin
|
|||
import KondoKit.pluginmanager.PluginProperties
|
||||
import KondoKit.util.HttpFetcher
|
||||
import KondoKit.pluginmanager.GitLabConfig
|
||||
import KondoKit.util.HttpStatusException
|
||||
import KondoKit.util.JsonParser
|
||||
import com.google.gson.JsonObject
|
||||
import java.io.BufferedReader
|
||||
import java.io.InputStreamReader
|
||||
import java.net.HttpURLConnection
|
||||
import java.util.concurrent.*
|
||||
import javax.swing.SwingUtilities
|
||||
|
||||
object GitLabPluginFetcher {
|
||||
|
||||
private const val TAG = "GitLabPluginFetcher"
|
||||
|
||||
// Thread pool for concurrent plugin property fetching
|
||||
private val executorService = Executors.newFixedThreadPool(5)
|
||||
|
||||
|
||||
// Debug logging function
|
||||
private fun debugLog(message: String) {
|
||||
if (GitLabConfig.DEBUG) {
|
||||
println("[GitLabPluginFetcher] $message")
|
||||
}
|
||||
}
|
||||
|
||||
private fun debugLog(message: String) = PluginLogger.debug(TAG, message)
|
||||
|
||||
// Function to fetch plugins from GitLab
|
||||
fun fetchGitLabPlugins(onComplete: (List<GitLabPlugin>) -> Unit) {
|
||||
Thread {
|
||||
val plugins = mutableListOf<GitLabPlugin>()
|
||||
try {
|
||||
debugLog("Starting to fetch GitLab plugins...")
|
||||
val plugins = mutableListOf<GitLabPlugin>()
|
||||
val apiUrl = GitLabConfig.getRepositoryTreeUrl()
|
||||
debugLog("API URL: $apiUrl")
|
||||
|
||||
val connection = HttpFetcher.openGetConnection(apiUrl)
|
||||
|
||||
// Read response
|
||||
val responseCode = connection.responseCode
|
||||
debugLog("Response code: $responseCode")
|
||||
|
||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||
val reader = BufferedReader(InputStreamReader(connection.inputStream))
|
||||
val response = reader.use { it.readText() }
|
||||
debugLog("Response length: ${response.length} characters")
|
||||
debugLog("Response preview: ${response.take(200)}...")
|
||||
|
||||
// Parse JSON response
|
||||
val treeItems = JsonParser.fromJson(response, Array<JsonObject>::class.java)
|
||||
debugLog("Parsed ${treeItems.size} items from JSON")
|
||||
|
||||
// Filter for directories (trees) with mode "040000"
|
||||
val pluginDirectories = mutableListOf<Pair<String, String>>()
|
||||
for (jsonObject in treeItems) {
|
||||
if (jsonObject["type"].asString == "tree" && jsonObject["mode"].asString == "040000") {
|
||||
val folderId = jsonObject["id"].asString
|
||||
val folderPath = jsonObject["path"].asString
|
||||
pluginDirectories.add(folderId to folderPath)
|
||||
debugLog("Found directory: $folderPath (ID: $folderId)")
|
||||
}
|
||||
|
||||
val response = HttpFetcher.fetchString(apiUrl)
|
||||
debugLog("Response length: ${response.length} characters")
|
||||
debugLog("Response preview: ${response.take(200)}...")
|
||||
|
||||
// Parse JSON response
|
||||
val treeItems = JsonParser.fromJson(response, Array<JsonObject>::class.java)
|
||||
debugLog("Parsed ${treeItems.size} items from JSON")
|
||||
|
||||
// Filter for directories (trees) with mode "040000"
|
||||
val pluginDirectories = mutableListOf<Pair<String, String>>()
|
||||
for (jsonObject in treeItems) {
|
||||
if (jsonObject["type"].asString == "tree" && jsonObject["mode"].asString == "040000") {
|
||||
val folderId = jsonObject["id"].asString
|
||||
val folderPath = jsonObject["path"].asString
|
||||
pluginDirectories.add(folderId to folderPath)
|
||||
debugLog("Found directory: $folderPath (ID: $folderId)")
|
||||
}
|
||||
debugLog("Found ${pluginDirectories.size} plugin directories")
|
||||
|
||||
// Fetch plugin properties in parallel
|
||||
val pluginFutures = mutableListOf<Future<GitLabPlugin>>()
|
||||
for ((folderId, folderPath) in pluginDirectories) {
|
||||
val future = executorService.submit(Callable<GitLabPlugin> {
|
||||
try {
|
||||
val pluginProperties = fetchPluginProperties(folderPath)
|
||||
debugLog("Successfully fetched properties for: $folderPath")
|
||||
GitLabPlugin(folderId, folderPath, pluginProperties, null)
|
||||
} catch (e: Exception) {
|
||||
debugLog("Error fetching plugin.properties for $folderPath: ${e.message}")
|
||||
GitLabPlugin(folderId, folderPath, null, "Error fetching plugin.properties")
|
||||
}
|
||||
})
|
||||
pluginFutures.add(future)
|
||||
}
|
||||
|
||||
// Collect results
|
||||
for (future in pluginFutures) {
|
||||
}
|
||||
debugLog("Found ${pluginDirectories.size} plugin directories")
|
||||
|
||||
// Fetch plugin properties in parallel
|
||||
val pluginFutures = mutableListOf<Future<GitLabPlugin>>()
|
||||
for ((folderId, folderPath) in pluginDirectories) {
|
||||
val future = executorService.submit(Callable<GitLabPlugin> {
|
||||
try {
|
||||
plugins.add(future.get())
|
||||
val pluginProperties = fetchPluginProperties(folderPath)
|
||||
debugLog("Successfully fetched properties for: $folderPath")
|
||||
GitLabPlugin(folderId, folderPath, pluginProperties, null)
|
||||
} catch (e: Exception) {
|
||||
debugLog("Error getting plugin result: ${e.message}")
|
||||
debugLog("Error fetching plugin.properties for $folderPath: ${e.message}")
|
||||
GitLabPlugin(folderId, folderPath, null, "Error fetching plugin.properties")
|
||||
}
|
||||
})
|
||||
pluginFutures.add(future)
|
||||
}
|
||||
|
||||
// Collect results
|
||||
for (future in pluginFutures) {
|
||||
try {
|
||||
plugins.add(future.get())
|
||||
} catch (e: Exception) {
|
||||
debugLog("Error getting plugin result: ${e.message}")
|
||||
}
|
||||
} else {
|
||||
debugLog("HTTP error: $responseCode")
|
||||
val errorReader = BufferedReader(InputStreamReader(connection.errorStream))
|
||||
val errorResponse = errorReader.use { it.readText() }
|
||||
debugLog("Error response: $errorResponse")
|
||||
}
|
||||
|
||||
debugLog("Completed fetching plugins. Total plugins: ${plugins.size}")
|
||||
// Update on UI thread
|
||||
SwingUtilities.invokeLater {
|
||||
onComplete(plugins)
|
||||
}
|
||||
} catch (e: HttpStatusException) {
|
||||
debugLog("HTTP error ${e.statusCode} fetching plugin tree: ${e.body.take(200)}")
|
||||
} catch (e: Exception) {
|
||||
debugLog("Exception occurred: ${e.message}")
|
||||
e.printStackTrace()
|
||||
SwingUtilities.invokeLater {
|
||||
onComplete(emptyList())
|
||||
}
|
||||
}
|
||||
|
||||
debugLog("Completed fetching plugins. Total plugins: ${plugins.size}")
|
||||
// Update on UI thread
|
||||
SwingUtilities.invokeLater {
|
||||
onComplete(plugins)
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
|
@ -113,25 +93,16 @@ object GitLabPluginFetcher {
|
|||
val pluginUrl = GitLabConfig.getRawFileUrl(pluginFilePath)
|
||||
debugLog("Fetching plugin.properties from: $pluginUrl")
|
||||
|
||||
val connection = HttpFetcher.openGetConnection(pluginUrl)
|
||||
|
||||
// Read response
|
||||
val responseCode = connection.responseCode
|
||||
debugLog("plugin.properties response code: $responseCode")
|
||||
|
||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||
val reader = BufferedReader(InputStreamReader(connection.inputStream))
|
||||
val rawContent = reader.use { it.readText() }
|
||||
try {
|
||||
val rawContent = HttpFetcher.fetchString(pluginUrl)
|
||||
debugLog("plugin.properties content length: ${rawContent.length} characters")
|
||||
debugLog("plugin.properties content preview: ${rawContent.take(200)}...")
|
||||
|
||||
|
||||
return parseProperties(rawContent)
|
||||
} else {
|
||||
debugLog("Failed to fetch plugin.properties. Response code: $responseCode")
|
||||
val errorReader = BufferedReader(InputStreamReader(connection.errorStream))
|
||||
val errorResponse = errorReader.use { it.readText() }
|
||||
debugLog("Error response for plugin.properties: $errorResponse")
|
||||
throw Exception("Plugin file not found for folder: $folderPath")
|
||||
} catch (e: HttpStatusException) {
|
||||
debugLog("Failed to fetch plugin.properties. Response code: ${e.statusCode}")
|
||||
debugLog("Error response for plugin.properties: ${e.body.take(200)}")
|
||||
throw Exception("Plugin file not found for folder: $folderPath", e)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import javax.swing.SwingUtilities
|
|||
* Manages downloading and installing plugins from GitLab with concurrent support
|
||||
*/
|
||||
object PluginDownloadManager {
|
||||
private const val TAG = "PluginDownloadManager"
|
||||
private const val MAX_CONCURRENT_DOWNLOADS = 3
|
||||
|
||||
// Thread pool for concurrent downloads
|
||||
|
|
@ -30,12 +31,8 @@ object PluginDownloadManager {
|
|||
}
|
||||
|
||||
// Debug logging function
|
||||
private fun debugLog(message: String) {
|
||||
if (GitLabConfig.DEBUG) {
|
||||
println("[PluginDownloadManager] $message")
|
||||
}
|
||||
}
|
||||
|
||||
private fun debugLog(message: String) = PluginLogger.debug(TAG, message)
|
||||
|
||||
// Get download URL for debugging/logging purposes
|
||||
fun getDownloadUrlForLogging(plugin: GitLabPlugin): String {
|
||||
return GitLabConfig.getArchiveUrl(plugin.path)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
package KondoKit.pluginmanager
|
||||
|
||||
/**
|
||||
* Shared lightweight logger so pluginmanager classes don't each redefine
|
||||
* their own debug helper tied to GitLabConfig.DEBUG.
|
||||
*/
|
||||
object PluginLogger {
|
||||
fun debug(tag: String, message: String) {
|
||||
if (GitLabConfig.DEBUG) {
|
||||
println("[$tag] $message")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -435,50 +435,50 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
|
|||
companion object {
|
||||
var customToolTipWindow: JWindow? = null
|
||||
|
||||
private var customToolTipLabel: JLabel? = null
|
||||
|
||||
fun showCustomToolTip(text: String, component: JComponent) {
|
||||
val tooltipFont = ViewConstants.FONT_RUNESCAPE_SMALL_PLAIN_16
|
||||
val maxWidth = 150
|
||||
|
||||
// Create a dummy JLabel to get FontMetrics for the font used in the tooltip
|
||||
val dummyLabel = JLabel()
|
||||
dummyLabel.font = tooltipFont
|
||||
val fontMetrics = dummyLabel.getFontMetrics(tooltipFont)
|
||||
val lineHeight = fontMetrics.height
|
||||
|
||||
// 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 = tooltipFont
|
||||
maximumSize = Dimension(maxWidth, Int.MAX_VALUE)
|
||||
preferredSize = Dimension(maxWidth, requiredHeight)
|
||||
}
|
||||
pack()
|
||||
val bgColor = Helpers.colorToHex(KondoKit.plugin.Companion.TOOLTIP_BACKGROUND)
|
||||
val textColor = Helpers.colorToHex(KondoKit.plugin.Companion.secondaryColor)
|
||||
// Constrain width via HTML so Swing's renderer wraps the text naturally.
|
||||
val safeText = text
|
||||
.replace("&", "&")
|
||||
.replace("<", "<")
|
||||
.replace(">", ">")
|
||||
val html = """
|
||||
<html>
|
||||
<body style="margin:0; padding:6px; width:${maxWidth}px; color:$textColor; background-color:$bgColor; word-wrap:break-word;">
|
||||
$safeText
|
||||
</body>
|
||||
</html>
|
||||
""".trimIndent()
|
||||
|
||||
val (window, label) = if (customToolTipWindow == null || customToolTipLabel == null) {
|
||||
val lbl = JLabel().apply {
|
||||
border = BorderFactory.createLineBorder(Color.BLACK)
|
||||
isOpaque = true
|
||||
background = KondoKit.plugin.Companion.TOOLTIP_BACKGROUND
|
||||
foreground = Color.WHITE
|
||||
font = tooltipFont
|
||||
horizontalAlignment = SwingConstants.LEFT
|
||||
verticalAlignment = SwingConstants.TOP
|
||||
}
|
||||
val win = JWindow().apply { contentPane.add(lbl) }
|
||||
customToolTipWindow = win
|
||||
customToolTipLabel = lbl
|
||||
win to lbl
|
||||
} 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()
|
||||
customToolTipWindow!! to customToolTipLabel!!
|
||||
}
|
||||
|
||||
|
||||
label.text = html
|
||||
label.font = tooltipFont
|
||||
label.preferredSize = null // let HTML + pack decide size from width constraint
|
||||
window.pack()
|
||||
|
||||
// Position the tooltip near the component
|
||||
val locationOnScreen = component.locationOnScreen
|
||||
customToolTipWindow!!.setLocation(locationOnScreen.x, locationOnScreen.y + 15)
|
||||
|
|
|
|||
|
|
@ -18,15 +18,23 @@ object GEPriceService {
|
|||
val grand_exchange_price: String?
|
||||
)
|
||||
|
||||
private fun <T> mapToPriceMap(
|
||||
items: Array<T>,
|
||||
idSelector: (T) -> String?,
|
||||
priceSelector: (T) -> String?
|
||||
): Map<String, String> {
|
||||
return items.mapNotNull { item ->
|
||||
val id = idSelector(item)
|
||||
val price = priceSelector(item)
|
||||
if (id != null && price != null) id to price else null
|
||||
}.toMap()
|
||||
}
|
||||
|
||||
fun loadRemotePrices(): Map<String, String> {
|
||||
return try {
|
||||
val payload = HttpFetcher.fetchString(REMOTE_GE_URL)
|
||||
val items = JsonParser.fromJson<Array<RemoteGEItem>>(payload)
|
||||
items.mapNotNull { item ->
|
||||
val id = item.item_id
|
||||
val value = item.value
|
||||
if (id != null && value != null) id to value else null
|
||||
}.toMap()
|
||||
mapToPriceMap(items, { it.item_id }, { it.value })
|
||||
} catch (e: Exception) {
|
||||
emptyMap()
|
||||
}
|
||||
|
|
@ -36,11 +44,7 @@ object GEPriceService {
|
|||
return try {
|
||||
val json = jsonProvider() ?: return emptyMap()
|
||||
val items = JsonParser.fromJson<Array<LocalGEItem>>(json)
|
||||
items.mapNotNull { item ->
|
||||
val id = item.id
|
||||
val price = item.grand_exchange_price
|
||||
if (id != null && price != null) id to price else null
|
||||
}.toMap()
|
||||
mapToPriceMap(items, { it.id }, { it.grand_exchange_price })
|
||||
} catch (e: Exception) {
|
||||
emptyMap()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import KondoKit.util.setFixedSize
|
|||
import KondoKit.views.XPTrackerView.wrappedWidget
|
||||
import KondoKit.ui.components.PopupMenuComponent
|
||||
import KondoKit.ui.components.ProgressBar
|
||||
import KondoKit.ui.components.LabelComponent
|
||||
import KondoKit.ui.components.WidgetPanel
|
||||
import KondoKit.plugin.Companion.TITLE_BAR_COLOR
|
||||
import KondoKit.plugin.Companion.TOOLTIP_BACKGROUND
|
||||
|
|
@ -171,12 +172,8 @@ object LootTrackerView : View, OnPostClientTickCallback, OnKillingBlowNPCCallbac
|
|||
}
|
||||
}
|
||||
|
||||
private fun createLabel(text: String): JLabel {
|
||||
return JLabel(text).apply {
|
||||
font = ViewConstants.FONT_RUNESCAPE_SMALL_16
|
||||
horizontalAlignment = JLabel.LEFT
|
||||
}
|
||||
}
|
||||
private fun createLabel(text: String): LabelComponent =
|
||||
LabelComponent(text, alignment = JLabel.LEFT)
|
||||
|
||||
private fun addItemToLootPanel(lootTrackerView: JPanel, drop: Item, npcName: String) {
|
||||
findLootItemsPanel(lootTrackerView, npcName)?.let { lootPanel ->
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import KondoKit.util.attachPopupMenu
|
|||
import KondoKit.util.XPTable
|
||||
import KondoKit.ui.components.PopupMenuComponent
|
||||
import KondoKit.ui.components.ProgressBar
|
||||
import KondoKit.ui.components.LabelComponent
|
||||
import KondoKit.ui.components.WidgetPanel
|
||||
import KondoKit.ui.components.XPWidget
|
||||
import KondoKit.plugin.Companion.IMAGE_SIZE
|
||||
|
|
@ -91,17 +92,13 @@ object XPTrackerView : View, OnUpdateCallback, OnXPUpdateCallback {
|
|||
}
|
||||
}
|
||||
|
||||
private fun createMetricLabel(title: String, initialValue: String = "0", topPadding: Int = 0): JLabel {
|
||||
return JLabel(formatHtmlLabelText("$title ", primaryColor, initialValue, secondaryColor)).apply {
|
||||
horizontalAlignment = JLabel.LEFT
|
||||
font = widgetFont
|
||||
private fun createMetricLabel(title: String, initialValue: String = "0", topPadding: Int = 0): LabelComponent =
|
||||
LabelComponent(alignment = JLabel.LEFT).apply {
|
||||
updateHtmlText("$title ", primaryColor, initialValue, secondaryColor)
|
||||
if (topPadding > 0) {
|
||||
border = BorderFactory.createEmptyBorder(topPadding, 0, 0, 0)
|
||||
} else {
|
||||
border = BorderFactory.createEmptyBorder(0, 0, 0, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSkillIcon(skillId: Int): BufferedImage {
|
||||
return skillIconCache[skillId] ?: getBufferedImageFromSprite(API.GetSprite(getSpriteId(skillId))).also {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue