package org.eclipse.swt.examples.paint; | |
/* | |
* (c) Copyright IBM Corp. 2000, 2002. | |
* This file is made available under the terms of the Common Public License v1.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/cpl-v10.html | |
*/ | |
import org.eclipse.jface.action.*; | |
import org.eclipse.jface.resource.*; | |
import org.eclipse.swt.*; | |
import org.eclipse.swt.events.*; | |
import org.eclipse.swt.graphics.*; | |
import org.eclipse.swt.layout.*; | |
import org.eclipse.swt.widgets.*; | |
import org.eclipse.ui.*; | |
import org.eclipse.ui.part.*; | |
import java.net.*; | |
import java.util.*; | |
/** | |
* The view for the paint application. | |
* All rendering happens inside the area created by createPartControl(). | |
* | |
* @see ViewPart | |
*/ | |
public class PaintView extends ViewPart { | |
private Display workbenchDisplay; | |
// current active settings | |
private ToolSettings toolSettings; | |
// paint surface for drawing | |
private PaintSurface paintSurface; | |
// map action ids to useful data | |
private HashMap /* of String to PaintTool */ paintToolMap; | |
private HashMap /* of String to Integer */ paintFillTypeMap; | |
private HashMap /* of String to Integer */ paintLineStyleMap; | |
/** UI data **/ | |
// handle of currently active tool IAction on the UI | |
private IAction activeToolAction; | |
// handle of currently active filltype IAction on the UI | |
private IAction activeFillTypeAction; | |
// handle of currently active linetype IAction on the UI | |
private IAction activeLineStyleAction; | |
// handle of active foreground color box Canvas widget | |
private Canvas activeForegroundColorCanvas; | |
// handle of active background color box Canvas widget | |
private Canvas activeBackgroundColorCanvas; | |
private static final int numPaletteRows = 3; | |
private static final int numPaletteCols = 50; | |
// shared data | |
private Color paintColorBlack, paintColorWhite; // alias for paintColors[0] and [1] | |
private Color[] paintColors; | |
private Font paintDefaultFont; // do not free | |
/** | |
* Constructs a Paint view. | |
*/ | |
public PaintView() { | |
} | |
/** | |
* Cleanup | |
*/ | |
public void dispose() { | |
if (paintSurface != null) paintSurface.dispose(); | |
if (paintColors != null) { | |
for (int i = 0; i < paintColors.length; ++i) { | |
final Color color = paintColors[i]; | |
if (color != null) color.dispose(); | |
} | |
} | |
paintDefaultFont = null; | |
paintColors = null; | |
paintSurface = null; | |
super.dispose(); | |
} | |
/** | |
* Called when we must grab focus. | |
* | |
* @see org.eclipse.ui.part.ViewPart#setFocus | |
*/ | |
public void setFocus() { | |
paintSurface.setFocus(); | |
} | |
/** | |
* Creates the example. | |
* | |
* @see ViewPart#createPartControl | |
*/ | |
public void createPartControl(Composite parent) { | |
/*** Initialize shared data ***/ | |
workbenchDisplay = parent.getDisplay(); | |
paintColorWhite = new Color(workbenchDisplay, 255, 255, 255); | |
paintColorBlack = new Color(workbenchDisplay, 0, 0, 0); | |
paintDefaultFont = workbenchDisplay.getSystemFont(); | |
paintColors = new Color[numPaletteCols * numPaletteRows]; | |
paintColors[0] = paintColorBlack; | |
paintColors[1] = paintColorWhite; | |
for (int i = 2; i < paintColors.length; i++) { | |
paintColors[i] = new Color(workbenchDisplay, | |
((i*7)%255),((i*23)%255), ((i*51)%255)); | |
} | |
toolSettings = new ToolSettings(); | |
toolSettings.commonForegroundColor = paintColorBlack; | |
toolSettings.commonBackgroundColor = paintColorWhite; | |
toolSettings.commonFont = paintDefaultFont; | |
/*** Add toolbar contributions ***/ | |
final IActionBars actionBars = getViewSite().getActionBars(); | |
IToolBarManager toolbarManager = actionBars.getToolBarManager(); | |
toolbarManager.add(new GroupMarker("group.tools")); | |
toolbarManager.appendToGroup("group.tools", new SelectPaintToolAction("tool.Pencil")); | |
toolbarManager.appendToGroup("group.tools", new SelectPaintToolAction("tool.Airbrush")); | |
toolbarManager.appendToGroup("group.tools", new SelectPaintToolAction("tool.Line")); | |
toolbarManager.appendToGroup("group.tools", new SelectPaintToolAction("tool.PolyLine")); | |
toolbarManager.appendToGroup("group.tools", new SelectPaintToolAction("tool.Rectangle")); | |
toolbarManager.appendToGroup("group.tools", new SelectPaintToolAction("tool.RoundedRectangle")); | |
toolbarManager.appendToGroup("group.tools", new SelectPaintToolAction("tool.Ellipse")); | |
toolbarManager.appendToGroup("group.tools", new SelectPaintToolAction("tool.Text")); | |
toolbarManager.add(new Separator()); | |
toolbarManager.add(new GroupMarker("group.options.fill")); | |
toolbarManager.appendToGroup("group.options.fill", new SelectFillTypeAction("fill.None")); | |
toolbarManager.appendToGroup("group.options.fill", new SelectFillTypeAction("fill.Outline")); | |
toolbarManager.appendToGroup("group.options.fill", new SelectFillTypeAction("fill.Solid")); | |
toolbarManager.add(new Separator()); | |
toolbarManager.add(new GroupMarker("group.options.linestyle")); | |
toolbarManager.appendToGroup("group.options.linestyle", new SelectLineStyleAction("linestyle.Solid")); | |
toolbarManager.appendToGroup("group.options.linestyle", new SelectLineStyleAction("linestyle.Dash")); | |
toolbarManager.appendToGroup("group.options.linestyle", new SelectLineStyleAction("linestyle.Dot")); | |
toolbarManager.appendToGroup("group.options.linestyle", new SelectLineStyleAction("linestyle.DashDot")); | |
toolbarManager.add(new Separator()); | |
toolbarManager.add(new GroupMarker("group.options")); | |
toolbarManager.appendToGroup("group.options", new SelectFontAction("options.Font")); | |
actionBars.updateActionBars(); | |
/*** Build GUI ***/ | |
createGUI(parent); | |
/*** Set defaults ***/ | |
setPaintToolByID("tool.Pencil"); | |
setFillTypeByID("fill.None"); | |
setLineStyleByID("linestyle.Solid"); | |
setForegroundColor(paintColorBlack); | |
setBackgroundColor(paintColorWhite); | |
} | |
/** | |
* Creates the GUI. | |
*/ | |
private void createGUI(Composite parent) { | |
GridLayout gridLayout; | |
GridData gridData; | |
/*** Create principal GUI layout elements ***/ | |
Composite displayArea = new Composite(parent, SWT.NONE); | |
gridLayout = new GridLayout(); | |
gridLayout.numColumns = 1; | |
displayArea.setLayout(gridLayout); | |
// Creating these elements here avoids the need to instantiate the GUI elements | |
// in strict layout order. The natural layout ordering is an artifact of using | |
// SWT layouts, but unfortunately it is not the same order as that required to | |
// instantiate all of the non-GUI application elements to satisfy referential | |
// dependencies. It is possible to reorder the initialization to some extent, but | |
// this can be very tedious. | |
// paint canvas | |
final Canvas paintCanvas = new Canvas(displayArea, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | | |
SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND); | |
gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL); | |
paintCanvas.setLayoutData(gridData); | |
paintCanvas.setBackground(paintColorWhite); | |
// color selector frame | |
final Composite colorFrame = new Composite(displayArea, SWT.NONE); | |
gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL); | |
colorFrame.setLayoutData(gridData); | |
// tool settings frame | |
final Composite toolSettingsFrame = new Composite(displayArea, SWT.NONE); | |
gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL); | |
toolSettingsFrame.setLayoutData(gridData); | |
// status text | |
final Text statusText = new Text(displayArea, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); | |
gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL); | |
statusText.setLayoutData(gridData); | |
/*** Create the remaining application elements inside the principal GUI layout elements ***/ | |
// paintSurface | |
paintSurface = new PaintSurface(paintCanvas, statusText, paintColorWhite); | |
// paintToolMap | |
paintToolMap = new HashMap(); | |
paintToolMap.put("tool.Pencil", new PencilTool(toolSettings, paintSurface)); | |
paintToolMap.put("tool.Airbrush", new AirbrushTool(toolSettings, paintSurface)); | |
paintToolMap.put("tool.Line", new LineTool(toolSettings, paintSurface)); | |
paintToolMap.put("tool.PolyLine", new PolyLineTool(toolSettings, paintSurface)); | |
paintToolMap.put("tool.Rectangle", new RectangleTool(toolSettings, paintSurface)); | |
paintToolMap.put("tool.RoundedRectangle", new RoundedRectangleTool(toolSettings, paintSurface)); | |
paintToolMap.put("tool.Ellipse", new EllipseTool(toolSettings, paintSurface)); | |
paintToolMap.put("tool.Text", new TextTool(toolSettings, paintSurface)); | |
paintToolMap.put("tool.Null", null); | |
// paintFillTypeMap | |
paintFillTypeMap = new HashMap(); | |
paintFillTypeMap.put("fill.None", new Integer(ToolSettings.ftNone)); | |
paintFillTypeMap.put("fill.Outline", new Integer(ToolSettings.ftOutline)); | |
paintFillTypeMap.put("fill.Solid", new Integer(ToolSettings.ftSolid)); | |
// paintLineStyleMap | |
paintLineStyleMap = new HashMap(); | |
paintLineStyleMap.put("linestyle.Solid", new Integer(SWT.LINE_SOLID)); | |
paintLineStyleMap.put("linestyle.Dash", new Integer(SWT.LINE_DASH)); | |
paintLineStyleMap.put("linestyle.Dot", new Integer(SWT.LINE_DOT)); | |
paintLineStyleMap.put("linestyle.DashDot", new Integer(SWT.LINE_DASHDOT)); | |
// colorFrame | |
gridLayout = new GridLayout(); | |
gridLayout.numColumns = 3; | |
gridLayout.marginHeight = 0; | |
gridLayout.marginWidth = 0; | |
colorFrame.setLayout(gridLayout); | |
// activeForegroundColorCanvas, activeBackgroundColorCanvas | |
activeForegroundColorCanvas = new Canvas(colorFrame, SWT.BORDER); | |
gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL); | |
gridData.heightHint = 24; | |
gridData.widthHint = 24; | |
activeForegroundColorCanvas.setLayoutData(gridData); | |
activeBackgroundColorCanvas = new Canvas(colorFrame, SWT.BORDER); | |
gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL); | |
gridData.heightHint = 24; | |
gridData.widthHint = 24; | |
activeBackgroundColorCanvas.setLayoutData(gridData); | |
// paletteCanvas | |
final Canvas paletteCanvas = new Canvas(colorFrame, SWT.BORDER | SWT.NO_BACKGROUND); | |
gridData = new GridData(GridData.FILL_HORIZONTAL); | |
gridData.heightHint = 24; | |
paletteCanvas.setLayoutData(gridData); | |
paletteCanvas.addListener(SWT.MouseDown, new Listener() { | |
public void handleEvent(Event e) { | |
Rectangle bounds = paletteCanvas.getClientArea(); | |
Color color = getColorAt(bounds, e.x, e.y); | |
if (e.button == 1) setForegroundColor(color); | |
else setBackgroundColor(color); | |
} | |
private Color getColorAt(Rectangle bounds, int x, int y) { | |
if (bounds.height <= 1 && bounds.width <= 1) return paintColorWhite; | |
final int row = (y - bounds.y) * numPaletteRows / bounds.height; | |
final int col = (x - bounds.x) * numPaletteCols / bounds.width; | |
return paintColors[Math.min(Math.max(row * numPaletteCols + col, 0), paintColors.length - 1)]; | |
} | |
}); | |
Listener refreshListener = new Listener() { | |
public void handleEvent(Event e) { | |
if (e.gc == null) return; | |
Rectangle bounds = paletteCanvas.getClientArea(); | |
for (int row = 0; row < numPaletteRows; ++row) { | |
for (int col = 0; col < numPaletteCols; ++col) { | |
final int x = bounds.width * col / numPaletteCols; | |
final int y = bounds.height * row / numPaletteRows; | |
final int width = Math.max(bounds.width * (col + 1) / numPaletteCols - x, 1); | |
final int height = Math.max(bounds.height * (row + 1) / numPaletteRows - y, 1); | |
e.gc.setBackground(paintColors[row * numPaletteCols + col]); | |
e.gc.fillRectangle(bounds.x + x, bounds.y + y, width, height); | |
} | |
} | |
} | |
}; | |
paletteCanvas.addListener(SWT.Resize, refreshListener); | |
paletteCanvas.addListener(SWT.Paint, refreshListener); | |
//paletteCanvas.redraw(); | |
// toolSettingsFrame | |
gridLayout = new GridLayout(); | |
gridLayout.numColumns = 4; | |
gridLayout.marginHeight = 0; | |
gridLayout.marginWidth = 0; | |
toolSettingsFrame.setLayout(gridLayout); | |
Label label = new Label(toolSettingsFrame, SWT.NONE); | |
label.setText(PaintPlugin.getResourceString("settings.AirbrushRadius.text")); | |
final Scale airbrushRadiusScale = new Scale(toolSettingsFrame, SWT.HORIZONTAL); | |
airbrushRadiusScale.setMinimum(5); | |
airbrushRadiusScale.setMaximum(50); | |
airbrushRadiusScale.setSelection(toolSettings.airbrushRadius); | |
airbrushRadiusScale.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL)); | |
airbrushRadiusScale.addSelectionListener(new SelectionAdapter() { | |
public void widgetSelected(SelectionEvent e) { | |
toolSettings.airbrushRadius = airbrushRadiusScale.getSelection(); | |
updateToolSettings(); | |
} | |
}); | |
label = new Label(toolSettingsFrame, SWT.NONE); | |
label.setText(PaintPlugin.getResourceString("settings.AirbrushIntensity.text")); | |
final Scale airbrushIntensityScale = new Scale(toolSettingsFrame, SWT.HORIZONTAL); | |
airbrushIntensityScale.setMinimum(1); | |
airbrushIntensityScale.setMaximum(100); | |
airbrushIntensityScale.setSelection(toolSettings.airbrushIntensity); | |
airbrushIntensityScale.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL)); | |
airbrushIntensityScale.addSelectionListener(new SelectionAdapter() { | |
public void widgetSelected(SelectionEvent e) { | |
toolSettings.airbrushIntensity = airbrushIntensityScale.getSelection(); | |
updateToolSettings(); | |
} | |
}); | |
} | |
/** | |
* Notifies the tool that its settings have changed. | |
*/ | |
private void updateToolSettings() { | |
final PaintTool activePaintTool = paintSurface.getPaintTool(); | |
if (activePaintTool == null) return; | |
activePaintTool.endSession(); | |
activePaintTool.set(toolSettings); | |
activePaintTool.beginSession(); | |
} | |
/** | |
* Sets the tool foreground color. | |
* | |
* @param color the new color to use | |
*/ | |
public void setForegroundColor(Color color) { | |
if (activeForegroundColorCanvas != null) | |
activeForegroundColorCanvas.setBackground(color); | |
toolSettings.commonForegroundColor = color; | |
updateToolSettings(); | |
} | |
/** | |
* Set the tool background color. | |
* | |
* @param color the new color to use | |
*/ | |
public void setBackgroundColor(Color color) { | |
if (activeBackgroundColorCanvas != null) | |
activeBackgroundColorCanvas.setBackground(color); | |
toolSettings.commonBackgroundColor = color; | |
updateToolSettings(); | |
} | |
/** | |
* Selects a tool given its ID. | |
*/ | |
public void setPaintToolByID(String id) { | |
activeToolAction = handleRadioAction(activeToolAction, id); | |
final PaintTool paintTool = (PaintTool) paintToolMap.get(id); | |
paintSurface.setPaintSession(paintTool); | |
updateToolSettings(); | |
} | |
/** | |
* Selects a filltype given its ID. | |
*/ | |
public void setFillTypeByID(String id) { | |
activeFillTypeAction = handleRadioAction(activeFillTypeAction, id); | |
final Integer fillType = (Integer) paintFillTypeMap.get(id); | |
toolSettings.commonFillType = fillType.intValue(); | |
updateToolSettings(); | |
} | |
/** | |
* Selects line type given its ID. | |
*/ | |
public void setLineStyleByID(String id) { | |
activeLineStyleAction = handleRadioAction(activeLineStyleAction, id); | |
final Integer lineType = (Integer) paintLineStyleMap.get(id); | |
toolSettings.commonLineStyle = lineType.intValue(); | |
updateToolSettings(); | |
} | |
/** | |
* Gets the IAction for an ID belonging to a set of mutually exclusive actions, and | |
* toggles the old action off if necessary. | |
*/ | |
private IAction handleRadioAction(IAction oldAction, String id) { | |
IAction action = getActionByID(id); | |
if (action != null) { | |
if (oldAction != null) oldAction.setChecked(false); | |
if (! action.isChecked()) action.setChecked(true); | |
return action; | |
} | |
return oldAction; | |
} | |
/** | |
* Gets the IAction representing the UI toolbar button with the specified ID. | |
*/ | |
private IAction getActionByID(String id) { | |
final IActionBars actionBars = getViewSite().getActionBars(); | |
IToolBarManager toolbarManager = actionBars.getToolBarManager(); | |
ActionContributionItem contributionItem = (ActionContributionItem) toolbarManager.find(id); | |
if (contributionItem == null) return null; | |
return contributionItem.getAction(); | |
} | |
/** | |
* Returns the Display. | |
* | |
* @return the display we're using | |
*/ | |
public Display getDisplay() { | |
return workbenchDisplay; | |
} | |
/** | |
* Action set glue. | |
*/ | |
abstract class PaintAction extends Action { | |
public PaintAction(String id) { | |
super(); | |
setId(id); | |
try { | |
final URL installUrl = PaintPlugin.getDefault().getDescriptor().getInstallURL(); | |
final URL imageUrl = new URL(installUrl, PaintPlugin.getResourceString(id + ".image")); | |
setImageDescriptor(ImageDescriptor.createFromURL(imageUrl)); | |
} catch (MalformedURLException e) { | |
PaintPlugin.logError("", e); | |
} | |
setText(PaintPlugin.getResourceString(id + ".label")); | |
setToolTipText(PaintPlugin.getResourceString(id + ".tooltip")); | |
setDescription(PaintPlugin.getResourceString(id + ".description")); | |
} | |
} | |
class SelectPaintToolAction extends PaintAction { | |
public SelectPaintToolAction(String id) { super(id); } | |
public int getStyle() { return IAction.AS_CHECK_BOX; } | |
public void run() { setPaintToolByID(getId()); } | |
} | |
class SelectFillTypeAction extends PaintAction { | |
public SelectFillTypeAction(String id) { super(id); } | |
public int getStyle() { return IAction.AS_CHECK_BOX; } | |
public void run() { setFillTypeByID(getId()); } | |
} | |
class SelectLineStyleAction extends PaintAction { | |
public SelectLineStyleAction(String id) { super(id); } | |
public int getStyle() { return IAction.AS_CHECK_BOX; } | |
public void run() { setLineStyleByID(getId()); } | |
} | |
class SelectFontAction extends PaintAction { | |
public SelectFontAction(String id) { super(id); } | |
public int getStyle() { return IAction.AS_PUSH_BUTTON; } | |
public void run() { | |
FontDialog fontDialog = new FontDialog(paintSurface.getShell(), SWT.PRIMARY_MODAL); | |
FontData[] fontDatum = toolSettings.commonFont.getFontData(); | |
if (fontDatum != null && fontDatum.length > 0) { | |
fontDialog.setFontData(fontDatum[0]); | |
} | |
fontDialog.setText(PaintPlugin.getResourceString("options.Font.dialog.title")); | |
paintSurface.hideRubberband(); | |
FontData fontData = fontDialog.open(); | |
paintSurface.showRubberband(); | |
if (fontData != null) { | |
try { | |
Font font = new Font(workbenchDisplay, fontData); | |
toolSettings.commonFont = font; | |
updateToolSettings(); | |
} catch (SWTException e) { | |
} | |
} | |
} | |
} | |
} |