IFT-394 Rework promoter, so it can be used in non-empty case

And fix double scaling in empty borders

IJ-CR-28024

GitOrigin-RevId: eb91b5485533fc9024354d8872c334ee6408a7c9
This commit is contained in:
Alexey Merkulov
2022-08-01 21:03:34 +02:00
committed by intellij-monorepo-bot
parent 777cd13006
commit 0f512c103e
8 changed files with 69 additions and 41 deletions

View File

@@ -6,7 +6,6 @@ import com.intellij.openapi.application.ApplicationNamesInfo
import com.intellij.openapi.util.IconLoader
import training.ui.welcomeScreen.OnboardingLessonPromoter
import javax.swing.Icon
import javax.swing.JPanel
class JavaOnboardingTourPromoter : OnboardingLessonPromoter(
"java.onboarding", JavaLessonsBundle.message("java.onboarding.lesson.name"), "Java"
@@ -14,10 +13,6 @@ class JavaOnboardingTourPromoter : OnboardingLessonPromoter(
override val promoImage: Icon
get() = IconLoader.getIcon("img/idea-onboarding-tour.png", JavaOnboardingTourPromoter::class.java.classLoader)
override fun getPromotionForInitialState(): JPanel? {
if (ApplicationNamesInfo.getInstance().fullProductNameWithEdition.equals("IDEA Edu")) {
return null
}
return super.getPromotionForInitialState()
}
override fun canCreatePromo(isEmptyState: Boolean): Boolean =
super.canCreatePromo(isEmptyState) && !ApplicationNamesInfo.getInstance().fullProductNameWithEdition.equals("IDEA Edu")
}

View File

@@ -21,9 +21,8 @@ import java.awt.event.ActionEvent
import javax.swing.*
abstract class BannerStartPagePromoter : StartPagePromoter {
override fun getPromotionForInitialState(): JPanel? {
val rPanel: JPanel = NonOpaquePanel()
rPanel.border = JBUI.Borders.empty(JBUI.scale(10), JBUI.scale(16))
override fun getPromotion(isEmptyState: Boolean): JPanel? {
if (!canCreatePromo(isEmptyState)) return null
val vPanel: JPanel = NonOpaquePanel()
vPanel.layout = BoxLayout(vPanel, BoxLayout.PAGE_AXIS)
@@ -39,10 +38,12 @@ abstract class BannerStartPagePromoter : StartPagePromoter {
headerPanel.add(header)
headerPanel.add(Box.createHorizontalGlue())
val hPanel: JPanel = BackgroundRoundedPanel(JBUI.scale(16))
closeAction?.let { closeAction ->
val closeIcons = IconButton(null, AllIcons.Actions.Close, AllIcons.Actions.CloseDarkGrey)
val closeButton = InplaceButton(closeIcons) {
closeAction(rPanel)
closeAction(hPanel)
}
closeButton.maximumSize = Dimension(16, 16)
headerPanel.add(closeButton)
@@ -72,18 +73,16 @@ abstract class BannerStartPagePromoter : StartPagePromoter {
vPanel.add(Box.createVerticalGlue())
vPanel.add(buttonPixelHunting(jButton))
val hPanel: JPanel = BackgroundRoundedPanel(JBUI.scale(16))
hPanel.background = JBColor.namedColor("WelcomeScreen.SidePanel.background", JBColor(0xF2F2F2, 0x3C3F41))
hPanel.layout = BoxLayout(hPanel, BoxLayout.X_AXIS)
hPanel.border = JBUI.Borders.empty(JBUI.scale(12), JBUI.scale(16), JBUI.scale(16), JBUI.scale(16))
hPanel.border = JBUI.Borders.empty(12, 16, 16, 16)
val picture = JLabel(promoImage)
picture.alignmentY = Component.TOP_ALIGNMENT
hPanel.add(picture)
hPanel.add(rigid(20, 0))
hPanel.add(vPanel)
rPanel.add(hPanel)
return rPanel
return hPanel
}
private fun buttonPixelHunting(button: JButton): JPanel {
@@ -125,4 +124,5 @@ abstract class BannerStartPagePromoter : StartPagePromoter {
protected open val closeAction: ((promoPanel: JPanel) -> Unit)? = null
protected abstract fun runAction()
protected open fun canCreatePromo(isEmptyState: Boolean): Boolean = isEmptyState
}

View File

@@ -12,5 +12,5 @@ interface StartPagePromoter {
val START_PAGE_PROMOTER_EP = ExtensionPointName<StartPagePromoter>("com.intellij.startPagePromoter")
}
fun getPromotionForInitialState(): JPanel?
fun getPromotion(isEmptyState: Boolean): JPanel?
}

View File

@@ -11,7 +11,6 @@ import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.NlsContexts;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.StartPagePromoter;
import com.intellij.ui.components.AnActionLink;
import com.intellij.ui.components.DropDownLink;
import com.intellij.ui.components.JBLabel;
@@ -131,17 +130,18 @@ final class EmptyStateProjectsPanel extends BorderLayoutPanel {
private static JPanel createBottomPanelForEmptyState(@NotNull Disposable parentDisposable) {
JPanel vPanel = new NonOpaquePanel();
vPanel.setLayout(new BoxLayout(vPanel, BoxLayout.PAGE_AXIS));
StartPagePromoter[] extensions = StartPagePromoter.START_PAGE_PROMOTER_EP.getExtensions();
boolean hasPromotion = false;
for (StartPagePromoter x : extensions) {
JPanel promotion = x.getPromotionForInitialState();
if (promotion == null) continue;
vPanel.add(promotion);
hasPromotion = true;
}
JPanel promoPanel = WelcomeScreenComponentFactory.getSinglePromotion(true);
JPanel notification = WelcomeScreenComponentFactory.createNotificationPanel(parentDisposable);
if (!hasPromotion) return notification;
vPanel.add(notification);
return vPanel;
if (promoPanel == null) {
return notification;
}
else {
vPanel.add(notification);
JPanel borderPanel = new NonOpaquePanel();
borderPanel.setBorder(JBUI.Borders.empty(8, 16, 16, 16));
borderPanel.add(promoPanel);
vPanel.add(borderPanel);
return vPanel;
}
}
}

View File

@@ -29,6 +29,7 @@ import com.intellij.openapi.wm.impl.welcomeScreen.recentProjects.ProjectCollecto
import com.intellij.openapi.wm.impl.welcomeScreen.recentProjects.RecentProjectPanelComponentFactory.createComponent
import com.intellij.ui.ScrollPaneFactory
import com.intellij.ui.border.CustomLineBorder
import com.intellij.ui.components.panels.NonOpaquePanel
import com.intellij.ui.components.panels.Wrapper
import com.intellij.util.PlatformUtils
import com.intellij.util.containers.ContainerUtil
@@ -39,6 +40,7 @@ import java.awt.Component
import java.awt.Dimension
import java.awt.Insets
import java.io.File
import javax.swing.BoxLayout
import javax.swing.JComponent
import javax.swing.JPanel
import javax.swing.ScrollPaneConstants
@@ -141,7 +143,23 @@ class ProjectsTab(private val parentDisposable: Disposable) :
northPanel.add(projectActionsPanel, BorderLayout.EAST)
recentProjectsPanel.add(northPanel, BorderLayout.NORTH)
recentProjectsPanel.add(projectsPanel, BorderLayout.CENTER)
recentProjectsPanel.add(WelcomeScreenComponentFactory.createNotificationPanel(parentDisposable), BorderLayout.SOUTH)
val notificationPanel = WelcomeScreenComponentFactory.createNotificationPanel(parentDisposable)
val promoPanel = WelcomeScreenComponentFactory.getSinglePromotion(false)
if (promoPanel != null) {
val southPanel: JPanel = NonOpaquePanel()
southPanel.layout = BoxLayout(southPanel, BoxLayout.Y_AXIS)
southPanel.add(notificationPanel)
val borderPanel: JPanel = NonOpaquePanel()
borderPanel.border = JBUI.Borders.empty(8, 4, 3, 4)
borderPanel.add(promoPanel)
southPanel.add(borderPanel)
recentProjectsPanel.add(southPanel, BorderLayout.SOUTH)
} else {
recentProjectsPanel.add(notificationPanel, BorderLayout.SOUTH)
}
initDnD(treeComponent)
return recentProjectsPanel
}

View File

@@ -15,12 +15,14 @@ import com.intellij.openapi.actionSystem.impl.MenuItemPresentationFactory;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.StartPagePromoter;
import com.intellij.openapi.wm.impl.ProjectFrameHelper;
import com.intellij.ui.BalloonLayout;
import com.intellij.ui.ClickListener;
@@ -334,4 +336,19 @@ public final class WelcomeScreenComponentFactory {
panel.add(createEventLink("", parentDisposable));
return panel;
}
@Nullable
static JPanel getSinglePromotion(boolean isEmptyState) {
StartPagePromoter[] extensions = StartPagePromoter.START_PAGE_PROMOTER_EP.getExtensions();
JPanel result = null;
for (StartPagePromoter promoter : extensions) {
JPanel content = promoter.getPromotion(isEmptyState);
if (content == null) continue;
if (result != null) {
Logger.getInstance(WelcomeScreenComponentFactory.class).error("Several welcome screen promotions are found.");
}
result = content;
}
return result;
}
}

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package training.ui.welcomeScreen
import com.intellij.ide.RecentProjectsManagerBase
import com.intellij.ide.util.PropertiesComponent
import com.intellij.idea.ActionsBundle
import com.intellij.openapi.application.invokeLater
@@ -37,13 +38,13 @@ open class OnboardingLessonPromoter(@NonNls private val lessonId: String,
override val promoImage: Icon
get() = FeaturesTrainerIcons.Img.PluginIcon
override fun getPromotionForInitialState(): JPanel? {
override fun getPromotion(isEmptyState: Boolean): JPanel? {
scheduleOnboardingFeedback()
if (PropertiesComponent.getInstance().getBoolean(PROMO_HIDDEN, false)) {
return null
}
return super.getPromotionForInitialState()
return super.getPromotion(isEmptyState)
}
override fun canCreatePromo(isEmptyState: Boolean): Boolean =
!PropertiesComponent.getInstance().getBoolean(PROMO_HIDDEN, false) &&
RecentProjectsManagerBase.getInstanceEx().getRecentPaths().size < 5
override val headerLabel: String
get() = LearnBundle.message("welcome.promo.header")
@@ -87,6 +88,8 @@ open class OnboardingLessonPromoter(@NonNls private val lessonId: String,
override val closeAction: ((JPanel) -> Unit) = { promoPanel ->
PropertiesComponent.getInstance().setValue(PROMO_HIDDEN, true)
promoPanel.removeAll()
promoPanel.border = JBUI.Borders.empty(0, 2, 0, 0)
promoPanel.isOpaque = false
val text = LearnBundle.message("welcome.promo.close.hint",
ActionsBundle.message("group.HelpMenu.text").dropMnemonic(),
LearnBundle.message("action.ShowLearnPanel.text"), lessonName)

View File

@@ -6,7 +6,6 @@ import com.intellij.openapi.util.IconLoader
import com.jetbrains.python.ift.PythonLessonsBundle
import training.ui.welcomeScreen.OnboardingLessonPromoter
import javax.swing.Icon
import javax.swing.JPanel
internal class PyOnboardingTourPromoter : OnboardingLessonPromoter(
"python.onboarding", PythonLessonsBundle.message("python.onboarding.lesson.name"), "Python"
@@ -14,10 +13,6 @@ internal class PyOnboardingTourPromoter : OnboardingLessonPromoter(
override val promoImage: Icon
get() = IconLoader.getIcon("img/pycharm-onboarding-tour.png", PyOnboardingTourPromoter::class.java.classLoader)
override fun getPromotionForInitialState(): JPanel? {
if (ApplicationNamesInfo.getInstance().fullProductNameWithEdition.equals("PyCharm Edu")) {
return null
}
return super.getPromotionForInitialState()
}
override fun canCreatePromo(isEmptyState: Boolean): Boolean =
super.canCreatePromo(isEmptyState) && !ApplicationNamesInfo.getInstance().fullProductNameWithEdition.equals("PyCharm Edu")
}