From 3cf820cf70d9dd8e1ab8a4c65dbf00bb7339cdc2 Mon Sep 17 00:00:00 2001 From: Kirill Shumilov Date: Wed, 13 Feb 2019 13:32:38 +0300 Subject: [PATCH] feat(xod-client): new patch board look with bound values --- .../test-func/creatingBlinkPatch.spec.js | 2 +- .../src/core/styles/abstracts/colors.scss | 2 +- .../src/core/styles/abstracts/variables.scss | 6 +- .../src/core/styles/components/Comment.scss | 2 +- .../src/core/styles/components/Inspector.scss | 2 +- .../src/core/styles/components/Node.scss | 35 +++++++---- .../src/core/styles/components/PatchDocs.scss | 2 +- .../src/core/styles/components/Pin.scss | 20 ++++--- .../src/core/styles/components/PinLabel.scss | 16 ++--- .../src/core/styles/components/PinValue.scss | 24 ++++++++ .../components/PopupPublishProject.scss | 2 +- packages/xod-client/src/core/styles/main.scss | 1 + .../src/editor/components/PatchDocs.jsx | 25 ++++---- .../src/project/components/Node.jsx | 10 ++-- .../src/project/components/PatchSVG.jsx | 11 ++-- .../xod-client/src/project/components/Pin.jsx | 35 +---------- .../src/project/components/PinLabel.jsx | 34 ++++------- .../src/project/components/PinOverlay.jsx | 10 +++- .../src/project/components/PinValue.jsx | 60 +++++++++++++++++++ .../components/layers/BackgroundLayer.jsx | 23 +++++-- .../components/nodeParts/BusNodeBody.jsx | 2 +- .../components/nodeParts/JumperNodeBody.jsx | 16 ++--- .../components/nodeParts/TerminalNodeBody.jsx | 2 +- .../components/nodeParts/VariadicHandle.jsx | 48 ++++++++++++--- packages/xod-client/src/project/nodeLayout.js | 50 +++++++++++++--- 25 files changed, 287 insertions(+), 153 deletions(-) create mode 100644 packages/xod-client/src/core/styles/components/PinValue.scss create mode 100644 packages/xod-client/src/project/components/PinValue.jsx diff --git a/packages/xod-client-browser/test-func/creatingBlinkPatch.spec.js b/packages/xod-client-browser/test-func/creatingBlinkPatch.spec.js index 178b7fda..f1c0f55a 100644 --- a/packages/xod-client-browser/test-func/creatingBlinkPatch.spec.js +++ b/packages/xod-client-browser/test-func/creatingBlinkPatch.spec.js @@ -91,7 +91,7 @@ describe('creating blink patch', () => { await clockNode.drag(150, 10); const { x, y } = await clockNode.getBoundingClientRect(); - assert.deepEqual({ x, y }, { x: 389, y: 114 }); + assert.deepEqual({ x, y }, { x: 399.5, y: 128.5 }); }); it('adds rest of the nodes needed for blink patch', async () => { diff --git a/packages/xod-client/src/core/styles/abstracts/colors.scss b/packages/xod-client/src/core/styles/abstracts/colors.scss index b5efc8cc..015de035 100644 --- a/packages/xod-client/src/core/styles/abstracts/colors.scss +++ b/packages/xod-client/src/core/styles/abstracts/colors.scss @@ -19,7 +19,7 @@ $light-grey: #777; $light-grey-bright: #999; $chalk: #ccc; -$chalk-light: #aaa; +$chalk-light: #ddd; $chalk-bright: #eee; // Colored diff --git a/packages/xod-client/src/core/styles/abstracts/variables.scss b/packages/xod-client/src/core/styles/abstracts/variables.scss index 9fd5bc7a..c3fd78a6 100644 --- a/packages/xod-client/src/core/styles/abstracts/variables.scss +++ b/packages/xod-client/src/core/styles/abstracts/variables.scss @@ -14,7 +14,7 @@ $color-success: #579205; $color-canvas-background: $dark-deep; $color-canvas-background-gridlines: $dark-light; $color-canvas-face: #646464; -$color-canvas-face-light: #A7A7A7; +$color-canvas-face-light: $chalk-light; $color-canvas-face-text: #a7a7a7; $color-canvas-selected: #4ed5ed; $color-highlight: #eeeeee; @@ -30,7 +30,7 @@ $color-datatype-custom: $terracotta; $color-datatype-dead: $error; $color-node-fill: #222222; -$color-node-outline: #bbbbbb; +$color-node-outline: $light-grey-bright; $color-pin-fill: #262626; $color-watch-node-text: $color-canvas-face-text; @@ -44,7 +44,7 @@ $color-watch-node-highlight-outline: #bce88e; $color-comment-text: #d0ccc0; $color-comment-handle: #605f5b; -$color-pinlabel: $color-canvas-face-text; //#8b8b8b; +$color-pinlabel: $grey-bright; $color-toolbar-background: #b3b3b3; $color-toolbar-foreground: #000; diff --git a/packages/xod-client/src/core/styles/components/Comment.scss b/packages/xod-client/src/core/styles/components/Comment.scss index 28ea7fba..e6d8ee51 100644 --- a/packages/xod-client/src/core/styles/components/Comment.scss +++ b/packages/xod-client/src/core/styles/components/Comment.scss @@ -10,7 +10,7 @@ .outline { fill: transparent; - stroke-width: 2px; + stroke-width: 1px; } .container { diff --git a/packages/xod-client/src/core/styles/components/Inspector.scss b/packages/xod-client/src/core/styles/components/Inspector.scss index e68f86bb..eb99212c 100644 --- a/packages/xod-client/src/core/styles/components/Inspector.scss +++ b/packages/xod-client/src/core/styles/components/Inspector.scss @@ -199,7 +199,7 @@ .PinIcon { pointer-events: none; float: left; - margin-top: 4px; + margin-top: 7px; } label { diff --git a/packages/xod-client/src/core/styles/components/Node.scss b/packages/xod-client/src/core/styles/components/Node.scss index 423f64dd..efa4f8e2 100644 --- a/packages/xod-client/src/core/styles/components/Node.scss +++ b/packages/xod-client/src/core/styles/components/Node.scss @@ -15,7 +15,7 @@ .outline { fill: transparent; stroke: $color-node-outline; - stroke-width: 2px; + stroke-width: 1px; // For terminals: &.string { stroke: $color-datatype-string; } @@ -76,6 +76,12 @@ } } + .terminal-node, .bus-node { + .outline { + stroke-width: 2px; + } + } + .jumper-line { stroke: $color-node-outline; stroke-width: 2px; @@ -117,7 +123,7 @@ // move from under pins // leave 1px margin on the sides to avoid "gluing" of two nearest labels - margin: 12px 1px; + margin: 11px 1px; height: calc(100% - 24px); } @@ -125,9 +131,10 @@ display: block; text-align: center; padding: 0; - font-size: 12px; - font-family: $font-family-condensed; - color: $color-canvas-face-text; + font-size: 13px; + font-family: $font-family-normal; + font-weight: 400; + color: $color-canvas-face-light; white-space: pre; overflow: hidden; text-overflow: ellipsis; @@ -144,11 +151,11 @@ } .nodeLabel { - color: $color-highlight; + color: $color-canvas-face-light; } .VariadicHandle--grip { - stroke: $color-highlight; + fill: $color-highlight; } .NodeResizeHandle { @@ -173,7 +180,7 @@ } .VariadicHandle--grip { - stroke: $color-canvas-selected !important; + fill: $color-canvas-selected !important; } .NodeResizeHandle { @@ -185,9 +192,12 @@ pointer-events: none; opacity: 0.3; - .outline, .VariadicHandle--grip { + .outline { stroke: $color-node-outline !important; } + .VariadicHandle--grip { + fill: $color-node-outline !important; + } .nodeLabel { visibility: hidden; } @@ -201,7 +211,7 @@ color: $color-highlight; } .VariadicHandle--grip { - stroke: $color-highlight; + fill: $color-highlight; } } @@ -223,8 +233,7 @@ } &--grip { pointer-events: none; - stroke-width: 5px; - stroke-linecap: round; - stroke: $color-node-outline; + fill: $color-node-outline; + stroke-width: 0; } } diff --git a/packages/xod-client/src/core/styles/components/PatchDocs.scss b/packages/xod-client/src/core/styles/components/PatchDocs.scss index ee84868b..ad334934 100644 --- a/packages/xod-client/src/core/styles/components/PatchDocs.scss +++ b/packages/xod-client/src/core/styles/components/PatchDocs.scss @@ -87,7 +87,7 @@ $PinInfo-padding-bottom: 10px; min-height: $node-height; &--no-inputs { - min-height: 75px; + min-height: 77px; overflow: hidden; box-sizing: border-box; } diff --git a/packages/xod-client/src/core/styles/components/Pin.scss b/packages/xod-client/src/core/styles/components/Pin.scss index 609b6342..92e4662d 100644 --- a/packages/xod-client/src/core/styles/components/Pin.scss +++ b/packages/xod-client/src/core/styles/components/Pin.scss @@ -22,7 +22,7 @@ .symbol { fill: $color-pin-fill; stroke: $color-datatype-custom; - stroke-width: 2px; + stroke-width: 1.5px; &.t1, &.t2, &.t3 { @include symbol-coloring($color-datatype-generic); @@ -71,9 +71,12 @@ } .generic-pin-marker { - fill: none; - stroke: $color-datatype-generic; - stroke-width: 2px; + fill: $color-datatype-generic; + stroke-width: 0; + } + + .hotspotHelper { + fill: transparent; } .linkingHighlight { @@ -100,7 +103,7 @@ } .PinOverlay { - .symbol { + .linkingHighlight { fill: white; stroke: white; stroke-width: 2px; @@ -108,14 +111,13 @@ } &:hover { - .symbol { + .linkingHighlight { opacity: 0.5; } } - .linkingHighlight { - display: none; - opacity: 0; // just acts as a hotspot + .hotspot { + fill: transparent; } &.is-accepting-links, &.is-selected { diff --git a/packages/xod-client/src/core/styles/components/PinLabel.scss b/packages/xod-client/src/core/styles/components/PinLabel.scss index e2d223a4..1f76f850 100644 --- a/packages/xod-client/src/core/styles/components/PinLabel.scss +++ b/packages/xod-client/src/core/styles/components/PinLabel.scss @@ -1,14 +1,14 @@ .PinLabel { font-family: $font-family-condensed; font-weight: 500; - font-size: 10px; - dominant-baseline: central; - fill: $color-pinlabel; + font-size: 11px; + color: $color-pinlabel; user-select: none; - &.outline { - stroke: #262626; - stroke-linejoin: round; - stroke-width: 5; - } + text-align: center; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + + line-height: 1; } diff --git a/packages/xod-client/src/core/styles/components/PinValue.scss b/packages/xod-client/src/core/styles/components/PinValue.scss new file mode 100644 index 00000000..f927b89c --- /dev/null +++ b/packages/xod-client/src/core/styles/components/PinValue.scss @@ -0,0 +1,24 @@ +.PinValue { + font-family: $font-family-condensed; + font-weight: 400; + font-size: 11px; + color: $color-datatype-generic; + user-select: none; + + text-align: center; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + + line-height: 1; + + // For terminals: + &.string { color: $color-datatype-string; } + &.number { color: $color-datatype-number; } + &.boolean { color: $color-datatype-boolean; } + &.pulse { color: $color-datatype-pulse; } + &.byte { color: $color-datatype-byte; } + &.port { color: $color-datatype-port; } + &.dead, &.conflicting { color: $color-datatype-dead; } + &.self, &.custom { color: $color-datatype-custom; } +} diff --git a/packages/xod-client/src/core/styles/components/PopupPublishProject.scss b/packages/xod-client/src/core/styles/components/PopupPublishProject.scss index 2a40d141..a9391039 100644 --- a/packages/xod-client/src/core/styles/components/PopupPublishProject.scss +++ b/packages/xod-client/src/core/styles/components/PopupPublishProject.scss @@ -7,7 +7,7 @@ margin: 7px 0; .propertyLabel { - color: $color-canvas-face-light; + color: $color-canvas-face-text; } } diff --git a/packages/xod-client/src/core/styles/main.scss b/packages/xod-client/src/core/styles/main.scss index 178d4f8f..e1ce0b20 100644 --- a/packages/xod-client/src/core/styles/main.scss +++ b/packages/xod-client/src/core/styles/main.scss @@ -45,6 +45,7 @@ 'components/PatchWrapper', 'components/Pin', 'components/PinLabel', + 'components/PinValue', 'components/PopupPublishProject', 'components/ProjectBrowser', 'components/Sidebar', diff --git a/packages/xod-client/src/editor/components/PatchDocs.jsx b/packages/xod-client/src/editor/components/PatchDocs.jsx index c8a99fe3..595ba0df 100644 --- a/packages/xod-client/src/editor/components/PatchDocs.jsx +++ b/packages/xod-client/src/editor/components/PatchDocs.jsx @@ -12,11 +12,11 @@ import { SLOT_SIZE } from '../../project/nodeLayout'; const NODE_POSITION_IN_PREVIEW = { x: 3, - y: 20, // compensate for labels outside the node + y: 10, // compensate for bound values outside the node }; const MAX_NODE_WIDTH = 245 - NODE_POSITION_IN_PREVIEW.x * 2; -const NODE_PREVIEW_HEIGHT = 93; +const NODE_PREVIEW_HEIGHT = 85; const formatPinType = R.when(XP.isGenericType, type => `generic ${type}`); const getPinTypeClassName = R.when(XP.isGenericType, R.always('generic')); @@ -152,13 +152,6 @@ const PatchDocs = ({ patch, minimal }) => { const distanceBetweenPins = minimal ? 0 : scaleFactor * SLOT_SIZE.WIDTH - 1; - // because we never draw labels for terminal nodes - const position = R.when( - () => XP.isTerminalPatchPath(nodeType), - R.assoc('y', XP.isInputTerminalPath(nodeType) ? 32 : 8), - NODE_POSITION_IN_PREVIEW - ); - const deprecatedReason = XP.getDeprecationReason(patch); const cls = cn('PatchDocs', { @@ -200,10 +193,16 @@ const PatchDocs = ({ patch, minimal }) => { width={scaledNodeWidth} height={scaledNodePreviewHeight} > - - - - + + + + + + )} diff --git a/packages/xod-client/src/project/components/Node.jsx b/packages/xod-client/src/project/components/Node.jsx index 7e6ed3fb..cb7e82ac 100644 --- a/packages/xod-client/src/project/components/Node.jsx +++ b/packages/xod-client/src/project/components/Node.jsx @@ -6,6 +6,7 @@ import * as XP from 'xod-project'; import Pin from './Pin'; import PinLabel from './PinLabel'; +import PinValue from './PinValue'; import { noop } from '../../utils/ramda'; import { isPinSelected } from '../../editor/utils'; @@ -207,12 +208,11 @@ class Node extends React.Component { {pinsArr.map(pin => ( + {pin.isConnected || XP.isOutputPin(pin) ? null : ( + + )} {isTerminalNode ? null : ( - + )} - - - - {children} + {/* Nested svg to compensate bluring of strokes */} + + + + + {children} + ); diff --git a/packages/xod-client/src/project/components/Pin.jsx b/packages/xod-client/src/project/components/Pin.jsx index f3ea7f89..d34d5389 100644 --- a/packages/xod-client/src/project/components/Pin.jsx +++ b/packages/xod-client/src/project/components/Pin.jsx @@ -12,35 +12,6 @@ import { PIN_HIGHLIGHT_RADIUS, } from '../nodeLayout'; -/** - * An outline of half of the circle, that indicated that Pin is generic - * even it has a deduced type. - */ -// :: Number -> Number -> Boolean -> ReactElement -const genericPinMarker = (pinCircleCenter, output) => { - // To avoid using complex paths we draw just a circle - // but draw only half of the outline by CSS. - - // To do it with CSS we have to: - // 1. Calculate the length of the circle (circumference). - const circumference = Math.PI * PIN_RADIUS * 2; - // 2. Calculate distance beetween dashes - const dasharray = 0.5 * circumference; - // 3. And then set `dasharray` to draw a half of outline - // 4. And set `dashoffset` to draw another half (for output Pin) - return ( - - ); -}; - const Pin = props => { const isOutput = props.direction === PIN_DIRECTION.OUTPUT; @@ -104,9 +75,9 @@ const Pin = props => { r={PIN_INNER_RADIUS} /> ) : null} - {isGenericType(props.type) - ? genericPinMarker(pinCircleCenter, isOutput) - : null} + {isGenericType(props.type) ? ( + + ) : null} {variadicDots} ); diff --git a/packages/xod-client/src/project/components/PinLabel.jsx b/packages/xod-client/src/project/components/PinLabel.jsx index 94fd17cc..401f4353 100644 --- a/packages/xod-client/src/project/components/PinLabel.jsx +++ b/packages/xod-client/src/project/components/PinLabel.jsx @@ -1,36 +1,28 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { PIN_DIRECTION } from 'xod-project'; -import { PIN_RADIUS, TEXT_OFFSET_FROM_PIN_BORDER } from '../nodeLayout'; +import { PINLABEL_WIDTH, getPinLabelProps } from '../nodeLayout'; -const Pin = ({ keyName, label, direction, position }) => { - const textVerticalOffset = PIN_RADIUS + TEXT_OFFSET_FROM_PIN_BORDER; - const isInput = direction === PIN_DIRECTION.INPUT; - - const textProps = { - x: position.x, - y: position.y + textVerticalOffset * (isInput ? -1 : 1), - textAnchor: 'middle', - }; +const PinLabel = ({ label, direction, position }) => { + const textProps = getPinLabelProps(direction, position); return label ? ( - - + +
{label} - - - {label} - - +
+
) : null; }; -Pin.propTypes = { - keyName: PropTypes.string.isRequired, +PinLabel.propTypes = { label: PropTypes.string, direction: PropTypes.string.isRequired, position: PropTypes.object.isRequired, }; -export default Pin; +export default PinLabel; diff --git a/packages/xod-client/src/project/components/PinOverlay.jsx b/packages/xod-client/src/project/components/PinOverlay.jsx index 8dc22e18..e75eaeea 100644 --- a/packages/xod-client/src/project/components/PinOverlay.jsx +++ b/packages/xod-client/src/project/components/PinOverlay.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; -import { PIN_RADIUS, PIN_HIGHLIGHT_RADIUS } from '../nodeLayout'; +import { PIN_HOTSPOT_RADIUS, PIN_HOVER_HIGHLIGHT_RADIUS } from '../nodeLayout'; import deepSCU from '../../utils/deepSCU'; @@ -45,9 +45,13 @@ export default class PinOverlay extends React.Component { + -
); } diff --git a/packages/xod-client/src/project/components/PinValue.jsx b/packages/xod-client/src/project/components/PinValue.jsx new file mode 100644 index 00000000..59348ddf --- /dev/null +++ b/packages/xod-client/src/project/components/PinValue.jsx @@ -0,0 +1,60 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import cls from 'classnames'; +import { PIN_TYPE, INPUT_PULSE_PIN_BINDING_OPTIONS } from 'xod-project'; +import { unquote } from 'xod-func-tools'; + +import { PINVALUE_WIDTH, getPinValueProps } from '../nodeLayout'; +import { getRenderablePinType } from '../utils'; + +const formatPulsePinValue = value => { + switch (value) { + case INPUT_PULSE_PIN_BINDING_OPTIONS.CONTINUOUSLY: + return 'Loop'; + case INPUT_PULSE_PIN_BINDING_OPTIONS.ON_BOOT: + return 'Boot'; + default: + case INPUT_PULSE_PIN_BINDING_OPTIONS.NEVER: + return ''; + } +}; + +const formatPinValue = (type, value) => { + switch (type) { + case PIN_TYPE.STRING: + return unquote(value); + case PIN_TYPE.PULSE: + return formatPulsePinValue(value); + default: + return value; + } +}; + +const PinValue = ({ value, type, deducedType, direction, position }) => { + const textProps = getPinValueProps(direction, position); + + const pinType = getRenderablePinType({ type, deducedType }); + const className = cls('PinValue', pinType); + + return value ? ( + +
+ {formatPinValue(pinType, value)} +
+
+ ) : null; +}; + +PinValue.propTypes = { + value: PropTypes.string, + type: PropTypes.string, + deducedType: PropTypes.object, + direction: PropTypes.string.isRequired, + position: PropTypes.object.isRequired, +}; + +export default PinValue; diff --git a/packages/xod-client/src/project/components/layers/BackgroundLayer.jsx b/packages/xod-client/src/project/components/layers/BackgroundLayer.jsx index 19232b95..5a7f081d 100644 --- a/packages/xod-client/src/project/components/layers/BackgroundLayer.jsx +++ b/packages/xod-client/src/project/components/layers/BackgroundLayer.jsx @@ -4,19 +4,32 @@ import { noop } from 'xod-func-tools'; import { SLOT_SIZE, NODE_HEIGHT } from '../../nodeLayout'; +// Add 0.5 to compensate blurring of pattern +const COMPENSATE_BLUR = 0.5; + const NodeSlotPattern = ({ offset }) => ( - - - + + + ); diff --git a/packages/xod-client/src/project/components/nodeParts/BusNodeBody.jsx b/packages/xod-client/src/project/components/nodeParts/BusNodeBody.jsx index 97ddc5a1..eb5366fb 100644 --- a/packages/xod-client/src/project/components/nodeParts/BusNodeBody.jsx +++ b/packages/xod-client/src/project/components/nodeParts/BusNodeBody.jsx @@ -38,7 +38,7 @@ const BusNodeBody = ({ type, size, pins, label }) => { )(pins); return ( - + - R.compose( - foldMaybe('generic', R.identity), - R.map(foldEither('error', R.identity)), - maybePath([INPUT_PINKEY, 'deducedType']) - )(pins) -); - const JumperNodeBody = ({ pins }) => { const inConnected = R.path([INPUT_PINKEY, 'isConnected'], pins); const outConnected = R.path([OUTPUT_PINKEY, 'isConnected'], pins); const type = R.cond([ - [() => inConnected, getDeducedTypeOfPin(INPUT_PINKEY)], - [() => outConnected, getDeducedTypeOfPin(OUTPUT_PINKEY)], + [() => inConnected, R.pipe(R.prop(INPUT_PINKEY), getRenderablePinType)], + [() => outConnected, R.pipe(R.prop(OUTPUT_PINKEY), getRenderablePinType)], [R.T, R.always('generic')], ])(pins); @@ -30,7 +22,7 @@ const JumperNodeBody = ({ pins }) => { inConnected || outConnected ? 'is-connected' : 'not-connected'; return ( - + { ); return ( - + String + */ +const getVariadicPoints = size => { + const xRight = size.width - COMPENSATE_BLURING; + const xLeft = size.width - VARIADIC_HANDLE_WIDTH - COMPENSATE_BLURING; + const yTop = (size.height - VARIADIC_HANDLE_HEIGHT) / 2; + const yBottom = yTop + VARIADIC_HANDLE_HEIGHT; + + const points = [ + [xRight, yTop], // 0 + [xRight, yBottom], // 1 + [xLeft, yBottom - VARIADIC_HANDLE_WIDTH], // 2 + [xLeft, yTop + VARIADIC_HANDLE_WIDTH], // 3 + ]; + + return R.compose(R.join(' '), R.unnest)(points); +}; const VariadicHandle = props => ( @@ -9,19 +42,16 @@ const VariadicHandle = props => ( className="VariadicHandle--clickArea" rx={NODE_CORNER_RADIUS} ry={NODE_CORNER_RADIUS} - x={props.size.width - 8} + x={props.size.width - VARIADIC_HANDLE_WIDTH * 2} y={-1} - width={10} - height={props.size.height + 2} + width={VARIADIC_HANDLE_WIDTH * 2 + 2} + height={props.size.height + 1} fill="rgba(255,0,0,.5)" onMouseDown={props.onMouseDown} /> - ); diff --git a/packages/xod-client/src/project/nodeLayout.js b/packages/xod-client/src/project/nodeLayout.js index 6f172c70..e63317d2 100644 --- a/packages/xod-client/src/project/nodeLayout.js +++ b/packages/xod-client/src/project/nodeLayout.js @@ -3,14 +3,20 @@ import { Maybe } from 'ramda-fantasy'; import * as XP from 'xod-project'; import { foldMaybe } from 'xod-func-tools'; -const BASE_SIZE_UNIT = 17; +const BASE_SIZE_UNIT = 5; + +export const NODE_HEIGHT = BASE_SIZE_UNIT * 13; export const SLOT_SIZE = { - WIDTH: BASE_SIZE_UNIT * 2, - HEIGHT: BASE_SIZE_UNIT * 6, + WIDTH: BASE_SIZE_UNIT * 8 + 4, + HEIGHT: NODE_HEIGHT + BASE_SIZE_UNIT * 8, }; -export const NODE_HEIGHT = BASE_SIZE_UNIT * 3; +const PINVALUE_GAP = 4; +export const PINVALUE_WIDTH = SLOT_SIZE.WIDTH - PINVALUE_GAP / 2; + +const PINLABEL_GAP = 8; +export const PINLABEL_WIDTH = SLOT_SIZE.WIDTH - PINLABEL_GAP / 2; export const DEFAULT_PANNING_OFFSET = { x: NODE_HEIGHT, @@ -21,18 +27,22 @@ export const LINK_HOTSPOT_SIZE = { WIDTH: 8, }; -export const NODE_CORNER_RADIUS = 5; +export const NODE_CORNER_RADIUS = 3; export const RESIZE_HANDLE_SIZE = 12; +export const VARIADIC_HANDLE_WIDTH = 4; +export const VARIADIC_HANDLE_HEIGHT = BASE_SIZE_UNIT * 5; -export const PIN_RADIUS = 6; +export const PIN_RADIUS = 4; export const PIN_INNER_RADIUS = PIN_RADIUS - 2; export const PIN_RADIUS_WITH_OUTER_STROKE = PIN_RADIUS + 3; export const PIN_RADIUS_WITH_SHADOW = PIN_RADIUS + 4; // TODO: rename export const PIN_HIGHLIGHT_RADIUS = 15; -export const PIN_OFFSET_FROM_NODE_EDGE = 3; +export const PIN_HOVER_HIGHLIGHT_RADIUS = PIN_RADIUS; +export const PIN_HOTSPOT_RADIUS = PIN_HIGHLIGHT_RADIUS; +export const PIN_OFFSET_FROM_NODE_EDGE = 0; -export const TEXT_OFFSET_FROM_PIN_BORDER = 10; +export const TEXT_OFFSET_FROM_PIN_BORDER = 3; // :: { input: Number, output: Number } -> Size const nodeSizeInSlots = pinCountByDirection => ({ @@ -221,3 +231,27 @@ export const getBusNodePositionForPin = (node, pin) => { SLOT_SIZE.HEIGHT * (pinDirection === XP.PIN_DIRECTION.INPUT ? -1 : 1), }; }; + +// :: Number -> Boolean -> PIN_DIRECTION -> { x: Number, y: Number } -> { x, y, width, height } +const getPinTextProps = (width, isLabel, direction, position) => { + const FONT_HEIGHT = 11; + const isAboveNodeBorder = direction === XP.PIN_DIRECTION.OUTPUT || !isLabel; + const compensateFontHeight = isAboveNodeBorder ? FONT_HEIGHT : 0; + const offsetFromNodeBorder = + (PIN_RADIUS + TEXT_OFFSET_FROM_PIN_BORDER) * (isAboveNodeBorder ? -1 : 1); + + return { + x: position.x - width / 2, + y: position.y - compensateFontHeight + offsetFromNodeBorder, + width, + height: FONT_HEIGHT, + }; +}; + +// :: PIN_DIRECTION -> { x: Number, y: Number } -> { x, y, width, height } +export const getPinValueProps = (pinDirection, position) => + getPinTextProps(PINVALUE_WIDTH, false, pinDirection, position); + +// :: PIN_DIRECTION -> { x: Number, y: Number } -> { x, y, width, height } +export const getPinLabelProps = (pinDirection, position) => + getPinTextProps(PINLABEL_WIDTH, true, pinDirection, position);