/* * Copyright 2003-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 jetbrains.mps.ide.ui.dialogs.properties.roots.editors; import com.intellij.icons.AllIcons.Modules; import com.intellij.ui.DarculaColors; import com.intellij.ui.Gray; import com.intellij.ui.JBColor; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBPanel; import com.intellij.ui.roots.IconActionComponent; import com.intellij.ui.roots.ResizingWrapper; import com.intellij.util.EventDispatcher; import com.intellij.util.ui.JBInsets; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.mps.openapi.persistence.ModelRoot; import org.jetbrains.mps.openapi.ui.persistence.ModelRootEntry; import org.jetbrains.mps.openapi.ui.persistence.ModelRootEntry.ModelRootEntryListener; import org.jetbrains.mps.openapi.ui.persistence.ModelRootEntryEditor; import org.jetbrains.mps.openapi.ui.persistence.ModelRootEntryExt; import javax.swing.Box; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.EventListener; import static java.awt.GridBagConstraints.EAST; import static java.awt.GridBagConstraints.HORIZONTAL; import static java.awt.GridBagConstraints.NONE; import static java.awt.GridBagConstraints.NORTHWEST; import static java.awt.GridBagConstraints.RELATIVE; /** * A container for a single model root entry */ public final class ModelRootEntryContainer implements ModelRootEntryListener { static final Color SOURCES_COLOR = new JBColor(new Color(0x0A50A1), DarculaColors.BLUE); static final Color EXCLUDED_COLOR = new JBColor(new Color(0x992E00), DarculaColors.RED); static final Color TESTS_COLOR = new Color(0x008C2E); static final Color SELECTED_CONTENT_COLOR = new Color(0xF0F9FF); private static final Color SELECTED_HEADER_COLOR = new JBColor(new Color(0xDEF2FF), UIUtil.getPanelBackground().darker()); private static final Color HEADER_COLOR = new JBColor(new Color(0xF5F5F5), Gray._82); private static final Color CONTENT_COLOR = new JBColor(Color.WHITE, UIUtil.getPanelBackground()); private static final Color UNSELECTED_TEXT_COLOR = Gray._51; private final ModelRootEntry myModelRootEntry; protected ModelRootEntryEditor myEditor; private EventDispatcher<ContentEntryEditorListener> myEventDispatcher; private boolean myIsSelected = false; protected JPanel myMainPanel; private JComponent myHeader; private JComponent myDetailsComponent; private JComponent myBottom; private JLabel myHeaderLabel; private JBLabel myDetailsLabel; public ModelRootEntryContainer(@NotNull ModelRootEntry modelRootEntry) { myModelRootEntry = modelRootEntry; myModelRootEntry.addModelRootEntryListener(this); myEventDispatcher = EventDispatcher.create(ContentEntryEditorListener.class); } public ModelRootEntry getModelRootEntry() { return myModelRootEntry; } public ModelRoot getModelRoot() { return myModelRootEntry.getModelRoot(); } private void initUI() { myMainPanel = new JPanel(new GridBagLayout()); myMainPanel.setOpaque(false); myMainPanel.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { myIsSelected = true; myEventDispatcher.getMulticaster().focused(ModelRootEntryContainer.this); } @Override public void mouseEntered(MouseEvent e) { if (!myIsSelected) { setSelected(true); } } @Override public void mouseExited(MouseEvent e) { if (!myIsSelected) { setSelected(false); } } }); myHeader = createHeader(); myMainPanel.add(myHeader, new GridBagConstraints(0, RELATIVE, 1, 1, 1.0, 0.0, NORTHWEST, HORIZONTAL, new JBInsets(2,2,0,2), 0, 0)); myDetailsComponent = createDetailsComponent(); myMainPanel.add(myDetailsComponent, new GridBagConstraints(0, RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH, HORIZONTAL, new JBInsets(0,2,0,2), 0, 0)); myBottom = new JPanel(new BorderLayout()); myBottom.add(Box.createVerticalStrut(3), BorderLayout.NORTH); myMainPanel.add(myBottom, new GridBagConstraints(0, RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.NORTH, HORIZONTAL, new JBInsets(0,2,0,2), 0, 0)); setFocused(false); } protected JComponent createHeader() { final JPanel panel = new JPanel(new GridBagLayout()); myHeaderLabel = new JBLabel(myModelRootEntry.getModelRoot().toString()); myHeaderLabel.setFont(myHeaderLabel.getFont().deriveFont(Font.BOLD)); myHeaderLabel.setOpaque(false); final IconActionComponent deleteIconComponent = new IconActionComponent(Modules.DeleteContentRoot, Modules.DeleteContentRootRollover, "Delete Model Root", () -> myEventDispatcher.getMulticaster().delete(ModelRootEntryContainer.this)); panel.add(myHeaderLabel, new GridBagConstraints(0, RELATIVE, 1, 1, 1.0, 1.0, NORTHWEST, HORIZONTAL, new Insets(0, 2, 0, 0), 0, 0)); panel.add(deleteIconComponent, new GridBagConstraints(1, RELATIVE, 1, 1, 0.0, 1.0, EAST, NONE, new Insets(0, 0, 0, 2), 0, 0)); // FilePathClipper.install(myHeaderLabel, wrapper); return panel; } public JComponent getComponent() { if (myMainPanel == null) { initUI(); } return myMainPanel; } public void setFocused(boolean isFocused) { myIsSelected = isFocused; setSelected(isFocused); } protected void setSelected(boolean selected) { if (selected) { myHeader.setBackground(SELECTED_HEADER_COLOR); // myMainPanel.setBackground(UIUtil.isUnderDarcula() ? UIUtil.getPanelBackground() : SELECTED_CONTENT_COLOR); myDetailsComponent.setBackground(UIUtil.isUnderDarcula() ? UIUtil.getPanelBackground() : SELECTED_CONTENT_COLOR); myBottom.setBackground(SELECTED_HEADER_COLOR); if (myModelRootEntry instanceof ModelRootEntryExt) { ((ModelRootEntryExt) myModelRootEntry).resetForegroundColor(); } } else { myHeader.setBackground(HEADER_COLOR); // myMainPanel.setBackground(CONTENT_COLOR); myDetailsComponent.setBackground(CONTENT_COLOR); myBottom.setBackground(HEADER_COLOR); if (myModelRootEntry instanceof ModelRootEntryExt) { ((ModelRootEntryExt) myModelRootEntry).setForegroundColor(UNSELECTED_TEXT_COLOR); } } if (!myModelRootEntry.isValid()) { myHeader.setBackground(Color.PINK); } } public void addContentEntryEditorListener(ContentEntryEditorListener listener) { myEventDispatcher.addListener(listener); } public ModelRootEntryEditor getEditor() { return myModelRootEntry.getEditor(); } protected ModelRootEntryEditor createEditor() { return myModelRootEntry.getEditor(); } public void updateUI() { myHeaderLabel.setText(myModelRootEntry.getModelRoot().toString()); if (myDetailsLabel != null) { myDetailsLabel.setText(myModelRootEntry.getDetailsText()); } else { myMainPanel.remove(myDetailsComponent); if (myModelRootEntry instanceof ModelRootEntryExt) { myDetailsComponent = ((ModelRootEntryExt) myModelRootEntry).getDetailsComponent(); } myMainPanel.add(myDetailsComponent, new GridBagConstraints(0, RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH, HORIZONTAL, new JBInsets(0,2,0,2), 0, 0)); myMainPanel.revalidate(); } } protected JComponent createDetailsComponent() { JBPanel panel = new JBPanel(new GridBagLayout()); JComponent configurableComponent = null; if (myModelRootEntry instanceof ModelRootEntryExt) { configurableComponent = ((ModelRootEntryExt) myModelRootEntry).getDetailsComponent(); } if (configurableComponent == null) { myDetailsLabel = new JBLabel(myModelRootEntry.getDetailsText()); myDetailsLabel.setOpaque(false); panel.add(myDetailsLabel, new GridBagConstraints(0, RELATIVE, 1, 1, 1.0, 1.0, NORTHWEST, GridBagConstraints.BOTH, new Insets(0, 2, 0, 0), 0, 0)); } else { panel.add(configurableComponent, new GridBagConstraints(0, RELATIVE, 1, 1, 1.0, 1.0, NORTHWEST, GridBagConstraints.BOTH, new Insets(0, 2, 0, 0), 0, 0)); } return panel; } @Override public void fireDataChanged() { updateUI(); } public interface ContentEntryEditorListener extends EventListener { void focused(ModelRootEntryContainer entry); void delete(ModelRootEntryContainer entry); void dataChanged(ModelRootEntryContainer entry); } }