package org.xmind.ui.editor;
import java.util.List;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.resource.ResourceManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabFolderRenderer;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.TextLayout;
import org.xmind.core.ISettingEntry;
import org.xmind.core.ISheet;
import org.xmind.core.ISheetSettings;
import org.xmind.ui.internal.editor.MindMapEditor;
import org.xmind.ui.resources.ColorUtils;
public class PageTitleTabFolderRenderer extends CTabFolderRenderer {
private static final int FLAGS = 9;
private static final String ELLIPSIS = "..."; //$NON-NLS-1$
private MindMapEditor editor;
private ResourceManager resources;
public PageTitleTabFolderRenderer(CTabFolder parent, MindMapEditor editor) {
super(parent);
this.editor = editor;
resources = new LocalResourceManager(JFaceResources.getResources(),
parent);
}
@Override
protected void draw(final int part, int state, Rectangle bounds, GC gc) {
super.draw(part, state, bounds, gc);
if (0 <= part && part < parent.getItemCount()) {
if (bounds.width == 0 || bounds.height == 0)
return;
if ((state & SWT.SELECTED) != 0) {
drawSelectedItem(part, gc, bounds, state);
} else {
drawUnselectedItem(part, gc, bounds, state);
}
}
}
private void drawSelectedItem(int index, GC gc, Rectangle bounds,
int state) {
if ((state & SWT.BACKGROUND) != 0) {
drawItemBackground(index, gc, true);
}
if ((state & SWT.FOREGROUND) != 0) {
drawItemText(index, gc);
}
}
private void drawUnselectedItem(int index, GC gc, Rectangle bounds,
int state) {
CTabItem item = parent.getItem(index);
// Do not draw partial items
if (!item.isShowing())
return;
Rectangle clipping = gc.getClipping();
if (!clipping.intersects(bounds))
return;
if ((state & SWT.BACKGROUND) != 0) {
drawItemBackground(index, gc, false);
}
}
private void drawItemBackground(int index, GC gc, boolean selected) {
Rectangle bounds = parent.getItem(index).getBounds();
Color gcBackground = gc.getBackground();
Color background = getColor(index);
if (background != null && !gcBackground.equals(background)) {
gc.setBackground(background);
Rectangle paintedArea = selected
? new Rectangle(bounds.x, bounds.y + bounds.height * 6 / 7,
bounds.width, bounds.height / 7)
: new Rectangle(bounds.x, bounds.y, bounds.width,
bounds.height / 7);
gc.fillRectangle(paintedArea);
//recovery gc context
gc.setBackground(gcBackground);
}
}
private void drawItemText(int index, GC gc) {
Color foreground = getColor(index);
if (foreground == null || foreground.equals(gc.getForeground())) {
return;
}
CTabItem item = parent.getItem(index);
Rectangle bounds = item.getBounds();
int x = bounds.x;
int y = bounds.y;
int height = bounds.height;
int width = bounds.width;
Rectangle trim = computeTrim(index, SWT.NONE, 0, 0, 0, 0);
int xDraw = x - trim.x;
int textWidth = x + width - xDraw - (trim.width + trim.x);
if (textWidth > 0) {
Font gcFont = gc.getFont();
Color gcForeground = gc.getForeground();
Color gcBackground = gc.getBackground();
gc.setFont(item.getFont());
gc.setBackground(
parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
String shortenedText = shortenText2(gc, item.getText(), textWidth);
Point extent = gc.textExtent(shortenedText, FLAGS);
int textY = y + (height - extent.y) / 2;
boolean onBottom = (parent.getStyle() & SWT.BOTTOM) != 0;
textY += onBottom ? -1 : 1;
gc.setForeground(foreground);
// gc.setBackground();
gc.drawText(shortenedText, xDraw, textY, false);
//recovery gc context
gc.setFont(gcFont);
gc.setForeground(gcForeground);
gc.setBackground(gcBackground);
}
}
private String shortenText2(GC gc, String text, int width) {
return useEllipses2() ? shortenText2(gc, text, width, ELLIPSIS)
: shortenText2(gc, text, width, ""); //$NON-NLS-1$
}
private boolean useEllipses2() {
return parent.getSimple();
}
private String shortenText2(GC gc, String text, int width,
String ellipses) {
if (gc.textExtent(text, FLAGS).x <= width)
return text;
int ellipseWidth = gc.textExtent(ellipses, FLAGS).x;
int length = text.length();
TextLayout layout = new TextLayout(parent.getDisplay());
layout.setText(text);
int end = layout.getPreviousOffset(length, SWT.MOVEMENT_CLUSTER);
while (end > 0) {
text = text.substring(0, end);
int l = gc.textExtent(text, FLAGS).x;
if (l + ellipseWidth <= width) {
break;
}
end = layout.getPreviousOffset(end, SWT.MOVEMENT_CLUSTER);
}
layout.dispose();
return end == 0 ? text.substring(0, 1) : text + ellipses;
}
private Color getColor(int index) {
if (index < 0 || index >= editor.getPages().length) {
return null;
}
ISheet sheet = editor.getPage(index).getAdapter(ISheet.class);
String rgb = getRgb(sheet);
if (rgb == null || rgb.equals("")) { //$NON-NLS-1$
return null;
}
return (Color) resources.get(ColorUtils.toDescriptor(rgb));
}
private String getRgb(ISheet sheet) {
ISettingEntry entry = findEntry(sheet);
return entry == null ? null
: entry.getAttribute(ISheetSettings.ATTR_RGB);
}
private ISettingEntry findEntry(ISheet sheet) {
List<ISettingEntry> entries = sheet.getSettings()
.getEntries(ISheetSettings.TAB_COLOR);
return entries.size() == 0 ? null : entries.get(0);
}
}