OSDN Git Service

Add drawing styles to the layout helper API
authorTor Norbye <tnorbye@google.com>
Sat, 2 Oct 2010 01:44:27 +0000 (18:44 -0700)
committerTor Norbye <tnorbye@google.com>
Mon, 4 Oct 2010 20:44:51 +0000 (13:44 -0700)
Pull color constants out of the specific layout helper classes (groovy
scripts) and the canvas editor and use a generic style enum instead in
the interface, and associate the visual attributes (color, line style,
thickness, alpha) with a swt-specific enum on the editor side.  There
is a single new API method which takes an enum parameter, which should
let us add drawing styles over time. By having the color definitions
on the tool side rather in the specific layout helpers it's not only
easier to change the colors but also easier to ensure that the
different helper all stay consistent as we change color schemes.

In the immediate term (next integration) I'll change some of the
colors; after that we should make the colors adapt to the chosen
theme, and eventually these should be provided via the SDK from the
themes themselves.

This changeset doesn't actually change the colors used for the various
types of visual feedback (selection, hover, drop-zone, etc) - I'll
investigate that next. For that reason I also didn't replace all the
various client-side color usage in the RelativeLayout.

Change-Id: Iddf4ace9006ec02d9907c3c37d539ab7414f1371

eclipse/plugins/com.android.ide.eclipse.adt/gscripts/BaseView.groovy
eclipse/plugins/com.android.ide.eclipse.adt/gscripts/android.widget.LinearLayout.groovy
eclipse/plugins/com.android.ide.eclipse.adt/gscripts/android.widget.RelativeLayout.groovy
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/editors/layout/gscripts/DrawingStyle.java [new file with mode: 0644]
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/editors/layout/gscripts/IGraphics.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutEditor.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GCWrapper.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvas.java
eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SwtDrawingStyle.java [new file with mode: 0644]

index aff2e18..9c5b52f 100755 (executable)
@@ -313,14 +313,9 @@ public class BaseView implements IViewRule {
             return;
         }
 
-        gc.setLineWidth(1);
-        gc.setLineStyle(IGraphics.LineStyle.LINE_SOLID);
-        def olgBg = gc.getBackground();
-        gc.setBackground(gc.getForeground());
-        gc.setAlpha(64);
+        gc.useStyle(DrawingStyle.SELECTION_FILL);
         gc.fillRect(r);
-        gc.setBackground(olgBg);
-        gc.setAlpha(255);
+        gc.useStyle(DrawingStyle.SELECTION_BORDER);
         gc.drawRect(r);
 
         if (displayName == null || isMultipleSelection) {
@@ -340,8 +335,7 @@ public class BaseView implements IViewRule {
         Rect rc = childNode.getBounds();
 
         if (rp.isValid() && rc.isValid()) {
-            gc.setLineWidth(1);
-            gc.setLineStyle(IGraphics.LineStyle.LINE_DOT);
+            gc.useStyle(DrawingStyle.ANCHOR);
 
             // top line
             int m = rc.x + rc.w / 2;
index 7f74bfb..1865044 100755 (executable)
@@ -119,11 +119,10 @@ public class AndroidWidgetLinearLayoutRule extends BaseLayout {
         }
 
         // Highlight the receiver
-        gc.setForeground(gc.registerColor(0x00FFFF00));
-        gc.setLineStyle(IGraphics.LineStyle.LINE_SOLID);
-        gc.setLineWidth(2);
+        gc.useStyle(DrawingStyle.DROP_RECIPIENT);
         gc.drawRect(b);
 
+        gc.useStyle(DrawingStyle.DROP_ZONE);
         gc.setLineStyle(IGraphics.LineStyle.LINE_DOT);
         gc.setLineWidth(1);
 
@@ -145,6 +144,8 @@ public class AndroidWidgetLinearLayoutRule extends BaseLayout {
         def currY = feedback.userData.currY;
 
         if (currX != null && currY != null) {
+            gc.useStyle(DrawingStyle.DROP_ZONE_ACTIVE);
+
             int x = currX;
             int y = currY;
 
@@ -278,7 +279,5 @@ public class AndroidWidgetLinearLayoutRule extends BaseLayout {
                 addInnerElements(newChild, element, idMap);
             }
         }
-
-
     }
 }
index 60b5998..2cd34aa 100755 (executable)
@@ -437,15 +437,10 @@ public class AndroidWidgetRelativeLayoutRule extends BaseLayout {
             return;
         }
 
-        def color = gc.registerColor(0x00FF9900);
-        gc.setForeground(color);
-
-        gc.setLineStyle(IGraphics.LineStyle.LINE_SOLID);
-        gc.setLineWidth(2);
+        gc.useStyle(DrawingStyle.DROP_RECIPIENT);
         gc.drawRect(b);
 
-        gc.setLineStyle(IGraphics.LineStyle.LINE_DOT);
-        gc.setLineWidth(1);
+        gc.useStyle(DrawingStyle.DROP_ZONE);
 
         def data = feedback.userData;
 
@@ -456,8 +451,8 @@ public class AndroidWidgetRelativeLayoutRule extends BaseLayout {
         }
 
         if (data.curr) {
+            gc.useStyle(DrawingStyle.DROP_ZONE_ACTIVE);
             gc.setAlpha(200);
-            gc.setBackground(color);
             gc.fillRect(data.curr.rect);
             gc.setAlpha(255);
 
@@ -477,9 +472,6 @@ public class AndroidWidgetRelativeLayoutRule extends BaseLayout {
                 y += h;
             }
 
-            gc.setLineStyle(IGraphics.LineStyle.LINE_SOLID);
-            gc.setLineWidth(2);
-
             def mark = data.curr.get("mark");
             if (mark) {
                 def black = gc.registerColor(0);
@@ -529,9 +521,7 @@ public class AndroidWidgetRelativeLayoutRule extends BaseLayout {
 
         if (data.rejected) {
             def br = data.rejected;
-            gc.setForeground(gc.registerColor(0x000000FF));
-            gc.setLineStyle(IGraphics.LineStyle.LINE_SOLID);
-            gc.setLineWidth(4);
+            gc.useStyle(DrawingStyle.INVALID);
             gc.drawLine(br.x, br.y       , br.x + br.w, br.y + br.h);
             gc.drawLine(br.x, br.y + br.h, br.x + br.w, br.y       );
         }
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/editors/layout/gscripts/DrawingStyle.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/editors/layout/gscripts/DrawingStyle.java
new file mode 100644 (file)
index 0000000..ea6c5e8
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.editors.layout.gscripts;
+
+/**
+ * Drawing styles are used to distinguish the visual appearance of selection,
+ * hovers, anchors, etc. Each style may have different colors, line thickness,
+ * dashing style, transparency, etc.
+ */
+public enum DrawingStyle {
+    /**
+     * The style used for the border of a selected view
+     */
+    SELECTION_BORDER,
+
+    /**
+     * The style used for the interior of a selected view
+     */
+    SELECTION_FILL,
+
+    /**
+     * The style used for hovered views (e.g. when the mouse is directly on top
+     * of the view)
+     */
+    HOVER,
+
+    /**
+     * The style used to draw anchors (lines to the other views the given view
+     * is anchored to)
+     */
+    ANCHOR,
+
+    /**
+     * The style used to draw outlines (the structure of views)
+     */
+    OUTLINE,
+
+    /**
+     * The style used to draw the recipient/target View of a drop. This is
+     * typically going to be the bounding-box of the view into which you are
+     * adding a new child.
+     */
+    DROP_RECIPIENT,
+
+    /**
+     * The style used to draw a potential drop area <b>within</b> a
+     * {@link #DROP_RECIPIENT}. For example, if you are dragging into a view
+     * with a LinearLayout, the {@link #DROP_RECIPIENT} will be the view itself,
+     * whereas each possible insert position between two children will be a
+     * {@link #DROP_ZONE}. If the mouse is over a {@link #DROP_ZONE} it should
+     * be drawn using the style {@link #DROP_ZONE_ACTIVE}.
+     */
+    DROP_ZONE,
+
+    /**
+     * The style used to draw a currently active drop zone within a drop
+     * recipient. See the documentation for {@link #DROP_ZONE} for details on
+     * the distinction between {@link #DROP_RECIPIENT}, {@link #DROP_ZONE} and
+     * {@link #DROP_ZONE_ACTIVE}.
+     */
+    DROP_ZONE_ACTIVE,
+
+    /**
+     * The style used to raw illegal/error/invalid markers
+     */
+    INVALID,
+
+    /**
+     * A style used for unspecified purposes; can be used by a client to have
+     * yet another color that is domain specific; using this color constant
+     * rather than your own hardcoded value means that you will be guaranteed to
+     * pick up a color that is themed properly and will look decent with the
+     * rest of the colors
+     */
+    CUSTOM1,
+
+    /**
+     * A second styled used for unspecified purposes; see {@link #CUSTOM1} for
+     * details.
+     */
+    CUSTOM2
+}
index 22a3a6d..7c1dc15 100755 (executable)
@@ -27,13 +27,90 @@ package com.android.ide.eclipse.adt.editors.layout.gscripts;
 public interface IGraphics {
 
     /**
-     * Registers a color using 0x00rrggbb where each component is
-     * 0..0xFF.
+     * Draws a line between 2 points, using the current foreground color and
+     * alpha.
+     */
+    void drawLine(int x1, int y1, int x2, int y2);
+
+    /**
+     * Draws a line between 2 points, using the current foreground color and
+     * alpha.
+     */
+    void drawLine(Point p1, Point p2);
+
+    /**
+     * Draws a rectangle outline between 2 points, using the current foreground
+     * color and alpha.
+     */
+    void drawRect(int x1, int y1, int x2, int y2);
+
+    /**
+     * Draws a rectangle outline between 2 points, using the current foreground
+     * color and alpha.
+     */
+    void drawRect(Point p1, Point p2);
+
+    /**
+     * Draws a rectangle outline between 2 points, using the current foreground
+     * color and alpha.
+     */
+    void drawRect(Rect r);
+
+    /**
+     * Fills a rectangle outline between 2 points, using the current background
+     * color and alpha.
+     */
+    void fillRect(int x1, int y1, int x2, int y2);
+
+    /**
+     * Fills a rectangle outline between 2 points, using the current background
+     * color and alpha.
+     */
+    void fillRect(Point p1, Point p2);
+
+    /**
+     * Fills a rectangle outline between 2 points, using the current background
+     * color and alpha.
+     */
+    void fillRect(Rect r);
+
+    /**
+     * Draws the given string, using the current foreground color. No tab
+     * expansion or carriage return processing will be performed.
+     *
+     * @param string the string to be drawn.
+     * @param x the x coordinate of the top left corner of the text.
+     * @param y the y coordinate of the top left corner of the text.
+     */
+    void drawString(String string, int x, int y);
+
+    /**
+     * Draws the given string, using the current foreground color. No tab
+     * expansion or carriage return processing will be performed.
+     *
+     * @param string the string to be drawn.
+     * @param topLeft the top left corner of the text.
+     */
+    void drawString(String string, Point topLeft);
+
+    /**
+     * Set up the graphics context to use the given style for subsequent drawing
+     * operations.
+     *
+     * @param style The drawing style to be used. May not be null.
+     */
+    void useStyle(DrawingStyle style);
+
+    /**
+     * Registers a color using 0x00rrggbb where each component is 0..0xFF.
      * <p/>
      * Transparency is handled separately using {@link #setAlpha(int)}.
      * <p/>
-     * If the same color is registered twice, the same object will
-     * be returned.
+     * If the same color is registered twice, the same object will be returned.
+     * <p/>
+     * NOTE: It's preferable to use {@link #useStyle(DrawingStyle)} if possible
+     * to ensure that your colors work properly across multiple current and
+     * future themes.
      */
     IColor registerColor(int rgb);
 
@@ -49,24 +126,32 @@ public interface IGraphics {
     IColor getForeground();
 
     /**
-     * Returns the current background color.
-     * The background color is used for fill operations.
+     * Sets the foreground color. The foreground color is used for drawing
+     * operations including when text is drawn.
      */
-    IColor getBackground();
+    void setForeground(IColor color);
 
     /**
-     * Sets the foreground color. The foreground color is used
-     * for drawing operations including when text is drawn.
+     * Returns the current background color. The background color is used for
+     * fill operations.
      */
-    void setForeground(IColor color);
+    IColor getBackground();
 
     /**
-     * Sets the background color. The background color is used
-     * for fill operations.
+     * Sets the background color. The background color is used for fill
+     * operations.
      */
     void setBackground(IColor color);
 
     /**
+     * Returns the current alpha value (varies between 0 for transparent and 255
+     * for opaque).
+     * 
+     * @return The current alpha value in use
+     */
+    int getAlpha();
+
+    /**
      * Sets the receiver's alpha value which must be
      * between 0 (transparent) and 255 (opaque).
      * <p>
@@ -104,66 +189,4 @@ public interface IGraphics {
      * The operation is ignored if <var>width</var> is less than 1.
      */
     void setLineWidth(int width);
-
-    /**
-     * Draws a line between 2 points, using the current foreground
-     * color and alpha.
-     */
-    void drawLine(int x1, int y1, int x2, int y2);
-    /**
-     * Draws a line between 2 points, using the current foreground
-     * color and alpha.
-     */
-    void drawLine(Point p1, Point p2);
-
-    /**
-     * Draws a rectangle outline between 2 points, using the current
-     * foreground color and alpha.
-     */
-    void drawRect(int x1, int y1, int x2, int y2);
-    /**
-     * Draws a rectangle outline between 2 points, using the current
-     * foreground color and alpha.
-     */
-    void drawRect(Point p1, Point p2);
-    /**
-     * Draws a rectangle outline between 2 points, using the current
-     * foreground color and alpha.
-     */
-    void drawRect(Rect r);
-
-    /**
-     * Fills a rectangle outline between 2 points, using the current
-     * background color and alpha.
-     */
-    void fillRect(int x1, int y1, int x2, int y2);
-    /**
-     * Fills a rectangle outline between 2 points, using the current
-     * background color and alpha.
-     */
-    void fillRect(Point p1, Point p2);
-    /**
-     * Fills a rectangle outline between 2 points, using the current
-     * background color and alpha.
-     */
-    void fillRect(Rect r);
-
-    /**
-     * Draws the given string, using the current foreground color.
-     * No tab expansion or carriage return processing will be performed.
-     *
-     * @param string the string to be drawn.
-     * @param x the x coordinate of the top left corner of the text.
-     * @param y the y coordinate of the top left corner of the text.
-     */
-    void drawString(String string, int x, int y);
-
-    /**
-     * Draws the given string, using the current foreground color.
-     * No tab expansion or carriage return processing will be performed.
-     *
-     * @param string the string to be drawn.
-     * @param topLeft the top left corner of the text.
-     */
-    void drawString(String string, Point topLeft);
 }
index 8560fa8..d6e8f0c 100644 (file)
@@ -545,7 +545,7 @@ public class LayoutEditor extends AndroidXmlEditor implements IShowEditorInput,
      * the requested FQCN.
      *
      * @param fqcn The target View FQCN to find.
-     * @param descriptors A list of cildren descriptors to iterate through.
+     * @param descriptors A list of children descriptors to iterate through.
      * @param visited A set we use to remember which descriptors have already been visited,
      *  necessary since the view descriptor hierarchy is cyclic.
      * @return Either a matching {@link ViewElementDescriptor} or null.
index 3648639..2927c0e 100755 (executable)
@@ -16,6 +16,7 @@
 
 package com.android.ide.eclipse.adt.internal.editors.layout.gle2;
 
+import com.android.ide.eclipse.adt.editors.layout.gscripts.DrawingStyle;
 import com.android.ide.eclipse.adt.editors.layout.gscripts.IColor;
 import com.android.ide.eclipse.adt.editors.layout.gscripts.IGraphics;
 import com.android.ide.eclipse.adt.editors.layout.gscripts.IViewRule;
@@ -27,8 +28,11 @@ import org.eclipse.swt.SWTException;
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.FontMetrics;
 import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.RGB;
 
+import java.util.EnumMap;
 import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Wraps an SWT {@link GC} into an {@link IGraphics} interface so that {@link IViewRule} objects
@@ -63,6 +67,13 @@ public class GCWrapper implements IGraphics {
     /** A map of registered colors. All these colors must be disposed at the end. */
     private final HashMap<Integer, ColorWrapper> mColorMap = new HashMap<Integer, ColorWrapper>();
 
+    /**
+     * A map of the {@link SwtDrawingStyle} colors that we have actually used
+     * (to be disposed)
+     */
+    private final Map<DrawingStyle, Color> mStyleColorMap = new EnumMap<DrawingStyle, Color>(
+            DrawingStyle.class);
+
     /** The cached pixel height of the default current font. */
     private int mFontHeight = 0;
 
@@ -96,6 +107,11 @@ public class GCWrapper implements IGraphics {
             c.getColor().dispose();
         }
         mColorMap.clear();
+
+        for (Color c : mStyleColorMap.values()) {
+            c.dispose();
+        }
+        mStyleColorMap.clear();
     }
 
     //-------------
@@ -136,6 +152,10 @@ public class GCWrapper implements IGraphics {
         return new ColorWrapper(c);
     }
 
+    public int getAlpha() {
+        return getGc().getAlpha();
+    }
+
     public void setForeground(IColor color) {
         checkGC();
         getGc().setForeground(((ColorWrapper) color).getColor());
@@ -309,4 +329,48 @@ public class GCWrapper implements IGraphics {
     public void drawString(String string, Point topLeft) {
         drawString(string, topLeft.x, topLeft.y);
     }
+
+    // Styles
+
+    public void useStyle(DrawingStyle style) {
+        checkGC();
+
+        // Look up the specific SWT style which defines the actual
+        // colors and attributes to be used for the logical drawing style.
+        SwtDrawingStyle swtStyle = SwtDrawingStyle.of(style);
+        RGB fg = swtStyle.getForeground();
+        if (fg != null) {
+            Color color = getStyleColor(style, fg);
+            mGc.setForeground(color);
+        }
+        RGB bg = swtStyle.getBackground();
+        if (bg != null) {
+            Color color = getStyleColor(style, bg);
+            mGc.setBackground(color);
+        }
+        mGc.setLineWidth(swtStyle.getLineWidth());
+        mGc.setLineStyle(swtStyle.getLineStyle());
+        mGc.setAlpha(swtStyle.getAlpha());
+    }
+
+    /**
+     * Get the SWT color to use for the given style, using the provided color
+     * description if we haven't seen this color yet. The color will also be
+     * placed in the {@link #mStyleColorMap} such that it can be disposed of at
+     * cleanup time.
+     *
+     * @param style The drawing style for which we want a color
+     * @param defaultColorDesc The RGB values to initialize the color to if we
+     *            haven't seen this color before
+     * @return The color object
+     */
+    private Color getStyleColor(DrawingStyle style, RGB defaultColorDesc) {
+        Color color = mStyleColorMap.get(style);
+        if (color == null) {
+            color = new Color(getGc().getDevice(), defaultColorDesc);
+            mStyleColorMap.put(style, color);
+        }
+
+        return color;
+    }
 }
index 5a1bb6f..237deb8 100755 (executable)
@@ -287,9 +287,9 @@ class LayoutCanvas extends Canvas implements ISelectionProvider {
         mGCWrapper = new GCWrapper(mHScale, mVScale);
 
         Display d = getDisplay();
-        mSelectionFgColor = d.getSystemColor(SWT.COLOR_RED);
-        mHoverFgColor     = new Color(d, 0xFF, 0x99, 0x00); // orange
-        mOutlineColor     = d.getSystemColor(SWT.COLOR_GREEN);
+        mSelectionFgColor = new Color(d, SwtDrawingStyle.SELECTION_BORDER.getForeground());
+        mHoverFgColor     = new Color(d, SwtDrawingStyle.HOVER.getForeground());
+        mOutlineColor     = new Color(d, SwtDrawingStyle.OUTLINE.getForeground());
 
         mFont = d.getSystemFont();
 
@@ -962,13 +962,13 @@ class LayoutCanvas extends Canvas implements ISelectionProvider {
 
             if (mShowOutline && mLastValidViewInfoRoot != null) {
                 gc.setForeground(mOutlineColor);
-                gc.setLineStyle(SWT.LINE_DOT);
+                gc.setLineStyle(SwtDrawingStyle.OUTLINE.getLineStyle());
                 drawOutline(gc, mLastValidViewInfoRoot);
             }
 
             if (mHoverRect != null) {
                 gc.setForeground(mHoverFgColor);
-                gc.setLineStyle(SWT.LINE_DOT);
+                gc.setLineStyle(SwtDrawingStyle.HOVER.getLineStyle());
 
                 int x = mHScale.translate(mHoverRect.x);
                 int y = mVScale.translate(mHoverRect.y);
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SwtDrawingStyle.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SwtDrawingStyle.java
new file mode 100644 (file)
index 0000000..1d30c7b
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.internal.editors.layout.gle2;
+
+import com.android.ide.eclipse.adt.editors.layout.gscripts.DrawingStyle;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.RGB;
+
+/**
+ * Description of the drawing styles with specific color, line style and alpha
+ * definitions. This class corresponds to the more generic {@link DrawingStyle}
+ * class which defines the drawing styles but does not introduce any specific
+ * SWT values to the API clients.
+ * <p>
+ * TODO: This class should eventually pick up theme preferences.
+ */
+public enum SwtDrawingStyle {
+    /**
+     * The style used for the border of a selected view
+     */
+    SELECTION_BORDER(new RGB(0xFF, 0x00, 0x00), null, 1, SWT.LINE_SOLID, 255),
+
+    /**
+     * The style used for the interior of a selected view
+     */
+    SELECTION_FILL(null, new RGB(0xFF, 0x00, 0x00), 1, SWT.LINE_SOLID, 64),
+
+    /**
+     * The style used for hovered views (e.g. when the mouse is directly on top
+     * of the view)
+     */
+    HOVER(new RGB(0xFF, 0x99, 0x00), null, 1, SWT.LINE_DOT, 255),
+
+    /**
+     * The style used to draw anchors (lines to the other views the given view
+     * is anchored to)
+     */
+    ANCHOR(new RGB(0xFF, 0x00, 0x00), null, 1, SWT.LINE_SOLID, 255),
+
+    /**
+     * The style used to draw outlines (the structure of views)
+     */
+    OUTLINE(new RGB(0x00, 0xFF, 0x00), null, 1, SWT.LINE_DOT, 255),
+
+    /**
+     * The style used to draw the recipient/target View of a drop. This is
+     * typically going to be the bounding-box of the view into which you are
+     * adding a new child.
+     */
+    DROP_RECIPIENT(new RGB(0xFF, 0x99, 0x00), new RGB(0xFF, 0x99, 0x00), 1, SWT.LINE_SOLID, 255),
+
+    /**
+     * The style used to draw a potential drop area <b>within</b> a
+     * {@link #DROP_RECIPIENT}. For example, if you are dragging into a view
+     * with a LinearLayout, the {@link #DROP_RECIPIENT} will be the view itself,
+     * whereas each possible insert position between two children will be a
+     * {@link #DROP_ZONE}. If the mouse is over a {@link #DROP_ZONE} it should
+     * be drawn using the style {@link #DROP_ZONE_ACTIVE}.
+     */
+    DROP_ZONE(new RGB(0xFF, 0x99, 0x00), new RGB(0xFF, 0x99, 0x00), 1, SWT.LINE_DOT, 255),
+
+    /**
+     * The style used to draw a currently active drop zone within a drop
+     * recipient. See the documentation for {@link #DROP_ZONE} for details on
+     * the distinction between {@link #DROP_RECIPIENT}, {@link #DROP_ZONE} and
+     * {@link #DROP_ZONE_ACTIVE}.
+     */
+    DROP_ZONE_ACTIVE(new RGB(0xFF, 0x99, 0x00), new RGB(0xFF, 0x99, 0x00), 1, SWT.LINE_SOLID, 255),
+
+    /**
+     * The style used to raw illegal/error/invalid markers
+     */
+    INVALID(new RGB(0x00, 0x00, 0xFF), null, 3, SWT.LINE_SOLID, 255),
+
+    /**
+     * A style used for unspecified purposes; can be used by a client to have
+     * yet another color that is domain specific; using this color constant
+     * rather than your own hardcoded value means that you will be guaranteed to
+     * pick up a color that is themed properly and will look decent with the
+     * rest of the colors
+     */
+    CUSTOM1(new RGB(0xFF, 0x00, 0xFF), null, 1, SWT.LINE_SOLID, 255),
+
+    /**
+     * A second styled used for unspecified purposes; see {@link #CUSTOM1} for
+     * details.
+     */
+    CUSTOM2(new RGB(0x00, 0xFF, 0xFF), null, 1, SWT.LINE_DOT, 255);
+
+    /**
+     * Construct a new style value with the given foreground, background, width,
+     * linestyle and transparency.
+     *
+     * @param fg A color descriptor for the foreground color, or null if no
+     *            foreground color should be set
+     * @param bg A color descriptor for the background color, or null if no
+     *            foreground color should be set
+     * @param width The line width, in pixels, or 0 if no line width should be
+     *            set
+     * @param lineStyle The SWT line style - such as {@link SWT#LINE_SOLID}.
+     * @param alpha The alpha value, an integer in the range 0 to 255 where 0 is
+     *            fully transparent and 255 is fully opaque.
+     */
+    private SwtDrawingStyle(RGB fg, RGB bg, int width, int lineStyle, int alpha) {
+        mFg = fg;
+        mBg = bg;
+        mWidth = width;
+        mLineStyle = lineStyle;
+        mAlpha = alpha;
+    }
+
+    /**
+     * Return the foreground RGB color description to be used for this style, or
+     * null if none
+     */
+    public RGB getForeground() {
+        return mFg;
+    }
+
+    /**
+     * Return the background RGB color description to be used for this style, or
+     * null if none
+     */
+    public RGB getBackground() {
+        return mBg;
+    }
+
+    /** Return the line width to be used for this style */
+    public int getLineWidth() {
+        return mWidth;
+    }
+
+    /** Return the SWT line style to be used for this style */
+    public int getLineStyle() {
+        return mLineStyle;
+    }
+
+    /** Return the alpha value (in the range 0,255) to be used for this style */
+    public int getAlpha() {
+        return mAlpha;
+    }
+
+    /**
+     * Return the corresponding SwtDrawingStyle for the given
+     * {@link DrawingStyle}
+     */
+    public static SwtDrawingStyle of(DrawingStyle style) {
+        switch (style) {
+            case SELECTION_BORDER:
+                return SELECTION_BORDER;
+            case SELECTION_FILL:
+                return SELECTION_FILL;
+            case HOVER:
+                return HOVER;
+            case ANCHOR:
+                return ANCHOR;
+            case OUTLINE:
+                return OUTLINE;
+            case DROP_ZONE:
+                return DROP_ZONE;
+            case DROP_ZONE_ACTIVE:
+                return DROP_ZONE_ACTIVE;
+            case DROP_RECIPIENT:
+                return DROP_RECIPIENT;
+            case INVALID:
+                return INVALID;
+            case CUSTOM1:
+                return CUSTOM1;
+            case CUSTOM2:
+                return CUSTOM2;
+
+                // Internal error
+            default:
+                throw new IllegalArgumentException("Unknown style " + style);
+        }
+    }
+
+    private final RGB mFg;
+
+    private final RGB mBg;
+
+    private final int mWidth;
+
+    private final int mLineStyle;
+
+    private final int mAlpha;
+}