mirror of
https://gitlab.com/2009scape/rt4-client.git
synced 2025-12-17 03:50:24 -07:00
consistent sizing
This commit is contained in:
parent
16546ef862
commit
14b107861e
11 changed files with 343 additions and 336 deletions
|
|
@ -14,21 +14,24 @@ object ViewConstants {
|
||||||
val FONT_RUNESCAPE_SMALL_16 = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
val FONT_RUNESCAPE_SMALL_16 = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
||||||
val FONT_RUNESCAPE_SMALL_14 = Font("RuneScape Small", Font.PLAIN, 14)
|
val FONT_RUNESCAPE_SMALL_14 = Font("RuneScape Small", Font.PLAIN, 14)
|
||||||
val FONT_RUNESCAPE_SMALL_PLAIN_16 = Font("RuneScape Small", Font.PLAIN, 16)
|
val FONT_RUNESCAPE_SMALL_PLAIN_16 = Font("RuneScape Small", Font.PLAIN, 16)
|
||||||
|
val FONT_RUNESCAPE_SMALL_BOLD_16 = Font("RuneScape Small", Font.BOLD, 16)
|
||||||
val FONT_ARIAL_PLAIN_14 = Font("Arial", Font.PLAIN, 14)
|
val FONT_ARIAL_PLAIN_14 = Font("Arial", Font.PLAIN, 14)
|
||||||
val FONT_ARIAL_BOLD_12 = Font("Arial", Font.BOLD, 12)
|
val FONT_ARIAL_BOLD_12 = Font("Arial", Font.BOLD, 12)
|
||||||
|
|
||||||
// Common Dimensions
|
// Common Dimensions
|
||||||
val DIMENSION_SMALL_ICON = Dimension(12, 12)
|
val DIMENSION_SMALL_ICON = Dimension(12, 12)
|
||||||
val DIMENSION_LARGE_ICON = Dimension(30, 30)
|
val DIMENSION_LARGE_ICON = Dimension(30, 30)
|
||||||
val DEFAULT_WIDGET_SIZE = Dimension(220, 50)
|
val DEFAULT_WIDGET_SIZE = Dimension(234, 50)
|
||||||
|
val PLUGIN_LIST_ITEM_SIZE = Dimension(DEFAULT_WIDGET_SIZE.width, 60)
|
||||||
|
val TOGGLE_PLACEHOLDER_SIZE = Dimension(60, 24)
|
||||||
val TOTAL_XP_WIDGET_SIZE = Dimension(220, 30)
|
val TOTAL_XP_WIDGET_SIZE = Dimension(220, 30)
|
||||||
val IMAGE_SIZE = Dimension(25, 23)
|
val IMAGE_SIZE = Dimension(25, 23)
|
||||||
val SEARCH_FIELD_SIZE = Dimension(230, 30)
|
val SEARCH_FIELD_SIZE = Dimension(DEFAULT_WIDGET_SIZE.width, 30)
|
||||||
val DEFAULT_PANEL_SIZE = Dimension(230, 500)
|
val DEFAULT_PANEL_SIZE = Dimension(DEFAULT_WIDGET_SIZE.width, 500)
|
||||||
val FILTER_PANEL_SIZE = Dimension(230, 30)
|
val FILTER_PANEL_SIZE = Dimension(DEFAULT_WIDGET_SIZE.width, 30)
|
||||||
val SKILLS_PANEL_SIZE = Dimension(230, 290)
|
val SKILLS_PANEL_SIZE = Dimension(DEFAULT_WIDGET_SIZE.width, 290)
|
||||||
val TOTAL_COMBAT_PANEL_SIZE = Dimension(230, 30)
|
val TOTAL_COMBAT_PANEL_SIZE = Dimension(DEFAULT_WIDGET_SIZE.width, 30)
|
||||||
val SKILL_PANEL_SIZE = Dimension(76, 35)
|
val SKILL_PANEL_SIZE = Dimension(DEFAULT_WIDGET_SIZE.width / 3, 35)
|
||||||
val IMAGE_CANVAS_SIZE = Dimension(20, 20)
|
val IMAGE_CANVAS_SIZE = Dimension(20, 20)
|
||||||
val SKILL_SPRITE_SIZE = Dimension(14, 14)
|
val SKILL_SPRITE_SIZE = Dimension(14, 14)
|
||||||
val NUMBER_LABEL_SIZE = Dimension(20, 20)
|
val NUMBER_LABEL_SIZE = Dimension(20, 20)
|
||||||
|
|
@ -42,19 +45,6 @@ object ViewConstants {
|
||||||
val COLOR_RED = Color.RED
|
val COLOR_RED = Color.RED
|
||||||
val COLOR_GRAY = Color.GRAY
|
val COLOR_GRAY = Color.GRAY
|
||||||
|
|
||||||
// UI Colors (already defined in plugin.kt companion object, but referenced here for consistency)
|
|
||||||
// These should match the ones in plugin.kt Companion object
|
|
||||||
val COLOR_WIDGET = Color(30, 30, 30)
|
|
||||||
val COLOR_TITLE_BAR = Color(21, 21, 21)
|
|
||||||
val COLOR_VIEW_BACKGROUND = Color(40, 40, 40)
|
|
||||||
val COLOR_PRIMARY = Color(165, 165, 165)
|
|
||||||
val COLOR_SECONDARY = Color(255, 255, 255)
|
|
||||||
val COLOR_POPUP_BACKGROUND = Color(45, 45, 45)
|
|
||||||
val COLOR_POPUP_FOREGROUND = Color(220, 220, 220)
|
|
||||||
val COLOR_TOOLTIP_BACKGROUND = Color(50, 50, 50)
|
|
||||||
val COLOR_SCROLL_BAR = Color(64, 64, 64)
|
|
||||||
val COLOR_PROGRESS_BAR_FILL = Color(61, 56, 49)
|
|
||||||
|
|
||||||
// Skill display order
|
// Skill display order
|
||||||
val SKILL_DISPLAY_ORDER = arrayOf(0, 3, 14, 2, 16, 13, 1, 15, 10, 4, 17, 7, 5, 12, 11, 6, 9, 8, 20, 18, 19, 22, 21, 23)
|
val SKILL_DISPLAY_ORDER = arrayOf(0, 3, 14, 2, 16, 13, 1, 15, 10, 4, 17, 7, 5, 12, 11, 6, 9, 8, 20, 18, 19, 22, 21, 23)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ class SearchField(
|
||||||
private val parentPanel: JPanel,
|
private val parentPanel: JPanel,
|
||||||
private val onSearch: (String) -> Unit,
|
private val onSearch: (String) -> Unit,
|
||||||
private val placeholderText: String = "Search...",
|
private val placeholderText: String = "Search...",
|
||||||
private val fieldWidth: Int = 230,
|
private val fieldWidth: Int = ViewConstants.SEARCH_FIELD_SIZE.width,
|
||||||
private val fieldHeight: Int = 30,
|
private val fieldHeight: Int = ViewConstants.SEARCH_FIELD_SIZE.height,
|
||||||
private val viewName: String? = ""
|
private val viewName: String? = ""
|
||||||
) : Canvas() {
|
) : Canvas() {
|
||||||
|
|
||||||
|
|
@ -40,10 +40,25 @@ class SearchField(
|
||||||
preferredSize = dimension
|
preferredSize = dimension
|
||||||
background = WIDGET_COLOR
|
background = WIDGET_COLOR
|
||||||
foreground = secondaryColor
|
foreground = secondaryColor
|
||||||
font = Font("Arial", Font.PLAIN, 14)
|
font = ViewConstants.FONT_ARIAL_PLAIN_14
|
||||||
minimumSize = dimension
|
minimumSize = dimension
|
||||||
maximumSize = dimension
|
maximumSize = dimension
|
||||||
|
|
||||||
|
isFocusable = true
|
||||||
|
focusTraversalKeysEnabled = false
|
||||||
|
|
||||||
|
addFocusListener(object : FocusAdapter() {
|
||||||
|
override fun focusGained(e: FocusEvent) {
|
||||||
|
cursorVisible = true
|
||||||
|
repaintAsync()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun focusLost(e: FocusEvent) {
|
||||||
|
cursorVisible = false
|
||||||
|
repaintAsync()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
addKeyListener(object : KeyAdapter() {
|
addKeyListener(object : KeyAdapter() {
|
||||||
override fun keyTyped(e: KeyEvent) {
|
override fun keyTyped(e: KeyEvent) {
|
||||||
// Prevent null character from being typed on Ctrl+A & Ctrl+V
|
// Prevent null character from being typed on Ctrl+A & Ctrl+V
|
||||||
|
|
@ -56,33 +71,33 @@ class SearchField(
|
||||||
text = text.dropLast(1)
|
text = text.dropLast(1)
|
||||||
}
|
}
|
||||||
} else if (e.keyChar == '\n') {
|
} else if (e.keyChar == '\n') {
|
||||||
triggerSearch()
|
// Handled in keyPressed to avoid duplicate searches
|
||||||
} else {
|
} else {
|
||||||
text += e.keyChar
|
text += e.keyChar
|
||||||
}
|
}
|
||||||
SwingUtilities.invokeLater {
|
repaintAsync()
|
||||||
repaint()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun keyPressed(e: KeyEvent) {
|
override fun keyPressed(e: KeyEvent) {
|
||||||
|
if (e.keyCode == KeyEvent.VK_ENTER) {
|
||||||
|
triggerSearch()
|
||||||
|
e.consume()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (e.isControlDown) {
|
if (e.isControlDown) {
|
||||||
when (e.keyCode) {
|
when (e.keyCode) {
|
||||||
KeyEvent.VK_A -> {
|
KeyEvent.VK_A -> {
|
||||||
// They probably want to clear the search box
|
// They probably want to clear the search box
|
||||||
text = ""
|
text = ""
|
||||||
SwingUtilities.invokeLater {
|
repaintAsync()
|
||||||
repaint()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
KeyEvent.VK_V -> {
|
KeyEvent.VK_V -> {
|
||||||
try {
|
try {
|
||||||
val clipboard = Toolkit.getDefaultToolkit().systemClipboard
|
val clipboard = Toolkit.getDefaultToolkit().systemClipboard
|
||||||
val pasteText = clipboard.getData(DataFlavor.stringFlavor) as String
|
val pasteText = clipboard.getData(DataFlavor.stringFlavor) as String
|
||||||
text += pasteText
|
text += pasteText
|
||||||
SwingUtilities.invokeLater {
|
repaintAsync()
|
||||||
repaint()
|
|
||||||
}
|
|
||||||
} catch (_: Exception) { }
|
} catch (_: Exception) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -93,23 +108,24 @@ class SearchField(
|
||||||
addMouseListener(object : MouseAdapter() {
|
addMouseListener(object : MouseAdapter() {
|
||||||
// Clicked the search field 'x' button
|
// Clicked the search field 'x' button
|
||||||
override fun mouseClicked(e: MouseEvent) {
|
override fun mouseClicked(e: MouseEvent) {
|
||||||
|
requestFocusInWindow()
|
||||||
if (e.x > width - 20 && e.y < 20) {
|
if (e.x > width - 20 && e.y < 20) {
|
||||||
text = ""
|
text = ""
|
||||||
triggerSearch()
|
triggerSearch()
|
||||||
SwingUtilities.invokeLater {
|
repaintAsync()
|
||||||
repaint()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun mousePressed(e: MouseEvent) {
|
||||||
|
requestFocusInWindow()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
Timer(500) { _ ->
|
Timer(500) { _ ->
|
||||||
cursorVisible = !cursorVisible
|
cursorVisible = !cursorVisible
|
||||||
// Only repaint if the view is active or if viewName is not specified
|
// Only repaint if the view is active or if viewName is not specified
|
||||||
if (viewName == null || focusedView == viewName) {
|
if (viewName == null || focusedView == viewName) {
|
||||||
SwingUtilities.invokeLater {
|
repaintAsync()
|
||||||
repaint()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
|
|
@ -155,7 +171,7 @@ class SearchField(
|
||||||
|
|
||||||
fun setText(newText: String) {
|
fun setText(newText: String) {
|
||||||
text = newText
|
text = newText
|
||||||
repaint()
|
repaintAsync()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getText(): String = text
|
fun getText(): String = text
|
||||||
|
|
@ -164,10 +180,14 @@ class SearchField(
|
||||||
val query = text.trim()
|
val query = text.trim()
|
||||||
if (query.isNotEmpty()) {
|
if (query.isNotEmpty()) {
|
||||||
text = query
|
text = query
|
||||||
repaint()
|
repaintAsync()
|
||||||
onSearch(query)
|
onSearch(query)
|
||||||
} else {
|
} else {
|
||||||
onSearch(query) // Call with empty string for clearing filters
|
onSearch(query) // Call with empty string for clearing filters
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun repaintAsync() {
|
||||||
|
SwingUtilities.invokeLater { repaint() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ package KondoKit.components
|
||||||
|
|
||||||
import KondoKit.Helpers
|
import KondoKit.Helpers
|
||||||
import KondoKit.Helpers.FieldNotifier
|
import KondoKit.Helpers.FieldNotifier
|
||||||
|
import KondoKit.ViewConstants
|
||||||
import KondoKit.plugin.Companion.WIDGET_COLOR
|
import KondoKit.plugin.Companion.WIDGET_COLOR
|
||||||
import KondoKit.plugin.Companion.primaryColor
|
import KondoKit.plugin.Companion.primaryColor
|
||||||
import KondoKit.plugin.Companion.secondaryColor
|
import KondoKit.plugin.Companion.secondaryColor
|
||||||
|
|
@ -62,7 +63,7 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
|
||||||
|
|
||||||
val label = JLabel(field.name.capitalize()).apply {
|
val label = JLabel(field.name.capitalize()).apply {
|
||||||
foreground = secondaryColor
|
foreground = secondaryColor
|
||||||
font = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
font = ViewConstants.FONT_RUNESCAPE_SMALL_16
|
||||||
}
|
}
|
||||||
gbc.gridx = 0
|
gbc.gridx = 0
|
||||||
gbc.gridy = 0
|
gbc.gridy = 0
|
||||||
|
|
@ -229,7 +230,7 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
|
||||||
// Create title label
|
// Create title label
|
||||||
val titleLabel = JLabel("${field.name} (Key-Value Pairs)").apply {
|
val titleLabel = JLabel("${field.name} (Key-Value Pairs)").apply {
|
||||||
foreground = secondaryColor
|
foreground = secondaryColor
|
||||||
font = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
font = ViewConstants.FONT_RUNESCAPE_SMALL_16
|
||||||
alignmentX = Component.LEFT_ALIGNMENT
|
alignmentX = Component.LEFT_ALIGNMENT
|
||||||
|
|
||||||
// Add mouse listener to the label only if a description is available
|
// Add mouse listener to the label only if a description is available
|
||||||
|
|
@ -451,14 +452,14 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
|
||||||
var customToolTipWindow: JWindow? = null
|
var customToolTipWindow: JWindow? = null
|
||||||
|
|
||||||
fun showCustomToolTip(text: String, component: JComponent) {
|
fun showCustomToolTip(text: String, component: JComponent) {
|
||||||
val _font = Font("RuneScape Small", Font.PLAIN, 16)
|
val tooltipFont = ViewConstants.FONT_RUNESCAPE_SMALL_PLAIN_16
|
||||||
val maxWidth = 150
|
val maxWidth = 150
|
||||||
val lineHeight = 16
|
|
||||||
|
|
||||||
// Create a dummy JLabel to get FontMetrics for the font used in the tooltip
|
// Create a dummy JLabel to get FontMetrics for the font used in the tooltip
|
||||||
val dummyLabel = JLabel()
|
val dummyLabel = JLabel()
|
||||||
dummyLabel.font = _font
|
dummyLabel.font = tooltipFont
|
||||||
val fontMetrics = dummyLabel.getFontMetrics(_font)
|
val fontMetrics = dummyLabel.getFontMetrics(tooltipFont)
|
||||||
|
val lineHeight = fontMetrics.height
|
||||||
|
|
||||||
// Calculate the approximate width of the text
|
// Calculate the approximate width of the text
|
||||||
val textWidth = fontMetrics.stringWidth(text)
|
val textWidth = fontMetrics.stringWidth(text)
|
||||||
|
|
@ -478,7 +479,7 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
|
||||||
isOpaque = true
|
isOpaque = true
|
||||||
background = KondoKit.plugin.Companion.TOOLTIP_BACKGROUND
|
background = KondoKit.plugin.Companion.TOOLTIP_BACKGROUND
|
||||||
foreground = Color.WHITE
|
foreground = Color.WHITE
|
||||||
font = _font
|
font = tooltipFont
|
||||||
maximumSize = Dimension(maxWidth, Int.MAX_VALUE)
|
maximumSize = Dimension(maxWidth, Int.MAX_VALUE)
|
||||||
preferredSize = Dimension(maxWidth, requiredHeight)
|
preferredSize = Dimension(maxWidth, requiredHeight)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package KondoKit.components
|
package KondoKit.components
|
||||||
|
|
||||||
|
import KondoKit.ViewConstants
|
||||||
import KondoKit.plugin.Companion.TITLE_BAR_COLOR
|
import KondoKit.plugin.Companion.TITLE_BAR_COLOR
|
||||||
import KondoKit.plugin.Companion.secondaryColor
|
import KondoKit.plugin.Companion.secondaryColor
|
||||||
import java.awt.*
|
import java.awt.*
|
||||||
|
|
@ -19,7 +20,7 @@ class ViewHeader(
|
||||||
layout = BorderLayout()
|
layout = BorderLayout()
|
||||||
|
|
||||||
titleLabel.foreground = secondaryColor
|
titleLabel.foreground = secondaryColor
|
||||||
titleLabel.font = Font("RuneScape Small", Font.PLAIN, 16)
|
titleLabel.font = ViewConstants.FONT_RUNESCAPE_SMALL_PLAIN_16
|
||||||
titleLabel.horizontalAlignment = SwingConstants.CENTER
|
titleLabel.horizontalAlignment = SwingConstants.CENTER
|
||||||
|
|
||||||
add(titleLabel, BorderLayout.CENTER)
|
add(titleLabel, BorderLayout.CENTER)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package KondoKit.components
|
package KondoKit.components
|
||||||
|
|
||||||
|
import KondoKit.ViewConstants
|
||||||
import KondoKit.plugin.Companion.WIDGET_COLOR
|
import KondoKit.plugin.Companion.WIDGET_COLOR
|
||||||
import java.awt.BorderLayout
|
import java.awt.BorderLayout
|
||||||
import java.awt.Dimension
|
import java.awt.Dimension
|
||||||
|
|
@ -7,13 +8,16 @@ import javax.swing.BorderFactory
|
||||||
import javax.swing.JPanel
|
import javax.swing.JPanel
|
||||||
|
|
||||||
class WidgetPanel(
|
class WidgetPanel(
|
||||||
private val widgetWidth: Int = 220,
|
private val widgetWidth: Int = ViewConstants.DEFAULT_WIDGET_SIZE.width,
|
||||||
private val widgetHeight: Int = 50,
|
private val widgetHeight: Int = ViewConstants.DEFAULT_WIDGET_SIZE.height,
|
||||||
private val addDefaultPadding: Boolean = true
|
private val addDefaultPadding: Boolean = true
|
||||||
) : JPanel() {
|
) : JPanel() {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
layout = BorderLayout(5, 5)
|
layout = BorderLayout(
|
||||||
|
if (addDefaultPadding) 5 else 0,
|
||||||
|
if (addDefaultPadding) 5 else 0
|
||||||
|
)
|
||||||
background = WIDGET_COLOR
|
background = WIDGET_COLOR
|
||||||
|
|
||||||
val size = Dimension(widgetWidth, widgetHeight)
|
val size = Dimension(widgetWidth, widgetHeight)
|
||||||
|
|
@ -23,6 +27,8 @@ class WidgetPanel(
|
||||||
|
|
||||||
if (addDefaultPadding) {
|
if (addDefaultPadding) {
|
||||||
border = BorderFactory.createEmptyBorder(5, 5, 5, 5)
|
border = BorderFactory.createEmptyBorder(5, 5, 5, 5)
|
||||||
|
} else {
|
||||||
|
border = BorderFactory.createEmptyBorder(0, 0, 0, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package KondoKit.views
|
package KondoKit.views
|
||||||
|
|
||||||
|
import KondoKit.ViewConstants
|
||||||
import KondoKit.plugin.Companion.VIEW_BACKGROUND_COLOR
|
import KondoKit.plugin.Companion.VIEW_BACKGROUND_COLOR
|
||||||
import java.awt.Dimension
|
import java.awt.Dimension
|
||||||
import javax.swing.BorderFactory
|
import javax.swing.BorderFactory
|
||||||
|
|
@ -9,7 +10,7 @@ import javax.swing.JPanel
|
||||||
|
|
||||||
open class BaseView(
|
open class BaseView(
|
||||||
private val viewName: String,
|
private val viewName: String,
|
||||||
private val preferredWidth: Int = 242,
|
private val preferredWidth: Int = ViewConstants.DEFAULT_PANEL_SIZE.width,
|
||||||
private val addDefaultSpacing: Boolean = true
|
private val addDefaultSpacing: Boolean = true
|
||||||
) : JPanel() {
|
) : JPanel() {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,10 @@ import KondoKit.Helpers.showToast
|
||||||
import KondoKit.ImageCanvas
|
import KondoKit.ImageCanvas
|
||||||
import KondoKit.ViewConstants
|
import KondoKit.ViewConstants
|
||||||
import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
|
import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
|
||||||
import KondoKit.components.SearchField
|
|
||||||
import KondoKit.components.LabelComponent
|
import KondoKit.components.LabelComponent
|
||||||
|
import KondoKit.components.WidgetPanel
|
||||||
|
import KondoKit.components.SearchField
|
||||||
|
import KondoKit.views.ViewLayoutHelpers.createSearchFieldSection
|
||||||
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
|
||||||
|
|
@ -51,65 +53,50 @@ object HiscoresView : View {
|
||||||
setViewSize(ViewConstants.DEFAULT_PANEL_SIZE.height)
|
setViewSize(ViewConstants.DEFAULT_PANEL_SIZE.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
customSearchField = SearchField(
|
val searchSection = createSearchFieldSection(
|
||||||
hiscorePanel,
|
parent = hiscorePanel,
|
||||||
{ username ->
|
placeholderText = "Search player...",
|
||||||
searchPlayerForHiscores(username, hiscorePanel)
|
viewName = VIEW_NAME
|
||||||
},
|
) { username ->
|
||||||
"Search player...",
|
searchPlayerForHiscores(username, hiscorePanel)
|
||||||
242,
|
|
||||||
30,
|
|
||||||
VIEW_NAME
|
|
||||||
)
|
|
||||||
|
|
||||||
val searchField = customSearchField!!
|
|
||||||
|
|
||||||
val searchFieldWrapper = JPanel().apply {
|
|
||||||
layout = BoxLayout(this, BoxLayout.X_AXIS)
|
|
||||||
background = VIEW_BACKGROUND_COLOR
|
|
||||||
preferredSize = ViewConstants.SEARCH_FIELD_SIZE
|
|
||||||
maximumSize = preferredSize
|
|
||||||
minimumSize = preferredSize
|
|
||||||
alignmentX = Component.CENTER_ALIGNMENT
|
|
||||||
add(searchField)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val searchPanel = JPanel().apply {
|
customSearchField = searchSection.searchField
|
||||||
layout = BoxLayout(this, BoxLayout.Y_AXIS)
|
|
||||||
background = VIEW_BACKGROUND_COLOR
|
|
||||||
add(searchFieldWrapper)
|
|
||||||
}
|
|
||||||
|
|
||||||
hiscorePanel.add(Box.createVerticalStrut(5))
|
hiscorePanel.add(Box.createVerticalStrut(5))
|
||||||
hiscorePanel.add(searchPanel)
|
hiscorePanel.add(searchSection.wrapper)
|
||||||
hiscorePanel.add(Box.createVerticalStrut(5))
|
hiscorePanel.add(Box.createVerticalStrut(5))
|
||||||
|
|
||||||
val playerNamePanel = JPanel().apply {
|
val playerNamePanel = WidgetPanel(
|
||||||
|
widgetWidth = ViewConstants.FILTER_PANEL_SIZE.width,
|
||||||
|
widgetHeight = ViewConstants.FILTER_PANEL_SIZE.height,
|
||||||
|
addDefaultPadding = false
|
||||||
|
).apply {
|
||||||
layout = GridBagLayout() // This will center the JLabel both vertically and horizontally
|
layout = GridBagLayout() // This will center the JLabel both vertically and horizontally
|
||||||
background = TOOLTIP_BACKGROUND.darker()
|
background = TOOLTIP_BACKGROUND.darker()
|
||||||
preferredSize = ViewConstants.FILTER_PANEL_SIZE
|
|
||||||
maximumSize = preferredSize
|
|
||||||
minimumSize = preferredSize
|
|
||||||
name = "playerNameLabel"
|
name = "playerNameLabel"
|
||||||
}
|
}
|
||||||
|
|
||||||
hiscorePanel.add(playerNamePanel)
|
hiscorePanel.add(playerNamePanel)
|
||||||
hiscorePanel.add(Box.createVerticalStrut(5))
|
hiscorePanel.add(Box.createVerticalStrut(5))
|
||||||
|
|
||||||
val skillsPanel = JPanel(FlowLayout(FlowLayout.CENTER, 0, 0)).apply {
|
val skillsPanel = WidgetPanel(
|
||||||
|
widgetWidth = ViewConstants.SKILLS_PANEL_SIZE.width,
|
||||||
|
widgetHeight = ViewConstants.SKILLS_PANEL_SIZE.height,
|
||||||
|
addDefaultPadding = false
|
||||||
|
).apply {
|
||||||
|
layout = FlowLayout(FlowLayout.CENTER, 0, 0)
|
||||||
background = VIEW_BACKGROUND_COLOR
|
background = VIEW_BACKGROUND_COLOR
|
||||||
preferredSize = ViewConstants.SKILLS_PANEL_SIZE
|
|
||||||
maximumSize = preferredSize
|
|
||||||
minimumSize = preferredSize
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i in ViewConstants.SKILL_DISPLAY_ORDER) {
|
for (i in ViewConstants.SKILL_DISPLAY_ORDER) {
|
||||||
val skillPanel = JPanel().apply {
|
val skillPanel = WidgetPanel(
|
||||||
|
widgetWidth = ViewConstants.SKILL_PANEL_SIZE.width,
|
||||||
|
widgetHeight = ViewConstants.SKILL_PANEL_SIZE.height,
|
||||||
|
addDefaultPadding = false
|
||||||
|
).apply {
|
||||||
layout = BorderLayout()
|
layout = BorderLayout()
|
||||||
background = WIDGET_COLOR
|
background = WIDGET_COLOR
|
||||||
preferredSize = ViewConstants.SKILL_PANEL_SIZE
|
|
||||||
maximumSize = preferredSize
|
|
||||||
minimumSize = preferredSize
|
|
||||||
border = MatteBorder(5, 0, 0, 0, WIDGET_COLOR)
|
border = MatteBorder(5, 0, 0, 0, WIDGET_COLOR)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -143,11 +130,13 @@ object HiscoresView : View {
|
||||||
|
|
||||||
hiscorePanel.add(skillsPanel)
|
hiscorePanel.add(skillsPanel)
|
||||||
|
|
||||||
val totalCombatPanel = JPanel(FlowLayout(FlowLayout.CENTER, 0, 0)).apply {
|
val totalCombatPanel = WidgetPanel(
|
||||||
|
widgetWidth = ViewConstants.TOTAL_COMBAT_PANEL_SIZE.width,
|
||||||
|
widgetHeight = ViewConstants.TOTAL_COMBAT_PANEL_SIZE.height,
|
||||||
|
addDefaultPadding = false
|
||||||
|
).apply {
|
||||||
|
layout = FlowLayout(FlowLayout.LEFT, 0, 0)
|
||||||
background = WIDGET_COLOR
|
background = WIDGET_COLOR
|
||||||
preferredSize = ViewConstants.TOTAL_COMBAT_PANEL_SIZE
|
|
||||||
maximumSize = preferredSize
|
|
||||||
minimumSize = preferredSize
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val bufferedImageSprite = getBufferedImageFromSprite(API.GetSprite(ViewConstants.LVL_BAR_SPRITE))
|
val bufferedImageSprite = getBufferedImageFromSprite(API.GetSprite(ViewConstants.LVL_BAR_SPRITE))
|
||||||
|
|
@ -166,7 +155,12 @@ object HiscoresView : View {
|
||||||
iconTextGap = 10
|
iconTextGap = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
val totalLevelPanel = JPanel(FlowLayout(FlowLayout.LEFT)).apply {
|
val totalLevelPanel = WidgetPanel(
|
||||||
|
widgetWidth = ViewConstants.TOTAL_COMBAT_PANEL_SIZE.width / 2,
|
||||||
|
widgetHeight = ViewConstants.TOTAL_COMBAT_PANEL_SIZE.height,
|
||||||
|
addDefaultPadding = false
|
||||||
|
).apply {
|
||||||
|
layout = FlowLayout(FlowLayout.LEFT, 5, 0)
|
||||||
background = WIDGET_COLOR
|
background = WIDGET_COLOR
|
||||||
add(totalLevelIcon)
|
add(totalLevelIcon)
|
||||||
add(totalLevelLabel)
|
add(totalLevelLabel)
|
||||||
|
|
@ -188,7 +182,12 @@ object HiscoresView : View {
|
||||||
iconTextGap = 10
|
iconTextGap = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
val combatLevelPanel = JPanel(FlowLayout(FlowLayout.LEFT)).apply {
|
val combatLevelPanel = WidgetPanel(
|
||||||
|
widgetWidth = ViewConstants.TOTAL_COMBAT_PANEL_SIZE.width / 2,
|
||||||
|
widgetHeight = ViewConstants.TOTAL_COMBAT_PANEL_SIZE.height,
|
||||||
|
addDefaultPadding = false
|
||||||
|
).apply {
|
||||||
|
layout = FlowLayout(FlowLayout.LEFT, 5, 0)
|
||||||
background = WIDGET_COLOR
|
background = WIDGET_COLOR
|
||||||
add(combatLevelIcon)
|
add(combatLevelIcon)
|
||||||
add(combatLevelLabel)
|
add(combatLevelLabel)
|
||||||
|
|
@ -401,4 +400,3 @@ object HiscoresView : View {
|
||||||
return Math.round((base + maxCombatType + summoningFactor) * 1000.0) / 1000.0
|
return Math.round((base + maxCombatType + summoningFactor) * 1000.0) / 1000.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import KondoKit.Helpers.addMouseListenerToAll
|
||||||
import KondoKit.Helpers.formatHtmlLabelText
|
import KondoKit.Helpers.formatHtmlLabelText
|
||||||
import KondoKit.ImageCanvas
|
import KondoKit.ImageCanvas
|
||||||
import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
|
import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
|
||||||
|
import KondoKit.ViewConstants
|
||||||
import KondoKit.views.XPTrackerView.wrappedWidget
|
import KondoKit.views.XPTrackerView.wrappedWidget
|
||||||
import KondoKit.components.PopupMenuComponent
|
import KondoKit.components.PopupMenuComponent
|
||||||
import KondoKit.components.ProgressBar
|
import KondoKit.components.ProgressBar
|
||||||
|
|
@ -228,7 +229,7 @@ object LootTrackerView : View, OnPostClientTickCallback, OnKillingBlowNPCCallbac
|
||||||
|
|
||||||
private fun createLabel(text: String): JLabel {
|
private fun createLabel(text: String): JLabel {
|
||||||
return JLabel(text).apply {
|
return JLabel(text).apply {
|
||||||
font = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
font = ViewConstants.FONT_RUNESCAPE_SMALL_16
|
||||||
horizontalAlignment = JLabel.LEFT
|
horizontalAlignment = JLabel.LEFT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -320,7 +321,7 @@ object LootTrackerView : View, OnPostClientTickCallback, OnKillingBlowNPCCallbac
|
||||||
"GE: ${formatValue(totalGePrice)} ${geText}<br>" +
|
"GE: ${formatValue(totalGePrice)} ${geText}<br>" +
|
||||||
"HA: ${formatValue(totalHaPrice)} ${haText}</div></html>"
|
"HA: ${formatValue(totalHaPrice)} ${haText}</div></html>"
|
||||||
|
|
||||||
val _font = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
val tooltipFont = ViewConstants.FONT_RUNESCAPE_SMALL_16
|
||||||
if (customToolTipWindow == null) {
|
if (customToolTipWindow == null) {
|
||||||
customToolTipWindow = JWindow().apply {
|
customToolTipWindow = JWindow().apply {
|
||||||
contentPane = JLabel(text).apply {
|
contentPane = JLabel(text).apply {
|
||||||
|
|
@ -328,7 +329,7 @@ object LootTrackerView : View, OnPostClientTickCallback, OnKillingBlowNPCCallbac
|
||||||
isOpaque = true
|
isOpaque = true
|
||||||
background = TOOLTIP_BACKGROUND
|
background = TOOLTIP_BACKGROUND
|
||||||
foreground = Color.WHITE
|
foreground = Color.WHITE
|
||||||
font = _font
|
font = tooltipFont
|
||||||
}
|
}
|
||||||
pack()
|
pack()
|
||||||
}
|
}
|
||||||
|
|
@ -463,15 +464,15 @@ object LootTrackerView : View, OnPostClientTickCallback, OnKillingBlowNPCCallbac
|
||||||
val childFramePanel = JPanel().apply {
|
val childFramePanel = JPanel().apply {
|
||||||
layout = BoxLayout(this, BoxLayout.Y_AXIS)
|
layout = BoxLayout(this, BoxLayout.Y_AXIS)
|
||||||
background = WIDGET_COLOR
|
background = WIDGET_COLOR
|
||||||
minimumSize = Dimension(230, 0)
|
minimumSize = Dimension(ViewConstants.DEFAULT_WIDGET_SIZE.width, 0)
|
||||||
maximumSize = Dimension(230, 700)
|
maximumSize = Dimension(ViewConstants.DEFAULT_WIDGET_SIZE.width, 700)
|
||||||
name = "HELLO_WORLD"
|
name = "HELLO_WORLD"
|
||||||
}
|
}
|
||||||
|
|
||||||
val labelPanel = JPanel(BorderLayout()).apply {
|
val labelPanel = JPanel(BorderLayout()).apply {
|
||||||
background = TITLE_BAR_COLOR
|
background = TITLE_BAR_COLOR
|
||||||
border = BorderFactory.createEmptyBorder(5, 5, 5, 5)
|
border = BorderFactory.createEmptyBorder(5, 5, 5, 5)
|
||||||
maximumSize = Dimension(230, 24)
|
maximumSize = Dimension(ViewConstants.DEFAULT_WIDGET_SIZE.width, 24)
|
||||||
minimumSize = maximumSize
|
minimumSize = maximumSize
|
||||||
preferredSize = maximumSize
|
preferredSize = maximumSize
|
||||||
}
|
}
|
||||||
|
|
@ -479,14 +480,14 @@ object LootTrackerView : View, OnPostClientTickCallback, OnKillingBlowNPCCallbac
|
||||||
val killCount = npcKillCounts.getOrPut(npcName) { 0 }
|
val killCount = npcKillCounts.getOrPut(npcName) { 0 }
|
||||||
val countLabel = JLabel(formatHtmlLabelText(npcName, secondaryColor, " x $killCount", primaryColor)).apply {
|
val countLabel = JLabel(formatHtmlLabelText(npcName, secondaryColor, " x $killCount", primaryColor)).apply {
|
||||||
foreground = secondaryColor
|
foreground = secondaryColor
|
||||||
font = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
font = ViewConstants.FONT_RUNESCAPE_SMALL_16
|
||||||
horizontalAlignment = JLabel.LEFT
|
horizontalAlignment = JLabel.LEFT
|
||||||
name = "killCountLabel_$npcName"
|
name = "killCountLabel_$npcName"
|
||||||
}
|
}
|
||||||
|
|
||||||
val valueLabel = JLabel("0 gp").apply {
|
val valueLabel = JLabel("0 gp").apply {
|
||||||
foreground = secondaryColor
|
foreground = secondaryColor
|
||||||
font = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
font = ViewConstants.FONT_RUNESCAPE_SMALL_16
|
||||||
horizontalAlignment = JLabel.RIGHT
|
horizontalAlignment = JLabel.RIGHT
|
||||||
name = "valueLabel_$npcName"
|
name = "valueLabel_$npcName"
|
||||||
}
|
}
|
||||||
|
|
@ -531,7 +532,7 @@ object LootTrackerView : View, OnPostClientTickCallback, OnKillingBlowNPCCallbac
|
||||||
private fun removeLootFrameMenu(toRemove: JPanel, npcName: String): JPopupMenu {
|
private fun removeLootFrameMenu(toRemove: JPanel, npcName: String): JPopupMenu {
|
||||||
// Create a popup menu
|
// Create a popup menu
|
||||||
val popupMenu = PopupMenuComponent()
|
val popupMenu = PopupMenuComponent()
|
||||||
val rFont = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
val rFont = ViewConstants.FONT_RUNESCAPE_SMALL_16
|
||||||
|
|
||||||
popupMenu.background = POPUP_BACKGROUND
|
popupMenu.background = POPUP_BACKGROUND
|
||||||
|
|
||||||
|
|
@ -571,7 +572,7 @@ object LootTrackerView : View, OnPostClientTickCallback, OnKillingBlowNPCCallbac
|
||||||
|
|
||||||
// Create menu items with custom font and colors
|
// Create menu items with custom font and colors
|
||||||
val menuItem1 = JMenuItem("Reset Loot Tracker").apply {
|
val menuItem1 = JMenuItem("Reset Loot Tracker").apply {
|
||||||
font = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
font = ViewConstants.FONT_RUNESCAPE_SMALL_16
|
||||||
background = POPUP_BACKGROUND
|
background = POPUP_BACKGROUND
|
||||||
foreground = POPUP_FOREGROUND
|
foreground = POPUP_FOREGROUND
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@ package KondoKit.views
|
||||||
|
|
||||||
import KondoKit.Helpers
|
import KondoKit.Helpers
|
||||||
import KondoKit.components.*
|
import KondoKit.components.*
|
||||||
import KondoKit.components.SearchField
|
import KondoKit.ViewConstants
|
||||||
|
import KondoKit.views.ViewLayoutHelpers.createSearchFieldSection
|
||||||
import KondoKit.pluginmanager.GitLabPlugin
|
import KondoKit.pluginmanager.GitLabPlugin
|
||||||
import KondoKit.pluginmanager.GitLabPluginFetcher
|
import KondoKit.pluginmanager.GitLabPluginFetcher
|
||||||
import KondoKit.pluginmanager.PluginDownloadManager
|
import KondoKit.pluginmanager.PluginDownloadManager
|
||||||
|
|
@ -22,11 +23,8 @@ import rt4.GlobalJsonConfig
|
||||||
import java.awt.*
|
import java.awt.*
|
||||||
import java.awt.event.MouseAdapter
|
import java.awt.event.MouseAdapter
|
||||||
import java.awt.event.MouseEvent
|
import java.awt.event.MouseEvent
|
||||||
import java.awt.image.BufferedImage
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
|
||||||
import javax.imageio.ImageIO
|
|
||||||
import javax.swing.*
|
import javax.swing.*
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
|
|
||||||
|
|
@ -49,8 +47,6 @@ object ReflectiveEditorView : View {
|
||||||
|
|
||||||
private var pluginStatuses: List<PluginInfoWithStatus> = listOf()
|
private var pluginStatuses: List<PluginInfoWithStatus> = listOf()
|
||||||
|
|
||||||
private var cogIcon: Icon? = null
|
|
||||||
|
|
||||||
private var searchField: SearchField? = null
|
private var searchField: SearchField? = null
|
||||||
|
|
||||||
// Flag for scheduled plugin reload to avoid crashes
|
// Flag for scheduled plugin reload to avoid crashes
|
||||||
|
|
@ -61,19 +57,6 @@ object ReflectiveEditorView : View {
|
||||||
return pluginName == "KondoKit"
|
return pluginName == "KondoKit"
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadCogIcon() {
|
|
||||||
try {
|
|
||||||
val imageStream = this::class.java.getResourceAsStream("res/cog.png")
|
|
||||||
if (imageStream != null) {
|
|
||||||
val image: BufferedImage = ImageIO.read(imageStream)
|
|
||||||
val scaledImage = image.getScaledInstance(12, 12, Image.SCALE_SMOOTH)
|
|
||||||
cogIcon = ImageIcon(scaledImage)
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Card layout for switching between views within the reflective editor view
|
// Card layout for switching between views within the reflective editor view
|
||||||
private lateinit var cardLayout: CardLayout
|
private lateinit var cardLayout: CardLayout
|
||||||
private lateinit var mainPanel: JPanel
|
private lateinit var mainPanel: JPanel
|
||||||
|
|
@ -99,8 +82,6 @@ object ReflectiveEditorView : View {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createReflectiveEditorView() {
|
fun createReflectiveEditorView() {
|
||||||
loadCogIcon()
|
|
||||||
|
|
||||||
cardLayout = CardLayout()
|
cardLayout = CardLayout()
|
||||||
mainPanel = JPanel(cardLayout)
|
mainPanel = JPanel(cardLayout)
|
||||||
mainPanel.background = VIEW_BACKGROUND_COLOR
|
mainPanel.background = VIEW_BACKGROUND_COLOR
|
||||||
|
|
@ -122,7 +103,6 @@ object ReflectiveEditorView : View {
|
||||||
cardLayout.show(mainPanel, PLUGIN_LIST_VIEW)
|
cardLayout.show(mainPanel, PLUGIN_LIST_VIEW)
|
||||||
|
|
||||||
GitLabPluginFetcher.fetchGitLabPlugins { plugins ->
|
GitLabPluginFetcher.fetchGitLabPlugins { plugins ->
|
||||||
System.out.println("GitLab plugins fetched: ${plugins.size}")
|
|
||||||
gitLabPlugins = plugins
|
gitLabPlugins = plugins
|
||||||
// Update plugin statuses with comparison between installed and remote plugins
|
// Update plugin statuses with comparison between installed and remote plugins
|
||||||
updatePluginStatuses()
|
updatePluginStatuses()
|
||||||
|
|
@ -131,41 +111,26 @@ object ReflectiveEditorView : View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createPluginListView(): JPanel {
|
private fun createPluginListView(): JPanel {
|
||||||
val panel = JPanel()
|
val panel = BaseView(PLUGIN_LIST_VIEW, addDefaultSpacing = false).apply {
|
||||||
panel.layout = BoxLayout(panel, BoxLayout.Y_AXIS)
|
|
||||||
panel.background = VIEW_BACKGROUND_COLOR
|
|
||||||
|
|
||||||
val searchField = SearchField(
|
|
||||||
parentPanel = panel,
|
|
||||||
onSearch = { searchText ->
|
|
||||||
pluginSearchText = searchText
|
|
||||||
SwingUtilities.invokeLater {
|
|
||||||
addPlugins(reflectiveEditorView!!)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
placeholderText = "Search plugins...",
|
|
||||||
fieldWidth = 230,
|
|
||||||
fieldHeight = 30,
|
|
||||||
viewName = "REFLECTIVE_EDITOR_VIEW"
|
|
||||||
)
|
|
||||||
this.searchField = searchField
|
|
||||||
if (pluginSearchText.isNotBlank()) {
|
|
||||||
searchField.setText(pluginSearchText)
|
|
||||||
}
|
|
||||||
|
|
||||||
val searchFieldWrapperPanel = JPanel().apply {
|
|
||||||
layout = BoxLayout(this, BoxLayout.X_AXIS)
|
|
||||||
background = VIEW_BACKGROUND_COLOR
|
background = VIEW_BACKGROUND_COLOR
|
||||||
preferredSize = Dimension(230, 30)
|
|
||||||
maximumSize = preferredSize
|
|
||||||
minimumSize = preferredSize
|
|
||||||
alignmentX = Component.CENTER_ALIGNMENT
|
|
||||||
add(searchField)
|
|
||||||
}
|
}
|
||||||
searchFieldWrapper = searchFieldWrapperPanel
|
|
||||||
|
val searchSection = createSearchFieldSection(
|
||||||
|
parent = panel,
|
||||||
|
placeholderText = "Search plugins...",
|
||||||
|
viewName = VIEW_NAME,
|
||||||
|
initialText = pluginSearchText
|
||||||
|
) { searchText ->
|
||||||
|
pluginSearchText = searchText
|
||||||
|
SwingUtilities.invokeLater {
|
||||||
|
addPlugins(reflectiveEditorView!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.searchField = searchSection.searchField
|
||||||
|
searchFieldWrapper = searchSection.wrapper
|
||||||
|
|
||||||
panel.add(Box.createVerticalStrut(10))
|
panel.add(Box.createVerticalStrut(10))
|
||||||
panel.add(searchFieldWrapperPanel)
|
panel.add(searchSection.wrapper)
|
||||||
panel.add(Box.createVerticalStrut(10))
|
panel.add(Box.createVerticalStrut(10))
|
||||||
|
|
||||||
pluginListContentPanel = JPanel().apply {
|
pluginListContentPanel = JPanel().apply {
|
||||||
|
|
@ -276,59 +241,34 @@ object ReflectiveEditorView : View {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pluginSearchText.isNotBlank()) {
|
if (pluginSearchText.isNotBlank()) {
|
||||||
System.out.println("Filtering plugins for search term: '$pluginSearchText'")
|
|
||||||
System.out.println("Total plugin statuses: ${pluginStatuses.size}")
|
|
||||||
|
|
||||||
val matchingPluginStatuses = pluginStatuses.filter { pluginStatus ->
|
val matchingPluginStatuses = pluginStatuses.filter { pluginStatus ->
|
||||||
// Only show plugins that are not currently loaded and not KondoKit
|
!pluginStatus.isInstalled &&
|
||||||
val shouldShow = !pluginStatus.isInstalled &&
|
|
||||||
!isKondoKit(pluginStatus.name) &&
|
!isKondoKit(pluginStatus.name) &&
|
||||||
(pluginStatus.name.contains(pluginSearchText, ignoreCase = true) ||
|
(pluginStatus.name.contains(pluginSearchText, ignoreCase = true) ||
|
||||||
(pluginStatus.description?.contains(pluginSearchText, ignoreCase = true) ?: false))
|
(pluginStatus.description?.contains(pluginSearchText, ignoreCase = true) ?: false))
|
||||||
|
|
||||||
System.out.println("Plugin: ${pluginStatus.name}, isInstalled: ${pluginStatus.isInstalled}, shouldShow: $shouldShow")
|
|
||||||
shouldShow
|
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Matching plugin statuses: ${matchingPluginStatuses.size}")
|
|
||||||
|
|
||||||
// Add a separator
|
|
||||||
val separator = JPanel()
|
|
||||||
separator.background = VIEW_BACKGROUND_COLOR
|
|
||||||
separator.preferredSize = Dimension(Int.MAX_VALUE, 1)
|
|
||||||
separator.maximumSize = Dimension(Int.MAX_VALUE, 1)
|
|
||||||
contentPanel.add(Box.createVerticalStrut(10))
|
|
||||||
contentPanel.add(separator)
|
|
||||||
contentPanel.add(Box.createVerticalStrut(5))
|
|
||||||
|
|
||||||
val headerPanel = JPanel(FlowLayout(FlowLayout.LEFT))
|
|
||||||
headerPanel.background = VIEW_BACKGROUND_COLOR
|
|
||||||
val headerLabel = JLabel(if (matchingPluginStatuses.isNotEmpty()) "Available Plugins" else "")
|
|
||||||
headerLabel.foreground = secondaryColor
|
|
||||||
headerLabel.font = Font("RuneScape Small", Font.BOLD, 16)
|
|
||||||
headerPanel.add(headerLabel)
|
|
||||||
contentPanel.add(headerPanel)
|
|
||||||
contentPanel.add(Box.createVerticalStrut(5))
|
|
||||||
|
|
||||||
if (matchingPluginStatuses.isNotEmpty()) {
|
if (matchingPluginStatuses.isNotEmpty()) {
|
||||||
if (matchingPluginStatuses.size > 1) {
|
val separator = JPanel().apply {
|
||||||
val downloadAllPanel = JPanel(FlowLayout(FlowLayout.LEFT))
|
background = VIEW_BACKGROUND_COLOR
|
||||||
downloadAllPanel.background = VIEW_BACKGROUND_COLOR
|
preferredSize = Dimension(Int.MAX_VALUE, 1)
|
||||||
val downloadAllButton = JButton("Download All")
|
maximumSize = preferredSize
|
||||||
downloadAllButton.background = TITLE_BAR_COLOR
|
|
||||||
downloadAllButton.foreground = secondaryColor
|
|
||||||
downloadAllButton.font = Font("RuneScape Small", Font.PLAIN, 14)
|
|
||||||
downloadAllButton.addActionListener {
|
|
||||||
startMultiplePluginDownloads(matchingPluginStatuses)
|
|
||||||
}
|
|
||||||
downloadAllPanel.add(downloadAllButton)
|
|
||||||
contentPanel.add(downloadAllPanel)
|
|
||||||
contentPanel.add(Box.createVerticalStrut(5))
|
|
||||||
}
|
}
|
||||||
|
contentPanel.add(Box.createVerticalStrut(10))
|
||||||
|
contentPanel.add(separator)
|
||||||
|
contentPanel.add(Box.createVerticalStrut(5))
|
||||||
|
|
||||||
// Add matching plugin statuses
|
val headerPanel = JPanel(FlowLayout(FlowLayout.LEFT)).apply {
|
||||||
for (pluginStatus in matchingPluginStatuses) {
|
background = VIEW_BACKGROUND_COLOR
|
||||||
System.out.println("Adding plugin to UI: ${pluginStatus.name}")
|
add(JLabel("Available Plugins").apply {
|
||||||
|
foreground = secondaryColor
|
||||||
|
font = ViewConstants.FONT_RUNESCAPE_SMALL_BOLD_16
|
||||||
|
})
|
||||||
|
}
|
||||||
|
contentPanel.add(headerPanel)
|
||||||
|
contentPanel.add(Box.createVerticalStrut(5))
|
||||||
|
|
||||||
|
matchingPluginStatuses.forEach { pluginStatus ->
|
||||||
val pluginPanel = createPluginStatusItemPanel(pluginStatus)
|
val pluginPanel = createPluginStatusItemPanel(pluginStatus)
|
||||||
contentPanel.add(pluginPanel)
|
contentPanel.add(pluginPanel)
|
||||||
contentPanel.add(Box.createVerticalStrut(5))
|
contentPanel.add(Box.createVerticalStrut(5))
|
||||||
|
|
@ -342,16 +282,19 @@ object ReflectiveEditorView : View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createPluginItemPanel(pluginInfo: PluginInfo, plugin: Plugin): JPanel {
|
private fun createPluginItemPanel(pluginInfo: PluginInfo, plugin: Plugin): JPanel {
|
||||||
val panel = JPanel(BorderLayout())
|
val panel = WidgetPanel(
|
||||||
panel.background = WIDGET_COLOR
|
widgetWidth = ViewConstants.PLUGIN_LIST_ITEM_SIZE.width,
|
||||||
panel.border = BorderFactory.createEmptyBorder(10, 10, 10, 10)
|
widgetHeight = ViewConstants.PLUGIN_LIST_ITEM_SIZE.height,
|
||||||
panel.maximumSize = Dimension(220, 60)
|
addDefaultPadding = false
|
||||||
|
).apply {
|
||||||
|
layout = BorderLayout()
|
||||||
|
}
|
||||||
|
|
||||||
// Plugin name and version (using package name as in original implementation)
|
// Plugin name and version (using package name as in original implementation)
|
||||||
val packageName = plugin.javaClass.`package`.name
|
val packageName = plugin.javaClass.`package`.name
|
||||||
val nameLabel = JLabel(packageName)
|
val nameLabel = JLabel(packageName)
|
||||||
nameLabel.foreground = secondaryColor
|
nameLabel.foreground = secondaryColor
|
||||||
nameLabel.font = Font("RuneScape Small", Font.PLAIN, 16)
|
nameLabel.font = ViewConstants.FONT_RUNESCAPE_SMALL_PLAIN_16
|
||||||
|
|
||||||
// Check if plugin has exposed attributes
|
// Check if plugin has exposed attributes
|
||||||
val exposedFields = plugin.javaClass.declaredFields.filter { field ->
|
val exposedFields = plugin.javaClass.declaredFields.filter { field ->
|
||||||
|
|
@ -362,15 +305,10 @@ object ReflectiveEditorView : View {
|
||||||
|
|
||||||
// Edit button (only show if plugin has exposed attributes)
|
// Edit button (only show if plugin has exposed attributes)
|
||||||
val editButton = if (exposedFields.isNotEmpty()) {
|
val editButton = if (exposedFields.isNotEmpty()) {
|
||||||
val button = JButton()
|
val button = JButton("Edit")
|
||||||
if (cogIcon != null) {
|
|
||||||
button.icon = cogIcon
|
|
||||||
} else {
|
|
||||||
button.text = "Edit"
|
|
||||||
}
|
|
||||||
button.background = TITLE_BAR_COLOR
|
button.background = TITLE_BAR_COLOR
|
||||||
button.foreground = secondaryColor
|
button.foreground = secondaryColor
|
||||||
button.font = Font("RuneScape Small", Font.PLAIN, 14)
|
button.font = ViewConstants.FONT_RUNESCAPE_SMALL_14
|
||||||
button.addActionListener {
|
button.addActionListener {
|
||||||
showPluginDetails(pluginInfo, plugin)
|
showPluginDetails(pluginInfo, plugin)
|
||||||
}
|
}
|
||||||
|
|
@ -386,8 +324,8 @@ object ReflectiveEditorView : View {
|
||||||
// Create a placeholder component that takes the same space but is invisible
|
// Create a placeholder component that takes the same space but is invisible
|
||||||
val placeholder = JPanel()
|
val placeholder = JPanel()
|
||||||
placeholder.background = WIDGET_COLOR
|
placeholder.background = WIDGET_COLOR
|
||||||
placeholder.preferredSize = Dimension(60, 24) // Same size as toggle switch
|
placeholder.preferredSize = ViewConstants.TOGGLE_PLACEHOLDER_SIZE
|
||||||
placeholder.maximumSize = Dimension(60, 24)
|
placeholder.maximumSize = ViewConstants.TOGGLE_PLACEHOLDER_SIZE
|
||||||
placeholder.isVisible = false
|
placeholder.isVisible = false
|
||||||
placeholder
|
placeholder
|
||||||
}
|
}
|
||||||
|
|
@ -417,15 +355,18 @@ object ReflectiveEditorView : View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createDisabledPluginItemPanel(pluginName: String): JPanel {
|
private fun createDisabledPluginItemPanel(pluginName: String): JPanel {
|
||||||
val panel = JPanel(BorderLayout())
|
val panel = WidgetPanel(
|
||||||
panel.background = WIDGET_COLOR
|
widgetWidth = ViewConstants.PLUGIN_LIST_ITEM_SIZE.width,
|
||||||
panel.border = BorderFactory.createEmptyBorder(10, 10, 10, 10)
|
widgetHeight = ViewConstants.PLUGIN_LIST_ITEM_SIZE.height,
|
||||||
panel.maximumSize = Dimension(220, 60)
|
addDefaultPadding = false
|
||||||
|
).apply {
|
||||||
|
layout = BorderLayout()
|
||||||
|
}
|
||||||
|
|
||||||
// Plugin name
|
// Plugin name
|
||||||
val nameLabel = JLabel(pluginName)
|
val nameLabel = JLabel(pluginName)
|
||||||
nameLabel.foreground = secondaryColor
|
nameLabel.foreground = secondaryColor
|
||||||
nameLabel.font = Font("RuneScape Small", Font.PLAIN, 16)
|
nameLabel.font = ViewConstants.FONT_RUNESCAPE_SMALL_PLAIN_16
|
||||||
|
|
||||||
// Plugin toggle switch (iOS style) - initially off for disabled plugins
|
// Plugin toggle switch (iOS style) - initially off for disabled plugins
|
||||||
val toggleSwitch = ToggleSwitch()
|
val toggleSwitch = ToggleSwitch()
|
||||||
|
|
@ -462,21 +403,24 @@ object ReflectiveEditorView : View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createPluginStatusItemPanel(pluginStatus: PluginInfoWithStatus): JPanel {
|
private fun createPluginStatusItemPanel(pluginStatus: PluginInfoWithStatus): JPanel {
|
||||||
val panel = JPanel(BorderLayout())
|
val panel = WidgetPanel(
|
||||||
panel.background = WIDGET_COLOR
|
widgetWidth = ViewConstants.PLUGIN_LIST_ITEM_SIZE.width,
|
||||||
panel.border = BorderFactory.createEmptyBorder(10, 10, 10, 10)
|
widgetHeight = ViewConstants.PLUGIN_LIST_ITEM_SIZE.height,
|
||||||
panel.maximumSize = Dimension(220, 60)
|
addDefaultPadding = false
|
||||||
|
).apply {
|
||||||
|
layout = BorderLayout()
|
||||||
|
}
|
||||||
|
|
||||||
// Plugin name
|
// Plugin name
|
||||||
val nameLabel = JLabel(pluginStatus.name)
|
val nameLabel = JLabel(pluginStatus.name)
|
||||||
nameLabel.foreground = secondaryColor
|
nameLabel.foreground = secondaryColor
|
||||||
nameLabel.font = Font("RuneScape Small", Font.PLAIN, 16)
|
nameLabel.font = ViewConstants.FONT_RUNESCAPE_SMALL_PLAIN_16
|
||||||
|
|
||||||
// Action button based on plugin status
|
// Action button based on plugin status
|
||||||
val actionButton = JButton()
|
val actionButton = JButton()
|
||||||
actionButton.background = TITLE_BAR_COLOR
|
actionButton.background = TITLE_BAR_COLOR
|
||||||
actionButton.foreground = secondaryColor
|
actionButton.foreground = secondaryColor
|
||||||
actionButton.font = Font("RuneScape Small", Font.PLAIN, 14)
|
actionButton.font = ViewConstants.FONT_RUNESCAPE_SMALL_14
|
||||||
|
|
||||||
// Progress bar for downloads
|
// Progress bar for downloads
|
||||||
val progressBar = JProgressBar(0, 100)
|
val progressBar = JProgressBar(0, 100)
|
||||||
|
|
@ -543,6 +487,17 @@ object ReflectiveEditorView : View {
|
||||||
controlsPanel.add(toggleSwitch)
|
controlsPanel.add(toggleSwitch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!pluginStatus.isInstalled) {
|
||||||
|
val tooltipText = buildInstallableTooltip(pluginStatus)
|
||||||
|
panel.toolTipText = tooltipText
|
||||||
|
actionButton.toolTipText = tooltipText
|
||||||
|
progressBar.toolTipText = tooltipText
|
||||||
|
} else {
|
||||||
|
panel.toolTipText = null
|
||||||
|
actionButton.toolTipText = null
|
||||||
|
progressBar.toolTipText = null
|
||||||
|
}
|
||||||
|
|
||||||
panel.add(infoPanel, BorderLayout.CENTER)
|
panel.add(infoPanel, BorderLayout.CENTER)
|
||||||
panel.add(controlsPanel, BorderLayout.EAST)
|
panel.add(controlsPanel, BorderLayout.EAST)
|
||||||
|
|
||||||
|
|
@ -554,6 +509,32 @@ object ReflectiveEditorView : View {
|
||||||
return panel
|
return panel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun buildInstallableTooltip(pluginStatus: PluginInfoWithStatus): String {
|
||||||
|
val lines = mutableListOf<String>()
|
||||||
|
pluginStatus.remoteVersion?.takeIf { it.isNotBlank() }?.let {
|
||||||
|
lines += "<b>Version:</b> ${escapeHtml(it)}"
|
||||||
|
}
|
||||||
|
pluginStatus.author?.takeIf { it.isNotBlank() }?.let {
|
||||||
|
lines += "<b>Author:</b> ${escapeHtml(it)}"
|
||||||
|
}
|
||||||
|
pluginStatus.description?.takeIf { it.isNotBlank() }?.let {
|
||||||
|
lines += escapeHtml(it).replace("\n", "<br>")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lines.isEmpty()) {
|
||||||
|
lines += "Click Download to install this plugin."
|
||||||
|
}
|
||||||
|
|
||||||
|
return "<html>${lines.joinToString("<br>")}</html>"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun escapeHtml(value: String): String {
|
||||||
|
return value
|
||||||
|
.replace("&", "&")
|
||||||
|
.replace("<", "<")
|
||||||
|
.replace(">", ">")
|
||||||
|
}
|
||||||
|
|
||||||
private fun enablePlugin(pluginName: String) {
|
private fun enablePlugin(pluginName: String) {
|
||||||
try {
|
try {
|
||||||
// Source and destination directories
|
// Source and destination directories
|
||||||
|
|
@ -733,13 +714,13 @@ object ReflectiveEditorView : View {
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
|
|
||||||
|
val infoFont = ViewConstants.FONT_RUNESCAPE_SMALL_14
|
||||||
val infoLabel = LabelComponent(infoText, isHtml = true).apply {
|
val infoLabel = LabelComponent(infoText, isHtml = true).apply {
|
||||||
font = Font("RuneScape Small", Font.PLAIN, 14)
|
font = infoFont
|
||||||
}
|
}
|
||||||
infoPanel.add(infoLabel, BorderLayout.CENTER)
|
infoPanel.add(infoLabel, BorderLayout.CENTER)
|
||||||
|
|
||||||
val font = Font("RuneScape Small", Font.PLAIN, 14)
|
val fm = infoLabel.getFontMetrics(infoFont)
|
||||||
val fm = infoLabel.getFontMetrics(font)
|
|
||||||
|
|
||||||
val avgCharWidth = fm.stringWidth("x")
|
val avgCharWidth = fm.stringWidth("x")
|
||||||
val availableWidth = 200
|
val availableWidth = 200
|
||||||
|
|
@ -759,7 +740,7 @@ object ReflectiveEditorView : View {
|
||||||
|
|
||||||
val finalHeight = kotlin.math.max(60, kotlin.math.min(estimatedHeight, 150))
|
val finalHeight = kotlin.math.max(60, kotlin.math.min(estimatedHeight, 150))
|
||||||
infoPanel.maximumSize = Dimension(Int.MAX_VALUE, finalHeight)
|
infoPanel.maximumSize = Dimension(Int.MAX_VALUE, finalHeight)
|
||||||
infoPanel.preferredSize = Dimension(220, finalHeight)
|
infoPanel.preferredSize = Dimension(ViewConstants.DEFAULT_WIDGET_SIZE.width, finalHeight)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -798,7 +779,6 @@ object ReflectiveEditorView : View {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addPlugins(reflectiveEditorView: JPanel) {
|
fun addPlugins(reflectiveEditorView: JPanel) {
|
||||||
System.out.println("addPlugins called")
|
|
||||||
// Ensure we run on the EDT; if not, reschedule and return
|
// Ensure we run on the EDT; if not, reschedule and return
|
||||||
if (!SwingUtilities.isEventDispatchThread()) {
|
if (!SwingUtilities.isEventDispatchThread()) {
|
||||||
SwingUtilities.invokeLater { addPlugins(reflectiveEditorView) }
|
SwingUtilities.invokeLater { addPlugins(reflectiveEditorView) }
|
||||||
|
|
@ -850,14 +830,14 @@ object ReflectiveEditorView : View {
|
||||||
var customToolTipWindow: JWindow? = null
|
var customToolTipWindow: JWindow? = null
|
||||||
|
|
||||||
fun showCustomToolTip(text: String, component: JComponent) {
|
fun showCustomToolTip(text: String, component: JComponent) {
|
||||||
val _font = Font("RuneScape Small", Font.PLAIN, 16)
|
val tooltipFont = ViewConstants.FONT_RUNESCAPE_SMALL_PLAIN_16
|
||||||
val maxWidth = 150
|
val maxWidth = 150
|
||||||
val lineHeight = 16
|
|
||||||
|
|
||||||
// Create a dummy JLabel to get FontMetrics for the font used in the tooltip
|
// Create a dummy JLabel to get FontMetrics for the font used in the tooltip
|
||||||
val dummyLabel = JLabel()
|
val dummyLabel = JLabel()
|
||||||
dummyLabel.font = _font
|
dummyLabel.font = tooltipFont
|
||||||
val fontMetrics = dummyLabel.getFontMetrics(_font)
|
val fontMetrics = dummyLabel.getFontMetrics(tooltipFont)
|
||||||
|
val lineHeight = fontMetrics.height
|
||||||
|
|
||||||
// Calculate the approximate width of the text
|
// Calculate the approximate width of the text
|
||||||
val textWidth = fontMetrics.stringWidth(text)
|
val textWidth = fontMetrics.stringWidth(text)
|
||||||
|
|
@ -877,7 +857,7 @@ object ReflectiveEditorView : View {
|
||||||
isOpaque = true
|
isOpaque = true
|
||||||
background = TOOLTIP_BACKGROUND
|
background = TOOLTIP_BACKGROUND
|
||||||
foreground = Color.WHITE
|
foreground = Color.WHITE
|
||||||
font = _font
|
font = tooltipFont
|
||||||
maximumSize = Dimension(maxWidth, Int.MAX_VALUE)
|
maximumSize = Dimension(maxWidth, Int.MAX_VALUE)
|
||||||
preferredSize = Dimension(maxWidth, requiredHeight)
|
preferredSize = Dimension(maxWidth, requiredHeight)
|
||||||
}
|
}
|
||||||
|
|
@ -911,7 +891,6 @@ object ReflectiveEditorView : View {
|
||||||
return parsePluginProperties(content)
|
return parsePluginProperties(content)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
System.out.println("Error reading properties for disabled plugin $pluginName: ${e.message}")
|
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
@ -967,18 +946,15 @@ object ReflectiveEditorView : View {
|
||||||
loadedPluginsField.isAccessible = true
|
loadedPluginsField.isAccessible = true
|
||||||
val loadedPlugins = loadedPluginsField.get(null) as HashMap<*, *>
|
val loadedPlugins = loadedPluginsField.get(null) as HashMap<*, *>
|
||||||
|
|
||||||
System.out.println("Found ${loadedPlugins.size} loaded plugins")
|
|
||||||
|
|
||||||
for ((_, plugin) in loadedPlugins) {
|
for ((_, plugin) in loadedPlugins) {
|
||||||
val pluginName = getPluginDirName(plugin as Plugin)
|
val pluginName = getPluginDirName(plugin as Plugin)
|
||||||
loadedPluginNames.add(pluginName)
|
loadedPluginNames.add(pluginName)
|
||||||
//System.out.println("Loaded plugin: $pluginName")
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Returning loaded plugin names: ${loadedPluginNames.joinToString(", ")}")
|
|
||||||
return loadedPluginNames
|
return loadedPluginNames
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -992,7 +968,6 @@ object ReflectiveEditorView : View {
|
||||||
|
|
||||||
// Log the download URL for debugging
|
// Log the download URL for debugging
|
||||||
val downloadUrl = PluginDownloadManager.getDownloadUrlForLogging(gitLabPlugin)
|
val downloadUrl = PluginDownloadManager.getDownloadUrlForLogging(gitLabPlugin)
|
||||||
System.out.println("Download URL for plugin ${gitLabPlugin.path}: $downloadUrl")
|
|
||||||
|
|
||||||
// Update plugin status to show downloading
|
// Update plugin status to show downloading
|
||||||
val updatedStatuses = pluginStatuses.map {
|
val updatedStatuses = pluginStatuses.map {
|
||||||
|
|
@ -1056,80 +1031,11 @@ object ReflectiveEditorView : View {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method to start downloading multiple plugins
|
|
||||||
private fun startMultiplePluginDownloads(pluginStatuses: List<PluginInfoWithStatus>) {
|
|
||||||
val gitLabPlugins = pluginStatuses.mapNotNull { it.gitLabPlugin }
|
|
||||||
|
|
||||||
if (gitLabPlugins.isEmpty()) {
|
|
||||||
showToast(mainPanel, "No valid plugins to download", JOptionPane.ERROR_MESSAGE)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update all plugin statuses to show downloading
|
|
||||||
val pluginNames = pluginStatuses.map { it.name }.toSet()
|
|
||||||
val updatedStatuses = pluginStatuses.map {
|
|
||||||
if (pluginNames.contains(it.name)) {
|
|
||||||
it.copy(isDownloading = true, downloadProgress = 0)
|
|
||||||
} else {
|
|
||||||
it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.pluginStatuses = updatedStatuses
|
|
||||||
|
|
||||||
// Refresh UI to show progress bars
|
|
||||||
SwingUtilities.invokeLater {
|
|
||||||
addPlugins(reflectiveEditorView!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Counter to track completed downloads
|
|
||||||
val completedCount = AtomicInteger(0)
|
|
||||||
val totalCount = gitLabPlugins.size
|
|
||||||
val failedPlugins = mutableListOf<String>()
|
|
||||||
|
|
||||||
// Start the downloads
|
|
||||||
PluginDownloadManager.downloadPlugins(gitLabPlugins) { pluginName, success, errorMessage ->
|
|
||||||
// Update progress in plugin statuses
|
|
||||||
val updatedStatuses = this.pluginStatuses.map {
|
|
||||||
if (it.name == pluginName) {
|
|
||||||
it.copy(isDownloading = false, downloadProgress = if (success) 100 else 0)
|
|
||||||
} else {
|
|
||||||
it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.pluginStatuses = updatedStatuses
|
|
||||||
|
|
||||||
// Track completion
|
|
||||||
if (!success) {
|
|
||||||
failedPlugins.add(pluginName)
|
|
||||||
}
|
|
||||||
|
|
||||||
val completed = completedCount.incrementAndGet()
|
|
||||||
|
|
||||||
// If all downloads are complete, show final message
|
|
||||||
if (completed == totalCount) {
|
|
||||||
SwingUtilities.invokeLater {
|
|
||||||
if (failedPlugins.isEmpty()) {
|
|
||||||
showToast(mainPanel, "All plugins downloaded successfully!", JOptionPane.INFORMATION_MESSAGE)
|
|
||||||
// Reload plugins to make the newly downloaded plugins available
|
|
||||||
PluginRepository.reloadPlugins()
|
|
||||||
} else {
|
|
||||||
val failedList = failedPlugins.joinToString(", ")
|
|
||||||
showToast(mainPanel, "Completed with errors. Failed plugins: $failedList", JOptionPane.WARNING_MESSAGE)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Refresh UI
|
|
||||||
addPlugins(reflectiveEditorView!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update plugin statuses by comparing installed and remote plugins
|
// Update plugin statuses by comparing installed and remote plugins
|
||||||
private fun updatePluginStatuses() {
|
private fun updatePluginStatuses() {
|
||||||
val loadedPluginNames = getLoadedPluginNames()
|
val loadedPluginNames = getLoadedPluginNames()
|
||||||
val statuses = mutableListOf<PluginInfoWithStatus>()
|
val statuses = mutableListOf<PluginInfoWithStatus>()
|
||||||
|
|
||||||
System.out.println("Updating plugin statuses. Loaded plugins: ${loadedPluginNames.joinToString(", ")}")
|
|
||||||
|
|
||||||
// Get disabled plugin names and their versions
|
// Get disabled plugin names and their versions
|
||||||
val disabledPluginInfo = getDisabledPluginInfo()
|
val disabledPluginInfo = getDisabledPluginInfo()
|
||||||
|
|
@ -1152,7 +1058,6 @@ object ReflectiveEditorView : View {
|
||||||
val isDisabled = disabledPluginInfo.containsKey(pluginName)
|
val isDisabled = disabledPluginInfo.containsKey(pluginName)
|
||||||
val disabledVersion = disabledPluginInfo[pluginName]
|
val disabledVersion = disabledPluginInfo[pluginName]
|
||||||
|
|
||||||
//System.out.println("Processing plugin: $pluginName, isLoaded: $isLoaded, isDisabled: $isDisabled, disabledVersion: $disabledVersion")
|
|
||||||
|
|
||||||
// Check if this plugin is currently being downloaded
|
// Check if this plugin is currently being downloaded
|
||||||
val existingStatus = pluginStatuses.find { it.name == pluginName }
|
val existingStatus = pluginStatuses.find { it.name == pluginName }
|
||||||
|
|
@ -1209,7 +1114,6 @@ object ReflectiveEditorView : View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Updated plugin statuses. Total statuses: ${statuses.size}")
|
|
||||||
pluginStatuses = statuses
|
pluginStatuses = statuses
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1218,20 +1122,16 @@ object ReflectiveEditorView : View {
|
||||||
var needsReload = false
|
var needsReload = false
|
||||||
for (pluginName in loadedPluginNames) {
|
for (pluginName in loadedPluginNames) {
|
||||||
if (disabledPluginInfo.containsKey(pluginName)) {
|
if (disabledPluginInfo.containsKey(pluginName)) {
|
||||||
System.out.println("Found duplicate plugin: $pluginName. Deleting disabled version.")
|
|
||||||
try {
|
try {
|
||||||
val disabledDir = File(pluginsDirectory, "disabled")
|
val disabledDir = File(pluginsDirectory, "disabled")
|
||||||
val pluginDir = File(disabledDir, pluginName)
|
val pluginDir = File(disabledDir, pluginName)
|
||||||
if (pluginDir.exists() && pluginDir.isDirectory) {
|
if (pluginDir.exists() && pluginDir.isDirectory) {
|
||||||
if (deleteRecursively(pluginDir)) {
|
if (deleteRecursively(pluginDir)) {
|
||||||
System.out.println("Successfully deleted disabled version of $pluginName")
|
|
||||||
needsReload = true
|
needsReload = true
|
||||||
} else {
|
} else {
|
||||||
System.out.println("Failed to delete disabled version of $pluginName")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
System.out.println("Error deleting disabled version of $pluginName: ${e.message}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1257,10 +1157,8 @@ object ReflectiveEditorView : View {
|
||||||
val content = propertiesFile.readText()
|
val content = propertiesFile.readText()
|
||||||
val properties = parsePluginProperties(content)
|
val properties = parsePluginProperties(content)
|
||||||
disabledPluginInfo[pluginDir.name] = properties.version
|
disabledPluginInfo[pluginDir.name] = properties.version
|
||||||
System.out.println("Found disabled plugin: ${pluginDir.name}, version: ${properties.version}")
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
System.out.println("Error reading properties for disabled plugin ${pluginDir.name}: ${e.message}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
package KondoKit.views
|
||||||
|
|
||||||
|
import KondoKit.ViewConstants
|
||||||
|
import KondoKit.components.SearchField
|
||||||
|
import KondoKit.components.WidgetPanel
|
||||||
|
import KondoKit.plugin.Companion.VIEW_BACKGROUND_COLOR
|
||||||
|
import java.awt.Color
|
||||||
|
import java.awt.Component
|
||||||
|
import java.awt.Container
|
||||||
|
import java.awt.Dimension
|
||||||
|
import javax.swing.Box
|
||||||
|
import javax.swing.BoxLayout
|
||||||
|
import javax.swing.JPanel
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility helpers shared across view implementations to avoid duplicating
|
||||||
|
* common UI wiring such as search rows and vertical panel setup.
|
||||||
|
*/
|
||||||
|
object ViewLayoutHelpers {
|
||||||
|
|
||||||
|
data class SearchFieldSection(
|
||||||
|
val wrapper: JPanel,
|
||||||
|
val searchField: SearchField
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a standard search field row with consistent sizing and styling.
|
||||||
|
*/
|
||||||
|
fun createSearchFieldSection(
|
||||||
|
parent: JPanel,
|
||||||
|
placeholderText: String,
|
||||||
|
viewName: String,
|
||||||
|
initialText: String = "",
|
||||||
|
fieldWidth: Int = ViewConstants.SEARCH_FIELD_SIZE.width,
|
||||||
|
fieldHeight: Int = ViewConstants.SEARCH_FIELD_SIZE.height,
|
||||||
|
onSearch: (String) -> Unit
|
||||||
|
): SearchFieldSection {
|
||||||
|
val searchField = SearchField(
|
||||||
|
parentPanel = parent,
|
||||||
|
onSearch = onSearch,
|
||||||
|
placeholderText = placeholderText,
|
||||||
|
fieldWidth = fieldWidth,
|
||||||
|
fieldHeight = fieldHeight,
|
||||||
|
viewName = viewName
|
||||||
|
)
|
||||||
|
|
||||||
|
if (initialText.isNotBlank()) {
|
||||||
|
searchField.setText(initialText)
|
||||||
|
}
|
||||||
|
|
||||||
|
val preferredSize = Dimension(fieldWidth, fieldHeight)
|
||||||
|
val wrapper = WidgetPanel(
|
||||||
|
widgetWidth = preferredSize.width,
|
||||||
|
widgetHeight = preferredSize.height,
|
||||||
|
addDefaultPadding = false
|
||||||
|
).apply {
|
||||||
|
layout = BoxLayout(this, BoxLayout.X_AXIS)
|
||||||
|
background = VIEW_BACKGROUND_COLOR
|
||||||
|
alignmentX = Component.CENTER_ALIGNMENT
|
||||||
|
add(searchField)
|
||||||
|
}
|
||||||
|
|
||||||
|
return SearchFieldSection(wrapper = wrapper, searchField = searchField)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a BoxLayout.Y_AXIS panel with the default view background.
|
||||||
|
*/
|
||||||
|
fun createVerticalPanel(background: Color = VIEW_BACKGROUND_COLOR): JPanel {
|
||||||
|
return JPanel().apply {
|
||||||
|
layout = BoxLayout(this, BoxLayout.Y_AXIS)
|
||||||
|
this.background = background
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ import KondoKit.Helpers.formatNumber
|
||||||
import KondoKit.Helpers.getProgressBarColor
|
import KondoKit.Helpers.getProgressBarColor
|
||||||
import KondoKit.Helpers.getSpriteId
|
import KondoKit.Helpers.getSpriteId
|
||||||
import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
|
import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
|
||||||
|
import KondoKit.ViewConstants
|
||||||
import KondoKit.XPTable
|
import KondoKit.XPTable
|
||||||
import KondoKit.components.PopupMenuComponent
|
import KondoKit.components.PopupMenuComponent
|
||||||
import KondoKit.components.ProgressBar
|
import KondoKit.components.ProgressBar
|
||||||
|
|
@ -64,7 +65,7 @@ object XPTrackerView : View, OnUpdateCallback, OnXPUpdateCallback {
|
||||||
emptyMap()
|
emptyMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val widgetFont = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
|
private val widgetFont = ViewConstants.FONT_RUNESCAPE_SMALL_16
|
||||||
|
|
||||||
private fun createPopupListener(popupMenu: JPopupMenu) = object : MouseAdapter() {
|
private fun createPopupListener(popupMenu: JPopupMenu) = object : MouseAdapter() {
|
||||||
override fun mousePressed(e: MouseEvent) {
|
override fun mousePressed(e: MouseEvent) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue