Skip to content

Commit 3bf5d95

Browse files
authored
UI changes and fixes (#9)
* Fix deprecated thread helper logic * Disable menu selection until solution is fully loaded * Fix add Beat Saber references behavior Closes #8. * Fix exception when hint path is not specified * Add IPA folder to references * Properly sort references when adding new ones * Remove add references global menu entry * Temp fix for reload issue * Rework UI, more in line with IDE * Remove unused package * Bump dependencies
1 parent 2282c08 commit 3bf5d95

File tree

15 files changed

+77
-192
lines changed

15 files changed

+77
-192
lines changed

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import java.io.ByteArrayOutputStream
77
plugins {
88
id("java")
99
alias(libs.plugins.kotlinJvm)
10-
id("org.jetbrains.intellij.platform") version "2.0.0-beta5" // See https://github.com/JetBrains/intellij-platform-gradle-plugin/releases
10+
id("org.jetbrains.intellij.platform") version "2.2.0" // See https://github.com/JetBrains/intellij-platform-gradle-plugin/releases
1111
id("me.filippov.gradle.jvm.wrapper") version "0.14.0"
1212
}
1313

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ PublishToken="_PLACEHOLDER_"
1515
# Release: 2020.2
1616
# Nightly: 2020.3-SNAPSHOT
1717
# EAP: 2020.3-EAP2-SNAPSHOT
18-
ProductVersion=2024.3-EAP2-SNAPSHOT
18+
ProductVersion=2024.3
1919
# 2021.3.3
2020

2121
# Kotlin 1.4 will bundle the stdlib dependency by default, causing problems with the version bundled with the IDE

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[versions]
22
kotlin = "1.9.24" # https://plugins.jetbrains.com/docs/intellij/using-kotlin.html#kotlin-standard-library
3-
rdGen = "2024.3.0" # https://github.com/JetBrains/rd/releases
3+
rdGen = "2024.3.1" # https://github.com/JetBrains/rd/releases
44

55
[libraries]
66
kotlinStdLib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" }

protocol/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ val RiderPluginId: String by rootProject
2323

2424
rdgen {
2525
val csOutput = File(rootDir, "src/dotnet/${DotnetPluginId}")
26-
val ktOutput = File(rootDir, "src/rider/main/kotlin/com/jetbrains/rider/plugins/${RiderPluginId.replace('.','/').toLowerCase()}")
26+
val ktOutput = File(rootDir, "src/rider/main/kotlin/com/jetbrains/rider/plugins/${RiderPluginId.replace('.','/').lowercase()}")
2727

2828
verbose = true
2929
packages = "model.rider"

src/dotnet/ReSharperPlugin.BSMT/ReSharperPlugin.BSMT.Rider.csproj

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626

2727
<ItemGroup>
2828
<PackageReference Include="JetBrains.Rider.SDK" Version="$(SdkVersion)" />
29-
<!-- https://www.nuget.org/packages/JetBrains.Rider.Rider.Backend -->
30-
<PackageReference Include="JetBrains.Rider.Rider.Backend" Version="243.0.20241010.72915-eap04" />
3129
</ItemGroup>
3230

3331
<!-- TODO: uncomment for xaml icons -->

src/rider/main/kotlin/com/github/fernthedev/bsmt_rider/actions/BeatSaberProjectAction.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import com.intellij.openapi.actionSystem.CommonDataKeys
99
import com.intellij.openapi.components.service
1010
import com.intellij.platform.backend.workspace.WorkspaceModel
1111
import com.jetbrains.rider.projectView.hasSolution
12+
import com.jetbrains.rider.projectView.solution
1213
import com.jetbrains.rider.projectView.workspace.ProjectModelEntity
1314
import com.jetbrains.rider.projectView.workspace.findProjects
1415
import kotlinx.coroutines.launch
@@ -27,7 +28,8 @@ abstract class BeatSaberProjectAction : AnAction() {
2728
return
2829
}
2930

30-
e.presentation.isEnabledAndVisible = project.hasSolution == true
31+
e.presentation.isVisible = project.hasSolution == true
32+
e.presentation.isEnabled = project.solution.solutionLifecycle.fullStartupFinished.valueOrNull?.fullStartupTime != null
3133

3234
findProjects = WorkspaceModel.getInstance(project).findProjects()
3335
val beatSaberProjectManager = project.service<BeatSaberProjectManager>()

src/rider/main/kotlin/com/github/fernthedev/bsmt_rider/actions/BeatSaberReferenceGeneratorAction.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package com.github.fernthedev.bsmt_rider.actions
22

33
import com.github.fernthedev.bsmt_rider.helpers.BeatSaberReferenceManager
4+
import com.intellij.ide.util.treeView.AbstractTreeNode
45
import com.intellij.openapi.actionSystem.ActionUpdateThread
56
import com.intellij.openapi.actionSystem.AnActionEvent
67
import com.intellij.openapi.actionSystem.CommonDataKeys
8+
import com.intellij.openapi.actionSystem.PlatformCoreDataKeys
79
import com.intellij.openapi.components.service
810
import com.intellij.platform.ide.progress.withBackgroundProgress
911
import kotlinx.coroutines.launch
@@ -14,14 +16,15 @@ class BeatSaberReferenceGeneratorAction : BeatSaberProjectAction() {
1416

1517
override fun actionPerformed(e: AnActionEvent) {
1618
val project = e.getData(CommonDataKeys.PROJECT)
19+
val selectedItem = e.getData(PlatformCoreDataKeys.SELECTED_ITEM) as? AbstractTreeNode<*>
1720

18-
if (project == null || !e.presentation.isEnabledAndVisible || findProjects == null) return
21+
if (project == null || selectedItem == null || !e.presentation.isEnabledAndVisible || findProjects == null) return
1922

2023
val referenceManager = project.service<BeatSaberReferenceManager>()
2124

2225
referenceManager.scope.launch {
2326
withBackgroundProgress(project, "Adding to Beat Saber References", cancellable = true) {
24-
referenceManager.askToAddReferences()
27+
referenceManager.askToAddReferences(selectedItem.parent.name!!)
2528
}
2629
}
2730
}

src/rider/main/kotlin/com/github/fernthedev/bsmt_rider/dialogue/BeatSaberChooseDialogue.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ class BeatSaberChooseDialogue(val project: Project?) : DialogWrapper(project) {
5555
beatSaberInput.componentPopupMenu?.isVisible = AppSettingsState.instance.beatSaberFolders.isNotEmpty()
5656
beatSaberInput.isEditable = true
5757

58-
setAsDefault = CheckBox("Set this beat saber folder as default")
59-
addToConfigCheckbox = CheckBox("Store this beat saber folder in config")
58+
setAsDefault = CheckBox("Set as default")
59+
addToConfigCheckbox = CheckBox("Store in config")
6060

6161
// logic
6262

src/rider/main/kotlin/com/github/fernthedev/bsmt_rider/dialogue/BeatSaberReferencesDialogue.kt

Lines changed: 39 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,17 @@ package com.github.fernthedev.bsmt_rider.dialogue
33
import com.github.fernthedev.bsmt_rider.xml.ReferenceXML
44
import com.intellij.openapi.project.Project
55
import com.intellij.openapi.ui.DialogWrapper
6+
import com.intellij.ui.CheckBoxList
67
import com.intellij.ui.SearchTextField
7-
import com.intellij.ui.components.JBCheckBox
88
import com.intellij.ui.components.JBScrollPane
9-
import com.intellij.ui.table.JBTable
109
import com.intellij.util.PathUtil
1110
import com.intellij.util.ui.FormBuilder
12-
import com.intellij.util.ui.UI
11+
import com.intellij.util.ui.JBUI
1312
import java.awt.Dimension
1413
import java.io.File
1514
import java.util.*
15+
import javax.swing.JCheckBox
1616
import javax.swing.JComponent
17-
import javax.swing.table.AbstractTableModel
1817

1918

2019
/// $(Beat_Saber_Path)\Beat Saber_Data\Managed
@@ -29,8 +28,7 @@ class BeatSaberReferencesDialogue(
2928
val references = ArrayList<File>()
3029

3130
private val _searchBox = SearchTextField(false)
32-
private val _parentDirectoryCheckbox = JBCheckBox("Show parent directory", true)
33-
private val _beatSaberReferences: JBTable
31+
private val _beatSaberReferences: CheckBoxList<BeatSaberReferencePair>
3432
private val _beatSaberReferencesScrollPane: JBScrollPane
3533

3634
init {
@@ -40,7 +38,7 @@ class BeatSaberReferencesDialogue(
4038
throw IllegalArgumentException("Beat saber folders are empty or not found!")
4139

4240
val existingReferencesMatch = existingReferences.map { ref ->
43-
PathUtil.getFileName(ref.stringHintPath)
41+
ref.stringHintPath?.let { PathUtil.getFileName(it) }
4442
}
4543

4644

@@ -55,72 +53,77 @@ class BeatSaberReferencesDialogue(
5553
// Merge list
5654
}.reduce { acc, arrayOfFiles ->
5755
acc + arrayOfFiles
58-
// Remove duplicates
59-
}.distinct().map {
56+
}.map {
6057
BeatSaberReferencePair(false, it)
6158
}
6259

6360

64-
title = "Beat Saber Reference Manager"
61+
title = "Add Beat Saber Reference"
6562

66-
_beatSaberReferences =
67-
JBTable(BeatSaberReferenceTable(_foundBeatSaberReferences, _parentDirectoryCheckbox.isSelected))
68-
_beatSaberReferences.setShowColumns(true)
63+
_beatSaberReferences = CheckBoxList<BeatSaberReferencePair>()
64+
_beatSaberReferences.setItems(_foundBeatSaberReferences) { pair ->
65+
pair.file.nameWithoutExtension
66+
}
67+
_beatSaberReferences.setCheckBoxListListener { index, value ->
68+
_beatSaberReferences.getItemAt(index)!!.included = value
69+
}
6970

7071
_beatSaberReferencesScrollPane = JBScrollPane(_beatSaberReferences)
7172

7273
_searchBox.textEditor.addCaretListener {
73-
val beatSaberReferenceTable = _beatSaberReferences.model as BeatSaberReferenceTable
74-
beatSaberReferenceTable.rows =
75-
_foundBeatSaberReferences.filter { it.file.path.lowercase().contains(_searchBox.text.lowercase()) }
76-
beatSaberReferenceTable.fireTableDataChanged()
77-
}
74+
val searchText = _searchBox.text.lowercase()
75+
val filteredReferences = _foundBeatSaberReferences.filter { pair ->
76+
pair.file.nameWithoutExtension.lowercase().contains(searchText)
77+
}
78+
79+
_beatSaberReferences.setItems(filteredReferences) { pair ->
80+
pair.file.nameWithoutExtension
81+
}
7882

79-
_parentDirectoryCheckbox.addChangeListener {
80-
val beatSaberReferenceTable = _beatSaberReferences.model as BeatSaberReferenceTable
81-
beatSaberReferenceTable.showParentFolder = _parentDirectoryCheckbox.isSelected
82-
beatSaberReferenceTable.fireTableDataChanged()
83+
refreshCheckboxes()
8384
}
8485

86+
setOKButtonText("Add")
87+
refreshCheckboxes()
8588
init()
8689
}
8790

91+
private fun refreshCheckboxes() {
92+
val model = _beatSaberReferences.model
93+
for (i in 0 until model.size) {
94+
val checkbox = model.getElementAt(i) as JCheckBox
95+
val pair = _beatSaberReferences.getItemAt(i)!!
96+
checkbox.isSelected = pair.included
97+
checkbox.toolTipText = pair.file.absolutePath
98+
}
99+
}
88100

89101
override fun createCenterPanel(): JComponent {
90102
// This is not a self assignment, they are different methods!
91103
// _beatSaberReferencesScrollPane.preferredSize = _beatSaberReferences.preferredSize
92-
_beatSaberReferences.autoResizeMode = JBTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS
93-
94-
_beatSaberReferences.columnModel.getColumn(0).maxWidth = UI.scale(100)
95-
_beatSaberReferences.fillsViewportHeight = true
96104

97105

98106
// _beatSaberReferences.preferredScrollableViewportSize = _beatSaberReferences.preferredScrollableViewportSize
99107

100108
val panel = FormBuilder.createFormBuilder()
101109
.addComponent(_searchBox)
102-
.addComponent(_parentDirectoryCheckbox)
103-
.addLabeledComponentFillVertically("BeatSaber references", _beatSaberReferencesScrollPane)
110+
.addComponentFillVertically(_beatSaberReferencesScrollPane, 8)
104111
// .addComponentFillVertically(JPanel(GridLayout()), 0)
105112
.panel
106113

107114

108-
panel.preferredSize = Dimension(UI.scale(340), UI.scale(350))
115+
panel.minimumSize = Dimension(JBUI.scale(400), JBUI.scale(400))
116+
panel.preferredSize = Dimension(JBUI.scale(400), JBUI.scale(400))
109117

110118
return panel
111119
}
112120

113-
override fun getPreferredFocusedComponent(): JComponent? {
121+
override fun getPreferredFocusedComponent(): JComponent {
114122
return _searchBox
115123
}
116124

117125
override fun doOKAction() {
118-
val model = _beatSaberReferences.model
119-
120-
for (i in 0 until model.rowCount) {
121-
122-
val pair = model.getValueAt(i, -1) as BeatSaberReferencePair
123-
126+
_foundBeatSaberReferences.forEach { pair ->
124127
if (pair.included) {
125128
references.add(pair.file)
126129
}
@@ -130,127 +133,7 @@ class BeatSaberReferencesDialogue(
130133
}
131134
}
132135

133-
private enum class ColumnEnum(
134-
val strName: String,
135-
val clazz: Class<*>,
136-
val editable: Boolean = false,
137-
) {
138-
INCLUDE("Include", Boolean::class.javaObjectType, true),
139-
REFERENCE("Reference", String::class.java)
140-
}
141-
142136
data class BeatSaberReferencePair(
143137
var included: Boolean = false,
144138
var file: File,
145139
)
146-
147-
148-
class BeatSaberReferenceTable(files: List<BeatSaberReferencePair>, var showParentFolder: Boolean) :
149-
AbstractTableModel() {
150-
private val columns: Array<ColumnEnum> = arrayOf(ColumnEnum.INCLUDE, ColumnEnum.REFERENCE)
151-
152-
var rows: List<BeatSaberReferencePair> = ArrayList(files)
153-
set(value) {
154-
field = ArrayList(value)
155-
}
156-
157-
/**
158-
* Returns a default name for the column using spreadsheet conventions:
159-
* A, B, C, ... Z, AA, AB, etc. If `column` cannot be found,
160-
* returns an empty string.
161-
*
162-
* @param column the column being queried
163-
* @return a string containing the default name of `column`
164-
*/
165-
override fun getColumnName(column: Int): String {
166-
return columns[column].strName
167-
}
168-
169-
/**
170-
* Returns `Object.class` regardless of `columnIndex`.
171-
*
172-
* @param columnIndex the column being queried
173-
* @return the Object.class
174-
*/
175-
override fun getColumnClass(columnIndex: Int): Class<*> {
176-
return columns[columnIndex].clazz
177-
}
178-
179-
/**
180-
* Returns false. This is the default implementation for all cells.
181-
*
182-
* @param rowIndex the row being queried
183-
* @param columnIndex the column being queried
184-
* @return false
185-
*/
186-
override fun isCellEditable(rowIndex: Int, columnIndex: Int): Boolean {
187-
return columns[columnIndex].editable
188-
}
189-
190-
/**
191-
* Returns the number of rows in the model. A
192-
* `JTable` uses this method to determine how many rows it
193-
* should display. This method should be quick, as it
194-
* is called frequently during rendering.
195-
*
196-
* @return the number of rows in the model
197-
* @see .getColumnCount
198-
*/
199-
override fun getRowCount(): Int {
200-
return rows.size
201-
}
202-
203-
/**
204-
* Returns the number of columns in the model. A
205-
* `JTable` uses this method to determine how many columns it
206-
* should create and display by default.
207-
*
208-
* @return the number of columns in the model
209-
* @see .getRowCount
210-
*/
211-
override fun getColumnCount(): Int {
212-
return columns.size
213-
}
214-
215-
/**
216-
* Returns the value for the cell at `columnIndex` and
217-
* `rowIndex`.
218-
*
219-
* @param rowIndex the row whose value is to be queried
220-
* @param columnIndex the column whose value is to be queried
221-
* @return the value Object at the specified cell
222-
*/
223-
override fun getValueAt(rowIndex: Int, columnIndex: Int): Any? {
224-
val pair = rows[rowIndex]
225-
226-
return when (columnIndex) {
227-
// We use this ourselves
228-
-1 -> pair
229-
0 -> pair.included
230-
1 ->
231-
if (showParentFolder) "${pair.file.parentFile.name}/${pair.file.nameWithoutExtension}"
232-
else pair.file.nameWithoutExtension
233-
234-
else -> null
235-
}
236-
}
237-
238-
/**
239-
* This empty implementation is provided so users don't have to implement
240-
* this method if their data model is not editable.
241-
*
242-
* @param aValue value to assign to cell
243-
* @param rowIndex row of cell
244-
* @param columnIndex column of cell
245-
*/
246-
override fun setValueAt(aValue: Any?, rowIndex: Int, columnIndex: Int) {
247-
248-
val pair = rows[rowIndex]
249-
250-
when (columnIndex) {
251-
0 -> pair.included = aValue as Boolean
252-
}
253-
}
254-
255-
256-
}

0 commit comments

Comments
 (0)