| package org.eclipse.nebula.widgets.nattable.renderer.swt.graphics
|
|
|
| import java.util.Map
|
| import java.util.Stack
|
| import org.eclipse.nebula.widgets.nattable.core.geometry.PixelRectangle
|
| import org.eclipse.nebula.widgets.nattable.core.graphics.Color
|
| import org.eclipse.nebula.widgets.nattable.core.graphics.GraphicsContext
|
| import org.eclipse.nebula.widgets.nattable.renderer.swt.event.mode.ModeSwitcher
|
| import org.eclipse.swt.SWT
|
| import org.eclipse.swt.graphics.GC
|
| import org.eclipse.swt.graphics.Rectangle
|
| import org.eclipse.swt.widgets.Composite
|
|
|
| import static org.eclipse.nebula.widgets.nattable.renderer.swt.graphics.GraphicsPropertiesEnum.*
|
|
|
| /** |
| * Proxy implementation of {@link IGraphicsContext} to provide the drawing |
| * capabilities by {@link GC} so the NatTable can be painted using this. |
| * |
| * @author Dirk Fauth |
| * |
| */ |
| class SWTGraphicsContext implements GraphicsContext { |
| |
| /** |
| * The SWT {@link GC} which is proxied by this implementation. |
| */ |
| val GC gc |
| val Composite composite |
| val ModeSwitcher modeSwitcher |
| val stateStack = new Stack<Map<GraphicsPropertiesEnum, Object>> |
| |
| Map<GraphicsPropertiesEnum, Object> originalState = newHashMap |
| double xOffset |
| double yOffset |
| int foregroundAlpha = 255 |
| int backgroundAlpha = 255 |
| |
| /** |
| * Create a new proxy instance for the specified {@link GC}. |
| * @param gc The SWT {@link GC} which is proxied by this implementation. |
| */ |
| new(GC gc, Composite composite, ModeSwitcher modeSwitcher) { |
| if (gc == null) throw new IllegalArgumentException("gc can not be null"); //$NON-NLS-1$ |
| if (composite == null) throw new IllegalArgumentException("composite can not be null"); //$NON-NLS-1$ |
| this.gc = gc |
| this.composite = composite |
| this.modeSwitcher = modeSwitcher |
| } |
| |
| def getSWTComposite() { composite }
|
| def getModeSwitcher() { modeSwitcher } |
| |
| def getXOffset() { xOffset } |
| def getYOffset() { yOffset } |
| |
| // GraphicsContext interface |
| |
| override pushState() { |
| stateStack.push(originalState) |
| originalState = newHashMap |
| } |
| |
| override popState() { |
| for (property : originalState.keySet) { |
| val originalValue = originalState.get(property) |
| switch (property) { |
| case FOREGROUND_COLOR: gc.foreground = originalValue as org.eclipse.swt.graphics.Color |
| case FOREGROUND_ALPHA: foregroundAlpha = originalValue as Integer |
| case BACKGROUND_COLOR: gc.background = originalValue as org.eclipse.swt.graphics.Color |
| case BACKGROUND_ALPHA: backgroundAlpha = originalValue as Integer |
| case CLIP_BOUNDS: gc.clipping = originalValue as Rectangle |
| case X_OFFSET: xOffset = originalValue as Double |
| case Y_OFFSET: yOffset = originalValue as Double |
| } |
| } |
| originalState = stateStack.pop |
| } |
| |
| override translate(double deltaX, double deltaY) { |
| originalState.put(X_OFFSET, xOffset) |
| originalState.put(Y_OFFSET, yOffset) |
| |
| xOffset = xOffset + deltaX |
| yOffset = yOffset + deltaY |
| } |
| |
| override setForegroundColor(Color foregroundColor) { |
| originalState.put(FOREGROUND_COLOR, gc.foreground) |
| originalState.put(FOREGROUND_ALPHA, foregroundAlpha) |
| |
| gc.foreground = new org.eclipse.swt.graphics.Color( |
| gc.device, |
| foregroundColor.red, |
| foregroundColor.green, |
| foregroundColor.blue |
| ) |
| foregroundAlpha = foregroundColor.alpha |
| } |
| |
| override setBackgroundColor(Color backgroundColor) { |
| originalState.put(BACKGROUND_COLOR, gc.background) |
| originalState.put(BACKGROUND_ALPHA, backgroundAlpha) |
| |
| gc.background = new org.eclipse.swt.graphics.Color( |
| gc.device, |
| backgroundColor.red, |
| backgroundColor.green, |
| backgroundColor.blue |
| ) |
| backgroundAlpha = backgroundColor.alpha |
| } |
| |
| override getClipBounds() { |
| new PixelRectangle((gc.clipping.x - xOffset), gc.clipping.y - yOffset, gc.clipping.width, gc.clipping.height) |
| } |
| |
| override setClipBounds(PixelRectangle clipBounds) { |
| originalState.put(CLIP_BOUNDS, gc.clipping) |
| gc.clipping = new Rectangle((xOffset + clipBounds.x) as int, (yOffset + clipBounds.y) as int, clipBounds.width.intValue, clipBounds.height.intValue) |
| } |
| |
| override drawLine(double x1, double y1, double x2, double y2) { |
| gc.alpha = foregroundAlpha |
| gc.drawLine((xOffset + x1) as int, (yOffset + y1) as int, (xOffset + x2) as int, (yOffset + y2) as int) |
| } |
| |
| override drawRectangle(PixelRectangle rect) { |
| gc.alpha = foregroundAlpha |
| gc.drawRectangle((xOffset + rect.x) as int, (yOffset + rect.y) as int, rect.width.intValue, rect.height.intValue) |
| } |
| |
| override fillRectangle(PixelRectangle rect) { |
| gc.alpha = backgroundAlpha |
| gc.fillRectangle((xOffset + rect.x) as int, (yOffset + rect.y) as int, rect.width.intValue, rect.height.intValue) |
| } |
| |
| override clearRectangle(PixelRectangle rect) { |
| fillRectangle(rect) |
| } |
| |
| override drawText(String text, double x, double y) { |
| gc.alpha = foregroundAlpha |
| gc.drawText(text, (xOffset + x) as int, (yOffset + y) as int, SWT::DRAW_TRANSPARENT.bitwiseOr(SWT::DRAW_DELIMITER)) |
| |
| //TODO draw underline and strikethrough in here instead of the TextPainter itself |
| } |
| |
| override calculateTextWidth(String text) { |
| gc.textExtent(text).x |
| } |
| |
| override getFontHeight() { |
| gc.fontMetrics.height |
| } |
| |
| } |