Skip to content

Commit

Permalink
Refactor mouseTool
Browse files Browse the repository at this point in the history
The mouseTool is part of the default sprotty module and our customization should therefore be part of the `glspDefaultModule`.
- Move mouse tool into base package
- Rework `Rank` interface and utility function to our default interface+namespace pattern
- Remove `TYPES.MouseTool` service identifert, and unecessary interface wrapper. Directly inject mousetool instead
  • Loading branch information
tortmayr committed Jul 6, 2023
1 parent 03c47ab commit c884623
Show file tree
Hide file tree
Showing 12 changed files with 49 additions and 63 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
- Removed the `TYPES.SelectionService` service identifier. Please directly use the `SelectionService` class as service identifier instead.
- The `SelectionService` binding is now part of the `defaultGLSPModule`. This means the `SelectionService` remains available even if the `selectModule` is not configured.
- `RootModelChangeListener`s are no longer tied to the `FeedbackawareUpdateModelCommand` instead they are managed by the `GLSPCommandStack`.
- `IMouseTool` and `TYPES.IMouseTool` are no longer available. Directly inject and use `MouseTool` instead.
- Refactored rank utility functions
- `isRanked()` -> `Ranked.is()`
- `getRank()` -> `Ranked.getRank()`
- `DEFAULT_RANK` -> `Ranked.DEFAULT_RANK`

## [v1.0.0 - 30/06/2022](https://github.com/eclipse-glsp/glsp-client/releases/tag/v1.0.0)

Expand Down
4 changes: 4 additions & 0 deletions packages/client/src/base/di.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
ActionHandlerRegistry,
InitializeResult,
ModelSource,
MouseTool,
SetEditModeAction,
TYPES,
bindAsService,
Expand All @@ -39,6 +40,7 @@ import { GLSPModelRegistry } from './model/model-registry';
import { SelectionClearingMouseListener } from './selection-clearing-mouse-listener';
import { SelectionService } from './selection-service';
import { GLSPToolManager } from './tool-manager/glsp-tool-manager';
import { RankingMouseTool } from './view/mouse-tool';
import { GLSPViewRegistry } from './view/view-registry';

const defaultGLSPModule = new ContainerModule((bind, _unbind, isBound, rebind) => {
Expand All @@ -64,6 +66,8 @@ const defaultGLSPModule = new ContainerModule((bind, _unbind, isBound, rebind) =
bind(TYPES.IFeedbackActionDispatcher).to(FeedbackActionDispatcher).inSingletonScope();
configureCommand(context, FeedbackAwareUpdateModelCommand);

rebind(MouseTool).to(RankingMouseTool).inSingletonScope();

bindAsService(context, TYPES.MouseListener, SelectionClearingMouseListener);

bindOrRebind(context, TYPES.ICommandStack).to(GLSPCommandStack);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,30 @@
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { ContainerModule } from 'inversify';
import { MouseTool, TYPES } from '~glsp-sprotty';
import { RankingMouseTool } from './mouse-tool';

const glspMouseToolModule = new ContainerModule((bind, _unbind, _isBound, rebind) => {
bind(RankingMouseTool).toSelf().inSingletonScope();
bind(TYPES.MouseTool).toService(RankingMouseTool);
rebind(MouseTool).toService(RankingMouseTool);
});
import { AnyObject, hasNumberProp } from '~glsp-sprotty';

export default glspMouseToolModule;
/**
* A common interface for services/listeners that should be
* orderable by a type or rank/priority.
*/
export interface Ranked {
rank: number;
}

export namespace Ranked {
export const DEFAULT_RANK = 0;
export function is(object: unknown): object is Ranked {
return AnyObject.is(object) && hasNumberProp(object, 'rank');
}

/**
* Tries to retrieve the rank form the given object. If the object
* implements the {@link Ranked} interface the corresponding rank is returned
* otherwise the {@link DEFAULT_RANK} is returned.
* @param object
*/
export function getRank(object: unknown): number {
return is(object) ? object.rank : DEFAULT_RANK;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,7 @@
********************************************************************************/
import { injectable, multiInject, optional } from 'inversify';
import { Action, MouseListener, MouseTool, SModelElement, SModelRoot, TYPES } from '~glsp-sprotty';
import { getRank } from '../rank/model';

export interface IMouseTool {
register(mouseListener: MouseListener): void;
deregister(mouseListener: MouseListener): void;
}
import { Ranked } from '../ranked';

/**
* Custom helper type to declare the explicit mouse listener methods
Expand All @@ -29,22 +24,22 @@ export interface IMouseTool {
type MouseListenerMethods = keyof Omit<MouseListener, 'decorate'>;

@injectable()
export class RankingMouseTool extends MouseTool implements IMouseTool {
export class RankingMouseTool extends MouseTool {
protected rankedMouseListeners: Map<number, MouseListener[]>;

constructor(@multiInject(TYPES.MouseListener) @optional() protected override mouseListeners: MouseListener[] = []) {
super(mouseListeners);
this.rankedMouseListeners = groupBy(mouseListeners, listener => getRank(listener));
this.rankedMouseListeners = groupBy(mouseListeners, listener => Ranked.getRank(listener));
}

override register(mouseListener: MouseListener): void {
super.register(mouseListener);
this.rankedMouseListeners = groupBy(this.mouseListeners, listener => getRank(listener));
this.rankedMouseListeners = groupBy(this.mouseListeners, listener => Ranked.getRank(listener));
}

override deregister(mouseListener: MouseListener): void {
super.deregister(mouseListener);
this.rankedMouseListeners = groupBy(this.mouseListeners, listener => getRank(listener));
this.rankedMouseListeners = groupBy(this.mouseListeners, listener => Ranked.getRank(listener));
}

protected override handleEvent<K extends MouseListenerMethods>(methodName: K, model: SModelRoot, event: MouseEvent): void {
Expand Down
2 changes: 0 additions & 2 deletions packages/client/src/container-modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ import glspExportModule from './features/export/di.config';
import modelHintsModule from './features/hints/di.config';
import glspHoverModule from './features/hover/di.config';
import layoutModule from './features/layout/di.config';
import glspMouseToolModule from './features/mouse-tool/di.config';
import navigationModule from './features/navigation/di.config';
import glspSelectModule from './features/select/di.config';
import sourceModelWatcherModule from './features/source-model-watcher/di.config';
Expand All @@ -67,7 +66,6 @@ export const DEFAULT_MODULES = [
glspDecorationModule,
glspEditLabelModule,
glspHoverModule,
glspMouseToolModule,
glspSelectModule,
glspServerCopyPasteModule,
glspViewportModule,
Expand Down
29 changes: 0 additions & 29 deletions packages/client/src/features/rank/model.ts

This file was deleted.

4 changes: 2 additions & 2 deletions packages/client/src/features/select/select-mouse-listener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ import {
isSelectable,
toArray
} from '~glsp-sprotty';
import { DEFAULT_RANK, Ranked } from '../rank/model';
import { Ranked } from '../../base/ranked';

/**
* Ranked select mouse listener that is executed before default mouse listeners when using the RankedMouseTool.
* This ensures that default mouse listeners are working on a model that has selection changes already applied.
*/
export class RankedSelectMouseListener extends SelectMouseListener implements Ranked {
rank: number = DEFAULT_RANK - 1; /* we want to be executed before all default mouse listeners */
rank: number = Ranked.DEFAULT_RANK - 1; /* we want to be executed before all default mouse listeners */

override mouseDown(target: SModelElement, event: MouseEvent): (Action | Promise<Action>)[] {
const result: Action[] = [];
Expand Down
5 changes: 2 additions & 3 deletions packages/client/src/features/tools/base-glsp-tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,16 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { inject, injectable } from 'inversify';
import { Action, IActionDispatcher, KeyTool, TYPES } from '~glsp-sprotty';
import { Action, IActionDispatcher, KeyTool, MouseTool, TYPES } from '~glsp-sprotty';
import { EditorContextService } from '../../base/editor-context-service';
import { IFeedbackActionDispatcher, IFeedbackEmitter } from '../../base/feedback/feedback-action-dispatcher';
import { GLSPTool } from '../../base/tool-manager/glsp-tool-manager';
import { IMouseTool } from '../mouse-tool/mouse-tool';

@injectable()
export abstract class BaseGLSPTool implements GLSPTool {
@inject(TYPES.IFeedbackActionDispatcher) protected feedbackDispatcher: IFeedbackActionDispatcher;
@inject(TYPES.IActionDispatcher) protected actionDispatcher: IActionDispatcher;
@inject(TYPES.MouseTool) protected mouseTool: IMouseTool;
@inject(MouseTool) protected mouseTool: MouseTool;
@inject(KeyTool) protected keyTool: KeyTool;
@inject(EditorContextService) protected readonly editorContext: EditorContextService;

Expand Down
4 changes: 2 additions & 2 deletions packages/client/src/features/tools/delete-tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
KeyListener,
KeyTool,
MouseListener,
MouseTool,
SModelElement,
TYPES,
findParentByFeature,
Expand All @@ -31,7 +32,6 @@ import {
} from '~glsp-sprotty';
import { IFeedbackActionDispatcher } from '../../base/feedback/feedback-action-dispatcher';
import { GLSPTool } from '../../base/tool-manager/glsp-tool-manager';
import { IMouseTool } from '../mouse-tool/mouse-tool';
import { CursorCSS, cursorFeedbackAction } from '../tool-feedback/css-feedback';

/**
Expand Down Expand Up @@ -89,7 +89,7 @@ export class MouseDeleteTool implements GLSPTool {

protected deleteToolMouseListener: DeleteToolMouseListener = new DeleteToolMouseListener();

@inject(TYPES.MouseTool) protected mouseTool: IMouseTool;
@inject(MouseTool) protected mouseTool: MouseTool;
@inject(TYPES.IFeedbackActionDispatcher) protected readonly feedbackDispatcher: IFeedbackActionDispatcher;

get id(): string {
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/glsp-sprotty/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export {
IButtonHandlerRegistration,
configureButtonHandler
} from 'sprotty/lib/features/button/button-handler';
export * from 'sprotty/lib/features/button/model';
export { SButtonImpl as SButton, SButtonSchema } from 'sprotty/lib/features/button/model';
export * from 'sprotty/lib/features/command-palette/action-providers';
export * from 'sprotty/lib/features/command-palette/command-palette';
export { Anchor, IContextMenuService, IContextMenuServiceProvider } from 'sprotty/lib/features/context-menu/context-menu-service';
Expand Down
1 change: 0 additions & 1 deletion packages/client/src/glsp-sprotty/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export const TYPES = {
IMovementRestrictor: Symbol('IMovementRestrictor'),
SelectionListener: Symbol('SelectionListener'),
SModelRootListener: Symbol('SModelRootListener'),
MouseTool: Symbol('MouseTool'),
IContextMenuProvider: Symbol('IContextMenuProvider'),
ICopyPasteHandler: Symbol('ICopyPasteHandler'),
ITool: Symbol('ITool'),
Expand Down
7 changes: 3 additions & 4 deletions packages/client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import glspEditLabelModule from './features/edit-label/di.config';
import modelHintsModule from './features/hints/di.config';
import glspHoverModule from './features/hover/di.config';
import layoutModule from './features/layout/di.config';
import glspMouseToolModule from './features/mouse-tool/di.config';
import navigationModule from './features/navigation/di.config';
import saveModule from './features/save/di.config';
import glspSelectModule from './features/select/di.config';
Expand Down Expand Up @@ -56,15 +55,18 @@ export * from './base/feedback/update-model-command';
export * from './base/focus-tracker';
export * from './base/model-initialization-constraint';
export * from './base/model/model-registry';
export * from './base/ranked';
export * from './base/selection-clearing-mouse-listener';
export * from './base/selection-service';
export * from './base/source-uri-aware';
export * from './base/tool-manager/glsp-tool-manager';
export * from './base/view/mouse-tool';
export * from './base/view/view-registry';
export * from './container-modules';

//
// ------------------ Features ------------------
export * from './base/view/mouse-tool';
export * from './features/accessibility/resize-key-tool/resize-key-tool';
export * from './features/accessibility/view-key-tools/deselect-key-tool';
export * from './features/accessibility/view-key-tools/movement-key-tool';
Expand Down Expand Up @@ -92,10 +94,8 @@ export * from './features/hints/model';
export * from './features/hints/type-hints';
export * from './features/hover/hover';
export * from './features/layout/layout-elements-action';
export * from './features/mouse-tool/mouse-tool';
export * from './features/navigation/navigation-action-handler';
export * from './features/navigation/navigation-target-resolver';
export * from './features/rank/model';
export * from './features/reconnect/model';
export * from './features/save/model';
export * from './features/save/save-keylistener';
Expand Down Expand Up @@ -149,7 +149,6 @@ export {
glspDecorationModule,
glspEditLabelModule,
glspHoverModule,
glspMouseToolModule,
glspMoveZoomModule,
glspResizeKeyModule,
glspSearchPaletteModule,
Expand Down

0 comments on commit c884623

Please sign in to comment.