diff --git a/packages/editor/cypress/e2e/topicShape.cy.ts b/packages/editor/cypress/e2e/topicShape.cy.ts index 0ee796a5..995fe211 100644 --- a/packages/editor/cypress/e2e/topicShape.cy.ts +++ b/packages/editor/cypress/e2e/topicShape.cy.ts @@ -48,7 +48,7 @@ describe('Topic Shape Suite', () => { .invoke('attr', 'rx') .then(parseInt) .should('be.a', 'number') - .should('be.eq', 9); + .should('be.gte', 8); cy.focusTopicByText('Mind Mapping'); cy.matchImageSnapshot('changeToRoundedRectangle'); diff --git a/packages/editor/cypress/snapshots/relationship.cy.ts/delete relationship.snap.png b/packages/editor/cypress/snapshots/relationship.cy.ts/delete relationship.snap.png index 1de7c594..bdbf37f9 100644 Binary files a/packages/editor/cypress/snapshots/relationship.cy.ts/delete relationship.snap.png and b/packages/editor/cypress/snapshots/relationship.cy.ts/delete relationship.snap.png differ diff --git a/packages/editor/cypress/snapshots/relationship.cy.ts/move ctl pont 0.snap.png b/packages/editor/cypress/snapshots/relationship.cy.ts/move ctl pont 0.snap.png index 898ec27a..8e5e85bd 100644 Binary files a/packages/editor/cypress/snapshots/relationship.cy.ts/move ctl pont 0.snap.png and b/packages/editor/cypress/snapshots/relationship.cy.ts/move ctl pont 0.snap.png differ diff --git a/packages/editor/cypress/snapshots/relationship.cy.ts/move ctl pont 1.snap.png b/packages/editor/cypress/snapshots/relationship.cy.ts/move ctl pont 1.snap.png index 527adabd..0a0fb5ed 100644 Binary files a/packages/editor/cypress/snapshots/relationship.cy.ts/move ctl pont 1.snap.png and b/packages/editor/cypress/snapshots/relationship.cy.ts/move ctl pont 1.snap.png differ diff --git a/packages/editor/cypress/snapshots/relationship.cy.ts/rel ctl undo.snap.png b/packages/editor/cypress/snapshots/relationship.cy.ts/rel ctl undo.snap.png index c32e7f1c..a6b43a4b 100644 Binary files a/packages/editor/cypress/snapshots/relationship.cy.ts/rel ctl undo.snap.png and b/packages/editor/cypress/snapshots/relationship.cy.ts/rel ctl undo.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/movedownNode.snap.png b/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/movedownNode.snap.png index c5612976..e7e492ad 100644 Binary files a/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/movedownNode.snap.png and b/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/movedownNode.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontColor.snap.png b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontColor.snap.png index 654944ea..0549b409 100644 Binary files a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontColor.snap.png and b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontColor.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToEllipseShape.snap.png b/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToEllipseShape.snap.png index adfdb113..830d241b 100644 Binary files a/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToEllipseShape.snap.png and b/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToEllipseShape.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToRoundedRectangle.snap.png b/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToRoundedRectangle.snap.png index 9b31de66..5beaee71 100644 Binary files a/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToRoundedRectangle.snap.png and b/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToRoundedRectangle.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToSquareShape.snap.png b/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToSquareShape.snap.png index c299fdf5..3c28a3b2 100644 Binary files a/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToSquareShape.snap.png and b/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToSquareShape.snap.png differ diff --git a/packages/editor/src/components/action-widget/pane/theme-editor/index.tsx b/packages/editor/src/components/action-widget/pane/theme-editor/index.tsx index 2c4bc8ba..439c6f5b 100644 --- a/packages/editor/src/components/action-widget/pane/theme-editor/index.tsx +++ b/packages/editor/src/components/action-widget/pane/theme-editor/index.tsx @@ -39,6 +39,7 @@ const ThemeEditor = (props: { } label="Classic" /> } label="Summer" /> + } label="Dark" /> ); diff --git a/packages/editor/src/components/editor-toolbar/configBuilder.tsx b/packages/editor/src/components/editor-toolbar/configBuilder.tsx index 8253be30..a9c2b256 100644 --- a/packages/editor/src/components/editor-toolbar/configBuilder.tsx +++ b/packages/editor/src/components/editor-toolbar/configBuilder.tsx @@ -407,7 +407,6 @@ export function buildEditorPanelConfig(model: Editor, intl: IntlShape): ActionCo ), }, ], - disabled: () => model.getDesignerModel().filterSelectedTopics().length === 0, }; /** diff --git a/packages/mindplot/src/components/Canvas.ts b/packages/mindplot/src/components/Canvas.ts index 9f7e9cf8..7f0c78e9 100644 --- a/packages/mindplot/src/components/Canvas.ts +++ b/packages/mindplot/src/components/Canvas.ts @@ -262,6 +262,11 @@ class Canvas { return this._workspace.getSVGElement(); } + setBackgroundStyle(css: string): void { + const elem = this.getSVGElement().parentElement!.parentElement!; + elem.setAttribute('style', css); + } + private _registerDragEvents() { const workspace = this._workspace; const screenManager = this._screenManager; diff --git a/packages/mindplot/src/components/Designer.ts b/packages/mindplot/src/components/Designer.ts index 6b54a086..b45130f3 100644 --- a/packages/mindplot/src/components/Designer.ts +++ b/packages/mindplot/src/components/Designer.ts @@ -61,6 +61,7 @@ import XMLSerializerFactory from './persistence/XMLSerializerFactory'; import ImageExpoterFactory from './export/ImageExporterFactory'; import PositionType from './PositionType'; import ThemeType from './model/ThemeType'; +import ThemeFactory from './theme/ThemeFactory'; class Designer extends Events { private _mindmap: Mindmap | null; @@ -606,6 +607,13 @@ class Designer extends Events { loadMap(mindmap: Mindmap): Promise { this._mindmap = mindmap; + // Update background style... + const themeId = mindmap.getTheme(); + const theme = ThemeFactory.createById(themeId); + const style = theme.getCanvasCssStyle(); + this._canvas.setBackgroundStyle(style); + + // Delay render ... this._canvas.enableQueueRender(true); // Init layout manager ... @@ -682,9 +690,16 @@ class Designer extends Events { return result; } - changeTheme(theme: ThemeType): void { - console.log(`theme:${theme}`); - this.getMindmap().setTheme(theme); + changeTheme(id: ThemeType): void { + const mindmap = this.getMindmap(); + mindmap.setTheme(id); + + // Update background color ... + const theme = ThemeFactory.createById(id); + + const style = theme.getCanvasCssStyle(); + this._canvas.setBackgroundStyle(style); + const centralTopic = this.getModel().getCentralTopic(); centralTopic.redraw(true); } diff --git a/packages/mindplot/src/components/theme/DarkPrismTheme.ts b/packages/mindplot/src/components/theme/DarkPrismTheme.ts new file mode 100644 index 00000000..0c7838b8 --- /dev/null +++ b/packages/mindplot/src/components/theme/DarkPrismTheme.ts @@ -0,0 +1,197 @@ +/* + * Copyright [2011] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { LineType } from '../ConnectionLine'; +import { FontStyleType } from '../FontStyleType'; +import { FontWeightType } from '../FontWeightType'; +import { TopicShapeType } from '../model/INodeModel'; +import Topic from '../Topic'; +import DefaultTheme, { TopicStyleType } from './DefaultTheme'; +import { TopicType } from './Theme'; + +const defaultStyles = new Map([ + [ + 'CentralTopic', + { + msgKey: 'CENTRAL_TOPIC', + borderColor: '#FFFFFF', + backgroundColor: '#FFFFFF', + fontFamily: 'Verdana', + fontSize: 10, + fontStyle: 'normal' as FontStyleType, + fontWeight: 'bold' as FontWeightType, + fontColor: '#000000', + connectionStyle: LineType.ARC, + connectionColor: '#345780', + shapeType: 'rounded rectangle' as TopicShapeType, + outerBackgroundColor: '#F4B82D', + outerBorderColor: '#F4B82D', + }, + ], + [ + 'MainTopic', + { + msgKey: 'MAIN_TOPIC', + borderColor: [ + '#9B7BEB', + '#E5628C', + '#EB5130', + '#F3AE3D', + '#F8D651', + '#A5D945', + '#6BC953', + '#6AD6D7', + '#4CA6F7', + '#4B6FF6', + ], + backgroundColor: [ + '#9B7BEB', + '#E5628C', + '#EB5130', + '#F3AE3D', + '#F8D651', + '#A5D945', + '#6BC953', + '#6AD6D7', + '#4CA6F7', + '#4B6FF6', + ], + connectionColor: [ + '#9B7BEB', + '#E5628C', + '#EB5130', + '#F3AE3D', + '#F8D651', + '#A5D945', + '#6BC953', + '#6AD6D7', + '#4CA6F7', + '#4B6FF6', + ], + fontFamily: 'Verdana', + fontSize: 9, + fontStyle: 'normal' as FontStyleType, + fontWeight: 'normal' as FontWeightType, + fontColor: '#FFFFFF', + connectionStyle: LineType.ARC, + shapeType: 'rounded rectangle' as TopicShapeType, + outerBackgroundColor: '#F4B82D', + outerBorderColor: '#F4B82D', + }, + ], + [ + 'SubTopic', + { + msgKey: 'SUB_TOPIC', + borderColor: '#96e3ff', + backgroundColor: '#96e3ff', + fontFamily: 'Verdana', + fontSize: 8, + fontStyle: 'normal' as FontStyleType, + fontWeight: 'normal' as FontWeightType, + fontColor: '#FFFFFF', + connectionStyle: LineType.ARC, + connectionColor: '#345780', + shapeType: 'none' as TopicShapeType, + outerBackgroundColor: '#F4B82D', + outerBorderColor: '#F4B82D', + }, + ], + [ + 'IsolatedTopic', + { + msgKey: 'ISOLATED_TOPIC', + borderColor: '#023BB9', + backgroundColor: '#96e3ff', + fontFamily: 'Verdana', + fontSize: 8, + fontStyle: 'normal' as FontStyleType, + fontWeight: 'normal' as FontWeightType, + fontColor: '#000000', + connectionStyle: LineType.ARC, + connectionColor: '#345780', + shapeType: 'line' as TopicShapeType, + outerBackgroundColor: '#F4B82D', + outerBorderColor: '#F4B82D', + }, + ], +]); + +class DarkPrismTheme extends DefaultTheme { + constructor() { + super(defaultStyles); + } + + getCanvasCssStyle(): string { + return `position: relative; + left: 0; + width: 100%; + height: 100%; + border: 0; + overflow: hidden; + opacity: 1; + background-color: #353B3F; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none;`; + } + + getConnectionColor(topic: Topic): string { + let result: string | null = null; + + // Color of the node is the connection is the color of the parent ... + const parent = topic.getParent(); + if (parent && !parent.isCentralTopic()) { + result = this.resolve('connectionColor', parent, false) as string; + } + + if (!result) { + let colors: string[] = []; + colors = colors.concat(this.resolve('connectionColor', topic) as string[] | string); + + // if the element is an array, use topic order to decide color .. + let order = topic.getOrder(); + order = order || 0; + + const index = order % colors.length; + result = colors[index]; + } + return result!; + } + + getBorderColor(topic: Topic): string { + const model = topic.getModel(); + let result = model.getBorderColor(); + + // If border color has not been defined, use the connection color for the border ... + if (!result) { + let colors: string[] = []; + colors = colors.concat(this.resolve('borderColor', topic) as string[] | string); + + // if the element is an array, use topic order to decide color .. + let order = topic.getOrder(); + order = order || 0; + + const index = order % colors.length; + result = colors[index]; + } + return result; + } +} + +export default DarkPrismTheme; diff --git a/packages/mindplot/src/components/theme/DefaultTheme.ts b/packages/mindplot/src/components/theme/DefaultTheme.ts index 0f47e911..b0f0e8da 100644 --- a/packages/mindplot/src/components/theme/DefaultTheme.ts +++ b/packages/mindplot/src/components/theme/DefaultTheme.ts @@ -171,7 +171,7 @@ abstract class DefaultTheme implements Theme { result = topic.getConnectionColor(); } - if (result === undefined) { + if (!result) { const parent = topic.getParent(); if (parent) { result = parent.getBorderColor(); diff --git a/packages/mindplot/src/components/theme/PrismTheme.ts b/packages/mindplot/src/components/theme/PrismTheme.ts index 10583d28..75001d30 100644 --- a/packages/mindplot/src/components/theme/PrismTheme.ts +++ b/packages/mindplot/src/components/theme/PrismTheme.ts @@ -104,7 +104,7 @@ const defaultStyles = new Map([ fontStyle: 'normal' as FontStyleType, fontWeight: 'normal' as FontWeightType, fontColor: '#000000', - connectionStyle: LineType.THICK_CURVED, + connectionStyle: LineType.ARC, connectionColor: '#345780', shapeType: 'none' as TopicShapeType, outerBackgroundColor: '#F4B82D', @@ -122,7 +122,7 @@ const defaultStyles = new Map([ fontStyle: 'normal' as FontStyleType, fontWeight: 'normal' as FontWeightType, fontColor: '#000000', - connectionStyle: LineType.THICK_CURVED, + connectionStyle: LineType.ARC, connectionColor: '#345780', shapeType: 'line' as TopicShapeType, outerBackgroundColor: '#F4B82D', @@ -155,8 +155,13 @@ class PrismTheme extends DefaultTheme { } getConnectionColor(topic: Topic): string { - const model = topic.getModel(); - let result: string | undefined = model.getConnectionColor(); + let result: string | null = null; + + // Color of the node is the connection is the color of the parent ... + const parent = topic.getParent(); + if (parent && !parent.isCentralTopic()) { + result = this.resolve('connectionColor', parent, false) as string; + } if (!result) { let colors: string[] = []; @@ -176,8 +181,6 @@ class PrismTheme extends DefaultTheme { const model = topic.getModel(); let result = model.getBorderColor(); - // If the the style is a line, the color is alward the connection one. - // If border color has not been defined, use the connection color for the border ... if (!result) { let colors: string[] = []; diff --git a/packages/mindplot/src/components/theme/ThemeFactory.ts b/packages/mindplot/src/components/theme/ThemeFactory.ts index cbea3888..4dee6af6 100644 --- a/packages/mindplot/src/components/theme/ThemeFactory.ts +++ b/packages/mindplot/src/components/theme/ThemeFactory.ts @@ -1,13 +1,16 @@ import NodeModel from '../model/NodeModel'; import ClassicTheme from './ClassicTheme'; +import DarkPrismTheme from './DarkPrismTheme'; import PrismTheme from './PrismTheme'; import Theme from './Theme'; -type ThemeId = 'prism' | 'classic'; +type ThemeId = 'prism' | 'classic' | 'dark-prism'; class ThemeFactory { private static prismTheme = new PrismTheme(); + private static darkPrismTheme = new DarkPrismTheme(); + private static classicTheme = new ClassicTheme(); static createById(id: ThemeId): Theme { @@ -16,6 +19,9 @@ class ThemeFactory { case 'classic': result = ThemeFactory.classicTheme; break; + case 'dark-prism': + result = ThemeFactory.darkPrismTheme; + break; case 'prism': result = ThemeFactory.prismTheme; break;