Skip to main content



      Home
Home » Eclipse Projects » GEF » [GEF4] Huge selection circle and line when zoom in
[GEF4] Huge selection circle and line when zoom in [message #1711685] Mon, 19 October 2015 05:35 Go to next message
Eclipse UserFriend
Hello,

I have problem with circle and line selection, when you zoom in a lot they are huge as you can see in the screenshot.
What I want to get is a selection circle that would have the same size on the screen regardless of the zoom.
Is there an easy way for me to change this default behavior?

Thank you.

index.php/fa/23595/0/

Re: [GEF4] Huge selection circle and line when zoom in [message #1711778 is a reply to message #1711685] Mon, 19 October 2015 11:06 Go to previous messageGo to next message
Eclipse UserFriend
By default the visuals of IFeedbackParts and IHandleParts are put in the feedback and handle layer, which are both scaled with the content layer by default.

The easiest way to achieve what you want is probably to bind a different FXRootPart implementation that introduces unscaled layers for handles and feedback, overwriting the addChildVisual() and removeChildVisual operations to add the visuals of those parts you don't won't to scale to these new layers. The positioning of the feedback and handles should still work out-of-the-box.
Re: [GEF4] Huge selection circle and line when zoom in [message #1746294 is a reply to message #1711778] Wed, 26 October 2016 10:34 Go to previous messageGo to next message
Eclipse UserFriend
Hello Alexander,

can you provide a small example how to create a unscalable layer.
I have indroduced a own FXRootPart and could override the createFeedbackLayer-method, but I couldn't found the place to modify the zoom (scaling) behavior.

Many thanks
Uwe

Re: [GEF4] Huge selection circle and line when zoom in [message #1746367 is a reply to message #1746294] Thu, 27 October 2016 10:24 Go to previous messageGo to next message
Eclipse UserFriend
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 #1746407 is a reply to message #1746367] Fri, 28 October 2016 06:16 Go to previous messageGo to next message
Eclipse UserFriend
Thank you for the fast response.

The first step solved my problem for the moment.
The second step is only necessary on zooming with active HandleParts or SelectionParts in my understanding?

In my opinion the zooming should be deactivated by default in the feedback and handle layers. In my application the zoom changes up to factor 10000 or further, such zoomed handles are useless.

A short question on your solution:

1. the class "LayeredRootPart" and the function "bindRootPart" are not available in my GEF SDK (i use the version released with NEON)? I could replace it with "FXRootPart" and "bindFXRootPartAsContentViewerAdapter".

2. It seems very complex to extend every Handle- and SelectionPart for the second part of your solution. Can you give me a hint which classes and which bindings are affected creating an extension of the AbstractFXView?

Thanks
Uwe
Re: [GEF4] Huge selection circle and line when zoom in [message #1746422 is a reply to message #1746407] Fri, 28 October 2016 09:18 Go to previous message
Eclipse UserFriend
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

Previous Topic:Node overlapping problem in HorizontalTreeLayoutAlgorithm
Next Topic:[GEF4] Bad Performance on Scaling with larger amount of Nodes
Goto Forum:
  


Current Time: Wed Apr 23 02:16:10 EDT 2025

Powered by FUDForum. Page generated in 0.04295 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top