Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    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 09:35 Go to next message
Xavier JACQUES is currently offline Xavier JACQUESFriend
Messages: 10
Registered: October 2015
Junior Member
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 15:06 Go to previous messageGo to next message
Alexander Nyssen is currently offline Alexander NyssenFriend
Messages: 244
Registered: July 2009
Location: L√ľnen
Senior Member
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 14:34 Go to previous messageGo to next message
Uwe Peuker is currently offline Uwe PeukerFriend
Messages: 13
Registered: September 2016
Junior Member
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 14:24 Go to previous messageGo to next message
Matthias Wienand is currently offline Matthias WienandFriend
Messages: 230
Registered: March 2015
Senior Member
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 14:27]

Report message to a moderator

Re: [GEF4] Huge selection circle and line when zoom in [message #1746407 is a reply to message #1746367] Fri, 28 October 2016 10:16 Go to previous messageGo to next message
Uwe Peuker is currently offline Uwe PeukerFriend
Messages: 13
Registered: September 2016
Junior Member
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 13:18 Go to previous message
Matthias Wienand is currently offline Matthias WienandFriend
Messages: 230
Registered: March 2015
Senior Member
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 21:38]

Report message to a moderator

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


Current Time: Thu Dec 07 05:10:26 GMT 2023

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

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

Back to the top