package org.gudy.azureus2.ui.swt.views.table.impl; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.*; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.gudy.azureus2.core3.config.COConfigurationManager; import org.gudy.azureus2.core3.config.ParameterListener; import org.gudy.azureus2.core3.util.AERunnable; import org.gudy.azureus2.ui.swt.Utils; import org.gudy.azureus2.ui.swt.mainwindow.Colors; import org.gudy.azureus2.ui.swt.mainwindow.HSLColor; import org.gudy.azureus2.ui.swt.views.table.TableColumnOrTreeColumn; import org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem; import org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT; import com.aelitis.azureus.ui.swt.utils.ColorCache; public class TableViewSWT_EraseItem implements Listener { final static public Color[] alternatingColors = new Color[] { null, Colors.colorAltRow }; static{ Colors.getInstance().addColorsChangedListener( new ParameterListener() { public void parameterChanged(String parameterName) { alternatingColors[1] = Colors.colorAltRow; } }); } private final TableOrTreeSWT table; private TableViewSWTImpl<?> tv; private boolean drawExtended; private boolean first = true; private static Color colorLine; public TableViewSWT_EraseItem(TableViewSWTImpl<?> _tv, TableOrTreeSWT table) { this.table = table; this.tv = _tv; COConfigurationManager.addAndFireParameterListener("Table.extendedErase", new ParameterListener() { public void parameterChanged(String parameterName) { Utils.execSWTThread(new AERunnable() { public void runSupport() { drawExtended = COConfigurationManager.getBooleanParameter("Table.extendedErase"); if (!first) { Rectangle bounds = tv.getTableOrTreeSWT().getBounds(); tv.getTableOrTreeSWT().redraw(bounds.x, bounds.y, bounds.width, bounds.height, true); } first = false; } }); } }); if (colorLine == null) { colorLine = tv.getComposite().getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND); HSLColor hslColor = new HSLColor(); hslColor.initHSLbyRGB(colorLine.getRed(), colorLine.getGreen(), colorLine.getBlue()); int lum = hslColor.getLuminence(); if (lum > 127) lum -= 25; else lum += 40; hslColor.setLuminence(lum); colorLine = new Color(tv.getComposite().getDisplay(), hslColor.getRed(), hslColor.getGreen(), hslColor.getBlue()); } /* Background image badly slows down tree drawing int itemHeight = table.getItemHeight() + 1; int height = 1920; Image image = new Image(table.getComposite().getDisplay(), 10, height); GC gc = new GC(image); int y = table.getHeaderHeight(); while (y < height) { gc.setBackground(table.getBackground()); gc.fillRectangle(0, y, 10, itemHeight); gc.setBackground(alternatingColors[1]); gc.fillRectangle(0, y + itemHeight, 10, itemHeight); y += itemHeight * 2; } gc.dispose(); table.setBackgroundImage(image); */ } public void handleEvent(Event event) { if (event.type == SWT.EraseItem) { TableItemOrTreeItem item = TableOrTreeUtils.getEventItem(event.item); eraseItem(event, event.gc, item, event.index, drawExtended, item.getBounds(event.index), tv, false); } else if (drawExtended) { paint(event); } } private void paint(Event event) { //System.out.println("paint " + event.getBounds() + ";" + table.getColumnCount()); int numItems = table.getItemCount(); int rowHeight = table.getItemHeight(); int height = rowHeight * numItems; int rowAreaHeight = tv.clientArea.height + tv.clientArea.y; int blankHeight = rowAreaHeight - height; if (blankHeight > 0) { int startY; if (numItems > 0) { TableItemOrTreeItem lastItem = table.getItem(numItems - 1); // dunno how, but I have a stacktrace with an NPE caused by lastItem being null (even though numItems > 0 ...) if ( lastItem != null ){ Rectangle lastItemBounds; if (lastItem.getExpanded()) { TableItemOrTreeItem[] subItems = lastItem.getItems(); lastItemBounds = subItems == null || subItems.length == 0 ? lastItem.getBounds() : subItems[subItems.length - 1].getBounds(); } else { lastItemBounds = lastItem.getBounds(); } startY = lastItemBounds.y + lastItemBounds.height; }else{ startY = 0; } } else { startY = 0; } //if (event.width == tv.clientArea.width && event.height < blankHeight) { // System.out.println("MOO"); // table.redraw(tv.clientArea.x, startY, tv.clientArea.width, blankHeight, false); // return; //} //System.out.println("numItems=" + numItems + ";" + startY); GC gc = event.gc; gc.setClipping((Rectangle) null); for (int i = 0; i < blankHeight / rowHeight; i++) { int curY = (startY + (i * rowHeight)); int pos = (i + numItems) % 2; //System.out.println(i + "==" + pos + " for " + (startY + (i * rowHeight))); Color color = i <= -1 ? ColorCache.getRandomColor() : alternatingColors[pos]; if (color == null) { //color = event.display.getSystemColor(SWT.COLOR_LIST_BACKGROUND); continue; } gc.setBackground(color); gc.fillRectangle(tv.clientArea.x, startY + (i * rowHeight), tv.clientArea.width, rowHeight); } // Vertical lines between columns if (TableViewSWTImpl.DRAW_VERTICAL_LINES) { TableColumnOrTreeColumn[] columns = table.getColumns(); int pos = 0; //gc.setForeground(ColorCache.getColor(event.display, 245, 245, 245)); gc.setForeground(Colors.black); gc.setAdvanced(true); gc.setAlpha(10); for (TableColumnOrTreeColumn tc : columns) { gc.drawLine(pos - 1, startY, pos - 1, startY + blankHeight); pos += tc.getWidth(); } gc.drawLine(pos - 1, startY, pos - 1, startY + blankHeight); } } } public static void eraseItem(Event event, GC gc, TableItemOrTreeItem item, int columnNo, boolean drawExtended, Rectangle bounds, TableViewSWTImpl<?> tv, boolean alwaysDrawBG) { TableOrTreeSWT table = tv.getTableOrTreeSWT(); if (event == null || (event.detail & (SWT.HOT | SWT.SELECTED | SWT.FOCUSED)) == 0) { int pos; TableItemOrTreeItem parentItem = item.getParentItem(); if (parentItem != null) { pos = parentItem.indexOf(item) + ((table.indexOf(parentItem) + 1) % 2); } else { pos = table.indexOf(item); } Color color = alternatingColors[pos % 2]; if (color != null) { gc.setBackground(color); if (parentItem != null) { gc.setAlpha(128); } } Rectangle drawBounds = bounds; if (TableViewSWTImpl.DRAW_FULL_ROW && drawExtended && columnNo == table.getColumnCount() - 1) { tv.swt_calculateClientArea(); drawBounds = new Rectangle(bounds.x, bounds.y, tv.clientArea.x + tv.clientArea.width - bounds.x, bounds.height); gc.setClipping(drawBounds); //System.out.println(bounds.width); } if (alwaysDrawBG || color != null) { if (color == null) { gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); } gc.fillRectangle(drawBounds); if (event != null) { event.detail &= ~SWT.BACKGROUND; } } } if (event != null && (event.detail & SWT.SELECTED) > 0 && !table.isFocusControl()) { gc.setBackground(Colors.blues[3]); gc.fillRectangle(bounds); if (event != null) { event.detail &= ~SWT.BACKGROUND; } } // Vertical lines between columns if (TableViewSWTImpl.DRAW_VERTICAL_LINES && drawExtended && colorLine != null) { if (item != null && (bounds.width == item.getParent().getColumn(columnNo).getWidth()) && bounds.width > 0) { Color fg = gc.getForeground(); gc.setForeground(colorLine); // needed because windows shifts the area over, dragging our old line // around. Clear clipping so we can erase it gc.setClipping((Rectangle) null); gc.drawLine(bounds.x + bounds.width - 1, bounds.y - 1, bounds.x + bounds.width - 1, bounds.y + bounds.height); gc.setForeground(fg); } } } }