001: /*******************************************************************************
002: * Copyright (c) 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: * Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
011: * - fix for bug 183850, 182652, 182800
012: ******************************************************************************/package org.eclipse.jface.viewers;
013:
014: import org.eclipse.core.runtime.Assert;
015: import org.eclipse.swt.SWT;
016: import org.eclipse.swt.graphics.Color;
017: import org.eclipse.swt.graphics.GC;
018: import org.eclipse.swt.graphics.Rectangle;
019: import org.eclipse.swt.widgets.Event;
020: import org.eclipse.swt.widgets.Listener;
021:
022: /**
023: * @since 3.3
024: *
025: */
026: public class FocusCellOwnerDrawHighlighter extends FocusCellHighlighter {
027: // Needed to work-around problem in bug 183850
028: private static final boolean WIN_32 = "win32".equals(SWT.getPlatform()); //$NON-NLS-1$
029:
030: /**
031: * @param viewer
032: * the viewer
033: */
034: public FocusCellOwnerDrawHighlighter(ColumnViewer viewer) {
035: super (viewer);
036: hookListener(viewer);
037: }
038:
039: private void markFocusedCell(Event event, ViewerCell cell) {
040: Color background = getSelectedCellBackgroundColor(cell);
041: Color foreground = getSelectedCellForegroundColor(cell);
042:
043: if (WIN_32 || foreground != null || background != null) {
044: GC gc = event.gc;
045:
046: if (background == null) {
047: background = cell.getItem().getDisplay()
048: .getSystemColor(SWT.COLOR_LIST_SELECTION);
049: }
050:
051: if (foreground == null) {
052: foreground = cell.getItem().getDisplay()
053: .getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT);
054: }
055:
056: gc.setBackground(background);
057: gc.setForeground(foreground);
058: gc.fillRectangle(event.getBounds());
059:
060: // This is a workaround for an SWT-Bug on WinXP bug 169517
061: gc.drawText(
062: " ", cell.getBounds().x, cell.getBounds().y, false); //$NON-NLS-1$
063: event.detail &= ~SWT.SELECTED;
064: }
065: }
066:
067: private void removeSelectionInformation(Event event, ViewerCell cell) {
068: GC gc = event.gc;
069: gc.setBackground(cell.getViewerRow().getBackground(
070: cell.getColumnIndex()));
071: gc.setForeground(cell.getViewerRow().getForeground(
072: cell.getColumnIndex()));
073: gc.fillRectangle(cell.getBounds());
074: // This is a workaround for an SWT-Bug on WinXP bug 169517
075: gc.drawText(" ", cell.getBounds().x, cell.getBounds().y, false); //$NON-NLS-1$
076: event.detail &= ~SWT.SELECTED;
077: }
078:
079: private void hookListener(final ColumnViewer viewer) {
080:
081: Listener listener = new Listener() {
082:
083: public void handleEvent(Event event) {
084: if ((event.detail & SWT.SELECTED) > 0) {
085: ViewerCell focusCell = getFocusCell();
086: ViewerRow row = viewer
087: .getViewerRowFromItem(event.item);
088:
089: Assert
090: .isNotNull(row,
091: "Internal structure invalid. Item without associated row is not possible."); //$NON-NLS-1$
092:
093: ViewerCell cell = row.getCell(event.index);
094:
095: if (focusCell == null || !cell.equals(focusCell)) {
096: removeSelectionInformation(event, cell);
097: } else {
098: markFocusedCell(event, cell);
099: }
100: }
101: }
102:
103: };
104: viewer.getControl().addListener(SWT.EraseItem, listener);
105: }
106:
107: /**
108: * @param cell
109: * the cell which is colored
110: * @return the color
111: */
112: protected Color getSelectedCellBackgroundColor(ViewerCell cell) {
113: return null;
114: }
115:
116: /**
117: * @param cell
118: * the cell which is colored
119: * @return the color
120: */
121: protected Color getSelectedCellForegroundColor(ViewerCell cell) {
122: return null;
123: }
124:
125: protected void focusCellChanged(ViewerCell newCell,
126: ViewerCell oldCell) {
127: super .focusCellChanged(newCell, oldCell);
128:
129: // Redraw new area
130: if (newCell != null) {
131: Rectangle rect = newCell.getBounds();
132: int x = newCell.getColumnIndex() == 0 ? 0 : rect.x;
133: int width = newCell.getColumnIndex() == 0 ? rect.x
134: + rect.width : rect.width;
135: // 1 is a fix for Linux-GTK
136: newCell.getControl().redraw(x, rect.y - 1, width,
137: rect.height + 1, true);
138: }
139:
140: if (oldCell != null) {
141: Rectangle rect = oldCell.getBounds();
142: int x = oldCell.getColumnIndex() == 0 ? 0 : rect.x;
143: int width = oldCell.getColumnIndex() == 0 ? rect.x
144: + rect.width : rect.width;
145: // 1 is a fix for Linux-GTK
146: oldCell.getControl().redraw(x, rect.y - 1, width,
147: rect.height + 1, true);
148: }
149: }
150: }
|