blob: ae9aba9c59eefb355465fd8936830aeb9eb8ae5d [file] [log] [blame]
/*
* Copyright 2000-2014 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 git4idea.history.browser;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Trinity;
import com.intellij.openapi.vcs.changes.committed.CommittedChangeListRenderer;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
public abstract class FictiveTableCellRenderer extends ColoredListCellRenderer {
// for cases when our renderer is encapsulated
protected abstract int getParentWidth(JList list);
@Nullable
protected abstract Color getBgrndColor(JList list, Object value, int index, boolean selected, boolean hasFocus);
protected abstract Description getDescription(Object value);
protected abstract Trinity<String, SimpleTextAttributes, Object> getMoreTag();
protected abstract boolean willRender(Object value);
protected abstract static class Description {
private final java.util.List<Pair<String, SimpleTextAttributes>> myPieces;
private final int myMiddleIdx;
public Description(int middleIdx, java.util.List<Pair<String, SimpleTextAttributes>> pieces) {
myMiddleIdx = middleIdx;
myPieces = pieces;
}
public int getMiddleIdx() {
return myMiddleIdx;
}
public java.util.List<Pair<String, SimpleTextAttributes>> getPieces() {
return myPieces;
}
public abstract String getMaxString(final int idx);
}
@Override
protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
if (! willRender(value)) return;
final int parentWidth = getParentWidth(list);
final Color bgrndColor = getBgrndColor(list, value, index, selected, hasFocus);
if (bgrndColor != null) {
setBackground(bgrndColor);
}
final Description description = getDescription(value);
final MyFontHelper helper = new MyFontHelper(list);
int fixedWidth = 0;
int fixedWidthBefore = 0;
int changeableWidth = 0;
final java.util.List<Pair<String,SimpleTextAttributes>> pieces = description.getPieces();
final int middleIdx = description.getMiddleIdx();
for (int i = 0; i < pieces.size(); i++) {
final Pair<String, SimpleTextAttributes> pair = pieces.get(i);
if (middleIdx == i) {
changeableWidth = helper.getWidth(pair);
} else {
final int width = helper.getWidth(pair);
if (i < middleIdx) {
fixedWidthBefore += width;
append(pair.getFirst(), pair.getSecond());
final String adj = description.getMaxString(i);
if (adj != null) {
final int adjWidth = helper.getWidth(Pair.create(adj, pair.getSecond()));
appendFixedTextFragmentWidth(adjWidth);
fixedWidth += adjWidth;
} else {
appendFixedTextFragmentWidth(width);
fixedWidth += width;
}
} else {
fixedWidth += width;
}
}
}
final Pair<String, SimpleTextAttributes> changeable = pieces.get(middleIdx);
final int difference = parentWidth - fixedWidth;
if ((fixedWidth + changeableWidth) > parentWidth) {
// need zipping
if (fixedWidth < parentWidth) {
// todo this should be rewised
final Trinity<String, SimpleTextAttributes, Object> tag = getMoreTag();
final int more = helper.getWidth(Pair.create(tag.getFirst(), tag.getSecond()));
if (more < difference) {
final String truncated = CommittedChangeListRenderer
.truncateDescription(changeable.getFirst(), helper.getFontMetrics(changeable.getSecond()), difference - more);
final int truncatedWidth = helper.getWidth(Pair.create(truncated, changeable.getSecond()));
append(truncated, changeable.getSecond());
append(tag.getFirst(), tag.getSecond(), tag.getThird());
if (truncatedWidth > 0) {
appendFixedTextFragmentWidth(difference - truncatedWidth);
}
} else {
appendFixedTextFragmentWidth(difference);
}
}
} else {
append(changeable.getFirst(), changeable.getSecond());
appendFixedTextFragmentWidth(parentWidth - fixedWidth);
}
for (int i = middleIdx + 1; i < pieces.size(); i++) {
final Pair<String, SimpleTextAttributes> pair = pieces.get(i);
append(pair.getFirst(), pair.getSecond());
}
}
private static class MyFontHelper {
private final FontMetrics myFontMetrics;
private final FontMetrics myBoldMetrics;
private final FontMetrics myItalicsMetrics;
private final FontMetrics myBoldItalicsMetrics;
private MyFontHelper(final JList list) {
final Font font = list.getFont();
myFontMetrics = list.getFontMetrics(font);
myBoldMetrics = list.getFontMetrics(font.deriveFont(Font.BOLD));
myItalicsMetrics = list.getFontMetrics(font.deriveFont(Font.ITALIC));
myBoldItalicsMetrics = list.getFontMetrics(font.deriveFont(Font.ITALIC | Font.BOLD));
}
public int getWidth(final Pair<String, SimpleTextAttributes> pair) {
final SimpleTextAttributes ta = pair.getSecond();
FontMetrics fm;
fm = getFontMetrics(ta);
return fm.stringWidth(pair.getFirst());
}
public FontMetrics getFontMetrics(SimpleTextAttributes ta) {
FontMetrics fm;
if ((ta.getStyle() & SimpleTextAttributes.STYLE_BOLD) == SimpleTextAttributes.STYLE_BOLD) {
if ((ta.getStyle() & SimpleTextAttributes.STYLE_ITALIC) == SimpleTextAttributes.STYLE_ITALIC) {
fm = myBoldItalicsMetrics;
} else {
fm = myBoldMetrics;
}
} else {
if ((ta.getStyle() & SimpleTextAttributes.STYLE_ITALIC) == SimpleTextAttributes.STYLE_ITALIC) {
fm = myItalicsMetrics;
} else {
fm = myFontMetrics;
}
}
return fm;
}
}
}