-
Notifications
You must be signed in to change notification settings - Fork 29
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
Add marquee tool #108
Conversation
Signed-off-by: Simon Graband <sgraband@eclipsesource.com>
Signed-off-by: Simon Graband <sgraband@eclipsesource.com>
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. |
There was a problem hiding this 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.
examples/workflow-glsp/src/model.ts
Outdated
@@ -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, |
There was a problem hiding this comment.
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() |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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);
});
There was a problem hiding this comment.
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);
};
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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)]); |
There was a problem hiding this comment.
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()]); |
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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>
Signed-off-by: Simon Graband <sgraband@eclipsesource.com>
There was a problem hiding this 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); |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
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.