1
0
Fork 0
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:
Markus Grigull 2017-08-01 22:06:22 +02:00
parent b7d80c5fc5
commit 5d9f24e304
4 changed files with 51 additions and 88 deletions

View file

@ -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

View file

@ -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>
))}

View file

@ -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' }}>

View file

@ -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;