blob: 6e301aaf0914e9842a45b3e13c6f040155455eb6 [file] [log] [blame]
package org.eclipse.nebula.widgets.nattable.renderer.swt.graphics
import java.util.HashMap
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.core.graphics.GraphicsPropertiesEnum
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.core.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 {
val Composite composite
/**
* The SWT {@link GC} which is proxied by this implementation.
*/
val GC gc
val stateStack = new Stack<Map<GraphicsPropertiesEnum, Object>>
Map<GraphicsPropertiesEnum, Object> originalState = newHashMap
int xOffset
int yOffset
/**
* Create a new proxy instance for the specified {@link GC}.
* @param gc The SWT {@link GC} which is proxied by this implementation.
*/
new(Composite composite, GC gc) {
if (composite == null) throw new IllegalArgumentException("composite can not be null"); //$NON-NLS-1$
if (gc == null) throw new IllegalArgumentException("gc can not be null"); //$NON-NLS-1$
this.composite = composite
this.gc = gc
}
def getSWTComposite() {
composite
}
def getXOffset() { xOffset }
def getYOffset() { yOffset }
// GraphicsContext interface
override pushState() {
stateStack.push(originalState)
originalState = new HashMap<GraphicsPropertiesEnum, Object>
}
override popState() {
for (property : originalState.keySet) {
switch (property) {
case FOREGROUND_COLOR: gc.foreground = originalState.get(property) as org.eclipse.swt.graphics.Color
case BACKGROUND_COLOR: gc.background = originalState.get(property) as org.eclipse.swt.graphics.Color
case CLIP_BOUNDS: gc.clipping = originalState.get(property) as Rectangle
case X_OFFSET: xOffset = originalState.get(property) as Integer
case Y_OFFSET: yOffset = originalState.get(property) as Integer
}
}
originalState = stateStack.pop
}
override translate(int deltaX, int 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)
gc.foreground = new org.eclipse.swt.graphics.Color(
gc.device,
foregroundColor.red,
foregroundColor.green,
foregroundColor.blue
)
}
override setBackgroundColor(Color backgroundColor) {
originalState.put(BACKGROUND_COLOR, gc.background)
gc.background = new org.eclipse.swt.graphics.Color(
gc.device,
backgroundColor.red,
backgroundColor.green,
backgroundColor.blue
)
}
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, yOffset + clipBounds.y, clipBounds.width, clipBounds.height)
}
override drawLine(int x1, int y1, int x2, int y2) {
gc.drawLine(xOffset + x1, yOffset + y1, xOffset + x2, yOffset + y2)
}
override drawRectangle(PixelRectangle rect) {
gc.drawRectangle(rect.x, rect.y, rect.width, rect.height)
}
override fillRectangle(PixelRectangle rect) {
gc.fillRectangle(rect.x, rect.y, rect.width, rect.height)
}
override drawText(String text, int x, int y) {
gc.drawText(text, xOffset + x, yOffset + y, 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
}
}