Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/BufferedCanvas.java')
-rwxr-xr-xvisualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/BufferedCanvas.java201
1 files changed, 201 insertions, 0 deletions
diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/BufferedCanvas.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/BufferedCanvas.java
new file mode 100755
index 00000000000..b4f2778cef4
--- /dev/null
+++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/BufferedCanvas.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Tilera Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William R. Swanson (Tilera Corporation)
+ *******************************************************************************/
+
+package org.eclipse.cdt.visualizer.ui.canvas;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+
+// ---------------------------------------------------------------------------
+// BufferedCanvas
+// ---------------------------------------------------------------------------
+
+/** Canvas control with double-buffering support. */
+public class BufferedCanvas extends Canvas
+ implements PaintListener, ControlListener
+{
+ // --- members ---
+
+ /** double-buffering image */
+ protected Image m_doubleBuffer = null;
+
+ /** buffer GC */
+ protected GC m_doubleBufferGC = null;
+
+
+ // --- constructors/destructors ---
+
+ /** Constructor. */
+ public BufferedCanvas(Composite parent) {
+ super(parent,
+ SWT.NO_BACKGROUND | // don't automatically clear background on paint event
+ SWT.NO_REDRAW_RESIZE // don't automatically repaint on resize event
+ );
+ initBufferedCanvas();
+ }
+
+ /** Dispose method. */
+ public void dispose() {
+ super.dispose();
+ cleanupBufferedCanvas();
+ }
+
+ // --- init methods ---
+
+ /** Initializes control. */
+ protected void initBufferedCanvas() {
+ addControlListener(this);
+ addPaintListener(this);
+ }
+
+ /** Cleans up control. */
+ protected void cleanupBufferedCanvas() {
+ removePaintListener(this);
+ removeControlListener(this);
+ if (m_doubleBuffer != null) {
+ m_doubleBuffer.dispose();
+ m_doubleBuffer = null;
+ }
+ }
+
+
+ // --- event handlers ---
+
+ /** Invoked when control is moved/resized */
+ public void controlMoved(ControlEvent e) {
+ // do nothing, we don't care
+ }
+
+ /** Invoked when control is resized */
+ public void controlResized(ControlEvent e) {
+ resized(getBounds());
+ }
+
+
+ // --- resize methods ---
+
+ /** Invoked when control is resized.
+ * Default implementation does nothing,
+ * intended to be overridden by derived types.
+ */
+ public void resized(Rectangle bounds) {
+
+ }
+
+
+ // --- GC management ---
+
+ /** Gets/creates GC for current background buffer.
+ * NOTE: The GC is disposed whenever the canvas size changes,
+ * so caller should not retain a reference to this GC.
+ */
+ protected synchronized GC getBufferedGC() {
+ if (m_doubleBufferGC == null) {
+
+ m_doubleBufferGC = new GC(m_doubleBuffer);
+ }
+ return m_doubleBufferGC;
+ }
+
+ /** Disposes of current background buffer GC. */
+ protected synchronized void disposeBufferedGC() {
+ if (m_doubleBufferGC != null) {
+ m_doubleBufferGC.dispose();
+ m_doubleBufferGC = null;
+ }
+ }
+
+
+ // --- paint methods ---
+
+ /** Invoked when control needs to be repainted */
+ public void paintControl(PaintEvent e) {
+ // Handle last paint event of a cluster.
+ if (e.count<=1) {
+ Display display = e.display;
+ GC gc = e.gc;
+ paintDoubleBuffered(display, gc);
+ }
+ }
+
+ /** Internal -- handles double-buffering support, calls paintCanvas() */
+ // NOTE: need display to create image buffer, not for painting code
+ protected void paintDoubleBuffered(Display display, GC gc) {
+ // get/create background image buffer
+ Rectangle clientArea = getClientArea();
+ int width = clientArea.width;
+ int height = clientArea.height;
+ if (m_doubleBuffer == null
+ || m_doubleBuffer.getBounds().width < width
+ || m_doubleBuffer.getBounds().height < height)
+ {
+ m_doubleBuffer = new Image(display, width, height);
+ disposeBufferedGC();
+ }
+
+ // create graphics context for buffer
+ GC bgc = getBufferedGC();
+
+ // copy current GC properties into it as defaults
+ bgc.setBackground(gc.getBackground());
+ bgc.setForeground(gc.getForeground());
+ bgc.setFont(gc.getFont());
+ bgc.setAlpha(255);
+
+ // invoke paintCanvas() method to paint into the buffer
+ try {
+ paintCanvas(bgc);
+ }
+ catch (Throwable t) {
+ // Throwing an exception in painting code can hang Eclipse,
+ // so catch any exceptions here.
+ System.err.println("BufferedCanvas: Exception thrown in painting code: \n" + t);
+ }
+
+ // then copy image buffer to actual canvas (reduces repaint flickering)
+ gc.drawImage(m_doubleBuffer, 0,0);
+ }
+
+ /** Invoked when canvas repaint event is raised.
+ * Default implementation clears canvas to background color.
+ */
+ public void paintCanvas(GC gc) {
+ clearCanvas(gc);
+ }
+
+ /** Clears canvas to background color. */
+ public void clearCanvas(GC gc) {
+ Rectangle bounds = getClientArea();
+ gc.fillRectangle(bounds);
+ }
+
+
+ // --- update methods ---
+
+ /** Redraws control */
+ public void update() {
+ // guard against update events that happen
+ // after app has shut down
+ if (! isDisposed()) {
+ redraw();
+ }
+ }
+}

Back to the top