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

View File

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

View File

@ -19,10 +19,10 @@ import { $assert } from '@wisemapping/core-js';
import { Point } from '@wisemapping/web2d'; import { Point } from '@wisemapping/web2d';
class ScreenManager { class ScreenManager {
_divContainer: JQuery; private _divContainer: JQuery;
_padding: { x: number; y: number; }; private _padding: { x: number; y: number; };
_clickEvents: ((event: UIEvent)=>void)[]; private _clickEvents: ((event: UIEvent)=>void)[];
_scale: number; private _scale: number;
constructor(divElement: JQuery) { constructor(divElement: JQuery) {
$assert(divElement, 'can not be null'); $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) { setScale(scale: number) {
$assert(scale, 'Screen scale can not be null'); $assert(scale, 'Screen scale can not be null');
this._scale = scale; 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 { $assert, $defined } from '@wisemapping/core-js';
import { Workspace as Workspace2D } from '@wisemapping/web2d'; import { Workspace as Workspace2D } from '@wisemapping/web2d';
import ScreenManager from './ScreenManager'; import ScreenManager from './ScreenManager';
import { Size } from './Size';
class Workspace { class Workspace {
_zoom: number; _zoom: number;
_screenManager: ScreenManager; _screenManager: ScreenManager;
_isReadOnly: boolean; _isReadOnly: boolean;
_screenWidth: number; _containerSize: Size;
_screenHeight: number;
_workspace: Workspace2D; _workspace: Workspace2D;
_eventsEnabled: boolean; _eventsEnabled: boolean;
_viewPort: { height: number, width: number }; private _visibleAreaSize: any;
constructor(screenManager: ScreenManager, zoom: number, isReadOnly: boolean) { constructor(screenManager: ScreenManager, zoom: number, isReadOnly: boolean) {
// Create a suitable container ... // Create a suitable container ...
@ -39,36 +39,48 @@ class Workspace {
this._isReadOnly = isReadOnly; this._isReadOnly = isReadOnly;
const divContainer = screenManager.getContainer(); const divContainer = screenManager.getContainer();
this._screenWidth = Number.parseInt(divContainer.css('width'), 10); this._containerSize = {
this._screenHeight = Number.parseInt(divContainer.css('height'), 10); width: Number.parseInt(divContainer.css('width'), 10),
height: Number.parseInt(divContainer.css('height'), 10)
}
// Initialize web2d workspace. // Initialize web2d workspace.
const workspace = this._createWorkspace(); const workspace = this._createWorkspace();
this._workspace = workspace; this._workspace = workspace;
// Append to the workspace... // Append to the workspace...
workspace.addItAsChildTo(divContainer); workspace.addItAsChildTo(divContainer);
this.setZoom(zoom, true);
// Register drag events ... // Register drag events ...
this._registerDragEvents(); this._registerDragEvents();
this._eventsEnabled = true; 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; return this._isReadOnly;
} }
private _createWorkspace() { private _createWorkspace() {
// Initialize workspace ... // Initialize workspace ...
const coordOriginX = -(this._screenWidth / 2); const browserVisibleSize = this._screenManager.getVisibleBrowserSize();
const coordOriginY = -(this._screenHeight / 2); const coordOriginX = -(browserVisibleSize.width / 2);
const coordOriginY = -(browserVisibleSize.height / 2);
const workspaceProfile = { const workspaceProfile = {
width: `${this._screenWidth}px`, width: `${this._containerSize.width}px`,
height: `${this._screenHeight}px`, height: `${this._containerSize.height}px`,
coordSizeWidth: this._screenWidth, coordSizeWidth: browserVisibleSize.width,
coordSizeHeight: this._screenHeight, coordSizeHeight: browserVisibleSize.height,
coordOriginX, coordOriginX,
coordOriginY, coordOriginY,
fillColor: 'transparent', fillColor: 'transparent',
@ -95,11 +107,11 @@ class Workspace {
} }
} }
addEvent(type, listener) { addEvent(type: string, listener) {
this._workspace.addEvent(type, listener); this._workspace.addEvent(type, listener);
} }
removeEvent(type, listener) { removeEvent(type: string, listener) {
$assert(type, 'type can not be null'); $assert(type, 'type can not be null');
$assert(listener, 'listener can not be null'); $assert(listener, 'listener can not be null');
this._workspace.removeEvent(type, listener); this._workspace.removeEvent(type, listener);
@ -112,52 +124,42 @@ class Workspace {
setZoom(zoom: number, center: boolean = false): void { setZoom(zoom: number, center: boolean = false): void {
this._zoom = zoom; this._zoom = zoom;
const workspace = this._workspace; const workspace = this._workspace;
const newVisibleAreaSize = this._screenManager.getVisibleBrowserSize();
// Calculate the original boxview size ...
let origWidth = 0;
let origHeight = 0
if (this._viewPort) {
origWidth = this._viewPort.width;
origHeight = this._viewPort.height;
}
// Update coord scale... // Update coord scale...
const coordWidth = zoom * this._screenWidth; const newCoordWidth = zoom * this._containerSize.width;
const coordHeight = zoom * this._screenHeight; const newCoordHeight = zoom * this._containerSize.height;
workspace.setCoordSize(coordWidth, coordHeight);
// View port coords ...
if (this._viewPort) {
this._viewPort.width *= zoom;
this._viewPort.height *= zoom;
}
// Center topic....
let coordOriginX: number; let coordOriginX: number;
let coordOriginY: number; let coordOriginY: number;
if (center) { if (center) {
if (this._viewPort) { // Center and define a new center of coordinates ...
coordOriginX = -(this._viewPort.width / 2); coordOriginX = -(newVisibleAreaSize.width / 2) * zoom;
coordOriginY = -(this._viewPort.height / 2); coordOriginY = -(newVisibleAreaSize.height / 2) * zoom;
} else {
coordOriginX = -(coordWidth / 2);
coordOriginY = -(coordHeight / 2);
}
} else { } 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(); const oldCoordOrigin = workspace.getCoordOrigin();
// coordOriginX = coordOrigin.x - xPaddinng;
// coordOriginY = coordOrigin.y - yPaddinng;
const coordOrigin = workspace.getCoordOrigin();
coordOriginX = coordOrigin.x;
coordOriginY = coordOrigin.y;
// 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.setCoordOrigin(coordOriginX, coordOriginY);
workspace.setCoordSize(newCoordWidth, newCoordHeight);
this._visibleAreaSize = newVisibleAreaSize;
// Update screen. // Update screen.
this._screenManager.setOffset(coordOriginX, coordOriginY); this._screenManager.setOffset(coordOriginX, coordOriginY);
@ -242,10 +244,6 @@ class Workspace {
}; };
screenManager.addEvent('mousedown', mouseDownListener); screenManager.addEvent('mousedown', mouseDownListener);
} }
setViewPort(size: { height: number, width: number }) {
this._viewPort = size;
}
} }
export default Workspace; export default Workspace;

View File

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

View File

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