diff --git a/src/components/widget-factory.js b/src/components/widget-factory.js
index aa1a955..c6173bb 100644
--- a/src/components/widget-factory.js
+++ b/src/components/widget-factory.js
@@ -21,7 +21,8 @@ class WidgetFactory {
height: 100,
x: position.x,
y: position.y,
- z: position.z
+ z: position.z,
+ locked: false
};
// set type specific properties
diff --git a/src/containers/visualization.js b/src/containers/visualization.js
index c342430..61bea93 100644
--- a/src/containers/visualization.js
+++ b/src/containers/visualization.js
@@ -41,6 +41,8 @@ import AppDispatcher from '../app-dispatcher';
import NotificationsDataManager from '../data-managers/notifications-data-manager';
import NotificationsFactory from '../data-managers/notifications-factory';
+import 'react-contextmenu/public/styles.5bb557.css';
+
class Visualization extends React.Component {
static getStores() {
return [ VisualizationStore, ProjectStore, SimulationStore, FileStore, UserStore ];
@@ -357,8 +359,36 @@ class Visualization extends React.Component {
this.setState({ visualization });
}
+ lockWidget(data) {
+ // lock the widget
+ let widget = this.state.visualization.widgets[data.key];
+ widget.locked = true;
+
+ // update visualization
+ let widgets = {};
+ widgets[data.key] = widget;
+ widgets = Object.assign({}, this.state.visualization.widgets, widgets);
+
+ const visualization = Object.assign({}, this.state.visualization, { widgets });
+ this.setState({ visualization });
+ }
+
+ unlockWidget(data) {
+ // lock the widget
+ let widget = this.state.visualization.widgets[data.key];
+ widget.locked = false;
+
+ // update visualization
+ let widgets = {};
+ widgets[data.key] = widget;
+ widgets = Object.assign({}, this.state.visualization.widgets, widgets);
+
+ const visualization = Object.assign({}, this.state.visualization, { widgets });
+ this.setState({ visualization });
+ }
+
render() {
- var current_widgets = this.state.visualization.widgets;
+ const current_widgets = this.state.visualization.widgets;
return (
@@ -425,13 +455,16 @@ class Visualization extends React.Component {
{current_widgets != null &&
Object.keys(current_widgets).map( (widget_key) => (
))}
diff --git a/src/containers/widget.js b/src/containers/widget.js
index 42b4177..8b7f094 100644
--- a/src/containers/widget.js
+++ b/src/containers/widget.js
@@ -181,7 +181,8 @@ class Widget extends Component {
'widget': !this.props.editing,
'editing-widget': this.props.editing,
'border': borderedWidget,
- 'unselectable': this.props.editing
+ 'unselectable': this.props.editing,
+ 'locked': widget.locked && this.props.editing
});
if (this.props.editing) {
@@ -201,12 +202,14 @@ class Widget extends Component {
dragGrid={grid}
resizeGrid={grid}
zIndex={widget.z}
+ enableResizing={!widget.locked}
+ disableDragging={widget.locked}
>
- );
+ );
} else {
return (
diff --git a/src/styles/widgets.css b/src/styles/widgets.css
index 70c802c..b8f2483 100644
--- a/src/styles/widgets.css
+++ b/src/styles/widgets.css
@@ -35,6 +35,10 @@
background-color: #fff;
}
+.locked {
+ cursor: not-allowed !important;
+}
+
/* Firefox-specific rules */
@-moz-document url-prefix() {
.editing-widget:not(.border):hover {
@@ -46,84 +50,6 @@
outline: 1px solid lightgray;
}
-/* Area to trigger the context menu */
-.react-contextmenu-wrapper {
- width: 100%;
- height: 100%;
- position: absolute;
- top: 0px;
- left: 0px;
- overflow: auto;
-}
-
-.react-contextmenu {
- min-width: 160px;
- padding: 5px 0;
- margin: 2px 0 0;
- font-size: 16px;
- color: #373a3c;
- text-align: left;
- background-color: #fff;
- background-clip: padding-box;
- border: 1px solid rgba(0,0,0,.15);
- border-radius: .25rem;
- outline: none;
- opacity: 0;
- pointer-events: none;
- z-index: 100;
-}
-
-.react-contextmenu.react-contextmenu--visible {
- opacity: 1;
- pointer-events: auto;
-}
-
-.react-contextmenu-item {
- width: 200px;
- padding: 3px 20px;
- font-weight: 400;
- line-height: 1.5;
- color: #373a3c;
- text-align: inherit;
- white-space: nowrap;
- background: 0 0;
- border: 0;
- cursor: pointer;
-}
-
-.react-contextmenu-item.react-contextmenu-item--active,
-.react-contextmenu-item:hover {
- color: #fff;
- background-color: #0275d8;
- border-color: #0275d8;
- text-decoration: none;
-}
-
-.react-contextmenu-item--divider {
- margin-bottom: 3px;
- padding: 2px 0;
- border-bottom: 1px solid rgba(0,0,0,.15);
- cursor: inherit;
-}
-.react-contextmenu-item--divider:hover {
- background-color: transparent;
- border-color: rgba(0,0,0,.15);
-}
-
-.react-contextmenu-item.react-contextmenu-submenu {
- padding: 0;
-}
-
-.react-contextmenu-item.react-contextmenu-submenu > .react-contextmenu-item {
-}
-
-.react-contextmenu-item.react-contextmenu-submenu > .react-contextmenu-item:after {
- content: "▶";
- display: inline-block;
- position: absolute;
- right: 7px;
-}
-
/* Reset Bootstrap styles to "disable" while editing */
div[class*="-widget"] .btn[disabled], .btn.disabled, div[class*="-widget"] input[disabled], .form-control[disabled], .checkbox.disabled label {
cursor: inherit;