mirror of
https://git.rwth-aachen.de/acs/public/villas/web/
synced 2025-03-09 00:00:01 +01:00
Add widget locking
Widgets can be locked and unlocked with the context menu Import react-contextmenu stylesheet instead of coping it into widgets.css
This commit is contained in:
parent
b7d80c5fc5
commit
5d9f24e304
4 changed files with 51 additions and 88 deletions
|
@ -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
|
||||
|
|
|
@ -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 (
|
||||
<div className='section box' >
|
||||
|
@ -425,13 +455,16 @@ class Visualization extends React.Component {
|
|||
{current_widgets != null &&
|
||||
Object.keys(current_widgets).map( (widget_key) => (
|
||||
<ContextMenu id={'widgetMenu'+ widget_key} key={widget_key} >
|
||||
<MenuItem data={{key: widget_key}} onClick={(e, data) => this.editWidget(e, data)}>Edit</MenuItem>
|
||||
<MenuItem data={{key: widget_key}} onClick={(e, data) => this.deleteWidget(e, data)}>Delete</MenuItem>
|
||||
<MenuItem data={{key: widget_key}} disabled={this.state.visualization.widgets[widget_key].locked} onClick={(e, data) => this.editWidget(e, data)}>Edit</MenuItem>
|
||||
<MenuItem data={{key: widget_key}} disabled={this.state.visualization.widgets[widget_key].locked} onClick={(e, data) => this.deleteWidget(e, data)}>Delete</MenuItem>
|
||||
<MenuItem divider />
|
||||
<MenuItem data={{key: widget_key}} onClick={(e, data) => this.moveWidget(e, data, this.moveAbove)}>Move above</MenuItem>
|
||||
<MenuItem data={{key: widget_key}} onClick={(e, data) => this.moveWidget(e, data, this.moveToFront)}>Move to front</MenuItem>
|
||||
<MenuItem data={{key: widget_key}} onClick={(e, data) => this.moveWidget(e, data, this.moveUnderneath)}>Move underneath</MenuItem>
|
||||
<MenuItem data={{key: widget_key}} onClick={(e, data) => this.moveWidget(e, data, this.moveToBack)}>Move to back</MenuItem>
|
||||
<MenuItem data={{key: widget_key}} disabled={this.state.visualization.widgets[widget_key].locked} onClick={(e, data) => this.moveWidget(e, data, this.moveAbove)}>Move above</MenuItem>
|
||||
<MenuItem data={{key: widget_key}} disabled={this.state.visualization.widgets[widget_key].locked} onClick={(e, data) => this.moveWidget(e, data, this.moveToFront)}>Move to front</MenuItem>
|
||||
<MenuItem data={{key: widget_key}} disabled={this.state.visualization.widgets[widget_key].locked} onClick={(e, data) => this.moveWidget(e, data, this.moveUnderneath)}>Move underneath</MenuItem>
|
||||
<MenuItem data={{key: widget_key}} disabled={this.state.visualization.widgets[widget_key].locked} onClick={(e, data) => this.moveWidget(e, data, this.moveToBack)}>Move to back</MenuItem>
|
||||
<MenuItem divider />
|
||||
<MenuItem data={{key: widget_key}} disabled={this.state.visualization.widgets[widget_key].locked} onClick={(e, data) => this.lockWidget(data)}>Lock</MenuItem>
|
||||
<MenuItem data={{key: widget_key}} disabled={!this.state.visualization.widgets[widget_key].locked} onClick={(e, data) => this.unlockWidget(data)}>Unlock</MenuItem>
|
||||
</ContextMenu>
|
||||
))}
|
||||
|
||||
|
|
|
@ -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}
|
||||
>
|
||||
<ContextMenuTrigger id={'widgetMenu' + this.props.index} ref={c => this.contextMenuTriggerViaDraggable = c} >
|
||||
{element}
|
||||
</ContextMenuTrigger>
|
||||
</Rnd>
|
||||
);
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className={ widgetClasses } style={{ width: Number(widget.width), height: Number(widget.height), left: Number(widget.x), top: Number(widget.y), 'zIndex': Number(widget.z), position: 'absolute' }}>
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue