new project wizard concept

This commit is contained in:
Konstantin Bulenkov
2012-10-18 03:42:44 +02:00
parent 75096effab
commit bc35af6266
26 changed files with 431 additions and 14 deletions
@@ -21,6 +21,7 @@ package com.intellij.ide.impl;
import com.intellij.ide.GeneralSettings;
import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
import com.intellij.ide.util.newProjectWizard.AddModuleWizardPro;
import com.intellij.ide.util.projectWizard.ProjectBuilder;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
@@ -44,6 +45,7 @@ import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.wm.*;
import com.intellij.openapi.wm.ex.WindowManagerEx;
@@ -68,7 +70,9 @@ public class NewProjectUtil {
}
}, ProjectBundle.message("project.new.wizard.progress.title"), true, null);
if (!proceed) return;
final AddModuleWizard dialog = new AddModuleWizard(null, ModulesProvider.EMPTY_MODULES_PROVIDER, defaultPath);
final AddModuleWizard dialog = Registry.is("new.project.wizard")
? new AddModuleWizardPro(null, ModulesProvider.EMPTY_MODULES_PROVIDER, defaultPath)
: new AddModuleWizard(null, ModulesProvider.EMPTY_MODULES_PROVIDER, defaultPath);
dialog.show();
if (!dialog.isOK()) {
return;
@@ -56,7 +56,7 @@ public class AddModuleWizard extends AbstractWizard<ModuleWizardStep> {
private final Project myCurrentProject;
private final ModulesProvider myModulesProvider;
private WizardContext myWizardContext;
private ProjectCreateModeStep myRootStep;
protected ProjectCreateModeStep myRootStep;
/**
@@ -166,7 +166,7 @@ public class AddModuleWizard extends AbstractWizard<ModuleWizardStep> {
super.doOKAction();
}
private boolean commitStepData(final ModuleWizardStep step) {
protected boolean commitStepData(final ModuleWizardStep step) {
try {
if (!step.validate()) {
return false;
@@ -0,0 +1,197 @@
package com.intellij.ide.util.newProjectWizard;
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.ide.wizard.CommitStepException;
import com.intellij.ide.wizard.Step;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.ValidationInfo;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Enumeration;
/**
* @author Konstantin Bulenkov
*/
public class AddModuleWizardPro extends AddModuleWizard {
protected JPanel myStepsPanel;
public AddModuleWizardPro(Project project, @NotNull ModulesProvider modulesProvider, @Nullable String defaultPath) {
super(project, modulesProvider, defaultPath);
getWizardContext().addContextListener(new WizardContext.Listener() {
@Override
public void buttonsUpdateRequested() {
updateStepsPanel();
}
@Override
public void nextStepRequested() {
updateStepsPanel();
}
});
}
@Override
protected void updateButtons() {
super.updateButtons();
if (isLastStep()) {
getNextButton().setText("Done");
}
getPreviousButton().setVisible(false);
getCancelButton().setVisible(false);
}
public AddModuleWizardPro(Component parent, Project project, @NotNull ModulesProvider modulesProvider) {
super(parent, project, modulesProvider);
}
@Override
protected void createDefaultActions() {
super.createDefaultActions();
}
@Override
protected JComponent createCenterPanel() {
myStepsPanel = new JPanel() {
@Override
public void addNotify() {
super.addNotify();
getNextStepObject().updateDataModel();
updateStepsPanel();
new AnAction(){
@Override
public void actionPerformed(AnActionEvent e) {
if (!isLastStep()) doNextAction();
}
}.registerCustomShortcutSet(CustomShortcutSet.fromString("control TAB"), getContentPanel(), getDisposable());
new AnAction(){
@Override
public void actionPerformed(AnActionEvent e) {
doPreviousAction();
}
}.registerCustomShortcutSet(CustomShortcutSet.fromString("control shift TAB"), getContentPanel(), getDisposable());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
final Component c = getComponent(getComponentCount() - 1);
int y = c.getBounds().y + c.getBounds().height + 4;
g.translate(0, y);
myIcon.paintIcon(g);
g.translate(0, -y);
}
};
myStepsPanel.setLayout(new BoxLayout(myStepsPanel, BoxLayout.Y_AXIS) {
@Override
public void layoutContainer(Container target) {
super.layoutContainer(target);
int maxWidth = -1;
for (Component c : target.getComponents()) {
maxWidth = Math.max(maxWidth, c.getWidth());
}
for (Component c : target.getComponents()) {
final Rectangle b = c.getBounds();
c.setBounds(b.x, b.y, maxWidth, b.height);
}
}
});
myStepsPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 4));
updateStepsPanel();
final JPanel panel = new JPanel(new BorderLayout());
panel.add(myStepsPanel, BorderLayout.WEST);
panel.add(myContentPanel, BorderLayout.CENTER);
return panel;
}
@Override
public void doNextAction() {
super.doNextAction();
updateStepsPanel();
}
@Override
protected void doPreviousAction() {
super.doPreviousAction();
updateStepsPanel();
}
@Nullable
@Override
protected ValidationInfo doValidate() {
final ValidationInfo result = super.doValidate();
updateStepsPanel();
return result;
}
private void updateStepsPanel() {
myStepsPanel.removeAll();
int index = 0;
final ButtonGroup group = new ButtonGroup();
while (index != -1) {
final int ind = index;
final ModuleWizardStep step = mySteps.get(index);
final JRadioButton rb = new JRadioButton(step.getName(), index == myCurrentStep);
rb.setUI(new WizardArrowUI(rb, index < myCurrentStep));
myStepsPanel.add(rb);
group.add(rb);
rb.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final ModuleWizardStep step = getCurrentStepObject();
if (ind > getCurrentStep() && !commitStepData(step)) {
updateStepsPanel();
return;
}
step.onStepLeaving();
// Commit data of current step
final Step currentStep = mySteps.get(myCurrentStep);
try {
currentStep._commit(false);
}
catch (final CommitStepException exc) {
Messages.showErrorDialog(
myContentPanel,
exc.getMessage()
);
return;
}
myCurrentStep = ind;
updateStep();
}
});
final int next = getNextStep(index);
index = index == next ? -1 : next;
}
final Enumeration<AbstractButton> buttons = group.getElements();
while (buttons.hasMoreElements()) {
final JRadioButton b = (JRadioButton)buttons.nextElement();
b.setUI(new WizardArrowUI(b, index < myCurrentStep));
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
myStepsPanel.revalidate();
myStepsPanel.repaint();
}
});
}
}
@@ -30,7 +30,7 @@ import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.DoubleClickListener;
import com.intellij.ui.ClickListener;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -93,11 +93,15 @@ public class ProjectCreateModeStep extends ModuleWizardStep {
setMode(mode);
}
});
new DoubleClickListener() {
new ClickListener() {
@Override
protected boolean onDoubleClick(MouseEvent e) {
wizardContext.requestNextStep();
return true;
public boolean onClick(MouseEvent event, int clickCount) {
if (mode.getAdditionalSettings(wizardContext) == null) {
wizardContext.requestNextStep();
return true;
} else {
return false;
}
}
}.installOn(rb);
@@ -139,6 +143,11 @@ public class ProjectCreateModeStep extends ModuleWizardStep {
return myWizardContext.getStepIcon();
}
@Override
public String getName() {
return myMode.getShortName();
}
public WizardMode getMode() {
return myMode;
}
@@ -467,4 +467,9 @@ public class ProjectNameWithTypeStep extends ProjectNameStep {
myInternalPanel.add(component, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(10, 0, 0, 0), 0, 0));
}
@Override
public String getName() {
return "Name and Type";
}
}
@@ -359,6 +359,11 @@ public class SelectTemplateStep extends ModuleWizardStep {
Disposer.dispose(myBuilder);
}
@Override
public String getName() {
return "Template Type";
}
private void createUIComponents() {
mySearchField = new SearchTextField(false);
}
@@ -400,4 +400,9 @@ public class SourcePathsStep extends AbstractStepWithProgress<List<JavaModuleSou
public String getHelpId() {
return myHelpId;
}
@Override
public String getName() {
return "Path to Sources";
}
}
@@ -87,6 +87,11 @@ public class SupportForFrameworksStep extends ModuleWizardStep {
public void updateDataModel() {
}
@Override
public String getName() {
return "Add Frameworks";
}
private static class FrameworkSupportModelInWizard extends FrameworkSupportModelBase {
private final ModuleBuilder myBuilder;
@@ -0,0 +1,111 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.util.newProjectWizard;
import com.intellij.openapi.ui.GraphicsConfig;
import com.intellij.ui.Gray;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
import sun.swing.SwingUtilities2;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicButtonUI;
import java.awt.*;
import java.awt.geom.GeneralPath;
import java.awt.geom.Path2D;
/**
* @author Konstantin Bulenkov
*/
class WizardArrowUI extends BasicButtonUI {
private final AbstractButton myButton;
private static Rectangle viewRect = new Rectangle();
private static Rectangle textRect = new Rectangle();
private static Rectangle iconRect = new Rectangle();
public WizardArrowUI(AbstractButton b, boolean valid) {
myButton = b;
//b.setIcon(EmptyIcon.create(1));
b.setOpaque(false);
b.setBorder(new EmptyBorder(8, 0, 8, 40));
}
@SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
public static ComponentUI createUI(JComponent c) {
return new WizardArrowUI((AbstractButton)c, false);
}
@Override
protected void paintIcon(Graphics g, JComponent c, Rectangle iconRect) {
}
@Override
protected int getTextShiftOffset() {
return 5;
}
private String layout(AbstractButton b, FontMetrics fm,
int width, int height) {
Insets i = b.getInsets();
viewRect.x = i.left;
viewRect.y = i.top;
viewRect.width = width - (i.right + viewRect.x);
viewRect.height = height - (i.bottom + viewRect.y);
textRect.x = textRect.y = textRect.width = textRect.height = 0;
iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
// layout the text and icon
return SwingUtilities.layoutCompoundLabel(
b, fm, b.getText(), b.getIcon(),
b.getVerticalAlignment(), b.getHorizontalAlignment(),
b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
viewRect, iconRect, textRect,
b.getText() == null ? 0 : b.getIconTextGap());
}
@Override
public void paint(Graphics g, JComponent c) {
int w = c.getWidth();
int h = c.getHeight();
layout(myButton, SwingUtilities2.getFontMetrics(c, g), w, h);
final GraphicsConfig config = GraphicsUtil.setupAAPainting(g);
h-=4;
if (!myButton.isSelected()) {
w-=15;
}
final Path2D.Double path = new GeneralPath.Double();
path.moveTo(0, 0);
path.lineTo(w - h / 2, 0);
path.lineTo(w, h / 2);
path.lineTo(w-h/2, h);
path.lineTo(0, h);
path.lineTo(0, 0);
g.setColor(myButton.isSelected() ? UIUtil.getListSelectionBackground() : Gray._255.withAlpha(200));
((Graphics2D)g).fill(path);
g.setColor(Gray._0.withAlpha(50));
((Graphics2D)g).draw(path);
config.restore();
textRect.x = 2;
textRect.y-=7;
c.setForeground(UIUtil.getListForeground(myButton.isSelected()));
paintText(g, c, textRect, myButton.getText());
}
}
@@ -96,6 +96,11 @@ public class CreateFromScratchMode extends WizardMode {
}
@Override
public String getShortName() {
return "Create from Scratch";
}
public void dispose() {
super.dispose();
myBuildersMap.clear();
@@ -96,6 +96,11 @@ public abstract class CreateFromSourcesMode extends WizardMode {
public void onChosen(final boolean enabled) {
}
@Override
public String getShortName() {
return "Create from Sources";
}
public void dispose() {
myProjectBuilder = null;
super.dispose();
@@ -69,6 +69,11 @@ public class CreateFromTemplateMode extends WizardMode {
return template.createModuleBuilder();
}
@Override
public String getShortName() {
return "Create from Template";
}
@Override
public void onChosen(boolean enabled) {
}
@@ -121,6 +121,11 @@ public class ImportImlMode extends WizardMode {
}
}
@Override
public String getShortName() {
return "Import from *.iml";
}
private static class ModuleFileChooserDescriptor extends FileChooserDescriptor {
public ModuleFileChooserDescriptor() {
super(true, false, false, false, false, false);
@@ -94,4 +94,8 @@ public class ImportMode extends WizardMode {
public void onChosen(final boolean enabled) {}
@Override
public String getShortName() {
return "Import from External Model";
}
}
@@ -74,6 +74,10 @@ public abstract class WizardMode implements Disposable {
myStepSequence = null;
}
public String getShortName() {
return "";
}
@Nullable
public String getFootnote(final WizardContext wizardContext) {
return null;
@@ -99,6 +99,11 @@ public class ProjectJdkStep extends ModuleWizardStep {
return true;
}
@Override
public String getName() {
return "Project JDK";
}
public void disposeUIResources() {
super.disposeUIResources();
myProjectJdksConfigurable.disposeUIResources();
@@ -150,6 +150,11 @@ public class ProjectNameStep extends ModuleWizardStep {
return myNamePathComponent.getNameValue();
}
@Override
public String getName() {
return "Name";
}
public boolean isStepVisible() {
final ProjectBuilder builder = myWizardContext.getProjectBuilder();
if (builder != null && builder.isUpdate()) return false;
@@ -90,6 +90,11 @@ public class ProjectWizardStepFactoryImpl extends ProjectWizardStepFactory {
return icon;
}
@Override
public String getName() {
return "Specify JDK";
}
public String getHelpId() {
return helpId;
}
@@ -127,6 +127,11 @@ public class ImportChooserStep extends ProjectImportWizardStep {
}
}
@Override
public String getName() {
return "Choose External Model";
}
@NonNls
public String getHelpId() {
return "reference.dialogs.new.project.import";
@@ -85,8 +85,9 @@ public class JavaModuleType extends ModuleType<JavaModuleBuilder> {
steps.add(wizardFactory.createProjectJdkStep(wizardContext, JavaSdk.getInstance(), moduleBuilder, new Computable<Boolean>() {
@Override
public Boolean compute() {
final Sdk projectJdk = wizardFactory.getNewProjectSdk(wizardContext);
return projectJdk == null || projectJdk.getSdkType() != JavaSdk.getInstance() ? Boolean.TRUE : Boolean.FALSE;
//final Sdk projectJdk = wizardFactory.getNewProjectSdk(wizardContext);
//return projectJdk == null || projectJdk.getSdkType() != JavaSdk.getInstance() ? Boolean.TRUE : Boolean.FALSE;
return Boolean.TRUE;
}
}, getWizardIcon(), "reference.dialogs.new.project.fromScratch.sdk"));
final ModuleWizardStep supportForFrameworksStep = wizardFactory.createSupportForFrameworksStep(wizardContext, moduleBuilder, modulesProvider);