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

GLSP-1388 Enhance extensibility of ContainerManager #385

Merged
merged 2 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,36 @@ export interface TrackedInsert {
options: InsertOptions;
}

export interface IContainerManager {
martin-fleck-at marked this conversation as resolved.
Show resolved Hide resolved
insert(proxy: GModelElement, location: Point, elementTypeId: string, opts?: Partial<InsertOptions>): TrackedInsert;
findContainer(location: Point, ctx: GModelElement, evt?: MouseEvent): ContainerElement | undefined;
addInsertFeedback(feedback: FeedbackEmitter, trackedInsert: TrackedInsert, ctx?: GModelElement, event?: MouseEvent): FeedbackEmitter;
}

/**
* The default {@link IContainerManager} implementation.
* This class class manages the insertion of elements into containers by validating their positions and types,
* providing feedback on the insertion process, and determining the appropriate container based on the location and context.
*/
@injectable()
export class ContainerManager {
export class ContainerManager implements IContainerManager {
@inject(ChangeBoundsManager) protected readonly changeBoundsManager: ChangeBoundsManager;

insert(proxy: GModelElement, location: Point, elementTypeId: string, opts?: Partial<InsertOptions>): TrackedInsert {
const options = { ...DEFAULT_INSERT_OPTIONS, ...opts };
const container = this.findContainer(location, proxy, opts?.evt);
let valid = !container || container.isContainableElement(elementTypeId);
let valid = this.isCreationAllowed(container, elementTypeId, opts);
if (valid && (!container || options.validateLocationInContainer)) {
// we need to check whether the location is valid either because we do not have a container or the option is set
valid = opts?.validLocationOverwrite ?? this.changeBoundsManager.hasValidPosition(proxy, location);
}
return { elementTypeId, container, location, valid, options };
}

protected isCreationAllowed(container: ContainerElement | undefined, elementTypeId: string, opts?: Partial<InsertOptions>): boolean {
martin-fleck-at marked this conversation as resolved.
Show resolved Hide resolved
return !container || container.isContainableElement(elementTypeId);
}

findContainer(location: Point, ctx: GModelElement, evt?: MouseEvent): ContainerElement | undefined {
// reverse order of children to find the innermost, top-rendered containers first
return findChildrenAtPosition(ctx.root, location)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { InsertIndicatorView } from './node-creation-views';
export const nodeCreationToolModule = new FeatureModule(
(bind, unbind, isBound, rebind) => {
const context = { bind, unbind, isBound, rebind };
bind(ContainerManager).toSelf().inSingletonScope();
bind(TYPES.IContainerManager).to(ContainerManager).inSingletonScope();
martin-fleck-at marked this conversation as resolved.
Show resolved Hide resolved
bindAsService(context, TYPES.ITool, NodeCreationTool);
configureActionHandler(context, TriggerNodeCreationAction.KIND, NodeCreationTool);
configureModelElement(context, InsertIndicator.TYPE, InsertIndicator, InsertIndicatorView);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import { RemoveTemplateElementsAction } from '../../element-template/remove-temp
import { BaseCreationTool } from '../base-tools';
import { ChangeBoundsManager } from '../change-bounds/change-bounds-manager';
import { TrackedMove } from '../change-bounds/change-bounds-tracker';
import { ContainerManager, TrackedInsert } from './container-manager';
import { IContainerManager, TrackedInsert } from './container-manager';
import { InsertIndicator } from './insert-indicator';

@injectable()
Expand All @@ -55,7 +55,7 @@ export class NodeCreationTool extends BaseCreationTool<TriggerNodeCreationAction
protected isTriggerAction = TriggerNodeCreationAction.is;

@inject(ChangeBoundsManager) readonly changeBoundsManager: ChangeBoundsManager;
@inject(ContainerManager) readonly containerManager: ContainerManager;
@inject(TYPES.IContainerManager) readonly containerManager: IContainerManager;
@inject(TYPES.IModelFactory) modelFactory: IModelFactory;

get id(): string {
Expand Down Expand Up @@ -95,7 +95,7 @@ export class NodeCreationTool extends BaseCreationTool<TriggerNodeCreationAction
}

export interface ContainerPositioningTool extends PositioningTool {
readonly containerManager: ContainerManager;
readonly containerManager: IContainerManager;
}

export class NodeInsertTrackingListener extends MouseTrackingElementPositionListener {
Expand Down
1 change: 1 addition & 0 deletions packages/glsp-sprotty/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,6 @@ export const TYPES = {
IDiagramOptions: Symbol('IDiagramOptions'),
IDiagramStartup: Symbol('IDiagramStartup'),
IToolManager: Symbol('IToolManager'),
IContainerManager: Symbol('IContainerManager'),
Grid: Symbol('Grid')
};
Loading