From 5d9f24e304fd13c3e90379f4f6c538687c8c4b96 Mon Sep 17 00:00:00 2001 From: Markus Grigull Date: Tue, 1 Aug 2017 22:06:22 +0200 Subject: [PATCH] Add widget locking Widgets can be locked and unlocked with the context menu Import react-contextmenu stylesheet instead of coping it into widgets.css --- src/components/widget-factory.js | 3 +- src/containers/visualization.js | 47 +++++++++++++++--- src/containers/widget.js | 7 ++- src/styles/widgets.css | 82 ++------------------------------ 4 files changed, 51 insertions(+), 88 deletions(-) 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) => ( - this.editWidget(e, data)}>Edit - this.deleteWidget(e, data)}>Delete + this.editWidget(e, data)}>Edit + this.deleteWidget(e, data)}>Delete - this.moveWidget(e, data, this.moveAbove)}>Move above - this.moveWidget(e, data, this.moveToFront)}>Move to front - this.moveWidget(e, data, this.moveUnderneath)}>Move underneath - this.moveWidget(e, data, this.moveToBack)}>Move to back + this.moveWidget(e, data, this.moveAbove)}>Move above + this.moveWidget(e, data, this.moveToFront)}>Move to front + this.moveWidget(e, data, this.moveUnderneath)}>Move underneath + this.moveWidget(e, data, this.moveToBack)}>Move to back + + this.lockWidget(data)}>Lock + this.unlockWidget(data)}>Unlock ))} 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} > this.contextMenuTriggerViaDraggable = c} > {element} - ); + ); } 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;