|
|
|
Re: [GEF4] Huge selection circle and line when zoom in [message #1746367 is a reply to message #1746294] |
Thu, 27 October 2016 10:24   |
Eclipse User |
|
|
|
Hi Uwe,
the InfiniteCanvasViewer/FXViewer applies a so-called "contentTransform" to its "contentGroup" where the visual of the LayeredRootPart is inserted. Therefore, the "contentTransform" is applied to all layers. In order to have the handles unscaled, you need to compute the inverse transform and apply it to the handle layer visual. This can be done by subclassing LayeredRootPart/FXRootPart and overriding the #createHandleLayer() method as follows:
import org.eclipse.gef.fx.nodes.InfiniteCanvas;
import javafx.scene.Group;
import javafx.scene.transform.Affine;
import javafx.scene.transform.NonInvertibleTransformException;
public class UnscaledHandlesRootPart extends LayeredRootPart {
@Override
protected Group createHandleLayer() {
Group handleLayer = super.createHandleLayer();
Affine handleLayerTransform = new Affine();
handleLayer.getTransforms().add(handleLayerTransform);
ChangeListener<? super Number> updateHandleTransformOnTransformChange = (
observable, oldValue, newValue) -> {
updateHandleTransform(handleLayerTransform,
((InfiniteCanvas) getViewer().getCanvas())
.getContentTransform());
};
((InfiniteCanvas) getViewer().getCanvas()).getContentTransform()
.mxxProperty()
.addListener(updateHandleTransformOnTransformChange);
((InfiniteCanvas) getViewer().getCanvas()).getContentTransform()
.mxyProperty()
.addListener(updateHandleTransformOnTransformChange);
((InfiniteCanvas) getViewer().getCanvas()).getContentTransform()
.myxProperty()
.addListener(updateHandleTransformOnTransformChange);
((InfiniteCanvas) getViewer().getCanvas()).getContentTransform()
.myyProperty()
.addListener(updateHandleTransformOnTransformChange);
((InfiniteCanvas) getViewer().getCanvas()).getContentTransform()
.txProperty()
.addListener(updateHandleTransformOnTransformChange);
((InfiniteCanvas) getViewer().getCanvas()).getContentTransform()
.tyProperty()
.addListener(updateHandleTransformOnTransformChange);
return handleLayer;
}
private void updateHandleTransform(Affine handleLayerTransform,
Affine newValue) {
Affine inv;
try {
inv = newValue.createInverse();
} catch (NonInvertibleTransformException e) {
throw new IllegalStateException(e);
}
handleLayerTransform.setMxx(inv.getMxx());
handleLayerTransform.setMxy(inv.getMxy());
handleLayerTransform.setMyx(inv.getMyx());
handleLayerTransform.setMyy(inv.getMyy());
handleLayerTransform.setTx(inv.getTx());
handleLayerTransform.setTy(inv.getTy());
}
}
This IRootPart implementation needs to be registered within the module as follows:
@Override
protected void bindIRootPart() {
binder().bind(IRootPart.class).to(UnscaledHandlesRootPart.class);
}
Additionally, the handle parts need to be refreshed when the "contentTransform" changes. This can be done by subclassing the handle part implementations and overriding the #doActivate() and #doDeactivate() methods as follows:
private ChangeListener<? super Number> refreshOnTransformChange = (a, b, c) -> {
refreshVisual();
};
private Affine contentTransform;
@Override
protected void doActivate() {
super.doActivate();
InfiniteCanvas canvas = (InfiniteCanvas) getViewer().getCanvas();
contentTransform = canvas.getContentTransform();
contentTransform.mxxProperty().addListener(refreshOnTransformChange);
contentTransform.mxyProperty().addListener(refreshOnTransformChange);
contentTransform.myxProperty().addListener(refreshOnTransformChange);
contentTransform.myyProperty().addListener(refreshOnTransformChange);
contentTransform.txProperty().addListener(refreshOnTransformChange);
contentTransform.tyProperty().addListener(refreshOnTransformChange);
}
@Override
protected void doDeactivate() {
contentTransform.mxxProperty().removeListener(refreshOnTransformChange);
contentTransform.mxyProperty().removeListener(refreshOnTransformChange);
contentTransform.myxProperty().removeListener(refreshOnTransformChange);
contentTransform.myyProperty().removeListener(refreshOnTransformChange);
contentTransform.txProperty().removeListener(refreshOnTransformChange);
contentTransform.tyProperty().removeListener(refreshOnTransformChange);
contentTransform = null;
super.doDeactivate();
}
h2h & best regards,
Matthias
[Updated on: Thu, 27 October 2016 10:27] by Moderator
|
|
|
|
Re: [GEF4] Huge selection circle and line when zoom in [message #1746422 is a reply to message #1746407] |
Fri, 28 October 2016 09:18  |
Eclipse User |
|
|
|
Hi Uwe,
1) yes you are right, the FXRootPart was renamed to LayeredRootPart in the development branch, and some methods were renamed within the module. Using bindFXRootPartAsContentViewerAdapter() is the correct place to bind the alternative IRootPart implementation.
2) Actually, I think we covered a bug related to VisualChangeListener by having all layers transformed per default. It should not be necessary to register listeners on the transformation for each handle part as these listeners should have been registered already by the VisualChangeListener that is used to refresh feedback- and handle-parts to stay in sync with their corresponding content-part(s). I will create a Bugzilla to keep track of the issue (once the post_bug.cgi is working again) and post the ticket # here.
update: I opened a Bugzilla ticket for the VisualChangeListener bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=506707
edit: For the moment, it should be easier to refresh all feedback and handle parts from within the custom root part in response to "contentTransform" changes, so that you do not need to replace the individual feedback and handle part classes.
Best regards,
Matthias
[Updated on: Sun, 30 October 2016 17:38] by Moderator
|
|
|
Powered by
FUDForum. Page generated in 0.04295 seconds