1+ @file:Suppress(" UnstableApiUsage" )
2+
13package com.programmersbox.fullmultiplatformcompose
24
5+ import com.intellij.ide.fileTemplates.FileTemplateManager
36import com.intellij.ide.projectWizard.ProjectSettingsStep
4- import com.intellij.ide.util.projectWizard.ModuleBuilder
7+ import com.intellij.ide.starters.local.*
8+ import com.intellij.ide.starters.local.wizard.StarterInitialStep
9+ import com.intellij.ide.starters.shared.KOTLIN_STARTER_LANGUAGE
10+ import com.intellij.ide.starters.shared.StarterLanguage
11+ import com.intellij.ide.starters.shared.StarterProjectType
512import com.intellij.ide.util.projectWizard.ModuleWizardStep
6- import com.intellij.ide.util.projectWizard.SettingsStep
713import com.intellij.ide.util.projectWizard.WizardContext
8- import com.intellij.openapi.Disposable
9- import com.intellij.openapi.application.ApplicationManager
1014import com.intellij.openapi.module.ModuleType
1115import com.intellij.openapi.project.Project
12- import com.intellij.openapi.roots.ModifiableRootModel
16+ import com.intellij.openapi.project.ProjectManager
1317import com.intellij.openapi.roots.ui.configuration.ModulesProvider
1418import com.intellij.openapi.util.io.FileUtil
1519import com.intellij.openapi.vfs.LocalFileSystem
1620import com.intellij.openapi.vfs.VirtualFile
17- import com.intellij.psi.PsiManager
21+ import com.intellij.pom.java.LanguageLevel
1822import com.intellij.psi.codeStyle.CodeStyleManager
19- import com.intellij.psi.impl.file.PsiDirectoryFactory
20- import com.intellij.ui.components.Link
23+ import com.intellij.util.lang.JavaVersion
2124import com.programmersbox.fullmultiplatformcompose.generators.CommonGenerator
25+ import com.programmersbox.fullmultiplatformcompose.generators.PACKAGE_NAME
26+ import com.programmersbox.fullmultiplatformcompose.generators.SHARED_NAME
27+ import com.programmersbox.fullmultiplatformcompose.steps.ComposeStarterStep
2228import com.programmersbox.fullmultiplatformcompose.steps.PlatformOptionsStep
2329import com.programmersbox.fullmultiplatformcompose.utils.NetworkVersions
24- import com.programmersbox.fullmultiplatformcompose.utils.backgroundTask
25- import com.programmersbox.fullmultiplatformcompose.utils.runGradle
30+ import kotlinx.coroutines.runBlocking
31+ import org.jetbrains.kotlin.idea.KotlinIcons
2632import org.jetbrains.kotlin.idea.core.util.toPsiFile
27- import org.jetbrains.plugins.gradle.service.project.open.linkAndRefreshGradleProject
28- import org.jetbrains.skiko.OS
29- import org.jetbrains.skiko.hostOs
30- import java.awt.Desktop
31- import java.awt.event.ItemEvent
3233import java.io.File
33- import java.net.URI
34- import javax.swing.JCheckBox
35- import javax.swing.JLabel
36- import javax.swing.JSeparator
34+ import javax.swing.Icon
3735
38- class BuilderWizardBuilder : ModuleBuilder () {
36+ /* *
37+ * Following https://github.com/JetBrains/intellij-community/blob/master/plugins/kotlin/project-wizard/compose/src/org/jetbrains/kotlin/tools/composeProjectWizard/ComposeModuleBuilder.kt
38+ */
39+ class BuilderWizardBuilder : StarterModuleBuilder () {
3940 val params = BuilderParams ()
4041
4142 override fun getModuleType (): ModuleType <* > = BuilderModuleType ()
43+ override fun getNodeIcon (): Icon = KotlinIcons .Wizard .MULTIPLATFORM
44+
45+ override fun getPresentableName (): String = " Full Multiplatform Compose"
46+
47+ override fun getProjectTypes (): List <StarterProjectType > = emptyList()
48+
49+ override fun getMinJavaVersion (): JavaVersion = LanguageLevel .JDK_11 .toJavaVersion()
50+
51+ override fun getStarterPack (): StarterPack = StarterPack (
52+ " compose" ,
53+ listOf (
54+ Starter (" compose" , " Compose" , getDependencyConfig(" /starters/compose.pom" ), emptyList())
55+ )
56+ )
4257
43- override fun setupRootModel (modifiableRootModel : ModifiableRootModel ) {
58+ /* override fun setupRootModel(modifiableRootModel: ModifiableRootModel) {
4459 val root = createAndGetRoot() ?: return
4560 modifiableRootModel.addContentEntry(root)
4661 modifiableRootModel.sdk = moduleJdk
@@ -69,14 +84,9 @@ class BuilderWizardBuilder : ModuleBuilder() {
6984 )
7085
7186 formatCode(modifiableRootModel.project, root)
72-
73- /* BuilderConfigurationFactory.createConfigurations(
74- modifiableRootModel.project,
75- params
76- )*/
7787 }
7888 }
79- }
89+ }*/
8090
8191 private fun formatCode (project : Project , root : VirtualFile ) {
8292 val csm = CodeStyleManager .getInstance(project)
@@ -91,73 +101,85 @@ class BuilderWizardBuilder : ModuleBuilder() {
91101 return LocalFileSystem .getInstance().refreshAndFindFileByPath(File (path).apply { mkdirs() }.absolutePath)
92102 }
93103
94- private fun installGradleWrapper (project : Project ) {
95- project.runGradle(" wrapper --gradle-version 7.5.1 --distribution-type all" )
96- }
97-
98- override fun getCustomOptionsStep (context : WizardContext ? , parentDisposable : Disposable ? ): ModuleWizardStep {
99- return ProjectSettingsStep (context)
104+ override fun createOptionsStep (contextProvider : StarterContextProvider ): StarterInitialStep {
105+ return ComposeStarterStep (this , params, contextProvider)
100106 }
101107
102108 override fun createWizardSteps (
103- wizardContext : WizardContext ,
104- modulesProvider : ModulesProvider
109+ context : WizardContext ,
110+ modulesProvider : ModulesProvider ,
105111 ): Array <ModuleWizardStep > {
106112 return arrayOf(
107113 PlatformOptionsStep (this ),
108114 )
109115 }
110116
111- override fun modifySettingsStep (settingsStep : SettingsStep ): ModuleWizardStep ? {
112- settingsStep.addCheckboxItem(" Include Android" , params.hasAndroid) { params.hasAndroid = it }
113- if (hostOs == OS .MacOS ) {
114- settingsStep.addCheckboxItem(" Include iOS" , params.hasiOS) { params.hasiOS = it }
115- }
116- settingsStep.addCheckboxItem(" Include Desktop" , params.hasDesktop) { params.hasDesktop = it }
117- settingsStep.addCheckboxItem(" Include Web" , params.hasWeb) { params.hasWeb = it }
118- settingsStep.addDivider()
119- settingsStep.addCheckboxItem(" Use Material 3" , params.compose.useMaterial3) { params.compose.useMaterial3 = it }
117+ override fun getAssets (starter : Starter ): List <GeneratorAsset > {
118+ val ftManager = FileTemplateManager .getInstance(ProjectManager .getInstance().defaultProject)
119+ val standardAssetsProvider = StandardAssetsProvider ()
120120
121- settingsStep.addDivider()
121+ return mutableListOf<GeneratorAsset >().apply {
122+ val packageName = starterContext.group.split(" ." ).joinToString(" /" )
122123
123- settingsStep.addCheckboxItem(" Use Koin for Dependency Injection" , params.library.useKoin) { params.library.useKoin = it }
124- settingsStep.addCheckboxItem(" Use Ktor for HTTP client apps" , params.library.useKtor) { params.library.useKtor = it }
124+ operator fun GeneratorAsset.unaryPlus () = add(this )
125125
126- settingsStep.addDivider( )
126+ addAll(standardAssetsProvider.getGradlewAssets() )
127127
128- settingsStep.addCheckboxItem(
129- " Get latest library versions from remote source?" ,
130- params.remoteVersions
131- ) { params.remoteVersions = it }
132- settingsStep.addSettingsField(" " , JLabel ().apply { text = " The source is from this plugin's GitHub Repo." })
133-
134- settingsStep.addExpertField(
135- " GitHub:" ,
136- Link (NetworkVersions .githubRepoUrl) { Desktop .getDesktop().browse(URI (NetworkVersions .githubRepoUrl)) }
137- )
128+ if (starterContext.isCreatingNewProject) {
129+ addAll(standardAssetsProvider.getGradleIgnoreAssets())
130+ }
138131
139- return super .modifySettingsStep(settingsStep)
132+ CommonGenerator (params, starterContext).generate(this , ftManager, packageName)
133+ }
140134 }
141135
142- private fun SettingsStep.addDivider () = addSettingsField(" " , JSeparator ())
143-
144- private fun SettingsStep.addCheckboxItem (
145- label : String ,
146- isChecked : Boolean ,
147- selectedChangeListener : (Boolean ) -> Unit
148- ) {
149- addSettingsField(
150- " " ,
151- JCheckBox ().apply {
152- text = label
153- isSelected = isChecked
154- addItemListener { selectedChangeListener(it.stateChange == ItemEvent .SELECTED ) }
155- }
136+ override fun getTemplateProperties (): Map <String , Any > {
137+ val versions = runBlocking { NetworkVersions ().getVersions(params.remoteVersions) }
138+ val sanitizedPackageName = sanitizePackage(starterContext.artifact)
139+ return mapOf (
140+ PACKAGE_NAME to starterContext.group,
141+ SHARED_NAME to params.sharedName,
142+ " APP_NAME" to starterContext.artifact,
143+ params.hasAndroid(),
144+ params.hasDesktop(),
145+ params.hasIOS(),
146+ params.hasWeb(),
147+ " USE_MATERIAL3" to params.compose.useMaterial3,
148+ " COMPOSE" to versions.composeVersion,
149+ " KOTLIN" to versions.kotlinVersion,
150+ " AGP" to versions.agpVersion,
151+ " KTOR" to versions.ktor,
152+ " KOIN" to versions.koin,
153+ " androidxAppCompat" to versions.androidxAppCompat,
154+ " androidxCore" to versions.androidxCore,
155+ " LAST_PACKAGE_NAME" to sanitizedPackageName,
156+ " MINSDK" to params.android.minimumSdk,
157+ " USE_KTOR" to params.library.useKtor,
158+ " USE_KOIN" to params.library.useKoin,
156159 )
157160 }
158161
162+ override fun getBuilderId (): String = BuilderModuleType .ID
163+
164+ override fun getDescription (): String = """
165+ A project wizard to create a compose multiplatform application in your choice of android, ios, web,
166+ and/or desktop!
167+ """ .trimIndent()
168+
159169 override fun getIgnoredSteps (): MutableList <Class <out ModuleWizardStep >> {
160170 return mutableListOf (ProjectSettingsStep ::class .java)
161171 }
162172
163- }
173+ override fun getLanguages (): List <StarterLanguage > = listOf (KOTLIN_STARTER_LANGUAGE )
174+
175+ override fun setupModule (module : com.intellij.openapi.module.Module ) {
176+ starterContext.starter = starterContext.starterPack.starters.first()
177+ starterContext.starterDependencyConfig = loadDependencyConfig()[starterContext.starter?.id]
178+ super .setupModule(module)
179+ }
180+ }
181+
182+ private fun BuilderParams.hasAndroid () = " HAS_ANDROID" to hasAndroid
183+ private fun BuilderParams.hasIOS () = " HAS_IOS" to hasiOS
184+ private fun BuilderParams.hasWeb () = " HAS_WEB" to hasWeb
185+ private fun BuilderParams.hasDesktop () = " HAS_DESKTOP" to hasDesktop
0 commit comments