Skip to content
Snippets Groups Projects
Commit ed38c70a authored by Florian Hölzl's avatar Florian Hölzl
Browse files

fixed connection support

added port connection compositor
parent f5f46474
No related branches found
No related tags found
No related merge requests found
Showing
with 357 additions and 7 deletions
/*--------------------------------------------------------------------------+
$Id$
| |
| Copyright 2011 ForTISS GmbH |
| |
| Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 |
| |
| 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 org.fortiss.tooling.base.ui.compose;
import org.eclipse.emf.ecore.EObject;
import org.fortiss.tooling.base.model.base.ConnectionSegmentBase;
import org.fortiss.tooling.base.model.base.ConnectorBase;
import org.fortiss.tooling.base.model.base.EntryConnectorBase;
import org.fortiss.tooling.base.model.base.ExitConnectorBase;
import org.fortiss.tooling.base.model.base.HierarchicElementBase;
import org.fortiss.tooling.base.model.element.IConnector;
import org.fortiss.tooling.base.model.element.IHierarchicElement;
import org.fortiss.tooling.base.ui.dnd.DragContext;
import org.fortiss.tooling.base.ui.editpart.interfaces.IFreeConnectorEditPart;
import org.fortiss.tooling.kernel.interfaces.IConnectionCompositionContext;
import org.fortiss.tooling.kernel.interfaces.IConnectionCompositor;
import org.fortiss.tooling.kernel.interfaces.ITopLevelElementContext;
import org.fortiss.tooling.kernel.services.IPersistencyService;
/**
* Base compositor for connections supporting entry and exit connectors.
*
* @author hoelzl
* @author $Author$
* @version $Rev$
* @ConQAT.Rating RED Hash:
*/
public abstract class ConnectorConnectionCompositorBase<HE extends IHierarchicElement, S extends IConnector, T extends IConnector>
implements IConnectionCompositor<S, T> {
/** {@inheritDoc} */
@Override
public boolean canConnect(S source, T target, EObject connection,
IConnectionCompositionContext context) {
// Deny creation of feedback connections in internal view
if (!allowInternalFeedback() && context instanceof DragContext) {
DragContext dc = (DragContext) context;
//
if (dc.getSource() instanceof IFreeConnectorEditPart
&& dc.getTarget() instanceof IFreeConnectorEditPart) {
return false;
}
}
if (source instanceof EntryConnectorBase) {
if (target instanceof EntryConnectorBase) {
return checkEntryEntry((EntryConnectorBase) source,
(EntryConnectorBase) target, connection);
} else if (target instanceof ExitConnectorBase) {
// use swapping here
return checkExitEntry((ExitConnectorBase) target,
(EntryConnectorBase) source, connection);
}
} else if (source instanceof ExitConnectorBase) {
if (target instanceof EntryConnectorBase) {
return checkExitEntry((ExitConnectorBase) source,
(EntryConnectorBase) target, connection);
} else if (target instanceof ExitConnectorBase) {
return checkExitExit((ExitConnectorBase) source,
(ExitConnectorBase) target, connection);
}
}
return false;
}
/** Checks entry to entry connection. */
private boolean checkEntryEntry(EntryConnectorBase source,
EntryConnectorBase target, EObject connection) {
boolean swapped = false;
// child input to super input => swap input
if (source.eContainer().eContainer() == target.eContainer()) {
EntryConnectorBase temp = source;
source = target;
target = temp;
swapped = true;
}
// super input to child input
if (swapped || source.eContainer() == target.eContainer().eContainer()) {
return checkSourceOut(source, connection)
&& checkTargetIn(target, connection);
}
return false;
}
/** Checks exit to entry connection. */
private boolean checkExitEntry(ExitConnectorBase source,
EntryConnectorBase target, EObject connection) {
if (source.eContainer().eContainer() == target.eContainer()
.eContainer()) {
return checkSourceOut(source, connection)
&& checkTargetIn(target, connection);
}
return false;
}
/**
* Checks exit to exit connection.
*/
private boolean checkExitExit(ExitConnectorBase source,
ExitConnectorBase target, EObject connection) {
boolean swapped = false;
if (source.eContainer() == target.eContainer().eContainer()) {
ExitConnectorBase temp = source;
source = target;
target = temp;
swapped = true;
}
if (swapped || source.eContainer().eContainer() == target.eContainer()) {
return checkSourceOut(source, connection)
&& checkTargetIn(target, connection);
}
return false;
}
/**
* Checks outgoing connection of source connector.
*/
private boolean checkSourceOut(ConnectorBase source, EObject connection) {
// source has no outgoing connection, is already connected, or allows
// multiple connections
return source.getOutgoingLength() == 0
|| (connection instanceof ConnectionSegmentBase && ((ConnectionSegmentBase) connection)
.getSource() == source) || allowOneToMany();
}
/**
* Checks incoming connections of target port.
*/
private boolean checkTargetIn(ConnectorBase target, EObject connection) {
// target has no incoming connection, is already connected, or allows
// multiple connections.
return target.getIncomingLength() == 0
|| (connection instanceof ConnectionSegmentBase && ((ConnectionSegmentBase) connection)
.getTarget() == target) || allowManyToOne();
}
/**
* {@inheritDoc}
*/
@Override
public void connect(S source, T target, EObject connection,
IConnectionCompositionContext context) {
ConnectionSegmentBase conn;
if (connection instanceof ConnectionSegmentBase) {
conn = (ConnectionSegmentBase) connection;
} else {
conn = createConnection(source, target, context);
}
// If we are working in a connected model, deal with IDs
ITopLevelElementContext modelContext = IPersistencyService.INSTANCE
.getTopLevelElementContextFor(source);
if (modelContext != null) {
// FIXME (FH): IDs
// modelContext.prepareIDsForCompose(channel);
}
boolean swap = false;
if (source instanceof EntryConnectorBase) {
if (target instanceof EntryConnectorBase) {
if (source.eContainer() == target.eContainer().eContainer()) {
((HierarchicElementBase) source.eContainer())
.getConnectionsList().add(conn);
} else {
// source.eContainer().eContainer() ==
// target.eContainer()
((HierarchicElementBase) target.eContainer())
.getConnectionsList().add(conn);
swap = true;
}
} else if (target instanceof ExitConnectorBase) {
((HierarchicElementBase) source.eContainer().eContainer())
.getConnectionsList().add(conn);
swap = true;
}
} else if (source instanceof ExitConnectorBase) {
if (target instanceof EntryConnectorBase) {
((HierarchicElementBase) source.eContainer().eContainer())
.getConnectionsList().add(conn);
} else if (target instanceof ExitConnectorBase) {
if (source.eContainer() == target.eContainer().eContainer()) {
((HierarchicElementBase) source.eContainer())
.getConnectionsList().add(conn);
swap = true;
} else {
// source.eContainer().eContainer() ==
// target.eContainer()
((HierarchicElementBase) target.eContainer())
.getConnectionsList().add(conn);
}
}
}
if (swap) {
conn.setSource(target);
conn.setTarget(source);
} else {
conn.setSource(source);
conn.setTarget(target);
}
}
/**
* Creates a new {@link ConnectionSegmentBase}. The {@link IConnector}s are
* provided to make use of their names when naming the connection. However
* they should not be used for connecting.
*/
protected abstract ConnectionSegmentBase createConnection(S source,
T target, IConnectionCompositionContext context);
/**
* Configures multiple connection behavior for 1-to-many connections. The
* default is allow.
*/
protected boolean allowOneToMany() {
return true;
}
/**
* Configures multiple connection behavior for many-to-1 connections. The
* default is allow.
*/
protected boolean allowManyToOne() {
return true;
}
/**
* Allows internal feedback connection. The default is disallow.
*/
protected boolean allowInternalFeedback() {
return false;
}
}
......@@ -26,6 +26,7 @@ import org.fortiss.tooling.base.ui.dnd.DragContext;
import org.fortiss.tooling.base.ui.dnd.DropContext;
import org.fortiss.tooling.base.ui.editpart.RootEditPartBase;
import org.fortiss.tooling.kernel.interfaces.IConnectionCompositionContext;
import org.fortiss.tooling.kernel.interfaces.IConnectionCompositor;
import org.fortiss.tooling.kernel.services.ICompositorService;
/**
......@@ -57,7 +58,7 @@ import org.fortiss.tooling.kernel.services.ICompositorService;
* @ConQAT.Rating RED Hash:
*/
public abstract class HierarchicElementConnectionCompositorBase<HE extends IHierarchicElement, S extends IHierarchicElement, T extends IHierarchicElement>
implements org.fortiss.tooling.kernel.interfaces.IConnectionCompositor<S, T> {
implements IConnectionCompositor<S, T> {
/**
* Determines whether connectors of the component may be connected
......
......@@ -175,9 +175,9 @@ public abstract class LabeledConnectorEditPartBase<T extends IConnector & ILayou
private List<IConnection> filterConnections(List<IConnection> connections,
IHierarchicElement owner) {
List<IConnection> result = new ArrayList<IConnection>();
for (IConnection channel : connections) {
if (channel.eContainer() == owner) {
result.add(channel);
for (IConnection connection : connections) {
if (connection.eContainer() == owner) {
result.add(connection);
}
}
return result;
......
......@@ -101,7 +101,7 @@ public class LabeledConnectorFigure extends Figure {
// compute label size
Rectangle labelTextBounds = label.getTextBounds();
Rectangle newBounds = new Rectangle(containerBounds);
newBounds.x += connectorDimension.width;
newBounds.x += connectorDimension.width / 2;
newBounds.y += (connectorDimension.height - labelTextBounds.height) / 2;
// +1 needed for proper display
newBounds.width += 1 + labelTextBounds.width;
......
/*--------------------------------------------------------------------------+
$Id$
| |
| Copyright 2011 ForTISS GmbH |
| |
| Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 |
| |
| 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 org.fortiss.tooling.base.ui.editpart.interfaces;
/**
* This is a marker interface for edit parts, which resemble a free behavior
* like some connector moving freely on the background area of its parent
* element when viewed internally.
*
* <p>
* Edit parts implementing this marker must not implement
* {@link IStickyConnectorEditPart}.
*
* @author $Author$
* @version $Rev$
* @ConQAT.Rating RED Hash:
*/
public interface IFreeConnectorEditPart {
// marker interface
}
/*--------------------------------------------------------------------------+
$Id$
| |
| Copyright 2011 ForTISS GmbH |
| |
| Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 |
| |
| 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 org.fortiss.tooling.base.ui.editpart.interfaces;
/**
* This is a marker interface for edit parts, which resemble a sticky behavior
* like some connector moving only on the border of its parent element when
* viewed externally.
*
* <p>
* Edit parts implementing this marker must not implement
* {@link IFreeConnectorEditPart}.
*
* @author hoelzl
* @author $Author$
* @version $Rev$
* @ConQAT.Rating RED Hash:
*/
public interface IStickyConnectorEditPart {
// marker interface
}
......@@ -67,7 +67,7 @@ public final class RecommendedLayoutConstants {
public static final int RECTANGULAR_SHAPE_MINIMUM_HEIGHT = 6 * GRID_SIZE;
// connector default constants
/** The size of a rectangular connector. */
/** The size of a default connector. */
public static final int DEFAULT_CONNECTOR_SIZE = 2 * GRID_SIZE;
/** Dimension used for rectangular connector. */
......
......@@ -10,6 +10,9 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Require-Bundle: org.fortiss.tooling.kernel;bundle-version="0.0.1";visibility:=reexport
Bundle-ActivationPolicy: lazy
Export-Package: org.fortiss.tooling.base,
org.fortiss.tooling.base.model.base,
org.fortiss.tooling.base.model.base.impl,
org.fortiss.tooling.base.model.base.util,
org.fortiss.tooling.base.model.element,
org.fortiss.tooling.base.model.element.impl,
org.fortiss.tooling.base.model.element.util,
......
......@@ -234,4 +234,17 @@
</eAnnotations>
</eClassifiers>
</eSubpackages>
<eSubpackages name="base" nsURI="http://www.fortiss.org/af3/micro/base" nsPrefix="org-fortiss-af3-micro-base">
<eClassifiers xsi:type="ecore:EClass" name="HierarchicElementBase" abstract="true"
eSuperTypes="../../org.fortiss.tooling.kernel/model/kernel.ecore#//INamedCommentedElement #//element/IHierarchicElement #//layout/ILayoutedModelElement"/>
<eClassifiers xsi:type="ecore:EClass" name="ConnectorBase" abstract="true" eSuperTypes="../../org.fortiss.tooling.kernel/model/kernel.ecore#//INamedCommentedElement #//element/IConnector #//layout/ILayoutedModelElement"/>
<eClassifiers xsi:type="ecore:EClass" name="EntryConnectorBase" abstract="true"
eSuperTypes="#//base/ConnectorBase"/>
<eClassifiers xsi:type="ecore:EClass" name="ExitConnectorBase" abstract="true"
eSuperTypes="#//base/ConnectorBase"/>
<eClassifiers xsi:type="ecore:EClass" name="LocalConnectorBase" abstract="true"
eSuperTypes="#//base/ConnectorBase"/>
<eClassifiers xsi:type="ecore:EClass" name="ConnectionSegmentBase" abstract="true"
eSuperTypes="../../org.fortiss.tooling.kernel/model/kernel.ecore#//INamedCommentedElement #//element/IConnection #//layout/ILayoutedModelElement"/>
</eSubpackages>
</ecore:EPackage>
......@@ -3,7 +3,8 @@
xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/org.fortiss.tooling.base/generated-src"
modelPluginID="org.fortiss.tooling.base" modelName="Base" importerID="org.eclipse.emf.importer.ecore"
containmentProxies="true" arrayAccessors="true" complianceLevel="6.0" copyrightFields="false">
containmentProxies="true" arrayAccessors="true" complianceLevel="6.0" copyrightFields="false"
usedGenPackages="platform:/plugin/org.fortiss.tooling.kernel/model/kernel.genmodel#//model">
<foreignModel>base.ecore</foreignModel>
<genPackages prefix="Base" basePackage="org.fortiss.tooling.base" disposableProviderFactory="true"
ecorePackage="base.ecore#/">
......@@ -77,5 +78,14 @@
</genClasses>
<genClasses ecoreClass="base.ecore#//layout/OffsetOrientation"/>
</nestedGenPackages>
<nestedGenPackages prefix="Base" basePackage="org.fortiss.tooling.base.model"
disposableProviderFactory="true" ecorePackage="base.ecore#//base">
<genClasses image="false" ecoreClass="base.ecore#//base/HierarchicElementBase"/>
<genClasses image="false" ecoreClass="base.ecore#//base/ConnectorBase"/>
<genClasses image="false" ecoreClass="base.ecore#//base/EntryConnectorBase"/>
<genClasses image="false" ecoreClass="base.ecore#//base/ExitConnectorBase"/>
<genClasses image="false" ecoreClass="base.ecore#//base/LocalConnectorBase"/>
<genClasses image="false" ecoreClass="base.ecore#//base/ConnectionSegmentBase"/>
</nestedGenPackages>
</genPackages>
</genmodel:GenModel>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment