/* * 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.application.options.codeStyle.arrangement.group; import com.intellij.application.options.codeStyle.arrangement.ArrangementConstants; import com.intellij.application.options.codeStyle.arrangement.color.ArrangementColorsProvider; import com.intellij.application.options.codeStyle.arrangement.ui.ArrangementEditorAware; import com.intellij.application.options.codeStyle.arrangement.ui.ArrangementRepresentationAware; import com.intellij.application.options.codeStyle.arrangement.util.ArrangementRuleIndexControl; import com.intellij.psi.codeStyle.arrangement.ArrangementUtil; import com.intellij.psi.codeStyle.arrangement.std.*; import com.intellij.ui.IdeBorderFactory; import com.intellij.util.containers.ContainerUtilRt; import com.intellij.util.ui.GridBag; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.util.Collections; import java.util.List; /** * @author Denis Zhdanov * @since 11/13/12 8:10 PM */ public class ArrangementGroupingComponent extends JPanel implements ArrangementRepresentationAware, ArrangementEditorAware { @NotNull private final ArrangementUiComponent myGroupingTypeToken; @NotNull private final ArrangementRuleIndexControl myRowIndexControl; @Nullable private final ArrangementUiComponent myOrderTypeToken; /** * Assumes that given token {@link CompositeArrangementSettingsToken#getChildren() has no children} or all its children have * the {@link CompositeArrangementSettingsToken#getRole() same UI role}. * <p/> * Lays out given token (and its children if any) in a single row. * * @param token base token which serves as a grouping rule model * @param colorsProvider colors provider * * @throws IllegalArgumentException if invariant described above is not satisfied */ public ArrangementGroupingComponent(@NotNull CompositeArrangementSettingsToken token, @NotNull ArrangementColorsProvider colorsProvider, @NotNull ArrangementStandardSettingsManager settingsManager) throws IllegalArgumentException { List<ArrangementSettingsToken> children = ContainerUtilRt.newArrayList(); StdArrangementTokenUiRole childRole = null; for (CompositeArrangementSettingsToken child : token.getChildren()) { if (childRole == null) { childRole = child.getRole(); children.add(child.getToken()); } else if (!childRole.equals(child.getRole())) { throw new IllegalArgumentException(String.format( "Can't build a grouping component for token '%s'. Reason: its children has different UI roles (%s and %s)", token, childRole, child.getRole() )); } else { children.add(child.getToken()); } } FontMetrics metrics = getFontMetrics(getFont()); int maxWidth = 0; for (int i = 0; i <= 99; i++) { maxWidth = Math.max(metrics.stringWidth(String.valueOf(i)), maxWidth); } int height = metrics.getHeight() - metrics.getDescent() - metrics.getLeading(); int diameter = Math.max(maxWidth, height) * 5 / 3; myRowIndexControl = new ArrangementRuleIndexControl(diameter, height); myGroupingTypeToken = ArrangementUtil.buildUiComponent( token.getRole(), Collections.singletonList(token.getToken()), colorsProvider, settingsManager ); if (children.size() <= 0) { myOrderTypeToken = null; } else { assert childRole != null; myOrderTypeToken = ArrangementUtil.buildUiComponent(childRole, children, colorsProvider, settingsManager); myGroupingTypeToken.setListener(new ArrangementUiComponent.Listener() { @Override public void stateChanged() { myOrderTypeToken.setEnabled(myGroupingTypeToken.isSelected()); } }); } init(); } private void init() { setLayout(new GridBagLayout()); add(myRowIndexControl, new GridBag().anchor(GridBagConstraints.CENTER) .insets(0, ArrangementConstants.HORIZONTAL_PADDING, 0, ArrangementConstants.HORIZONTAL_GAP * 2) ); add(myGroupingTypeToken.getUiComponent(), new GridBag().anchor(GridBagConstraints.WEST).insets(0, 0, 0, 2)); if (myOrderTypeToken != null) { add(myOrderTypeToken.getUiComponent(), new GridBag().anchor(GridBagConstraints.WEST)); } add(new JLabel(" "), new GridBag().weightx(1).fillCellHorizontally()); setBackground(UIUtil.getListBackground()); setBorder(IdeBorderFactory.createEmptyBorder(ArrangementConstants.VERTICAL_GAP)); setOpaque(!UIUtil.isUnderIntelliJLaF() && !UIUtil.isUnderNativeMacLookAndFeel() && !UIUtil.isUnderDarcula()); } @Override protected void paintComponent(Graphics g) { Dimension size = getSize(); if (size != null) { int baseline = myGroupingTypeToken.getBaselineToUse(size.width, size.height); if (baseline > 0) { baseline -= myRowIndexControl.getBounds().y; myRowIndexControl.setBaseLine(baseline); } } if (UIUtil.isUnderIntelliJLaF() || UIUtil.isUnderDarcula() || UIUtil.isUnderNativeMacLookAndFeel()) { g.setColor(getBackground()); g.fillRect(1, 1, getWidth() - 2, getHeight() - 2); } super.paintComponent(g); } @NotNull @Override public JComponent getComponent() { return this; } public boolean isSelected() { return myGroupingTypeToken.isSelected(); } public void setSelected(boolean selected) { myGroupingTypeToken.setSelected(selected); refreshControl(); } private void refreshControl() { boolean checked = isSelected(); if (myOrderTypeToken != null) { myOrderTypeToken.setEnabled(checked); } } @NotNull public ArrangementSettingsToken getGroupingType() { ArrangementSettingsToken token = myGroupingTypeToken.getToken(); assert token != null; return token; } public void setOrderType(@NotNull ArrangementSettingsToken type) { if (myOrderTypeToken != null) { myOrderTypeToken.chooseToken(type); } } public void setRowIndex(int row) { myRowIndexControl.setIndex(row); } public void setHighlight(boolean highlight) { setBackground(highlight ? UIUtil.getDecoratedRowColor() : UIUtil.getListBackground()); } @Nullable public ArrangementSettingsToken getOrderType() { return myOrderTypeToken == null ? null : myOrderTypeToken.getToken(); } @Override public String toString() { return myGroupingTypeToken.toString(); } }