package org.xmind.ui.internal.e4models;
import org.eclipse.jface.resource.FontDescriptor;
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.eclipse.swt.widgets.Control;
import org.xmind.ui.resources.ColorUtils;
import org.xmind.ui.resources.FontUtils;
public class ViewModelFolderRenderer extends CTabFolderRenderer {
private static final int FLAGS = SWT.DRAW_TRANSPARENT | SWT.DRAW_MNEMONIC;
private static final String ELLIPSIS = "..."; //$NON-NLS-1$
private static final int BORDER1_COLOR = SWT.COLOR_WIDGET_NORMAL_SHADOW;
private ResourceManager resources;
public ViewModelFolderRenderer(CTabFolder parent) {
super(parent);
resources = new LocalResourceManager(JFaceResources.getResources(),
parent);
}
@Override
protected Point computeSize(int part, int state, GC gc, int wHint,
int hHint) {
Point size = super.computeSize(part, state, gc, wHint, hHint);
if (0 <= part && part < parent.getItemCount()) {
Control topRight = parent.getTopRight();
if (parent.getItemCount() == 1) {
size.x = parent.getSize().x;
} else {
size.x = (parent.getSize().x - (topRight.getSize().x + 8))
/ parent.getItemCount();
}
size.y += 5;
}
return size;
}
@Override
protected void draw(final int part, int state, Rectangle bounds, GC gc) {
if (part == PART_HEADER) {
drawTabArea2(gc, bounds, state);
} else if (0 <= part && part < parent.getItemCount()) {
if (bounds.width == 0 || bounds.height == 0) {
return;
}
CTabItem item = parent.getItem(part);
if (parent.getItemCount() == 1) {
drawSingleItem(bounds, gc, item);
} else {
drawMultiItems(part, state, bounds, gc, item);
}
} else {
super.draw(part, state, bounds, gc);
}
}
private void drawSingleItem(Rectangle bounds, GC gc, CTabItem item) {
//draw background
int fullWidth = parent.getSize().x;
gc.setBackground(
(Color) resources.get(ColorUtils.toDescriptor("#f4f4f4"))); //$NON-NLS-1$
gc.fillRectangle(bounds.x + 1, bounds.y + 1, bounds.x + fullWidth - 2,
bounds.y + bounds.height - 1);
//draw border
gc.setLineWidth(1);
gc.setForeground(
(Color) resources.get(ColorUtils.toDescriptor("#cecece"))); //$NON-NLS-1$
gc.drawLine(bounds.x + 1, bounds.y + bounds.height,
bounds.x + fullWidth - 2, bounds.y + bounds.height);
Rectangle topBounds = new Rectangle(bounds.x, bounds.y,
parent.getSize().x, bounds.height);
drawText(bounds, gc, item, "#1c1c1c", topBounds); //$NON-NLS-1$
}
private void drawMultiItems(final int part, int state, Rectangle bounds,
GC gc, CTabItem item) {
int fullWidth = parent.getSize().x;
//draw background
gc.setBackground(
(Color) resources.get(ColorUtils.toDescriptor("#f4f4f4"))); //$NON-NLS-1$
gc.fillRectangle(bounds.x + 1, bounds.y + 1, bounds.width,
bounds.height - 1);
//draw border
gc.setLineWidth(1);
gc.setForeground(
(Color) resources.get(ColorUtils.toDescriptor("#a0a0a0"))); //$NON-NLS-1$
gc.drawLine(bounds.x + 1, bounds.y + bounds.height,
bounds.x + bounds.width, bounds.y + bounds.height);
if ((state & SWT.SELECTED) != 0) {
drawSelectedItem(part, gc, bounds, state);
} else {
drawUnselectedItem(part, gc, bounds, state);
}
//draw top right control area.
if (part == parent.getItemCount() - 1) {
//draw background
gc.setBackground(
(Color) resources.get(ColorUtils.toDescriptor("#f4f4f4"))); //$NON-NLS-1$
gc.fillRectangle(bounds.x + bounds.width + 1, bounds.y + 1,
fullWidth - (bounds.x + bounds.width + 1) - 1,
bounds.height - 1);
//draw border
gc.setLineWidth(1);
gc.setForeground(
(Color) resources.get(ColorUtils.toDescriptor("#a0a0a0"))); //$NON-NLS-1$
gc.drawLine(bounds.x + bounds.width + 1, bounds.y + bounds.height,
fullWidth - 1, bounds.y + bounds.height);
}
}
private void drawSelectedItem(int part, GC gc, Rectangle bounds,
int state) {
//draw background
gc.setBackground(
(Color) resources.get(ColorUtils.toDescriptor("#28abe6"))); //$NON-NLS-1$
gc.fillRectangle(bounds.x + 1, bounds.y + 1, bounds.width - 1,
bounds.height - 1);
//draw separator
gc.setLineWidth(1);
gc.setForeground(
(Color) resources.get(ColorUtils.toDescriptor("#a0a0a0"))); //$NON-NLS-1$
gc.drawLine(bounds.x + bounds.width, bounds.y, bounds.x + bounds.width,
bounds.y + bounds.height - 1);
if (part != 0) {
gc.drawLine(bounds.x, bounds.y, bounds.x,
bounds.y + bounds.height - 1);
}
CTabItem item = parent.getItem(part);
drawText(bounds, gc, item, "#ffffff", null); //$NON-NLS-1$
}
private void drawUnselectedItem(int part, GC gc, Rectangle bounds,
int state) {
//draw background
gc.setBackground(
(Color) resources.get(ColorUtils.toDescriptor("#f4f4f4"))); //$NON-NLS-1$
gc.fillRectangle(bounds.x + 1, bounds.y + 1, bounds.width - 3,
bounds.height - 1);
//draw separator
gc.setLineWidth(1);
gc.setForeground(
(Color) resources.get(ColorUtils.toDescriptor("#a0a0a0"))); //$NON-NLS-1$
gc.drawLine(bounds.x + bounds.width, bounds.y, bounds.x + bounds.width,
bounds.y + bounds.height - 1);
if (part != 0) {
gc.drawLine(bounds.x, bounds.y, bounds.x,
bounds.y + bounds.height - 1);
}
CTabItem item = parent.getItem(part);
drawText(bounds, gc, item, "#1c1c1c", null); //$NON-NLS-1$
}
private void drawText(Rectangle bounds, GC gc, CTabItem item,
String foreground, Rectangle topBounds) {
Color gcForeground = gc.getForeground();
gc.setForeground(
(Color) resources.get(ColorUtils.toDescriptor(foreground)));
Font gcFont = gc.getFont();
gc.setFont((Font) resources.get(FontDescriptor.createFrom(
FontUtils.relativeHeight(gcFont.getFontData(), 2))));
item.setText(shortenText2(true, gc, item.getText(), bounds.width));
Point extent = gc.textExtent(item.getText(), FLAGS);
int textX = bounds.x + (bounds.width - extent.x) / 2;
//centered text
if (topBounds != null) {
textX = topBounds.x + (topBounds.width - extent.x) / 2;
if (textX + extent.x > bounds.x + bounds.width) {
textX = bounds.x + bounds.width - extent.x;
}
}
int textY = bounds.y + (bounds.height - extent.y) / 2;
gc.drawText(item.getText(), textX, textY, FLAGS);
gc.setFont(gcFont);
gc.setForeground(gcForeground);
}
private String shortenText2(boolean useEllipses, GC gc, String text,
int width) {
return useEllipses ? shortenText2(gc, text, width, ELLIPSIS)
: shortenText2(gc, text, width, ""); //$NON-NLS-1$
}
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 void drawTabArea2(GC gc, Rectangle bounds, int state) {
Color borderColor = parent.getDisplay().getSystemColor(BORDER1_COLOR);
int tabHeight = parent.getTabHeight();
gc.setLineWidth(1);
gc.setForeground(borderColor);
gc.drawRectangle(bounds.x, bounds.y, bounds.width - 1, tabHeight);
}
}