diff --git a/packages/xod-client/src/core/styles/components/Link.scss b/packages/xod-client/src/core/styles/components/Link.scss
index 354cccb4..bef4b317 100644
--- a/packages/xod-client/src/core/styles/components/Link.scss
+++ b/packages/xod-client/src/core/styles/components/Link.scss
@@ -1,33 +1,40 @@
+@mixin link-parts-coloring($type-color) {
+ .line {
+ stroke: $type-color;
+ }
+
+ .end {
+ fill: $type-color;
+ }
+}
.Link {
- stroke: grey;
- stroke-width: 2px;
+ .line {
+ stroke: grey;
+ stroke-width: 2px;
+ }
&.string {
- stroke: $color-datatype-string;
+ @include link-parts-coloring($color-datatype-string);
}
&.number {
- stroke: $color-datatype-number;
+ @include link-parts-coloring($color-datatype-number);
}
&.bool {
- stroke: $color-datatype-bool;
+ @include link-parts-coloring($color-datatype-bool);
}
&.pulse {
- stroke: $color-datatype-pulse;
+ @include link-parts-coloring($color-datatype-pulse);
}
&:hover {
- .line {
- stroke: white;
- }
+ @include link-parts-coloring(white);
}
&.is-selected {
- .line {
- stroke: #4ed5ec;
- }
+ @include link-parts-coloring($color-canvas-selected);
}
}
diff --git a/packages/xod-client/src/core/styles/components/Pin.scss b/packages/xod-client/src/core/styles/components/Pin.scss
index c1e23423..32f180d2 100644
--- a/packages/xod-client/src/core/styles/components/Pin.scss
+++ b/packages/xod-client/src/core/styles/components/Pin.scss
@@ -1,17 +1,8 @@
@mixin symbol-coloring($type-color) {
stroke: $type-color;
- $hover-color: lighten($type-color, 25%);
-
- &:hover {
- stroke: $hover-color
- }
-
&.is-connected {
fill: $type-color;
- &:hover {
- fill: $hover-color
- }
}
}
@@ -22,10 +13,6 @@
stroke-width: 2px;
filter: url(#dropshadow);
- &:hover {
- fill: color-canvas-hover($color-pin-fill);
- }
-
&.string {
@include symbol-coloring($color-datatype-string);
}
@@ -43,20 +30,24 @@
}
}
- .label {
- font-family: $font-family-condensed;
- font-weight: 500;
- font-size: 12px;
- dominant-baseline: central;
- }
+ &:hover {
+ .symbol {
+ &.string {
+ @include symbol-coloring(lighten($color-datatype-string, 25%));
+ }
- .label.input {
- fill: $color-pinlabel-input;
- }
+ &.number {
+ @include symbol-coloring(lighten($color-datatype-number, 25%));
+ }
- .label.output {
- fill: $color-pinlabel-output;
- font-weight: 700; // black font looks thinner
+ &.bool {
+ @include symbol-coloring(lighten($color-datatype-bool, 25%));
+ }
+
+ &.pulse {
+ @include symbol-coloring(lighten($color-datatype-pulse, 25%));
+ }
+ }
}
.linkingHighlight {
@@ -77,6 +68,4 @@
fill: $color-canvas-selected;
}
}
-
-
}
diff --git a/packages/xod-client/src/core/styles/components/PinLabel.scss b/packages/xod-client/src/core/styles/components/PinLabel.scss
new file mode 100644
index 00000000..f6c5d861
--- /dev/null
+++ b/packages/xod-client/src/core/styles/components/PinLabel.scss
@@ -0,0 +1,15 @@
+.PinLabel {
+ font-family: $font-family-condensed;
+ font-weight: 500;
+ font-size: 12px;
+ dominant-baseline: central;
+}
+
+.PinLabel.input {
+ fill: $color-pinlabel-input;
+}
+
+.PinLabel.output {
+ fill: $color-pinlabel-output;
+ font-weight: 700; // black font looks thinner
+}
\ No newline at end of file
diff --git a/packages/xod-client/src/core/styles/main.scss b/packages/xod-client/src/core/styles/main.scss
index 06e3586e..cf6a5eac 100644
--- a/packages/xod-client/src/core/styles/main.scss
+++ b/packages/xod-client/src/core/styles/main.scss
@@ -26,6 +26,7 @@
'components/Node',
'components/NodeText',
'components/Pin',
+ 'components/PinLabel',
'components/Link',
'components/PopupAlert',
'components/PopupPrompt',
diff --git a/packages/xod-client/src/editor/containers/Patch.jsx b/packages/xod-client/src/editor/containers/Patch.jsx
index aa287dfd..a3599ea8 100644
--- a/packages/xod-client/src/editor/containers/Patch.jsx
+++ b/packages/xod-client/src/editor/containers/Patch.jsx
@@ -18,6 +18,7 @@ import NodesLayer from '../../project/components/NodesLayer';
import LinksLayer from '../../project/components/LinksLayer';
import GhostsLayer from '../../project/components/GhostsLayer';
import SnappingPreviewLayer from '../../project/components/SnappingPreviewLayer';
+import DraggedNodeLayer from '../../project/components/DraggedNodeLayer';
import {
addNodesPositioning,
addLinksPositioning,
@@ -47,6 +48,9 @@ class Patch extends React.Component {
this.onLinkClick = this.onLinkClick.bind(this);
this.deselectAll = this.deselectAll.bind(this);
+
+ this.getDraggedNodeId = this.getDraggedNodeId.bind(this);
+ this.extendNodesByPinValidness = this.extendNodesByPinValidness.bind(this);
}
shouldComponentUpdate(nextProps, nextState) {
@@ -171,8 +175,11 @@ class Patch extends React.Component {
}
getNodes() {
- const nodes = R.values(this.props.nodes);
- return this.extendNodesByPinValidness(nodes);
+ return R.compose(
+ this.extendNodesByPinValidness,
+ R.values,
+ R.omit([this.getDraggedNodeId()]) // we are rendering dragged node in a separate layer
+ )(this.props.nodes);
}
getLinks() {
return R.values(this.props.links);
@@ -259,6 +266,7 @@ class Patch extends React.Component {
}
render() {
+ const draggedNodeId = this.getDraggedNodeId();
const nodes = this.getNodes();
const links = this.getLinks();
@@ -276,19 +284,23 @@ class Patch extends React.Component {
height={this.props.size.height}
onClick={this.deselectAll}
/>
+
-
+
+
+ );
+ }
+}
+
+DraggedNodeLayer.propTypes = {
+ draggedNodeId: React.PropTypes.any,
+ nodes: React.PropTypes.any,
+};
+
+export default DraggedNodeLayer;
diff --git a/packages/xod-client/src/project/components/Link.jsx b/packages/xod-client/src/project/components/Link.jsx
index 676fad99..8d441394 100644
--- a/packages/xod-client/src/project/components/Link.jsx
+++ b/packages/xod-client/src/project/components/Link.jsx
@@ -3,6 +3,7 @@ import classNames from 'classnames';
import { SIZE } from 'xod-core';
import { noop } from '../../utils/ramda';
+import { PIN_RADIUS } from '../nodeLayout';
class Link extends React.Component {
constructor(props) {
@@ -48,6 +49,8 @@ class Link extends React.Component {
const clickable = this.isClickable();
const pointerEvents = (clickable) ? 'all' : 'none';
+ const linkEndRadius = PIN_RADIUS - 3;
+
return (
+
+
);
}
diff --git a/packages/xod-client/src/project/components/Node.jsx b/packages/xod-client/src/project/components/Node.jsx
index 2d240011..03a54998 100644
--- a/packages/xod-client/src/project/components/Node.jsx
+++ b/packages/xod-client/src/project/components/Node.jsx
@@ -3,6 +3,7 @@ import React from 'react';
import classNames from 'classnames';
import Pin from './Pin';
+import PinLabel from './PinLabel';
import NodeText from './NodeText';
import { noop } from '../../utils/ramda';
@@ -12,13 +13,8 @@ class Node extends React.Component {
constructor(props) {
super(props);
this.id = this.props.id;
-
- // needed for distinguishing between mouseDown events on pins and on node body
- this.pinListRef = null;
-
- this.assignPinListRef = this.assignPinListRef.bind(this);
-
this.onMouseDown = this.onMouseDown.bind(this);
+
this.onPinMouseUp = this.onPinMouseUp.bind(this);
this.onPinMouseDown = this.onPinMouseDown.bind(this);
}
@@ -28,11 +24,6 @@ class Node extends React.Component {
}
onMouseDown(event) {
- if (this.pinListRef && this.pinListRef.contains(event.target)) {
- event.preventDefault();
- return;
- }
-
this.props.onMouseDown(event, this.id);
}
@@ -44,10 +35,6 @@ class Node extends React.Component {
this.props.onPinMouseDown(this.id, pinId);
}
- assignPinListRef(ref) {
- this.pinListRef = ref;
- }
-
render() {
const {
size,
@@ -76,16 +63,12 @@ class Node extends React.Component {
return (
diff --git a/packages/xod-client/src/project/components/Pin.jsx b/packages/xod-client/src/project/components/Pin.jsx
index d05d2197..240eb67b 100644
--- a/packages/xod-client/src/project/components/Pin.jsx
+++ b/packages/xod-client/src/project/components/Pin.jsx
@@ -1,10 +1,8 @@
import React from 'react';
import classNames from 'classnames';
-import { PIN_DIRECTION, PIN_VALIDITY } from 'xod-core';
+import { PIN_VALIDITY } from 'xod-core';
import { noop } from '../../utils/ramda';
-
-const PIN_RADIUS = 6;
-const TEXT_OFFSET_FROM_PIN_BORDER = 10;
+import { PIN_RADIUS } from '../nodeLayout';
export default class Pin extends React.Component {
constructor(props) {
@@ -57,39 +55,11 @@ export default class Pin extends React.Component {
};
}
- getTextProps() {
- const textVerticalOffset = PIN_RADIUS + TEXT_OFFSET_FROM_PIN_BORDER;
- const pos = this.getPinCenter();
- return {
- x: pos.x,
- y: pos.y + (textVerticalOffset * (this.isInput() ? 1 : -1)),
- textAnchor: 'middle',
- };
- }
-
- getDirection() {
- return this.props.direction;
- }
-
- isInput() {
- return (this.getDirection() === PIN_DIRECTION.INPUT);
- }
-
isInjected() {
return !!this.props.injected;
}
render() {
- const pinLabel = this.props.pinLabel ? (
-
- {this.props.pinLabel}
-
- ) : null;
-
const cls = classNames('Pin', {
'is-property': this.isInjected(),
'is-selected': this.props.isSelected,
@@ -125,7 +95,6 @@ export default class Pin extends React.Component {
r="15"
/>
{symbol}
- {pinLabel}
);
}
@@ -134,9 +103,7 @@ export default class Pin extends React.Component {
Pin.propTypes = {
keyName: React.PropTypes.string.isRequired,
injected: React.PropTypes.bool,
- pinLabel: React.PropTypes.string,
type: React.PropTypes.string,
- direction: React.PropTypes.string.isRequired,
position: React.PropTypes.object.isRequired,
onMouseUp: React.PropTypes.func.isRequired,
onMouseDown: React.PropTypes.func.isRequired,
diff --git a/packages/xod-client/src/project/components/PinLabel.jsx b/packages/xod-client/src/project/components/PinLabel.jsx
new file mode 100644
index 00000000..9d649fda
--- /dev/null
+++ b/packages/xod-client/src/project/components/PinLabel.jsx
@@ -0,0 +1,47 @@
+import React from 'react';
+import { PIN_DIRECTION } from 'xod-core';
+
+import { PIN_RADIUS, TEXT_OFFSET_FROM_PIN_BORDER } from '../nodeLayout';
+
+export default class Pin extends React.Component {
+ getPinCenter() {
+ return this.props.position;
+ }
+
+ getTextProps() {
+ const textVerticalOffset = PIN_RADIUS + TEXT_OFFSET_FROM_PIN_BORDER;
+ const pos = this.getPinCenter();
+ return {
+ x: pos.x,
+ y: pos.y + (textVerticalOffset * (this.isInput() ? 1 : -1)),
+ textAnchor: 'middle',
+ };
+ }
+
+ getDirection() {
+ return this.props.direction;
+ }
+
+ isInput() {
+ return (this.getDirection() === PIN_DIRECTION.INPUT);
+ }
+
+ render() {
+ return this.props.pinLabel ? (
+
+ {this.props.pinLabel}
+
+ ) : null;
+ }
+}
+
+Pin.propTypes = {
+ keyName: React.PropTypes.string.isRequired,
+ pinLabel: React.PropTypes.string,
+ direction: React.PropTypes.string.isRequired,
+ position: React.PropTypes.object.isRequired,
+};
diff --git a/packages/xod-client/src/project/nodeLayout.js b/packages/xod-client/src/project/nodeLayout.js
index 2c4ebbcd..489fe368 100644
--- a/packages/xod-client/src/project/nodeLayout.js
+++ b/packages/xod-client/src/project/nodeLayout.js
@@ -20,6 +20,8 @@ export const PIN_MARGIN = {
};
export const NODE_CORNER_RADIUS = 5;
+export const PIN_RADIUS = 6;
+export const TEXT_OFFSET_FROM_PIN_BORDER = 10;
/**
* @param {number} pinCount
diff --git a/packages/xod-client/stories/Link.jsx b/packages/xod-client/stories/Link.jsx
new file mode 100644
index 00000000..cdaaf549
--- /dev/null
+++ b/packages/xod-client/stories/Link.jsx
@@ -0,0 +1,68 @@
+import React from 'react';
+import { storiesOf } from '@kadira/storybook';
+
+import '../src/core/styles/main.scss';
+import XODLink from '../src/project/components/Link';
+
+const pFrom = { x: 30, y: 30 };
+const pTo = { x: 120, y: 120 };
+
+const baseProps = {
+ id: 'qwerty',
+ from: pFrom,
+ to: pTo,
+ isGhost: false,
+ isSelected: false,
+ type: 'string',
+};
+
+storiesOf('Link', module)
+ .addDecorator(story => (
+
+ ))
+ .add('string', () => (
+
+ ))
+ .add('bool', () => (
+
+ ))
+ .add('number', () => (
+
+ ))
+ .add('pulse', () => (
+
+ ))
+ .add('selected', () => (
+
+ ));
+
diff --git a/packages/xod-client/stories/Pin.jsx b/packages/xod-client/stories/Pin.jsx
index 71969ac7..92788272 100644
--- a/packages/xod-client/stories/Pin.jsx
+++ b/packages/xod-client/stories/Pin.jsx
@@ -34,16 +34,9 @@ storiesOf('Pin', module)
{story()}
))
- .add('input', () => (
+ .add('default', () => (
- ))
- .add('output', () => (
-
))
.add('selected', () => (
diff --git a/packages/xod-client/stories/PinLabel.jsx b/packages/xod-client/stories/PinLabel.jsx
new file mode 100644
index 00000000..492549a7
--- /dev/null
+++ b/packages/xod-client/stories/PinLabel.jsx
@@ -0,0 +1,41 @@
+import React from 'react';
+import { storiesOf } from '@kadira/storybook';
+
+import '../src/core/styles/main.scss';
+import PinLabel from '../src/project/components/PinLabel';
+
+const pinCenter = { x: 70, y: 70 };
+
+const baseProps = {
+ keyName: "my pin's keyname",
+ pinLabel: 'PIN',
+ direction: 'input',
+ position: pinCenter,
+};
+
+storiesOf('PinLabel', module)
+ .addDecorator(story => (
+
+ ))
+ .add('input', () => (
+
+ ))
+ .add('output', () => (
+
+ ));
+