| /******************************************************************************* |
| * Copyright (c) 2008 IBM 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.gmf.examples.runtime.diagram.logic.internal.wizards; |
| |
| import java.util.List; |
| |
| import org.eclipse.core.commands.ExecutionException; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.draw2d.geometry.Dimension; |
| import org.eclipse.draw2d.geometry.Point; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.transaction.RollbackException; |
| import org.eclipse.emf.transaction.impl.EMFCommandTransaction; |
| import org.eclipse.emf.transaction.impl.InternalTransactionalEditingDomain; |
| import org.eclipse.gef.commands.Command; |
| import org.eclipse.gmf.examples.runtime.diagram.logic.internal.editparts.CircuitEditPart; |
| import org.eclipse.gmf.examples.runtime.diagram.logic.internal.editparts.TerminalEditPart; |
| import org.eclipse.gmf.examples.runtime.diagram.logic.internal.providers.LogicConstants; |
| import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.AndGate; |
| import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.Circuit; |
| import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.Element; |
| import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.InputTerminal; |
| import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.LED; |
| import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.Model; |
| import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.OrGate; |
| import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.OutputTerminal; |
| import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.Wire; |
| import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.XORGate; |
| import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.util.LogicSemanticType; |
| import org.eclipse.gmf.runtime.common.core.command.ICommand; |
| import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; |
| import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramGraphicalViewer; |
| import org.eclipse.gmf.runtime.diagram.ui.requests.CreateConnectionViewRequest; |
| import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest; |
| import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequestFactory; |
| import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest.ViewAndElementDescriptor; |
| import org.eclipse.gmf.runtime.emf.core.util.EMFCoreUtil; |
| import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry; |
| import org.eclipse.gmf.runtime.emf.type.core.IElementType; |
| import org.eclipse.gmf.runtime.emf.type.core.requests.CreateRelationshipRequest; |
| |
| /** |
| * Factory for creating contents of example logic diagrams. |
| * |
| * @author mgobeil |
| */ |
| public class LogicDiagramFactory { |
| |
| public static void CreateFourBitAdder(IGraphicalEditPart diagramEditPart, |
| IProgressMonitor progressMonitor) { |
| |
| // create logic elements |
| Circuit fullAdder1 = createFullAdder(new Point(20, 120), new Dimension( |
| 140, 230), diagramEditPart, progressMonitor); |
| Circuit fullAdder2 = createFullAdder(new Point(170, 120), |
| new Dimension(140, 230), diagramEditPart, progressMonitor); |
| Circuit fullAdder3 = createFullAdder(new Point(320, 120), |
| new Dimension(140, 230), diagramEditPart, progressMonitor); |
| Circuit halfAdder = createHalfAdder(new Point(470, 120), new Dimension( |
| 70, 230), diagramEditPart, progressMonitor); |
| |
| // chain carry bits |
| connect(outputTerminal(fullAdder1, 3), inputTerminal(fullAdder2, 4), |
| diagramEditPart, progressMonitor); |
| connect(outputTerminal(fullAdder2, 3), inputTerminal(fullAdder3, 4), |
| diagramEditPart, progressMonitor); |
| connect(outputTerminal(fullAdder3, 3), inputTerminal(halfAdder, 4), |
| diagramEditPart, progressMonitor); |
| |
| // create and connect led input 1 |
| final LED ledInput1 = createElement(LogicSemanticType.LED, LED.class, |
| new Point(150, 20), diagramEditPart, progressMonitor); |
| connect(outputTerminal(ledInput1, 3), inputTerminal(fullAdder1, 0), |
| diagramEditPart, progressMonitor); |
| connect(outputTerminal(ledInput1, 2), inputTerminal(fullAdder2, 0), |
| diagramEditPart, progressMonitor); |
| connect(outputTerminal(ledInput1, 1), inputTerminal(fullAdder3, 0), |
| diagramEditPart, progressMonitor); |
| connect(outputTerminal(ledInput1, 0), inputTerminal(halfAdder, 0), |
| diagramEditPart, progressMonitor); |
| |
| // create and connect led input 2 |
| final LED ledInput2 = createElement(LogicSemanticType.LED, LED.class, |
| new Point(350, 20), diagramEditPart, progressMonitor); |
| connect(outputTerminal(ledInput2, 3), inputTerminal(fullAdder1, 2), |
| diagramEditPart, progressMonitor); |
| connect(outputTerminal(ledInput2, 2), inputTerminal(fullAdder2, 2), |
| diagramEditPart, progressMonitor); |
| connect(outputTerminal(ledInput2, 1), inputTerminal(fullAdder3, 2), |
| diagramEditPart, progressMonitor); |
| connect(outputTerminal(ledInput2, 0), inputTerminal(halfAdder, 3), |
| diagramEditPart, progressMonitor); |
| |
| // create and connect led output |
| LED ledOutput = createElement(LogicSemanticType.LED, LED.class, |
| new Point(250, 400), diagramEditPart, progressMonitor); |
| connect(outputTerminal(fullAdder1, 7), inputTerminal(ledOutput, 3), |
| diagramEditPart, progressMonitor); |
| connect(outputTerminal(fullAdder2, 7), inputTerminal(ledOutput, 2), |
| diagramEditPart, progressMonitor); |
| connect(outputTerminal(fullAdder3, 7), inputTerminal(ledOutput, 1), |
| diagramEditPart, progressMonitor); |
| connect(outputTerminal(halfAdder, 7), inputTerminal(ledOutput, 0), |
| diagramEditPart, progressMonitor); |
| |
| // set the input values |
| org.eclipse.emf.common.command.Command cmd = new org.eclipse.emf.common.command.AbstractCommand() { |
| public void execute() { |
| ledInput1.setValue(3); |
| ledInput2.setValue(7); |
| } |
| |
| public void redo() { |
| execute(); |
| } |
| }; |
| EMFCommandTransaction trans = new EMFCommandTransaction(cmd, |
| (InternalTransactionalEditingDomain) diagramEditPart |
| .getEditingDomain(), null); |
| try { |
| trans.start(); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| trans.getCommand().execute(); |
| try { |
| trans.commit(); |
| } catch (RollbackException e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| public static Circuit createFullAdder(Point location, Dimension size, |
| IGraphicalEditPart containerEditPart, |
| IProgressMonitor progressMonitor) { |
| Circuit circuit = createElement(LogicSemanticType.CIRCUIT, |
| Circuit.class, location, size, containerEditPart, |
| progressMonitor); |
| CircuitEditPart circuitEditPart = getEditPart(circuit, |
| CircuitEditPart.class, containerEditPart); |
| |
| Circuit halfAdder1 = createHalfAdder(new Point(10, 10), |
| circuitEditPart, progressMonitor); |
| Circuit halfAdder2 = createHalfAdder(new Point(50, 100), |
| circuitEditPart, progressMonitor); |
| OrGate orGate = createElement(LogicSemanticType.ORGATE, OrGate.class, |
| new Point(40, 180), circuitEditPart, progressMonitor); |
| ; |
| |
| // input to first half adder |
| connect(outputTerminal(circuit, 0), inputTerminal(halfAdder1, 0), |
| circuitEditPart, progressMonitor); |
| connect(outputTerminal(circuit, 2), inputTerminal(halfAdder1, 3), |
| circuitEditPart, progressMonitor); |
| |
| // input to second half adder |
| connect(outputTerminal(circuit, 3), inputTerminal(halfAdder2, 3), |
| circuitEditPart, progressMonitor); |
| connect(outputTerminal(halfAdder1, 7), inputTerminal(halfAdder2, 0), |
| circuitEditPart, progressMonitor); |
| |
| // input to OR gate |
| connect(outputTerminal(halfAdder1, 4), inputTerminal(orGate, 0), |
| circuitEditPart, progressMonitor); |
| connect(outputTerminal(halfAdder2, 4), inputTerminal(orGate, 1), |
| circuitEditPart, progressMonitor); |
| |
| // output of circuit |
| connect(outputTerminal(orGate, 0), inputTerminal(circuit, 4), |
| circuitEditPart, progressMonitor); |
| connect(outputTerminal(halfAdder2, 7), inputTerminal(circuit, 7), |
| circuitEditPart, progressMonitor); |
| |
| return circuit; |
| } |
| |
| public static Circuit createHalfAdder(Point location, |
| IGraphicalEditPart containerEditPart, |
| IProgressMonitor progressMonitor) { |
| return createHalfAdder(location, new Dimension(70, 70), |
| containerEditPart, progressMonitor); |
| } |
| |
| public static Circuit createHalfAdder(Point location, Dimension size, |
| IGraphicalEditPart containerEditPart, |
| IProgressMonitor progressMonitor) { |
| Circuit circuit = createElement(LogicSemanticType.CIRCUIT, |
| Circuit.class, location, size, containerEditPart, |
| progressMonitor); |
| CircuitEditPart circuitEditPart = getEditPart(circuit, |
| CircuitEditPart.class, containerEditPart); |
| |
| AndGate andGate = createElement(LogicSemanticType.ANDGATE, |
| AndGate.class, new Point(10, 20), circuitEditPart, |
| progressMonitor); |
| ; |
| XORGate xorGate = createElement(LogicSemanticType.XORGATE, |
| XORGate.class, new Point(40, 20), circuitEditPart, |
| progressMonitor); |
| ; |
| |
| connect(outputTerminal(circuit, 0), inputTerminal(andGate, 0), |
| circuitEditPart, progressMonitor); |
| connect(outputTerminal(circuit, 3), inputTerminal(andGate, 1), |
| circuitEditPart, progressMonitor); |
| connect(outputTerminal(circuit, 0), inputTerminal(xorGate, 0), |
| circuitEditPart, progressMonitor); |
| connect(outputTerminal(circuit, 3), inputTerminal(xorGate, 1), |
| circuitEditPart, progressMonitor); |
| |
| connect(outputTerminal(andGate, 0), inputTerminal(circuit, 4), |
| circuitEditPart, progressMonitor); |
| connect(outputTerminal(xorGate, 0), inputTerminal(circuit, 7), |
| circuitEditPart, progressMonitor); |
| |
| return circuit; |
| } |
| |
| private static <T> T createElement(IElementType elementType, |
| Class<T> elementTypeClass, Point location, |
| IGraphicalEditPart container, IProgressMonitor progressMonitor) { |
| |
| return createElement(elementType, elementTypeClass, location, null, |
| container, progressMonitor); |
| } |
| |
| private static <T> T createElement(IElementType elementType, |
| Class<T> elementTypeClass, Point location, Dimension size, |
| IGraphicalEditPart container, IProgressMonitor progressMonitor) { |
| |
| if (container instanceof CircuitEditPart) { |
| container = (IGraphicalEditPart) container |
| .getChildBySemanticHint(LogicConstants.LOGIC_SHAPE_COMPARTMENT); |
| } |
| |
| CreateViewRequest createRequest = CreateViewRequestFactory |
| .getCreateShapeRequest(elementType, container |
| .getDiagramPreferencesHint()); |
| |
| createRequest.setLocation(location); |
| createRequest.setSize(size); |
| |
| Command command = container.getCommand(createRequest); |
| |
| container.getDiagramEditDomain().getDiagramCommandStack().execute( |
| command, progressMonitor); |
| |
| List<IAdaptable> newObject = (List<IAdaptable>) createRequest |
| .getNewObject(); |
| ViewAndElementDescriptor viewAndElementDescriptor = (ViewAndElementDescriptor) newObject |
| .get(0); |
| return (T) viewAndElementDescriptor.getElementAdapter().getAdapter( |
| elementTypeClass); |
| } |
| |
| private static void connect(OutputTerminal outputTerminal, |
| InputTerminal inputTerminal, IGraphicalEditPart container, |
| IProgressMonitor progressMonitor) { |
| CreateRelationshipRequest createRequest = new CreateRelationshipRequest( |
| container.getEditingDomain(), outputTerminal, inputTerminal, |
| LogicSemanticType.WIRE); |
| |
| IElementType elementType = ElementTypeRegistry.getInstance() |
| .getElementType(createRequest.getEditHelperContext()); |
| |
| ICommand createCommand = elementType.getEditCommand(createRequest); |
| |
| try { |
| createCommand.execute(progressMonitor, null); |
| } catch (ExecutionException e) { |
| e.printStackTrace(); |
| } |
| |
| // HAAAACK! why won't the above command create a view when the parent is |
| // a Model instead of a Circuit? |
| if (createRequest.getContainer() instanceof Model) { |
| |
| // get matching editparts for semantic terminals |
| TerminalEditPart outputTerminalEditPart = getEditPart( |
| outputTerminal, TerminalEditPart.class, container); |
| TerminalEditPart inputTerminalEditPart = getEditPart(inputTerminal, |
| TerminalEditPart.class, container); |
| |
| // create matching notational wire connection |
| Command command = CreateConnectionViewRequest.getCreateCommand( |
| (Wire) createCommand.getCommandResult().getReturnValue(), |
| outputTerminalEditPart, inputTerminalEditPart, container |
| .getDiagramPreferencesHint()); |
| container.getDiagramEditDomain().getDiagramCommandStack().execute( |
| command, progressMonitor); |
| } |
| } |
| |
| private static OutputTerminal outputTerminal(Element element, int terminal) { |
| return (OutputTerminal) element.getOutputTerminals().get(terminal); |
| } |
| |
| private static InputTerminal inputTerminal(Element element, int terminal) { |
| return (InputTerminal) element.getInputTerminals().get(terminal); |
| } |
| |
| private static <T> T getEditPart(EObject modelElement, |
| Class<T> editPartType, IGraphicalEditPart container) { |
| if (container instanceof CircuitEditPart) { |
| container = (IGraphicalEditPart) container |
| .getChildBySemanticHint(LogicConstants.LOGIC_SHAPE_COMPARTMENT); |
| } |
| |
| DiagramGraphicalViewer viewer = (DiagramGraphicalViewer) container |
| .getRoot().getViewer(); |
| String proxyId = EMFCoreUtil.getProxyID(modelElement); |
| return (T) viewer.findEditPartsForElement(proxyId, editPartType).get(0); |
| } |
| } |