Fix center option.

This commit is contained in:
Paulo Gustavo Veiga 2022-01-10 10:52:11 -08:00
parent cdd044c41d
commit 041adbc142
7 changed files with 115 additions and 151 deletions

View File

@ -57,6 +57,7 @@ import Point from '@wisemapping/web2d';
import { DesignerOptions } from './DesignerOptionsBuilder';
import MainTopic from './MainTopic';
import DragTopic from './DragTopic';
import NodeGraph from './NodeGraph';
class Designer extends Events {
private _mindmap: Mindmap;
@ -70,10 +71,10 @@ class Designer extends Events {
private _clipboard: any[];
private _cleanScreen: any;
constructor(options: DesignerOptions, divElement:JQuery) {
constructor(options: DesignerOptions, divElement: JQuery) {
$assert(options, 'options must be defined');
$assert(options.zoom, 'zoom must be defined');
$assert(options.size, 'size must be defined');
$assert(options.containerSize, 'size must be defined');
$assert(divElement, 'divElement must be defined');
super();
@ -83,7 +84,7 @@ class Designer extends Events {
this._options = options;
// Set full div elem render area ...
divElement.css(options.size);
divElement.css(options.containerSize);
// Dispatcher manager ...
const commandContext = new CommandContext(this);
@ -118,14 +119,12 @@ class Designer extends Events {
this._relPivot = new RelationshipPivot(this._workspace, this);
// Set editor working area ...
this.setViewPort(options.viewPort);
TopicEventDispatcher.configure(this.isReadOnly());
this._clipboard = [];
// Hack: There are static reference to designer variable. Needs to be reviewed.
global.designer = this;
}
private _registerWheelEvents(): void {
@ -167,12 +166,12 @@ class Designer extends Events {
});
// Deselect on click ...
screenManager.addEvent('click', (event:UIEvent) => {
screenManager.addEvent('click', (event: UIEvent) => {
me.onObjectFocusEvent(null, event);
});
// Create nodes on double click...
screenManager.addEvent('dblclick', (event:MouseEvent) => {
screenManager.addEvent('dblclick', (event: MouseEvent) => {
if (workspace.isWorkspaceEventsEnabled()) {
const mousePos = screenManager.getWorkspaceMousePosition(event);
const centralTopic = me.getModel().getCentralTopic();
@ -182,7 +181,7 @@ class Designer extends Events {
});
}
private _buildDragManager(workspace: Workspace):DragManager {
private _buildDragManager(workspace: Workspace): DragManager {
const designerModel = this.getModel();
const dragConnector = new DragConnector(designerModel, this._workspace);
const dragManager = new DragManager(workspace, this._eventBussDispatcher);
@ -193,7 +192,7 @@ class Designer extends Events {
topics.forEach((topic) => topic.setMouseEventsEnabled(false));
});
dragManager.addEvent('dragging', (event:MouseEvent, dragTopic:DragTopic) => {
dragManager.addEvent('dragging', (event: MouseEvent, dragTopic: DragTopic) => {
dragTopic.updateFreeLayout(event);
if (!dragTopic.isFreeLayoutOn(event)) {
// The node is being drag. Is the connection still valid ?
@ -205,7 +204,7 @@ class Designer extends Events {
}
});
dragManager.addEvent('enddragging', (event:MouseEvent, dragTopic:DragTopic) => {
dragManager.addEvent('enddragging', (event: MouseEvent, dragTopic: DragTopic) => {
topics.forEach((topic) => topic.setMouseEventsEnabled(true));
dragTopic.applyChanges(workspace);
});
@ -213,12 +212,6 @@ class Designer extends Events {
return dragManager;
}
private setViewPort(size: { height: number, width: number }):void {
this._workspace.setViewPort(size);
const model = this.getModel();
this._workspace.setZoom(model.getZoom(), true);
}
private _buildNodeGraph(model: NodeModel, readOnly: boolean): MainTopic {
// Create node graph ...
const topic = create(model, { readOnly });
@ -325,9 +318,9 @@ class Designer extends Events {
this._workspace.setZoom(zoom);
}
setZoomToFit(): void {
zoomToFit(): void {
this.getModel().setZoom(1);
this._workspace.setZoom(1,true);
this._workspace.setZoom(1, true);
}
zoomOut(factor: number = 1.2) {
@ -415,22 +408,8 @@ class Designer extends Events {
return this._model;
}
shrinkSelectedBranch(): void {
const nodes = this.getModel().filterSelectedTopics();
if (nodes.length <= 0 || nodes.length !== 1) {
// If there are more than one node selected,
$notify($msg('ONLY_ONE_TOPIC_MUST_BE_SELECTED_COLLAPSE'));
return;
}
// Execute event ...
const topic = nodes[0];
if (topic.getType() !== 'CentralTopic') {
this._actionDispatcher.shrinkBranch([topic.getId()], !topic.areChildrenShrunken());
}
}
/** create a NodeModel for the selected node's child and add it via the ActionDispatcher */
createChildForSelectedNode():void {
private _createChildForSelectedNode(): void {
const nodes = this.getModel().filterSelectedTopics();
if (nodes.length <= 0) {
// If there are more than one node selected,
@ -516,21 +495,7 @@ class Designer extends Events {
return childModel;
}
addDraggedNode(event, model: NodeModel) {
$assert(event, 'event can not be null');
$assert(model, 'model can not be null');
// Position far from the visual area ...
model.setPosition(1000, 1000);
this._actionDispatcher.addTopics([model]);
const topic = this.getModel().findTopicById(model.getId());
// Simulate a mouse down event to start the dragging ...
topic.fireEvent('mousedown', event);
}
createSiblingForSelectedNode():void {
createSiblingForSelectedNode(): void {
const nodes = this.getModel().filterSelectedTopics();
if (nodes.length <= 0) {
// If there are no nodes selected,
@ -547,7 +512,7 @@ class Designer extends Events {
if (!topic.getOutgoingConnectedTopic()) {
// Central topic and isolated topics ....
// Central topic doesn't have siblings ...
this.createChildForSelectedNode();
this._createChildForSelectedNode();
} else {
const parentTopic = topic.getOutgoingConnectedTopic();
const siblingModel = this._createSiblingModel(topic);
@ -563,7 +528,7 @@ class Designer extends Events {
}
}
private _createSiblingModel(topic: Topic):NodeModel {
private _createSiblingModel(topic: Topic): NodeModel {
let result = null;
let model = null;
const parentTopic = topic.getOutgoingConnectedTopic();
@ -584,7 +549,7 @@ class Designer extends Events {
return result;
}
showRelPivot(event):void {
showRelPivot(event: MouseEvent): void {
const nodes = this.getModel().filterSelectedTopics();
if (nodes.length <= 0) {
// This could not happen ...
@ -600,8 +565,7 @@ class Designer extends Events {
this._relPivot.start(nodes[0], pos);
}
/** @return {{zoom:Number}} the zoom */
getMindmapProperties() {
getMindmapProperties(): { zoom: number } {
const model = this.getModel();
return { zoom: model.getZoom() };
}
@ -610,7 +574,7 @@ class Designer extends Events {
* @param {mindplot.Mindmap} mindmap
* @throws will throw an error if mindmapModel is null or undefined
*/
loadMap(mindmap: Mindmap) {
loadMap(mindmap: Mindmap): void {
$assert(mindmap, 'mindmapModel can not be null');
this._mindmap = mindmap;
@ -629,7 +593,7 @@ class Designer extends Events {
// Building node graph ...
const branches = mindmap.getBranches();
branches.forEach((branch) => {
const nodeGraph = this.nodeModelToNodeGraph(branch);
const nodeGraph = this._nodeModelToTopic(branch);
nodeGraph.setBranchVisibility(true);
});
@ -651,27 +615,20 @@ class Designer extends Events {
return this._mindmap;
}
/** */
undo() {
// @Todo: This is a hack...
undo(): void {
this._actionDispatcher._actionRunner.undo();
}
/** */
redo() {
redo(): void {
this._actionDispatcher._actionRunner.redo();
}
/** */
isReadOnly() {
isReadOnly(): boolean {
return this._options.readOnly;
}
/**
* @param {mindplot.model.NodeModel} nodeModel
* @return {mindplot.Topic} the topic (extends mindplot.NodeGraph) created to the model
*/
nodeModelToNodeGraph(nodeModel: NodeModel) {
private _nodeModelToTopic(nodeModel: NodeModel):Topic {
$assert(nodeModel, 'Node model can not be null');
let children = nodeModel.getChildren().slice();
children = children.sort((a, b) => a.getOrder() - b.getOrder());
@ -682,19 +639,19 @@ class Designer extends Events {
this._workspace.append(result);
children.forEach((child) => {
if ($defined(child)) {
this.nodeModelToNodeGraph(child);
this._nodeModelToTopic(child);
}
});
return result;
}
/**
* @private
* @param {mindplot.model.RelationshipModel} model
* @return {mindplot.Relationship} the relationship created to the model
* @throws will throw an error if model is null or undefined
*/
private _relationshipModelToRelationship(model: RelationshipModel) {
* @private
* @param {mindplot.model.RelationshipModel} model
* @return {mindplot.Relationship} the relationship created to the model
* @throws will throw an error if model is null or undefined
*/
private _relationshipModelToRelationship(model: RelationshipModel):Relationship {
$assert(model, 'Node model can not be null');
const result = this._buildRelationshipShape(model);
@ -715,7 +672,7 @@ class Designer extends Events {
* @param {mindplot.model.RelationshipModel} model
* @return {mindplot.Relationship} the relationship added to the mindmap
*/
addRelationship(model: RelationshipModel) {
addRelationship(model: RelationshipModel):Relationship {
const mindmap = this.getMindmap();
mindmap.addRelationship(model);
return this._relationshipModelToRelationship(model);
@ -725,7 +682,7 @@ class Designer extends Events {
* deletes the relationship from the linked topics, DesignerModel, Workspace and Mindmap
* @param {mindplot.Relationship} rel the relationship to delete
*/
deleteRelationship(rel: Relationship) {
deleteRelationship(rel: Relationship):void {
const sourceTopic = rel.getSourceTopic();
sourceTopic.deleteRelationship(rel);
@ -745,7 +702,7 @@ class Designer extends Events {
* @return {mindplot.Relationship} the new relationship with events registered
* @throws will throw an error if the target topic cannot be found
*/
_buildRelationshipShape(model: RelationshipModel) {
private _buildRelationshipShape(model: RelationshipModel):Relationship {
const dmodel = this.getModel();
const sourceTopicId = model.getFromNode();

View File

@ -17,11 +17,11 @@
*/
import { $assert } from '@wisemapping/core-js';
import PersistenceManager from './PersistenceManager';
import { Size } from './Size';
export type DesignerOptions = {
zoom: number,
viewPort?: { height: number, width: number },
size?: { height: number, width: number },
containerSize?: Size,
readOnly?: boolean,
mapId?: string,
container: string,
@ -34,27 +34,21 @@ class OptionsBuilder {
static buildOptions(options: DesignerOptions): DesignerOptions {
$assert(options.persistenceManager, 'persistence must be defined');
let containerSize = options.size;
if (options.size == null) {
let containerSize = options.containerSize;
if (options.containerSize == null) {
// If it has not been defined, use browser size ...
containerSize = {
width: window.screen.availWidth,
height: window.screen.availHeight,
width: window.screen.width,
height: window.screen.height,
}
console.log("height:"+containerSize.height);
}
// Is offset adjustment required
const viewPort = {
height: window.innerHeight,
width: window.innerWidth,
};
const defaultOptions: DesignerOptions = {
readOnly: false,
zoom: 0.85,
saveOnLoad: true,
size: containerSize,
viewPort: viewPort,
containerSize: containerSize,
container: 'mindplot',
locale: 'en',
};

View File

@ -19,10 +19,10 @@ import { $assert } from '@wisemapping/core-js';
import { Point } from '@wisemapping/web2d';
class ScreenManager {
_divContainer: JQuery;
_padding: { x: number; y: number; };
_clickEvents: ((event: UIEvent)=>void)[];
_scale: number;
private _divContainer: JQuery;
private _padding: { x: number; y: number; };
private _clickEvents: ((event: UIEvent)=>void)[];
private _scale: number;
constructor(divElement: JQuery) {
$assert(divElement, 'can not be null');
@ -41,6 +41,16 @@ class ScreenManager {
});
}
/**
* Return the current visibile area in the browser.
*/
getVisibleBrowserSize():{width:number,height:number}{
return {
width: window.innerWidth,
height: window.innerHeight - 50 // Todo: Fix toolbar hardcode.
}
}
setScale(scale: number) {
$assert(scale, 'Screen scale can not be null');
this._scale = scale;

View File

@ -0,0 +1,4 @@
export type Size = {
width: number;
height: number;
};

View File

@ -18,16 +18,16 @@
import { $assert, $defined } from '@wisemapping/core-js';
import { Workspace as Workspace2D } from '@wisemapping/web2d';
import ScreenManager from './ScreenManager';
import { Size } from './Size';
class Workspace {
_zoom: number;
_screenManager: ScreenManager;
_isReadOnly: boolean;
_screenWidth: number;
_screenHeight: number;
_containerSize: Size;
_workspace: Workspace2D;
_eventsEnabled: boolean;
_viewPort: { height: number, width: number };
private _visibleAreaSize: any;
constructor(screenManager: ScreenManager, zoom: number, isReadOnly: boolean) {
// Create a suitable container ...
@ -39,36 +39,48 @@ class Workspace {
this._isReadOnly = isReadOnly;
const divContainer = screenManager.getContainer();
this._screenWidth = Number.parseInt(divContainer.css('width'), 10);
this._screenHeight = Number.parseInt(divContainer.css('height'), 10);
this._containerSize = {
width: Number.parseInt(divContainer.css('width'), 10),
height: Number.parseInt(divContainer.css('height'), 10)
}
// Initialize web2d workspace.
const workspace = this._createWorkspace();
this._workspace = workspace;
// Append to the workspace...
workspace.addItAsChildTo(divContainer);
this.setZoom(zoom, true);
// Register drag events ...
this._registerDragEvents();
this._eventsEnabled = true;
// Readjust if the window is resized ...
window.addEventListener('resize', (event) => {
this._adjustWorkspace();
});
this.setZoom(zoom, true);
}
get isReadOnly() {
private _adjustWorkspace(): void {
this.setZoom(this._zoom, false);
}
isReadOnly(): boolean {
return this._isReadOnly;
}
private _createWorkspace() {
// Initialize workspace ...
const coordOriginX = -(this._screenWidth / 2);
const coordOriginY = -(this._screenHeight / 2);
const browserVisibleSize = this._screenManager.getVisibleBrowserSize();
const coordOriginX = -(browserVisibleSize.width / 2);
const coordOriginY = -(browserVisibleSize.height / 2);
const workspaceProfile = {
width: `${this._screenWidth}px`,
height: `${this._screenHeight}px`,
coordSizeWidth: this._screenWidth,
coordSizeHeight: this._screenHeight,
width: `${this._containerSize.width}px`,
height: `${this._containerSize.height}px`,
coordSizeWidth: browserVisibleSize.width,
coordSizeHeight: browserVisibleSize.height,
coordOriginX,
coordOriginY,
fillColor: 'transparent',
@ -95,11 +107,11 @@ class Workspace {
}
}
addEvent(type, listener) {
addEvent(type: string, listener) {
this._workspace.addEvent(type, listener);
}
removeEvent(type, listener) {
removeEvent(type: string, listener) {
$assert(type, 'type can not be null');
$assert(listener, 'listener can not be null');
this._workspace.removeEvent(type, listener);
@ -112,52 +124,42 @@ class Workspace {
setZoom(zoom: number, center: boolean = false): void {
this._zoom = zoom;
const workspace = this._workspace;
// Calculate the original boxview size ...
let origWidth = 0;
let origHeight = 0
if (this._viewPort) {
origWidth = this._viewPort.width;
origHeight = this._viewPort.height;
}
const newVisibleAreaSize = this._screenManager.getVisibleBrowserSize();
// Update coord scale...
const coordWidth = zoom * this._screenWidth;
const coordHeight = zoom * this._screenHeight;
workspace.setCoordSize(coordWidth, coordHeight);
const newCoordWidth = zoom * this._containerSize.width;
const newCoordHeight = zoom * this._containerSize.height;
// View port coords ...
if (this._viewPort) {
this._viewPort.width *= zoom;
this._viewPort.height *= zoom;
}
// Center topic....
let coordOriginX: number;
let coordOriginY: number;
if (center) {
if (this._viewPort) {
coordOriginX = -(this._viewPort.width / 2);
coordOriginY = -(this._viewPort.height / 2);
} else {
coordOriginX = -(coordWidth / 2);
coordOriginY = -(coordHeight / 2);
}
// Center and define a new center of coordinates ...
coordOriginX = -(newVisibleAreaSize.width / 2) * zoom;
coordOriginY = -(newVisibleAreaSize.height / 2) * zoom;
} else {
// Zoom keeping the center in the same place ...
// const xPaddinng = (this._viewPort.width - origWidth) / 2;
// const yPaddinng = (this._viewPort.height - origHeight) / 2;
// const coordOrigin = workspace.getCoordOrigin();
// coordOriginX = coordOrigin.x - xPaddinng;
// coordOriginY = coordOrigin.y - yPaddinng;
const coordOrigin = workspace.getCoordOrigin();
coordOriginX = coordOrigin.x;
coordOriginY = coordOrigin.y;
const oldCoordOrigin = workspace.getCoordOrigin();
// Next coordSize is always centered in the middle of the visible area ...
const newCoordOriginX = -(newVisibleAreaSize.width / 2) * zoom;
const newCoordOriginY = -(newVisibleAreaSize.height / 2) * zoom;
// Calculate the offset with the original center to ...
const oldCenterOriginX = -(this._visibleAreaSize.width / 2) * zoom;
const oldCenterOriginY = -(this._visibleAreaSize.height / 2) * zoom;
const offsetX = oldCoordOrigin.x - oldCenterOriginX;
const offsetY = oldCoordOrigin.y - oldCenterOriginY;
// Update to new coordinate ...
coordOriginX = Math.round(newCoordOriginX + offsetX);
coordOriginY = Math.round(newCoordOriginY + offsetY);
}
workspace.setCoordOrigin(coordOriginX, coordOriginY);
workspace.setCoordSize(newCoordWidth, newCoordHeight);
this._visibleAreaSize = newVisibleAreaSize;
// Update screen.
this._screenManager.setOffset(coordOriginX, coordOriginY);
@ -242,10 +244,6 @@ class Workspace {
};
screenManager.addEvent('mousedown', mouseDownListener);
}
setViewPort(size: { height: number, width: number }) {
this._viewPort = size;
}
}
export default Workspace;

View File

@ -260,7 +260,7 @@ class Menu extends IMenu {
Menu._registerTooltip('zoom-minus', $msg('ZOOM_OUT'));
this._addButton('position', false, false, () => {
designer.setZoomToFit();
designer.zoomToFit();
});
Menu._registerTooltip('position', $msg('CENTER_POSITION'));

View File

@ -4,6 +4,7 @@
<head>
<title>WiseMapping - Editor </title>
<meta name="viewport" content="initial-scale=1">
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<link rel="icon" href="favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">