You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openNG/src/client/components/window/window.jsx

100 lines
2.5 KiB
JavaScript

'use strict';
const React = require("react");
const createReactClass = require("create-react-class");
const classnames = require("classnames");
const renderIf = require("../../util/render-if");
const windowTitleContext = require("./window-title-context");
function cancelEvent(event) {
/* NOTE: This is used on mousedown events for controls like the CloseButton, to ensure that a click-and-drag on a titlebar control cannot start a window drag operation. */
event.stopPropagation();
}
function relativePosition(event, bounds) {
let relativeX = event.clientX - bounds.x;
let relativeY = event.clientY - bounds.y;
return {
x: relativeX,
y: relativeY
};
}
function CloseButton({onClick}) {
return (
<div className="button close" onClick={onClick} onMouseDown={cancelEvent}>
</div>
);
}
let TitleBar = createReactClass({
displayName: "TitleBar",
setRef: function (ref) {
this.setState({
ref: ref
});
},
handleMouseDown: function (event) {
let bounds = this.state.ref.getBoundingClientRect();
let relativeX = event.clientX - bounds.x;
let relativeY = event.clientY - bounds.y;
this.props.onMouseDown(event, relativeX, relativeY);
},
render: function () {
return (
<div ref={this.setRef} className="titleBar" onMouseDown={this.handleMouseDown}>
<div className="title">
{this.props.title}
</div>
<div className="buttons">
{this.props.extraButtons}
<CloseButton onClick={this.props.onClose} />
</div>
</div>
);
}
});
function Resizer({onMouseDown}) {
let [ref, setRef] = React.useState(null);
function onMouseDown_(event) {
let {x, y} = relativePosition(event, ref.getBoundingClientRect());
onMouseDown(event, x, y);
event.stopPropagation();
}
return (
<div className="resizer" ref={setRef} onMouseDown={onMouseDown_}>
<div className="arrow" />
</div>
);
}
module.exports = function Window({elementRef, style, window: window_, onMouseDown, onTitleMouseDown, onClose, onResizerMouseDown}) {
let [windowTitle, setWindowTitle] = React.useState("");
return (
<div ref={elementRef} className={classnames("window", {active: window_.isActive})} style={style} onMouseDown={onMouseDown}>
<TitleBar title={windowTitle} onMouseDown={onTitleMouseDown} onClose={onClose} />
<windowTitleContext.Provider value={setWindowTitle}>
<div className="body">
<div className="contents">
{window_.contents}
</div>
{renderIf(window_.resizable, <Resizer onMouseDown={onResizerMouseDown} />)}
</div>
</windowTitleContext.Provider>
</div>
);
};