blob: 63150d5c390fdea66047bc36d8390cde67f3a74d [file] [log] [blame]
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
}
}