Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » GEF » [GEF4] Menu bar on right click
[GEF4] Menu bar on right click [message #1732558] Wed, 18 May 2016 02:02 Go to next message
Colin Sharples is currently offline Colin SharplesFriend
Messages: 96
Registered: July 2009
Location: Wellington, New Zealand
Member

I had been using the approach in the Logo example of using the FXDefaultHoverHandlePartFactory to add some buttons to the selected part on hover, but it doesn't quite fit what I need. For a start, I don't really want the hover behaviour, as I generally have a lot of parts in my editor, and the hover outline is very distracting. I could just turn off the outline, but that then leaves the hover handles floating way out in space with no outline to show what they relate to. That's the second thing - a lot of my parts can be quite large, and the top right corner of the bounds could be a long way away from the actual outline of the shape. I'd prefer for the action buttons to appear close to where the mouse is, probably on a right-click rather than a hover.

I added an IFXOnClickPolicy similar to the FXCreationMenuOnClickPolicy, and got that to pop up an HBox containing some buttons relevant to the part. However, to get those buttons to work, I had to handle the action directly in the IFXOnClickPolicy. I'd prefer to have the buttons treated as parts and have their policies injected, as there will be several different buttons depending on the part selected (I have a provider that will supply the correct buttons to use).

I tried getting an instance of DeleteHoverHandlePart from the injector, and although it showed up in the popup, its DeleteOnClickPolicy did not respond to mouse clicks. Here's the IFXOnClickPolicy:

public class TerrainActionOnClickPolicy extends AbstractFXInteractionPolicy implements IFXOnClickPolicy {
  @Inject
  private Injector injector;
  private HBox menu;

  @Override
  public void click(MouseEvent e) {
    if (e.isSecondaryButtonDown()) {
      menu = new HBox(4);
      Node visual = getHost().getVisual();
      Point2D local = visual.sceneToLocal(e.getSceneX(), e.getSceneY());
      menu.setLayoutX(local.getX() + 10);
      menu.setLayoutY(local.getY() + 10);
      DeleteHoverHandlePart delete = new DeleteHoverHandlePart();
      injector.injectMembers(delete);
      menu.getChildren().add(delete.getVisual());
      getOverlayLayer().getChildren().add(menu);
    }
  }

  protected Group getOverlayLayer() {
    return ((FXViewer) getHost().getRoot().getViewer()).getCanvas().getOverlayLayer();
  }

}


Is there something else I need to do to get the DeleteHoverHandlePart hooked? Or is there another way to go about this?


Colin Sharples
CTG Games Ltd
Wellington, New Zealand
Re: [GEF4] Menu bar on right click [message #1732726 is a reply to message #1732558] Thu, 19 May 2016 15:52 Go to previous message
Matthias Wienand is currently offline Matthias WienandFriend
Messages: 230
Registered: March 2015
Senior Member
Hi Colin,

the created parts need to be put into the visual-part-hierarchy, i.e. they need a parent part. For example, handle parts are always added as children to the root part, this is done within AbstractBehavior. However, a simple IFXOnClickPolicy is not sufficient to implement a context menu because the menu needs to be removed at some point (click in the background, etc.). Therefore, I would use a viewer model to maintain context menu state similar to the HoverModel. You can use a ContextMenuRootPart for the layout of the individual menu actions, similar to the FXHoverHandleRootPart. A ContextMenuOnClickPolicy can then be used to manipulate the ContextMenuModel, i.e. hide/show the context menu.

1) Implement ContextMenuModel and register as viewer adapter.
2) Implement ContextMenuHandleRootPart (similar to FXHoverHandleRootPart).
3) Implement handle parts for the individual context menu actions (e.g. FXDeleteHoverHandlePart).
4) Implement ContextMenuBehavior and register as content root part adapter.
5) Implement ContextMenuOnClickPolicy (your TerrainActionOnClickPolicy) and register as content root part adapter, as well as content part adapter for all parts that need a context menu.

The implementation of ContextMenuBehavior should look like this, approximately:
public class ContextMenuBehavior extends AbstractBehavior<Node> {
        @Inject
        private Injector injector;

        private final ChangeListener<IContentPart<Node, ? extends Node>> contextPartObserver = new ChangeListener<IContentPart<Node, ? extends Node>>() {
                @Override
                public void changed(ObservableValue<? extends IContentPart<Node, ? extends Node>> observable,
                                IContentPart<Node, ? extends Node> oldValue, IContentPart<Node, ? extends Node> newValue) {
                        updateContextMenu(oldValue, newValue);
                }
        };

        @Override
        protected void doActivate() {
                super.doActivate();
                getHost().getRoot().getViewer().getAdapter(ContextMenuModel.class).contextPartProperty()
                                .addListener(contextPartObserver);
        }

        @Override
        protected void doDeactivate() {
                getHost().getRoot().getViewer().getAdapter(ContextMenuModel.class).contextPartProperty()
                                .removeListener(contextPartObserver);
                super.doDeactivate();
        }

        protected void updateContextMenu(IContentPart<Node, ? extends Node> oldPart,
                        IContentPart<Node, ? extends Node> newPart) {
                if (oldPart != null) {
                        removeHandles(getHandleParts());
                }
                if (newPart != null) {
                        // create menu root handle part
                        ContextMenuRootPart contextMenuRootPart = new ContextMenuRootPart();
                        injector.injectMembers(contextMenuRootPart);

                        // create individual parts for the menu actions
                        DeleteHoverHandlePart deletePart = new DeleteHoverHandlePart();
                        injector.injectMembers(deletePart);
                        contextMenuRootPart.addChild(deletePart);
                        // ...

                        // add context menu to viewer
                        addHandles(Collections.singletonList(getHost()), Collections.singletonList(contextMenuRootPart));
                }
        }
}


Best regards,
Matthias
Re: [GEF4] Menu bar on right click [message #1732746 is a reply to message #1732726] Thu, 19 May 2016 12:52 Go to previous message
Colin Sharples is currently offline Colin SharplesFriend
Messages: 96
Registered: July 2009
Location: Wellington, New Zealand
Member

Great, thanks, I will give that a go.

Colin Sharples
CTG Games Ltd
Wellington, New Zealand
Previous Topic:Dashed grid not working in GEF 3.11.0.201605020204
Next Topic:[GEF4] Selection handles for different actions
Goto Forum:
  


Current Time: Fri Apr 26 00:32:43 GMT 2024

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

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

Back to the top