Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add marquee tool #108

Merged
merged 5 commits into from
Mar 23, 2021
Merged

Add marquee tool #108

merged 5 commits into from
Mar 23, 2021

Conversation

sgraband
Copy link
Contributor

Add marquee tool to select multiple elements at once. Selecting with the marquee tool is done by clicking and dragging the mouse while the shift key is pressed.

MarqueeFinished

Signed-off-by: Simon Graband <sgraband@eclipsesource.com>
Signed-off-by: Simon Graband <sgraband@eclipsesource.com>
@tortmayr tortmayr self-requested a review March 18, 2021 12:50
@planger
Copy link
Member

planger commented Mar 18, 2021

Just one comment from the top of my head, I think it'd be cool to also add a tool to the palette to enable the marquee tool directly. Can be done in a follow-up PR though.

Copy link
Contributor

@tortmayr tortmayr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! In general the tool works well and is a great contribution to glsp.
I have a couple of inline comments and found one general issue:

The current implementation is specific to the workflow-example and cannot be reused generically.
We should move the model configuration and the marquee view definition into the glsp-client package. It is probably a good idea to create a dedicated marqueeToolsModule that handles both the tool registration/binding and the configuration of the marqueeView.

@@ -58,6 +59,13 @@ export class TaskNode extends RectangularNode implements Nameable, WithEditableL
}
}

export class MarqueeNode extends RectangularNode {
static readonly DEFAULT_FEATURES = [connectableFeature, deletableFeature, selectFeature, boundsFeature,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should remove all unneeded features here to avoid potential unintended side effects.
IMO it should be enough to only activate the boundsFeature

@@ -65,6 +65,21 @@ export class ForkOrJoinNodeView extends RectangularNodeView {
}
}

@injectable()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The view definition should be part of @eclipse-glsp/client to enable generic reuse.


const toolsModule = new ContainerModule((bind, _unbind, isBound) => {
// Register default tools
bind(GLSP_TYPES.IDefaultTool).to(ChangeBoundsTool);
bind(GLSP_TYPES.IDefaultTool).to(EdgeEditTool);
bind(GLSP_TYPES.IDefaultTool).to(DelKeyDeleteTool);
bind(GLSP_TYPES.IDefaultTool).to(MarqueeTool);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It probably makes sense to introduce a dedicated 'marqueeToolModule'
This module than binds the corresponding tools, and configures the modelelement/view.

Copy link
Contributor Author

@sgraband sgraband Mar 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that the marquee tool is no longer handled by 'tools' feature and is completly handled in a newly created 'marquee-tool' feature?
The marqueeToolModule would then look like this:

const glspMarqueeToolModule = new ContainerModule((bind, unbind, isBound, rebind) => {
    const context = { bind, unbind, isBound, rebind };
    configureModelElement(context, 'marquee', MarqueeNode, MarqueeView);
    bind(GLSP_TYPES.IDefaultTool).to(MarqueeTool);
    bind(GLSP_TYPES.ITool).to(MarqueeMouseTool);
});

Copy link
Contributor

@tortmayr tortmayr Mar 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, however on second thought it may be better to just create a utility function configureMarqueeTool which is then called inside of the tools module

const toolsModule = new ContainerModule((bind, _unbind, isBound) => {
//...
 const context = { bind, isBound};
configureMarqueeTool(context);
}

export function configureMarqueeTool((context: { bind: interfaces.Bind, isBound: interfaces.IsBound }){
    configureModelElement(context, 'marquee', MarqueeNode, MarqueeView);
    bind(GLSP_TYPES.IDefaultTool).to(MarqueeTool);
    bind(GLSP_TYPES.ITool).to(MarqueeMouseTool);
};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you then expect the MarqueeNode, MarqueeView, MarqueeMouseTool and MarqueeTool to be in the tools feature or in the separate marquee-tool, even though they will be bound in the tools feature?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would omit the separate marque-tool for now and keep MarqueeNode, MarqueeView, MarqueeMouseTool and MarqueeTool in the tools feature but extract the actual binding process into a utility function. This way it can be easily reused and/or removed in subclasses.

export class MarqueeMouseTool extends BaseGLSPTool {
static ID = "glsp.marquee-mouse-tool";

@inject(GLSP_TYPES.MouseTool) protected mouseTool: IMouseTool;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mouseTool,keyTool and feedbackActionDispatcher are already injected in the super class ('BaseGLSPTool'). No need to inject them here again

this.marqueeMouseListener = new MarqueeMouseListener(this.domHelper);
this.mouseTool.register(this.marqueeMouseListener);
this.keyTool.register(this.shiftKeyListener);
this.feedbackDispatcher.registerFeedback(this, [cursorFeedbackAction(CursorCSS.MARQUEE)]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use the dispatchFeedback() method from the super class for this

disable(): void {
this.mouseTool.deregister(this.marqueeMouseListener);
this.keyTool.deregister(this.shiftKeyListener);
this.feedbackDispatcher.registerFeedback(this, [cursorFeedbackAction()]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use the `deregisterFeedback()' method from the superclass for this

export class MarqueeTool extends BaseGLSPTool {
static ID = "glsp.marquee-tool";

protected selectionKeyListener: MarqueeKeyListener = new MarqueeKeyListener();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably be named 'marqueeKeyListener' instead of 'selectionKeyListener'

Signed-off-by: Simon Graband <sgraband@eclipsesource.com>
@sgraband sgraband requested a review from tortmayr March 22, 2021 13:26
Signed-off-by: Simon Graband <sgraband@eclipsesource.com>
Copy link
Contributor

@tortmayr tortmayr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot. Change looks good to me now, I only have one minor suggestion

bind(NodeCreationTool).toSelf().inSingletonScope();
bind(EdgeCreationTool).toSelf().inSingletonScope();
bind(GLSP_TYPES.ITool).toService(EdgeCreationTool);
bind(GLSP_TYPES.ITool).toService(NodeCreationTool);

configureMarqueeTool({ bind, isBound });
configureActionHandler({ bind, isBound }, EnableToolsAction.KIND, GLSPScrollMouseListener);
Copy link
Contributor

@tortmayr tortmayr Mar 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

configureActionHandler() should be moved into the glspViewportModule

bind(NodeCreationTool).toSelf().inSingletonScope();
bind(EdgeCreationTool).toSelf().inSingletonScope();
bind(GLSP_TYPES.ITool).toService(EdgeCreationTool);
bind(GLSP_TYPES.ITool).toService(NodeCreationTool);

configureMarqueeTool({ bind, isBound });
configureActionHandler({ bind, isBound }, EnableToolsAction.KIND, GLSPScrollMouseListener);
configureActionHandler({ bind, isBound }, EnableDefaultToolsAction.KIND, GLSPScrollMouseListener);
Copy link
Contributor

@tortmayr tortmayr Mar 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

configureActionHandler() should be moved into the glspViewportModule

Signed-off-by: Simon Graband <sgraband@eclipsesource.com>
@tortmayr tortmayr self-requested a review March 23, 2021 11:36
Copy link
Contributor

@tortmayr tortmayr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@tortmayr tortmayr merged commit 012a1a3 into eclipse-glsp:master Mar 23, 2021
tortmayr added a commit that referenced this pull request Mar 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants