| /******************************************************************************* |
| * Copyright (c) 2000, 2003 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are 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 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.swt.examples.paint; |
| |
| |
| 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.setFontList(fontDatum); |
| } |
| 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) { |
| } |
| } |
| } |
| } |
| } |