IFT-525 Add Java or Kotlin onboarding tour promoter

Created the separate `intellij.kotlin.onboarding-promoter` module for the promoter extension.
This module is not bundled to Kotlin plugin because the promoter should be present only in IDEA Community/Ultimate (when Kotlin and Features Trainer plugins are enabled).
The name of this module is prefixed by `intellij`, because otherwise `KotlinModuleConsistencyTest` will fail. Also, there will be a lot of failed tests because this module won't be loaded in `ClassPathXmlPathResolver.resolveModuleFile` (`intellij` prefixed module descriptors can be missed when loading, by `kotlin` is not).

GitOrigin-RevId: 4b81ff2bfc0b60148e8b91fd35539edd113ab787
This commit is contained in:
Konstantin Hudyakov
2023-11-29 11:39:58 +02:00
committed by intellij-monorepo-bot
parent 4798cf5858
commit 228b04489b
12 changed files with 108 additions and 16 deletions

1
.idea/modules.xml generated
View File

@@ -845,6 +845,7 @@
<module fileurl="file://$PROJECT_DIR$/plugins/devkit/intellij.kotlin.devkit/intellij.kotlin.devkit.iml" filepath="$PROJECT_DIR$/plugins/devkit/intellij.kotlin.devkit/intellij.kotlin.devkit.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/kotlin/gradle/multiplatform-tests-k2/intellij.kotlin.gradle.multiplatform-tests-k2.iml" filepath="$PROJECT_DIR$/plugins/kotlin/gradle/multiplatform-tests-k2/intellij.kotlin.gradle.multiplatform-tests-k2.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/kotlin/gradle/multiplatform-tests/intellij.kotlin.gradle.multiplatformTests.iml" filepath="$PROJECT_DIR$/plugins/kotlin/gradle/multiplatform-tests/intellij.kotlin.gradle.multiplatformTests.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/kotlin/onboarding-promoter/intellij.kotlin.onboarding-promoter.iml" filepath="$PROJECT_DIR$/plugins/kotlin/onboarding-promoter/intellij.kotlin.onboarding-promoter.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/kotlin/intellij.kotlin.plugin.community.main.iml" filepath="$PROJECT_DIR$/plugins/kotlin/intellij.kotlin.plugin.community.main.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/laf/macos/intellij.laf.macos.iml" filepath="$PROJECT_DIR$/plugins/laf/macos/intellij.laf.macos.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/laf/win10/intellij.laf.win10.iml" filepath="$PROJECT_DIR$/plugins/laf/win10/intellij.laf.win10.iml" />

View File

@@ -15,6 +15,7 @@
<module name="intellij.platform.ide.newUiOnboarding"/>
<module name="intellij.platform.ml.embeddings"/>
<module name="intellij.ide.startup.importSettings"/>
<module name="intellij.kotlin.onboarding-promoter"/>
</content>
<extensions defaultExtensionNs="com.intellij">

View File

@@ -210,5 +210,6 @@
<orderEntry type="module" module-name="intellij.jsonpath" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.ide.newUiOnboarding" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.platform.compose" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.kotlin.onboarding-promoter" scope="RUNTIME" />
</component>
</module>

View File

@@ -2,6 +2,7 @@
package com.intellij.ide.java.training
import com.intellij.java.ift.JavaLessonsBundle
import com.intellij.java.ift.javaLanguageId
import com.intellij.java.ift.lesson.essential.ideaOnboardingLessonId
import com.intellij.openapi.util.IconLoader
import com.intellij.util.PlatformUtils
@@ -9,7 +10,7 @@ import training.ui.welcomeScreen.OnboardingLessonPromoter
import javax.swing.Icon
class JavaOnboardingTourPromoter : OnboardingLessonPromoter(
ideaOnboardingLessonId, "JAVA", JavaLessonsBundle.message("java.onboarding.lesson.name")
ideaOnboardingLessonId, javaLanguageId, JavaLessonsBundle.message("java.onboarding.lesson.name")
) {
override val promoImage: Icon
get() = IconLoader.getIcon("img/idea-onboarding-tour.png", JavaLessonsBundle::class.java.classLoader)

View File

@@ -19,11 +19,14 @@ import training.ui.LearningUiUtil
import training.util.getFeedbackLink
import javax.swing.JList
/** should be the same as in the [JavaLangSupport] bean declaration in the plugin XML */
const val javaLanguageId: String = "JAVA"
internal class JavaLangSupport : JavaBasedLangSupport() {
override val contentRootDirectoryName: String = "IdeaLearningProject"
override val projectResourcePath: String = "learnProjects/java/LearnProject"
override val primaryLanguage: String = "JAVA"
override val primaryLanguage: String = javaLanguageId
override val defaultProductName: String = "IDEA"

View File

@@ -56,18 +56,12 @@ abstract class BannerStartPagePromoter : StartPagePromoter {
it.foreground = UIUtil.getContextHelpForeground()
}
vPanel.add(description)
val jButton = JButton()
jButton.isOpaque = false
jButton.alignmentX = Component.LEFT_ALIGNMENT
jButton.action = object : AbstractAction(actionLabel) {
override fun actionPerformed(e: ActionEvent?) {
runAction()
}
}
val button = createButton()
val minSize = JBDimension(0, 8)
vPanel.add(Box.Filler(minSize, minSize, Dimension(0, Short.MAX_VALUE.toInt())))
vPanel.add(buttonPixelHunting(jButton))
vPanel.add(buttonPixelHunting(button))
hPanel.background = JBColor.namedColor("WelcomeScreen.SidePanel.background", JBColor(0xF2F2F2, 0x3C3F41))
hPanel.layout = BoxLayout(hPanel, BoxLayout.X_AXIS)
@@ -81,7 +75,7 @@ abstract class BannerStartPagePromoter : StartPagePromoter {
return hPanel
}
private fun buttonPixelHunting(button: JButton): JPanel {
private fun buttonPixelHunting(button: JComponent): JPanel {
val buttonPlace = object: JPanel() {
override fun updateUI() {
super.updateUI()
@@ -134,4 +128,16 @@ abstract class BannerStartPagePromoter : StartPagePromoter {
result.font = JBFont.create(labelFont).deriveFont(Font.BOLD).deriveFont(labelFont.size2D + JBUI.scale(2))
return result
}
protected open fun createButton(): JComponent {
val jButton = JButton()
jButton.isOpaque = false
jButton.alignmentX = Component.LEFT_ALIGNMENT
jButton.action = object : AbstractAction(actionLabel) {
override fun actionPerformed(e: ActionEvent?) {
runAction()
}
}
return jButton
}
}

View File

@@ -33,7 +33,7 @@ private const val PROMO_HIDDEN = "ift.hide.welcome.screen.promo"
/** Do not use lesson itself in the parameters to postpone IFT modules/lessons initialization */
@ApiStatus.Internal
open class OnboardingLessonPromoter(@NonNls private val lessonId: String,
open class OnboardingLessonPromoter(@NonNls protected val lessonId: String,
@NonNls private val languageId: String,
@Nls private val lessonName: String) : BannerStartPagePromoter() {
override val promoImage: Icon
@@ -55,12 +55,12 @@ open class OnboardingLessonPromoter(@NonNls private val lessonId: String,
get() = LearnBundle.message("welcome.promo.start.tour")
override fun runAction() =
startOnboardingLessonWithSdk()
startOnboardingLessonWithSdk(lessonId, languageId)
override val description: String
get() = LearnBundle.message("welcome.promo.description", LessonUtil.productName)
private fun startOnboardingLessonWithSdk() {
protected fun startOnboardingLessonWithSdk(lessonId: String, languageId: String) {
resetPrimaryLanguage(languageId)
val lesson = CourseManager.instance.lessonsForModules.find { it.id == lessonId }
if (lesson == null) {

View File

@@ -1,5 +1,8 @@
configure.kotlin.progress.title=Configure Kotlin
welcome.promo.start.tour.java=Start Tour in Java
welcome.promo.start.tour.kotlin=Start Tour in Kotlin
kotlin.onboarding.invoke.intention.for.warning.1=You have just fixed a bug, but you can make this code look even better. \
IDEA highlights and adds a yellow bulb to the code lines that can be improved.
kotlin.onboarding.invoke.intention.for.warning.2=Press {0} to preview the warnings and apply a quick-fix.

View File

@@ -15,11 +15,14 @@ import org.jetbrains.kotlin.idea.formatter.ProjectCodeStyleImporter
import org.jetbrains.kotlin.idea.framework.KotlinSdkType
import java.nio.file.Path
/** should be the same as in the [KotlinLangSupport] bean declaration in the plugin XML */
const val kotlinLanguageId: String = "kotlin"
class KotlinLangSupport : JavaBasedLangSupport() {
override val contentRootDirectoryName = "KotlinLearningProject"
override val defaultProductName: String = "IDEA"
override val primaryLanguage: String = "kotlin"
override val primaryLanguage: String = kotlinLanguageId
override val scratchFileName: String = "Learning.kt"
override val sampleFilePath: String = "$sourcesDirectoryPath/Sample.kt"

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="intellij.platform.ide.impl" />
<orderEntry type="module" module-name="intellij.featuresTrainer" />
<orderEntry type="module" module-name="intellij.java.featuresTrainer" />
<orderEntry type="module" module-name="kotlin.features-trainer" />
</component>
</module>

View File

@@ -0,0 +1,11 @@
<idea-plugin package="org.jetbrains.kotlin.training.promoter">
<dependencies>
<plugin id="training"/>
<plugin id="org.jetbrains.kotlin"/>
<module name="kotlin.features-trainer"/>
</dependencies>
<extensions defaultExtensionNs="com.intellij">
<startPagePromoter id="JavaOrKotlinOnboardingTourPromoter"
implementation="org.jetbrains.kotlin.training.promoter.JavaOrKotlinOnboardingTourPromoter"/>
</extensions>
</idea-plugin>

View File

@@ -0,0 +1,46 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.training.promoter
import com.intellij.java.ift.JavaLessonsBundle
import com.intellij.java.ift.javaLanguageId
import com.intellij.java.ift.lesson.essential.ideaOnboardingLessonId
import com.intellij.openapi.util.IconLoader
import com.intellij.openapi.wm.StartPagePromoter
import com.intellij.ui.components.JBOptionButton
import org.jetbrains.annotations.Nls
import org.jetbrains.kotlin.training.ift.KotlinLessonsBundle
import org.jetbrains.kotlin.training.ift.kotlinLanguageId
import training.ui.welcomeScreen.OnboardingLessonPromoter
import java.awt.event.ActionEvent
import javax.swing.AbstractAction
import javax.swing.Icon
import javax.swing.JComponent
class JavaOrKotlinOnboardingTourPromoter : OnboardingLessonPromoter(
ideaOnboardingLessonId, javaLanguageId, JavaLessonsBundle.message("java.onboarding.lesson.name")
) {
// show this promoter instead of Java onboarding tour promoter
override fun getPriorityLevel(): Int = StartPagePromoter.PRIORITY_LEVEL_NORMAL + 10
override val promoImage: Icon
get() = IconLoader.getIcon("img/idea-onboarding-tour.png", JavaLessonsBundle::class.java.classLoader)
override fun createButton(): JComponent {
val javaOnboardingAction = StartOnboardingAction(javaLanguageId, KotlinLessonsBundle.message("welcome.promo.start.tour.java"))
val kotlinOnboardingAction = StartOnboardingAction(kotlinLanguageId, KotlinLessonsBundle.message("welcome.promo.start.tour.kotlin"))
val button = JBOptionButton(javaOnboardingAction, arrayOf(javaOnboardingAction, kotlinOnboardingAction)).also {
it.addSeparator = false
it.showPopupYOffset = 1 // visually, it will be 4, because of the empty 3px bottom border of the button
}
return button
}
private inner class StartOnboardingAction(
private val languageId: String,
name: @Nls String
) : AbstractAction(name) {
override fun actionPerformed(e: ActionEvent?) {
startOnboardingLessonWithSdk(lessonId, languageId)
}
}
}