diff --git a/README.md b/README.md index e2815da..4fbab0b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,12 @@ -## Menu Preview +# KotlinBukkitAPI-Tooling -When using KotlinBukkitAPI Menu DSL you have a good preview of how the slots are arranged in the Menu in the game. +[![Install Plugin](https://img.shields.io/jetbrains/plugin/v/14913)](https://red-tea.gitbook.io/kotlinbukkitkit/genref/getting-started-with-idea-plugin) + +The KotlinBukkitKit Tooling is plugin for IntelliJ that helps developers using [KotlinBukkitKIT](https://github.com/CarcadeX/KotlinBukkitKit) + +## Features + +- Generator of KotlinBukkitKIT project + +![Preview] (https://red-tea.gitbook.io/~gitbook/image?url=https:%2F%2F630270463-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F1PBqxCHnbDKJwzj8IhJk%252Fuploads%252Fo2jPveKWzw47uGTxMm2Q%252Fimage.png%3Falt=media%26token=403c70a1-fa12-435d-99c2-aab79493de97&width=400&dpr=3&quality=100&sign=5ca18a6e18c88ceb0b5a355577cfb45cadea88b46003ac032ac4f52d7cfe52b0) -![Preview](https://i.imgur.com/9MzzAzs.gif) \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index a2874c5..06a207f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ val kotlinVersion = "1.9.0" val kotlinBukkitAPIVersion = "1.0.0.2" group = "tech.carcadex.kotlinbukkitkit" -version = "0.0.1" +version = "0.0.2" repositories { mavenLocal() diff --git a/settings.gradle.kts b/settings.gradle.kts index b1a9b4a..37cbc07 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,2 +1,2 @@ -rootProject.name = "KBK-Menu-Preview Bukkit" +rootProject.name = "KotlinBukkitKit-Tooling" diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/KBAPIArtifactWizard.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/KBAPIArtifactWizard.kt new file mode 100644 index 0000000..6cbb3e1 --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/KBAPIArtifactWizard.kt @@ -0,0 +1,78 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard + +import tech.carcadex.kotlinbukkitkit.tooling.wizard.utils.addAtGrid +import com.intellij.ide.util.projectWizard.* +import com.intellij.uiDesigner.core.* +import javax.swing.* + +/** + * https://github.com/ktorio/ktor-init-tools/blob/master/ktor-intellij-plugin/src/io/ktor/start/intellij/KtorArtifactWizardStep.kt + */ +class KBAPIArtifactWizard(val config: KBAPIModuleConfig) : ModuleWizardStep() { + val groupId: JTextField + val artifactId: JTextField + val version: JTextField + val author: JTextField + val website: JTextField + val description: JTextField + + val panel = JPanel().apply { + layout = GridLayoutManager(8, 2) + + fun addLabelText(name: String, value: String, row: Int): JTextField { + val tfield = JTextField(value) + addAtGrid( + JLabel(name), + row = row, + column = 0, + anchor = GridConstraints.ANCHOR_WEST, + fill = GridConstraints.FILL_NONE, + HSizePolicy = GridConstraints.SIZEPOLICY_FIXED, + VSizePolicy = GridConstraints.SIZEPOLICY_FIXED + ) + addAtGrid( + tfield, + row = row, + column = 1, + anchor = GridConstraints.ANCHOR_WEST, + fill = GridConstraints.FILL_HORIZONTAL, + HSizePolicy = GridConstraints.SIZEPOLICY_CAN_GROW or GridConstraints.SIZEPOLICY_WANT_GROW, + VSizePolicy = GridConstraints.SIZEPOLICY_FIXED + ) + return tfield + } + + addAtGrid( + JLabel(""), + row = 0, + column = 0, + HSizePolicy = GridConstraints.SIZEPOLICY_FIXED, + VSizePolicy = GridConstraints.SIZEPOLICY_FIXED + ) + + artifactId = addLabelText("Plugin Name", config.artifactId, row = 1) + groupId = addLabelText("GroupId", config.artifactGroup, row = 2) + version = addLabelText("Version", config.artifactVersion, row = 3) + author = addLabelText("Author", config.author, row = 4) + website = addLabelText("Website", config.author, row = 5) + description = addLabelText("Description", config.description, row = 6) + + add(Spacer().apply {}, GridConstraints().apply { + colSpan = 2 + row = 7 + column = 0 + fill = GridConstraints.FILL_VERTICAL + }) + } + + override fun updateDataModel() { + config.artifactGroup = groupId.text + config.artifactId = artifactId.text + config.artifactVersion = version.text + config.author = author.text + config.website = website.text + config.description = description.text + } + + override fun getComponent() = panel +} diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/KBAPIModuleBuilder.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/KBAPIModuleBuilder.kt new file mode 100644 index 0000000..f915c39 --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/KBAPIModuleBuilder.kt @@ -0,0 +1,118 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard + +import tech.carcadex.kotlinbukkitkit.tooling.wizard.creator.* +import tech.carcadex.kotlinbukkitkit.tooling.wizard.utils.backgroundTask +import tech.carcadex.kotlinbukkitkit.tooling.wizard.utils.get +import tech.carcadex.kotlinbukkitkit.tooling.wizard.utils.invokeLater +import com.intellij.codeInsight.actions.ReformatCodeProcessor +import com.intellij.ide.actions.ImportModuleAction +import com.intellij.ide.util.projectWizard.JavaModuleBuilder +import com.intellij.ide.util.projectWizard.ModuleBuilder +import com.intellij.ide.util.projectWizard.WizardContext +import com.intellij.openapi.Disposable +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.application.ModalityState +import com.intellij.openapi.module.ModuleType +import com.intellij.openapi.project.DumbAwareRunnable +import com.intellij.openapi.projectRoots.JavaSdk +import com.intellij.openapi.projectRoots.SdkTypeId +import com.intellij.openapi.roots.ModifiableRootModel +import com.intellij.openapi.roots.ui.configuration.ModulesProvider +import com.intellij.openapi.util.Computable +import com.intellij.openapi.util.Ref +import com.intellij.openapi.util.io.FileUtil +import com.intellij.openapi.vfs.LocalFileSystem +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.projectImport.ProjectImportProvider +import java.io.File +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths +import javax.swing.Icon + +class KBAPIModuleBuilder : ModuleBuilder() { + override fun getPresentableName(): String = KBAPIModuleType.NAME + override fun getNodeIcon(): Icon = KBAPIModuleType.ICON + override fun getGroupName(): String = KBAPIModuleType.NAME + override fun getBuilderId(): String? = "KOTLINBUKKITAPI_MODULE" + + override fun isSuitableSdkType(sdkType: SdkTypeId?): Boolean = sdkType === JavaSdk.getInstance() + + val config = KBAPIModuleConfig() + + override fun setupRootModel(rootModel: ModifiableRootModel) { + val project = rootModel.project + val (rootPath, vFile) = createAndGetRoot() + val root = rootPath.toFile() + rootModel.addContentEntry(vFile) + if (moduleJdk != null) rootModel.sdk = moduleJdk + + project.backgroundTask("Setting Up Project") { progress -> + progress.text = "Generating Gradle" + + val gradleBuildFile = generateGradleBuildFile(root).createIfNotExists() + val gradleSettingFile = generateGradleSettingsFile(root).createIfNotExists() + generateConfigFile(root).createIfNotExists() + generateMessagesFile(root).createIfNotExists() + + gradleBuildFile.appendText(generateGradleBuildFileContent(config)) + gradleSettingFile.appendText(generateGradleSettingsFileContent(config)) + + progress.text = "Generating Plugin Main" + + val pluginMain = generatePluginMainFile(root, config).createIfNotExists() + + pluginMain.appendText(generatePluginMainFileContent(config)) + + progress.text = "Configuring project gradle" + vFile.refresh(false, true) + + val buildGradle = vFile["build.gradle.kts"] + if (buildGradle != null) + invokeLater { + val provider = ProjectImportProvider.PROJECT_IMPORT_PROVIDER.extensions + .firstOrNull { it.canImport(buildGradle, project) } + ?: return@invokeLater + + val wizard = ImportModuleAction.createImportWizard( + project, + null, + buildGradle, + provider + ) + + if (wizard != null && (wizard.stepCount <= 0 || wizard.showAndGet())) { + ImportModuleAction.createFromWizard(project, wizard) + } + } + } + } + + override fun getModuleType(): ModuleType<*> { + return KBAPIModuleType() + } + + override fun getParentGroup() = KBAPIModuleType.NAME + + override fun createWizardSteps(wizardContext: WizardContext, modulesProvider: ModulesProvider) = arrayOf( + KBAPIArtifactWizard(config) + ) + + override fun getCustomOptionsStep(context: WizardContext, parentDisposable: Disposable?) = + KBAPIWizardStep(config) + + + private fun createAndGetRoot(): Pair { + val temp = contentEntryPath ?: throw IllegalStateException("Failed to get content entry path") + + val pathName = FileUtil.toSystemIndependentName(temp) + + val path = Paths.get(pathName) + Files.createDirectories(path) + val vFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(pathName) + ?: throw IllegalStateException("Failed to refresh and file file: $path") + + return path to vFile + } + +} diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/KBAPIModuleConfig.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/KBAPIModuleConfig.kt new file mode 100644 index 0000000..213e290 --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/KBAPIModuleConfig.kt @@ -0,0 +1,18 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard + +import tech.carcadex.kotlinbukkitkit.tooling.wizard.bukkit.Plugin +import tech.carcadex.kotlinbukkitkit.tooling.wizard.bukkit.ServerType +import tech.carcadex.kotlinbukkitkit.tooling.wizard.bukkit.ServerVersion + +data class KBAPIModuleConfig( + var artifactGroup: String = "com.example", + var artifactId: String = "MyPlugin", + var artifactVersion: String = "0.0.1", + var externalPlugins: List = listOf(), + var kbAPIVersion: KotlinBukkitAPIVersion = Versions.LAST, + var serverVersion: ServerVersion = ServerVersion.v1_8, + var serverType: ServerType = ServerType.PAPERMC, + var author: String = "", + var website: String = "", + var description: String = "" +) diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/KBAPIModuleType.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/KBAPIModuleType.kt new file mode 100644 index 0000000..9d52d17 --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/KBAPIModuleType.kt @@ -0,0 +1,22 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard + +import tech.carcadex.kotlinbukkitkit.tooling.Assets +import com.intellij.openapi.module.ModuleType +import javax.swing.Icon + +class KBAPIModuleType : ModuleType("kotlinbukkitkit") { + + companion object { + val NAME = "KotlinBukkitKit" + val DESCRIPTION = "KotlinBukkitKit Quick" + val ICON = tech.carcadex.kotlinbukkitkit.tooling.Assets.KotlinBukkitAPIIcon + val INSTANCE = KBAPIModuleType() + } + + override fun createModuleBuilder(): KBAPIModuleBuilder = KBAPIModuleBuilder() + override fun getName(): String = NAME + override fun getDescription(): String = DESCRIPTION + override fun getNodeIcon(isOpened: Boolean): Icon = ICON + override fun getIcon(): Icon = ICON + +} \ No newline at end of file diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/KBAPIWizardStep.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/KBAPIWizardStep.kt new file mode 100644 index 0000000..4cb0eba --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/KBAPIWizardStep.kt @@ -0,0 +1,91 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard + +import tech.carcadex.kotlinbukkitkit.tooling.wizard.bukkit.* +import tech.carcadex.kotlinbukkitkit.tooling.wizard.utils.* +import com.intellij.ide.util.projectWizard.ModuleWizardStep +import com.intellij.openapi.ui.Splitter +import com.intellij.ui.IdeBorderFactory +import java.awt.BorderLayout +import javax.swing.* + +/** + * https://github.com/ktorio/ktor-init-tools/blob/master/ktor-intellij-plugin/src/io/ktor/start/intellij/KtorModuleWizardStep.kt + */ +class KBAPIWizardStep( + val config: KBAPIModuleConfig +) : ModuleWizardStep() { + lateinit var serverApiVersionCB: JComboBox + lateinit var serverForkCB: JComboBox + lateinit var kotlinBukkitAPIVersionCB: JComboBox + lateinit var externalPluginList: PluginCheckboxList + + override fun updateDataModel() { + config.serverVersion = serverApiVersionCB.selectedItem as ServerVersion + config.externalPlugins = externalPluginList.pluginsToCheckbox.keys.filter { it.isSelected } + config.serverType = serverForkCB.selectedItem as ServerType + config.kbAPIVersion = kotlinBukkitAPIVersionCB.selectedItem as KotlinBukkitAPIVersion + } + + val panel by lazy { + JPanel().apply { + val description = JPanel().apply { + layout = BoxLayout(this, BoxLayout.Y_AXIS) + border = IdeBorderFactory.createBorder() + } + + externalPluginList = object : PluginCheckboxList(ALL_PLUGINS) { + override fun onSelected(feature: Plugin?, node: ThreeStateCheckedTreeNode) { + // TODO: Show source link? + } + override fun onChanged(feature: Plugin, node: ThreeStateCheckedTreeNode) { + feature.isSelected = !feature.isSelected + + externalPluginList.repaint() + } + } + + this.layout = BorderLayout(0, 0) + + add(table { + tr( + policy = TdSize.FIXED, + fill = TdFill.NONE, + align = TdAlign.CENTER_LEFT + ) { + td(JLabel("Server API Version:")) + td(JComboBox(ServerVersion.values().reversedArray()).apply { serverApiVersionCB = this }) + td(JLabel("Server:")) + td(JComboBox(ServerType.values()).apply { serverForkCB = this }) + td(JLabel("KotlinBukkitKit:")) + td(JComboBox(Versions.ALL).apply { + kotlinBukkitAPIVersionCB = this + selectedItem = Versions.LAST + }) + } + }, BorderLayout.NORTH) + + add(Splitter(true, 0.8f, 0.2f, 0.8f).apply { + this.firstComponent = table { + tr( + policy = TdSize.FIXED, + minHeight = 24, + maxHeight = 24, + fill = TdFill.NONE, + align = TdAlign.CENTER_LEFT + ) { + td(JLabel("Plugins:")) + } + tr { + td(externalPluginList.scrollVertical()) + } + } + this.secondComponent = description + }, BorderLayout.CENTER) + } + } + + override fun getComponent(): JComponent { + return panel + } + +} \ No newline at end of file diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/LibraryVersions.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/LibraryVersions.kt new file mode 100644 index 0000000..21313ff --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/LibraryVersions.kt @@ -0,0 +1,6 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard + +const val PLUGIN_YML = "0.6.0" +const val SHADOW_PLUGIN = "7.1.2" +const val KSP = "1.9.0-1.0.11" +const val RUN_PAPER = "2.1.0" \ No newline at end of file diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/Versions.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/Versions.kt new file mode 100644 index 0000000..e1de8a3 --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/Versions.kt @@ -0,0 +1,54 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard + +object Versions { + val `1-0-0-3-SNAPSHOT` = KotlinBukkitAPIVersion("1.0.0.3-SNAPSHOT") + + val ALL = arrayOf( + `1-0-0-3-SNAPSHOT` + ) + + val LAST = `1-0-0-3-SNAPSHOT` + + val visitorAll = ALL.associate { it.version to it } + + fun fromString(version: String) = visitorAll[version] +} + +data class KotlinBukkitAPIVersion( + val version: String, + val kotlinVersion: String = "1.9.23" +) { + override fun toString(): String { + return version + } + + private val group = "tech.carcadex" + + val repositories = listOf( + "https://hub.spigotmc.org/nexus/content/repositories/snapshots/", + "https://s01.oss.sonatype.org/content/repositories/snapshots/" + ) + + val dependencies = listOf( + "${group}:kotlinbukkitkit-architecture:\$kbk_version", + "${group}:kotlinbukkitkit-extensions:\$kbk_version", + "${group}:kotlinbukkitkit-serialization:\$kbk_version", + "${group}:kotlinbukkitkit-messages:\$kbk_version", + "${group}:kotlinbukkitkit-commands:\$kbk_version", + "${group}:kotlinbukkitkit-utility:\$kbk_version", + "${group}:kotlinbukkitkit-menu:\$kbk_version", + + "org.jetbrains.kotlin:kotlin-stdlib", + "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.2", + "org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1", + "com.github.cryptomorin:XSeries:9.2.0" + ) + + val dependenciesCompileOnly = listOf( + "org.jetbrains:annotations:24.0.0", + ) + + val kspModules = listOf( + "${group}:kotlinbukkitkit-genref:$version" + ) +} \ No newline at end of file diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/bukkit/Plugin.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/bukkit/Plugin.kt new file mode 100644 index 0000000..49d9dd2 --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/bukkit/Plugin.kt @@ -0,0 +1,10 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard.bukkit + +data class Plugin( + val name: String, + val versions: List, + val repositories: Set, + val displayName: String = name +) { + var isSelected = false +} \ No newline at end of file diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/bukkit/PluginList.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/bukkit/PluginList.kt new file mode 100644 index 0000000..c9ed6c6 --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/bukkit/PluginList.kt @@ -0,0 +1,96 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard.bukkit + +import tech.carcadex.kotlinbukkitkit.tooling.wizard.bukkit.ServerVersion.* + +private val worldEdit = "com.sk89q.worldedit" + +// TODO: plotsquared, multiverse + +val ALL_PLUGINS = listOf( + Plugin( + "Vault", + allVersion("1.7") { setOf("com.github.MilkBowl:VaultAPI:$it") }, + setOf("https://jitpack.io"), + ), + Plugin( + "WorldEdit", + listOf(v1_8, v1_9, v1_12).asPluginVersion("6.1.5") { setOf("$worldEdit:worldedit-core:$it", "$worldEdit:worldedit-bukkit:$it") } + + listOf(v1_13, v1_14, v1_15, v1_16, v1_17, v1_18, v1_19).asPluginVersion("7.2.14-SNAPSHOT") { setOf("$worldEdit:worldedit-core:$it", "$worldEdit:worldedit-bukkit:$it") } + + listOf(v1_20).asPluginVersion("7.3.0-SNAPSHOT") { setOf("$worldEdit:worldedit-core:$it", "$worldEdit:worldedit-bukkit:$it") } + , + setOf("http://maven.sk89q.com/repo/") + ), + Plugin( + "WorldGuard", + listOf(v1_8, v1_9, v1_12).asPluginVersion("6.1") { setOf("com.sk89q:worldguard:$it") } + + listOf(v1_13, v1_14, v1_15, v1_16, v1_17, v1_18, v1_19, v1_20).asPluginVersion("7.0.4-SNAPSHOT") { setOf("com.sk89q.worldguard:worldguard-core:$it", "com.sk89q.worldguard:worldguard-bukkit:$it") } + , + setOf("http://maven.sk89q.com/repo/") + ), + Plugin( + "Citizens", + allVersion("2.0.27-SNAPSHOT") { setOf("net.citizensnpcs:citizensapi:$it", "net.citizensnpcs:citizens:$it") }, + setOf("http://repo.citizensnpcs.co/") + ), + Plugin( + "LuckPerms", + allVersion("5.4") { setOf("net.luckperms:api:$it") }, + setOf() // mavenCentral + ), + Plugin( + "ProtocolLib", + allVersion("5.1.0") { setOf("com.comphenix.protocol:ProtocolLib:$it") }, + setOf("http://repo.dmulloy2.net/nexus/repository/public/") + ), + Plugin( + "PlaceholderAPI", + allVersion("2.11.5") { setOf("me.clip:placeholderapi:$it") }, + setOf("http://repo.extendedclip.com/content/repositories/placeholderapi/") + ), + Plugin( + "MVdWPlaceholderAPI", + allVersion("3.1.1") { setOf("be.maximvdw:MVdWPlaceholderAPI:$it") }, + setOf("http://repo.mvdw-software.be/content/groups/public/")), + Plugin( + "ActionBarAPI", + allVersion("d60c2aedb9") { setOf("com.github.ConnorLinfoot:ActionBarAPI:$it") }, + setOf("https://jitpack.io") + ), + Plugin( + "TitleAPI", + allVersion("1.8.1") { setOf("com.github.ConnorLinfoot:TitleAPI:$it") }, + setOf("https://jitpack.io")), + Plugin( + "ViaVersion", + allVersion("4.9.3") { setOf("us.myles:viaversion-common:$it") }, + setOf("https://repo.viaversion.com/") + ), + Plugin( + "BossBarAPI", + allVersion("2.4.2") { setOf("org.inventivetalent:bossbarapi:$it") }, + setOf("https://repo.inventivetalent.org/content/groups/public/") + ), + Plugin( + "HologramAPI", + allVersion("1.6.0") { setOf("org.inventivetalent:hologramapi:$it") }, + setOf("https://repo.inventivetalent.org/content/groups/public/") + ), + Plugin( + "NoDropX", + allVersion("1.0.3c") { setOf("com.github.iRedTea:NoDropX:$it") }, + setOf("https://jitpack.io") + ), + Plugin( + "EssentialsX", + allVersion("2.20.1") { setOf("net.essentialsx:EssentialsX:$it") }, + setOf("https://repo.essentialsx.net/releases/") + ), + Plugin( + "Multiverse-Core", + allVersion("4.3.1") { setOf("com.onarandombox.multiversecore:Multiverse-Core:$it") }, + setOf("https://repo.onarandombox.com/content/groups/public/") + ), +) + +inline fun allVersion(version: String, dependencies: (String) -> Set): List = ServerVersion.values().map { PluginVersion(version, it, dependencies(version)) } +inline fun List.asPluginVersion(version: String, dependencies: (String) -> Set): List = map { PluginVersion(version, it, dependencies(version)) } \ No newline at end of file diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/bukkit/PluginVersion.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/bukkit/PluginVersion.kt new file mode 100644 index 0000000..e940354 --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/bukkit/PluginVersion.kt @@ -0,0 +1,7 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard.bukkit + +class PluginVersion( + val version: String, + val serverVersion: ServerVersion, + val dependencies: Set +) \ No newline at end of file diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/bukkit/ServerAPI.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/bukkit/ServerAPI.kt new file mode 100644 index 0000000..831f0c2 --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/bukkit/ServerAPI.kt @@ -0,0 +1,54 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard.bukkit + +data class ServerAPI( + val version: ServerVersion, + val serverType: ServerType +) + +val ServerAPI.dependencies: List get() { + + val versionName = when(version) { + ServerVersion.v1_8 -> "1.8.8-R0.1-SNAPSHOT" + ServerVersion.v1_9 -> "1.9.4-R0.1-SNAPSHOT" + ServerVersion.v1_12 -> "1.12.2-R0.1-SNAPSHOT" + ServerVersion.v1_13 -> "1.13.2-R0.1-SNAPSHOT" + ServerVersion.v1_14 -> "1.14.4-R0.1-SNAPSHOT" + ServerVersion.v1_15 -> "1.15.2-R0.1-SNAPSHOT" + ServerVersion.v1_16 -> "1.16.5-R0.1-SNAPSHOT" + ServerVersion.v1_17 -> "1.17.1-R0.1-SNAPSHOT" + ServerVersion.v1_18 -> "1.18.2-R0.1-SNAPSHOT" + ServerVersion.v1_19 -> "1.19.4-R0.1-SNAPSHOT" + ServerVersion.v1_20 -> "1.20.4-R0.1-SNAPSHOT" + } + + val dependency = when(serverType) { + ServerType.SPIGOT -> "org.spigotmc:spigot-api:$versionName" + ServerType.PAPERMC -> { + val v17 = "org.github.paperspigot:paperspigot-api" + val v19 = "com.destroystokyo.paper:paper-api" + val v20 = "io.papermc.paper:paper-api" + + when(version) { + ServerVersion.v1_8 -> "$v17:$versionName" + ServerVersion.v1_9, ServerVersion.v1_12, ServerVersion.v1_13, + ServerVersion.v1_14, ServerVersion.v1_15, ServerVersion.v1_16 -> "$v19:$versionName"; + else -> "$v20:$versionName" + } + } + } + + return listOf(dependency) +} + +val ServerAPI.repositories: List get() { + return when(serverType) { + ServerType.SPIGOT -> listOf( + "https://hub.spigotmc.org/nexus/content/repositories/snapshots/", + "https://oss.sonatype.org/content/repositories/snapshots/" + ) + ServerType.PAPERMC -> listOf( + "https://papermc.io/repo/repository/maven-public/", + "https://oss.sonatype.org/content/repositories/snapshots/" + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/bukkit/ServerType.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/bukkit/ServerType.kt new file mode 100644 index 0000000..6708246 --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/bukkit/ServerType.kt @@ -0,0 +1,5 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard.bukkit + +enum class ServerType { + SPIGOT, PAPERMC +} \ No newline at end of file diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/bukkit/ServerVersion.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/bukkit/ServerVersion.kt new file mode 100644 index 0000000..e9954db --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/bukkit/ServerVersion.kt @@ -0,0 +1,20 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard.bukkit + +enum class ServerVersion(val displayName: String, val maxVersion: String, val minor: Int,) { + v1_8("1.8", "1.8.9", 8), + v1_9("1.9", "1.9.4", 9), + v1_12("1.12", "1.12.2", 12), + v1_13("1.13", "1.13.2", 13), + v1_14("1.14", "1.14.4", 14), + v1_15("1.15", "1.15.2", 15), + v1_16("1.16", "1.16.5", 16), + v1_17("1.17", "1.17.1", 17), + v1_18("1.18", "1.18.2", 18), + v1_19("1.19", "1.19.4", 19), + v1_20("1.20", "1.20.4", 20),; + + + override fun toString(): String { + return displayName + } +} diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/creator/GradleBuilder.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/creator/GradleBuilder.kt new file mode 100644 index 0000000..bacadeb --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/creator/GradleBuilder.kt @@ -0,0 +1,159 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard.creator + +import tech.carcadex.kotlinbukkitkit.tooling.wizard.* +import tech.carcadex.kotlinbukkitkit.tooling.wizard.bukkit.ServerAPI +import tech.carcadex.kotlinbukkitkit.tooling.wizard.bukkit.dependencies +import tech.carcadex.kotlinbukkitkit.tooling.wizard.bukkit.repositories +import java.io.File + +fun generateGradleBuildFile( + root: File +): File = File(root, "build.gradle.kts") + +fun generateGradleSettingsFile( + root: File +): File = File(root, "settings.gradle.kts") + +fun generateConfigFile( + root: File +): File = File(root, "src/main/resources/config.yml") + +fun generateMessagesFile( + root: File +): File = File(root, "src/main/resources/messages.yml") + +fun generateGradleBuildFileContent( + config: KBAPIModuleConfig +): String = with(config) { + val kbapiDependencies = kbAPIVersion.dependencies + .dependenciesAsGradle(if (config.serverVersion.minor >= 16) "library" else "implementation") + val kbapiDependenciesCompileOnly = kbAPIVersion.dependenciesCompileOnly + .dependenciesAsGradle("compileOnly") + val kspModules = kbAPIVersion.kspModules.dependenciesAsGradle("ksp") + val kspDependencies = kbAPIVersion.kspModules.dependenciesAsGradle() + + val kbapiRepositories = kbAPIVersion.repositories + .repositoriesAsGradle() + + val serverApi = ServerAPI(config.serverVersion, config.serverType) + val serverRepositories = serverApi.repositories.repositoriesAsGradle() + val serverDependencies = serverApi.dependencies.dependenciesAsGradle() + + val pluginDependencies = "${DEFAULT_INDENTATION}val transitive = Action { isTransitive = false }\n" + externalPlugins + .flatMap { it.versions.first { it.serverVersion == serverVersion }.dependencies } + .distinct() + .dependenciesAsGradle(with = ", transitive") + + val pluginRepositories = externalPlugins + .flatMap { it.repositories } + .distinct() + .repositoriesAsGradle() + + + val plugins = (externalPlugins.map{ "\"${it.name}\"" }).joinToString() + + return """ + |// More about the setup here: https://red-tea.gitbook.io/kotlinbukkitkit + |plugins { + | kotlin("jvm") version "${kbAPIVersion.kotlinVersion}" + | kotlin("plugin.serialization") version "${kbAPIVersion.kotlinVersion}" + | id("net.minecrell.plugin-yml.bukkit") version "$PLUGIN_YML" + | id("com.github.johnrengelman.shadow") version "$SHADOW_PLUGIN" + | id("xyz.jpenilla.run-paper") version "$RUN_PAPER" + | id("com.google.devtools.ksp") version "$KSP" + |} + | + |group = "$artifactGroup" + |version = "$artifactVersion" + |val kbk_version = "${config.kbAPIVersion.version}" + | + |repositories { + | mavenCentral() + | // minecraft + |$serverRepositories + | + | //kotlinbukkitapi with backup repo + |$kbapiRepositories + | + | //plugins + |$pluginRepositories + |} + | + |dependencies { + | compileOnly(kotlin("stdlib-jdk8")) + | + | //minecraft + |$serverDependencies + | + | //kotlinbukkitapi + |$kbapiDependencies + |$kbapiDependenciesCompileOnly + | + | //ksp + |$kspDependencies + |$kspModules + | + | //plugins + |$pluginDependencies + |} + | + |bukkit { + | main = "${packageName}.${pluginMainName}Plugin" + | depend = listOf($plugins) + | description = "$description" + | author = "$author" + | website = "$website" + | apiVersion = "${config.serverVersion.displayName}" + |} + | + |tasks { + | shadowJar { + | dependencies { + | exclude(dependency("org.jetbrains:*:*")) + | } + | } + | runServer { + | minecraftVersion("${config.serverVersion.maxVersion}") + | } + |} + | + | + |sourceSets { + | main { + | kotlin.srcDirs.add(File("build/generated/ksp")) + | } + |} + | + """.trimMargin() +} + +private inline fun List.dependenciesAsGradle(configuration: String = "compileOnly", with: String = ""): String = + joinToString("\n") { + "$configuration(\"${it}\"$with)" + }.prependIndent(DEFAULT_INDENTATION) + + +private inline fun List.repositoriesAsGradle(): String = + joinToString("\n") { + """ + |maven { + | url = uri("$it") + | isAllowInsecureProtocol = true + |} + """.trimMargin() + }.prependIndent(DEFAULT_INDENTATION) + +fun generateGradleSettingsFileContent( + config: KBAPIModuleConfig +): String = with(config) { + return """ + rootProject.name = "$artifactId" + """.trimSource() +} + +fun String.trimSource(): String { + val lines = lines() + val indentation = lines[1].indexOfFirst { !it.isWhitespace() } + + return lines.joinToString("\n") { it.removePrefix(" ".repeat(indentation)) } +} \ No newline at end of file diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/creator/PluginMainBuilder.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/creator/PluginMainBuilder.kt new file mode 100644 index 0000000..05ef4bb --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/creator/PluginMainBuilder.kt @@ -0,0 +1,36 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard.creator + +import tech.carcadex.kotlinbukkitkit.tooling.wizard.KBAPIModuleConfig +import java.io.File + +fun generatePluginPackageFolder( + root: File, + config: KBAPIModuleConfig +): File = File(root, "src/main/kotlin/${config.packageName.replace(".", "/")}") + +fun generatePluginMainFile( + root: File, + config: KBAPIModuleConfig +): File = File(generatePluginPackageFolder(root, config), "${config.pluginMainName}.kt") + +fun generatePluginMainFileContent( + config: KBAPIModuleConfig +): String = with(config) { + return """ + package $packageName + + import tech.carcadex.kotlinbukkitkit.architecture.KotlinPlugin + import tech.carcadex.kotlinbukkitkit.genref.plugin.annotations.OnDisable + import tech.carcadex.kotlinbukkitkit.genref.plugin.annotations.Plugin + + @Plugin + fun KotlinPlugin.start() { + + } + + @OnDisable + fun KotlinPlugin.stop() { + + } + """.trimIndent() +} \ No newline at end of file diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/creator/Utils.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/creator/Utils.kt new file mode 100644 index 0000000..45152fe --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/creator/Utils.kt @@ -0,0 +1,22 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard.creator + +import tech.carcadex.kotlinbukkitkit.tooling.wizard.KBAPIModuleConfig +import java.io.File + +const val DEFAULT_INDENTATION = " " + +inline fun String.mapIfNotBlank(block: (String) -> String): String = + if(isNotBlank()) + block(this) + else + this + +fun File.createIfNotExists(): File = apply { + if(!exists()) { + parentFile.mkdirs() + createNewFile() + } +} + +val KBAPIModuleConfig.packageName get() = "${artifactGroup}.${artifactId.toLowerCase()}" +val KBAPIModuleConfig.pluginMainName get() = artifactId \ No newline at end of file diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/utils/PluginCheckboxList.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/utils/PluginCheckboxList.kt new file mode 100644 index 0000000..6be25ed --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/utils/PluginCheckboxList.kt @@ -0,0 +1,99 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard.utils + +import tech.carcadex.kotlinbukkitkit.tooling.wizard.bukkit.Plugin +import com.intellij.ui.CheckboxTree +import com.intellij.ui.CheckedTreeNode +import com.intellij.ui.SimpleTextAttributes +import com.intellij.util.ui.ThreeStateCheckBox +import com.intellij.util.ui.UIUtil +import javax.swing.JTree +import javax.swing.tree.DefaultTreeModel +import javax.swing.tree.TreePath + +open class ThreeStateCheckedTreeNode : CheckedTreeNode { + constructor() : super() + constructor(userObject: Any?) : super(userObject) + + var indeterminate = false +} + +/** + * Based on Ktor FeatureCheckboxList + * https://github.com/ktorio/ktor-init-tools/blob/master/ktor-intellij-plugin/src/io/ktor/start/intellij/KtorModuleWizardStep.kt#L175 + */ +abstract class PluginCheckboxList(val plugins: List) : CheckboxTree( + object : CheckboxTree.CheckboxTreeCellRenderer() { + override fun customizeRenderer( + tree: JTree?, + value: Any?, + selected: Boolean, + expanded: Boolean, + leaf: Boolean, + row: Int, + hasFocus: Boolean + ) { + if (value is ThreeStateCheckedTreeNode) { + val plugin = value.userObject + val tscheckbox = checkbox as ThreeStateCheckBox + if (plugin is Plugin) { + val style: SimpleTextAttributes = when { + value.indeterminate -> SimpleTextAttributes.REGULAR_ITALIC_ATTRIBUTES + else -> SimpleTextAttributes.REGULAR_ATTRIBUTES + } + textRenderer.append(plugin.name, style) + textRenderer.isEnabled = true + tscheckbox.isVisible = true + tscheckbox.state = when { + value.indeterminate -> ThreeStateCheckBox.State.DONT_CARE + value.isChecked -> ThreeStateCheckBox.State.SELECTED + else -> ThreeStateCheckBox.State.NOT_SELECTED + } + textRenderer.foreground = UIUtil.getTreeForeground() + } else if (plugin is String) { + textRenderer.append(plugin) + textRenderer.isEnabled = false + isEnabled = false + tscheckbox.isVisible = false + } + } + } + }, + ThreeStateCheckedTreeNode() +) { + val CheckedTreeNode?.plugin: Plugin? get() = this?.userObject as? Plugin? + + val pluginsToCheckbox = LinkedHashMap() + val root = (this.model as DefaultTreeModel).root as ThreeStateCheckedTreeNode + init { + this.model = object : DefaultTreeModel(root) { + override fun valueForPathChanged(path: TreePath, newValue: Any) { + super.valueForPathChanged(path, newValue) + val node = path.lastPathComponent as ThreeStateCheckedTreeNode + val plugin = node.plugin + if (plugin != null) { + onChanged(plugin, node) + } + } + } + } + + init { + for (plugin in plugins) { + root.add(ThreeStateCheckedTreeNode(plugin).apply { isChecked = false; pluginsToCheckbox[plugin] = this }) + } + (this.model as DefaultTreeModel).reload(root) + + addTreeSelectionListener { e -> + val node = (e.newLeadSelectionPath.lastPathComponent as? ThreeStateCheckedTreeNode) + val plugin = node?.userObject as? Plugin? + + if (node != null) { + onSelected(plugin, node) + } + } + } + + abstract fun onSelected(feature: Plugin?, node: ThreeStateCheckedTreeNode) + open fun onChanged(feature: Plugin, node: ThreeStateCheckedTreeNode) { + } +} \ No newline at end of file diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/utils/Project.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/utils/Project.kt new file mode 100644 index 0000000..8afef0e --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/utils/Project.kt @@ -0,0 +1,54 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard.utils + +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.application.ModalityState +import com.intellij.openapi.progress.ProgressIndicator +import com.intellij.openapi.progress.ProgressManager +import com.intellij.openapi.progress.Task +import com.intellij.openapi.project.Project +import com.intellij.openapi.vfs.VirtualFile + +/** + * https://github.com/ktorio/ktor-init-tools/blob/master/ktor-intellij-plugin/src/io/ktor/start/intellij/util/Utils.kt + */ + +operator fun VirtualFile?.get(path: String?): VirtualFile? { + if (this == null || path == null || path == "" || path == ".") return this + val parts = path.split('/', limit = 2) + val firstName = parts[0] + val lastName = parts.getOrNull(1) + val child = this.findChild(firstName) + return if (lastName != null) child[lastName] else child +} + + +fun Project.backgroundTask( + name: String, + indeterminate: Boolean = true, + cancellable: Boolean = false, + background: Boolean = false, + callback: (indicator: ProgressIndicator) -> Unit +) { + ProgressManager.getInstance().run(object : Task.Backgroundable(this, name, cancellable, { background }) { + override fun shouldStartInBackground() = background + + override fun run(indicator: ProgressIndicator) { + try { + if (indeterminate) indicator.isIndeterminate = true + callback(indicator) + } catch (e: Throwable) { + e.printStackTrace() + throw e + } + } + }) +} + +inline fun invokeLater(crossinline func: () -> Unit) { + if (ApplicationManager.getApplication().isDispatchThread) { + func() + } else { + ApplicationManager.getApplication().invokeLater({ func() }, ModalityState.defaultModalityState()) + } +} + diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/utils/Ui.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/utils/Ui.kt new file mode 100644 index 0000000..cddb7a4 --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/tooling/wizard/utils/Ui.kt @@ -0,0 +1,171 @@ +package tech.carcadex.kotlinbukkitkit.tooling.wizard.utils + +import com.intellij.ui.ScrollPaneFactory +import com.intellij.ui.components.JBScrollPane +import com.intellij.uiDesigner.core.* +import java.awt.* +import javax.swing.* + +data class TdPos(val col: Int, val row: Int) + +@DslMarker +annotation class TableTagMarker + +@TableTagMarker +class TableBuilder { + val items = LinkedHashMap>() + var row = 0 + var col = 0 + + var fill: TdFill = TdFill.BOTH + var anchor: TdAlign = TdAlign.CENTER_CENTER + var hpolicy: TdSize = TdSize.CAN_SHRINK_GROW + var vpolicy: TdSize = TdSize.CAN_SHRINK_GROW + var minWidth: Int? = null + var minHeight: Int? = null + var maxWidth: Int? = null + var maxHeight: Int? = null + + val nrows get() = items.values.map { it.second.row + it.second.rowSpan }.max() ?: 0 + val ncols get() = items.values.map { it.second.column + it.second.colSpan }.max() ?: 0 +} + +fun table(callback: TableBuilder.() -> Unit): JPanel { + val tb = TableBuilder() + tb.callback() + val panel = JPanel(GridLayoutManager(tb.nrows, tb.ncols, Insets(0, 0, 0, 0), 0, 0, false, false)) + for (item in tb.items.values) { + panel.add(item.first, item.second) + } + //add(panel) + return panel +} + +fun TableBuilder.tr( + fill: TdFill = TdFill.BOTH, + align: TdAlign = TdAlign.CENTER_CENTER, + policy: TdSize = TdSize.CAN_SHRINK_GROW, + hpolicy: TdSize = policy, + vpolicy: TdSize = policy, + minWidth: Int? = null, + maxWidth: Int? = null, + minHeight: Int? = null, + maxHeight: Int? = null, + callback: TableBuilder.() -> Unit +) { + this.fill = fill + this.anchor = align + this.hpolicy = hpolicy + this.vpolicy = vpolicy + this.minWidth = minWidth + this.maxWidth = maxWidth + this.minHeight = minHeight + this.maxHeight = maxHeight + callback() + row++ + col = 0 +} + +//fun TableBuilder.td(colspan: Int = 1, rowspan: Int = 1, callback: TableBuilder.() -> Unit) { +// GridConstraints() +//} + +fun TableBuilder.td( + component: Component, colspan: Int = 1, rowspan: Int = 1, + fill: TdFill? = null, + anchor: TdAlign? = null, + hpolicy: TdSize? = null, + vpolicy: TdSize? = null, + minWidth: Int? = null, + maxWidth: Int? = null, + minHeight: Int? = null, + maxHeight: Int? = null +) { + items[TdPos(col, row)] = Pair( + component, GridConstraints( + row, col, + rowspan, colspan, + (anchor ?: this.anchor).value, + (fill ?: this.fill).value, + (hpolicy ?: this.hpolicy).value, + (vpolicy ?: this.vpolicy).value, + Dimension((minWidth ?: this.minWidth) ?: -1, (minHeight ?: this.minHeight) ?: -1), + Dimension(-1, -1), + Dimension((maxWidth ?: this.maxWidth) ?: -1, (maxHeight ?: this.maxHeight) ?: -1), + 0, + false + ) + ) + col++ +} + +enum class TdFill(val value: Int) { + NONE(GridConstraints.FILL_NONE), + HORIZONTAL(GridConstraints.FILL_HORIZONTAL), + VERTICAL(GridConstraints.FILL_VERTICAL), + BOTH(GridConstraints.FILL_BOTH) +} + +enum class TdAlign(val value: Int) { + TOP_LEFT(GridConstraints.ANCHOR_NORTHWEST), + TOP_CENTER(GridConstraints.ANCHOR_NORTH), + TOP_RIGHT(GridConstraints.ANCHOR_NORTHEAST), + + CENTER_LEFT(GridConstraints.ANCHOR_WEST), + CENTER_CENTER(GridConstraints.ANCHOR_CENTER), + CENTER_RIGHT(GridConstraints.ANCHOR_EAST), + + BOTTOM_LEFT(GridConstraints.ANCHOR_SOUTHWEST), + BOTTOM_CENTER(GridConstraints.ANCHOR_SOUTH), + BOTTOM_RIGHT(GridConstraints.ANCHOR_SOUTHEAST), +} + +enum class TdSize(val value: Int) { + FIXED(GridConstraints.SIZEPOLICY_FIXED), + CAN_SHRINK(GridConstraints.SIZEPOLICY_CAN_SHRINK), + CAN_GROW(GridConstraints.SIZEPOLICY_CAN_GROW), + CAN_SHRINK_GROW(GridConstraints.SIZEPOLICY_CAN_SHRINK or GridConstraints.SIZEPOLICY_CAN_SHRINK), + WANT_GROW(GridConstraints.SIZEPOLICY_WANT_GROW), +} + +val JComboBox.items get() = (0 until this.itemCount).map { getItemAt(it) } + +/** + * API from: https://github.com/ktorio/ktor-init-tools/blob/master/ktor-intellij-plugin/src/io/ktor/start/intellij/util/Utils.kt + */ + +fun JPanel.addAtGrid( + item: JComponent, + row: Int, column: Int, + rowSpan: Int = 1, colSpan: Int = 1, + anchor: Int = GridConstraints.ANCHOR_CENTER, + fill: Int = GridConstraints.FILL_NONE, + HSizePolicy: Int = GridConstraints.SIZEPOLICY_CAN_GROW or GridConstraints.SIZEPOLICY_CAN_SHRINK, + VSizePolicy: Int = GridConstraints.SIZEPOLICY_CAN_GROW or GridConstraints.SIZEPOLICY_CAN_SHRINK, + minimumSize: Dimension = Dimension(-1, -1), + preferredSize: Dimension = Dimension(-1, -1), + maximumSize: Dimension = Dimension(-1, -1) +) { + add( + item, + GridConstraints( + row, + column, + rowSpan, + colSpan, + anchor, + fill, + HSizePolicy, + VSizePolicy, + minimumSize, + preferredSize, + maximumSize + ) + ) +} + +fun Component.scrollVertical() = ScrollPaneFactory.createScrollPane( + this, + JBScrollPane.VERTICAL_SCROLLBAR_ALWAYS, + JBScrollPane.HORIZONTAL_SCROLLBAR_NEVER +) \ No newline at end of file diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 2b50ffb..55dbf7c 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -1,6 +1,6 @@ - tech.carcadex.kotlinbukkitkit.tooling.menu - KBK-Menu-Preview Bukkit + tech.carcadex.kotlinbukkitkit.tooling + KotlinBukkitKit Tooling Denis Istratov